From antonynpavlov at gmail.com  Wed Oct  1 00:19:39 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 1 Oct 2014 11:19:39 +0400
Subject: [PATCH 00/15] PCI bridges and Tegra PCI stuff
In-Reply-To: <20141001061721.GB4992@pengutronix.de>
References: <1411664709-13699-1-git-send-email-dev@lynxeye.de>
 <20140925230238.18b41a52be8f3d5cc45d9bc7@gmail.com>
 <1411678015.2207.2.camel@tellur.intern.lynxeye.de>
 <20141001061721.GB4992@pengutronix.de>
Message-ID: <20141001111939.a47affd2340d830a60237d20@gmail.com>

On Wed, 1 Oct 2014 08:17:21 +0200
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> On Thu, Sep 25, 2014 at 10:46:55PM +0200, Lucas Stach wrote:
> > Am Donnerstag, den 25.09.2014, 23:02 +0400 schrieb Antony Pavlov:
> > > On Thu, 25 Sep 2014 19:04:54 +0200
> > > Lucas Stach <dev at lynxeye.de> wrote:
> > > 
> > > > Ok, I'm sending this out before it gathers any more dust.
> > > > 
> > > > This still doesn't work on Tegra K1 and I also haven't got
> > > > around to finish the rtl8169 network driver, but it seems
> > > > this pile is already a worthwile improvement.
> > > > 
> > > > First 7 patches are general barebox PCI improvements for
> > > > better tracking of PCI resources and handling bridge setup.
> > > 
> > > I have tryed this series.
> > > 
> > > I have got several 
> > >   'BAR does not fit within bus IO res'
> > > messages on qemu-malta. So not all available pci devices were registered.
> > > 
> > I think that's because patch 2 fixes a problem where IO resources would
> > be populated from the host controllers MEM resource. IO resources are
> > now properly accounted.
> > 
> > From a quick look at the code it seems you aren't properly assigning the
> > resource.end for the IO region on malta. Can you please check this?
> > Otherwise please post the PCI debug messages.
> 
> How do we proceed with this series? Antony, could you help debugging
> this?

Lucas is right. Malta's pci controller code assings wrong value for io resource.end.
I'm examining correspoinding linux kernel code, but I can't point a source of the problem just now.

 
--?
Best regards,
? Antony Pavlov


From yamada.m at jp.panasonic.com  Wed Oct  1 03:35:34 2014
From: yamada.m at jp.panasonic.com (Masahiro Yamada)
Date: Wed, 01 Oct 2014 19:35:34 +0900
Subject: Newbie question
Message-ID: <20141001193534.5A4B.AA925319@jp.panasonic.com>

Hi.


Please forgive me if I am asking a silly newbie question.

I have some knowledge of U-Boot
but I have just started digging into barebox.


My simple question is, something like SPL
(secondary program loader) in U-boot is covered by barebox?



I assume the following steps
for running Linux on our boards by booting from NAND device.


[1] BootROM (hard-wired)

[2] Tiny boot program
    for initializing SDRAM, etc.

[3] High-level boot loader
    for loading the kernel, handling device tree etc.

[4] Linux



I guess [3] is covered by barebox.

Is [2] supported by barebox? Or is it like Do-It-Yourself thing?


Best Regards
Masahiro Yamada



From luigi.origa at gmail.com  Wed Oct  1 05:03:45 2014
From: luigi.origa at gmail.com (luigi origa)
Date: Wed, 1 Oct 2014 14:03:45 +0200
Subject: Little bug
In-Reply-To: <CACSabZ8wCRJAE2Oc2ZrQGQg5=X=mRJ9OF14tiC981=zWRSaTiw@mail.gmail.com>
References: <CACSabZ_nSs8L6yHn6Pz3quNvYQSDWiB0FWOYow1vyp9akRp0PA@mail.gmail.com>
 <20141001060247.GZ4992@pengutronix.de>
 <CACSabZ8wCRJAE2Oc2ZrQGQg5=X=mRJ9OF14tiC981=zWRSaTiw@mail.gmail.com>
Message-ID: <CACSabZ99bES8dwb=LcxPGJY_bDTJEiQg-rNJihL6pYUxEwAJwQ@mail.gmail.com>

Few days ago i got the files using git but in this moment i'm out so i
downloaded the file "barebox-2014.08.0.tar.bz2".

Looking inside i found the same error.

Open the file "barebox-2014.08.0\arch\arm\boards\friendlyarm-mini2440\mini2440.c"
and goto at line 84.

#ifdef CONFIG_MINI2440_VIDEO_A70
{
.name = "A70",
.refresh = 50,
.xres = 800,
.left_margin = 40,
.right_margin = 40,
.hsync_len = 48,
.yres = 480,
.upper_margin = 29,
.lower_margin = 3,
.vsync_len = 3,
.pixclock = 41848,
.sync = FB_SYNC_USE_PWREN | FB_SYNC_DE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,    // <<<<<<<<<<<<<<<<<<<<<<<< mismatch
},
#endif
#ifdef CONFIG_MINI2440_VIDEO_SVGA
{
.name = "SVGA",
.refresh = 24,
.xres = 1024,
.left_margin = 1,
.right_margin = 2,
.hsync_len = 2,
.yres = 768,
.upper_margin = 200,
.lower_margin = 16,
.vsync_len = 16,
.pixclock = 40492,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_DE_HIGH_ACT
                                  /* | FB_SYNC_SWAP_HW */ /* FIXME maybe */ ,
.vmode = FB_VMODE_NONINTERLACED,
.flag = 0,    // <<<<<<<<<<<<<<<<<<<<<<<< mismatch
},
#endif

Luigi


From s.hauer at pengutronix.de  Wed Oct  1 05:06:43 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 1 Oct 2014 14:06:43 +0200
Subject: Newbie question
In-Reply-To: <20141001193534.5A4B.AA925319@jp.panasonic.com>
References: <20141001193534.5A4B.AA925319@jp.panasonic.com>
Message-ID: <20141001120643.GH4992@pengutronix.de>

Hi,

On Wed, Oct 01, 2014 at 07:35:34PM +0900, Masahiro Yamada wrote:
> Hi.
> 
> 
> Please forgive me if I am asking a silly newbie question.
> 
> I have some knowledge of U-Boot
> but I have just started digging into barebox.
> 
> 
> My simple question is, something like SPL
> (secondary program loader) in U-boot is covered by barebox?

Yes, it is, in barebox it's called PBL (PreBootLoader).

If enabled the ROM will load the PBL from the boot device (Or sometimes
the whole image, depends on the ROM). The PBL will then load the rest
of the image from the device, uncompress it and jump to it.

> [1] BootROM (hard-wired)
> 
> [2] Tiny boot program
>     for initializing SDRAM, etc.
> 
> [3] High-level boot loader
>     for loading the kernel, handling device tree etc.
> 
> [4] Linux
> 
> 
> 
> I guess [3] is covered by barebox.
> 
> Is [2] supported by barebox? Or is it like Do-It-Yourself thing?

Well, there's infrastructure for it, but due to the limited space
and restricted environment in the PBL there's still some DIY left ;)

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 t.gamez at phytec.de  Wed Oct  1 07:37:16 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Wed, 1 Oct 2014 16:37:16 +0200
Subject: [PATCH] i2c: omap: fix dts property "clock-frequency" usage
Message-ID: <1412174236-45854-1-git-send-email-t.gamez@phytec.de>

Looking at the linux kernel the clock-frequency property of
the device tree is used to set the bus speed and not the
fclk_rate. Adapted this to be compliant with linux kernel.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 drivers/i2c/busses/i2c-omap.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index adc952b..48bdfbe 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -151,7 +151,6 @@ struct omap_i2c_struct {
 	u8			reg_shift;
 	struct omap_i2c_driver_data	*data;
 	struct resource		*ioarea;
-	u32			fclk_rate;
 	u32			speed;		/* Speed of bus in Khz */
 	u16			scheme;
 	u16			cmd_err;
@@ -421,7 +420,7 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
 		internal_clk = 4000;
 
 	/* Compute prescaler divisor */
-	psc = i2c_omap->fclk_rate / internal_clk;
+	psc = i2c_data->fclk_rate / internal_clk;
 	psc = psc - 1;
 
 	/* If configured for High Speed */
@@ -1016,9 +1015,16 @@ i2c_omap_probe(struct device_d *pdev)
 	i2c_omap->reg_shift = (i2c_data->flags >>
 					OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
 
-	if (pdev->platform_data != NULL)
+	if (pdev->platform_data != NULL) {
 		speed = *(u32 *)pdev->platform_data;
-	else
+	} else {
+		of_property_read_u32(pdev->device_node, "clock-frequency",
+			&speed);
+		/* convert DT freq value in Hz into kHz for speed */
+		speed /= 1000;
+	}
+
+	if (!speed)
 		speed = 100;	/* Default speed */
 
 	i2c_omap->speed = speed;
@@ -1080,12 +1086,6 @@ i2c_omap_probe(struct device_d *pdev)
 			i2c_omap->b_hw = 1; /* Enable hardware fixes */
 	}
 
-	i2c_omap->fclk_rate = i2c_data->fclk_rate;
-
-	if (!i2c_omap->fclk_rate)
-		of_property_read_u32(pdev->device_node, "clock-frequency",
-				&i2c_omap->fclk_rate);
-
 	/* reset ASAP, clearing any IRQs */
 	omap_i2c_init(i2c_omap);
 
-- 
1.9.1



From dev at lynxeye.de  Wed Oct  1 12:14:15 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Wed,  1 Oct 2014 21:14:15 +0200
Subject: [PATCH 2/2] MIPS: malta: fix pci IO resource assignment
In-Reply-To: <1412190855-14289-1-git-send-email-dev@lynxeye.de>
References: <1412190855-14289-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412190855-14289-3-git-send-email-dev@lynxeye.de>

Does the same thing as the Linux kernel now.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
I tested this with qemu-malta and at least barebox is now
again able to enumerate all 4 PCI devices.
---
 arch/mips/mach-malta/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c
index 9035175..47c0e22 100644
--- a/arch/mips/mach-malta/pci.c
+++ b/arch/mips/mach-malta/pci.c
@@ -151,7 +151,7 @@ static struct pci_controller gt64120_controller = {
 
 static int pcibios_init(void)
 {
-	resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+	resource_size_t start, end, map, start1, end1, map1, mask;
 
 	/*
 	 * Due to a bug in the Galileo system controller, we need
@@ -207,7 +207,7 @@ static int pcibios_init(void)
 	BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
 		mask != ~((mask & -mask) - 1));
 	gt64120_io_resource.start = map & mask;
-	res_end = (map & mask) | ~mask;
+	gt64120_io_resource.end = (map & mask) | ~mask;
 	gt64120_controller.io_offset = 0;
 	/* Addresses are 36-bit, so do shifts in the destinations. */
 	gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
-- 
1.9.3



From dev at lynxeye.de  Wed Oct  1 12:14:13 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Wed,  1 Oct 2014 21:14:13 +0200
Subject: [PATCH 0/2] Increamental fixes for the PCI series
Message-ID: <1412190855-14289-1-git-send-email-dev@lynxeye.de>

Those two patches fix the remaining issues with my previous
PCI series. It fixes the regression on malta reported by
Antony and another potential issue where function
dependencies weren't exactly right.

Lucas Stach (2):
  fixup! of: import pci range parser from linux
  MIPS: malta: fix pci IO resource assignment

 arch/mips/mach-malta/pci.c |  4 ++--
 drivers/of/Kconfig         |  1 +
 drivers/of/address.c       |  4 ++--
 include/of_address.h       | 22 +++++++++++++++-------
 4 files changed, 20 insertions(+), 11 deletions(-)

-- 
1.9.3



From dev at lynxeye.de  Wed Oct  1 12:14:14 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Wed,  1 Oct 2014 21:14:14 +0200
Subject: [PATCH 1/2] fixup! of: import pci range parser from linux
In-Reply-To: <1412190855-14289-1-git-send-email-dev@lynxeye.de>
References: <1412190855-14289-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412190855-14289-2-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
Correct dependencies and put function definitions under
correct ifdef to avoid build warnings/errors on systems
with PCI but without OF.
---
 drivers/of/Kconfig   |  1 +
 drivers/of/address.c |  4 ++--
 include/of_address.h | 22 +++++++++++++++-------
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 8195506..39cd138 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -30,6 +30,7 @@ config OF_GPIO
 config OF_PCI
 	bool
 	depends on PCI
+	select OF_ADDRESS_PCI
 	help
 	  OpenFirmware PCI bus accessors
 
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 15f3ade..8018d78 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -179,7 +179,7 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
 }
 #endif /* CONFIG_OF_ADDRESS_PCI */
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_OF_PCI
 int of_pci_range_parser_init(struct of_pci_range_parser *parser,
 				struct device_node *node)
 {
@@ -245,7 +245,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
 	return range;
 }
 EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_OF_PCI */
 
 /*
  * Array of bus specific translators
diff --git a/include/of_address.h b/include/of_address.h
index f9c3c0f..cef785e 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -55,11 +55,7 @@ extern struct device_node *of_find_matching_node_by_address(
 	struct device_node *from, const struct of_device_id *matches,
 	u64 base_address);
 extern void __iomem *of_iomap(struct device_node *np, int index);
-extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
-			struct device_node *node);
-extern struct of_pci_range *of_pci_range_parser_one(
-			struct of_pci_range_parser *parser,
-			struct of_pci_range *range);
+
 #else /* CONFIG_OFTREE */
 
 static inline u64 of_translate_address(struct device_node *dev,
@@ -103,6 +99,20 @@ static inline void __iomem *of_iomap(struct device_node *np, int index)
 	return NULL;
 }
 
+#endif /* CONFIG_OFTREE */
+
+#ifdef CONFIG_OF_PCI
+
+extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+			struct device_node *node);
+
+extern struct of_pci_range *of_pci_range_parser_one(
+			struct of_pci_range_parser *parser,
+			struct of_pci_range *range);
+
+#else
+
+#endif /* CONFIG_OF_PCI */
 static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
 			struct device_node *node)
 {
@@ -116,6 +126,4 @@ static inline struct of_pci_range *of_pci_range_parser_one(
 	return NULL;
 }
 
-#endif /* CONFIG_OFTREE */
-
 #endif /* __OF_ADDRESS_H */
-- 
1.9.3



From yamada.m at jp.panasonic.com  Wed Oct  1 20:51:33 2014
From: yamada.m at jp.panasonic.com (Masahiro Yamada)
Date: Thu, 02 Oct 2014 12:51:33 +0900
Subject: Newbie question
In-Reply-To: <20141001120643.GH4992@pengutronix.de>
References: <20141001193534.5A4B.AA925319@jp.panasonic.com>
 <20141001120643.GH4992@pengutronix.de>
Message-ID: <20141002125132.4702.AA925319@jp.panasonic.com>

Hi Sascha,



On Wed, 1 Oct 2014 14:06:43 +0200
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> Hi,
> 
> On Wed, Oct 01, 2014 at 07:35:34PM +0900, Masahiro Yamada wrote:
> > Hi.
> > 
> > 
> > Please forgive me if I am asking a silly newbie question.
> > 
> > I have some knowledge of U-Boot
> > but I have just started digging into barebox.
> > 
> > 
> > My simple question is, something like SPL
> > (secondary program loader) in U-boot is covered by barebox?
> 
> Yes, it is, in barebox it's called PBL (PreBootLoader).
> 
> If enabled the ROM will load the PBL from the boot device (Or sometimes
> the whole image, depends on the ROM). The PBL will then load the rest
> of the image from the device, uncompress it and jump to it.
> 
> > [1] BootROM (hard-wired)
> > 
> > [2] Tiny boot program
> >     for initializing SDRAM, etc.
> > 
> > [3] High-level boot loader
> >     for loading the kernel, handling device tree etc.
> > 
> > [4] Linux
> > 
> > 
> > 
> > I guess [3] is covered by barebox.
> > 
> > Is [2] supported by barebox? Or is it like Do-It-Yourself thing?
> 
> Well, there's infrastructure for it, but due to the limited space
> and restricted environment in the PBL there's still some DIY left ;)
> 



Now I understood how it works.

 obj-y  => Main barebox
 pbl-y  => PBL


Thanks!



Best Regards
Masahiro Yamada



From s.hauer at pengutronix.de  Wed Oct  1 22:51:29 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 2 Oct 2014 07:51:29 +0200
Subject: [PATCH] i2c: omap: fix dts property "clock-frequency" usage
In-Reply-To: <1412174236-45854-1-git-send-email-t.gamez@phytec.de>
References: <1412174236-45854-1-git-send-email-t.gamez@phytec.de>
Message-ID: <20141002055129.GI4992@pengutronix.de>

On Wed, Oct 01, 2014 at 04:37:16PM +0200, Teresa G?mez wrote:
> Looking at the linux kernel the clock-frequency property of
> the device tree is used to set the bus speed and not the
> fclk_rate. Adapted this to be compliant with linux kernel.
> 
> Signed-off-by: Teresa G?mez <t.gamez at phytec.de>

Applied, thanks

Sascha

> ---
>  drivers/i2c/busses/i2c-omap.c | 20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index adc952b..48bdfbe 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -151,7 +151,6 @@ struct omap_i2c_struct {
>  	u8			reg_shift;
>  	struct omap_i2c_driver_data	*data;
>  	struct resource		*ioarea;
> -	u32			fclk_rate;
>  	u32			speed;		/* Speed of bus in Khz */
>  	u16			scheme;
>  	u16			cmd_err;
> @@ -421,7 +420,7 @@ static int omap_i2c_init(struct omap_i2c_struct *i2c_omap)
>  		internal_clk = 4000;
>  
>  	/* Compute prescaler divisor */
> -	psc = i2c_omap->fclk_rate / internal_clk;
> +	psc = i2c_data->fclk_rate / internal_clk;
>  	psc = psc - 1;
>  
>  	/* If configured for High Speed */
> @@ -1016,9 +1015,16 @@ i2c_omap_probe(struct device_d *pdev)
>  	i2c_omap->reg_shift = (i2c_data->flags >>
>  					OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
>  
> -	if (pdev->platform_data != NULL)
> +	if (pdev->platform_data != NULL) {
>  		speed = *(u32 *)pdev->platform_data;
> -	else
> +	} else {
> +		of_property_read_u32(pdev->device_node, "clock-frequency",
> +			&speed);
> +		/* convert DT freq value in Hz into kHz for speed */
> +		speed /= 1000;
> +	}
> +
> +	if (!speed)
>  		speed = 100;	/* Default speed */
>  
>  	i2c_omap->speed = speed;
> @@ -1080,12 +1086,6 @@ i2c_omap_probe(struct device_d *pdev)
>  			i2c_omap->b_hw = 1; /* Enable hardware fixes */
>  	}
>  
> -	i2c_omap->fclk_rate = i2c_data->fclk_rate;
> -
> -	if (!i2c_omap->fclk_rate)
> -		of_property_read_u32(pdev->device_node, "clock-frequency",
> -				&i2c_omap->fclk_rate);
> -
>  	/* reset ASAP, clearing any IRQs */
>  	omap_i2c_init(i2c_omap);
>  
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> 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  Wed Oct  1 23:17:29 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 2 Oct 2014 08:17:29 +0200
Subject: v2014.10.0
Message-ID: <20141002061729.GJ4992@pengutronix.de>


Hi All,

Here's barebox-2014.10.0. Not very much has happened since the last
release. Many of the patches are fixes so chances are good we fixed
more bugs than we created new ones. Nice :)

Sascha

----------------------------------------------------------------
Antony Pavlov (2):
      Documentation: davinci.rst: fix code-block formatting
      net: dm9k: fix copy-paste typo

Christian Hemp (1):
      dts:imx6:pfla02: Fix SPI NOR for phyFLEX-i.MX6

Ezequiel Garcia (2):
      nand: Add Marvell Orion NAND driver
      ARM: mvebu: Add Plat'home's Kirkwood Openblocks A6 board support

Jan Weitzel (1):
      commands: of_dump switch to get fixed devictree

Michael Grzeschik (1):
      ubi: add setting devnum to ubiattach

Michael Olbrich (1):
      efi: use objcopy with CROSS_COMPILE prefix

Philipp Zabel (1):
      serial: imx: Fix for non-devicetree boards

Rapha?l Poggi (8):
      mtd: nand: add has_pmecc member
      mtd: atmel_nand: retrieve ecc_mode from pdata
      mtd: atmel_nand: add support for device tree
      arm: mach-at91: move gpio.h to include folder
      pinctrl: at91: add pinctrl driver
      pinctrl: at91: add driver data
      pinctrl: at91: fix the pin_to_controller function
      pinctrl: at91: retrieve device id in non dtb probe

Sascha Hauer (14):
      ARM: dts: Use local version of rk3188-clocks.dtsi
      ARM: dts: move imx6q-embedsky-e9.dtsi to arch/arm/dts/boot
      dts: update to v3.17-rc1
      dts: update to v3.17-rc2
      Merge branch 'for-next/at91'
      Merge branch 'for-next/dts'
      Merge branch 'for-next/marvell'
      Merge branch 'for-next/misc'
      ARM: AT91: Add missing include
      ARM: AT91: Make gpio mux functions inline
      net: Call edev->recv with correct eth_device
      USB: gadget: fastboot: Add missing include
      USB: gadget: dfu: Add max_speed to dfu_driver
      Release v2014.10.0

Silvio Fricke (1):
      ARM: i.MX: edmqmx6: free phy-reset gpio pin

Teresa G?mez (4):
      defaultenv: Reorder overlay append order
      commands: of_dump: Fix return value
      read_file_2: Fix return value
      i2c: omap: fix dts property "clock-frequency" usage

Wjatscheslaw Stoljarski (1):
      commands: usb: drop help for force rescan option

-- 
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 r.schwebel at pengutronix.de  Thu Oct  2 09:40:44 2014
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Thu,  2 Oct 2014 18:40:44 +0200
Subject: [PATCH] commands: select FILE_LIST for usbgadget
Message-ID: <1412268044-1360-1-git-send-email-r.schwebel@pengutronix.de>

Otherwhise we get this error message:

commands/built-in.o: In function `do_usbgadget':
barebox-2014.10.0/commands/usbgadget.c:77: undefined reference to `file_list_parse'

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 commands/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/commands/Kconfig b/commands/Kconfig
index 3a49baf..aafa80f 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -1851,6 +1851,7 @@ config CMD_USB
 config CMD_USBGADGET
 	bool
 	depends on USB_GADGET
+	select FILE_LIST
 	prompt "usbgadget"
 
 config CMD_WD
-- 
2.1.0



From gregory.hermant at calao-systems.com  Fri Oct  3 00:05:17 2014
From: gregory.hermant at calao-systems.com (=?UTF-8?B?R3LDqWdvcnkgSGVybWFudA==?=)
Date: Fri, 03 Oct 2014 09:05:17 +0200
Subject: at91 usbserial issue
Message-ID: <542E4AAD.7070703@calao-systems.com>

Hi all,
The usbserial seems to be broken for board equipped with an Atmel sam9260/9g20 Soc.
I ran the lastest version of barebox (v2014.10.0) on a USB_A9G20_LPW.
Below the trace
udc0: registering UDC driver [g_serial]
g_serial usbgadget: acm/23ba9538: can't bind, err -19
g_serial udc0: failed to start g_serial: -19
usbserial: No such device
I didn't yet investigate this issue but i was wondering if someone noticed the problem.
Greg


From dev at lynxeye.de  Sat Oct  4 10:40:07 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:07 +0200
Subject: [PATCH v2 01/19] MIPS: malta: fix pci IO resource assignment
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-2-git-send-email-dev@lynxeye.de>

Does the same thing as the Linux kernel now.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
I tested this with qemu-malta and at least barebox is now
again able to enumerate all 4 PCI devices.
---
 arch/mips/mach-malta/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c
index 9035175..47c0e22 100644
--- a/arch/mips/mach-malta/pci.c
+++ b/arch/mips/mach-malta/pci.c
@@ -151,7 +151,7 @@ static struct pci_controller gt64120_controller = {
 
 static int pcibios_init(void)
 {
-	resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+	resource_size_t start, end, map, start1, end1, map1, mask;
 
 	/*
 	 * Due to a bug in the Galileo system controller, we need
@@ -207,7 +207,7 @@ static int pcibios_init(void)
 	BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
 		mask != ~((mask & -mask) - 1));
 	gt64120_io_resource.start = map & mask;
-	res_end = (map & mask) | ~mask;
+	gt64120_io_resource.end = (map & mask) | ~mask;
 	gt64120_controller.io_offset = 0;
 	/* Addresses are 36-bit, so do shifts in the destinations. */
 	gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:12 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:12 +0200
Subject: [PATCH v2 06/19] pci: defer device registration until after bridge
 setup
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-7-git-send-email-dev@lynxeye.de>

Otherwise the drivers for a device may probe before the
devices parent bridge is fully configured, which leads
to errors when accessing the BARs.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 59f942d..943d0e8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -208,7 +208,6 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 
 	pci_write_config_byte(dev, PCI_COMMAND, cmd);
 	list_add_tail(&dev->bus_list, &dev->bus->devices);
-	pci_register_device(dev);
 }
 
 static void prescan_setup_bridge(struct pci_dev *dev)
@@ -362,6 +361,11 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			prescan_setup_bridge(dev);
 			pci_scan_bus(child_bus);
 			postscan_setup_bridge(dev);
+			/* first activate bridge then all devices on it's bus */
+			pci_register_device(dev);
+			list_for_each_entry(dev, &child_bus->devices, bus_list)
+				if (!dev->subordinate)
+					pci_register_device(dev);
 			break;
 		default:
 		bad:
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:06 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:06 +0200
Subject: [PATCH v2 00/19] PCI and Tegra series revamp
Message-ID: <1412444425-2569-1-git-send-email-dev@lynxeye.de>

Ok, I got around to work a bit more on this. I now
actually finished the rtl8169 network driver, so
this series yields working PCI attached ethernet
on Tegra30 Beaver.

For Jetson K1 some work is left to setup the PHYs, but
that shouldn't be far out. 

While working on this I stumbled upon a few more issues,
so I decided to just roll the fixes into this series
and resend.

Lucas Stach (19):
  MIPS: malta: fix pci IO resource assignment
  pci: split out device init
  pci: add resource enum
  pci: properly populate prefetchable BARs
  pci: setup bridges and traverse buses behind them
  pci: defer device registration until after bridge setup
  pci: prettyprint device names
  pci: track parent<->child relationship
  commands: lspci: go down into subordinate busses
  clk: tegra: add PLLE setup functions
  clk: tegra30: add PCIe clocks
  i2c: tegra: move to fs initcall
  ARM: tegra: beaver: enable PEX voltage rail
  tegra: pmc: add powerdomain handling
  of: import pci range parser from linux
  pci: add Tegra host controller driver
  ARM: tegra: advertise PCI support
  net: add rtl8169 driver
  ARM: tegra: enable network related options in defconfig

 arch/arm/Kconfig                                   |    1 +
 arch/arm/boards/nvidia-beaver/board.c              |   13 +-
 arch/arm/configs/tegra_v7_defconfig                |    8 +
 arch/arm/mach-tegra/include/mach/tegra-powergate.h |   93 ++
 arch/arm/mach-tegra/include/mach/tegra20-car.h     |    2 +
 arch/arm/mach-tegra/include/mach/tegra30-car.h     |    2 +
 arch/arm/mach-tegra/tegra20-pmc.c                  |  139 ++-
 arch/mips/mach-malta/pci.c                         |    4 +-
 commands/lspci.c                                   |   25 +-
 drivers/clk/tegra/clk-pll.c                        |  116 ++
 drivers/clk/tegra/clk-tegra30.c                    |   31 +
 drivers/clk/tegra/clk.h                            |    6 +
 drivers/i2c/busses/i2c-tegra.c                     |    2 +-
 drivers/net/Kconfig                                |    8 +
 drivers/net/Makefile                               |    1 +
 drivers/net/rtl8169.c                              |  566 ++++++++++
 drivers/of/Kconfig                                 |    1 +
 drivers/of/address.c                               |   68 ++
 drivers/pci/Kconfig                                |    7 +
 drivers/pci/Makefile                               |    1 +
 drivers/pci/bus.c                                  |    3 +-
 drivers/pci/pci-tegra.c                            | 1193 ++++++++++++++++++++
 drivers/pci/pci.c                                  |  276 +++--
 include/linux/pci.h                                |    9 +
 include/linux/pci_regs.h                           |   28 +
 include/of_address.h                               |   57 +
 26 files changed, 2573 insertions(+), 87 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/tegra-powergate.h
 create mode 100644 drivers/net/rtl8169.c
 create mode 100644 drivers/pci/pci-tegra.c

-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:09 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:09 +0200
Subject: [PATCH v2 03/19] pci: add resource enum
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-4-git-send-email-dev@lynxeye.de>

Makes things way clearer than juggling numbers.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c   | 14 ++++++++------
 include/linux/pci.h |  6 ++++++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ef998dc..e9f0cb5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -41,15 +41,15 @@ void register_pci_controller(struct pci_controller *hose)
 	hose->bus = bus;
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
-	bus->resource[0] = hose->mem_resource;
-	bus->resource[1] = hose->io_resource;
+	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
+	bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
 	bus->number = bus_index++;
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
 
-	last_mem = bus->resource[0]->start;
-	last_io = bus->resource[1]->start;
+	last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+	last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
 
 	pci_scan_bus(bus);
 
@@ -141,7 +141,8 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 		if (mask & 0x01) { /* IO */
 			size = -(mask & 0xfffffffe);
 			DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
-			if (last_mem + size > dev->bus->resource[0]->end) {
+			if (last_io + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_IO]->end) {
 				DBG("BAR does not fit within bus IO res\n");
 				return;
 			}
@@ -152,7 +153,8 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 		} else { /* MEM */
 			size = -(mask & 0xfffffff0);
 			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
-			if (last_mem + size > dev->bus->resource[0]->end) {
+			if (last_mem + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
 				DBG("BAR does not fit within bus mem res\n");
 				return;
 			}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0ec1320..f5ef588 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -114,6 +114,12 @@ struct pci_dev {
 };
 #define	to_pci_dev(dev) container_of(dev, struct pci_dev, dev)
 
+enum {
+	PCI_BUS_RESOURCE_IO = 0,
+	PCI_BUS_RESOURCE_MEM = 1,
+	PCI_BUS_RESOURCE_MEM_PREF = 2,
+	PCI_BUS_RESOURCE_BUSN = 3,
+};
 struct pci_bus {
 	struct pci_controller *host;	/* associated host controller */
 	struct list_head node;		/* node in list of buses */
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:08 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:08 +0200
Subject: [PATCH v2 02/19] pci: split out device init
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-3-git-send-email-dev@lynxeye.de>

To make it reusable and the code more readable.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c | 137 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 74 insertions(+), 63 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a1b7680..ef998dc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -12,6 +12,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
 LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
 static u8 bus_index;
+static resource_size_t last_mem;
+static resource_size_t last_io;
 
 static struct pci_bus *pci_alloc_bus(void)
 {
@@ -45,6 +47,10 @@ void register_pci_controller(struct pci_controller *hose)
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
+
+	last_mem = bus->resource[0]->start;
+	last_io = bus->resource[1]->start;
+
 	pci_scan_bus(bus);
 
 	list_add_tail(&bus->node, &pci_root_buses);
@@ -111,27 +117,80 @@ static struct pci_dev *alloc_pci_dev(void)
 	return dev;
 }
 
+static void setup_device(struct pci_dev *dev, int max_bar)
+{
+	int bar, size;
+	u32 mask;
+	u8 cmd;
+
+	pci_read_config_byte(dev, PCI_COMMAND, &cmd);
+	pci_write_config_byte(dev, PCI_COMMAND,
+			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
+	for (bar = 0; bar < max_bar; bar++) {
+		resource_size_t last_addr;
+
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
+		pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
+
+		if (mask == 0 || mask == 0xffffffff) {
+			DBG("  PCI: pbar%d set bad mask\n", bar);
+			continue;
+		}
+
+		if (mask & 0x01) { /* IO */
+			size = -(mask & 0xfffffffe);
+			DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus IO res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
+			dev->resource[bar].flags = IORESOURCE_IO;
+			last_addr = last_io;
+			last_io += size;
+		} else { /* MEM */
+			size = -(mask & 0xfffffff0);
+			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus mem res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
+			dev->resource[bar].flags = IORESOURCE_MEM;
+			last_addr = last_mem;
+			last_mem += size;
+
+			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
+				dev->resource[bar].flags |= IORESOURCE_MEM_64;
+				pci_write_config_dword(dev,
+				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
+			}
+		}
+
+		dev->resource[bar].start = last_addr;
+		dev->resource[bar].end = last_addr + size - 1;
+		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
+			bar++;
+	}
+
+	pci_write_config_byte(dev, PCI_COMMAND, cmd);
+	list_add_tail(&dev->bus_list, &dev->bus->devices);
+	pci_register_device(dev);
+}
+
 unsigned int pci_scan_bus(struct pci_bus *bus)
 {
+	struct pci_dev *dev;
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
-	struct pci_dev *dev;
-	resource_size_t last_mem;
-	resource_size_t last_io;
-
-	/* FIXME: use res_start() */
-	last_mem = bus->resource[0]->start;
-	last_io = bus->resource[1]->start;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
 	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
 	max = bus->secondary;
 
 	for (devfn = 0; devfn < 0xff; ++devfn) {
-		int bar;
-		u32 old_bar, mask;
-		int size;
-
 		if (PCI_FUNC(devfn) && !is_multi) {
 			/* not a multi-function device */
 			continue;
@@ -169,6 +228,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		dev->hdr_type = hdr_type;
 
 		DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
+		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
+		    dev->vendor, dev->device);
 
 		switch (hdr_type & 0x7f) {		    /* header type */
 		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
@@ -181,6 +242,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			 */
 			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
 			dev->rom_address = (l == 0xffffffff) ? 0 : l;
+
+			setup_device(dev, 6);
 			break;
 		default:				    /* unknown header */
 		bad:
@@ -189,62 +252,10 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			continue;
 		}
 
-		DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
-
 		if (class == PCI_CLASS_BRIDGE_HOST) {
 			DBG("PCI: skip pci host bridge\n");
 			continue;
 		}
-
-		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
-		pci_write_config_byte(dev, PCI_COMMAND,
-				      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-
-		for (bar = 0; bar < 6; bar++) {
-			resource_size_t last_addr;
-
-			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &old_bar);
-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
-			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, old_bar);
-
-			if (mask == 0 || mask == 0xffffffff) {
-				DBG("  PCI: pbar%d set bad mask\n", bar);
-				continue;
-			}
-
-			if (mask & 0x01) { /* IO */
-				size = -(mask & 0xfffffffe);
-				DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
-				dev->resource[bar].flags = IORESOURCE_IO;
-				last_addr = last_io;
-				last_io += size;
-			} else { /* MEM */
-				size = -(mask & 0xfffffff0);
-				DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
-				dev->resource[bar].flags = IORESOURCE_MEM;
-				last_addr = last_mem;
-				last_mem += size;
-
-				if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-				    PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					dev->resource[bar].flags |= IORESOURCE_MEM_64;
-					pci_write_config_dword(dev,
-					       PCI_BASE_ADDRESS_1 + bar * 4, 0);
-				}
-			}
-
-			dev->resource[bar].start = last_addr;
-			dev->resource[bar].end = last_addr + size - 1;
-			if (dev->resource[bar].flags & IORESOURCE_MEM_64)
-				bar++;
-		}
-
-		pci_write_config_byte(dev, PCI_COMMAND, cmd);
-		list_add_tail(&dev->bus_list, &bus->devices);
-		pci_register_device(dev);
 	}
 
 	/*
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:18 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:18 +0200
Subject: [PATCH v2 12/19] i2c: tegra: move to fs initcall
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-13-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

i2c is needed to enable voltage rails that are later
needed by other drivers.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/boards/nvidia-beaver/board.c | 2 +-
 drivers/i2c/busses/i2c-tegra.c        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/nvidia-beaver/board.c b/arch/arm/boards/nvidia-beaver/board.c
index e87594d..e67d2aa 100644
--- a/arch/arm/boards/nvidia-beaver/board.c
+++ b/arch/arm/boards/nvidia-beaver/board.c
@@ -35,4 +35,4 @@ static int nvidia_beaver_devices_init(void)
 
 	return 0;
 }
-device_initcall(nvidia_beaver_devices_init);
+fs_initcall(nvidia_beaver_devices_init);
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index c52da18..f793cbe 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -696,4 +696,4 @@ static struct driver_d tegra_i2c_driver = {
 	.probe   = tegra_i2c_probe,
 	.of_compatible = DRV_OF_COMPAT(tegra_i2c_compatible),
 };
-device_platform_driver(tegra_i2c_driver);
+register_driver_macro(fs, platform, tegra_i2c_driver);
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:19 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:19 +0200
Subject: [PATCH v2 13/19] ARM: tegra: beaver: enable PEX voltage rail
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-14-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

Supply for the PCIe PLL.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/boards/nvidia-beaver/board.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boards/nvidia-beaver/board.c b/arch/arm/boards/nvidia-beaver/board.c
index e67d2aa..20707d8 100644
--- a/arch/arm/boards/nvidia-beaver/board.c
+++ b/arch/arm/boards/nvidia-beaver/board.c
@@ -15,8 +15,10 @@
  */
 
 #include <common.h>
-#include <init.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <gpio.h>
 #include <i2c/i2c.h>
+#include <init.h>
 
 static int nvidia_beaver_devices_init(void)
 {
@@ -33,6 +35,13 @@ static int nvidia_beaver_devices_init(void)
 	data = 0x65;
 	i2c_write_reg(&client, 0x32, &data, 1);
 
+	/* TPS659110: LDO1_REG = 1.05v, ACTIVE to PEX */
+	data = 0x15;
+	i2c_write_reg(&client, 0x30, &data, 1);
+
+	/* enable SYS_3V3_PEXS */
+	gpio_direction_output(TEGRA_GPIO(L, 7), 1);
+
 	return 0;
 }
 fs_initcall(nvidia_beaver_devices_init);
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:15 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:15 +0200
Subject: [PATCH v2 09/19] commands: lspci: go down into subordinate busses
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-10-git-send-email-dev@lynxeye.de>

This way we also list devices that are behind
bridges.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 commands/lspci.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/commands/lspci.c b/commands/lspci.c
index fdf0269..27edd5d 100644
--- a/commands/lspci.c
+++ b/commands/lspci.c
@@ -20,10 +20,24 @@
 #include <complete.h>
 #include <linux/pci.h>
 
+static void traverse_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		printf("%02x:%02x.%1x %04x: %04x:%04x (rev %02x)\n",
+		       dev->bus->number, PCI_SLOT(dev->devfn),
+		       PCI_FUNC(dev->devfn), (dev->class >> 8) & 0xffff,
+		       dev->vendor, dev->device, dev->revision);
+
+		if (dev->subordinate)
+			traverse_bus(dev->subordinate);
+	}
+}
+
 static int do_lspci(int argc, char *argv[])
 {
 	struct pci_bus *root_bus;
-	struct pci_dev *dev;
 
 	if (list_empty(&pci_root_buses)) {
 		printf("No PCI bus detected\n");
@@ -31,14 +45,7 @@ static int do_lspci(int argc, char *argv[])
 	}
 
 	list_for_each_entry(root_bus, &pci_root_buses, node) {
-		list_for_each_entry(dev, &root_bus->devices, bus_list) {
-			printf("%02x: %04x: %04x:%04x (rev %02x)\n",
-				      dev->devfn,
-				      (dev->class >> 8) & 0xffff,
-				      dev->vendor,
-				      dev->device,
-				      dev->revision);
-		}
+		traverse_bus(root_bus);
 	}
 
 	return 0;
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:13 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:13 +0200
Subject: [PATCH v2 07/19] pci: prettyprint device names
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-8-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/bus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 8215ee5..866ab08 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -86,7 +86,8 @@ int pci_register_device(struct pci_dev *pdev)
 	struct device_d *dev = &pdev->dev;
 	int ret;
 
-	strcpy(dev->name, "pci");
+	snprintf(dev->name, MAX_DRIVER_NAME, "pci-%04x:%04x.",
+	         pdev->vendor, pdev->device);
 	dev->bus = &pci_bus;
 	dev->id = DEVICE_ID_DYNAMIC;
 
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:14 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:14 +0200
Subject: [PATCH v2 08/19] pci: track parent<->child relationship
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-9-git-send-email-dev@lynxeye.de>

So that PCI devices hang down from bridges and root
bridges down from the PCI host controller when
calling devinfo.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c   | 4 ++++
 include/linux/pci.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 943d0e8..ba9d097 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -40,6 +40,7 @@ void register_pci_controller(struct pci_controller *hose)
 
 	bus = pci_alloc_bus();
 	hose->bus = bus;
+	bus->parent = hose->parent;
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
 	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
@@ -309,6 +310,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		dev->devfn = devfn;
 		dev->vendor = l & 0xffff;
 		dev->device = (l >> 16) & 0xffff;
+		dev->dev.parent = bus->parent;
 
 		/* non-destructively determine if device can be a master: */
 		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
@@ -354,6 +356,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 				bus->resource[PCI_BUS_RESOURCE_MEM_PREF];
 			child_bus->resource[PCI_BUS_RESOURCE_IO] =
 				bus->resource[PCI_BUS_RESOURCE_IO];
+
+			child_bus->parent = &dev->dev;
 			child_bus->number = bus_index++;
 			list_add_tail(&child_bus->node, &bus->children);
 			dev->subordinate = child_bus;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 932acf0..3d0e73b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -122,6 +122,7 @@ enum {
 };
 struct pci_bus {
 	struct pci_controller *host;	/* associated host controller */
+	struct device_d *parent;
 	struct list_head node;		/* node in list of buses */
 	struct list_head children;	/* list of child buses */
 	struct list_head devices;	/* list of devices on this bus */
@@ -158,6 +159,7 @@ extern struct pci_ops *pci_ops;
  */
 struct pci_controller {
 	struct pci_controller *next;
+	struct device_d *parent;
 	struct pci_bus *bus;
 
 	struct pci_ops *pci_ops;
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:17 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:17 +0200
Subject: [PATCH v2 11/19] clk: tegra30: add PCIe clocks
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-12-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/mach-tegra/include/mach/tegra20-car.h |  2 ++
 drivers/clk/tegra/clk-tegra30.c                | 31 ++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/arch/arm/mach-tegra/include/mach/tegra20-car.h b/arch/arm/mach-tegra/include/mach/tegra20-car.h
index 161e3d8..5a35f21 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-car.h
@@ -49,6 +49,8 @@
 #define CRC_CLK_OUT_ENB_H		0x014
 #define CRC_CLK_OUT_ENB_H_DVC		(1 << 15)
 
+#define CRC_CLK_OUT_ENB_U		0x018
+
 #define CRC_CCLK_BURST_POLICY		0x020
 #define CRC_CCLK_BURST_POLICY_SYS_STATE_SHIFT	28
 #define CRC_CCLK_BURST_POLICY_SYS_STATE_FIQ	8
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index ed6d736..9997ab9 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -130,6 +130,13 @@ static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
 	{ 0, 0, 0, 0, 0, 0 },
 };
 
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+	/* PLLE special case: use cpcon field to store cml divider value */
+	{ 12000000,  100000000, 150, 1,  18, 11},
+	{ 216000000, 100000000, 200, 18, 24, 13},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
 /* PLL parameters */
 static struct tegra_clk_pll_params pll_c_params = {
 	.input_min = 2000000,
@@ -201,6 +208,19 @@ static struct tegra_clk_pll_params pll_u_params = {
 	.lock_delay = 1000,
 };
 
+static struct tegra_clk_pll_params pll_e_params = {
+	.input_min = 12000000,
+	.input_max = 216000000,
+	.cf_min = 12000000,
+	.cf_max = 12000000,
+	.vco_min = 1200000000,
+	.vco_max = 2400000000U,
+	.base_reg = CRC_PLLE_BASE,
+	.misc_reg = CRC_PLLE_MISC,
+	.lock_enable_bit_idx = CRC_PLLE_MISC_LOCK_ENABLE,
+	.lock_delay = 300,
+};
+
 static void tegra30_pll_init(void)
 {
 	/* PLLC */
@@ -251,6 +271,11 @@ static void tegra30_pll_init(void)
 	clks[TEGRA30_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref",
 			car_base, 0, 0, &pll_u_params, TEGRA_PLLU |
 			TEGRA_PLL_HAS_CPCON, pll_u_freq_table);
+
+	/* PLLE */
+	clks[TEGRA30_CLK_PLL_E] = tegra_clk_register_plle("pll_e", "pll_ref",
+			car_base, 0, 100000000, &pll_e_params,
+			TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, pll_e_freq_table);
 }
 
 static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"};
@@ -278,6 +303,12 @@ static void tegra30_periph_init(void)
 			mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base,
 			CRC_CLK_SOURCE_UARTE, TEGRA30_CLK_UARTE,
 			TEGRA_PERIPH_ON_APB);
+	clks[TEGRA30_CLK_PCIE] = clk_gate("pcie", "clk_m",
+			car_base + CRC_CLK_OUT_ENB_U, 6, 0, 0);
+	clks[TEGRA30_CLK_AFI] = clk_gate("afi", "clk_m",
+			car_base + CRC_CLK_OUT_ENB_U, 8, 0, 0);
+	clks[TEGRA30_CLK_CML0] = clk_gate("cml0", "pll_e",
+			car_base + CRC_PLLE_AUX, 0, 0, 0);
 
 	/* peripheral clocks with a divider */
 	clks[TEGRA30_CLK_MSELECT] = tegra_clk_register_periph("mselect",
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:10 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:10 +0200
Subject: [PATCH v2 04/19] pci: properly populate prefetchable BARs
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-5-git-send-email-dev@lynxeye.de>

Some host controllers provide a prefetchable
memory area and devices will prefer this for
some of their BARs.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c   | 59 ++++++++++++++++++++++++++++++++++++++++-------------
 include/linux/pci.h |  1 +
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e9f0cb5..115d8a3 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -13,6 +13,7 @@ LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
 static u8 bus_index;
 static resource_size_t last_mem;
+static resource_size_t last_mem_pref;
 static resource_size_t last_io;
 
 static struct pci_bus *pci_alloc_bus(void)
@@ -42,14 +43,27 @@ void register_pci_controller(struct pci_controller *hose)
 	bus->host = hose;
 	bus->ops = hose->pci_ops;
 	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
+	bus->resource[PCI_BUS_RESOURCE_MEM_PREF] = hose->mem_pref_resource;
 	bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
 	bus->number = bus_index++;
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
 
-	last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
-	last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+	if (bus->resource[PCI_BUS_RESOURCE_MEM])
+		last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+	else
+		last_mem = 0;
+
+	if (bus->resource[PCI_BUS_RESOURCE_MEM])
+		last_mem_pref = bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->start;
+	else
+		last_mem_pref = 0;
+
+	if (bus->resource[PCI_BUS_RESOURCE_IO])
+		last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+	else
+		last_io = 0;
 
 	pci_scan_bus(bus);
 
@@ -150,31 +164,46 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 			dev->resource[bar].flags = IORESOURCE_IO;
 			last_addr = last_io;
 			last_io += size;
-		} else { /* MEM */
+		} else if ((mask & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+		           last_mem_pref) /* prefetchable MEM */ {
 			size = -(mask & 0xfffffff0);
-			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+			DBG("  PCI: pbar%d: mask=%08x P memory %d bytes\n",
+			    bar, mask, size);
+			if (last_mem_pref + size >
+			    dev->bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->end) {
+				DBG("BAR does not fit within bus p-mem res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem_pref);
+			dev->resource[bar].flags = IORESOURCE_MEM |
+			                           IORESOURCE_PREFETCH;
+			last_addr = last_mem_pref;
+			last_mem_pref += size;
+		} else { /* non-prefetch MEM */
+			size = -(mask & 0xfffffff0);
+			DBG("  PCI: pbar%d: mask=%08x NP memory %d bytes\n",
+			    bar, mask, size);
 			if (last_mem + size >
 			    dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
-				DBG("BAR does not fit within bus mem res\n");
+				DBG("BAR does not fit within bus np-mem res\n");
 				return;
 			}
 			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
 			dev->resource[bar].flags = IORESOURCE_MEM;
 			last_addr = last_mem;
 			last_mem += size;
-
-			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
-				dev->resource[bar].flags |= IORESOURCE_MEM_64;
-				pci_write_config_dword(dev,
-				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
-			}
 		}
 
 		dev->resource[bar].start = last_addr;
 		dev->resource[bar].end = last_addr + size - 1;
-		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
+
+		if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+		    PCI_BASE_ADDRESS_MEM_TYPE_64) {
+			dev->resource[bar].flags |= IORESOURCE_MEM_64;
+			pci_write_config_dword(dev,
+			       PCI_BASE_ADDRESS_1 + bar * 4, 0);
 			bar++;
+		}
 	}
 
 	pci_write_config_byte(dev, PCI_COMMAND, cmd);
@@ -189,7 +218,9 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
-	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
+	DBG(" last_io = 0x%08x, last_mem = 0x%08x, last_mem_pref = 0x%08x\n",
+	    last_io, last_mem, last_mem_pref);
+
 	max = bus->secondary;
 
 	for (devfn = 0; devfn < 0xff; ++devfn) {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f5ef588..932acf0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -162,6 +162,7 @@ struct pci_controller {
 
 	struct pci_ops *pci_ops;
 	struct resource *mem_resource;
+	struct resource *mem_pref_resource;
 	unsigned long mem_offset;
 	struct resource *io_resource;
 	unsigned long io_offset;
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:23 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:23 +0200
Subject: [PATCH v2 17/19] ARM: tegra: advertise PCI support
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-18-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/Kconfig                    | 1 +
 arch/arm/configs/tegra_v7_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3c9b81a..2a00e5e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -198,6 +198,7 @@ config ARCH_TEGRA
 	bool "NVIDIA Tegra"
 	select CPU_V7
 	select HAS_DEBUG_LL
+	select HW_HAS_PCI
 	select COMMON_CLK
 	select COMMON_CLK_OF_PROVIDER
 	select CLKDEV_LOOKUP
diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig
index 22f5765..8f01b54 100644
--- a/arch/arm/configs/tegra_v7_defconfig
+++ b/arch/arm/configs/tegra_v7_defconfig
@@ -37,6 +37,7 @@ CONFIG_DRIVER_SERIAL_NS16550=y
 CONFIG_MCI=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_TEGRA=y
+CONFIG_PCI_TEGRA=y
 CONFIG_FS_EXT4=y
 CONFIG_FS_FAT=y
 CONFIG_FS_FAT_LFN=y
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:11 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:11 +0200
Subject: [PATCH v2 05/19] pci: setup bridges and traverse buses behind them
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-6-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c        | 92 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/pci_regs.h | 28 +++++++++++++++
 2 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 115d8a3..59f942d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -211,9 +211,73 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 	pci_register_device(dev);
 }
 
+static void prescan_setup_bridge(struct pci_dev *dev)
+{
+	u16 cmdstat;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmdstat);
+
+	/* Configure bus number registers */
+	pci_write_config_byte(dev, PCI_PRIMARY_BUS, dev->bus->number);
+	pci_write_config_byte(dev, PCI_SECONDARY_BUS, dev->subordinate->number);
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, 0xff);
+
+	if (last_mem) {
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_write_config_word(dev, PCI_MEMORY_BASE,
+				      (last_mem & 0xfff00000) >> 16);
+		cmdstat |= PCI_COMMAND_MEMORY;
+	}
+
+	if (last_mem_pref) {
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
+				      (last_mem_pref & 0xfff00000) >> 16);
+		cmdstat |= PCI_COMMAND_MEMORY;
+	} else {
+
+		/* We don't support prefetchable memory for now, so disable */
+		pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x1000);
+		pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0x0);
+	}
+
+	if (last_io) {
+		pci_write_config_byte(dev, PCI_IO_BASE,
+				      (last_io & 0x0000f000) >> 8);
+		pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+				      (last_io & 0xffff0000) >> 16);
+		cmdstat |= PCI_COMMAND_IO;
+	}
+
+	/* Enable memory and I/O accesses, enable bus master */
+	pci_write_config_word(dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+static void postscan_setup_bridge(struct pci_dev *dev)
+{
+	/* limit subordinate to last used bus number */
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, bus_index - 1);
+
+	if (last_mem)
+		pci_write_config_word(dev, PCI_MEMORY_LIMIT,
+				      ((last_mem - 1) & 0xfff00000) >> 16);
+
+	if (last_mem_pref)
+		pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
+				      ((last_mem_pref - 1) & 0xfff00000) >> 16);
+
+	if (last_io) {
+		pci_write_config_byte(dev, PCI_IO_LIMIT,
+				((last_io - 1) & 0x0000f000) >> 8);
+		pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+				((last_io - 1) & 0xffff0000) >> 16);
+	}
+}
+
 unsigned int pci_scan_bus(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
+	struct pci_bus *child_bus;
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
 
@@ -264,8 +328,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
 		    dev->vendor, dev->device);
 
-		switch (hdr_type & 0x7f) {		    /* header type */
-		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
+		switch (hdr_type & 0x7f) {
+		case PCI_HEADER_TYPE_NORMAL:
 			if (class == PCI_CLASS_BRIDGE_PCI)
 				goto bad;
 
@@ -278,7 +342,28 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 
 			setup_device(dev, 6);
 			break;
-		default:				    /* unknown header */
+		case PCI_HEADER_TYPE_BRIDGE:
+			setup_device(dev, 2);
+
+			child_bus = pci_alloc_bus();
+			/* inherit parent properties */
+			child_bus->host = bus->host;
+			child_bus->ops = bus->host->pci_ops;
+			child_bus->resource[PCI_BUS_RESOURCE_MEM] =
+				bus->resource[PCI_BUS_RESOURCE_MEM];
+			child_bus->resource[PCI_BUS_RESOURCE_MEM_PREF] =
+				bus->resource[PCI_BUS_RESOURCE_MEM_PREF];
+			child_bus->resource[PCI_BUS_RESOURCE_IO] =
+				bus->resource[PCI_BUS_RESOURCE_IO];
+			child_bus->number = bus_index++;
+			list_add_tail(&child_bus->node, &bus->children);
+			dev->subordinate = child_bus;
+
+			prescan_setup_bridge(dev);
+			pci_scan_bus(child_bus);
+			postscan_setup_bridge(dev);
+			break;
+		default:
 		bad:
 			printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
 			       bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
@@ -298,6 +383,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 	 *
 	 * Return how far we've got finding sub-buses.
 	 */
+	max = bus_index;
 	DBG("PCI: pci_scan_bus returning with max=%02x\n", max);
 
 	return max;
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 14a3ed3..8669fc7 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -107,4 +107,32 @@
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
 #define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
 
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS		0x18	/* Primary bus number */
+#define PCI_SECONDARY_BUS	0x19	/* Secondary bus number */
+#define PCI_SUBORDINATE_BUS	0x1a	/* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER	0x1b	/* Latency timer for secondary interface */
+#define PCI_IO_BASE		0x1c	/* I/O range behind the bridge */
+#define PCI_IO_LIMIT		0x1d
+#define  PCI_IO_RANGE_TYPE_MASK	0x0fUL	/* I/O bridging type */
+#define  PCI_IO_RANGE_TYPE_16	0x00
+#define  PCI_IO_RANGE_TYPE_32	0x01
+#define  PCI_IO_RANGE_MASK	(~0x0fUL) /* Standard 4K I/O windows */
+#define  PCI_IO_1K_RANGE_MASK	(~0x03UL) /* Intel 1K I/O windows */
+#define PCI_SEC_STATUS		0x1e	/* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE		0x20	/* Memory range behind */
+#define PCI_MEMORY_LIMIT	0x22
+#define  PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_MEMORY_RANGE_MASK	(~0x0fUL)
+#define PCI_PREF_MEMORY_BASE	0x24	/* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT	0x26
+#define  PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define  PCI_PREF_RANGE_TYPE_32	0x00
+#define  PCI_PREF_RANGE_TYPE_64	0x01
+#define  PCI_PREF_RANGE_MASK	(~0x0fUL)
+#define PCI_PREF_BASE_UPPER32	0x28	/* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32	0x2c
+#define PCI_IO_BASE_UPPER16	0x30	/* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16	0x32
+
 #endif /* LINUX_PCI_REGS_H */
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:16 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:16 +0200
Subject: [PATCH v2 10/19] clk: tegra: add PLLE setup functions
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-11-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/mach-tegra/include/mach/tegra30-car.h |   2 +
 drivers/clk/tegra/clk-pll.c                    | 116 +++++++++++++++++++++++++
 drivers/clk/tegra/clk.h                        |   6 ++
 3 files changed, 124 insertions(+)

diff --git a/arch/arm/mach-tegra/include/mach/tegra30-car.h b/arch/arm/mach-tegra/include/mach/tegra30-car.h
index c8f6c9f..7fb2238 100644
--- a/arch/arm/mach-tegra/include/mach/tegra30-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra30-car.h
@@ -33,3 +33,5 @@
 #define CRC_RST_DEV_V_CLR		0x434
 
 #define CRC_CLK_OUT_ENB_V_SET		0x440
+
+#define CRC_PLLE_AUX			0x48c
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index c18c67f..bff5651 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -17,12 +17,15 @@
  */
 
 #include <common.h>
+#include <clock.h>
 #include <io.h>
 #include <malloc.h>
 #include <asm-generic/div64.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 
+#include <mach/iomap.h>
+
 #include "clk.h"
 
 #define PLL_BASE_BYPASS		BIT(31)
@@ -393,6 +396,108 @@ const struct clk_ops tegra_clk_pll_ops = {
 	.set_rate = clk_pll_set_rate,
 };
 
+static unsigned long clk_plle_recalc_rate(struct clk *hw,
+					 unsigned long parent_rate)
+{
+	struct tegra_clk_pll *pll = to_clk_pll(hw);
+	u32 val = pll_readl_base(pll);
+	u32 divn = 0, divm = 0, divp = 0;
+	u64 rate = parent_rate;
+
+	divp = (val >> 16) & 0x3f;
+	divn = (val >> 8) & (0xff);
+	divm = (val >> 0) & (0xff);
+	divm *= divp;
+
+	rate *= divn;
+	do_div(rate, divm);
+	return rate;
+}
+
+static int clk_plle_training(struct tegra_clk_pll *pll)
+{
+	u32 val;
+
+	/*
+	 * PLLE is already disabled, and setup cleared;
+	 * create falling edge on PLLE IDDQ input.
+	 */
+	val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+	val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+	writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+	val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+	val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+	writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+	val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+	val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+	writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+	return wait_on_timeout(100 * MSECOND,
+			(pll_readl_misc(pll) & PLLE_MISC_READY));
+}
+
+static int clk_plle_enable(struct clk *hw)
+{
+	struct tegra_clk_pll *pll = to_clk_pll(hw);
+	unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+	struct tegra_clk_pll_freq_table sel;
+	u32 val;
+	int err;
+
+	if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+		return -EINVAL;
+
+	clk_pll_disable(hw);
+
+	val = pll_readl_misc(pll);
+	val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+	pll_writel_misc(val, pll);
+
+	val = pll_readl_misc(pll);
+	if (!(val & PLLE_MISC_READY)) {
+		err = clk_plle_training(pll);
+		if (err)
+			return err;
+	}
+
+	/* configure dividers */
+	val = pll_readl_base(pll);
+	val &= ~(0x3fffff);
+	val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
+	val |= sel.m << 0;
+	val |= sel.n << 8;
+	val |= sel.p << 16;
+	val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+	pll_writel_base(val, pll);
+
+	val = pll_readl_misc(pll);
+	val |= PLLE_MISC_SETUP_VALUE;
+	val |= PLLE_MISC_LOCK_ENABLE;
+	pll_writel_misc(val, pll);
+
+	val = readl(pll->clk_base + PLLE_SS_CTRL);
+	val |= PLLE_SS_DISABLE;
+	writel(val, pll->clk_base + PLLE_SS_CTRL);
+
+	val = pll_readl_base(pll);
+	val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+	pll_writel_base(val, pll);
+
+	clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
+			      pll->params->lock_bit_idx);
+
+	return 0;
+}
+
+const struct clk_ops tegra_clk_plle_ops = {
+	.recalc_rate = clk_plle_recalc_rate,
+	.is_enabled = clk_pll_is_enabled,
+	.disable = clk_pll_disable,
+	.enable = clk_plle_enable,
+};
+
 static struct clk *_tegra_clk_register_pll(const char *name,
 		const char *parent_name, void __iomem *clk_base,
 		unsigned long flags, unsigned long fixed_rate,
@@ -447,3 +552,14 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
 			flags, fixed_rate, pll_params, pll_flags, freq_table,
 			&tegra_clk_pll_ops);
 }
+
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+		void __iomem *clk_base,
+		unsigned long flags, unsigned long fixed_rate,
+		struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+		struct tegra_clk_pll_freq_table *freq_table)
+{
+	return _tegra_clk_register_pll(name, parent_name, clk_base,
+			flags, fixed_rate, pll_params, pll_flags, freq_table,
+			&tegra_clk_plle_ops);
+}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index d5d0730..85777a8 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -101,6 +101,12 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
 		struct tegra_clk_pll_params *pll_params, u8 pll_flags,
 		struct tegra_clk_pll_freq_table *freq_table);
 
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+		void __iomem *clk_base,
+		unsigned long flags, unsigned long fixed_rate,
+		struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+		struct tegra_clk_pll_freq_table *freq_table);
+
 /* struct tegra_clk_pll_out - PLL output divider */
 struct tegra_clk_pll_out {
 	struct clk	hw;
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:20 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:20 +0200
Subject: [PATCH v2 14/19] tegra: pmc: add powerdomain handling
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-15-git-send-email-dev@lynxeye.de>

From: Lucas Stach <l.stach at pengutronix.de>

In order to use some devices we first have to power
up their power domain. Add support to do this in a
generic way.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/mach-tegra/include/mach/tegra-powergate.h |  93 ++++++++++++++
 arch/arm/mach-tegra/tegra20-pmc.c                  | 139 ++++++++++++++++++++-
 2 files changed, 229 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/tegra-powergate.h

diff --git a/arch/arm/mach-tegra/include/mach/tegra-powergate.h b/arch/arm/mach-tegra/include/mach/tegra-powergate.h
new file mode 100644
index 0000000..e32250a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra-powergate.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ *	Colin Cross <ccross at google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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_TEGRA_POWERGATE_H_
+#define _MACH_TEGRA_POWERGATE_H_
+
+struct clk;
+struct reset_control;
+
+#define TEGRA_POWERGATE_CPU	0
+#define TEGRA_POWERGATE_3D	1
+#define TEGRA_POWERGATE_VENC	2
+#define TEGRA_POWERGATE_PCIE	3
+#define TEGRA_POWERGATE_VDEC	4
+#define TEGRA_POWERGATE_L2	5
+#define TEGRA_POWERGATE_MPE	6
+#define TEGRA_POWERGATE_HEG	7
+#define TEGRA_POWERGATE_SATA	8
+#define TEGRA_POWERGATE_CPU1	9
+#define TEGRA_POWERGATE_CPU2	10
+#define TEGRA_POWERGATE_CPU3	11
+#define TEGRA_POWERGATE_CELP	12
+#define TEGRA_POWERGATE_3D1	13
+#define TEGRA_POWERGATE_CPU0	14
+#define TEGRA_POWERGATE_C0NC	15
+#define TEGRA_POWERGATE_C1NC	16
+#define TEGRA_POWERGATE_SOR	17
+#define TEGRA_POWERGATE_DIS	18
+#define TEGRA_POWERGATE_DISB	19
+#define TEGRA_POWERGATE_XUSBA	20
+#define TEGRA_POWERGATE_XUSBB	21
+#define TEGRA_POWERGATE_XUSBC	22
+#define TEGRA_POWERGATE_VIC	23
+#define TEGRA_POWERGATE_IRAM	24
+
+#define TEGRA_POWERGATE_3D0	TEGRA_POWERGATE_3D
+
+#define TEGRA_IO_RAIL_CSIA	0
+#define TEGRA_IO_RAIL_CSIB	1
+#define TEGRA_IO_RAIL_DSI	2
+#define TEGRA_IO_RAIL_MIPI_BIAS	3
+#define TEGRA_IO_RAIL_PEX_BIAS	4
+#define TEGRA_IO_RAIL_PEX_CLK1	5
+#define TEGRA_IO_RAIL_PEX_CLK2	6
+#define TEGRA_IO_RAIL_USB0	9
+#define TEGRA_IO_RAIL_USB1	10
+#define TEGRA_IO_RAIL_USB2	11
+#define TEGRA_IO_RAIL_USB_BIAS	12
+#define TEGRA_IO_RAIL_NAND	13
+#define TEGRA_IO_RAIL_UART	14
+#define TEGRA_IO_RAIL_BB	15
+#define TEGRA_IO_RAIL_AUDIO	17
+#define TEGRA_IO_RAIL_HSIC	19
+#define TEGRA_IO_RAIL_COMP	22
+#define TEGRA_IO_RAIL_HDMI	28
+#define TEGRA_IO_RAIL_PEX_CNTRL	32
+#define TEGRA_IO_RAIL_SDMMC1	33
+#define TEGRA_IO_RAIL_SDMMC3	34
+#define TEGRA_IO_RAIL_SDMMC4	35
+#define TEGRA_IO_RAIL_CAM	36
+#define TEGRA_IO_RAIL_RES	37
+#define TEGRA_IO_RAIL_HV	38
+#define TEGRA_IO_RAIL_DSIB	39
+#define TEGRA_IO_RAIL_DSIC	40
+#define TEGRA_IO_RAIL_DSID	41
+#define TEGRA_IO_RAIL_CSIE	44
+#define TEGRA_IO_RAIL_LVDS	57
+#define TEGRA_IO_RAIL_SYS_DDC	58
+
+int tegra_powergate_is_powered(int id);
+int tegra_powergate_power_on(int id);
+int tegra_powergate_power_off(int id);
+int tegra_powergate_remove_clamping(int id);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+				      struct reset_control *rst);
+
+#endif /* _MACH_TEGRA_POWERGATE_H_ */
diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
index d868094..4cd01ff 100644
--- a/arch/arm/mach-tegra/tegra20-pmc.c
+++ b/arch/arm/mach-tegra/tegra20-pmc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Lucas Stach <l.stach at pengutronix.de>
+ * Copyright (C) 2013-2014 Lucas Stach <l.stach at pengutronix.de>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -19,15 +19,19 @@
  * @brief Device driver for the Tegra 20 power management controller.
  */
 
-#include <common.h>
 #include <command.h>
+#include <common.h>
 #include <init.h>
 #include <io.h>
 #include <linux/err.h>
-
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <mach/lowlevel.h>
+#include <mach/tegra-powergate.h>
 #include <mach/tegra20-pmc.h>
 
 static void __iomem *pmc_base;
+static int tegra_num_powerdomains;
 
 /* main SoC reset trigger */
 void __noreturn reset_cpu(ulong addr)
@@ -38,6 +42,133 @@ void __noreturn reset_cpu(ulong addr)
 }
 EXPORT_SYMBOL(reset_cpu);
 
+static int tegra_powergate_set(int id, bool new_state)
+{
+	bool status;
+
+	status = readl(pmc_base + PMC_PWRGATE_STATUS) & (1 << id);
+
+	if (status == new_state) {
+		return 0;
+	}
+
+	writel(PMC_PWRGATE_TOGGLE_START | id, pmc_base + PMC_PWRGATE_TOGGLE);
+
+	return 0;
+}
+
+int tegra_powergate_power_on(int id)
+{
+	if (id < 0 || id >= tegra_num_powerdomains)
+		return -EINVAL;
+
+	return tegra_powergate_set(id, true);
+}
+
+int tegra_powergate_power_off(int id)
+{
+	if (id < 0 || id >= tegra_num_powerdomains)
+		return -EINVAL;
+
+	return tegra_powergate_set(id, false);
+}
+EXPORT_SYMBOL(tegra_powergate_power_off);
+
+int tegra_powergate_is_powered(int id)
+{
+	u32 status;
+
+	if (id < 0 || id >= tegra_num_powerdomains)
+		return -EINVAL;
+
+	status = readl(pmc_base + PMC_PWRGATE_STATUS) & (1 << id);
+	return !!status;
+}
+
+int tegra_powergate_remove_clamping(int id)
+{
+	u32 mask;
+
+	if (id < 0 || id >= tegra_num_powerdomains)
+		return -EINVAL;
+
+	/*
+	 * Tegra 2 has a bug where PCIE and VDE clamping masks are
+	 * swapped relatively to the partition ids
+	 */
+	if (id == TEGRA_POWERGATE_VDEC)
+		mask = (1 << TEGRA_POWERGATE_PCIE);
+	else if (id == TEGRA_POWERGATE_PCIE)
+		mask = (1 << TEGRA_POWERGATE_VDEC);
+	else
+		mask = (1 << id);
+
+	writel(mask, pmc_base + PMC_REMOVE_CLAMPING_CMD);
+
+	return 0;
+}
+EXPORT_SYMBOL(tegra_powergate_remove_clamping);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+					struct reset_control *rst)
+{
+	int ret;
+
+	reset_control_assert(rst);
+
+	ret = tegra_powergate_power_on(id);
+	if (ret)
+		goto err_power;
+
+	ret = clk_enable(clk);
+	if (ret)
+		goto err_clk;
+
+	udelay(10);
+
+	ret = tegra_powergate_remove_clamping(id);
+	if (ret)
+		goto err_clamp;
+
+	udelay(10);
+	reset_control_deassert(rst);
+
+	return 0;
+
+err_clamp:
+	clk_disable(clk);
+err_clk:
+	tegra_powergate_power_off(id);
+err_power:
+	return ret;
+}
+EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
+
+static int tegra_powergate_init(void)
+{
+	switch (tegra_get_chiptype()) {
+	case TEGRA20:
+		tegra_num_powerdomains = 7;
+		break;
+	case TEGRA30:
+		tegra_num_powerdomains = 14;
+		break;
+	case TEGRA114:
+		tegra_num_powerdomains = 23;
+		break;
+	case TEGRA124:
+		tegra_num_powerdomains = 25;
+		break;
+	default:
+		/* Unknown Tegra variant. Disable powergating */
+		tegra_num_powerdomains = 0;
+		break;
+	}
+
+	return 0;
+}
+
 static int tegra20_pmc_probe(struct device_d *dev)
 {
 	pmc_base = dev_request_mem_region(dev, 0);
@@ -46,6 +177,8 @@ static int tegra20_pmc_probe(struct device_d *dev)
 		return PTR_ERR(pmc_base);
 	}
 
+	tegra_powergate_init();
+
 	return 0;
 }
 
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:21 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:21 +0200
Subject: [PATCH v2 15/19] of: import pci range parser from linux
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-16-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/of/Kconfig   |  1 +
 drivers/of/address.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of_address.h | 57 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 97a1d93..97378ab 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -30,6 +30,7 @@ config OF_GPIO
 config OF_PCI
 	bool
 	depends on PCI
+	select OF_ADDRESS_PCI
 	help
 	  OpenFirmware PCI bus accessors
 
diff --git a/drivers/of/address.c b/drivers/of/address.c
index b3cbb15..8018d78 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -179,6 +179,74 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
 }
 #endif /* CONFIG_OF_ADDRESS_PCI */
 
+#ifdef CONFIG_OF_PCI
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+				struct device_node *node)
+{
+	const int na = 3, ns = 2;
+	int rlen;
+
+	parser->node = node;
+	parser->pna = of_n_addr_cells(node);
+	parser->np = parser->pna + na + ns;
+
+	parser->range = of_get_property(node, "ranges", &rlen);
+	if (parser->range == NULL)
+		return -ENOENT;
+
+	parser->end = parser->range + rlen / sizeof(__be32);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+						struct of_pci_range *range)
+{
+	const int na = 3, ns = 2;
+
+	if (!range)
+		return NULL;
+
+	if (!parser->range || parser->range + parser->np > parser->end)
+		return NULL;
+
+	range->pci_space = parser->range[0];
+	range->flags = of_bus_pci_get_flags(parser->range);
+	range->pci_addr = of_read_number(parser->range + 1, ns);
+	range->cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+	range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+	parser->range += parser->np;
+
+	/* Now consume following elements while they are contiguous */
+	while (parser->range + parser->np <= parser->end) {
+		u32 flags, pci_space;
+		u64 pci_addr, cpu_addr, size;
+
+		pci_space = be32_to_cpup(parser->range);
+		flags = of_bus_pci_get_flags(parser->range);
+		pci_addr = of_read_number(parser->range + 1, ns);
+		cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+		size = of_read_number(parser->range + parser->pna + na, ns);
+
+		if (flags != range->flags)
+			break;
+		if (pci_addr != range->pci_addr + range->size ||
+		    cpu_addr != range->cpu_addr + range->size)
+			break;
+
+		range->size += size;
+		parser->range += parser->np;
+	}
+
+	return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+#endif /* CONFIG_OF_PCI */
+
 /*
  * Array of bus specific translators
  */
diff --git a/include/of_address.h b/include/of_address.h
index 9022ab7..ebf3ec2 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -4,6 +4,38 @@
 #include <common.h>
 #include <of.h>
 
+struct of_pci_range_parser {
+	struct device_node *node;
+	const __be32 *range;
+	const __be32 *end;
+	int np;
+	int pna;
+};
+
+struct of_pci_range {
+	u32 pci_space;
+	u64 pci_addr;
+	u64 cpu_addr;
+	u64 size;
+	u32 flags;
+};
+
+#define for_each_of_pci_range(parser, range) \
+	for (; of_pci_range_parser_one(parser, range);)
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+					    struct device_node *np,
+					    struct resource *res)
+{
+	res->flags = range->flags;
+	res->start = range->cpu_addr;
+	res->end = range->cpu_addr + range->size - 1;
+	res->parent = NULL;
+	INIT_LIST_HEAD(&res->children);
+	INIT_LIST_HEAD(&res->sibling);
+	res->name = np->full_name;
+}
+
 #ifndef pci_address_to_pio
 static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #endif
@@ -69,4 +101,29 @@ static inline void __iomem *of_iomap(struct device_node *np, int index)
 
 #endif /* CONFIG_OFTREE */
 
+#ifdef CONFIG_OF_PCI
+
+extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+			struct device_node *node);
+
+extern struct of_pci_range *of_pci_range_parser_one(
+			struct of_pci_range_parser *parser,
+			struct of_pci_range *range);
+
+#else
+
+static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+			struct device_node *node)
+{
+	return -1;
+}
+
+static inline struct of_pci_range *of_pci_range_parser_one(
+					struct of_pci_range_parser *parser,
+					struct of_pci_range *range)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF_PCI */
+
 #endif /* __OF_ADDRESS_H */
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:22 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:22 +0200
Subject: [PATCH v2 16/19] pci: add Tegra host controller driver
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-17-git-send-email-dev@lynxeye.de>

Only tested on Tegra30 for now.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/Kconfig     |    7 +
 drivers/pci/Makefile    |    1 +
 drivers/pci/pci-tegra.c | 1193 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1201 insertions(+)
 create mode 100644 drivers/pci/pci-tegra.c

diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index d17a151..0e9308e 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -30,6 +30,13 @@ config PCI_MVEBU
 	select OF_PCI
 	select PCI
 
+config PCI_TEGRA
+	bool "NVDIA Tegra PCIe driver"
+	depends on ARCH_TEGRA
+	select OF_ADDRESS_PCI
+	select OF_PCI
+	select PCI
+
 endmenu
 
 endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 4423531..b93b28a 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -8,3 +8,4 @@ ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 CPPFLAGS += $(ccflags-y)
 
 obj-$(CONFIG_PCI_MVEBU)	+= pci-mvebu.o pci-mvebu-phy.o
+obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
diff --git a/drivers/pci/pci-tegra.c b/drivers/pci/pci-tegra.c
new file mode 100644
index 0000000..07bb251
--- /dev/null
+++ b/drivers/pci/pci-tegra.c
@@ -0,0 +1,1193 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach at pengutronix.de>
+ *
+ * based on code
+ * Copyright (c) 2010, CompuLab, Ltd.
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <malloc.h>
+#include <io.h>
+#include <init.h>
+#include <asm/mmu.h>
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <of_address.h>
+#include <of_pci.h>
+#include <linux/pci.h>
+#include <linux/reset.h>
+#include <sizes.h>
+#include <mach/tegra-powergate.h>
+#include <regulator.h>
+
+/* register definitions */
+
+#define AFI_AXI_BAR0_SZ	0x00
+#define AFI_AXI_BAR1_SZ	0x04
+#define AFI_AXI_BAR2_SZ	0x08
+#define AFI_AXI_BAR3_SZ	0x0c
+#define AFI_AXI_BAR4_SZ	0x10
+#define AFI_AXI_BAR5_SZ	0x14
+
+#define AFI_AXI_BAR0_START	0x18
+#define AFI_AXI_BAR1_START	0x1c
+#define AFI_AXI_BAR2_START	0x20
+#define AFI_AXI_BAR3_START	0x24
+#define AFI_AXI_BAR4_START	0x28
+#define AFI_AXI_BAR5_START	0x2c
+
+#define AFI_FPCI_BAR0	0x30
+#define AFI_FPCI_BAR1	0x34
+#define AFI_FPCI_BAR2	0x38
+#define AFI_FPCI_BAR3	0x3c
+#define AFI_FPCI_BAR4	0x40
+#define AFI_FPCI_BAR5	0x44
+
+#define AFI_CACHE_BAR0_SZ	0x48
+#define AFI_CACHE_BAR0_ST	0x4c
+#define AFI_CACHE_BAR1_SZ	0x50
+#define AFI_CACHE_BAR1_ST	0x54
+
+#define AFI_MSI_BAR_SZ		0x60
+#define AFI_MSI_FPCI_BAR_ST	0x64
+#define AFI_MSI_AXI_BAR_ST	0x68
+
+#define AFI_MSI_VEC0		0x6c
+#define AFI_MSI_VEC1		0x70
+#define AFI_MSI_VEC2		0x74
+#define AFI_MSI_VEC3		0x78
+#define AFI_MSI_VEC4		0x7c
+#define AFI_MSI_VEC5		0x80
+#define AFI_MSI_VEC6		0x84
+#define AFI_MSI_VEC7		0x88
+
+#define AFI_MSI_EN_VEC0		0x8c
+#define AFI_MSI_EN_VEC1		0x90
+#define AFI_MSI_EN_VEC2		0x94
+#define AFI_MSI_EN_VEC3		0x98
+#define AFI_MSI_EN_VEC4		0x9c
+#define AFI_MSI_EN_VEC5		0xa0
+#define AFI_MSI_EN_VEC6		0xa4
+#define AFI_MSI_EN_VEC7		0xa8
+
+#define AFI_CONFIGURATION		0xac
+#define  AFI_CONFIGURATION_EN_FPCI	(1 << 0)
+
+#define AFI_FPCI_ERROR_MASKS	0xb0
+
+#define AFI_INTR_MASK		0xb4
+#define  AFI_INTR_MASK_INT_MASK	(1 << 0)
+#define  AFI_INTR_MASK_MSI_MASK	(1 << 8)
+
+#define AFI_INTR_CODE			0xb8
+#define  AFI_INTR_CODE_MASK		0xf
+#define  AFI_INTR_AXI_SLAVE_ERROR	1
+#define  AFI_INTR_AXI_DECODE_ERROR	2
+#define  AFI_INTR_TARGET_ABORT		3
+#define  AFI_INTR_MASTER_ABORT		4
+#define  AFI_INTR_INVALID_WRITE		5
+#define  AFI_INTR_LEGACY		6
+#define  AFI_INTR_FPCI_DECODE_ERROR	7
+
+#define AFI_INTR_SIGNATURE	0xbc
+#define AFI_UPPER_FPCI_ADDRESS	0xc0
+#define AFI_SM_INTR_ENABLE	0xc4
+#define  AFI_SM_INTR_INTA_ASSERT	(1 << 0)
+#define  AFI_SM_INTR_INTB_ASSERT	(1 << 1)
+#define  AFI_SM_INTR_INTC_ASSERT	(1 << 2)
+#define  AFI_SM_INTR_INTD_ASSERT	(1 << 3)
+#define  AFI_SM_INTR_INTA_DEASSERT	(1 << 4)
+#define  AFI_SM_INTR_INTB_DEASSERT	(1 << 5)
+#define  AFI_SM_INTR_INTC_DEASSERT	(1 << 6)
+#define  AFI_SM_INTR_INTD_DEASSERT	(1 << 7)
+
+#define AFI_AFI_INTR_ENABLE		0xc8
+#define  AFI_INTR_EN_INI_SLVERR		(1 << 0)
+#define  AFI_INTR_EN_INI_DECERR		(1 << 1)
+#define  AFI_INTR_EN_TGT_SLVERR		(1 << 2)
+#define  AFI_INTR_EN_TGT_DECERR		(1 << 3)
+#define  AFI_INTR_EN_TGT_WRERR		(1 << 4)
+#define  AFI_INTR_EN_DFPCI_DECERR	(1 << 5)
+#define  AFI_INTR_EN_AXI_DECERR		(1 << 6)
+#define  AFI_INTR_EN_FPCI_TIMEOUT	(1 << 7)
+#define  AFI_INTR_EN_PRSNT_SENSE	(1 << 8)
+
+#define AFI_PCIE_CONFIG					0x0f8
+#define  AFI_PCIE_CONFIG_PCIE_DISABLE(x)		(1 << ((x) + 1))
+#define  AFI_PCIE_CONFIG_PCIE_DISABLE_ALL		0xe
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK	(0xf << 20)
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE	(0x0 << 20)
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420	(0x0 << 20)
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL	(0x1 << 20)
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222	(0x1 << 20)
+#define  AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411	(0x2 << 20)
+
+#define AFI_FUSE			0x104
+#define  AFI_FUSE_PCIE_T0_GEN2_DIS	(1 << 2)
+
+#define AFI_PEX0_CTRL			0x110
+#define AFI_PEX1_CTRL			0x118
+#define AFI_PEX2_CTRL			0x128
+#define  AFI_PEX_CTRL_RST		(1 << 0)
+#define  AFI_PEX_CTRL_CLKREQ_EN		(1 << 1)
+#define  AFI_PEX_CTRL_REFCLK_EN		(1 << 3)
+
+#define AFI_PEXBIAS_CTRL_0		0x168
+
+#define RP_VEND_XP	0x00000F00
+#define  RP_VEND_XP_DL_UP	(1 << 30)
+
+#define RP_LINK_CONTROL_STATUS			0x00000090
+#define  RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE	0x20000000
+#define  RP_LINK_CONTROL_STATUS_LINKSTAT_MASK	0x3fff0000
+
+#define PADS_CTL_SEL		0x0000009C
+
+#define PADS_CTL		0x000000A0
+#define  PADS_CTL_IDDQ_1L	(1 << 0)
+#define  PADS_CTL_TX_DATA_EN_1L	(1 << 6)
+#define  PADS_CTL_RX_DATA_EN_1L	(1 << 10)
+
+#define PADS_PLL_CTL_TEGRA20			0x000000B8
+#define PADS_PLL_CTL_TEGRA30			0x000000B4
+#define  PADS_PLL_CTL_RST_B4SM			(1 << 1)
+#define  PADS_PLL_CTL_LOCKDET			(1 << 8)
+#define  PADS_PLL_CTL_REFCLK_MASK		(0x3 << 16)
+#define  PADS_PLL_CTL_REFCLK_INTERNAL_CML	(0 << 16)
+#define  PADS_PLL_CTL_REFCLK_INTERNAL_CMOS	(1 << 16)
+#define  PADS_PLL_CTL_REFCLK_EXTERNAL		(2 << 16)
+#define  PADS_PLL_CTL_TXCLKREF_MASK		(0x1 << 20)
+#define  PADS_PLL_CTL_TXCLKREF_DIV10		(0 << 20)
+#define  PADS_PLL_CTL_TXCLKREF_DIV5		(1 << 20)
+#define  PADS_PLL_CTL_TXCLKREF_BUF_EN		(1 << 22)
+
+#define PADS_REFCLK_CFG0			0x000000C8
+#define PADS_REFCLK_CFG1			0x000000CC
+
+/*
+ * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit
+ * entries, one entry per PCIe port. These field definitions and desired
+ * values aren't in the TRM, but do come from NVIDIA.
+ */
+#define PADS_REFCLK_CFG_TERM_SHIFT		2  /* 6:2 */
+#define PADS_REFCLK_CFG_E_TERM_SHIFT		7
+#define PADS_REFCLK_CFG_PREDI_SHIFT		8  /* 11:8 */
+#define PADS_REFCLK_CFG_DRVI_SHIFT		12 /* 15:12 */
+
+/* Default value provided by HW engineering is 0xfa5c */
+#define PADS_REFCLK_CFG_VALUE \
+	( \
+		(0x17 << PADS_REFCLK_CFG_TERM_SHIFT)   | \
+		(0    << PADS_REFCLK_CFG_E_TERM_SHIFT) | \
+		(0xa  << PADS_REFCLK_CFG_PREDI_SHIFT)  | \
+		(0xf  << PADS_REFCLK_CFG_DRVI_SHIFT)     \
+	)
+
+/* used to differentiate between Tegra SoC generations */
+struct tegra_pcie_soc_data {
+	unsigned int num_ports;
+	unsigned int msi_base_shift;
+	u32 pads_pll_ctl;
+	u32 tx_ref_sel;
+	bool has_pex_clkreq_en;
+	bool has_pex_bias_ctrl;
+	bool has_intr_prsnt_sense;
+	bool has_avdd_supply;
+	bool has_cml_clk;
+};
+
+struct tegra_pcie {
+	struct device_d *dev;
+	struct pci_controller pci;
+
+	void __iomem *pads;
+	void __iomem *afi;
+	void __iomem *cs;
+
+	struct list_head buses;
+
+	struct resource io;
+	struct resource mem;
+	struct resource prefetch;
+	struct resource busn;
+	struct resource *cs_res;
+
+	struct clk *pex_clk;
+	struct clk *afi_clk;
+	struct clk *pll_e;
+	struct clk *cml_clk;
+
+	struct reset_control *pex_rst;
+	struct reset_control *afi_rst;
+	struct reset_control *pcie_xrst;
+
+	struct list_head ports;
+	unsigned int num_ports;
+	u32 xbar_config;
+
+	struct regulator *pex_clk_supply;
+	struct regulator *vdd_supply;
+	struct regulator *avdd_supply;
+
+	const struct tegra_pcie_soc_data *soc_data;
+};
+
+struct tegra_pcie_port {
+	struct tegra_pcie *pcie;
+	struct list_head list;
+	struct resource regs;
+	void __iomem *base;
+	unsigned int index;
+	unsigned int lanes;
+};
+
+static inline struct tegra_pcie *host_to_pcie(struct pci_controller *host)
+{
+	return container_of(host, struct tegra_pcie, pci);
+}
+
+static inline void afi_writel(struct tegra_pcie *pcie, u32 value,
+			      unsigned long offset)
+{
+	writel(value, pcie->afi + offset);
+}
+
+static inline u32 afi_readl(struct tegra_pcie *pcie, unsigned long offset)
+{
+	return readl(pcie->afi + offset);
+}
+
+static inline void pads_writel(struct tegra_pcie *pcie, u32 value,
+			       unsigned long offset)
+{
+	writel(value, pcie->pads + offset);
+}
+
+static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
+{
+	return readl(pcie->pads + offset);
+}
+
+static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus,
+					     unsigned int devfn,
+					     int where)
+{
+	struct tegra_pcie *pcie = host_to_pcie(bus->host);
+	void __iomem *addr = NULL;
+
+	if (bus->number == 0) {
+		unsigned int slot = PCI_SLOT(devfn);
+		struct tegra_pcie_port *port;
+
+		list_for_each_entry(port, &pcie->ports, list) {
+			if (port->index + 1 == slot) {
+				addr = (void __force __iomem *)
+					port->regs.start + (where & ~3);
+				break;
+			}
+		}
+	} else {
+		addr = pcie->cs;
+
+		addr += ((where & 0xf00) << 16) | (bus->number << 16) |
+			(PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) |
+			(where & 0xfc);
+	}
+
+	return addr;
+}
+
+static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	void __iomem *addr;
+
+	addr = tegra_pcie_conf_address(bus, devfn, where);
+	if (!addr) {
+		*value = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	*value = readl(addr);
+
+	if (size == 1)
+		*value = (*value >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*value = (*value >> (8 * (where & 3))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 value)
+{
+	void __iomem *addr;
+	u32 mask, tmp;
+
+	addr = tegra_pcie_conf_address(bus, devfn, where);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size == 4) {
+		writel(value, addr);
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	if (size == 2)
+		mask = ~(0xffff << ((where & 0x3) * 8));
+	else if (size == 1)
+		mask = ~(0xff << ((where & 0x3) * 8));
+	else
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	tmp = readl(addr) & mask;
+	tmp |= value << ((where & 0x3) * 8);
+	writel(tmp, addr);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_res_start(struct pci_bus *bus, resource_size_t res_addr)
+{
+	return res_addr;
+}
+
+static struct pci_ops tegra_pcie_ops = {
+	.read = tegra_pcie_read_conf,
+	.write = tegra_pcie_write_conf,
+	.res_start = tegra_pcie_res_start,
+};
+
+static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
+{
+	unsigned long ret = 0;
+
+	switch (port->index) {
+	case 0:
+		ret = AFI_PEX0_CTRL;
+		break;
+
+	case 1:
+		ret = AFI_PEX1_CTRL;
+		break;
+
+	case 2:
+		ret = AFI_PEX2_CTRL;
+		break;
+	}
+
+	return ret;
+}
+
+static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+{
+	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+	unsigned long value;
+
+	/* pulse reset signal */
+	value = afi_readl(port->pcie, ctrl);
+	value &= ~AFI_PEX_CTRL_RST;
+	afi_writel(port->pcie, value, ctrl);
+
+	mdelay(1);
+
+	value = afi_readl(port->pcie, ctrl);
+	value |= AFI_PEX_CTRL_RST;
+	afi_writel(port->pcie, value, ctrl);
+}
+
+static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
+{
+	const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
+	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+	unsigned long value;
+
+	/* enable reference clock */
+	value = afi_readl(port->pcie, ctrl);
+	value |= AFI_PEX_CTRL_REFCLK_EN;
+
+	if (soc->has_pex_clkreq_en)
+		value |= AFI_PEX_CTRL_CLKREQ_EN;
+
+	afi_writel(port->pcie, value, ctrl);
+
+	tegra_pcie_port_reset(port);
+}
+
+static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
+{
+	unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+	unsigned long value;
+
+	/* assert port reset */
+	value = afi_readl(port->pcie, ctrl);
+	value &= ~AFI_PEX_CTRL_RST;
+	afi_writel(port->pcie, value, ctrl);
+
+	/* disable reference clock */
+	value = afi_readl(port->pcie, ctrl);
+	value &= ~AFI_PEX_CTRL_REFCLK_EN;
+	afi_writel(port->pcie, value, ctrl);
+}
+
+static void tegra_pcie_port_free(struct tegra_pcie_port *port)
+{
+	list_del(&port->list);
+	kfree(port);
+}
+
+#if 0
+static void tegra_pcie_fixup_bridge(struct pci_dev *dev)
+{
+	u16 reg;
+
+	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+		pci_read_config_word(dev, PCI_COMMAND, &reg);
+		reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+		pci_write_config_word(dev, PCI_COMMAND, reg);
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
+
+/* Tegra PCIE root complex wrongly reports device class */
+static void tegra_pcie_fixup_class(struct pci_dev *dev)
+{
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
+
+/* Tegra PCIE requires relaxed ordering */
+static void tegra_pcie_relax_enable(struct pci_dev *dev)
+{
+	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
+#endif
+
+/*
+ * FPCI map is as follows:
+ * - 0xfdfc000000: I/O space
+ * - 0xfdfe000000: type 0 configuration space
+ * - 0xfdff000000: type 1 configuration space
+ * - 0xfe00000000: type 0 extended configuration space
+ * - 0xfe10000000: type 1 extended configuration space
+ */
+static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
+{
+	u32 fpci_bar, size, axi_address;
+
+	/* Bar 0: type 1 extended configuration space */
+	fpci_bar = 0xfe100000;
+	size = resource_size(pcie->cs_res);
+	axi_address = pcie->cs_res->start;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
+
+	/* Bar 1: downstream IO bar */
+	fpci_bar = 0xfdfc0000;
+	size = resource_size(&pcie->io);
+	axi_address = pcie->io.start;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
+
+	/* Bar 2: prefetchable memory BAR */
+	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
+	size = resource_size(&pcie->prefetch);
+	axi_address = pcie->prefetch.start;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
+
+	/* Bar 3: non prefetchable memory BAR */
+	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
+	size = resource_size(&pcie->mem);
+	axi_address = pcie->mem.start;
+	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+
+	/* NULL out the remaining BARs as they are not used */
+	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
+	afi_writel(pcie, 0, AFI_AXI_BAR4_SZ);
+	afi_writel(pcie, 0, AFI_FPCI_BAR4);
+
+	afi_writel(pcie, 0, AFI_AXI_BAR5_START);
+	afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
+	afi_writel(pcie, 0, AFI_FPCI_BAR5);
+
+	/* map all upstream transactions as uncached */
+	/* FIXME: is 0 ok for BAR0 start ??? */
+	afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
+	afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
+
+	/* MSI translations are setup only when needed */
+	afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+	afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
+	afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+}
+
+static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+	struct tegra_pcie_port *port;
+	unsigned long value;
+
+	/* power down PCIe slot clock bias pad */
+	if (soc->has_pex_bias_ctrl)
+		afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0);
+
+	/* configure mode and disable all ports */
+	value = afi_readl(pcie, AFI_PCIE_CONFIG);
+	value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
+	value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
+
+	list_for_each_entry(port, &pcie->ports, list)
+		value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
+
+	afi_writel(pcie, value, AFI_PCIE_CONFIG);
+
+	value = afi_readl(pcie, AFI_FUSE);
+	value |= AFI_FUSE_PCIE_T0_GEN2_DIS;
+	afi_writel(pcie, value, AFI_FUSE);
+
+	/* initialize internal PHY, enable up to 16 PCIE lanes */
+	pads_writel(pcie, 0x0, PADS_CTL_SEL);
+
+	/* override IDDQ to 1 on all 4 lanes */
+	value = pads_readl(pcie, PADS_CTL);
+	value |= PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, value, PADS_CTL);
+
+	/*
+	 * Set up PHY PLL inputs select PLLE output as refclock,
+	 * set TX ref sel to div10 (not div5).
+	 */
+	value = pads_readl(pcie, soc->pads_pll_ctl);
+	value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
+	value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel;
+	pads_writel(pcie, value, soc->pads_pll_ctl);
+
+	/* take PLL out of reset  */
+	value = pads_readl(pcie, soc->pads_pll_ctl);
+	value |= PADS_PLL_CTL_RST_B4SM;
+	pads_writel(pcie, value, soc->pads_pll_ctl);
+
+	/* Configure the reference clock driver */
+	value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16);
+	pads_writel(pcie, value, PADS_REFCLK_CFG0);
+	if (soc->num_ports > 2)
+		pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1);
+
+	/* wait for the PLL to lock */
+	if (wait_on_timeout(300 * MSECOND,
+		(pads_readl(pcie, soc->pads_pll_ctl) & PADS_PLL_CTL_LOCKDET))) {
+		pr_err("Tegra PCIe error: timeout waiting for PLL\n");
+		return -EBUSY;
+	}
+
+	/* turn off IDDQ override */
+	value = pads_readl(pcie, PADS_CTL);
+	value &= ~PADS_CTL_IDDQ_1L;
+	pads_writel(pcie, value, PADS_CTL);
+
+	/* enable TX/RX data */
+	value = pads_readl(pcie, PADS_CTL);
+	value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L;
+	pads_writel(pcie, value, PADS_CTL);
+
+	/* take the PCIe interface module out of reset */
+	reset_control_deassert(pcie->pcie_xrst);
+
+	/* finally enable PCIe */
+	value = afi_readl(pcie, AFI_CONFIGURATION);
+	value |= AFI_CONFIGURATION_EN_FPCI;
+	afi_writel(pcie, value, AFI_CONFIGURATION);
+
+	value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
+		AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
+		AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR;
+
+	if (soc->has_intr_prsnt_sense)
+		value |= AFI_INTR_EN_PRSNT_SENSE;
+
+	afi_writel(pcie, value, AFI_AFI_INTR_ENABLE);
+	afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
+
+	/* don't enable MSI for now, only when needed */
+	afi_writel(pcie, AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+
+	/* disable all exceptions */
+	afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
+
+	return 0;
+}
+
+static void tegra_pcie_power_off(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+	int err;
+
+	/* TODO: disable and unprepare clocks? */
+
+	reset_control_assert(pcie->pcie_xrst);
+	reset_control_assert(pcie->afi_rst);
+	reset_control_assert(pcie->pex_rst);
+
+	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+
+	if (soc->has_avdd_supply) {
+		err = regulator_disable(pcie->avdd_supply);
+		if (err < 0)
+			dev_warn(pcie->dev,
+				 "failed to disable AVDD regulator: %d\n",
+				 err);
+	}
+
+	err = regulator_disable(pcie->pex_clk_supply);
+	if (err < 0)
+		dev_warn(pcie->dev, "failed to disable pex-clk regulator: %d\n",
+			 err);
+
+	err = regulator_disable(pcie->vdd_supply);
+	if (err < 0)
+		dev_warn(pcie->dev, "failed to disable VDD regulator: %d\n",
+			 err);
+}
+
+static int tegra_pcie_power_on(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+	int err;
+
+	reset_control_assert(pcie->pcie_xrst);
+	reset_control_assert(pcie->afi_rst);
+	reset_control_assert(pcie->pex_rst);
+
+	tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+
+	/* enable regulators */
+	err = regulator_enable(pcie->vdd_supply);
+	if (err < 0) {
+		dev_err(pcie->dev, "failed to enable VDD regulator: %d\n", err);
+		return err;
+	}
+
+	err = regulator_enable(pcie->pex_clk_supply);
+	if (err < 0) {
+		dev_err(pcie->dev, "failed to enable pex-clk regulator: %d\n",
+			err);
+		return err;
+	}
+
+	if (soc->has_avdd_supply) {
+		err = regulator_enable(pcie->avdd_supply);
+		if (err < 0) {
+			dev_err(pcie->dev,
+				"failed to enable AVDD regulator: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
+						pcie->pex_clk,
+						pcie->pex_rst);
+	if (err) {
+		dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
+		return err;
+	}
+
+	reset_control_deassert(pcie->afi_rst);
+
+	err = clk_enable(pcie->afi_clk);
+	if (err < 0) {
+		dev_err(pcie->dev, "failed to enable AFI clock: %d\n", err);
+		return err;
+	}
+
+	if (soc->has_cml_clk) {
+		err = clk_enable(pcie->cml_clk);
+		if (err < 0) {
+			dev_err(pcie->dev, "failed to enable CML clock: %d\n",
+				err);
+			return err;
+		}
+	}
+
+	err = clk_enable(pcie->pll_e);
+	if (err < 0) {
+		dev_err(pcie->dev, "failed to enable PLLE clock: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+
+	pcie->pex_clk = clk_get(pcie->dev, "pex");
+	if (IS_ERR(pcie->pex_clk))
+		return PTR_ERR(pcie->pex_clk);
+
+	pcie->afi_clk = clk_get(pcie->dev, "afi");
+	if (IS_ERR(pcie->afi_clk))
+		return PTR_ERR(pcie->afi_clk);
+
+	pcie->pll_e = clk_get(pcie->dev, "pll_e");
+	if (IS_ERR(pcie->pll_e))
+		return PTR_ERR(pcie->pll_e);
+
+	if (soc->has_cml_clk) {
+		pcie->cml_clk = clk_get(pcie->dev, "cml");
+		if (IS_ERR(pcie->cml_clk))
+			return PTR_ERR(pcie->cml_clk);
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_resets_get(struct tegra_pcie *pcie)
+{
+	pcie->pex_rst = reset_control_get(pcie->dev, "pex");
+	if (IS_ERR(pcie->pex_rst))
+		return PTR_ERR(pcie->pex_rst);
+
+	pcie->afi_rst = reset_control_get(pcie->dev, "afi");
+	if (IS_ERR(pcie->afi_rst))
+		return PTR_ERR(pcie->afi_rst);
+
+	pcie->pcie_xrst = reset_control_get(pcie->dev, "pcie_x");
+	if (IS_ERR(pcie->pcie_xrst))
+		return PTR_ERR(pcie->pcie_xrst);
+
+	return 0;
+}
+
+static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
+{
+	struct device_d *dev = pcie->dev;
+	int err;
+
+	err = tegra_pcie_clocks_get(pcie);
+	if (err) {
+		dev_err(dev, "failed to get clocks: %d\n", err);
+		return err;
+	}
+
+	err = tegra_pcie_resets_get(pcie);
+	if (err) {
+		dev_err(dev, "failed to get resets: %d\n", err);
+		return err;
+	}
+
+	err = tegra_pcie_power_on(pcie);
+	if (err) {
+		dev_err(dev, "failed to power up: %d\n", err);
+		return err;
+	}
+
+	pcie->pads = dev_request_mem_region_by_name(dev, "pads");
+	if (IS_ERR(pcie->pads)) {
+		err = PTR_ERR(pcie->pads);
+		goto poweroff;
+	}
+
+	pcie->afi = dev_request_mem_region_by_name(dev, "afi");
+	if (IS_ERR(pcie->afi)) {
+		err = PTR_ERR(pcie->afi);
+		goto poweroff;
+	}
+
+	pcie->cs_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "cs");
+	pcie->cs = dev_request_mem_region_by_name(dev, "cs");
+	if (IS_ERR(pcie->cs)) {
+		err = PTR_ERR(pcie->cs);
+		goto poweroff;
+	}
+
+	return 0;
+
+poweroff:
+	tegra_pcie_power_off(pcie);
+	return err;
+}
+
+static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
+{
+	tegra_pcie_power_off(pcie);
+	return 0;
+}
+
+static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
+				      u32 *xbar)
+{
+	struct device_node *np = pcie->dev->device_node;
+
+	if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
+		switch (lanes) {
+		case 0x00000204:
+			dev_info(pcie->dev, "4x1, 2x1 configuration\n");
+			*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420;
+			return 0;
+
+		case 0x00020202:
+			dev_info(pcie->dev, "2x3 configuration\n");
+			*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222;
+			return 0;
+
+		case 0x00010104:
+			dev_info(pcie->dev, "4x1, 1x2 configuration\n");
+			*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
+			return 0;
+		}
+	} else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
+		switch (lanes) {
+		case 0x00000004:
+			dev_info(pcie->dev, "single-mode configuration\n");
+			*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE;
+			return 0;
+
+		case 0x00000202:
+			dev_info(pcie->dev, "dual-mode configuration\n");
+			*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
+{
+	const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+	struct device_node *np = pcie->dev->device_node, *port;
+	struct of_pci_range_parser parser;
+	struct of_pci_range range;
+	struct resource *rp_res;
+	struct resource res;
+	u32 lanes = 0;
+	int err;
+
+	if (of_pci_range_parser_init(&parser, np)) {
+		dev_err(pcie->dev, "missing \"ranges\" property\n");
+		return -EINVAL;
+	}
+
+	pcie->vdd_supply = regulator_get(pcie->dev, "vdd");
+	if (IS_ERR(pcie->vdd_supply))
+		return PTR_ERR(pcie->vdd_supply);
+
+	pcie->pex_clk_supply = regulator_get(pcie->dev, "pex-clk");
+	if (IS_ERR(pcie->pex_clk_supply))
+		return PTR_ERR(pcie->pex_clk_supply);
+
+	if (soc->has_avdd_supply) {
+		pcie->avdd_supply = regulator_get(pcie->dev, "avdd");
+		if (IS_ERR(pcie->avdd_supply))
+			return PTR_ERR(pcie->avdd_supply);
+	}
+
+	for_each_of_pci_range(&parser, &range) {
+		of_pci_range_to_resource(&range, np, &res);
+
+		switch (res.flags & IORESOURCE_TYPE_BITS) {
+		case IORESOURCE_IO:
+			memcpy(&pcie->io, &res, sizeof(res));
+			pcie->io.name = "I/O";
+			break;
+
+		case IORESOURCE_MEM:
+			if (res.flags & IORESOURCE_PREFETCH) {
+				memcpy(&pcie->prefetch, &res, sizeof(res));
+				pcie->prefetch.name = "PREFETCH";
+			} else {
+				memcpy(&pcie->mem, &res, sizeof(res));
+				pcie->mem.name = "MEM";
+			}
+			break;
+		}
+	}
+#if 0
+	err = of_pci_parse_bus_range(np, &pcie->busn);
+	if (err < 0) {
+		dev_err(pcie->dev, "failed to parse ranges property: %d\n",
+			err);
+		pcie->busn.name = np->name;
+		pcie->busn.start = 0;
+		pcie->busn.end = 0xff;
+		pcie->busn.flags = IORESOURCE_BUS;
+	}
+#endif
+	/* parse root ports */
+	for_each_child_of_node(np, port) {
+		struct tegra_pcie_port *rp;
+		unsigned int index;
+		u32 value;
+
+		err = of_pci_get_devfn(port);
+		if (err < 0) {
+			dev_err(pcie->dev, "failed to parse address: %d\n",
+				err);
+			return err;
+		}
+
+		index = PCI_SLOT(err);
+
+		if (index < 1 || index > soc->num_ports) {
+			dev_err(pcie->dev, "invalid port number: %d\n", index);
+			return -EINVAL;
+		}
+
+		index--;
+
+		err = of_property_read_u32(port, "nvidia,num-lanes", &value);
+		if (err < 0) {
+			dev_err(pcie->dev, "failed to parse # of lanes: %d\n",
+				err);
+			return err;
+		}
+
+		if (value > 16) {
+			dev_err(pcie->dev, "invalid # of lanes: %u\n", value);
+			return -EINVAL;
+		}
+
+		lanes |= value << (index << 3);
+
+		if (!of_device_is_available(port))
+			continue;
+
+		rp = kzalloc(sizeof(*rp), GFP_KERNEL);
+		if (!rp)
+			return -ENOMEM;
+
+		err = of_address_to_resource(port, 0, &rp->regs);
+		if (err < 0) {
+			dev_err(pcie->dev, "failed to parse address: %d\n",
+				err);
+			return err;
+		}
+
+		/*
+		 * if the port address is inside the NULL page we alias this
+		 * range at +1MB and fix up the resource, otherwise just request
+		 */
+		if (!(rp->regs.start & 0xfffff000)) {
+			rp_res = request_iomem_region(dev_name(pcie->dev),
+					rp->regs.start + SZ_1M,
+					rp->regs.end + SZ_1M);
+			if (!rp_res)
+				return -ENOMEM;
+
+			map_io_sections(rp->regs.start,
+					(void *)rp_res->start, SZ_1M);
+
+			rp->regs.start = rp_res->start;
+			rp->regs.end = rp_res->end;
+		} else {
+			rp_res = request_iomem_region(dev_name(pcie->dev),
+					rp->regs.start, rp->regs.end);
+			if (!rp_res)
+				return -ENOMEM;
+		}
+
+		INIT_LIST_HEAD(&rp->list);
+		rp->index = index;
+		rp->lanes = value;
+		rp->pcie = pcie;
+
+		rp->base = (void __force __iomem *)rp->regs.start;
+		if (IS_ERR(rp->base))
+			return PTR_ERR(rp->base);
+
+		list_add_tail(&rp->list, &pcie->ports);
+	}
+
+	err = tegra_pcie_get_xbar_config(pcie, lanes, &pcie->xbar_config);
+	if (err < 0) {
+		dev_err(pcie->dev, "invalid lane configuration\n");
+		return err;
+	}
+
+	return 0;
+}
+
+/*
+ * FIXME: If there are no PCIe cards attached, then calling this function
+ * can result in the increase of the bootup time as there are big timeout
+ * loops.
+ */
+#define TEGRA_PCIE_LINKUP_TIMEOUT	200	/* up to 1.2 seconds */
+static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
+{
+	unsigned int timeout;
+	unsigned int retries = 2;
+
+	do {
+		timeout = wait_on_timeout(50 * MSECOND,
+			readl(port->regs.start + RP_VEND_XP) & RP_VEND_XP_DL_UP);
+
+		if (timeout) {
+			dev_dbg(port->pcie->dev, "link %u down, retrying\n",
+				port->index);
+			goto retry;
+		}
+
+		timeout = wait_on_timeout(200 * MSECOND,
+			readl(port->regs.start + RP_LINK_CONTROL_STATUS) &
+			RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
+
+		if (!timeout)
+			return true;
+
+retry:
+		tegra_pcie_port_reset(port);
+	} while (--retries);
+
+	return false;
+}
+
+static int tegra_pcie_enable(struct tegra_pcie *pcie)
+{
+	struct tegra_pcie_port *port, *tmp;
+
+	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+		dev_dbg(pcie->dev, "probing port %u, using %u lanes\n",
+			 port->index, port->lanes);
+
+		tegra_pcie_port_enable(port);
+
+		if (tegra_pcie_port_check_link(port))
+			continue;
+
+		dev_dbg(pcie->dev, "link %u down, ignoring\n", port->index);
+
+		tegra_pcie_port_disable(port);
+		tegra_pcie_port_free(port);
+	}
+
+	pcie->pci.parent = pcie->dev;
+	pcie->pci.pci_ops = &tegra_pcie_ops;
+	pcie->pci.mem_resource = &pcie->mem;
+	pcie->pci.mem_pref_resource = &pcie->prefetch;
+	pcie->pci.io_resource = &pcie->io;
+
+	register_pci_controller(&pcie->pci);
+
+	return 0;
+}
+
+static const struct tegra_pcie_soc_data tegra20_pcie_data = {
+	.num_ports = 2,
+	.msi_base_shift = 0,
+	.pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
+	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
+	.has_pex_clkreq_en = false,
+	.has_pex_bias_ctrl = false,
+	.has_intr_prsnt_sense = false,
+	.has_avdd_supply = false,
+	.has_cml_clk = false,
+};
+
+static const struct tegra_pcie_soc_data tegra30_pcie_data = {
+	.num_ports = 3,
+	.msi_base_shift = 8,
+	.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
+	.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+	.has_pex_clkreq_en = true,
+	.has_pex_bias_ctrl = true,
+	.has_intr_prsnt_sense = true,
+	.has_avdd_supply = true,
+	.has_cml_clk = true,
+};
+
+static __maybe_unused struct of_device_id tegra_pcie_of_match[] = {
+	{
+		.compatible = "nvidia,tegra30-pcie",
+		.data = (unsigned long)&tegra30_pcie_data
+	}, {
+		.compatible = "nvidia,tegra20-pcie",
+		.data = (unsigned long)&tegra20_pcie_data
+	}, {
+		/* sentinel */
+	},
+};
+
+static int tegra_pcie_probe(struct device_d *dev)
+{
+	struct tegra_pcie *pcie;
+	int err;
+
+	pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&pcie->buses);
+	INIT_LIST_HEAD(&pcie->ports);
+	dev_get_drvdata(dev, (unsigned long *)&pcie->soc_data);
+	pcie->dev = dev;
+
+	err = tegra_pcie_parse_dt(pcie);
+	if (err < 0) {
+		printk("parse DT failed\n");
+		return err;
+	}
+
+	err = tegra_pcie_get_resources(pcie);
+	if (err < 0) {
+		dev_err(dev, "failed to request resources: %d\n", err);
+		return err;
+	}
+
+	err = tegra_pcie_enable_controller(pcie);
+	if (err)
+		goto put_resources;
+
+	/* setup the AFI address translations */
+	tegra_pcie_setup_translations(pcie);
+
+	err = tegra_pcie_enable(pcie);
+	if (err < 0) {
+		dev_err(dev, "failed to enable PCIe ports: %d\n", err);
+		goto put_resources;
+	}
+
+	return 0;
+
+put_resources:
+	tegra_pcie_put_resources(pcie);
+	return err;
+}
+
+static struct driver_d tegra_pcie_driver = {
+	.name = "tegra-pcie",
+	.of_compatible = DRV_OF_COMPAT(tegra_pcie_of_match),
+	.probe = tegra_pcie_probe,
+};
+device_platform_driver(tegra_pcie_driver);
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:25 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:25 +0200
Subject: [PATCH v2 19/19] ARM: tegra: enable network related options in
 defconfig
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-20-git-send-email-dev@lynxeye.de>

Now that we have working network support on the Beaver board
it makes sense to enable some network options.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/configs/tegra_v7_defconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig
index 8f01b54..ead69ed 100644
--- a/arch/arm/configs/tegra_v7_defconfig
+++ b/arch/arm/configs/tegra_v7_defconfig
@@ -27,17 +27,24 @@ CONFIG_CMD_RESET=y
 CONFIG_CMD_EXPORT=y
 CONFIG_CMD_LOADENV=y
 CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_TIMEOUT=y
 CONFIG_CMD_CLK=y
 CONFIG_CMD_DETECT=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
 CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_NET_RTL8169=y
 CONFIG_MCI=y
 CONFIG_MCI_MMC_BOOT_PARTITIONS=y
 CONFIG_MCI_TEGRA=y
 CONFIG_PCI_TEGRA=y
 CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
 CONFIG_FS_FAT=y
 CONFIG_FS_FAT_LFN=y
-- 
1.9.3



From dev at lynxeye.de  Sat Oct  4 10:40:24 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sat,  4 Oct 2014 19:40:24 +0200
Subject: [PATCH v2 18/19] net: add rtl8169 driver
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412444425-2569-19-git-send-email-dev@lynxeye.de>

This adds the driver for RealTek 8169 and compatible
pci attached network chips.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/net/Kconfig   |   8 +
 drivers/net/Makefile  |   1 +
 drivers/net/rtl8169.c | 566 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 575 insertions(+)
 create mode 100644 drivers/net/rtl8169.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c99fcc8..24b9844 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -156,6 +156,14 @@ config DRIVER_NET_RTL8139
 	  This is a driver for the Fast Ethernet PCI network cards based on
 	  the RTL 8139 chips.
 
+config DRIVER_NET_RTL8169
+	bool "RealTek RTL-8169 PCI Ethernet driver"
+	depends on PCI
+	select PHYLIB
+	help
+	  This is a driver for the Fast Ethernet PCI network cards based on
+	  the RTL 8169 chips.
+
 config DRIVER_NET_SMC911X
 	bool "smc911x ethernet driver"
 	select PHYLIB
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1b85778..3e66b31 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_DRIVER_NET_MPC5200)	+= fec_mpc5200.o
 obj-$(CONFIG_DRIVER_NET_NETX)		+= netx_eth.o
 obj-$(CONFIG_DRIVER_NET_ORION)		+= orion-gbe.o
 obj-$(CONFIG_DRIVER_NET_RTL8139)	+= rtl8139.o
+obj-$(CONFIG_DRIVER_NET_RTL8169)	+= rtl8169.o
 obj-$(CONFIG_DRIVER_NET_SMC911X)	+= smc911x.o
 obj-$(CONFIG_DRIVER_NET_SMC91111)	+= smc91111.o
 obj-$(CONFIG_DRIVER_NET_TAP)		+= tap.o
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
new file mode 100644
index 0000000..3ed2e56
--- /dev/null
+++ b/drivers/net/rtl8169.c
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <asm/mmu.h>
+#include <common.h>
+#include <init.h>
+#include <net.h>
+#include <malloc.h>
+#include <linux/pci.h>
+
+#define NUM_TX_DESC	1
+#define NUM_RX_DESC	4
+#define PKT_BUF_SIZE	1536
+#define ETH_ZLEN	60
+
+struct rtl8169_chip_info {
+	const char *name;
+	u8 version;
+	u32 RxConfigMask;
+};
+
+#define BD_STAT_OWN	0x80000000
+#define BD_STAT_EOR	0x40000000
+#define BD_STAT_FS	0x20000000
+#define BD_STAT_LS	0x10000000
+#define BD_STAT_RX_RES	0x00200000
+struct bufdesc {
+	u32 status;
+	u32 vlan_tag;
+	u32 buf_addr;
+	u32 buf_Haddr;
+};
+
+struct rtl8169_priv {
+	struct eth_device	edev;
+	void __iomem		*base;
+	struct pci_dev		*pci_dev;
+	int			chipset;
+
+	struct bufdesc		*tx_desc;
+	void			*tx_buf;
+	unsigned int		cur_tx;
+
+	struct bufdesc		*rx_desc;
+	void			*rx_buf;
+	unsigned int		cur_rx;
+
+	struct mii_bus miibus;
+};
+
+#define MAC0 			0x00
+#define MAR0			0x08
+#define TxDescStartAddrLow	0x20
+#define TxDescStartAddrHigh	0x24
+#define TxHDescStartAddrLow	0x28
+#define TxHDescStartAddrHigh	0x2c
+#define FLASH			0x30
+#define ERSR			0x36
+#define ChipCmd			0x37
+#define  CmdReset		0x10
+#define  CmdRxEnb		0x08
+#define  CmdTxEnb		0x04
+#define  RxBufEmpty		0x01
+#define TxPoll			0x38
+#define IntrMask		0x3c
+#define IntrStatus		0x3e
+#define  SYSErr			0x8000
+#define  PCSTimeout		0x4000
+#define  SWInt			0x0100
+#define  TxDescUnavail		0x80
+#define  RxFIFOOver		0x40
+#define  RxUnderrun		0x20
+#define  RxOverflow		0x10
+#define  TxErr			0x08
+#define  TxOK			0x04
+#define  RxErr			0x02
+#define  RxOK			0x01
+#define TxConfig		0x40
+#define  TxInterFrameGapShift	24
+#define  TxDMAShift		8
+#define RxConfig		0x44
+#define  AcceptErr		0x20
+#define  AcceptRunt		0x10
+#define  AcceptBroadcast	0x08
+#define  AcceptMulticast	0x04
+#define  AcceptMyPhys		0x02
+#define  AcceptAllPhys		0x01
+#define  RxCfgFIFOShift		13
+#define  RxCfgDMAShift		8
+#define RxMissed		0x4c
+#define Cfg9346			0x50
+#define  Cfg9346_Lock		0x00
+#define  Cfg9346_Unlock		0xc0
+#define Config0			0x51
+#define Config1			0x52
+#define Config2			0x53
+#define Config3			0x54
+#define Config4			0x55
+#define Config5			0x56
+#define MultiIntr		0x5c
+#define PHYAR			0x60
+#define TBICSR			0x64
+#define TBI_ANAR		0x68
+#define TBI_LPAR		0x6a
+#define PHYstatus		0x6c
+#define RxMaxSize		0xda
+#define CPlusCmd		0xe0
+#define RxDescStartAddrLow	0xe4
+#define RxDescStartAddrHigh	0xe8
+#define EarlyTxThres		0xec
+#define FuncEvent		0xf0
+#define FuncEventMask		0xf4
+#define FuncPresetState		0xf8
+#define FuncForceEvent		0xfc
+
+/* write MMIO register */
+#define RTL_W8(priv, reg, val)	writeb(val, ((char *)(priv->base) + reg))
+#define RTL_W16(priv, reg, val)	writew(val, ((char *)(priv->base) + reg))
+#define RTL_W32(priv, reg, val)	writel(val, ((char *)(priv->base) + reg))
+
+/* read MMIO register */
+#define RTL_R8(priv, reg)	readb(((char *)(priv->base) + reg))
+#define RTL_R16(priv, reg)	readw(((char *)(priv->base) + reg))
+#define RTL_R32(priv, reg)	readl(((char *)(priv->base) + reg))
+
+static const u32 rtl8169_rx_config =
+		 (7 << RxCfgFIFOShift) | (6 << RxCfgDMAShift);
+
+static void rtl8169_chip_reset(struct rtl8169_priv *priv)
+{
+	int i;
+
+	/* Soft reset the chip. */
+	RTL_W8(priv, ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 1000; i > 0; i--) {
+		if ((RTL_R8(priv, ChipCmd) & CmdReset) == 0)
+			break;
+		udelay(10);
+	}
+}
+
+static struct rtl8169_chip_info chip_info[] = {
+	{"RTL-8169",		0x00,	0xff7e1880},
+	{"RTL-8169",		0x04,	0xff7e1880},
+	{"RTL-8169",		0x00,	0xff7e1880},
+	{"RTL-8169s/8110s",	0x02,	0xff7e1880},
+	{"RTL-8169s/8110s",	0x04,	0xff7e1880},
+	{"RTL-8169sb/8110sb",	0x10,	0xff7e1880},
+	{"RTL-8169sc/8110sc",	0x18,	0xff7e1880},
+	{"RTL-8168b/8111sb",	0x30,	0xff7e1880},
+	{"RTL-8168b/8111sb",	0x38,	0xff7e1880},
+	{"RTL-8168d/8111d",	0x28,	0xff7e1880},
+	{"RTL-8168evl/8111evl",	0x2e,	0xff7e1880},
+	{"RTL-8101e",		0x34,	0xff7e1880},
+	{"RTL-8100e",		0x32,	0xff7e1880},
+};
+
+static void rtl8169_chip_identify(struct rtl8169_priv *priv)
+{
+	u32 val;
+	int i;
+
+	val = RTL_R32(priv, TxConfig);
+	val = ((val & 0x7c000000) + ((val & 0x00800000) << 2)) >> 24;
+
+	for (i = ARRAY_SIZE(chip_info) - 1; i >= 0; i--){
+		if (val == chip_info[i].version) {
+			priv->chipset = i;
+			dev_dbg(&priv->pci_dev->dev, "found %s chipset\n",
+				chip_info[i].name);
+			return;
+		}
+	}
+
+	dev_dbg(&priv->pci_dev->dev,
+		"no matching chip version found, assuming RTL-8169\n");
+	priv->chipset = 0;
+}
+
+static int rtl8169_init_dev(struct eth_device *edev)
+{
+	struct rtl8169_priv *priv = edev->priv;
+
+	rtl8169_chip_reset(priv);
+	rtl8169_chip_identify(priv);
+	pci_set_master(priv->pci_dev);
+
+	return 0;
+}
+
+static void __set_rx_mode(struct rtl8169_priv *priv)
+{
+	u32 mc_filter[2], val;
+
+	/* IFF_ALLMULTI */
+	/* Too many to filter perfectly -- accept all multicasts. */
+	mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+	val = AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+	      rtl8169_rx_config | (RTL_R32(priv, RxConfig) &
+				  chip_info[priv->chipset].RxConfigMask);
+
+	RTL_W32(priv, RxConfig, val);
+	RTL_W32(priv, MAR0 + 0, mc_filter[0]);
+	RTL_W32(priv, MAR0 + 4, mc_filter[1]);
+}
+
+static void rtl8169_init_ring(struct rtl8169_priv *priv)
+{
+	int i;
+
+	priv->cur_rx = priv->cur_tx = 0;
+
+	priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC *
+				sizeof(struct bufdesc));
+	priv->tx_buf = malloc(NUM_TX_DESC * PKT_BUF_SIZE);
+	priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC *
+				sizeof(struct bufdesc));
+	priv->rx_buf = malloc(NUM_RX_DESC * PKT_BUF_SIZE);
+
+	memset(priv->tx_desc, 0, NUM_TX_DESC * sizeof(struct bufdesc));
+	memset(priv->rx_desc, 0, NUM_RX_DESC * sizeof(struct bufdesc));
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		if (i == (NUM_RX_DESC - 1))
+			priv->rx_desc[i].status =
+				BD_STAT_OWN | BD_STAT_EOR | PKT_BUF_SIZE;
+		else
+			priv->rx_desc[i].status =
+				BD_STAT_OWN | PKT_BUF_SIZE;
+
+		priv->rx_desc[i].buf_addr =
+				virt_to_phys(priv->rx_buf + i * PKT_BUF_SIZE);
+	}
+
+	dma_flush_range((unsigned long)priv->rx_desc,
+			(unsigned long)priv->rx_desc +
+			NUM_RX_DESC * sizeof(struct bufdesc));
+}
+
+static void rtl8169_hw_start(struct rtl8169_priv *priv)
+{
+	u32 val;
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+
+	/* RTL-8169sb/8110sb or previous version */
+	if (priv->chipset <= 5)
+		RTL_W8(priv, ChipCmd, CmdTxEnb | CmdRxEnb);
+
+	RTL_W8(priv, EarlyTxThres, 0x3f);
+
+	/* For gigabit rtl8169 */
+	RTL_W16(priv, RxMaxSize, 0x800);
+
+	/* Set Rx Config register */
+	val = rtl8169_rx_config | (RTL_R32(priv, RxConfig) &
+	      chip_info[priv->chipset].RxConfigMask);
+	RTL_W32(priv, RxConfig, val);
+
+	/* Set DMA burst size and Interframe Gap Time */
+	RTL_W32(priv, TxConfig, (6 << TxDMAShift) | (3 << TxInterFrameGapShift));
+
+	RTL_W32(priv, TxDescStartAddrLow, virt_to_phys(priv->tx_desc));
+	RTL_W32(priv, TxDescStartAddrHigh, 0);
+	RTL_W32(priv, RxDescStartAddrLow, virt_to_phys(priv->rx_desc));
+	RTL_W32(priv, RxDescStartAddrHigh, 0);
+
+	/* RTL-8169sc/8110sc or later version */
+	if (priv->chipset > 5)
+		RTL_W8(priv, ChipCmd, CmdTxEnb | CmdRxEnb);
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+	udelay(10);
+
+	RTL_W32(priv, RxMissed, 0);
+
+	__set_rx_mode(priv);
+
+	/* no early-rx interrupts */
+	RTL_W16(priv, MultiIntr, RTL_R16(priv, MultiIntr) & 0xf000);
+}
+
+static int rtl8169_eth_open(struct eth_device *edev)
+{
+	struct rtl8169_priv *priv = edev->priv;
+	int ret;
+
+	rtl8169_init_ring(priv);
+	rtl8169_hw_start(priv);
+
+	ret = phy_device_connect(edev, &priv->miibus, 0, NULL, 0,
+				 PHY_INTERFACE_MODE_NA);
+
+	return ret;
+}
+
+static int rtl8169_phy_write(struct mii_bus *bus, int phy_addr,
+	int reg, u16 val)
+{
+	struct rtl8169_priv *priv = bus->priv;
+	int i;
+
+	if (phy_addr != 0)
+		return -1;
+
+	RTL_W32(priv, PHYAR, 0x80000000 | (reg & 0xff) << 16 | val);
+	mdelay(1);
+
+	for (i = 2000; i > 0; i--) {
+		if (!(RTL_R32(priv, PHYAR) & 0x80000000)) {
+			return 0;
+		} else {
+			udelay(100);
+		}
+	}
+
+	return -1;
+}
+
+static int rtl8169_phy_read(struct mii_bus *bus, int phy_addr, int reg)
+{
+	struct rtl8169_priv *priv = bus->priv;
+	int i, val = 0xffff;
+
+	RTL_W32(priv, PHYAR, 0x0 | (reg & 0xff) << 16);
+	mdelay(10);
+
+	if (phy_addr != 0)
+		return val;
+
+	for (i = 2000; i > 0; i--) {
+		if (RTL_R32(priv, PHYAR) & 0x80000000) {
+			val = (int) (RTL_R32(priv, PHYAR) & 0xffff);
+			break;
+		} else {
+			udelay(100);
+		}
+	}
+	return val;
+}
+
+static int rtl8169_eth_send(struct eth_device *edev, void *packet,
+				int packet_length)
+{
+	struct rtl8169_priv *priv = edev->priv;
+	unsigned int entry;
+
+	entry = priv->cur_tx % NUM_TX_DESC;
+
+	if (packet_length < ETH_ZLEN)
+		memset(priv->tx_buf + entry * PKT_BUF_SIZE, 0, ETH_ZLEN);
+	memcpy(priv->tx_buf + entry * PKT_BUF_SIZE, packet, packet_length);
+	dma_flush_range((unsigned long)priv->tx_buf + entry * PKT_BUF_SIZE,
+			(unsigned long)priv->tx_buf + (entry + 1) * PKT_BUF_SIZE);
+
+	priv->tx_desc[entry].buf_Haddr = 0;
+	priv->tx_desc[entry].buf_addr =
+		virt_to_phys(priv->tx_buf + entry * PKT_BUF_SIZE);
+
+	if (entry != (NUM_TX_DESC - 1)) {
+		priv->tx_desc[entry].status =
+			BD_STAT_OWN | BD_STAT_FS | BD_STAT_LS |
+			((packet_length > ETH_ZLEN) ? packet_length : ETH_ZLEN);
+	} else {
+		priv->tx_desc[entry].status =
+			BD_STAT_OWN | BD_STAT_EOR | BD_STAT_FS | BD_STAT_LS |
+			((packet_length > ETH_ZLEN) ? packet_length : ETH_ZLEN);
+	}
+
+	dma_flush_range((unsigned long)&priv->tx_desc[entry],
+			(unsigned long)&priv->tx_desc[entry + 1]);
+
+	RTL_W8(priv, TxPoll, 0x40);
+	do {
+		dma_inv_range((unsigned long)&priv->tx_desc[entry],
+		              (unsigned long)&priv->tx_desc[entry + 1]);
+	} while (priv->tx_desc[entry].status & BD_STAT_OWN);
+
+	priv->cur_tx++;
+
+	return 0;
+}
+
+static int rtl8169_eth_rx(struct eth_device *edev)
+{
+	struct rtl8169_priv *priv = edev->priv;
+	unsigned int entry, pkt_size = 0;
+	u8 status;
+
+	entry = priv->cur_rx % NUM_RX_DESC;
+
+	dma_inv_range((unsigned long)&priv->rx_desc[entry],
+	              (unsigned long)&priv->rx_desc[entry + 1]);
+
+	if ((priv->rx_desc[entry].status & BD_STAT_OWN) == 0) {
+		if (!(priv->rx_desc[entry].status & BD_STAT_RX_RES)) {
+			pkt_size = (priv->rx_desc[entry].status & 0x1fff) - 4;
+
+			dma_inv_range((unsigned long)priv->rx_buf
+			               + entry * PKT_BUF_SIZE,
+			              (unsigned long)priv->rx_buf
+			               + entry * PKT_BUF_SIZE + pkt_size);
+
+			net_receive(edev, priv->rx_buf + entry * PKT_BUF_SIZE,
+			            pkt_size);
+
+			if (entry == NUM_RX_DESC - 1)
+				priv->rx_desc[entry].status = BD_STAT_OWN |
+					BD_STAT_EOR | PKT_BUF_SIZE;
+			else
+				priv->rx_desc[entry].status =
+					BD_STAT_OWN | PKT_BUF_SIZE;
+			priv->rx_desc[entry].buf_addr =
+				virt_to_phys(priv->rx_buf +
+				             entry * PKT_BUF_SIZE);
+
+			dma_flush_range((unsigned long)&priv->rx_desc[entry],
+			                (unsigned long)&priv->rx_desc[entry + 1]);
+		} else {
+			dev_err(&edev->dev, "rx error\n");
+		}
+
+		priv->cur_rx++;
+
+		return pkt_size;
+
+	} else {
+		status = RTL_R8(priv, IntrStatus);
+		RTL_W8(priv, IntrStatus, status & ~(TxErr | RxErr | SYSErr));
+		udelay(100);	/* wait */
+	}
+
+	return 0;
+}
+
+static int rtl8169_get_ethaddr(struct eth_device *edev, unsigned char *m)
+{
+	struct rtl8169_priv *priv = edev->priv;
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		m[i] = RTL_R8(priv, MAC0 + i);
+	}
+
+	return 0;
+}
+
+static int rtl8169_set_ethaddr(struct eth_device *edev, unsigned char *mac_addr)
+{
+	struct rtl8169_priv *priv = edev->priv;
+	int i;
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+
+	for (i = 0; i < 6; i++) {
+		RTL_W8(priv, (MAC0 + i), mac_addr[i]);
+		RTL_R8(priv, mac_addr[i]);
+	}
+
+	RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+
+	return 0;
+}
+
+static void rtl8169_eth_halt(struct eth_device *edev)
+{
+	struct rtl8169_priv *priv = edev->priv;
+
+	/* Stop the chip's Tx and Rx DMA processes. */
+	RTL_W8(priv, ChipCmd, 0x00);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	RTL_W16(priv, IntrMask, 0x0000);
+	RTL_W32(priv, RxMissed, 0);
+
+	pci_clear_master(priv->pci_dev);
+}
+
+static int rtl8169_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct device_d *dev = &pdev->dev;
+	struct eth_device *edev;
+	struct rtl8169_priv *priv;
+	int ret;
+
+	/* enable pci device */
+	pci_enable_device(pdev);
+
+	priv = xzalloc(sizeof(struct rtl8169_priv));
+
+	edev = &priv->edev;
+	dev->type_data = edev;
+	edev->priv = priv;
+
+	priv->pci_dev = pdev;
+
+	priv->miibus.read = rtl8169_phy_read;
+	priv->miibus.write = rtl8169_phy_write;
+	priv->miibus.priv = priv;
+	priv->miibus.parent = &edev->dev;
+
+	priv->base = pci_iomap(pdev, pdev->device == 0x8168 ? 2 : 1);
+
+	dev_dbg(dev, "rtl%04x (rev %02x) (base=%p)\n",
+		 pdev->device, pdev->revision, priv->base);
+
+	edev->init = rtl8169_init_dev;
+	edev->open = rtl8169_eth_open;
+	edev->send = rtl8169_eth_send;
+	edev->recv = rtl8169_eth_rx;
+	edev->get_ethaddr = rtl8169_get_ethaddr;
+	edev->set_ethaddr = rtl8169_set_ethaddr;
+	edev->halt = rtl8169_eth_halt;
+	edev->parent = dev;
+	ret = eth_register(edev);
+	if (ret)
+		goto eth_err;
+
+	ret = mdiobus_register(&priv->miibus);
+	if (ret)
+		goto mdio_err;
+
+	return 0;
+
+mdio_err:
+	eth_unregister(edev);
+
+eth_err:
+	free(priv);
+
+	return ret;
+}
+static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), },
+	{ /* sentinel */ }
+};
+
+static struct pci_driver rtl8169_eth_driver = {
+	.name = "rtl8169_eth",
+	.id_table = rtl8169_pci_tbl,
+	.probe = rtl8169_probe,
+};
+
+static int rtl8169_init(void)
+{
+	return pci_register_driver(&rtl8169_eth_driver);
+}
+device_initcall(rtl8169_init);
-- 
1.9.3



From dev at lynxeye.de  Sun Oct  5 12:39:42 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sun,  5 Oct 2014 21:39:42 +0200
Subject: [PATCH 1/2] ARM: tegra30: add environment path to Beaver DT
Message-ID: <1412537983-5337-1-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/dts/tegra30-beaver.dts | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts
index 35b4d7e..94955f9 100644
--- a/arch/arm/dts/tegra30-beaver.dts
+++ b/arch/arm/dts/tegra30-beaver.dts
@@ -11,6 +11,13 @@
 		rtc1 = "/rtc at 7000e000";
 	};
 
+	chosen {
+		environment at 0 {
+			compatible = "barebox,environment";
+			device-path = &emmc, "partname:boot1";
+		};
+	};
+
 	memory {
 		reg = <0x80000000 0x7ff00000>;
 	};
@@ -750,7 +757,7 @@
 		bus-width = <4>;
 	};
 
-	sdhci at 78000600 {
+	emmc: sdhci at 78000600 {
 		status = "okay";
 		bus-width = <8>;
 		non-removable;
-- 
1.9.3



From dev at lynxeye.de  Sun Oct  5 12:39:43 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Sun,  5 Oct 2014 21:39:43 +0200
Subject: [PATCH 2/2] ARM: tegra124: add environment path to Jetson-TK1 DT
In-Reply-To: <1412537983-5337-1-git-send-email-dev@lynxeye.de>
References: <1412537983-5337-1-git-send-email-dev@lynxeye.de>
Message-ID: <1412537983-5337-2-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/dts/tegra124-jetson-tk1.dts | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/tegra124-jetson-tk1.dts b/arch/arm/dts/tegra124-jetson-tk1.dts
index 16082c0..32e41f9 100644
--- a/arch/arm/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/dts/tegra124-jetson-tk1.dts
@@ -12,6 +12,13 @@
 		rtc1 = "/rtc at 0,7000e000";
 	};
 
+	chosen {
+		environment at 0 {
+			compatible = "barebox,environment";
+			device-path = &emmc, "partname:boot1";
+		};
+	};
+
 	memory {
 		reg = <0x0 0x80000000 0x0 0x80000000>;
 	};
@@ -1630,7 +1637,7 @@
 	};
 
 	/* eMMC */
-	sdhci at 0,700b0600 {
+	emmc: sdhci at 0,700b0600 {
 		status = "okay";
 		bus-width = <8>;
 		non-removable;
-- 
1.9.3



From s.hauer at pengutronix.de  Sun Oct  5 22:45:48 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 6 Oct 2014 07:45:48 +0200
Subject: [PATCH] commands: select FILE_LIST for usbgadget
In-Reply-To: <1412268044-1360-1-git-send-email-r.schwebel@pengutronix.de>
References: <1412268044-1360-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <20141006054548.GL4992@pengutronix.de>

On Thu, Oct 02, 2014 at 06:40:44PM +0200, Robert Schwebel wrote:
> Otherwhise we get this error message:
> 
> commands/built-in.o: In function `do_usbgadget':
> barebox-2014.10.0/commands/usbgadget.c:77: undefined reference to `file_list_parse'
> 
> Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>

Applied, thanks

Sascha

> ---
>  commands/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 3a49baf..aafa80f 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -1851,6 +1851,7 @@ config CMD_USB
>  config CMD_USBGADGET
>  	bool
>  	depends on USB_GADGET
> +	select FILE_LIST
>  	prompt "usbgadget"
>  
>  config CMD_WD
> -- 
> 2.1.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  Sun Oct  5 22:52:31 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 6 Oct 2014 07:52:31 +0200
Subject: at91 usbserial issue
In-Reply-To: <542E4AAD.7070703@calao-systems.com>
References: <542E4AAD.7070703@calao-systems.com>
Message-ID: <20141006055231.GM4992@pengutronix.de>

Hi Greg,

On Fri, Oct 03, 2014 at 09:05:17AM +0200, Gr?gory Hermant wrote:
> Hi all,
> The usbserial seems to be broken for board equipped with an Atmel sam9260/9g20 Soc.
> I ran the lastest version of barebox (v2014.10.0) on a USB_A9G20_LPW.
> Below the trace
> udc0: registering UDC driver [g_serial]
> g_serial usbgadget: acm/23ba9538: can't bind, err -19
> g_serial udc0: failed to start g_serial: -19
> usbserial: No such device
> I didn't yet investigate this issue but i was wondering if someone noticed the problem.

There have been quite some changes in the USB gadget stuff. I know
USB serial currently works with i.MX and MUSB. Does v2014.08.0 still
work? That was before the changes. If yes, I think bisecting it is
the fastest way to find the culprit.

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 t.gamez at phytec.de  Tue Oct  7 01:40:37 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Tue, 7 Oct 2014 10:40:37 +0200
Subject: [PATCH 4/4] pfla03: add to am335x_defconfig
In-Reply-To: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
References: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412671237-46551-5-git-send-email-t.gamez@phytec.de>

From: Stefan M?ller-Klieser <s.mueller-klieser at phytec.de>

Signed-off-by: Stefan M?ller-Klieser <s.mueller-klieser at phytec.de>
---
 arch/arm/configs/am335x_defconfig     | 1 +
 arch/arm/configs/am335x_mlo_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/configs/am335x_defconfig b/arch/arm/configs/am335x_defconfig
index 6ef9c83..0f92564 100644
--- a/arch/arm/configs/am335x_defconfig
+++ b/arch/arm/configs/am335x_defconfig
@@ -5,6 +5,7 @@ CONFIG_OMAP_MULTI_BOARDS=y
 CONFIG_MACH_AFI_GF=y
 CONFIG_MACH_BEAGLEBONE=y
 CONFIG_MACH_PCM051=y
+CONFIG_MACH_PFLA03=y
 CONFIG_THUMB2_BAREBOX=y
 CONFIG_ARM_BOARD_APPEND_ATAG=y
 CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
diff --git a/arch/arm/configs/am335x_mlo_defconfig b/arch/arm/configs/am335x_mlo_defconfig
index dee8c5b..d691570 100644
--- a/arch/arm/configs/am335x_mlo_defconfig
+++ b/arch/arm/configs/am335x_mlo_defconfig
@@ -4,6 +4,7 @@ CONFIG_OMAP_MULTI_BOARDS=y
 CONFIG_MACH_AFI_GF=y
 CONFIG_MACH_BEAGLEBONE=y
 CONFIG_MACH_PCM051=y
+CONFIG_MACH_PFLA03=y
 CONFIG_THUMB2_BAREBOX=y
 # CONFIG_CMD_ARM_CPUINFO is not set
 # CONFIG_MEMINFO is not set
-- 
1.9.1



From t.gamez at phytec.de  Tue Oct  7 01:40:35 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Tue, 7 Oct 2014 10:40:35 +0200
Subject: [PATCH 2/4] net: micrel: Add ksz8081 support
In-Reply-To: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
References: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412671237-46551-3-git-send-email-t.gamez@phytec.de>

From: Jan Weitzel <j.weitzel at phytec.de>

Signed-off-by: Jan Weitzel <j.weitzel at phytec.de>
---
 drivers/net/phy/micrel.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 88c64e5..866391c 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -226,13 +226,21 @@ static struct phy_driver ksphy_driver[] = {
 }, {
 	.phy_id		= PHY_ID_KSZ8051,
 	.phy_id_mask	= 0x00fffff0,
-	.drv.name		= "Micrel KSZ8051",
+	.drv.name	= "Micrel KSZ8051",
 	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
 				| SUPPORTED_Asym_Pause),
 	.config_init	= ks8051_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 }, {
+	.phy_id		= PHY_ID_KSZ8081,
+	.phy_id_mask	= MICREL_PHY_ID_MASK,
+	.drv.name	= "Micrel KSZ8081/91",
+	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.config_init	= kszphy_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+}, {
 	.phy_id		= PHY_ID_KSZ8001,
 	.drv.name	= "Micrel KSZ8001 or KS8721",
 	.phy_id_mask	= 0x00ffffff,
-- 
1.9.1



From t.gamez at phytec.de  Tue Oct  7 01:40:34 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Tue, 7 Oct 2014 10:40:34 +0200
Subject: [PATCH 1/4] net: cpsw: Allow gigabit connection
In-Reply-To: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
References: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412671237-46551-2-git-send-email-t.gamez@phytec.de>

From: Jan Weitzel <j.weitzel at phytec.de>

Signed-off-by: Jan Weitzel <j.weitzel at phytec.de>
---
 drivers/net/cpsw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 167b2dd..50890c4 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -581,8 +581,7 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
 		else if (phydev->speed == SPEED_100)
 			mac_control |= BIT(15);
 		else if (phydev->speed == SPEED_1000)
-			mac_control &= ~BIT(7);	/* TODO: Do not enable
-						 * gig support now */
+			mac_control |= BIT(7);
 		if (phydev->duplex == DUPLEX_FULL)
 			mac_control |= BIT(0);	/* FULLDUPLEXEN	*/
 	}
-- 
1.9.1



From t.gamez at phytec.de  Tue Oct  7 01:40:33 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Tue, 7 Oct 2014 10:40:33 +0200
Subject: [PATCH 0/4] Add phyFLEX-AM335x support
Message-ID: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>

This patchset adds phyFLEX-AM335x support. This is
based on Jan's work and was rewitten for device
tree and multi image support by Stefan. I cleaned up the
code and rebased it to master.

Teresa

Jan Weitzel (2):
  net: cpsw: Allow gigabit connection
  net: micrel: Add ksz8081 support

Stefan M?ller-Klieser (2):
  boards: Add phytec-phyflex-am335x
  pfla03: add to am335x_defconfig

 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/phytec-phyflex-am335x/Makefile     |   3 +
 arch/arm/boards/phytec-phyflex-am335x/board.c      | 100 ++++++
 .../defaultenv-phyflex-am335x/boot/mmc             |   8 +
 .../defaultenv-phyflex-am335x/boot/nand            |   8 +
 .../defaultenv-phyflex-am335x/boot/spi             |   8 +
 .../defaultenv-phyflex-am335x/config-board         |  17 +
 arch/arm/boards/phytec-phyflex-am335x/lowlevel.c   | 180 +++++++++++
 arch/arm/configs/am335x_defconfig                  |   1 +
 arch/arm/configs/am335x_mlo_defconfig              |   1 +
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/am335x-phytec-phyflex.dts             | 356 +++++++++++++++++++++
 arch/arm/mach-omap/Kconfig                         |   5 +
 drivers/net/cpsw.c                                 |   3 +-
 drivers/net/phy/micrel.c                           |  10 +-
 images/Makefile.am33xx                             |  12 +
 16 files changed, 711 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/Makefile
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/board.c
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/mmc
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/spi
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/lowlevel.c
 create mode 100644 arch/arm/dts/am335x-phytec-phyflex.dts

-- 
1.9.1



From t.gamez at phytec.de  Tue Oct  7 01:40:36 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Tue, 7 Oct 2014 10:40:36 +0200
Subject: [PATCH 3/4] boards: Add phytec-phyflex-am335x
In-Reply-To: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
References: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412671237-46551-4-git-send-email-t.gamez@phytec.de>

From: Stefan M?ller-Klieser <s.mueller-klieser at phytec.de>

Add support for PHYTEC's phyFLEX-AM335x.

Signed-off-by: Stefan M?ller-Klieser <s.mueller-klieser at phytec.de>
[clean ups]
Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/phytec-phyflex-am335x/Makefile     |   3 +
 arch/arm/boards/phytec-phyflex-am335x/board.c      | 100 ++++++
 .../defaultenv-phyflex-am335x/boot/mmc             |   8 +
 .../defaultenv-phyflex-am335x/boot/nand            |   8 +
 .../defaultenv-phyflex-am335x/boot/spi             |   8 +
 .../defaultenv-phyflex-am335x/config-board         |  17 +
 arch/arm/boards/phytec-phyflex-am335x/lowlevel.c   | 180 +++++++++++
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/am335x-phytec-phyflex.dts             | 356 +++++++++++++++++++++
 arch/arm/mach-omap/Kconfig                         |   5 +
 images/Makefile.am33xx                             |  12 +
 12 files changed, 699 insertions(+)
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/Makefile
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/board.c
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/mmc
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/spi
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board
 create mode 100644 arch/arm/boards/phytec-phyflex-am335x/lowlevel.c
 create mode 100644 arch/arm/dts/am335x-phytec-phyflex.dts

diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index c80b9c9..25045ac 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_MACH_PCM038)			+= phytec-phycore-imx27/
 obj-$(CONFIG_MACH_PCM043)			+= phytec-phycore-imx35/
 obj-$(CONFIG_MACH_PCM049)			+= phytec-phycore-omap4460/
 obj-$(CONFIG_MACH_PCM051)			+= phytec-phycore-am335x/
+obj-$(CONFIG_MACH_PFLA03)			+= phytec-phyflex-am335x/
 obj-$(CONFIG_MACH_PHYTEC_PFLA02)		+= phytec-phyflex-imx6/
 obj-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3)	+= plathome-openblocks-ax3/
 obj-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6)	+= plathome-openblocks-a6/
diff --git a/arch/arm/boards/phytec-phyflex-am335x/Makefile b/arch/arm/boards/phytec-phyflex-am335x/Makefile
new file mode 100644
index 0000000..54734b5
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/Makefile
@@ -0,0 +1,3 @@
+lwl-y += lowlevel.o
+obj-y += board.o
+bbenv-y += defaultenv-phyflex-am335x
diff --git a/arch/arm/boards/phytec-phyflex-am335x/board.c b/arch/arm/boards/phytec-phyflex-am335x/board.c
new file mode 100644
index 0000000..12fad8f
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/board.c
@@ -0,0 +1,100 @@
+/*
+ * pfla03 - phyFLEX-AM335x Board Initalization Code
+ *
+ * Copyright (C) 2014 Stefan M?ller-Klieser, Phytec Messtechnik GmbH
+ *
+ * Based on arch/arm/boards/omap/board-beagle.c
+ *
+ * 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 <bootsource.h>
+#include <common.h>
+#include <nand.h>
+#include <init.h>
+#include <io.h>
+#include <sizes.h>
+#include <envfs.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <linux/phy.h>
+#include <linux/micrel_phy.h>
+#include <mach/am33xx-generic.h>
+#include <mach/am33xx-silicon.h>
+#include <mach/bbu.h>
+
+static int ksz9031rn_phy_fixup(struct phy_device *dev)
+{
+	phy_write_mmd_indirect(dev, 6, 2, 0);
+	phy_write_mmd_indirect(dev, 8, 2, 0x003ff);
+
+	return 0;
+}
+
+static int pfla03_coredevice_init(void)
+{
+	if (!of_machine_is_compatible("phytec,phyflex-am335x-som"))
+		return 0;
+
+	phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+					ksz9031rn_phy_fixup);
+	am33xx_register_ethaddr(0, 0);
+	am33xx_register_ethaddr(1, 1);
+
+	return 0;
+}
+coredevice_initcall(pfla03_coredevice_init);
+
+static struct omap_barebox_part pfla03_barebox_part = {
+	.nand_offset = SZ_512K,
+	.nand_size = SZ_512K,
+	.nor_offset = SZ_128K,
+	.nor_size = SZ_512K,
+};
+
+static char *xloadslots[] = {
+	"/dev/nand0.xload.bb",
+	"/dev/nand0.xload_backup1.bb",
+	"/dev/nand0.xload_backup2.bb",
+	"/dev/nand0.xload_backup3.bb"
+};
+
+static int pfla03_devices_init(void)
+{
+	if (!of_machine_is_compatible("phytec,phyflex-am335x-som"))
+		return 0;
+
+	switch (bootsource_get()) {
+	case BOOTSOURCE_SPI:
+		of_device_enable_path("/chosen/environment-spi");
+		break;
+	case BOOTSOURCE_MMC:
+		omap_set_bootmmc_devname("mmc0");
+		break;
+	default:
+		of_device_enable_path("/chosen/environment-nand");
+		break;
+	}
+
+	omap_set_barebox_part(&pfla03_barebox_part);
+	armlinux_set_architecture(MACH_TYPE_PFLA03);
+	defaultenv_append_directory(defaultenv_phyflex_am335x);
+
+	am33xx_bbu_spi_nor_mlo_register_handler("MLO.spi", "/dev/m25p0.xload");
+	am33xx_bbu_spi_nor_register_handler("spi", "/dev/m25p0.barebox");
+	am33xx_bbu_nand_xloadslots_register_handler("MLO.nand",
+		xloadslots, ARRAY_SIZE(xloadslots));
+	am33xx_bbu_nand_register_handler("nand", "/dev/nand0.barebox.bb");
+
+	return 0;
+}
+device_initcall(pfla03_devices_init);
diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/mmc b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/mmc
new file mode 100644
index 0000000..6a60761
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/mmc
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+global.bootm.image=/boot/linuximage
+#global.bootm.oftree=/boot/oftree
+
+bootargs-ip
+
+global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext3 rw rootwait"
diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
new file mode 100644
index 0000000..d9ef145
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+global.bootm.image="/dev/nand0.kernel.bb"
+#global.bootm.oftree="/env/oftree"
+
+bootargs-ip
+
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/spi b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/spi
new file mode 100644
index 0000000..c87299a
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/spi
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+global.bootm.image="/dev/m25p0.kernel"
+
+bootargs-ip
+
+# Use rootfs form NAND for now as rootfs partition < 4MB
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board
new file mode 100644
index 0000000..b620ac1
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/config-board
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# board defaults, do not change in running system. Change /env/config
+# instead
+
+global.hostname=pfla03
+global.linux.bootargs.base="console=ttyO0,115200"
+
+if [ $bootsource = mmc ]; then
+	global.boot.default="mmc nand spi net"
+elif [ $boosource = nand ]; then
+	global.boot.default="nand spi mmc net"
+elif [ $boosource = spi ]; then
+	global.boot.default="spi nand mmc net"
+elif [ $boosource = net ]; then
+	global.boot.default="net nand spi mmc"
+fi
diff --git a/arch/arm/boards/phytec-phyflex-am335x/lowlevel.c b/arch/arm/boards/phytec-phyflex-am335x/lowlevel.c
new file mode 100644
index 0000000..4d34968
--- /dev/null
+++ b/arch/arm/boards/phytec-phyflex-am335x/lowlevel.c
@@ -0,0 +1,180 @@
+/*
+ * pfla03 - phyFLEX-AM335x lowlevel code
+ *
+ * Copyright (C) 2014 Stefan M?ller-Klieser, Phytec Messtechnik GmbH
+ *
+ * Based on arch/arm/boards/omap/board-beagle.c
+ *
+ * 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 <sizes.h>
+#include <io.h>
+#include <init.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <mach/am33xx-silicon.h>
+#include <mach/am33xx-clock.h>
+#include <mach/generic.h>
+#include <mach/sdrc.h>
+#include <mach/sys_info.h>
+#include <mach/syslib.h>
+#include <mach/am33xx-mux.h>
+#include <mach/am33xx-generic.h>
+#include <mach/wdt.h>
+#include <debug_ll.h>
+
+#define CLK_M_OSC_MHZ	25
+#define DDR_IOCTRL	0x18B
+
+static const struct am33xx_cmd_control pfla03_cmd = {
+	.slave_ratio0	= 0x80,
+	.dll_lock_diff0	= 0x0,
+	.invert_clkout0	= 0x0,
+	.slave_ratio1	= 0x80,
+	.dll_lock_diff1	= 0x0,
+	.invert_clkout1	= 0x0,
+	.slave_ratio2	= 0x80,
+	.dll_lock_diff2	= 0x0,
+	.invert_clkout2	= 0x0,
+};
+
+struct pfla03_sdram_timings {
+	struct am33xx_emif_regs regs;
+	struct am33xx_ddr_data data;
+};
+
+enum {
+	MT41K128M16JT_256MB,
+	MT41K256M16HA_512MB,
+};
+
+struct pfla03_sdram_timings pfla03_timings[] = {
+	/* 256 MB */
+	[MT41K128M16JT_256MB] = {
+		.regs = {
+			.emif_read_latency	= 0x7,
+			.emif_tim1		= 0x0AAAD4DB,
+			.emif_tim2		= 0x26437FDA,
+			.emif_tim3		= 0x501F83FF,
+			.sdram_config		= 0x61C052B2,
+			.zq_config		= 0x50074BE4,
+			.sdram_ref_ctrl		= 0x00000C30,
+		},
+		.data = {
+			.rd_slave_ratio0	= 0x34,
+			.wr_dqs_slave_ratio0	= 0x47,
+			.fifo_we_slave_ratio0	= 0x9a,
+			.wr_slave_ratio0	= 0x7e,
+			.use_rank0_delay	= 0x0,
+			.dll_lock_diff0		= 0x0,
+		},
+	},
+	/* 512 MB */
+	[MT41K256M16HA_512MB] = {
+		.regs = {
+			.emif_read_latency	= 0x7,
+			.emif_tim1		= 0x0AAAE4DB,
+			.emif_tim2		= 0x266B7FDA,
+			.emif_tim3		= 0x501F867F,
+			.sdram_config		= 0x61C05332,
+			.zq_config		= 0x50074BE4,
+			.sdram_ref_ctrl		= 0x00000C30,
+		},
+		.data = {
+			.rd_slave_ratio0	= 0x36,
+			.wr_dqs_slave_ratio0	= 0x47,
+			.fifo_we_slave_ratio0	= 0x95,
+			.wr_slave_ratio0	= 0x7f,
+			.use_rank0_delay	= 0x0,
+			.dll_lock_diff0		= 0x0,
+		},
+	},
+};
+
+extern char __dtb_am335x_phytec_phyflex_start[];
+
+/**
+ * @brief The basic entry point for board initialization.
+ *
+ * This is called as part of machine init (after arch init).
+ * This is again called with stack in SRAM, so not too many
+ * constructs possible here.
+ *
+ * @return void
+ */
+static noinline void pfla03_board_init(int sdram)
+{
+	void *fdt;
+	struct pfla03_sdram_timings *timing = &pfla03_timings[sdram];
+
+	/*
+	 * WDT1 is already running when the bootloader gets control
+	 * Disable it to avoid "random" resets
+	 */
+	writel(WDT_DISABLE_CODE1, AM33XX_WDT_REG(WSPR));
+	while (readl(AM33XX_WDT_REG(WWPS)) != 0x0);
+
+	writel(WDT_DISABLE_CODE2, AM33XX_WDT_REG(WSPR));
+	while (readl(AM33XX_WDT_REG(WWPS)) != 0x0);
+
+	am33xx_pll_init(MPUPLL_M_600, CLK_M_OSC_MHZ, DDRPLL_M_400);
+
+	am335x_sdram_init(DDR_IOCTRL, &pfla03_cmd,
+			&timing->regs,
+			&timing->data);
+
+	am33xx_uart_soft_reset((void *)AM33XX_UART0_BASE);
+	am33xx_enable_uart0_pin_mux();
+	omap_uart_lowlevel_init((void *)AM33XX_UART0_BASE);
+	putc_ll('>');
+
+	fdt = __dtb_am335x_phytec_phyflex_start - get_runtime_offset();
+
+	am335x_barebox_entry(fdt);
+}
+
+static noinline void pfla03_board_entry(unsigned long bootinfo, int sdram)
+{
+	am33xx_save_bootinfo((void *)bootinfo);
+
+	arm_cpu_lowlevel_init();
+
+	/*
+	 * Setup C environment, the board init code uses global variables.
+	 * Stackpointer has already been initialized by the ROM code.
+	 */
+	relocate_to_current_adr();
+	setup_c();
+
+	pfla03_board_init(sdram);
+}
+
+ENTRY_FUNCTION(start_am33xx_phytec_phyflex_sram_256mb, bootinfo, r1, r2)
+{
+	pfla03_board_entry(bootinfo, MT41K128M16JT_256MB);
+}
+
+ENTRY_FUNCTION(start_am33xx_phytec_phyflex_sram_512mb, bootinfo, r1, r2)
+{
+	pfla03_board_entry(bootinfo, MT41K256M16HA_512MB);
+}
+
+ENTRY_FUNCTION(start_am33xx_phytec_phyflex_sdram, r0, r1, r2)
+{
+	void *fdt;
+
+	fdt = __dtb_am335x_phytec_phyflex_start - get_runtime_offset();
+
+	am335x_barebox_entry(fdt);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ede2b59..a9e9ee7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -27,6 +27,7 @@ pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o am335x-phytec-phycore-som-no-spi.dtb.o
+pbl-dtb-$(CONFIG_MACH_PFLA03) += am335x-phytec-phyflex.dtb.o
 pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += kirkwood-openblocks_a6-bb.dtb.o
diff --git a/arch/arm/dts/am335x-phytec-phyflex.dts b/arch/arm/dts/am335x-phytec-phyflex.dts
new file mode 100644
index 0000000..4dde328
--- /dev/null
+++ b/arch/arm/dts/am335x-phytec-phyflex.dts
@@ -0,0 +1,356 @@
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+	model = "Phytec phyFLEX AM335x";
+	compatible = "phytec,phyflex-am335x-som", "ti,am33xx";
+
+	chosen {
+		linux,stdout-path = &uart0;
+
+		environment-spi {
+			compatible = "barebox,environment";
+			device-path = &flash, "partname:bareboxenv";
+			status = "disabled";
+		};
+
+		environment-nand {
+			compatible = "barebox,environment";
+			device-path = &nand, "partname:bareboxenv";
+			status = "disabled";
+		};
+	};
+
+	vcc5v: fixedregulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+	};
+
+	vcc3v3: fixedregulator at 1 {
+		compatible = "regulator-fixed";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+};
+
+&am33xx_pinmux {
+	i2c0_pins: pinmux_i2c0_pins {
+			pinctrl-single,pins = <
+			0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda */
+			0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl */
+		>;
+	};
+
+	spi0_pins: pinmux_spi0_pins {
+		pinctrl-single,pins = <
+			0x150 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* spi0_clk.spi0_clk */
+			0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* spi0_d0.spi0_d0 */
+			0x158 (PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_d1.spi0_d1 */
+			0x15c (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_cs0.spi0_cs0 */
+		>;
+	};
+
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd */
+			0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd */
+		>;
+	};
+
+	mmc1_pins: pinmux_mmc1_pins {
+		pinctrl-single,pins = <
+			0x0f0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat3 */
+			0x0f4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat2 */
+			0x0f8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat1 */
+			0x0fc (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_dat0 */
+			0x100 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_clk */
+			0x104 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mmc0_cmd */
+			>;
+	};
+
+	emac_rgmii1_pins: pinmux_emac_rgmii1_pins {
+		pinctrl-single,pins = <
+			0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_tx_en.rgmii1_tctl */
+			0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rx_dv.rgmii1_rctl */
+			0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd3.rgmii1_td3 */
+			0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd2.rgmii1_td2 */
+			0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd1.rgmii1_td1 */
+			0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd0.rgmii1_td0 */
+			0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_tx_clk.rgmii1_tclk */
+			0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rx_clk.rgmii1_rclk */
+			0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd3.rgmii1_rd3 */
+			0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd2.rgmii1_rd2 */
+			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd1.rgmii1_rd1 */
+			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd0.rgmii1_rd0 */
+		>;
+	};
+
+	emac_rmii2_pins: pinmux_emac_rmii2_pins {
+		pinctrl-single,pins = <
+			0x040 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* gpmc_a0.rmii2_txen */
+			0x050 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* gpmc_a4.rmii2_txd1 */
+			0x054 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* gpmc_a5.rmii2_txd0 */
+			0x068 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* gpmc_a10.rmii2_rxd1 */
+			0x06c (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* gpmc_a11.rmii2_rxd0 */
+			0x074 (PIN_INPUT_PULLUP | MUX_MODE3)	/* gpmc_wpn.rmii2_rxer */
+			0x108 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_col.rmii2_refclk */
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data */
+			0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk */
+		>;
+	};
+
+	nandflash_pins_s0: nandflash_pins_s0 {
+		pinctrl-single,pins = <
+			0x000 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0 */
+			0x004 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1 */
+			0x008 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2 */
+			0x00c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3 */
+			0x010 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4 */
+			0x014 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5 */
+			0x018 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6 */
+			0x01c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7 */
+			0x070 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0 */
+			0x07c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* gpmc_csn0 */
+			0x090 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* gpmc_advn_ale */
+			0x094 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* gpmc_oen_ren */
+			0x098 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* gpmc_wen */
+			0x09c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* gpmc_be0n_cle */
+		>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+	clock-frequency = <400000>;
+
+	tps: pmic at 2d {
+		reg = <0x2d>;
+	};
+
+	at24c32: eeprom at 52 {
+		compatible = "atmel,24c32";
+		byte_len = <4096>;
+		pagesize = <32>;
+		reg = <0x52>;
+	};
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	status = "okay";
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>;
+	status = "okay";
+	flash: m25p80 {
+		compatible = "m25p80";
+		spi-max-frequency = <48000000>;
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		m25p,fast-read;
+
+		partition at 0 {
+			label = "xload";
+			reg = <0x0 0x20000>;
+		};
+
+		partition at 1 {
+			label = "barebox";
+			reg = <0x20000 0x80000>;
+		};
+
+		partition at 2 {
+			label = "bareboxenv";
+			reg = <0xa0000 0x20000>;
+		};
+
+		partition at 3 {
+			label = "oftree";
+			reg = <0xc0000 0x20000>;
+                };
+
+		partition at 4 {
+			label = "kernel";
+			reg = <0xe0000 0x400000>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	status = "okay";
+};
+
+&phy_sel {
+	rmii-clock-ext;
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <1>;
+	phy-mode = "rgmii";
+	dual_emac_res_vlan = <1>;
+};
+
+&cpsw_emac1 {
+	phy_id = <&davinci_mdio>, <2>;
+	phy-mode = "rmii";
+	dual_emac_res_vlan = <2>;
+};
+
+&mac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emac_rgmii1_pins &emac_rmii2_pins>;
+	dual_emac;
+	status = "okay";
+};
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand: nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <8>;
+		ti,nand-ecc-opt = "bch8";
+		gpmc,device-nand = "true";
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <30>;
+		gpmc,cs-wr-off-ns = <30>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <30>;
+		gpmc,adv-wr-off-ns = <30>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <20>;
+		gpmc,oe-on-ns = <10>;
+		gpmc,oe-off-ns = <30>;
+		gpmc,access-ns = <30>;
+		gpmc,rd-cycle-ns = <30>;
+		gpmc,wr-cycle-ns = <30>;
+		gpmc,wait-pin = <1>;
+		gpmc,wait-on-read = "true";
+		gpmc,wait-on-write = "true";
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <50>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,wr-access-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		elm_id = <&elm>;
+
+		partition at 0 {
+			label = "xload";
+			reg = <0x0 0x20000>;
+		};
+
+		partition at 1 {
+			label = "xload_backup1";
+			reg = <0x20000 0x20000>;
+		};
+
+		partition at 2 {
+			label = "xload_backup2";
+			reg = <0x40000 0x20000>;
+		};
+
+		partition at 3 {
+			label = "xload_backup3";
+			reg = <0x60000 0x20000>;
+		};
+
+		partition at 4 {
+			label = "barebox";
+			reg = <0x80000 0x80000>;
+		};
+
+		partition at 5 {
+			label = "bareboxenv";
+			reg = <0x100000 0x20000>;
+		};
+
+		partition at 6 {
+			label = "oftree";
+			reg = <0x120000 0x20000>;
+		};
+
+		partition at 7 {
+			label = "kernel";
+			reg = <0x140000 0x800000>;
+		};
+
+		partition at 8 {
+			label = "root";
+			reg = <0x940000 0x0>;
+		};
+	};
+};
+
+/include/ "tps65217.dtsi"
+&tps {
+	vcc1-supply = <&vcc5v>;
+	vcc2-supply = <&vcc5v>;
+	vcc3-supply = <&vcc5v>;
+	vcc4-supply = <&vcc5v>;
+	vcc5-supply = <&vcc5v>;
+	vcc6-supply = <&vcc5v>;
+	vcc7-supply = <&vcc5v>;
+	vccio-supply = <&vcc5v>;
+
+	regulators {
+		vdd1_reg: regulator at 2 {
+			/* VDD_MPU voltage limits 0.95V - 1.325V with +/-4% tolerance */
+			regulator-name = "vdd_mpu";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1378000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vdd2_reg: regulator at 3 {
+			/* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+			regulator-name = "vdd_core";
+			regulator-min-microvolt = <912500>;
+			regulator-max-microvolt = <1150000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		vmmc_reg: regulator at 12 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+	};
+};
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index e30027e..f9b5ec3 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -143,6 +143,11 @@ config MACH_PCM051
 	help
 	  Say Y here if you are using Phytecs phyCORE pcm051 board
 
+config MACH_PFLA03
+	bool "Phytec phyFLEX am335x pfla03"
+	select ARCH_AM33XX
+	help
+	  Say Y here if you are using Phytecs phyFLEX pfla03 board
 endif
 
 choice
diff --git a/images/Makefile.am33xx b/images/Makefile.am33xx
index 8d58733..002c103 100644
--- a/images/Makefile.am33xx
+++ b/images/Makefile.am33xx
@@ -39,6 +39,18 @@ pblx-$(CONFIG_MACH_PCM051) += start_am33xx_phytec_phycore_sram_2x512mb
 FILE_barebox-am33xx-phytec-phycore-mlo-2x512mb.img = start_am33xx_phytec_phycore_sram_2x512mb.pblx.mlo
 am33xx-mlo-$(CONFIG_MACH_PCM051) += barebox-am33xx-phytec-phycore-mlo-2x512mb.img
 
+pblx-$(CONFIG_MACH_PFLA03) += start_am33xx_phytec_phyflex_sdram
+FILE_barebox-am33xx-phytec-phyflex.img = start_am33xx_phytec_phyflex_sdram.pblx
+am33xx-barebox-$(CONFIG_MACH_PFLA03) += barebox-am33xx-phytec-phyflex.img
+
+pblx-$(CONFIG_MACH_PFLA03) += start_am33xx_phytec_phyflex_sram_256mb
+FILE_barebox-am33xx-phytec-phyflex-mlo-256mb.img = start_am33xx_phytec_phyflex_sram_256mb.pblx.mlo
+am33xx-mlo-$(CONFIG_MACH_PFLA03) += barebox-am33xx-phytec-phyflex-mlo-256mb.img
+
+pblx-$(CONFIG_MACH_PFLA03) += start_am33xx_phytec_phyflex_sram_512mb
+FILE_barebox-am33xx-phytec-phyflex-mlo-512mb.img = start_am33xx_phytec_phyflex_sram_512mb.pblx.mlo
+am33xx-mlo-$(CONFIG_MACH_PFLA03) += barebox-am33xx-phytec-phyflex-mlo-512mb.img
+
 pblx-$(CONFIG_MACH_BEAGLEBONE) += start_am33xx_beaglebone_sdram
 FILE_barebox-am33xx-beaglebone.img = start_am33xx_beaglebone_sdram.pblx
 am33xx-barebox-$(CONFIG_MACH_BEAGLEBONE) += barebox-am33xx-beaglebone.img
-- 
1.9.1



From gregory.hermant at calao-systems.com  Tue Oct  7 05:03:18 2014
From: gregory.hermant at calao-systems.com (=?ISO-8859-15?Q?Gr=E9gory_Hermant?=)
Date: Tue, 07 Oct 2014 14:03:18 +0200
Subject: at91 usbserial issue
In-Reply-To: <20141006055231.GM4992@pengutronix.de>
References: <542E4AAD.7070703@calao-systems.com>
 <20141006055231.GM4992@pengutronix.de>
Message-ID: <5433D686.6080805@calao-systems.com>

Hi Sacha,
Thanks for your feedback.
Greg

On 06/10/2014 07:52, Sascha Hauer wrote:
> Hi Greg,
> 
> On Fri, Oct 03, 2014 at 09:05:17AM +0200, Gr?gory Hermant wrote:
>> Hi all,
>> The usbserial seems to be broken for board equipped with an Atmel sam9260/9g20 Soc.
>> I ran the lastest version of barebox (v2014.10.0) on a USB_A9G20_LPW.
>> Below the trace
>> udc0: registering UDC driver [g_serial]
>> g_serial usbgadget: acm/23ba9538: can't bind, err -19
>> g_serial udc0: failed to start g_serial: -19
>> usbserial: No such device
>> I didn't yet investigate this issue but i was wondering if someone noticed the problem.
> 
> There have been quite some changes in the USB gadget stuff. I know
> USB serial currently works with i.MX and MUSB. Does v2014.08.0 still
> work? That was before the changes. If yes, I think bisecting it is
> the fastest way to find the culprit.
> 
> Sascha
> 


From jbe at pengutronix.de  Tue Oct  7 07:21:59 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:21:59 +0200
Subject: [RFC] Add PowerPC MPC5125 support
Message-ID: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>

This is a try to add the MPC5125 SoC to Barebox. This kind of SoC shares some
embedded devices with the MPC5200 and the MPC5121/MPC5123 (at least it uses
the same names for them) but differs in many annoying details. So this
adaption can only be used on a MPC5125 and is completely untested on MPC5121
and MPC5123.

Patch "arch/MPC5xxx: fix linker script for MPC5200" tries to repair the linker
script for the MPC5200 because the resulting binary image is broken without
this change. But I do not really know why it is broken and how to repair
it correctly. Comments?

At least the existing PSC code for the serial UART can be shared between both
SoCs, even if their internals differ. With some re-factoring it is possible
to use the main code on both SoCs.

The same might be possible with the FEC driver, but needs more effort, because
the DMA work differently on both SoCs. I'm not sure if its worth the effort,
so I just add a new FEC driver for the MPC5125 with this series.

Comments are welcome.

Juergen



From jbe at pengutronix.de  Tue Oct  7 07:22:04 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:04 +0200
Subject: [PATCH 05/19] arch/MPC5xxx: just a format clean up
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-6-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/start.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index 6a32718..8402345 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -68,7 +68,8 @@
 	 */
 _base:
 	mfspr	r4, MBAR
-	b setup_mbar
+	b	setup_mbar
+
 	. = EXC_OFF_SYS_RESET
 	.globl	_start
 _start:
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:02 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:02 +0200
Subject: [PATCH 03/19] arch/MPC5xxx: replace 'depends on' by 'select'
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-4-git-send-email-jbe@pengutronix.de>

This change will simplify the addition of new SOCs.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/Kconfig | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
index 1ecce3a..5eebf2a 100644
--- a/arch/ppc/mach-mpc5xxx/Kconfig
+++ b/arch/ppc/mach-mpc5xxx/Kconfig
@@ -14,6 +14,7 @@ choice
 
 config MACH_PHYCORE_MPC5200B_TINY
 	bool "Phycore mpc5200b tiny"
+	select MPC5200
 	help
 	  Say Y here if you are using the Phytec Phycore MPC5200B Tiny
 	  board aka pcm030.
@@ -21,19 +22,15 @@ endchoice
 
 config MPC5200
 	bool
-	depends on MACH_PHYCORE_MPC5200B_TINY
-	default y
+	select ARCH_MPC5200
 
 config ARCH_MPC5200
 	bool
-	depends on MACH_PHYCORE_MPC5200B_TINY
-	default y
+	select MPC5xxx
 
 config MPC5xxx
 	bool
-	depends on MACH_PHYCORE_MPC5200B_TINY
 	select HAVE_CONFIGURABLE_MEMORY_LAYOUT
-	default y
 
 menu "Board specific settings"
 
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:05 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:05 +0200
Subject: [PATCH 06/19] arch/MPC5xxx: move away existing files to be able to
 add a new SoC type
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-7-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/Makefile                           | 8 ++++----
 arch/ppc/mach-mpc5xxx/{cpu.c => cpu-mpc5200.c}           | 0
 arch/ppc/mach-mpc5xxx/{cpu_init.c => cpu_init-mpc5200.c} | 0
 arch/ppc/mach-mpc5xxx/{speed.c => speed-mpc5200.c}       | 0
 4 files changed, 4 insertions(+), 4 deletions(-)
 rename arch/ppc/mach-mpc5xxx/{cpu.c => cpu-mpc5200.c} (100%)
 rename arch/ppc/mach-mpc5xxx/{cpu_init.c => cpu_init-mpc5200.c} (100%)
 rename arch/ppc/mach-mpc5xxx/{speed.c => speed-mpc5200.c} (100%)

diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile
index bf8d68d..c8d503e 100644
--- a/arch/ppc/mach-mpc5xxx/Makefile
+++ b/arch/ppc/mach-mpc5xxx/Makefile
@@ -1,7 +1,7 @@
-obj-y 				+= cpu.o
-obj-y				+= cpu_init.o
-obj-y				+= loadtask.o
-obj-y				+= speed.o
+obj-$(CONFIG_MPC5200)		+= cpu-mpc5200.o
+obj-$(CONFIG_MPC5200)		+= cpu_init-mpc5200.o
+obj-$(CONFIG_MPC5200)		+= loadtask.o
+obj-$(CONFIG_MPC5200)		+= speed-mpc5200.o
 obj-y				+= traps.o
 obj-y				+= time.o
 extra-y				+= start.o
diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu-mpc5200.c
similarity index 100%
rename from arch/ppc/mach-mpc5xxx/cpu.c
rename to arch/ppc/mach-mpc5xxx/cpu-mpc5200.c
diff --git a/arch/ppc/mach-mpc5xxx/cpu_init.c b/arch/ppc/mach-mpc5xxx/cpu_init-mpc5200.c
similarity index 100%
rename from arch/ppc/mach-mpc5xxx/cpu_init.c
rename to arch/ppc/mach-mpc5xxx/cpu_init-mpc5200.c
diff --git a/arch/ppc/mach-mpc5xxx/speed.c b/arch/ppc/mach-mpc5xxx/speed-mpc5200.c
similarity index 100%
rename from arch/ppc/mach-mpc5xxx/speed.c
rename to arch/ppc/mach-mpc5xxx/speed-mpc5200.c
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:12 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:12 +0200
Subject: [PATCH 13/19] MPC5xxx/serial: re-factor the code to share it between
 MPC5200/MPC5125
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-14-git-send-email-jbe@pengutronix.de>

The MPC5200 and MPC5125 PSC units differs in:

 - register layout and status and control bits
 - configuration (baudrate, data format)
 - FIFO handling
 - clocking

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/serial/serial_mpc5xxx.c | 84 ++++++++++++++++++++++++++++++-----------
 1 file changed, 62 insertions(+), 22 deletions(-)

diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index 3b83bee..7cd448c 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -39,16 +39,66 @@
 #include <mach/clocks.h>
 #include <mach/mpc5xxx_psc.h>
 
-static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
+static int psc_tx_rdy(struct mpc5xxx_psc *psc)
 {
-	unsigned long baseclk;
-	int div;
+	return in_be16(&psc->psc_status) & PSC_SR_TXEMP;
+}
+
+static int psc_rx_rdy(struct mpc5xxx_psc *psc)
+{
+	return in_be16(&psc->psc_status) & PSC_SR_RXRDY;
+}
+
+static void psc_tx_write(struct mpc5xxx_psc *psc, char c)
+{
+	out_8(&psc->psc_buffer_8, c);
+}
+
+static int psc_rx_read(struct mpc5xxx_psc *psc)
+{
+	return in_8(&psc->psc_buffer_8);
+}
+
+static unsigned long mpc5xxx_get_base_clock(struct mpc5xxx_psc *psc)
+{
+#if defined(CONFIG_MGT5100)
+	return (CFG_MPC5XXX_CLKIN + 16) / 32;
+#elif defined(CONFIG_MPC5200)
+	return (get_ipb_clock() + 16) / 32;
+#else
+# error "Unknwon CPU"
+#endif
+}
 
+static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc)
+{
 #if defined(CONFIG_MGT5100)
-	baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32;
+	out_be16(&psc->psc_clock_select, 0xdd00);
 #elif defined(CONFIG_MPC5200)
-	baseclk = (get_ipb_clock() + 16) / 32;
+	out_be16(&psc->psc_clock_select, 0);
+#else
+# error "Unknwon CPU"
 #endif
+}
+
+static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc)
+{
+#if defined(CONFIG_MGT5100)
+	out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE);
+#elif defined(CONFIG_MPC5200)
+	out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE);
+	out_8(&psc->mode, PSC_MODE_ONE_STOP);
+#else
+# error "Unknwon CPU"
+#endif
+}
+
+static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
+{
+	unsigned long baseclk;
+	int div;
+
+	baseclk = mpc5xxx_get_base_clock(psc);
 
 	/* set up UART divisor */
 	div = (baseclk + (baudrate/2)) / baudrate;
@@ -73,23 +123,13 @@ static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc)
 	/* reset PSC */
 	out_8(&psc->command, PSC_SEL_MODE_REG_1);
 
-	/* select clock sources */
-#if defined(CONFIG_MGT5100)
-	out_be16(&psc->psc_clock_select, 0xdd00);
-#elif defined(CONFIG_MPC5200)
-	out_be16(&psc->psc_clock_select, 0);
-#endif
+	mpc5xxx_select_clock_source(psc);
 
 	/* switch to UART mode */
 	out_be32(&psc->sicr, 0);
 
 	/* configure parity, bit length and so on */
-#if defined(CONFIG_MGT5100)
-	out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE);
-#elif defined(CONFIG_MPC5200)
-	out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE);
-#endif
-	out_8(&psc->mode, PSC_MODE_ONE_STOP);
+	mpc5xxx_configure_serial_protocol(psc);
 
 	/* disable all interrupts */
 	out_be16(&psc->psc_imr, 0);
@@ -118,10 +158,10 @@ static void mpc5xxx_serial_putc (struct console_device *cdev, const char c)
 	struct mpc5xxx_psc *psc = dev->priv;
 
 	/* Wait for last character to go. */
-	while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP))
+	while (!psc_tx_rdy(psc))
 		;
 
-	out_8(&psc->psc_buffer_8, c);
+	psc_tx_write(psc, c);
 }
 
 static int mpc5xxx_serial_getc (struct console_device *cdev)
@@ -130,10 +170,10 @@ static int mpc5xxx_serial_getc (struct console_device *cdev)
 	struct mpc5xxx_psc *psc = dev->priv;
 
 	/* Wait for a character to arrive. */
-	while (!(in_be16(&psc->psc_status) & PSC_SR_RXRDY))
+	while (!psc_rx_rdy(psc))
 		;
 
-	return in_8(&psc->psc_buffer_8);
+	return psc_rx_read(psc);
 }
 
 static int mpc5xxx_serial_tstc (struct console_device *cdev)
@@ -141,7 +181,7 @@ static int mpc5xxx_serial_tstc (struct console_device *cdev)
 	struct device_d *dev = cdev->dev;
 	struct mpc5xxx_psc *psc = dev->priv;
 
-	return in_be16(&psc->psc_status) & PSC_SR_RXRDY;
+	return psc_rx_rdy(psc);
 }
 
 static int mpc5xxx_serial_probe(struct device_d *dev)
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:03 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:03 +0200
Subject: [PATCH 04/19] arch/MPC5xxx: Simplify the calculation
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-5-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/start.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index 291f625..6a32718 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -66,6 +66,7 @@
 	 * Second stage loader entry. When entered here we assume that spr 311
 	 * is set to the current MBAR address.
 	 */
+_base:
 	mfspr	r4, MBAR
 	b setup_mbar
 	. = EXC_OFF_SYS_RESET
@@ -251,9 +252,8 @@ _continue_init:
 
 	bl	calc_source     /* Calculate Source Address             */
 calc_source:
-	mfspr	r4,  LR
-	subi	r4, r4, (calc_source - _start)
-	subi	r4, r4, 0x100
+	mflr	r4
+	subi	r4, r4, (calc_source - _base)
 
 	lis	r5, __init_size at h		/* Size         	*/
 	ori	r5, r5, __init_size at l
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:09 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:09 +0200
Subject: [PATCH 10/19] MPC5xxx/serial: use dedicated I/O functions instead of
 memory access
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-11-git-send-email-jbe@pengutronix.de>

This forces the driver to use the hardware synchronized commands.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/serial/serial_mpc5xxx.c | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index 18aca87..9d92fed 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -32,6 +32,7 @@
 #include <common.h>
 #include <mach/mpc5xxx.h>
 #include <driver.h>
+#include <io.h>
 #include <init.h>
 #include <console.h>
 #include <xfuncs.h>
@@ -50,8 +51,8 @@ static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
 
 	/* set up UART divisor */
 	div = (baseclk + (baudrate/2)) / baudrate;
-	psc->ctur = (div >> 8) & 0xFF;
-	psc->ctlr =  div & 0xff;
+	out_8(&psc->ctur, (div >> 8) & 0xFF);
+	out_8(&psc->ctlr,  div & 0xff);
 
 	return 0;
 }
@@ -69,33 +70,33 @@ static int mpc5xxx_serial_setbaudrate(struct console_device *cdev, int baudrate)
 static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc)
 {
 	/* reset PSC */
-	psc->command = PSC_SEL_MODE_REG_1;
+	out_8(&psc->command, PSC_SEL_MODE_REG_1);
 
 	/* select clock sources */
 #if defined(CONFIG_MGT5100)
-	psc->psc_clock_select = 0xdd00;
+	out_be16(&psc->psc_clock_select, 0xdd00);
 #elif defined(CONFIG_MPC5200)
-	psc->psc_clock_select = 0;
+	out_be16(&psc->psc_clock_select, 0);
 #endif
 
 	/* switch to UART mode */
-	psc->sicr = 0;
+	out_be32(&psc->sicr, 0);
 
 	/* configure parity, bit length and so on */
 #if defined(CONFIG_MGT5100)
-	psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE;
+	out_8(&psc->mode, PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE);
 #elif defined(CONFIG_MPC5200)
-	psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE;
+	out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE);
 #endif
-	psc->mode = PSC_MODE_ONE_STOP;
+	out_8(&psc->mode, PSC_MODE_ONE_STOP);
 
 	/* disable all interrupts */
-	psc->psc_imr = 0;
+	out_be16(&psc->psc_imr, 0);
 
 	/* reset and enable Rx/Tx */
-//	psc->command = PSC_RST_RX;
-//	psc->command = PSC_RST_TX;
-	psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE;
+//	out_8(&psc->command, PSC_RST_RX);
+//	out_8(&psc->command, PSC_RST_TX);
+	out_8(&psc->command, PSC_RX_ENABLE | PSC_TX_ENABLE);
 
 	return 0;
 }
@@ -116,10 +117,10 @@ static void mpc5xxx_serial_putc (struct console_device *cdev, const char c)
 	struct mpc5xxx_psc *psc = dev->priv;
 
 	/* Wait for last character to go. */
-	while (!(psc->psc_status & PSC_SR_TXEMP))
+	while (!(in_be16(&psc->psc_status) & PSC_SR_TXEMP))
 		;
 
-	psc->psc_buffer_8 = c;
+	out_8(&psc->psc_buffer_8, c);
 }
 
 static int mpc5xxx_serial_getc (struct console_device *cdev)
@@ -128,10 +129,10 @@ static int mpc5xxx_serial_getc (struct console_device *cdev)
 	struct mpc5xxx_psc *psc = dev->priv;
 
 	/* Wait for a character to arrive. */
-	while (!(psc->psc_status & PSC_SR_RXRDY))
+	while (!(in_be16(&psc->psc_status) & PSC_SR_RXRDY))
 		;
 
-	return psc->psc_buffer_8;
+	return in_8(&psc->psc_buffer_8);
 }
 
 static int mpc5xxx_serial_tstc (struct console_device *cdev)
@@ -139,7 +140,7 @@ static int mpc5xxx_serial_tstc (struct console_device *cdev)
 	struct device_d *dev = cdev->dev;
 	struct mpc5xxx_psc *psc = dev->priv;
 
-	return (psc->psc_status & PSC_SR_RXRDY);
+	return in_be16(&psc->psc_status) & PSC_SR_RXRDY;
 }
 
 static int mpc5xxx_serial_probe(struct device_d *dev)
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:10 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:10 +0200
Subject: [PATCH 11/19] MPC5xxx/serial: provide an easier way to share register
 description
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-12-git-send-email-jbe@pengutronix.de>

Separate the register definition to be able to add more SoCs to use them.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h | 154 +++++++++++++++++++++++
 1 file changed, 154 insertions(+)
 create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h
new file mode 100644
index 0000000..a44d213
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h
@@ -0,0 +1,154 @@
+#include <linux/types.h>
+
+/* Programmable Serial Controller (PSC) status register bits */
+#define PSC_SR_CDE		0x0080
+#define PSC_SR_RXRDY		0x0100
+#define PSC_SR_RXFULL		0x0200
+#define PSC_SR_TXRDY		0x0400
+#define PSC_SR_TXEMP		0x0800
+#define PSC_SR_OE		0x1000
+#define PSC_SR_PE		0x2000
+#define PSC_SR_FE		0x4000
+#define PSC_SR_RB		0x8000
+
+/* PSC Command values */
+#define PSC_RX_ENABLE		0x0001
+#define PSC_RX_DISABLE		0x0002
+#define PSC_TX_ENABLE		0x0004
+#define PSC_TX_DISABLE		0x0008
+#define PSC_SEL_MODE_REG_1	0x0010
+#define PSC_RST_RX		0x0020
+#define PSC_RST_TX		0x0030
+#define PSC_RST_ERR_STAT	0x0040
+#define PSC_RST_BRK_CHG_INT	0x0050
+#define PSC_START_BRK		0x0060
+#define PSC_STOP_BRK		0x0070
+
+/* PSC Rx FIFO status bits */
+#define PSC_RX_FIFO_ERR		0x0040
+#define PSC_RX_FIFO_UF		0x0020
+#define PSC_RX_FIFO_OF		0x0010
+#define PSC_RX_FIFO_FR		0x0008
+#define PSC_RX_FIFO_FULL	0x0004
+#define PSC_RX_FIFO_ALARM	0x0002
+#define PSC_RX_FIFO_EMPTY	0x0001
+
+/* PSC interrupt mask bits */
+#define PSC_IMR_TXRDY		0x0100
+#define PSC_IMR_RXRDY		0x0200
+#define PSC_IMR_DB		0x0400
+#define PSC_IMR_IPC		0x8000
+
+/* PSC input port change bits */
+#define PSC_IPCR_CTS		0x01
+#define PSC_IPCR_DCD		0x02
+
+/* PSC mode fields */
+#define PSC_MODE_5_BITS		0x00
+#define PSC_MODE_6_BITS		0x01
+#define PSC_MODE_7_BITS		0x02
+#define PSC_MODE_8_BITS		0x03
+#define PSC_MODE_PAREVEN	0x00
+#define PSC_MODE_PARODD		0x04
+#define PSC_MODE_PARFORCE	0x08
+#define PSC_MODE_PARNONE	0x10
+#define PSC_MODE_ERR		0x20
+#define PSC_MODE_FFULL		0x40
+#define PSC_MODE_RXRTS		0x80
+
+#define PSC_MODE_ONE_STOP_5_BITS	0x00
+#define PSC_MODE_ONE_STOP		0x07
+#define PSC_MODE_TWO_STOP		0x0f
+
+struct mpc5xxx_psc {
+	u8	mode;		/* PSC + 0x00 */
+	u8	reserved0[3];
+	union {				/* PSC + 0x04 */
+		u16	status;
+		u16	clock_select;
+	} sr_csr;
+#define psc_status	sr_csr.status
+#define psc_clock_select sr_csr.clock_select
+	u16	reserved1;
+	u8	command;	/* PSC + 0x08 */
+	u8	reserved2[3];
+	union {				/* PSC + 0x0c */
+		u8	buffer_8;
+		u16	buffer_16;
+		u32	buffer_32;
+	} buffer;
+#define psc_buffer_8	buffer.buffer_8
+#define psc_buffer_16	buffer.buffer_16
+#define psc_buffer_32	buffer.buffer_32
+	union {				/* PSC + 0x10 */
+		u8	ipcr;
+		u8	acr;
+	} ipcr_acr;
+#define psc_ipcr	ipcr_acr.ipcr
+#define psc_acr		ipcr_acr.acr
+	u8	reserved3[3];
+	union {				/* PSC + 0x14 */
+		u16	isr;
+		u16	imr;
+	} isr_imr;
+#define psc_isr		isr_imr.isr
+#define psc_imr		isr_imr.imr
+	u16	reserved4;
+	u8	ctur;		/* PSC + 0x18 */
+	u8	reserved5[3];
+	u8	ctlr;		/* PSC + 0x1c */
+	u8	reserved6[3];
+	u16	ccr;		/* PSC + 0x20 */
+	u8	reserved7[14];
+	u8	ivr;		/* PSC + 0x30 */
+	u8	reserved8[3];
+	u8	ip;		/* PSC + 0x34 */
+	u8	reserved9[3];
+	u8	op1;		/* PSC + 0x38 */
+	u8	reserved10[3];
+	u8	op0;		/* PSC + 0x3c */
+	u8	reserved11[3];
+	u32	sicr;		/* PSC + 0x40 */
+	u8	ircr1;		/* PSC + 0x44 */
+	u8	reserved12[3];
+	u8	ircr2;		/* PSC + 0x44 */
+	u8	reserved13[3];
+	u8	irsdr;		/* PSC + 0x4c */
+	u8	reserved14[3];
+	u8	irmdr;		/* PSC + 0x50 */
+	u8	reserved15[3];
+	u8	irfdr;		/* PSC + 0x54 */
+	u8	reserved16[3];
+	u16	rfnum;		/* PSC + 0x58 */
+	u16	reserved17;
+	u16	tfnum;		/* PSC + 0x5c */
+	u16	reserved18;
+	u32	rfdata;		/* PSC + 0x60 */
+	u16	rfstat;		/* PSC + 0x64 */
+	u16	reserved20;
+	u8	rfcntl;		/* PSC + 0x68 */
+	u8	reserved21[5];
+	u16	rfalarm;	/* PSC + 0x6e */
+	u16	reserved22;
+	u16	rfrptr;		/* PSC + 0x72 */
+	u16	reserved23;
+	u16	rfwptr;		/* PSC + 0x76 */
+	u16	reserved24;
+	u16	rflrfptr;	/* PSC + 0x7a */
+	u16	reserved25;
+	u16	rflwfptr;	/* PSC + 0x7e */
+	u32	tfdata;		/* PSC + 0x80 */
+	u16	tfstat;		/* PSC + 0x84 */
+	u16	reserved26;
+	u8	tfcntl;		/* PSC + 0x88 */
+	u8	reserved27[5];
+	u16	tfalarm;	/* PSC + 0x8e */
+	u16	reserved28;
+	u16	tfrptr;		/* PSC + 0x92 */
+	u16	reserved29;
+	u16	tfwptr;		/* PSC + 0x96 */
+	u16	reserved30;
+	u16	tflrfptr;	/* PSC + 0x9a */
+	u16	reserved31;
+	u16	tflwfptr;	/* PSC + 0x9e */
+};
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:07 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:07 +0200
Subject: [PATCH 08/19] arch/MPC5xxx: separate clock functions
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-9-git-send-email-jbe@pengutronix.de>

In order to support the MPC5125 SoC we need a different set of clock functions.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/clocks.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
index 4e1a903..717a85b 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
@@ -1,10 +1,14 @@
 #ifndef __ASM_ARCH_CLOCKS_H
 #define __ASM_ARCH_CLOCKS_H
 
-unsigned long get_bus_clock(void);
+/* common clocks */
 unsigned long get_cpu_clock(void);
+unsigned long get_timebase_clock(void);
+
+#if defined(CONFIG_MGT5100) || defined(CONFIG_MPC5200)
+unsigned long get_bus_clock(void);
 unsigned long get_ipb_clock(void);
 unsigned long get_pci_clock(void);
-unsigned long get_timebase_clock(void);
+#endif
 
 #endif /* __ASM_ARCH_CLOCKS_H */
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:01 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:01 +0200
Subject: [PATCH 02/19] arch/MPC5xxx: use a mach specific linker script instead
 of a board specific one
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-3-git-send-email-jbe@pengutronix.de>

For easier maintenance in the future.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/Makefile                                      | 5 -----
 arch/ppc/boards/pcm030/Makefile                        | 1 -
 arch/ppc/mach-mpc5xxx/Makefile                         | 1 +
 arch/ppc/{boards/pcm030 => mach-mpc5xxx}/barebox.lds.S | 0
 4 files changed, 1 insertion(+), 6 deletions(-)
 rename arch/ppc/{boards/pcm030 => mach-mpc5xxx}/barebox.lds.S (100%)

diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index fb9b0b8..d0dd51e 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -64,9 +64,4 @@ endif
 
 common-y += $(BOARD) $(CPU) $(MACH)
 common-y += arch/ppc/lib/
-
-ifdef CONFIG_MPC85xx
 lds-y += $(MACH)/barebox.lds
-else
-lds-y += $(BOARD)/barebox.lds
-endif
diff --git a/arch/ppc/boards/pcm030/Makefile b/arch/ppc/boards/pcm030/Makefile
index e7d744b..3749605 100644
--- a/arch/ppc/boards/pcm030/Makefile
+++ b/arch/ppc/boards/pcm030/Makefile
@@ -1,2 +1 @@
 obj-y += pcm030.o
-extra-y += barebox.lds
diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile
index c532a6d..bf8d68d 100644
--- a/arch/ppc/mach-mpc5xxx/Makefile
+++ b/arch/ppc/mach-mpc5xxx/Makefile
@@ -5,6 +5,7 @@ obj-y				+= speed.o
 obj-y				+= traps.o
 obj-y				+= time.o
 extra-y				+= start.o
+extra-y				+= barebox.lds
 obj-$(CONFIG_MPC5200)		+= firmware_sc_task_bestcomm.impl.o
 obj-$(CONFIG_REGINFO)		+= reginfo.o
 
diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/mach-mpc5xxx/barebox.lds.S
similarity index 100%
rename from arch/ppc/boards/pcm030/barebox.lds.S
rename to arch/ppc/mach-mpc5xxx/barebox.lds.S
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:08 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:08 +0200
Subject: [PATCH 09/19] arch/MPC5xxx: just use macros instead of anonymous
 digits
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-10-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h |  1 +
 arch/ppc/mach-mpc5xxx/start.S                | 12 ++++++------
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
index 35762a1..28dfa6e 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
@@ -37,6 +37,7 @@
 #define EXC_OFF_SYS_RESET	0x0100
 #define _START_OFFSET		EXC_OFF_SYS_RESET
 
+#define DEFAULT_MBAR 0x80000000
 #define CFG_MBAR 0xf0000000
 
 /* useful macros for manipulating CSx_START/STOP */
diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index 8402345..810a5bb 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -75,18 +75,18 @@ _base:
 _start:
 	/*
 	 * Reset entry. When entered here we assume that MBAR is at reset default
-	 * 0x80000000.
+	 * DEFAULT_MBAR.
 	 */
-	lis	r4, 0x80000000 at h
-	ori	r4, r4, 0x80000000 at l
+	lis	r4, DEFAULT_MBAR at h
+	ori	r4, r4, DEFAULT_MBAR at l
 
 setup_mbar:
 	/* r4 == current MBAR */
 	mfmsr	r5			/* save msr contents		*/
 
-	/* Switch MBAR to 0xf0000000 */
-	lis	r3, 0xf0000000 at h
-	ori	r3, r3, 0xf0000000 at l
+	/* Switch MBAR to its new destination */
+	lis	r3, CFG_MBAR at h
+	ori	r3, r3, CFG_MBAR at l
 	mtspr	MBAR, r3
 	rlwinm	r3, r3, 16, 16, 31
 	stw	r3, 0(r4)
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:14 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:14 +0200
Subject: [PATCH 15/19] arch/MPC5xxx: add MPC5125 to the build-system
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-16-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/Makefile                            | 1 +
 arch/ppc/mach-mpc5xxx/Kconfig                | 8 ++++++++
 arch/ppc/mach-mpc5xxx/Makefile               | 6 ++++++
 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h | 2 ++
 4 files changed, 17 insertions(+)

diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index d0dd51e..74ca401 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -18,6 +18,7 @@ board-$(CONFIG_P1022DS)				:= freescale-p1022ds
 board-$(CONFIG_DA923RC)				:= geip-da923rc
 
 machine-$(CONFIG_ARCH_MPC5200)			:= mpc5xxx
+machine-$(CONFIG_ARCH_MPC512X)			:= mpc5xxx
 machine-$(CONFIG_ARCH_MPC85XX)			:= mpc85xx
 
 cpu-$(CONFIG_ARCH_MPC85XX)			:= 85xx
diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
index 5eebf2a..a65c21d 100644
--- a/arch/ppc/mach-mpc5xxx/Kconfig
+++ b/arch/ppc/mach-mpc5xxx/Kconfig
@@ -28,6 +28,14 @@ config ARCH_MPC5200
 	bool
 	select MPC5xxx
 
+config ARCH_MPC512X
+	bool
+
+config SOC_MPC5125
+	bool
+	select MPC5xxx
+	select ARCH_MPC512X
+
 config MPC5xxx
 	bool
 	select HAVE_CONFIGURABLE_MEMORY_LAYOUT
diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile
index c8d503e..0c2d830 100644
--- a/arch/ppc/mach-mpc5xxx/Makefile
+++ b/arch/ppc/mach-mpc5xxx/Makefile
@@ -1,4 +1,10 @@
 obj-$(CONFIG_MPC5200)		+= cpu-mpc5200.o
+obj-$(CONFIG_SOC_MPC5125)	+= cpu-mpc5125.o
+obj-$(CONFIG_SOC_MPC5125)	+= speed-mpc5125.o
+obj-$(CONFIG_SOC_MPC5125)	+= iomux-mpc5125.o
+obj-$(CONFIG_SOC_MPC5125)	+= sdram-mpc5125.o
+obj-$(CONFIG_SOC_MPC5125)	+= sys-mpc5125.o
+obj-$(CONFIG_SOC_MPC5125)	+= lpc-mpc5125.o
 obj-$(CONFIG_MPC5200)		+= cpu_init-mpc5200.o
 obj-$(CONFIG_MPC5200)		+= loadtask.o
 obj-$(CONFIG_MPC5200)		+= speed-mpc5200.o
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
index f5f0a75..d7660e5 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
@@ -3,6 +3,8 @@
 
 #if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100)
 # include <mach/mpc5200.h>
+#elif defined(CONFIG_ARCH_MPC512X)
+# include <mach/mpc512x.h>
 #else
 # error "Undefined Core CPU"
 #endif
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:00 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:00 +0200
Subject: [PATCH 01/19] arch/MPC5xxx: fix linker script for MPC5200
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-2-git-send-email-jbe@pengutronix.de>

Without this change the barebox.bin ends up with:

00000000  79 ba 8f 79 00 00 00 00  75 39 6e d1 74 27 00 00  |y..y....u9n.t'..|
00000010  01 00 00 00 00 00 00 00  28 80 ad db 8d c7 a8 67  |........(......g|
00000020  4e 07 00 00 10 00 00 00  2f 63 6f 6e 66 69 67 00  |N......./config.|
00000030  8d c7 a8 68 ff 01 00 00  23 21 2f 62 69 6e 2f 73  |...h....#!/bin/s|
00000040  68 0a 0a 68 6f 73 74 6e  61 6d 65 3d 46 49 58 4d  |h..hostname=FIXM|
00000050  45 0a 69 66 20 5b 20 2d  7a 20 22 24 75 73 65 72  |E.if [ -z "$user|
00000060  22 20 5d 3b 20 74 68 65  6e 0a 23 09 75 73 65 72  |" ]; then.#.user|
00000070  3d 0a 66 69 0a 0a 23 20  45 6e 74 65 72 20 4d 41  |=.fi..# Enter MA|
[...]

which means it starts with the default environment instead of the reset vector area.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/boards/pcm030/barebox.lds.S | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S
index 20ac0d8..1332ad1 100644
--- a/arch/ppc/boards/pcm030/barebox.lds.S
+++ b/arch/ppc/boards/pcm030/barebox.lds.S
@@ -26,7 +26,21 @@ SECTIONS
 {
   . = TEXT_BASE;
 
+  .text      :
+  {
+    _text = .;
+    _stext = .;
+    arch/ppc/mach-mpc5xxx/start.o	(.text)
+    *(.text*)
+    *(.got1*)
+    . = ALIGN(16);
+    *(.rodata*)
+    *(.rodata1*)
+    *(.rodata.str1.4)
+  }
+
   /* Read-only sections, merged into text segment: */
+/*
   .interp : { *(.interp) }
   .hash          : { *(.hash)		}
   .dynsym        : { *(.dynsym)		}
@@ -50,20 +64,10 @@ SECTIONS
   .init          : { *(.init)	}
   .plt : { *(.plt) }
   .text      :
-  {
-    _text = .;
-    _stext = .;
-    arch/ppc/mach-mpc5xxx/start.o	(.text)
-    *(.text*)
-    *(.got1*)
-    . = ALIGN(16);
-    *(.rodata*)
-    *(.rodata1*)
-    *(.rodata.str1.4)
-  }
   .fini      : { *(.fini)    } =0
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
+*/
 
   /* Read-write section, merged into data segment: */
   . = (. + 0x0FFF) & 0xFFFFF000;
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:11 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:11 +0200
Subject: [PATCH 12/19] MPC5xxx/serial: use new shared register description
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-13-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h | 154 ---------------------------
 drivers/serial/serial_mpc5xxx.c              |   1 +
 2 files changed, 1 insertion(+), 154 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
index 28dfa6e..31c0656 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
@@ -352,67 +352,6 @@
 #define I2C_IF		0x02
 #define I2C_RXAK	0x01
 
-/* Programmable Serial Controller (PSC) status register bits */
-#define PSC_SR_CDE		0x0080
-#define PSC_SR_RXRDY		0x0100
-#define PSC_SR_RXFULL		0x0200
-#define PSC_SR_TXRDY		0x0400
-#define PSC_SR_TXEMP		0x0800
-#define PSC_SR_OE		0x1000
-#define PSC_SR_PE		0x2000
-#define PSC_SR_FE		0x4000
-#define PSC_SR_RB		0x8000
-
-/* PSC Command values */
-#define PSC_RX_ENABLE		0x0001
-#define PSC_RX_DISABLE		0x0002
-#define PSC_TX_ENABLE		0x0004
-#define PSC_TX_DISABLE		0x0008
-#define PSC_SEL_MODE_REG_1	0x0010
-#define PSC_RST_RX		0x0020
-#define PSC_RST_TX		0x0030
-#define PSC_RST_ERR_STAT	0x0040
-#define PSC_RST_BRK_CHG_INT	0x0050
-#define PSC_START_BRK		0x0060
-#define PSC_STOP_BRK		0x0070
-
-/* PSC Rx FIFO status bits */
-#define PSC_RX_FIFO_ERR		0x0040
-#define PSC_RX_FIFO_UF		0x0020
-#define PSC_RX_FIFO_OF		0x0010
-#define PSC_RX_FIFO_FR		0x0008
-#define PSC_RX_FIFO_FULL	0x0004
-#define PSC_RX_FIFO_ALARM	0x0002
-#define PSC_RX_FIFO_EMPTY	0x0001
-
-/* PSC interrupt mask bits */
-#define PSC_IMR_TXRDY		0x0100
-#define PSC_IMR_RXRDY		0x0200
-#define PSC_IMR_DB		0x0400
-#define PSC_IMR_IPC		0x8000
-
-/* PSC input port change bits */
-#define PSC_IPCR_CTS		0x01
-#define PSC_IPCR_DCD		0x02
-
-/* PSC mode fields */
-#define PSC_MODE_5_BITS		0x00
-#define PSC_MODE_6_BITS		0x01
-#define PSC_MODE_7_BITS		0x02
-#define PSC_MODE_8_BITS		0x03
-#define PSC_MODE_PAREVEN	0x00
-#define PSC_MODE_PARODD		0x04
-#define PSC_MODE_PARFORCE	0x08
-#define PSC_MODE_PARNONE	0x10
-#define PSC_MODE_ERR		0x20
-#define PSC_MODE_FFULL		0x40
-#define PSC_MODE_RXRTS		0x80
-
-#define PSC_MODE_ONE_STOP_5_BITS	0x00
-#define PSC_MODE_ONE_STOP		0x07
-#define PSC_MODE_TWO_STOP		0x0f
-
-
 /* ATA config fields */
 #define MPC5xxx_ATA_HOSTCONF_SMR	0x80000000UL	/* State machine
 							   reset */
@@ -426,99 +365,6 @@
 
 #include <linux/types.h>
 
-struct mpc5xxx_psc {
-	volatile u8	mode;		/* PSC + 0x00 */
-	volatile u8	reserved0[3];
-	union {				/* PSC + 0x04 */
-		volatile u16	status;
-		volatile u16	clock_select;
-	} sr_csr;
-#define psc_status	sr_csr.status
-#define psc_clock_select sr_csr.clock_select
-	volatile u16	reserved1;
-	volatile u8	command;	/* PSC + 0x08 */
-	volatile u8	reserved2[3];
-	union {				/* PSC + 0x0c */
-		volatile u8	buffer_8;
-		volatile u16	buffer_16;
-		volatile u32	buffer_32;
-	} buffer;
-#define psc_buffer_8	buffer.buffer_8
-#define psc_buffer_16	buffer.buffer_16
-#define psc_buffer_32	buffer.buffer_32
-	union {				/* PSC + 0x10 */
-		volatile u8	ipcr;
-		volatile u8	acr;
-	} ipcr_acr;
-#define psc_ipcr	ipcr_acr.ipcr
-#define psc_acr		ipcr_acr.acr
-	volatile u8	reserved3[3];
-	union {				/* PSC + 0x14 */
-		volatile u16	isr;
-		volatile u16	imr;
-	} isr_imr;
-#define psc_isr		isr_imr.isr
-#define psc_imr		isr_imr.imr
-	volatile u16	reserved4;
-	volatile u8	ctur;		/* PSC + 0x18 */
-	volatile u8	reserved5[3];
-	volatile u8	ctlr;		/* PSC + 0x1c */
-	volatile u8	reserved6[3];
-	volatile u16	ccr;		/* PSC + 0x20 */
-	volatile u8	reserved7[14];
-	volatile u8	ivr;		/* PSC + 0x30 */
-	volatile u8	reserved8[3];
-	volatile u8	ip;		/* PSC + 0x34 */
-	volatile u8	reserved9[3];
-	volatile u8	op1;		/* PSC + 0x38 */
-	volatile u8	reserved10[3];
-	volatile u8	op0;		/* PSC + 0x3c */
-	volatile u8	reserved11[3];
-	volatile u32	sicr;		/* PSC + 0x40 */
-	volatile u8	ircr1;		/* PSC + 0x44 */
-	volatile u8	reserved12[3];
-	volatile u8	ircr2;		/* PSC + 0x44 */
-	volatile u8	reserved13[3];
-	volatile u8	irsdr;		/* PSC + 0x4c */
-	volatile u8	reserved14[3];
-	volatile u8	irmdr;		/* PSC + 0x50 */
-	volatile u8	reserved15[3];
-	volatile u8	irfdr;		/* PSC + 0x54 */
-	volatile u8	reserved16[3];
-	volatile u16	rfnum;		/* PSC + 0x58 */
-	volatile u16	reserved17;
-	volatile u16	tfnum;		/* PSC + 0x5c */
-	volatile u16	reserved18;
-	volatile u32	rfdata;		/* PSC + 0x60 */
-	volatile u16	rfstat;		/* PSC + 0x64 */
-	volatile u16	reserved20;
-	volatile u8	rfcntl;		/* PSC + 0x68 */
-	volatile u8	reserved21[5];
-	volatile u16	rfalarm;	/* PSC + 0x6e */
-	volatile u16	reserved22;
-	volatile u16	rfrptr;		/* PSC + 0x72 */
-	volatile u16	reserved23;
-	volatile u16	rfwptr;		/* PSC + 0x76 */
-	volatile u16	reserved24;
-	volatile u16	rflrfptr;	/* PSC + 0x7a */
-	volatile u16	reserved25;
-	volatile u16	rflwfptr;	/* PSC + 0x7e */
-	volatile u32	tfdata;		/* PSC + 0x80 */
-	volatile u16	tfstat;		/* PSC + 0x84 */
-	volatile u16	reserved26;
-	volatile u8	tfcntl;		/* PSC + 0x88 */
-	volatile u8	reserved27[5];
-	volatile u16	tfalarm;	/* PSC + 0x8e */
-	volatile u16	reserved28;
-	volatile u16	tfrptr;		/* PSC + 0x92 */
-	volatile u16	reserved29;
-	volatile u16	tfwptr;		/* PSC + 0x96 */
-	volatile u16	reserved30;
-	volatile u16	tflrfptr;	/* PSC + 0x9a */
-	volatile u16	reserved31;
-	volatile u16	tflwfptr;	/* PSC + 0x9e */
-};
-
 struct mpc5xxx_intr {
 	volatile u32	per_mask;	/* INTR + 0x00 */
 	volatile u32	per_pri1;	/* INTR + 0x04 */
diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index 9d92fed..3b83bee 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -37,6 +37,7 @@
 #include <console.h>
 #include <xfuncs.h>
 #include <mach/clocks.h>
+#include <mach/mpc5xxx_psc.h>
 
 static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
 {
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:17 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:17 +0200
Subject: [PATCH 18/19] MPC5125/WDG: add a watchdog driver
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-19-git-send-email-jbe@pengutronix.de>

This watchdog is always enabled after reset and can be configured only once.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/watchdog/Kconfig   |   6 ++
 drivers/watchdog/Makefile  |   1 +
 drivers/watchdog/mpc5125.c | 148 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/watchdog/mpc5125.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7f7b02e..4c57111 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -28,4 +28,10 @@ config WATCHDOG_JZ4740
 	help
 	  Hardware driver for the built-in watchdog timer on Ingenic jz4740 SoCs.
 
+config WATCHDOG_MPC5125
+	bool "MPC5125 SoC hardware watchdog"
+	depends on SOC_MPC5125
+	help
+	  Hardware driver for the built-in watchdog timer on MPC5125 SoCs.
+
 endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 865fc47..b7aa549 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_WATCHDOG) += wd_core.o
 obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
 obj-$(CONFIG_WATCHDOG_JZ4740) += jz4740.o
 obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o
+obj-$(CONFIG_WATCHDOG_MPC5125) += mpc5125.o
diff --git a/drivers/watchdog/mpc5125.c b/drivers/watchdog/mpc5125.c
new file mode 100644
index 0000000..7fefa21
--- /dev/null
+++ b/drivers/watchdog/mpc5125.c
@@ -0,0 +1,148 @@
+/*
+ * (c) 2014 Juergen Borleis <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.
+ *
+ * Note: this driver works for the MPC5125. It might work for the
+ * MPC512X SoCs as well, but is not tested yet.
+ */
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <errno.h>
+#include <malloc.h>
+#include <watchdog.h>
+#include <mach/clocks.h>
+
+/* WD register description */
+struct wdt {
+	u32 res0;
+	u32 swcrr; /* note: read often, write once */
+	u32 swcnr;
+	u16 res1;
+	u16 swsrr;
+};
+
+struct mpc5125_wd {
+	struct watchdog wd;
+	struct wdt *regs;
+	bool re_configured;
+};
+
+#define WDT_SWCRR_GET_SWTC(x) ((x) >> 16)
+#define WDT_SWCRR_SET_SWTC(x) ((x) << 16)
+#define WDT_SWCRR_SWEN (1 << 2)
+#define WDT_SWCRR_SWRI (1 << 1)
+#define WDT_SWCRR_SWPR (1 << 0)
+
+#define MPC5125_WDT_RESET1_MAGIC 0x556c
+#define MPC5125_WDT_RESET2_MAGIC 0xaa39
+
+#define MPC5125_WDT_PRESCALE 0x10000
+
+#define to_mpc5125_wd(h) container_of(h, struct mpc5125_wd, wd)
+
+static void mpc5125_wd_retrigger(struct mpc5125_wd *wd)
+{
+	out_be16(&wd->regs->swsrr, 0x556c);
+	out_be16(&wd->regs->swsrr, 0xaa39);
+}
+
+/* note: setting a new timeout is an irreversible step! */
+static int mpc5125_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+	struct mpc5125_wd *pwd = (struct mpc5125_wd *)to_mpc5125_wd(wd);
+	unsigned cnt_val, time;
+	uint64_t new_cnt_val;
+	u32 swcrr;
+
+	/*
+	 * what does the user wants us to do?
+	 * - just retrigger?
+	 * - or re-programming to a different timout value?
+	 *
+	 * Due to the fact we can program the SWCRR register only once we
+	 * must detect a difference between the given timeout and the time
+	 * which is currently in use to have the latter case.
+	 * If the given timeout is "nealy" the same then currently used, just
+	 * a re-trigger should occure (first case).
+	 */
+	swcrr = in_be32(&pwd->regs->swcrr);
+	cnt_val = WDT_SWCRR_GET_SWTC(swcrr);
+
+	if (swcrr & WDT_SWCRR_SWPR)
+		time = (cnt_val * MPC5125_WDT_PRESCALE) / get_timebase_clock();
+	else
+		time = cnt_val / get_timebase_clock();
+
+	if (time != timeout) {
+		/* it seems the user wants a new timout value */
+		if (pwd->re_configured) {
+			pr_err("Cannot configure the watchdog twice. "
+					"Still sticked to %u seconds.\n", time);
+			return -EINVAL;
+		}
+		/*
+		 * we always need the prescaler enabled, because without it
+		 * the timeout is far below a second...
+		 */
+		new_cnt_val = timeout * get_timebase_clock();
+		if (new_cnt_val >= 0xffff0000) {
+			time = 0xffff0000 / get_timebase_clock();
+			pr_err("Invalid timout value. Max value is "
+							"%u seconds.\n", time);
+			return -EINVAL;
+		}
+		new_cnt_val /= MPC5125_WDT_PRESCALE;
+		out_be32(&pwd->regs->swcrr, WDT_SWCRR_SET_SWTC(new_cnt_val) |
+			WDT_SWCRR_SWPR | WDT_SWCRR_SWEN | WDT_SWCRR_SWRI);
+		pwd->re_configured = true;
+	}
+
+	mpc5125_wd_retrigger(pwd);
+
+	return 0;
+}
+
+static int mpc5125_wd_probe(struct device_d *dev)
+{
+	struct mpc5125_wd *priv;
+	int rc;
+
+	priv = xzalloc(sizeof(struct mpc5125_wd));
+	priv->regs = dev_request_mem_region(dev, 0);
+	priv->wd.set_timeout = mpc5125_watchdog_set_timeout;
+
+	rc = watchdog_register(&priv->wd);
+	if (rc != 0)
+		goto on_error;
+
+	dev->priv = priv;
+	return 0;
+
+on_error:
+	free(priv);
+	return rc;
+}
+
+static void mpc5125_wd_remove(struct device_d *dev)
+{
+	struct mpc5125_wd *priv= dev->priv;
+	watchdog_deregister(&priv->wd);
+	free(priv);
+}
+
+static struct driver_d mpc5125_wd_driver = {
+	.name   = "mpc5125wd",
+	.probe  = mpc5125_wd_probe,
+	.remove = mpc5125_wd_remove,
+};
+device_platform_driver(mpc5125_wd_driver);
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:18 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:18 +0200
Subject: [PATCH 19/19] MPC5125/GPIO: add a generic GPIO driver
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-20-git-send-email-jbe@pengutronix.de>

The MPC5125 can handle up to 64 GPIOs divided in two units to control them.
Note: this driver cannot be used with a MPC521 or MPC5123!

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/include/asm/gpio.h                  |  28 ++++++
 arch/ppc/mach-mpc5xxx/Kconfig                |   1 +
 arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h |   2 +
 drivers/gpio/Kconfig                         |   6 ++
 drivers/gpio/Makefile                        |   1 +
 drivers/gpio/gpio-mpc5125.c                  | 136 +++++++++++++++++++++++++++
 6 files changed, 174 insertions(+)
 create mode 100644 arch/ppc/include/asm/gpio.h
 create mode 100644 drivers/gpio/gpio-mpc5125.c

diff --git a/arch/ppc/include/asm/gpio.h b/arch/ppc/include/asm/gpio.h
new file mode 100644
index 0000000..63b712d
--- /dev/null
+++ b/arch/ppc/include/asm/gpio.h
@@ -0,0 +1,28 @@
+#ifndef _ARCH_PPC_GPIO_H
+#define _ARCH_PPC_GPIO_H
+
+#ifndef CONFIG_GPIOLIB
+#include <mach/gpio.h>
+#else /* CONFIG_GPIOLIB */
+#ifdef CONFIG_SOC_MPC5125
+# define ARCH_NR_GPIOS 64
+#else
+# error "GPIO count for this architecture is undefined"
+#endif
+
+static inline int gpio_is_valid(int gpio)
+{
+	if (gpio < 0)
+		return 0;
+	if (gpio < ARCH_NR_GPIOS)
+		return 1;
+	return 0;
+}
+
+void gpio_set_value(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_direction_input(unsigned gpio);
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ARCH_PPC_GPIO_H */
diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
index a65c21d..0e969b7 100644
--- a/arch/ppc/mach-mpc5xxx/Kconfig
+++ b/arch/ppc/mach-mpc5xxx/Kconfig
@@ -35,6 +35,7 @@ config SOC_MPC5125
 	bool
 	select MPC5xxx
 	select ARCH_MPC512X
+	select GPIOLIB
 
 config MPC5xxx
 	bool
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
index ed60f2a..20df42f 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
@@ -54,6 +54,8 @@
 #define MPC512X_RESET	(CFG_MBAR + 0x00E00)
 #define MPC512X_CLKM	(CFG_MBAR + 0x00f00)
 #define MPC512X_WDT	(CFG_MBAR + 0x00900)
+#define MPC512X_GPIO1	(CFG_MBAR + 0x01100)
+#define MPC512X_GPIO2	(CFG_MBAR + 0x01180)
 #define MPC512X_FEC1	(CFG_MBAR + 0x02800)
 #define MPC512X_FEC2	(CFG_MBAR + 0x04800)
 #define MPC512X_DRAMC	(CFG_MBAR + 0x09000)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0ca7df4..e16ff80 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -110,6 +110,12 @@ config GPIO_DESIGNWARE
 	help
 	  Say Y or M here to build support for the Synopsys DesignWare APB
 	  GPIO block.
+
+config GPIO_MPC5125
+	tristate "PowerPC MPC5125 GPIO driver"
+	depends on SOC_MPC5125
+	help
+	  Say Y here to build support for the MPC5125 GPIO block.
 endmenu
 
 endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 510d146..82206db 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_GPIO_PL061)	+= gpio-pl061.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_TEGRA)	+= gpio-tegra.o
 obj-$(CONFIG_GPIO_DESIGNWARE)	+= gpio-dw.o
+obj-$(CONFIG_GPIO_MPC5125)	+= gpio-mpc5125.o
diff --git a/drivers/gpio/gpio-mpc5125.c b/drivers/gpio/gpio-mpc5125.c
new file mode 100644
index 0000000..8d1bcb3
--- /dev/null
+++ b/drivers/gpio/gpio-mpc5125.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, 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.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <init.h>
+#include <asm/io.h>
+#include <gpio.h>
+#include <mach/mpc5xxx.h>
+
+#define GPIO_DIR 0
+#define GPIO_ODR 1
+#define GPIO_DAT 2
+#define GPIO_IER 3
+#define GPIO_IMR 4
+#define GPIO_ICR1 5
+#define GPIO_ICR2 6
+
+struct mpc5125_gpio_chip {
+	u32 __iomem *base;
+	struct gpio_chip chip;
+};
+
+static unsigned gpio_no_to_bit(unsigned gpio)
+{
+	/*
+	 * GPIO0 is the highest bit in the register m(
+	 *  regular notation: GPIO0 is register bit 31
+	 *  PPC notation: GPIO0 is register bit 0
+	 */
+	return 1 << (31 - gpio);
+}
+
+static void mpc5125_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip);
+
+	if (value != 0)
+		setbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio));
+	else
+		clrbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio));
+}
+
+static int mpc5125_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip);
+
+	clrbits_be32(&mpcgpio->base[GPIO_DIR], gpio_no_to_bit(gpio));
+	return 0;
+}
+
+static int mpc5125_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip);
+
+	/* GPIO 0 ... 3 in GPIO unit 1 are input only */
+	if (mpcgpio->chip.dev->id == 0 && gpio < 4) {
+		dev_err(mpcgpio->chip.dev, "GPIO %u is input only\n", gpio);
+		return -ENODEV;
+	}
+
+	if (value != 0)
+		setbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio));
+	else
+		clrbits_be32(&mpcgpio->base[GPIO_DAT], gpio_no_to_bit(gpio));
+	setbits_be32(&mpcgpio->base[GPIO_DIR], gpio_no_to_bit(gpio));
+
+	return 0;
+}
+
+static int mpc5125_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip);
+
+	return in_be32(&mpcgpio->base[GPIO_DAT]) & gpio_no_to_bit(gpio) ? 1 : 0;
+}
+
+static int mpc5125_get_direction(struct gpio_chip *chip, unsigned gpio)
+{
+	struct mpc5125_gpio_chip *mpcgpio = container_of(chip, struct mpc5125_gpio_chip, chip);
+
+	return in_be32(&mpcgpio->base[GPIO_DIR]) & gpio_no_to_bit(gpio) ?
+					GPIOF_DIR_OUT : GPIOF_DIR_IN;
+}
+
+static struct gpio_ops mpc5125_gpio_ops = {
+	.direction_input = mpc5125_gpio_direction_input,
+	.direction_output = mpc5125_gpio_direction_output,
+	.get = mpc5125_gpio_get_value,
+	.set = mpc5125_gpio_set_value,
+	.get_direction = mpc5125_get_direction,
+};
+
+static int mpc5125_gpio_probe(struct device_d *dev)
+{
+	struct mpc5125_gpio_chip *mpcgpio;
+
+	mpcgpio = xzalloc(sizeof(*mpcgpio));
+	mpcgpio->base = dev_request_mem_region(dev, 0);
+	mpcgpio->chip.ops = &mpc5125_gpio_ops;
+	mpcgpio->chip.base = dev->id * 32;
+	mpcgpio->chip.ngpio = 32;
+	mpcgpio->chip.dev = dev;
+	gpiochip_add(&mpcgpio->chip);
+
+	dev_dbg(dev, "probed gpiochip%d with base %d\n", dev->id, mpcgpio->chip.base);
+
+	return 0;
+}
+
+static struct driver_d mpc5125_gpio_driver = {
+	.name = "mpc5125-gpio",
+	.probe = mpc5125_gpio_probe,
+};
+
+static int mpc5125_gpio_add(void)
+{
+	platform_driver_register(&mpc5125_gpio_driver);
+	add_generic_device("mpc5125-gpio", 0, NULL, MPC512X_GPIO1,
+				0x80, IORESOURCE_MEM, NULL);
+	add_generic_device("mpc5125-gpio", 1, NULL, MPC512X_GPIO2,
+				0x80, IORESOURCE_MEM, NULL);
+	return 0;
+}
+coredevice_initcall(mpc5125_gpio_add);
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:15 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:15 +0200
Subject: [PATCH 16/19] MPC5xxx/serial: add support for the MPC5125 SoC
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-17-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h |  98 ++++++++++++++
 drivers/serial/Kconfig                           |   4 +-
 drivers/serial/serial_mpc5xxx.c                  | 157 +++++++++++++++++++++++
 3 files changed, 257 insertions(+), 2 deletions(-)

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h
index a44d213..839b394 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx_psc.h
@@ -60,6 +60,7 @@
 #define PSC_MODE_ONE_STOP		0x07
 #define PSC_MODE_TWO_STOP		0x0f
 
+#ifdef CONFIG_MPC5200
 struct mpc5xxx_psc {
 	u8	mode;		/* PSC + 0x00 */
 	u8	reserved0[3];
@@ -152,3 +153,100 @@ struct mpc5xxx_psc {
 	u16	reserved31;
 	u16	tflwfptr;	/* PSC + 0x9e */
 };
+#endif
+
+#ifdef CONFIG_SOC_MPC5125
+/* PSC definition for MPC5125 */
+struct mpc5xxx_psc {
+	u8 mode;
+	u8 res0[3];
+	u8 mode2;
+	u8 res1[3];
+	u16 psc_status;
+	u8 resx[2];
+	u8 clock_select;
+	u8 res2[3];
+	u8 command;
+	u8 res3[3];
+	u32 buffer_32;
+	u8 ipcr;
+	u8 res4[3];
+	u8 acr;
+	u8 res5[3];
+	u16 isr;
+	u8 res5a[2];
+	u16 psc_imr;
+	u8 res5b[2];
+	u8 ctur;
+	u8 res6[3];
+	u8 ctlr;
+	u8 res7[3];
+	u32 ccr;
+	u32 ac97slots;
+	u32 ac97cmd;
+	u32 ac97data;
+	u8 res8[4];
+	u8 ip;
+	u8 res9[3];
+	u8 op1;
+	u8 res10[3];
+	u8 op0;
+	u8 res11[3];
+	u32 sicr;
+	u8 res12[44];
+	u32 tfcmd;
+	u32 tfalarm;
+	u32 tfstat;
+	u32 tfintstat;
+	u32 tfintmask;
+	u32 tfcount;
+	u32 tfwptr;
+	u32 tfsize;
+	u8 res13[28];
+	union {
+		u8 buffer_8;
+		u16 buffer_16;
+		u32 buffer_32;
+	} tfdata_buffer;
+#define tfdata_8 tfdata_buffer.buffer_8
+#define tfdata_16 tfdata_buffer.buffer_16
+#define tfdata_32 tfdata_buffer.buffer_32
+	u32 rfcmd;
+	u32 rfalarm;
+	u32 rfstat;
+	u32 rfintstat;
+	u32 rfintmask;
+	u32 rfcount;
+	u32 rfrptr;
+	u32 rfsize;
+	u8 res14[28];
+	union {
+		u8 buffer_8;
+		u16 buffer_16;
+		u32 buffer_32;
+	} rfdata_buffer;
+#define rfdata_8 rfdata_buffer.buffer_8
+#define rfdata_16 rfdata_buffer.buffer_16
+#define rfdata_32 rfdata_buffer.buffer_32
+};
+
+struct fifoc5125 {
+	u32 fifoc_cmd;
+	u32 fifoc_int;
+	u32 fifoc_dma;
+	u32 res1;
+	u32 fifoc_debug;
+};
+
+/* PSC FIFO Command values */
+#define PSC_FIFO_RESET_SLICE		0x80
+#define PSC_FIFO_ENABLE_SLICE		0x01
+
+/* PSC FIFO Controller Command values */
+#define FIFOC_ENABLE_CLOCK_GATE		0x01
+#define FIFOC_DISABLE_CLOCK_GATE	0x00
+
+/* PSC FIFO status */
+#define PSC_FIFO_EMPTY			0x01
+
+#endif
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 146bf1e..63c0703 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -50,9 +50,9 @@ config DRIVER_SERIAL_EFI_STDIO
 	bool "EFI stdio driver"
 
 config DRIVER_SERIAL_MPC5XXX
-	depends on MPC5200
+	depends on ARCH_MPC5XXX
 	default y
-	bool "MPC5200 serial driver"
+	bool "MPC5XXX serial driver"
 
 config DRIVER_SERIAL_BLACKFIN
 	depends on BLACKFIN
diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index 7cd448c..670c514 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -39,6 +39,142 @@
 #include <mach/clocks.h>
 #include <mach/mpc5xxx_psc.h>
 
+#ifdef CONFIG_SOC_MPC5125
+
+#define MPC512x_PSC_FIFO_EMPTY (1 << 0)
+
+static struct fifoc5125 * const fifoc = (struct fifoc5125 *)MPC512X_FIFOC;
+
+struct fifo_adr_pair {
+	unsigned tsize, toffs;
+	unsigned rsize, roffs;
+};
+
+/* describe the FIFO's internal memory layout */
+static const struct fifo_adr_pair mpc5xxx_fifo_addresses[] = {
+	{
+		.tsize = 0x04, .toffs = 0x000,
+		.rsize = 0x04, .roffs = 0x010,
+	}, {
+		.tsize = 0x04, .toffs = 0x020,
+		.rsize = 0x04, .roffs = 0x030,
+	}, {
+		.tsize = 0x04, .toffs = 0x040,
+		.rsize = 0x04, .roffs = 0x050,
+	}, {
+		.tsize = 0x04, .toffs = 0x060,
+		.rsize = 0x04, .roffs = 0x070,
+	}, {
+		.tsize = 0x04, .toffs = 0x080,
+		.rsize = 0x04, .roffs = 0x090,
+	}, {
+		.tsize = 0x04, .toffs = 0x0a0,
+		.rsize = 0x04, .roffs = 0x0b0,
+	}, {
+		.tsize = 0x04, .toffs = 0x0c0,
+		.rsize = 0x04, .roffs = 0x0d0,
+	}, {
+		.tsize = 0x04, .toffs = 0x0e0,
+		.rsize = 0x04, .roffs = 0x0f0,
+	}, {
+		.tsize = 0x04, .toffs = 0x100,
+		.rsize = 0x04, .roffs = 0x110,
+	}, {
+		.tsize = 0x04, .toffs = 0x120,
+		.rsize = 0x04, .roffs = 0x130,
+	},
+};
+
+static unsigned mpc5xxx_get_psc_index(void *p)
+{
+	/* all PSC offsets differ in 0x100 steps */
+	return ((unsigned)p & 0xf00) >> 8;
+}
+
+static void mpc5xxx_fifo_init(struct mpc5xxx_psc *psc)
+{
+	unsigned idx = mpc5xxx_get_psc_index(psc);
+	u32 tfsize, rfsize;
+
+	/*
+	 * we must enable the FIFO unit's clock,
+	 * when at least one PSC unit is in use
+	 */
+	mpc5125_enable_psc_fifo_clock();
+
+	/* reset Rx & Tx fifo slice */
+	out_be32(&psc->rfcmd, PSC_FIFO_RESET_SLICE);
+	out_be32(&psc->tfcmd, PSC_FIFO_RESET_SLICE);
+
+	/* disable Tx & Rx FIFO interrupts */
+	out_be32(&psc->rfintmask, 0);
+	out_be32(&psc->tfintmask, 0);
+
+	tfsize = mpc5xxx_fifo_addresses[idx].tsize |
+			(mpc5xxx_fifo_addresses[idx].toffs << 16);
+	rfsize = mpc5xxx_fifo_addresses[idx].rsize |
+			(mpc5xxx_fifo_addresses[idx].roffs << 16);
+
+	out_be32(&psc->tfsize, tfsize);
+	out_be32(&psc->rfsize, rfsize);
+
+	/* enable Tx & Rx FIFO slice */
+	out_be32(&psc->rfcmd, PSC_FIFO_ENABLE_SLICE);
+	out_be32(&psc->tfcmd, PSC_FIFO_ENABLE_SLICE);
+
+	out_be32(&fifoc->fifoc_cmd, FIFOC_DISABLE_CLOCK_GATE);
+	__asm__ volatile ("sync");
+}
+
+static int psc_tx_rdy(struct mpc5xxx_psc *psc)
+{
+	return in_be32(&psc->tfstat) & MPC512x_PSC_FIFO_EMPTY;
+}
+
+static int psc_rx_rdy(struct mpc5xxx_psc *psc)
+{
+	return !(in_be32(&psc->rfstat) & MPC512x_PSC_FIFO_EMPTY);
+}
+
+static void psc_tx_write(struct mpc5xxx_psc *psc, char c)
+{
+	out_8(&psc->tfdata_8, c);
+}
+
+static int psc_rx_read(struct mpc5xxx_psc *psc)
+{
+	return in_8(&psc->rfdata_8);
+}
+
+static unsigned long mpc5xxx_get_base_clock(struct mpc5xxx_psc *psc)
+{
+	return (get_ips_clock() + 8) / 16;
+}
+
+static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc)
+{
+	out_8(&psc->clock_select, 0xdd);
+}
+
+static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc)
+{
+	out_8(&psc->mode, PSC_MODE_8_BITS | PSC_MODE_PARNONE);
+	out_8(&psc->mode2, PSC_MODE_ONE_STOP);
+}
+
+static int mpc5xxx_enable_psc_unit(struct mpc5xxx_psc *psc)
+{
+	unsigned idx = mpc5xxx_get_psc_index(psc);
+
+	if (idx > ARRAY_SIZE(mpc5xxx_fifo_addresses))
+		return -ENODEV;
+
+	mpc5xxx_enable_psc_clock(idx);
+	return 0;
+}
+
+#else /* CONFIG_MPC512X */
+
 static int psc_tx_rdy(struct mpc5xxx_psc *psc)
 {
 	return in_be16(&psc->psc_status) & PSC_SR_TXEMP;
@@ -81,6 +217,11 @@ static void mpc5xxx_select_clock_source(struct mpc5xxx_psc *psc)
 #endif
 }
 
+static void mpc5xxx_fifo_init(struct mpc5xxx_psc *psc)
+{
+	/* nothing to be done here */
+}
+
 static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc)
 {
 #if defined(CONFIG_MGT5100)
@@ -93,6 +234,14 @@ static void mpc5xxx_configure_serial_protocol(struct mpc5xxx_psc *psc)
 #endif
 }
 
+static int mpc5xxx_enable_psc_unit(struct mpc5xxx_psc *psc)
+{
+	/* nothing to be done here */
+	return 0;
+}
+
+#endif /* !CONFIG_MPC512X */
+
 static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
 {
 	unsigned long baseclk;
@@ -120,11 +269,19 @@ static int mpc5xxx_serial_setbaudrate(struct console_device *cdev, int baudrate)
 
 static int __mpc5xxx_serial_init(struct mpc5xxx_psc *psc)
 {
+	int ret;
+
+	ret = mpc5xxx_enable_psc_unit(psc);
+	if (ret != 0)
+		return ret;
+
 	/* reset PSC */
 	out_8(&psc->command, PSC_SEL_MODE_REG_1);
 
 	mpc5xxx_select_clock_source(psc);
 
+	mpc5xxx_fifo_init(psc);
+
 	/* switch to UART mode */
 	out_be32(&psc->sicr, 0);
 
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:06 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:06 +0200
Subject: [PATCH 07/19] arch/MPC5xxx: separate architecture's main SoC header
 file
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-8-git-send-email-jbe@pengutronix.de>

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h | 794 +++++++++++++++++++++++++++
 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h | 793 +-------------------------
 2 files changed, 798 insertions(+), 789 deletions(-)
 create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h

diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
new file mode 100644
index 0000000..35762a1
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
@@ -0,0 +1,794 @@
+/*
+ * arch/ppc/mach-mpc5xxx/include/mach/mpc5200.h
+ *
+ * Prototypes, etc. for the Motorola MGT5xxx/MPC5xxx
+ * embedded cpu chips
+ *
+ * 2003 (c) MontaVista, Software, Inc.
+ * Author: Dale Farnsworth <dfarnsworth at mvista.com>
+ *
+ * 2003 (C) Wolfgang Denk, DENX Software Engineering, wd at denx.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.
+ *
+ */
+#ifndef __ASMPPC_MPC5200_H
+#define __ASMPPC_MPC5200_H
+
+/* Processor name */
+#if defined(CONFIG_MPC5200)
+#define CPU_ID_STR	"MPC5200"
+#elif defined(CONFIG_MGT5100)
+#define CPU_ID_STR	"MGT5100"
+#endif
+
+/* Exception offsets (PowerPC standard) */
+#define EXC_OFF_SYS_RESET	0x0100
+#define _START_OFFSET		EXC_OFF_SYS_RESET
+
+#define CFG_MBAR 0xf0000000
+
+/* useful macros for manipulating CSx_START/STOP */
+#if defined(CONFIG_MGT5100)
+#define START_REG(start)	((start) >> 15)
+#define STOP_REG(start, size)	(((start) + (size) - 1) >> 15)
+#elif defined(CONFIG_MPC5200)
+#define START_REG(start)	((start) >> 16)
+#define STOP_REG(start, size)	(((start) + (size) - 1) >> 16)
+#endif
+
+/* Internal memory map */
+
+#define MPC5XXX_CS0_START	(CFG_MBAR + 0x0004)
+#define MPC5XXX_CS0_STOP	(CFG_MBAR + 0x0008)
+#define MPC5XXX_CS1_START	(CFG_MBAR + 0x000c)
+#define MPC5XXX_CS1_STOP	(CFG_MBAR + 0x0010)
+#define MPC5XXX_CS2_START	(CFG_MBAR + 0x0014)
+#define MPC5XXX_CS2_STOP	(CFG_MBAR + 0x0018)
+#define MPC5XXX_CS3_START	(CFG_MBAR + 0x001c)
+#define MPC5XXX_CS3_STOP	(CFG_MBAR + 0x0020)
+#define MPC5XXX_CS4_START	(CFG_MBAR + 0x0024)
+#define MPC5XXX_CS4_STOP	(CFG_MBAR + 0x0028)
+#define MPC5XXX_CS5_START	(CFG_MBAR + 0x002c)
+#define MPC5XXX_CS5_STOP	(CFG_MBAR + 0x0030)
+#define MPC5XXX_BOOTCS_START	(CFG_MBAR + 0x004c)
+#define MPC5XXX_BOOTCS_STOP	(CFG_MBAR + 0x0050)
+#define MPC5XXX_ADDECR		(CFG_MBAR + 0x0054)
+
+#if defined(CONFIG_MGT5100)
+#define MPC5XXX_SDRAM_START	(CFG_MBAR + 0x0034)
+#define MPC5XXX_SDRAM_STOP	(CFG_MBAR + 0x0038)
+#define MPC5XXX_PCI1_START	(CFG_MBAR + 0x003c)
+#define MPC5XXX_PCI1_STOP	(CFG_MBAR + 0x0040)
+#define MPC5XXX_PCI2_START	(CFG_MBAR + 0x0044)
+#define MPC5XXX_PCI2_STOP	(CFG_MBAR + 0x0048)
+#elif defined(CONFIG_MPC5200)
+#define MPC5XXX_CS6_START	(CFG_MBAR + 0x0058)
+#define MPC5XXX_CS6_STOP	(CFG_MBAR + 0x005c)
+#define MPC5XXX_CS7_START	(CFG_MBAR + 0x0060)
+#define MPC5XXX_CS7_STOP	(CFG_MBAR + 0x0064)
+#define MPC5XXX_SDRAM_CS0CFG	(CFG_MBAR + 0x0034)
+#define MPC5XXX_SDRAM_CS1CFG	(CFG_MBAR + 0x0038)
+#endif
+
+#define MPC5XXX_SDRAM		(CFG_MBAR + 0x0100)
+#define MPC5XXX_CDM		(CFG_MBAR + 0x0200)
+#define MPC5XXX_LPB		(CFG_MBAR + 0x0300)
+#define MPC5XXX_ICTL		(CFG_MBAR + 0x0500)
+#define MPC5XXX_GPT		(CFG_MBAR + 0x0600)
+#define MPC5XXX_GPIO		(CFG_MBAR + 0x0b00)
+#define MPC5XXX_WU_GPIO         (CFG_MBAR + 0x0c00)
+#define MPC5XXX_PCI		(CFG_MBAR + 0x0d00)
+#define MPC5XXX_SPI		(CFG_MBAR + 0x0f00)
+#define MPC5XXX_USB		(CFG_MBAR + 0x1000)
+#define MPC5XXX_SDMA		(CFG_MBAR + 0x1200)
+#define MPC5XXX_XLBARB		(CFG_MBAR + 0x1f00)
+
+#if defined(CONFIG_MGT5100)
+#define	MPC5XXX_PSC1		(CFG_MBAR + 0x2000)
+#define	MPC5XXX_PSC2		(CFG_MBAR + 0x2400)
+#define	MPC5XXX_PSC3		(CFG_MBAR + 0x2800)
+#elif defined(CONFIG_MPC5200)
+#define	MPC5XXX_PSC1		(CFG_MBAR + 0x2000)
+#define	MPC5XXX_PSC2		(CFG_MBAR + 0x2200)
+#define	MPC5XXX_PSC3		(CFG_MBAR + 0x2400)
+#define	MPC5XXX_PSC4		(CFG_MBAR + 0x2600)
+#define	MPC5XXX_PSC5		(CFG_MBAR + 0x2800)
+#define	MPC5XXX_PSC6		(CFG_MBAR + 0x2c00)
+#endif
+
+#define	MPC5XXX_FEC		(CFG_MBAR + 0x3000)
+#define MPC5XXX_ATA             (CFG_MBAR + 0x3A00)
+
+#define MPC5XXX_I2C1		(CFG_MBAR + 0x3D00)
+#define MPC5XXX_I2C2		(CFG_MBAR + 0x3D40)
+
+#if defined(CONFIG_MGT5100)
+#define MPC5XXX_SRAM		(CFG_MBAR + 0x4000)
+#define MPC5XXX_SRAM_SIZE	(8*1024)
+#elif defined(CONFIG_MPC5200)
+#define MPC5XXX_SRAM		(CFG_MBAR + 0x8000)
+#define MPC5XXX_SRAM_SIZE	(16*1024)
+#endif
+
+/* SDRAM Controller */
+#define MPC5XXX_SDRAM_MODE	(MPC5XXX_SDRAM + 0x0000)
+#define MPC5XXX_SDRAM_CTRL	(MPC5XXX_SDRAM + 0x0004)
+#define MPC5XXX_SDRAM_CONFIG1	(MPC5XXX_SDRAM + 0x0008)
+#define MPC5XXX_SDRAM_CONFIG2	(MPC5XXX_SDRAM + 0x000c)
+#if defined(CONFIG_MGT5100)
+#define MPC5XXX_SDRAM_XLBSEL	(MPC5XXX_SDRAM + 0x0010)
+#endif
+#define MPC5XXX_SDRAM_SDELAY	(MPC5XXX_SDRAM + 0x0090)
+
+/* Clock Distribution Module */
+#define MPC5XXX_CDM_JTAGID	(MPC5XXX_CDM + 0x0000)
+#define MPC5XXX_CDM_PORCFG	(MPC5XXX_CDM + 0x0004)
+#define MPC5XXX_CDM_CFG		(MPC5XXX_CDM + 0x000c)
+#define MPC5XXX_CDM_48_FDC	(MPC5XXX_CDM + 0x0010)
+#define MPC5XXX_CDM_SRESET	(MPC5XXX_CDM + 0x0020)
+
+/* Local Plus Bus interface */
+#define MPC5XXX_CS0_CFG		(MPC5XXX_LPB + 0x0000)
+#define MPC5XXX_CS1_CFG		(MPC5XXX_LPB + 0x0004)
+#define MPC5XXX_CS2_CFG		(MPC5XXX_LPB + 0x0008)
+#define MPC5XXX_CS3_CFG		(MPC5XXX_LPB + 0x000c)
+#define MPC5XXX_CS4_CFG		(MPC5XXX_LPB + 0x0010)
+#define MPC5XXX_CS5_CFG		(MPC5XXX_LPB + 0x0014)
+#define MPC5XXX_BOOTCS_CFG	MPC5XXX_CS0_CFG
+#define MPC5XXX_CS_CTRL		(MPC5XXX_LPB + 0x0018)
+#define MPC5XXX_CS_STATUS	(MPC5XXX_LPB + 0x001c)
+#if defined(CONFIG_MPC5200)
+#define MPC5XXX_CS6_CFG		(MPC5XXX_LPB + 0x0020)
+#define MPC5XXX_CS7_CFG		(MPC5XXX_LPB + 0x0024)
+#define MPC5XXX_CS_BURST	(MPC5XXX_LPB + 0x0028)
+#define MPC5XXX_CS_DEADCYCLE	(MPC5XXX_LPB + 0x002c)
+#endif
+
+#if defined(CONFIG_MPC5200)
+/* XLB Arbiter registers */
+#define MPC5XXX_XLBARB_CFG		(MPC5XXX_XLBARB + 0x40)
+#define MPC5XXX_XLBARB_MPRIEN	(MPC5XXX_XLBARB + 0x64)
+#define MPC5XXX_XLBARB_MPRIVAL	(MPC5XXX_XLBARB + 0x68)
+#endif
+
+/* GPIO registers */
+#define MPC5XXX_GPS_PORT_CONFIG	(MPC5XXX_GPIO + 0x0000)
+
+/* Standard GPIO registers (simple, output only and simple interrupt */
+#define MPC5XXX_GPIO_ENABLE     (MPC5XXX_GPIO + 0x0004)
+#define MPC5XXX_GPIO_ODE        (MPC5XXX_GPIO + 0x0008)
+#define MPC5XXX_GPIO_DIR        (MPC5XXX_GPIO + 0x000c)
+#define MPC5XXX_GPIO_DATA_O     (MPC5XXX_GPIO + 0x0010)
+#define MPC5XXX_GPIO_DATA_I     (MPC5XXX_GPIO + 0x0014)
+#define MPC5XXX_GPIO_OO_ENABLE  (MPC5XXX_GPIO + 0x0018)
+#define MPC5XXX_GPIO_OO_DATA    (MPC5XXX_GPIO + 0x001C)
+#define MPC5XXX_GPIO_SI_ENABLE  (MPC5XXX_GPIO + 0x0020)
+#define MPC5XXX_GPIO_SI_ODE     (MPC5XXX_GPIO + 0x0024)
+#define MPC5XXX_GPIO_SI_DIR     (MPC5XXX_GPIO + 0x0028)
+#define MPC5XXX_GPIO_SI_DATA    (MPC5XXX_GPIO + 0x002C)
+#define MPC5XXX_GPIO_SI_IEN     (MPC5XXX_GPIO + 0x0030)
+#define MPC5XXX_GPIO_SI_ITYPE   (MPC5XXX_GPIO + 0x0034)
+#define MPC5XXX_GPIO_SI_MEN     (MPC5XXX_GPIO + 0x0038)
+#define MPC5XXX_GPIO_SI_STATUS  (MPC5XXX_GPIO + 0x003C)
+
+/* WakeUp GPIO registers */
+#define MPC5XXX_WU_GPIO_ENABLE  (MPC5XXX_WU_GPIO + 0x0000)
+#define MPC5XXX_WU_GPIO_ODE     (MPC5XXX_WU_GPIO + 0x0004)
+#define MPC5XXX_WU_GPIO_DIR     (MPC5XXX_WU_GPIO + 0x0008)
+#define MPC5XXX_WU_GPIO_DATA_O  (MPC5XXX_WU_GPIO + 0x000c)
+#define MPC5XXX_WU_GPIO_DATA_I  (MPC5XXX_WU_GPIO + 0x0020)
+
+/* GPIO pins */
+#define GPIO_WKUP_7		0x80000000UL
+#define GPIO_PSC6_0		0x10000000UL
+#define GPIO_PSC3_9		0x04000000UL
+#define GPIO_PSC1_4		0x01000000UL
+
+/* PCI registers */
+#define MPC5XXX_PCI_CMD		(MPC5XXX_PCI + 0x04)
+#define MPC5XXX_PCI_CFG		(MPC5XXX_PCI + 0x0c)
+#define MPC5XXX_PCI_BAR0	(MPC5XXX_PCI + 0x10)
+#define MPC5XXX_PCI_BAR1	(MPC5XXX_PCI + 0x14)
+#if defined(CONFIG_MGT5100)
+#define MPC5XXX_PCI_CTRL	(MPC5XXX_PCI + 0x68)
+#define MPC5XXX_PCI_VALMSKR	(MPC5XXX_PCI + 0x6c)
+#define MPC5XXX_PCI_VALMSKW	(MPC5XXX_PCI + 0x70)
+#define MPC5XXX_PCI_SUBW1	(MPC5XXX_PCI + 0x74)
+#define MPC5XXX_PCI_SUBW2	(MPC5XXX_PCI + 0x78)
+#define MPC5XXX_PCI_WINCOMMAND	(MPC5XXX_PCI + 0x7c)
+#elif defined(CONFIG_MPC5200)
+#define MPC5XXX_PCI_GSCR	(MPC5XXX_PCI + 0x60)
+#define MPC5XXX_PCI_TBATR0	(MPC5XXX_PCI + 0x64)
+#define MPC5XXX_PCI_TBATR1	(MPC5XXX_PCI + 0x68)
+#define MPC5XXX_PCI_TCR		(MPC5XXX_PCI + 0x6c)
+#define MPC5XXX_PCI_IW0BTAR	(MPC5XXX_PCI + 0x70)
+#define MPC5XXX_PCI_IW1BTAR	(MPC5XXX_PCI + 0x74)
+#define MPC5XXX_PCI_IW2BTAR	(MPC5XXX_PCI + 0x78)
+#define MPC5XXX_PCI_IWCR	(MPC5XXX_PCI + 0x80)
+#define MPC5XXX_PCI_ICR		(MPC5XXX_PCI + 0x84)
+#define MPC5XXX_PCI_ISR		(MPC5XXX_PCI + 0x88)
+#define MPC5XXX_PCI_ARB		(MPC5XXX_PCI + 0x8c)
+#define MPC5XXX_PCI_CAR		(MPC5XXX_PCI + 0xf8)
+#endif
+
+/* Interrupt Controller registers */
+#define MPC5XXX_ICTL_PER_MASK	(MPC5XXX_ICTL + 0x0000)
+#define MPC5XXX_ICTL_PER_PRIO1	(MPC5XXX_ICTL + 0x0004)
+#define MPC5XXX_ICTL_PER_PRIO2	(MPC5XXX_ICTL + 0x0008)
+#define MPC5XXX_ICTL_PER_PRIO3	(MPC5XXX_ICTL + 0x000c)
+#define MPC5XXX_ICTL_EXT	(MPC5XXX_ICTL + 0x0010)
+#define MPC5XXX_ICTL_CRIT	(MPC5XXX_ICTL + 0x0014)
+#define MPC5XXX_ICTL_MAIN_PRIO1	(MPC5XXX_ICTL + 0x0018)
+#define MPC5XXX_ICTL_MAIN_PRIO2	(MPC5XXX_ICTL + 0x001c)
+#define MPC5XXX_ICTL_STS	(MPC5XXX_ICTL + 0x0024)
+#define MPC5XXX_ICTL_CRIT_STS	(MPC5XXX_ICTL + 0x0028)
+#define MPC5XXX_ICTL_MAIN_STS	(MPC5XXX_ICTL + 0x002c)
+#define MPC5XXX_ICTL_PER_STS	(MPC5XXX_ICTL + 0x0030)
+#define MPC5XXX_ICTL_BUS_STS	(MPC5XXX_ICTL + 0x0038)
+
+#define NR_IRQS			64
+
+/* IRQ mapping - these are our logical IRQ numbers */
+#define MPC5XXX_CRIT_IRQ_NUM	4
+#define MPC5XXX_MAIN_IRQ_NUM	17
+#define MPC5XXX_SDMA_IRQ_NUM	17
+#define MPC5XXX_PERP_IRQ_NUM	23
+
+#define MPC5XXX_CRIT_IRQ_BASE	1
+#define MPC5XXX_MAIN_IRQ_BASE	(MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM)
+#define MPC5XXX_SDMA_IRQ_BASE	(MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM)
+#define MPC5XXX_PERP_IRQ_BASE	(MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)
+
+#define MPC5XXX_IRQ0			(MPC5XXX_CRIT_IRQ_BASE + 0)
+#define MPC5XXX_SLICE_TIMER_0_IRQ	(MPC5XXX_CRIT_IRQ_BASE + 1)
+#define MPC5XXX_HI_INT_IRQ		(MPC5XXX_CRIT_IRQ_BASE + 2)
+#define MPC5XXX_CCS_IRQ			(MPC5XXX_CRIT_IRQ_BASE + 3)
+
+#define MPC5XXX_IRQ1			(MPC5XXX_MAIN_IRQ_BASE + 1)
+#define MPC5XXX_IRQ2			(MPC5XXX_MAIN_IRQ_BASE + 2)
+#define MPC5XXX_IRQ3			(MPC5XXX_MAIN_IRQ_BASE + 3)
+#define MPC5XXX_RTC_PINT_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 5)
+#define MPC5XXX_RTC_SINT_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 6)
+#define MPC5XXX_RTC_GPIO_STD_IRQ	(MPC5XXX_MAIN_IRQ_BASE + 7)
+#define MPC5XXX_RTC_GPIO_WKUP_IRQ	(MPC5XXX_MAIN_IRQ_BASE + 8)
+#define MPC5XXX_TMR0_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 9)
+#define MPC5XXX_TMR1_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 10)
+#define MPC5XXX_TMR2_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 11)
+#define MPC5XXX_TMR3_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 12)
+#define MPC5XXX_TMR4_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 13)
+#define MPC5XXX_TMR5_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 14)
+#define MPC5XXX_TMR6_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 15)
+#define MPC5XXX_TMR7_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 16)
+
+#define MPC5XXX_SDMA_IRQ		(MPC5XXX_PERP_IRQ_BASE + 0)
+#define MPC5XXX_PSC1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 1)
+#define MPC5XXX_PSC2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 2)
+#define MPC5XXX_PSC3_IRQ		(MPC5XXX_PERP_IRQ_BASE + 3)
+#define MPC5XXX_PSC6_IRQ		(MPC5XXX_PERP_IRQ_BASE + 4)
+#define MPC5XXX_IRDA_IRQ		(MPC5XXX_PERP_IRQ_BASE + 4)
+#define MPC5XXX_FEC_IRQ			(MPC5XXX_PERP_IRQ_BASE + 5)
+#define MPC5XXX_USB_IRQ			(MPC5XXX_PERP_IRQ_BASE + 6)
+#define MPC5XXX_ATA_IRQ			(MPC5XXX_PERP_IRQ_BASE + 7)
+#define MPC5XXX_PCI_CNTRL_IRQ		(MPC5XXX_PERP_IRQ_BASE + 8)
+#define MPC5XXX_PCI_SCIRX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 9)
+#define MPC5XXX_PCI_SCITX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 10)
+#define MPC5XXX_PSC4_IRQ		(MPC5XXX_PERP_IRQ_BASE + 11)
+#define MPC5XXX_PSC5_IRQ		(MPC5XXX_PERP_IRQ_BASE + 12)
+#define MPC5XXX_SPI_MODF_IRQ		(MPC5XXX_PERP_IRQ_BASE + 13)
+#define MPC5XXX_SPI_SPIF_IRQ		(MPC5XXX_PERP_IRQ_BASE + 14)
+#define MPC5XXX_I2C1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 15)
+#define MPC5XXX_I2C2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 16)
+#define MPC5XXX_MSCAN1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 17)
+#define MPC5XXX_MSCAN2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 18)
+#define MPC5XXX_IR_RX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 19)
+#define MPC5XXX_IR_TX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 20)
+#define MPC5XXX_XLB_ARB_IRQ		(MPC5XXX_PERP_IRQ_BASE + 21)
+#define MPC5XXX_BDLC_IRQ		(MPC5XXX_PERP_IRQ_BASE + 22)
+
+/* General Purpose Timers registers */
+#define MPC5XXX_GPT0_ENABLE		(MPC5XXX_GPT + 0x0)
+#define MPC5XXX_GPT0_COUNTER		(MPC5XXX_GPT + 0x4)
+#define MPC5XXX_GPT0_STATUS		(MPC5XXX_GPT + 0x0C)
+#define MPC5XXX_GPT1_ENABLE		(MPC5XXX_GPT + 0x10)
+#define MPC5XXX_GPT1_COUNTER		(MPC5XXX_GPT + 0x14)
+#define MPC5XXX_GPT1_STATUS		(MPC5XXX_GPT + 0x1C)
+#define MPC5XXX_GPT2_ENABLE		(MPC5XXX_GPT + 0x20)
+#define MPC5XXX_GPT2_COUNTER		(MPC5XXX_GPT + 0x24)
+#define MPC5XXX_GPT2_STATUS		(MPC5XXX_GPT + 0x2C)
+#define MPC5XXX_GPT3_ENABLE		(MPC5XXX_GPT + 0x30)
+#define MPC5XXX_GPT3_COUNTER		(MPC5XXX_GPT + 0x34)
+#define MPC5XXX_GPT3_STATUS		(MPC5XXX_GPT + 0x3C)
+#define MPC5XXX_GPT4_ENABLE		(MPC5XXX_GPT + 0x40)
+#define MPC5XXX_GPT4_COUNTER		(MPC5XXX_GPT + 0x44)
+#define MPC5XXX_GPT4_STATUS		(MPC5XXX_GPT + 0x4C)
+#define MPC5XXX_GPT5_ENABLE		(MPC5XXX_GPT + 0x50)
+#define MPC5XXX_GPT5_STATUS		(MPC5XXX_GPT + 0x5C)
+#define MPC5XXX_GPT5_COUNTER		(MPC5XXX_GPT + 0x54)
+#define MPC5XXX_GPT6_ENABLE		(MPC5XXX_GPT + 0x60)
+#define MPC5XXX_GPT6_COUNTER		(MPC5XXX_GPT + 0x64)
+#define MPC5XXX_GPT6_STATUS		(MPC5XXX_GPT + 0x6C)
+#define MPC5XXX_GPT7_ENABLE		(MPC5XXX_GPT + 0x70)
+#define MPC5XXX_GPT7_COUNTER		(MPC5XXX_GPT + 0x74)
+#define MPC5XXX_GPT7_STATUS		(MPC5XXX_GPT + 0x7C)
+
+#define MPC5XXX_GPT_GPIO_PIN(status)	((0x00000100 & (status)) >> 8)
+
+#define MPC5XXX_GPT7_PWMCFG		(MPC5XXX_GPT + 0x78)
+
+/* ATA registers */
+#define MPC5XXX_ATA_HOST_CONFIG         (MPC5XXX_ATA + 0x0000)
+#define MPC5XXX_ATA_PIO1                (MPC5XXX_ATA + 0x0008)
+#define MPC5XXX_ATA_PIO2                (MPC5XXX_ATA + 0x000C)
+#define MPC5XXX_ATA_SHARE_COUNT         (MPC5XXX_ATA + 0x002C)
+
+/* I2Cn control register bits */
+#define I2C_EN		0x80
+#define I2C_IEN		0x40
+#define I2C_STA		0x20
+#define I2C_TX		0x10
+#define I2C_TXAK	0x08
+#define I2C_RSTA	0x04
+#define I2C_INIT_MASK	(I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
+
+/* I2Cn status register bits */
+#define I2C_CF		0x80
+#define I2C_AAS		0x40
+#define I2C_BB		0x20
+#define I2C_AL		0x10
+#define I2C_SRW		0x04
+#define I2C_IF		0x02
+#define I2C_RXAK	0x01
+
+/* Programmable Serial Controller (PSC) status register bits */
+#define PSC_SR_CDE		0x0080
+#define PSC_SR_RXRDY		0x0100
+#define PSC_SR_RXFULL		0x0200
+#define PSC_SR_TXRDY		0x0400
+#define PSC_SR_TXEMP		0x0800
+#define PSC_SR_OE		0x1000
+#define PSC_SR_PE		0x2000
+#define PSC_SR_FE		0x4000
+#define PSC_SR_RB		0x8000
+
+/* PSC Command values */
+#define PSC_RX_ENABLE		0x0001
+#define PSC_RX_DISABLE		0x0002
+#define PSC_TX_ENABLE		0x0004
+#define PSC_TX_DISABLE		0x0008
+#define PSC_SEL_MODE_REG_1	0x0010
+#define PSC_RST_RX		0x0020
+#define PSC_RST_TX		0x0030
+#define PSC_RST_ERR_STAT	0x0040
+#define PSC_RST_BRK_CHG_INT	0x0050
+#define PSC_START_BRK		0x0060
+#define PSC_STOP_BRK		0x0070
+
+/* PSC Rx FIFO status bits */
+#define PSC_RX_FIFO_ERR		0x0040
+#define PSC_RX_FIFO_UF		0x0020
+#define PSC_RX_FIFO_OF		0x0010
+#define PSC_RX_FIFO_FR		0x0008
+#define PSC_RX_FIFO_FULL	0x0004
+#define PSC_RX_FIFO_ALARM	0x0002
+#define PSC_RX_FIFO_EMPTY	0x0001
+
+/* PSC interrupt mask bits */
+#define PSC_IMR_TXRDY		0x0100
+#define PSC_IMR_RXRDY		0x0200
+#define PSC_IMR_DB		0x0400
+#define PSC_IMR_IPC		0x8000
+
+/* PSC input port change bits */
+#define PSC_IPCR_CTS		0x01
+#define PSC_IPCR_DCD		0x02
+
+/* PSC mode fields */
+#define PSC_MODE_5_BITS		0x00
+#define PSC_MODE_6_BITS		0x01
+#define PSC_MODE_7_BITS		0x02
+#define PSC_MODE_8_BITS		0x03
+#define PSC_MODE_PAREVEN	0x00
+#define PSC_MODE_PARODD		0x04
+#define PSC_MODE_PARFORCE	0x08
+#define PSC_MODE_PARNONE	0x10
+#define PSC_MODE_ERR		0x20
+#define PSC_MODE_FFULL		0x40
+#define PSC_MODE_RXRTS		0x80
+
+#define PSC_MODE_ONE_STOP_5_BITS	0x00
+#define PSC_MODE_ONE_STOP		0x07
+#define PSC_MODE_TWO_STOP		0x0f
+
+
+/* ATA config fields */
+#define MPC5xxx_ATA_HOSTCONF_SMR	0x80000000UL	/* State machine
+							   reset */
+#define MPC5xxx_ATA_HOSTCONF_FR		0x40000000UL	/* FIFO Reset */
+#define MPC5xxx_ATA_HOSTCONF_IE		0x02000000UL	/* Enable interrupt
+							   in PIO */
+#define MPC5xxx_ATA_HOSTCONF_IORDY	0x01000000UL	/* Drive supports
+							   IORDY protocol */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct mpc5xxx_psc {
+	volatile u8	mode;		/* PSC + 0x00 */
+	volatile u8	reserved0[3];
+	union {				/* PSC + 0x04 */
+		volatile u16	status;
+		volatile u16	clock_select;
+	} sr_csr;
+#define psc_status	sr_csr.status
+#define psc_clock_select sr_csr.clock_select
+	volatile u16	reserved1;
+	volatile u8	command;	/* PSC + 0x08 */
+	volatile u8	reserved2[3];
+	union {				/* PSC + 0x0c */
+		volatile u8	buffer_8;
+		volatile u16	buffer_16;
+		volatile u32	buffer_32;
+	} buffer;
+#define psc_buffer_8	buffer.buffer_8
+#define psc_buffer_16	buffer.buffer_16
+#define psc_buffer_32	buffer.buffer_32
+	union {				/* PSC + 0x10 */
+		volatile u8	ipcr;
+		volatile u8	acr;
+	} ipcr_acr;
+#define psc_ipcr	ipcr_acr.ipcr
+#define psc_acr		ipcr_acr.acr
+	volatile u8	reserved3[3];
+	union {				/* PSC + 0x14 */
+		volatile u16	isr;
+		volatile u16	imr;
+	} isr_imr;
+#define psc_isr		isr_imr.isr
+#define psc_imr		isr_imr.imr
+	volatile u16	reserved4;
+	volatile u8	ctur;		/* PSC + 0x18 */
+	volatile u8	reserved5[3];
+	volatile u8	ctlr;		/* PSC + 0x1c */
+	volatile u8	reserved6[3];
+	volatile u16	ccr;		/* PSC + 0x20 */
+	volatile u8	reserved7[14];
+	volatile u8	ivr;		/* PSC + 0x30 */
+	volatile u8	reserved8[3];
+	volatile u8	ip;		/* PSC + 0x34 */
+	volatile u8	reserved9[3];
+	volatile u8	op1;		/* PSC + 0x38 */
+	volatile u8	reserved10[3];
+	volatile u8	op0;		/* PSC + 0x3c */
+	volatile u8	reserved11[3];
+	volatile u32	sicr;		/* PSC + 0x40 */
+	volatile u8	ircr1;		/* PSC + 0x44 */
+	volatile u8	reserved12[3];
+	volatile u8	ircr2;		/* PSC + 0x44 */
+	volatile u8	reserved13[3];
+	volatile u8	irsdr;		/* PSC + 0x4c */
+	volatile u8	reserved14[3];
+	volatile u8	irmdr;		/* PSC + 0x50 */
+	volatile u8	reserved15[3];
+	volatile u8	irfdr;		/* PSC + 0x54 */
+	volatile u8	reserved16[3];
+	volatile u16	rfnum;		/* PSC + 0x58 */
+	volatile u16	reserved17;
+	volatile u16	tfnum;		/* PSC + 0x5c */
+	volatile u16	reserved18;
+	volatile u32	rfdata;		/* PSC + 0x60 */
+	volatile u16	rfstat;		/* PSC + 0x64 */
+	volatile u16	reserved20;
+	volatile u8	rfcntl;		/* PSC + 0x68 */
+	volatile u8	reserved21[5];
+	volatile u16	rfalarm;	/* PSC + 0x6e */
+	volatile u16	reserved22;
+	volatile u16	rfrptr;		/* PSC + 0x72 */
+	volatile u16	reserved23;
+	volatile u16	rfwptr;		/* PSC + 0x76 */
+	volatile u16	reserved24;
+	volatile u16	rflrfptr;	/* PSC + 0x7a */
+	volatile u16	reserved25;
+	volatile u16	rflwfptr;	/* PSC + 0x7e */
+	volatile u32	tfdata;		/* PSC + 0x80 */
+	volatile u16	tfstat;		/* PSC + 0x84 */
+	volatile u16	reserved26;
+	volatile u8	tfcntl;		/* PSC + 0x88 */
+	volatile u8	reserved27[5];
+	volatile u16	tfalarm;	/* PSC + 0x8e */
+	volatile u16	reserved28;
+	volatile u16	tfrptr;		/* PSC + 0x92 */
+	volatile u16	reserved29;
+	volatile u16	tfwptr;		/* PSC + 0x96 */
+	volatile u16	reserved30;
+	volatile u16	tflrfptr;	/* PSC + 0x9a */
+	volatile u16	reserved31;
+	volatile u16	tflwfptr;	/* PSC + 0x9e */
+};
+
+struct mpc5xxx_intr {
+	volatile u32	per_mask;	/* INTR + 0x00 */
+	volatile u32	per_pri1;	/* INTR + 0x04 */
+	volatile u32	per_pri2;	/* INTR + 0x08 */
+	volatile u32	per_pri3;	/* INTR + 0x0c */
+	volatile u32	ctrl;		/* INTR + 0x10 */
+	volatile u32	main_mask;	/* INTR + 0x14 */
+	volatile u32	main_pri1;	/* INTR + 0x18 */
+	volatile u32	main_pri2;	/* INTR + 0x1c */
+	volatile u32	reserved1;	/* INTR + 0x20 */
+	volatile u32	enc_status;	/* INTR + 0x24 */
+	volatile u32	crit_status;	/* INTR + 0x28 */
+	volatile u32	main_status;	/* INTR + 0x2c */
+	volatile u32	per_status;	/* INTR + 0x30 */
+	volatile u32	reserved2;	/* INTR + 0x34 */
+	volatile u32	per_error;	/* INTR + 0x38 */
+};
+
+struct mpc5xxx_gpio {
+	volatile u32 port_config;	/* GPIO + 0x00 */
+	volatile u32 simple_gpioe;	/* GPIO + 0x04 */
+	volatile u32 simple_ode;	/* GPIO + 0x08 */
+	volatile u32 simple_ddr;	/* GPIO + 0x0c */
+	volatile u32 simple_dvo;	/* GPIO + 0x10 */
+	volatile u32 simple_ival;	/* GPIO + 0x14 */
+	volatile u8 outo_gpioe;		/* GPIO + 0x18 */
+	volatile u8 reserved1[3];	/* GPIO + 0x19 */
+	volatile u8 outo_dvo;		/* GPIO + 0x1c */
+	volatile u8 reserved2[3];	/* GPIO + 0x1d */
+	volatile u8 sint_gpioe;		/* GPIO + 0x20 */
+	volatile u8 reserved3[3];	/* GPIO + 0x21 */
+	volatile u8 sint_ode;		/* GPIO + 0x24 */
+	volatile u8 reserved4[3];	/* GPIO + 0x25 */
+	volatile u8 sint_ddr;		/* GPIO + 0x28 */
+	volatile u8 reserved5[3];	/* GPIO + 0x29 */
+	volatile u8 sint_dvo;		/* GPIO + 0x2c */
+	volatile u8 reserved6[3];	/* GPIO + 0x2d */
+	volatile u8 sint_inten;		/* GPIO + 0x30 */
+	volatile u8 reserved7[3];	/* GPIO + 0x31 */
+	volatile u16 sint_itype;	/* GPIO + 0x34 */
+	volatile u16 reserved8;		/* GPIO + 0x36 */
+	volatile u8 gpio_control;	/* GPIO + 0x38 */
+	volatile u8 reserved9[3];	/* GPIO + 0x39 */
+	volatile u8 sint_istat;		/* GPIO + 0x3c */
+	volatile u8 sint_ival;		/* GPIO + 0x3d */
+	volatile u8 bus_errs;		/* GPIO + 0x3e */
+	volatile u8 reserved10;		/* GPIO + 0x3f */
+};
+
+struct mpc5xxx_sdma {
+	volatile u32 taskBar;		/* SDMA + 0x00 */
+	volatile u32 currentPointer;	/* SDMA + 0x04 */
+	volatile u32 endPointer;	/* SDMA + 0x08 */
+	volatile u32 variablePointer;	/* SDMA + 0x0c */
+
+	volatile u8 IntVect1;		/* SDMA + 0x10 */
+	volatile u8 IntVect2;		/* SDMA + 0x11 */
+	volatile u16 PtdCntrl;		/* SDMA + 0x12 */
+
+	volatile u32 IntPend;		/* SDMA + 0x14 */
+	volatile u32 IntMask;		/* SDMA + 0x18 */
+
+	volatile u16 tcr_0;		/* SDMA + 0x1c */
+	volatile u16 tcr_1;		/* SDMA + 0x1e */
+	volatile u16 tcr_2;		/* SDMA + 0x20 */
+	volatile u16 tcr_3;		/* SDMA + 0x22 */
+	volatile u16 tcr_4;		/* SDMA + 0x24 */
+	volatile u16 tcr_5;		/* SDMA + 0x26 */
+	volatile u16 tcr_6;		/* SDMA + 0x28 */
+	volatile u16 tcr_7;		/* SDMA + 0x2a */
+	volatile u16 tcr_8;		/* SDMA + 0x2c */
+	volatile u16 tcr_9;		/* SDMA + 0x2e */
+	volatile u16 tcr_a;		/* SDMA + 0x30 */
+	volatile u16 tcr_b;		/* SDMA + 0x32 */
+	volatile u16 tcr_c;		/* SDMA + 0x34 */
+	volatile u16 tcr_d;		/* SDMA + 0x36 */
+	volatile u16 tcr_e;		/* SDMA + 0x38 */
+	volatile u16 tcr_f;		/* SDMA + 0x3a */
+
+	volatile u8 IPR0;		/* SDMA + 0x3c */
+	volatile u8 IPR1;		/* SDMA + 0x3d */
+	volatile u8 IPR2;		/* SDMA + 0x3e */
+	volatile u8 IPR3;		/* SDMA + 0x3f */
+	volatile u8 IPR4;		/* SDMA + 0x40 */
+	volatile u8 IPR5;		/* SDMA + 0x41 */
+	volatile u8 IPR6;		/* SDMA + 0x42 */
+	volatile u8 IPR7;		/* SDMA + 0x43 */
+	volatile u8 IPR8;		/* SDMA + 0x44 */
+	volatile u8 IPR9;		/* SDMA + 0x45 */
+	volatile u8 IPR10;		/* SDMA + 0x46 */
+	volatile u8 IPR11;		/* SDMA + 0x47 */
+	volatile u8 IPR12;		/* SDMA + 0x48 */
+	volatile u8 IPR13;		/* SDMA + 0x49 */
+	volatile u8 IPR14;		/* SDMA + 0x4a */
+	volatile u8 IPR15;		/* SDMA + 0x4b */
+	volatile u8 IPR16;		/* SDMA + 0x4c */
+	volatile u8 IPR17;		/* SDMA + 0x4d */
+	volatile u8 IPR18;		/* SDMA + 0x4e */
+	volatile u8 IPR19;		/* SDMA + 0x4f */
+	volatile u8 IPR20;		/* SDMA + 0x50 */
+	volatile u8 IPR21;		/* SDMA + 0x51 */
+	volatile u8 IPR22;		/* SDMA + 0x52 */
+	volatile u8 IPR23;		/* SDMA + 0x53 */
+	volatile u8 IPR24;		/* SDMA + 0x54 */
+	volatile u8 IPR25;		/* SDMA + 0x55 */
+	volatile u8 IPR26;		/* SDMA + 0x56 */
+	volatile u8 IPR27;		/* SDMA + 0x57 */
+	volatile u8 IPR28;		/* SDMA + 0x58 */
+	volatile u8 IPR29;		/* SDMA + 0x59 */
+	volatile u8 IPR30;		/* SDMA + 0x5a */
+	volatile u8 IPR31;		/* SDMA + 0x5b */
+
+	volatile u32 res1;		/* SDMA + 0x5c */
+	volatile u32 res2;		/* SDMA + 0x60 */
+	volatile u32 res3;		/* SDMA + 0x64 */
+	volatile u32 MDEDebug;		/* SDMA + 0x68 */
+	volatile u32 ADSDebug;		/* SDMA + 0x6c */
+	volatile u32 Value1;		/* SDMA + 0x70 */
+	volatile u32 Value2;		/* SDMA + 0x74 */
+	volatile u32 Control;		/* SDMA + 0x78 */
+	volatile u32 Status;		/* SDMA + 0x7c */
+	volatile u32 EU00;		/* SDMA + 0x80 */
+	volatile u32 EU01;		/* SDMA + 0x84 */
+	volatile u32 EU02;		/* SDMA + 0x88 */
+	volatile u32 EU03;		/* SDMA + 0x8c */
+	volatile u32 EU04;		/* SDMA + 0x90 */
+	volatile u32 EU05;		/* SDMA + 0x94 */
+	volatile u32 EU06;		/* SDMA + 0x98 */
+	volatile u32 EU07;		/* SDMA + 0x9c */
+	volatile u32 EU10;		/* SDMA + 0xa0 */
+	volatile u32 EU11;		/* SDMA + 0xa4 */
+	volatile u32 EU12;		/* SDMA + 0xa8 */
+	volatile u32 EU13;		/* SDMA + 0xac */
+	volatile u32 EU14;		/* SDMA + 0xb0 */
+	volatile u32 EU15;		/* SDMA + 0xb4 */
+	volatile u32 EU16;		/* SDMA + 0xb8 */
+	volatile u32 EU17;		/* SDMA + 0xbc */
+	volatile u32 EU20;		/* SDMA + 0xc0 */
+	volatile u32 EU21;		/* SDMA + 0xc4 */
+	volatile u32 EU22;		/* SDMA + 0xc8 */
+	volatile u32 EU23;		/* SDMA + 0xcc */
+	volatile u32 EU24;		/* SDMA + 0xd0 */
+	volatile u32 EU25;		/* SDMA + 0xd4 */
+	volatile u32 EU26;		/* SDMA + 0xd8 */
+	volatile u32 EU27;		/* SDMA + 0xdc */
+	volatile u32 EU30;		/* SDMA + 0xe0 */
+	volatile u32 EU31;		/* SDMA + 0xe4 */
+	volatile u32 EU32;		/* SDMA + 0xe8 */
+	volatile u32 EU33;		/* SDMA + 0xec */
+	volatile u32 EU34;		/* SDMA + 0xf0 */
+	volatile u32 EU35;		/* SDMA + 0xf4 */
+	volatile u32 EU36;		/* SDMA + 0xf8 */
+	volatile u32 EU37;		/* SDMA + 0xfc */
+};
+
+struct mpc5xxx_i2c {
+	volatile u32 madr;		/* I2Cn + 0x00 */
+	volatile u32 mfdr;		/* I2Cn + 0x04 */
+	volatile u32 mcr;		/* I2Cn + 0x08 */
+	volatile u32 msr;		/* I2Cn + 0x0C */
+	volatile u32 mdr;		/* I2Cn + 0x10 */
+};
+
+struct mpc5xxx_spi {
+	volatile u8 cr1;		/* SPI + 0x0F00 */
+	volatile u8 cr2;		/* SPI + 0x0F01 */
+	volatile u8 reserved1[2];
+	volatile u8 brr;		/* SPI + 0x0F04 */
+	volatile u8 sr;			/* SPI + 0x0F05 */
+	volatile u8 reserved2[3];
+	volatile u8 dr;			/* SPI + 0x0F09 */
+	volatile u8 reserved3[3];
+	volatile u8 pdr;		/* SPI + 0x0F0D */
+	volatile u8 reserved4[2];
+	volatile u8 ddr;		/* SPI + 0x0F10 */
+};
+
+
+struct mpc5xxx_gpt {
+	volatile u32 emsr;		/* GPT + Timer# * 0x10 + 0x00 */
+	volatile u32 cir;		/* GPT + Timer# * 0x10 + 0x04 */
+	volatile u32 pwmcr;		/* GPT + Timer# * 0x10 + 0x08 */
+	volatile u32 sr;		/* GPT + Timer# * 0x10 + 0x0c */
+};
+
+struct mpc5xxx_gpt_0_7 {
+	struct mpc5xxx_gpt gpt0;
+	struct mpc5xxx_gpt gpt1;
+	struct mpc5xxx_gpt gpt2;
+	struct mpc5xxx_gpt gpt3;
+	struct mpc5xxx_gpt gpt4;
+	struct mpc5xxx_gpt gpt5;
+	struct mpc5xxx_gpt gpt6;
+	struct mpc5xxx_gpt gpt7;
+};
+
+struct mscan_buffer {
+	volatile u8  idr[0x8];          /* 0x00 */
+	volatile u8  dsr[0x10];         /* 0x08 */
+	volatile u8  dlr;               /* 0x18 */
+	volatile u8  tbpr;              /* 0x19 */      /* This register is not applicable for receive buffers */
+	volatile u16 rsrv1;             /* 0x1A */
+	volatile u8  tsrh;              /* 0x1C */
+	volatile u8  tsrl;              /* 0x1D */
+	volatile u16 rsrv2;             /* 0x1E */
+};
+
+struct mpc5xxx_mscan {
+	volatile u8  canctl0;           /* MSCAN + 0x00 */
+	volatile u8  canctl1;           /* MSCAN + 0x01 */
+	volatile u16 rsrv1;             /* MSCAN + 0x02 */
+	volatile u8  canbtr0;           /* MSCAN + 0x04 */
+	volatile u8  canbtr1;           /* MSCAN + 0x05 */
+	volatile u16 rsrv2;             /* MSCAN + 0x06 */
+	volatile u8  canrflg;           /* MSCAN + 0x08 */
+	volatile u8  canrier;           /* MSCAN + 0x09 */
+	volatile u16 rsrv3;             /* MSCAN + 0x0A */
+	volatile u8  cantflg;           /* MSCAN + 0x0C */
+	volatile u8  cantier;           /* MSCAN + 0x0D */
+	volatile u16 rsrv4;             /* MSCAN + 0x0E */
+	volatile u8  cantarq;           /* MSCAN + 0x10 */
+	volatile u8  cantaak;           /* MSCAN + 0x11 */
+	volatile u16 rsrv5;             /* MSCAN + 0x12 */
+	volatile u8  cantbsel;          /* MSCAN + 0x14 */
+	volatile u8  canidac;           /* MSCAN + 0x15 */
+	volatile u16 rsrv6[3];          /* MSCAN + 0x16 */
+	volatile u8  canrxerr;          /* MSCAN + 0x1C */
+	volatile u8  cantxerr;          /* MSCAN + 0x1D */
+	volatile u16 rsrv7;             /* MSCAN + 0x1E */
+	volatile u8  canidar0;          /* MSCAN + 0x20 */
+	volatile u8  canidar1;          /* MSCAN + 0x21 */
+	volatile u16 rsrv8;             /* MSCAN + 0x22 */
+	volatile u8  canidar2;          /* MSCAN + 0x24 */
+	volatile u8  canidar3;          /* MSCAN + 0x25 */
+	volatile u16 rsrv9;             /* MSCAN + 0x26 */
+	volatile u8  canidmr0;          /* MSCAN + 0x28 */
+	volatile u8  canidmr1;          /* MSCAN + 0x29 */
+	volatile u16 rsrv10;            /* MSCAN + 0x2A */
+	volatile u8  canidmr2;          /* MSCAN + 0x2C */
+	volatile u8  canidmr3;          /* MSCAN + 0x2D */
+	volatile u16 rsrv11;            /* MSCAN + 0x2E */
+	volatile u8  canidar4;          /* MSCAN + 0x30 */
+	volatile u8  canidar5;          /* MSCAN + 0x31 */
+	volatile u16 rsrv12;            /* MSCAN + 0x32 */
+	volatile u8  canidar6;          /* MSCAN + 0x34 */
+	volatile u8  canidar7;          /* MSCAN + 0x35 */
+	volatile u16 rsrv13;            /* MSCAN + 0x36 */
+	volatile u8  canidmr4;          /* MSCAN + 0x38 */
+	volatile u8  canidmr5;          /* MSCAN + 0x39 */
+	volatile u16 rsrv14;            /* MSCAN + 0x3A */
+	volatile u8  canidmr6;          /* MSCAN + 0x3C */
+	volatile u8  canidmr7;          /* MSCAN + 0x3D */
+	volatile u16 rsrv15;            /* MSCAN + 0x3E */
+
+	struct mscan_buffer canrxfg;    /* MSCAN + 0x40 */    /* Foreground receive buffer */
+	struct mscan_buffer cantxfg;    /* MSCAN + 0x60 */    /* Foreground transmit buffer */
+	};
+
+/* function prototypes */
+void loadtask(int basetask, int tasks);
+
+/* retrieve configured sdram size connected to a chipselect */
+unsigned long mpc5200_get_sdram_size(unsigned int cs);
+
+/* configure a local plus bus chip select */
+#define MPC5200_BOOTCS 8
+void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg);
+
+/* configure bus speeds. Both dividers are relative to xlb clock */
+int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASMPPC_MPC5200_H */
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
index f2cae90..2455484 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
@@ -1,793 +1,8 @@
-/*
- * arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
- *
- * Prototypes, etc. for the Motorola MGT5xxx/MPC5xxx
- * embedded cpu chips
- *
- * 2003 (c) MontaVista, Software, Inc.
- * Author: Dale Farnsworth <dfarnsworth at mvista.com>
- *
- * 2003 (C) Wolfgang Denk, DENX Software Engineering, wd at denx.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.
- *
- */
 #ifndef __ASMPPC_MPC5XXX_H
 #define __ASMPPC_MPC5XXX_H
 
-/* Processor name */
-#if defined(CONFIG_MPC5200)
-#define CPU_ID_STR	"MPC5200"
-#elif defined(CONFIG_MGT5100)
-#define CPU_ID_STR	"MGT5100"
+#if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100)
+# include <mach/mpc5200.h>
+#else
+# error "Undefined Core CPU"
 #endif
-
-/* Exception offsets (PowerPC standard) */
-#define EXC_OFF_SYS_RESET	0x0100
-#define _START_OFFSET		EXC_OFF_SYS_RESET
-
-#define CFG_MBAR 0xf0000000
-
-/* useful macros for manipulating CSx_START/STOP */
-#if defined(CONFIG_MGT5100)
-#define START_REG(start)	((start) >> 15)
-#define STOP_REG(start, size)	(((start) + (size) - 1) >> 15)
-#elif defined(CONFIG_MPC5200)
-#define START_REG(start)	((start) >> 16)
-#define STOP_REG(start, size)	(((start) + (size) - 1) >> 16)
-#endif
-
-/* Internal memory map */
-
-#define MPC5XXX_CS0_START	(CFG_MBAR + 0x0004)
-#define MPC5XXX_CS0_STOP	(CFG_MBAR + 0x0008)
-#define MPC5XXX_CS1_START	(CFG_MBAR + 0x000c)
-#define MPC5XXX_CS1_STOP	(CFG_MBAR + 0x0010)
-#define MPC5XXX_CS2_START	(CFG_MBAR + 0x0014)
-#define MPC5XXX_CS2_STOP	(CFG_MBAR + 0x0018)
-#define MPC5XXX_CS3_START	(CFG_MBAR + 0x001c)
-#define MPC5XXX_CS3_STOP	(CFG_MBAR + 0x0020)
-#define MPC5XXX_CS4_START	(CFG_MBAR + 0x0024)
-#define MPC5XXX_CS4_STOP	(CFG_MBAR + 0x0028)
-#define MPC5XXX_CS5_START	(CFG_MBAR + 0x002c)
-#define MPC5XXX_CS5_STOP	(CFG_MBAR + 0x0030)
-#define MPC5XXX_BOOTCS_START	(CFG_MBAR + 0x004c)
-#define MPC5XXX_BOOTCS_STOP	(CFG_MBAR + 0x0050)
-#define MPC5XXX_ADDECR		(CFG_MBAR + 0x0054)
-
-#if defined(CONFIG_MGT5100)
-#define MPC5XXX_SDRAM_START	(CFG_MBAR + 0x0034)
-#define MPC5XXX_SDRAM_STOP	(CFG_MBAR + 0x0038)
-#define MPC5XXX_PCI1_START	(CFG_MBAR + 0x003c)
-#define MPC5XXX_PCI1_STOP	(CFG_MBAR + 0x0040)
-#define MPC5XXX_PCI2_START	(CFG_MBAR + 0x0044)
-#define MPC5XXX_PCI2_STOP	(CFG_MBAR + 0x0048)
-#elif defined(CONFIG_MPC5200)
-#define MPC5XXX_CS6_START	(CFG_MBAR + 0x0058)
-#define MPC5XXX_CS6_STOP	(CFG_MBAR + 0x005c)
-#define MPC5XXX_CS7_START	(CFG_MBAR + 0x0060)
-#define MPC5XXX_CS7_STOP	(CFG_MBAR + 0x0064)
-#define MPC5XXX_SDRAM_CS0CFG	(CFG_MBAR + 0x0034)
-#define MPC5XXX_SDRAM_CS1CFG	(CFG_MBAR + 0x0038)
-#endif
-
-#define MPC5XXX_SDRAM		(CFG_MBAR + 0x0100)
-#define MPC5XXX_CDM		(CFG_MBAR + 0x0200)
-#define MPC5XXX_LPB		(CFG_MBAR + 0x0300)
-#define MPC5XXX_ICTL		(CFG_MBAR + 0x0500)
-#define MPC5XXX_GPT		(CFG_MBAR + 0x0600)
-#define MPC5XXX_GPIO		(CFG_MBAR + 0x0b00)
-#define MPC5XXX_WU_GPIO         (CFG_MBAR + 0x0c00)
-#define MPC5XXX_PCI		(CFG_MBAR + 0x0d00)
-#define MPC5XXX_SPI		(CFG_MBAR + 0x0f00)
-#define MPC5XXX_USB		(CFG_MBAR + 0x1000)
-#define MPC5XXX_SDMA		(CFG_MBAR + 0x1200)
-#define MPC5XXX_XLBARB		(CFG_MBAR + 0x1f00)
-
-#if defined(CONFIG_MGT5100)
-#define	MPC5XXX_PSC1		(CFG_MBAR + 0x2000)
-#define	MPC5XXX_PSC2		(CFG_MBAR + 0x2400)
-#define	MPC5XXX_PSC3		(CFG_MBAR + 0x2800)
-#elif defined(CONFIG_MPC5200)
-#define	MPC5XXX_PSC1		(CFG_MBAR + 0x2000)
-#define	MPC5XXX_PSC2		(CFG_MBAR + 0x2200)
-#define	MPC5XXX_PSC3		(CFG_MBAR + 0x2400)
-#define	MPC5XXX_PSC4		(CFG_MBAR + 0x2600)
-#define	MPC5XXX_PSC5		(CFG_MBAR + 0x2800)
-#define	MPC5XXX_PSC6		(CFG_MBAR + 0x2c00)
-#endif
-
-#define	MPC5XXX_FEC		(CFG_MBAR + 0x3000)
-#define MPC5XXX_ATA             (CFG_MBAR + 0x3A00)
-
-#define MPC5XXX_I2C1		(CFG_MBAR + 0x3D00)
-#define MPC5XXX_I2C2		(CFG_MBAR + 0x3D40)
-
-#if defined(CONFIG_MGT5100)
-#define MPC5XXX_SRAM		(CFG_MBAR + 0x4000)
-#define MPC5XXX_SRAM_SIZE	(8*1024)
-#elif defined(CONFIG_MPC5200)
-#define MPC5XXX_SRAM		(CFG_MBAR + 0x8000)
-#define MPC5XXX_SRAM_SIZE	(16*1024)
-#endif
-
-/* SDRAM Controller */
-#define MPC5XXX_SDRAM_MODE	(MPC5XXX_SDRAM + 0x0000)
-#define MPC5XXX_SDRAM_CTRL	(MPC5XXX_SDRAM + 0x0004)
-#define MPC5XXX_SDRAM_CONFIG1	(MPC5XXX_SDRAM + 0x0008)
-#define MPC5XXX_SDRAM_CONFIG2	(MPC5XXX_SDRAM + 0x000c)
-#if defined(CONFIG_MGT5100)
-#define MPC5XXX_SDRAM_XLBSEL	(MPC5XXX_SDRAM + 0x0010)
-#endif
-#define MPC5XXX_SDRAM_SDELAY	(MPC5XXX_SDRAM + 0x0090)
-
-/* Clock Distribution Module */
-#define MPC5XXX_CDM_JTAGID	(MPC5XXX_CDM + 0x0000)
-#define MPC5XXX_CDM_PORCFG	(MPC5XXX_CDM + 0x0004)
-#define MPC5XXX_CDM_CFG		(MPC5XXX_CDM + 0x000c)
-#define MPC5XXX_CDM_48_FDC	(MPC5XXX_CDM + 0x0010)
-#define MPC5XXX_CDM_SRESET	(MPC5XXX_CDM + 0x0020)
-
-/* Local Plus Bus interface */
-#define MPC5XXX_CS0_CFG		(MPC5XXX_LPB + 0x0000)
-#define MPC5XXX_CS1_CFG		(MPC5XXX_LPB + 0x0004)
-#define MPC5XXX_CS2_CFG		(MPC5XXX_LPB + 0x0008)
-#define MPC5XXX_CS3_CFG		(MPC5XXX_LPB + 0x000c)
-#define MPC5XXX_CS4_CFG		(MPC5XXX_LPB + 0x0010)
-#define MPC5XXX_CS5_CFG		(MPC5XXX_LPB + 0x0014)
-#define MPC5XXX_BOOTCS_CFG	MPC5XXX_CS0_CFG
-#define MPC5XXX_CS_CTRL		(MPC5XXX_LPB + 0x0018)
-#define MPC5XXX_CS_STATUS	(MPC5XXX_LPB + 0x001c)
-#if defined(CONFIG_MPC5200)
-#define MPC5XXX_CS6_CFG		(MPC5XXX_LPB + 0x0020)
-#define MPC5XXX_CS7_CFG		(MPC5XXX_LPB + 0x0024)
-#define MPC5XXX_CS_BURST	(MPC5XXX_LPB + 0x0028)
-#define MPC5XXX_CS_DEADCYCLE	(MPC5XXX_LPB + 0x002c)
-#endif
-
-#if defined(CONFIG_MPC5200)
-/* XLB Arbiter registers */
-#define MPC5XXX_XLBARB_CFG		(MPC5XXX_XLBARB + 0x40)
-#define MPC5XXX_XLBARB_MPRIEN	(MPC5XXX_XLBARB + 0x64)
-#define MPC5XXX_XLBARB_MPRIVAL	(MPC5XXX_XLBARB + 0x68)
-#endif
-
-/* GPIO registers */
-#define MPC5XXX_GPS_PORT_CONFIG	(MPC5XXX_GPIO + 0x0000)
-
-/* Standard GPIO registers (simple, output only and simple interrupt */
-#define MPC5XXX_GPIO_ENABLE     (MPC5XXX_GPIO + 0x0004)
-#define MPC5XXX_GPIO_ODE        (MPC5XXX_GPIO + 0x0008)
-#define MPC5XXX_GPIO_DIR        (MPC5XXX_GPIO + 0x000c)
-#define MPC5XXX_GPIO_DATA_O     (MPC5XXX_GPIO + 0x0010)
-#define MPC5XXX_GPIO_DATA_I     (MPC5XXX_GPIO + 0x0014)
-#define MPC5XXX_GPIO_OO_ENABLE  (MPC5XXX_GPIO + 0x0018)
-#define MPC5XXX_GPIO_OO_DATA    (MPC5XXX_GPIO + 0x001C)
-#define MPC5XXX_GPIO_SI_ENABLE  (MPC5XXX_GPIO + 0x0020)
-#define MPC5XXX_GPIO_SI_ODE     (MPC5XXX_GPIO + 0x0024)
-#define MPC5XXX_GPIO_SI_DIR     (MPC5XXX_GPIO + 0x0028)
-#define MPC5XXX_GPIO_SI_DATA    (MPC5XXX_GPIO + 0x002C)
-#define MPC5XXX_GPIO_SI_IEN     (MPC5XXX_GPIO + 0x0030)
-#define MPC5XXX_GPIO_SI_ITYPE   (MPC5XXX_GPIO + 0x0034)
-#define MPC5XXX_GPIO_SI_MEN     (MPC5XXX_GPIO + 0x0038)
-#define MPC5XXX_GPIO_SI_STATUS  (MPC5XXX_GPIO + 0x003C)
-
-/* WakeUp GPIO registers */
-#define MPC5XXX_WU_GPIO_ENABLE  (MPC5XXX_WU_GPIO + 0x0000)
-#define MPC5XXX_WU_GPIO_ODE     (MPC5XXX_WU_GPIO + 0x0004)
-#define MPC5XXX_WU_GPIO_DIR     (MPC5XXX_WU_GPIO + 0x0008)
-#define MPC5XXX_WU_GPIO_DATA_O  (MPC5XXX_WU_GPIO + 0x000c)
-#define MPC5XXX_WU_GPIO_DATA_I  (MPC5XXX_WU_GPIO + 0x0020)
-
-/* GPIO pins */
-#define GPIO_WKUP_7		0x80000000UL
-#define GPIO_PSC6_0		0x10000000UL
-#define GPIO_PSC3_9		0x04000000UL
-#define GPIO_PSC1_4		0x01000000UL
-
-/* PCI registers */
-#define MPC5XXX_PCI_CMD		(MPC5XXX_PCI + 0x04)
-#define MPC5XXX_PCI_CFG		(MPC5XXX_PCI + 0x0c)
-#define MPC5XXX_PCI_BAR0	(MPC5XXX_PCI + 0x10)
-#define MPC5XXX_PCI_BAR1	(MPC5XXX_PCI + 0x14)
-#if defined(CONFIG_MGT5100)
-#define MPC5XXX_PCI_CTRL	(MPC5XXX_PCI + 0x68)
-#define MPC5XXX_PCI_VALMSKR	(MPC5XXX_PCI + 0x6c)
-#define MPC5XXX_PCI_VALMSKW	(MPC5XXX_PCI + 0x70)
-#define MPC5XXX_PCI_SUBW1	(MPC5XXX_PCI + 0x74)
-#define MPC5XXX_PCI_SUBW2	(MPC5XXX_PCI + 0x78)
-#define MPC5XXX_PCI_WINCOMMAND	(MPC5XXX_PCI + 0x7c)
-#elif defined(CONFIG_MPC5200)
-#define MPC5XXX_PCI_GSCR	(MPC5XXX_PCI + 0x60)
-#define MPC5XXX_PCI_TBATR0	(MPC5XXX_PCI + 0x64)
-#define MPC5XXX_PCI_TBATR1	(MPC5XXX_PCI + 0x68)
-#define MPC5XXX_PCI_TCR		(MPC5XXX_PCI + 0x6c)
-#define MPC5XXX_PCI_IW0BTAR	(MPC5XXX_PCI + 0x70)
-#define MPC5XXX_PCI_IW1BTAR	(MPC5XXX_PCI + 0x74)
-#define MPC5XXX_PCI_IW2BTAR	(MPC5XXX_PCI + 0x78)
-#define MPC5XXX_PCI_IWCR	(MPC5XXX_PCI + 0x80)
-#define MPC5XXX_PCI_ICR		(MPC5XXX_PCI + 0x84)
-#define MPC5XXX_PCI_ISR		(MPC5XXX_PCI + 0x88)
-#define MPC5XXX_PCI_ARB		(MPC5XXX_PCI + 0x8c)
-#define MPC5XXX_PCI_CAR		(MPC5XXX_PCI + 0xf8)
-#endif
-
-/* Interrupt Controller registers */
-#define MPC5XXX_ICTL_PER_MASK	(MPC5XXX_ICTL + 0x0000)
-#define MPC5XXX_ICTL_PER_PRIO1	(MPC5XXX_ICTL + 0x0004)
-#define MPC5XXX_ICTL_PER_PRIO2	(MPC5XXX_ICTL + 0x0008)
-#define MPC5XXX_ICTL_PER_PRIO3	(MPC5XXX_ICTL + 0x000c)
-#define MPC5XXX_ICTL_EXT	(MPC5XXX_ICTL + 0x0010)
-#define MPC5XXX_ICTL_CRIT	(MPC5XXX_ICTL + 0x0014)
-#define MPC5XXX_ICTL_MAIN_PRIO1	(MPC5XXX_ICTL + 0x0018)
-#define MPC5XXX_ICTL_MAIN_PRIO2	(MPC5XXX_ICTL + 0x001c)
-#define MPC5XXX_ICTL_STS	(MPC5XXX_ICTL + 0x0024)
-#define MPC5XXX_ICTL_CRIT_STS	(MPC5XXX_ICTL + 0x0028)
-#define MPC5XXX_ICTL_MAIN_STS	(MPC5XXX_ICTL + 0x002c)
-#define MPC5XXX_ICTL_PER_STS	(MPC5XXX_ICTL + 0x0030)
-#define MPC5XXX_ICTL_BUS_STS	(MPC5XXX_ICTL + 0x0038)
-
-#define NR_IRQS			64
-
-/* IRQ mapping - these are our logical IRQ numbers */
-#define MPC5XXX_CRIT_IRQ_NUM	4
-#define MPC5XXX_MAIN_IRQ_NUM	17
-#define MPC5XXX_SDMA_IRQ_NUM	17
-#define MPC5XXX_PERP_IRQ_NUM	23
-
-#define MPC5XXX_CRIT_IRQ_BASE	1
-#define MPC5XXX_MAIN_IRQ_BASE	(MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM)
-#define MPC5XXX_SDMA_IRQ_BASE	(MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM)
-#define MPC5XXX_PERP_IRQ_BASE	(MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)
-
-#define MPC5XXX_IRQ0			(MPC5XXX_CRIT_IRQ_BASE + 0)
-#define MPC5XXX_SLICE_TIMER_0_IRQ	(MPC5XXX_CRIT_IRQ_BASE + 1)
-#define MPC5XXX_HI_INT_IRQ		(MPC5XXX_CRIT_IRQ_BASE + 2)
-#define MPC5XXX_CCS_IRQ			(MPC5XXX_CRIT_IRQ_BASE + 3)
-
-#define MPC5XXX_IRQ1			(MPC5XXX_MAIN_IRQ_BASE + 1)
-#define MPC5XXX_IRQ2			(MPC5XXX_MAIN_IRQ_BASE + 2)
-#define MPC5XXX_IRQ3			(MPC5XXX_MAIN_IRQ_BASE + 3)
-#define MPC5XXX_RTC_PINT_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 5)
-#define MPC5XXX_RTC_SINT_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 6)
-#define MPC5XXX_RTC_GPIO_STD_IRQ	(MPC5XXX_MAIN_IRQ_BASE + 7)
-#define MPC5XXX_RTC_GPIO_WKUP_IRQ	(MPC5XXX_MAIN_IRQ_BASE + 8)
-#define MPC5XXX_TMR0_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 9)
-#define MPC5XXX_TMR1_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 10)
-#define MPC5XXX_TMR2_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 11)
-#define MPC5XXX_TMR3_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 12)
-#define MPC5XXX_TMR4_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 13)
-#define MPC5XXX_TMR5_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 14)
-#define MPC5XXX_TMR6_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 15)
-#define MPC5XXX_TMR7_IRQ		(MPC5XXX_MAIN_IRQ_BASE + 16)
-
-#define MPC5XXX_SDMA_IRQ		(MPC5XXX_PERP_IRQ_BASE + 0)
-#define MPC5XXX_PSC1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 1)
-#define MPC5XXX_PSC2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 2)
-#define MPC5XXX_PSC3_IRQ		(MPC5XXX_PERP_IRQ_BASE + 3)
-#define MPC5XXX_PSC6_IRQ		(MPC5XXX_PERP_IRQ_BASE + 4)
-#define MPC5XXX_IRDA_IRQ		(MPC5XXX_PERP_IRQ_BASE + 4)
-#define MPC5XXX_FEC_IRQ			(MPC5XXX_PERP_IRQ_BASE + 5)
-#define MPC5XXX_USB_IRQ			(MPC5XXX_PERP_IRQ_BASE + 6)
-#define MPC5XXX_ATA_IRQ			(MPC5XXX_PERP_IRQ_BASE + 7)
-#define MPC5XXX_PCI_CNTRL_IRQ		(MPC5XXX_PERP_IRQ_BASE + 8)
-#define MPC5XXX_PCI_SCIRX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 9)
-#define MPC5XXX_PCI_SCITX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 10)
-#define MPC5XXX_PSC4_IRQ		(MPC5XXX_PERP_IRQ_BASE + 11)
-#define MPC5XXX_PSC5_IRQ		(MPC5XXX_PERP_IRQ_BASE + 12)
-#define MPC5XXX_SPI_MODF_IRQ		(MPC5XXX_PERP_IRQ_BASE + 13)
-#define MPC5XXX_SPI_SPIF_IRQ		(MPC5XXX_PERP_IRQ_BASE + 14)
-#define MPC5XXX_I2C1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 15)
-#define MPC5XXX_I2C2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 16)
-#define MPC5XXX_MSCAN1_IRQ		(MPC5XXX_PERP_IRQ_BASE + 17)
-#define MPC5XXX_MSCAN2_IRQ		(MPC5XXX_PERP_IRQ_BASE + 18)
-#define MPC5XXX_IR_RX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 19)
-#define MPC5XXX_IR_TX_IRQ		(MPC5XXX_PERP_IRQ_BASE + 20)
-#define MPC5XXX_XLB_ARB_IRQ		(MPC5XXX_PERP_IRQ_BASE + 21)
-#define MPC5XXX_BDLC_IRQ		(MPC5XXX_PERP_IRQ_BASE + 22)
-
-/* General Purpose Timers registers */
-#define MPC5XXX_GPT0_ENABLE		(MPC5XXX_GPT + 0x0)
-#define MPC5XXX_GPT0_COUNTER		(MPC5XXX_GPT + 0x4)
-#define MPC5XXX_GPT0_STATUS		(MPC5XXX_GPT + 0x0C)
-#define MPC5XXX_GPT1_ENABLE		(MPC5XXX_GPT + 0x10)
-#define MPC5XXX_GPT1_COUNTER		(MPC5XXX_GPT + 0x14)
-#define MPC5XXX_GPT1_STATUS		(MPC5XXX_GPT + 0x1C)
-#define MPC5XXX_GPT2_ENABLE		(MPC5XXX_GPT + 0x20)
-#define MPC5XXX_GPT2_COUNTER		(MPC5XXX_GPT + 0x24)
-#define MPC5XXX_GPT2_STATUS		(MPC5XXX_GPT + 0x2C)
-#define MPC5XXX_GPT3_ENABLE		(MPC5XXX_GPT + 0x30)
-#define MPC5XXX_GPT3_COUNTER		(MPC5XXX_GPT + 0x34)
-#define MPC5XXX_GPT3_STATUS		(MPC5XXX_GPT + 0x3C)
-#define MPC5XXX_GPT4_ENABLE		(MPC5XXX_GPT + 0x40)
-#define MPC5XXX_GPT4_COUNTER		(MPC5XXX_GPT + 0x44)
-#define MPC5XXX_GPT4_STATUS		(MPC5XXX_GPT + 0x4C)
-#define MPC5XXX_GPT5_ENABLE		(MPC5XXX_GPT + 0x50)
-#define MPC5XXX_GPT5_STATUS		(MPC5XXX_GPT + 0x5C)
-#define MPC5XXX_GPT5_COUNTER		(MPC5XXX_GPT + 0x54)
-#define MPC5XXX_GPT6_ENABLE		(MPC5XXX_GPT + 0x60)
-#define MPC5XXX_GPT6_COUNTER		(MPC5XXX_GPT + 0x64)
-#define MPC5XXX_GPT6_STATUS		(MPC5XXX_GPT + 0x6C)
-#define MPC5XXX_GPT7_ENABLE		(MPC5XXX_GPT + 0x70)
-#define MPC5XXX_GPT7_COUNTER		(MPC5XXX_GPT + 0x74)
-#define MPC5XXX_GPT7_STATUS		(MPC5XXX_GPT + 0x7C)
-
-#define MPC5XXX_GPT_GPIO_PIN(status)	((0x00000100 & (status)) >> 8)
-
-#define MPC5XXX_GPT7_PWMCFG		(MPC5XXX_GPT + 0x78)
-
-/* ATA registers */
-#define MPC5XXX_ATA_HOST_CONFIG         (MPC5XXX_ATA + 0x0000)
-#define MPC5XXX_ATA_PIO1                (MPC5XXX_ATA + 0x0008)
-#define MPC5XXX_ATA_PIO2                (MPC5XXX_ATA + 0x000C)
-#define MPC5XXX_ATA_SHARE_COUNT         (MPC5XXX_ATA + 0x002C)
-
-/* I2Cn control register bits */
-#define I2C_EN		0x80
-#define I2C_IEN		0x40
-#define I2C_STA		0x20
-#define I2C_TX		0x10
-#define I2C_TXAK	0x08
-#define I2C_RSTA	0x04
-#define I2C_INIT_MASK	(I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
-
-/* I2Cn status register bits */
-#define I2C_CF		0x80
-#define I2C_AAS		0x40
-#define I2C_BB		0x20
-#define I2C_AL		0x10
-#define I2C_SRW		0x04
-#define I2C_IF		0x02
-#define I2C_RXAK	0x01
-
-/* Programmable Serial Controller (PSC) status register bits */
-#define PSC_SR_CDE		0x0080
-#define PSC_SR_RXRDY		0x0100
-#define PSC_SR_RXFULL		0x0200
-#define PSC_SR_TXRDY		0x0400
-#define PSC_SR_TXEMP		0x0800
-#define PSC_SR_OE		0x1000
-#define PSC_SR_PE		0x2000
-#define PSC_SR_FE		0x4000
-#define PSC_SR_RB		0x8000
-
-/* PSC Command values */
-#define PSC_RX_ENABLE		0x0001
-#define PSC_RX_DISABLE		0x0002
-#define PSC_TX_ENABLE		0x0004
-#define PSC_TX_DISABLE		0x0008
-#define PSC_SEL_MODE_REG_1	0x0010
-#define PSC_RST_RX		0x0020
-#define PSC_RST_TX		0x0030
-#define PSC_RST_ERR_STAT	0x0040
-#define PSC_RST_BRK_CHG_INT	0x0050
-#define PSC_START_BRK		0x0060
-#define PSC_STOP_BRK		0x0070
-
-/* PSC Rx FIFO status bits */
-#define PSC_RX_FIFO_ERR		0x0040
-#define PSC_RX_FIFO_UF		0x0020
-#define PSC_RX_FIFO_OF		0x0010
-#define PSC_RX_FIFO_FR		0x0008
-#define PSC_RX_FIFO_FULL	0x0004
-#define PSC_RX_FIFO_ALARM	0x0002
-#define PSC_RX_FIFO_EMPTY	0x0001
-
-/* PSC interrupt mask bits */
-#define PSC_IMR_TXRDY		0x0100
-#define PSC_IMR_RXRDY		0x0200
-#define PSC_IMR_DB		0x0400
-#define PSC_IMR_IPC		0x8000
-
-/* PSC input port change bits */
-#define PSC_IPCR_CTS		0x01
-#define PSC_IPCR_DCD		0x02
-
-/* PSC mode fields */
-#define PSC_MODE_5_BITS		0x00
-#define PSC_MODE_6_BITS		0x01
-#define PSC_MODE_7_BITS		0x02
-#define PSC_MODE_8_BITS		0x03
-#define PSC_MODE_PAREVEN	0x00
-#define PSC_MODE_PARODD		0x04
-#define PSC_MODE_PARFORCE	0x08
-#define PSC_MODE_PARNONE	0x10
-#define PSC_MODE_ERR		0x20
-#define PSC_MODE_FFULL		0x40
-#define PSC_MODE_RXRTS		0x80
-
-#define PSC_MODE_ONE_STOP_5_BITS	0x00
-#define PSC_MODE_ONE_STOP		0x07
-#define PSC_MODE_TWO_STOP		0x0f
-
-/* ATA config fields */
-#define MPC5xxx_ATA_HOSTCONF_SMR	0x80000000UL	/* State machine
-							   reset */
-#define MPC5xxx_ATA_HOSTCONF_FR		0x40000000UL	/* FIFO Reset */
-#define MPC5xxx_ATA_HOSTCONF_IE		0x02000000UL	/* Enable interrupt
-							   in PIO */
-#define MPC5xxx_ATA_HOSTCONF_IORDY	0x01000000UL	/* Drive supports
-							   IORDY protocol */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct mpc5xxx_psc {
-	volatile u8	mode;		/* PSC + 0x00 */
-	volatile u8	reserved0[3];
-	union {				/* PSC + 0x04 */
-		volatile u16	status;
-		volatile u16	clock_select;
-	} sr_csr;
-#define psc_status	sr_csr.status
-#define psc_clock_select sr_csr.clock_select
-	volatile u16	reserved1;
-	volatile u8	command;	/* PSC + 0x08 */
-	volatile u8	reserved2[3];
-	union {				/* PSC + 0x0c */
-		volatile u8	buffer_8;
-		volatile u16	buffer_16;
-		volatile u32	buffer_32;
-	} buffer;
-#define psc_buffer_8	buffer.buffer_8
-#define psc_buffer_16	buffer.buffer_16
-#define psc_buffer_32	buffer.buffer_32
-	union {				/* PSC + 0x10 */
-		volatile u8	ipcr;
-		volatile u8	acr;
-	} ipcr_acr;
-#define psc_ipcr	ipcr_acr.ipcr
-#define psc_acr		ipcr_acr.acr
-	volatile u8	reserved3[3];
-	union {				/* PSC + 0x14 */
-		volatile u16	isr;
-		volatile u16	imr;
-	} isr_imr;
-#define psc_isr		isr_imr.isr
-#define psc_imr		isr_imr.imr
-	volatile u16	reserved4;
-	volatile u8	ctur;		/* PSC + 0x18 */
-	volatile u8	reserved5[3];
-	volatile u8	ctlr;		/* PSC + 0x1c */
-	volatile u8	reserved6[3];
-	volatile u16	ccr;		/* PSC + 0x20 */
-	volatile u8	reserved7[14];
-	volatile u8	ivr;		/* PSC + 0x30 */
-	volatile u8	reserved8[3];
-	volatile u8	ip;		/* PSC + 0x34 */
-	volatile u8	reserved9[3];
-	volatile u8	op1;		/* PSC + 0x38 */
-	volatile u8	reserved10[3];
-	volatile u8	op0;		/* PSC + 0x3c */
-	volatile u8	reserved11[3];
-	volatile u32	sicr;		/* PSC + 0x40 */
-	volatile u8	ircr1;		/* PSC + 0x44 */
-	volatile u8	reserved12[3];
-	volatile u8	ircr2;		/* PSC + 0x44 */
-	volatile u8	reserved13[3];
-	volatile u8	irsdr;		/* PSC + 0x4c */
-	volatile u8	reserved14[3];
-	volatile u8	irmdr;		/* PSC + 0x50 */
-	volatile u8	reserved15[3];
-	volatile u8	irfdr;		/* PSC + 0x54 */
-	volatile u8	reserved16[3];
-	volatile u16	rfnum;		/* PSC + 0x58 */
-	volatile u16	reserved17;
-	volatile u16	tfnum;		/* PSC + 0x5c */
-	volatile u16	reserved18;
-	volatile u32	rfdata;		/* PSC + 0x60 */
-	volatile u16	rfstat;		/* PSC + 0x64 */
-	volatile u16	reserved20;
-	volatile u8	rfcntl;		/* PSC + 0x68 */
-	volatile u8	reserved21[5];
-	volatile u16	rfalarm;	/* PSC + 0x6e */
-	volatile u16	reserved22;
-	volatile u16	rfrptr;		/* PSC + 0x72 */
-	volatile u16	reserved23;
-	volatile u16	rfwptr;		/* PSC + 0x76 */
-	volatile u16	reserved24;
-	volatile u16	rflrfptr;	/* PSC + 0x7a */
-	volatile u16	reserved25;
-	volatile u16	rflwfptr;	/* PSC + 0x7e */
-	volatile u32	tfdata;		/* PSC + 0x80 */
-	volatile u16	tfstat;		/* PSC + 0x84 */
-	volatile u16	reserved26;
-	volatile u8	tfcntl;		/* PSC + 0x88 */
-	volatile u8	reserved27[5];
-	volatile u16	tfalarm;	/* PSC + 0x8e */
-	volatile u16	reserved28;
-	volatile u16	tfrptr;		/* PSC + 0x92 */
-	volatile u16	reserved29;
-	volatile u16	tfwptr;		/* PSC + 0x96 */
-	volatile u16	reserved30;
-	volatile u16	tflrfptr;	/* PSC + 0x9a */
-	volatile u16	reserved31;
-	volatile u16	tflwfptr;	/* PSC + 0x9e */
-};
-
-struct mpc5xxx_intr {
-	volatile u32	per_mask;	/* INTR + 0x00 */
-	volatile u32	per_pri1;	/* INTR + 0x04 */
-	volatile u32	per_pri2;	/* INTR + 0x08 */
-	volatile u32	per_pri3;	/* INTR + 0x0c */
-	volatile u32	ctrl;		/* INTR + 0x10 */
-	volatile u32	main_mask;	/* INTR + 0x14 */
-	volatile u32	main_pri1;	/* INTR + 0x18 */
-	volatile u32	main_pri2;	/* INTR + 0x1c */
-	volatile u32	reserved1;	/* INTR + 0x20 */
-	volatile u32	enc_status;	/* INTR + 0x24 */
-	volatile u32	crit_status;	/* INTR + 0x28 */
-	volatile u32	main_status;	/* INTR + 0x2c */
-	volatile u32	per_status;	/* INTR + 0x30 */
-	volatile u32	reserved2;	/* INTR + 0x34 */
-	volatile u32	per_error;	/* INTR + 0x38 */
-};
-
-struct mpc5xxx_gpio {
-	volatile u32 port_config;	/* GPIO + 0x00 */
-	volatile u32 simple_gpioe;	/* GPIO + 0x04 */
-	volatile u32 simple_ode;	/* GPIO + 0x08 */
-	volatile u32 simple_ddr;	/* GPIO + 0x0c */
-	volatile u32 simple_dvo;	/* GPIO + 0x10 */
-	volatile u32 simple_ival;	/* GPIO + 0x14 */
-	volatile u8 outo_gpioe;		/* GPIO + 0x18 */
-	volatile u8 reserved1[3];	/* GPIO + 0x19 */
-	volatile u8 outo_dvo;		/* GPIO + 0x1c */
-	volatile u8 reserved2[3];	/* GPIO + 0x1d */
-	volatile u8 sint_gpioe;		/* GPIO + 0x20 */
-	volatile u8 reserved3[3];	/* GPIO + 0x21 */
-	volatile u8 sint_ode;		/* GPIO + 0x24 */
-	volatile u8 reserved4[3];	/* GPIO + 0x25 */
-	volatile u8 sint_ddr;		/* GPIO + 0x28 */
-	volatile u8 reserved5[3];	/* GPIO + 0x29 */
-	volatile u8 sint_dvo;		/* GPIO + 0x2c */
-	volatile u8 reserved6[3];	/* GPIO + 0x2d */
-	volatile u8 sint_inten;		/* GPIO + 0x30 */
-	volatile u8 reserved7[3];	/* GPIO + 0x31 */
-	volatile u16 sint_itype;	/* GPIO + 0x34 */
-	volatile u16 reserved8;		/* GPIO + 0x36 */
-	volatile u8 gpio_control;	/* GPIO + 0x38 */
-	volatile u8 reserved9[3];	/* GPIO + 0x39 */
-	volatile u8 sint_istat;		/* GPIO + 0x3c */
-	volatile u8 sint_ival;		/* GPIO + 0x3d */
-	volatile u8 bus_errs;		/* GPIO + 0x3e */
-	volatile u8 reserved10;		/* GPIO + 0x3f */
-};
-
-struct mpc5xxx_sdma {
-	volatile u32 taskBar;		/* SDMA + 0x00 */
-	volatile u32 currentPointer;	/* SDMA + 0x04 */
-	volatile u32 endPointer;	/* SDMA + 0x08 */
-	volatile u32 variablePointer;	/* SDMA + 0x0c */
-
-	volatile u8 IntVect1;		/* SDMA + 0x10 */
-	volatile u8 IntVect2;		/* SDMA + 0x11 */
-	volatile u16 PtdCntrl;		/* SDMA + 0x12 */
-
-	volatile u32 IntPend;		/* SDMA + 0x14 */
-	volatile u32 IntMask;		/* SDMA + 0x18 */
-
-	volatile u16 tcr_0;		/* SDMA + 0x1c */
-	volatile u16 tcr_1;		/* SDMA + 0x1e */
-	volatile u16 tcr_2;		/* SDMA + 0x20 */
-	volatile u16 tcr_3;		/* SDMA + 0x22 */
-	volatile u16 tcr_4;		/* SDMA + 0x24 */
-	volatile u16 tcr_5;		/* SDMA + 0x26 */
-	volatile u16 tcr_6;		/* SDMA + 0x28 */
-	volatile u16 tcr_7;		/* SDMA + 0x2a */
-	volatile u16 tcr_8;		/* SDMA + 0x2c */
-	volatile u16 tcr_9;		/* SDMA + 0x2e */
-	volatile u16 tcr_a;		/* SDMA + 0x30 */
-	volatile u16 tcr_b;		/* SDMA + 0x32 */
-	volatile u16 tcr_c;		/* SDMA + 0x34 */
-	volatile u16 tcr_d;		/* SDMA + 0x36 */
-	volatile u16 tcr_e;		/* SDMA + 0x38 */
-	volatile u16 tcr_f;		/* SDMA + 0x3a */
-
-	volatile u8 IPR0;		/* SDMA + 0x3c */
-	volatile u8 IPR1;		/* SDMA + 0x3d */
-	volatile u8 IPR2;		/* SDMA + 0x3e */
-	volatile u8 IPR3;		/* SDMA + 0x3f */
-	volatile u8 IPR4;		/* SDMA + 0x40 */
-	volatile u8 IPR5;		/* SDMA + 0x41 */
-	volatile u8 IPR6;		/* SDMA + 0x42 */
-	volatile u8 IPR7;		/* SDMA + 0x43 */
-	volatile u8 IPR8;		/* SDMA + 0x44 */
-	volatile u8 IPR9;		/* SDMA + 0x45 */
-	volatile u8 IPR10;		/* SDMA + 0x46 */
-	volatile u8 IPR11;		/* SDMA + 0x47 */
-	volatile u8 IPR12;		/* SDMA + 0x48 */
-	volatile u8 IPR13;		/* SDMA + 0x49 */
-	volatile u8 IPR14;		/* SDMA + 0x4a */
-	volatile u8 IPR15;		/* SDMA + 0x4b */
-	volatile u8 IPR16;		/* SDMA + 0x4c */
-	volatile u8 IPR17;		/* SDMA + 0x4d */
-	volatile u8 IPR18;		/* SDMA + 0x4e */
-	volatile u8 IPR19;		/* SDMA + 0x4f */
-	volatile u8 IPR20;		/* SDMA + 0x50 */
-	volatile u8 IPR21;		/* SDMA + 0x51 */
-	volatile u8 IPR22;		/* SDMA + 0x52 */
-	volatile u8 IPR23;		/* SDMA + 0x53 */
-	volatile u8 IPR24;		/* SDMA + 0x54 */
-	volatile u8 IPR25;		/* SDMA + 0x55 */
-	volatile u8 IPR26;		/* SDMA + 0x56 */
-	volatile u8 IPR27;		/* SDMA + 0x57 */
-	volatile u8 IPR28;		/* SDMA + 0x58 */
-	volatile u8 IPR29;		/* SDMA + 0x59 */
-	volatile u8 IPR30;		/* SDMA + 0x5a */
-	volatile u8 IPR31;		/* SDMA + 0x5b */
-
-	volatile u32 res1;		/* SDMA + 0x5c */
-	volatile u32 res2;		/* SDMA + 0x60 */
-	volatile u32 res3;		/* SDMA + 0x64 */
-	volatile u32 MDEDebug;		/* SDMA + 0x68 */
-	volatile u32 ADSDebug;		/* SDMA + 0x6c */
-	volatile u32 Value1;		/* SDMA + 0x70 */
-	volatile u32 Value2;		/* SDMA + 0x74 */
-	volatile u32 Control;		/* SDMA + 0x78 */
-	volatile u32 Status;		/* SDMA + 0x7c */
-	volatile u32 EU00;		/* SDMA + 0x80 */
-	volatile u32 EU01;		/* SDMA + 0x84 */
-	volatile u32 EU02;		/* SDMA + 0x88 */
-	volatile u32 EU03;		/* SDMA + 0x8c */
-	volatile u32 EU04;		/* SDMA + 0x90 */
-	volatile u32 EU05;		/* SDMA + 0x94 */
-	volatile u32 EU06;		/* SDMA + 0x98 */
-	volatile u32 EU07;		/* SDMA + 0x9c */
-	volatile u32 EU10;		/* SDMA + 0xa0 */
-	volatile u32 EU11;		/* SDMA + 0xa4 */
-	volatile u32 EU12;		/* SDMA + 0xa8 */
-	volatile u32 EU13;		/* SDMA + 0xac */
-	volatile u32 EU14;		/* SDMA + 0xb0 */
-	volatile u32 EU15;		/* SDMA + 0xb4 */
-	volatile u32 EU16;		/* SDMA + 0xb8 */
-	volatile u32 EU17;		/* SDMA + 0xbc */
-	volatile u32 EU20;		/* SDMA + 0xc0 */
-	volatile u32 EU21;		/* SDMA + 0xc4 */
-	volatile u32 EU22;		/* SDMA + 0xc8 */
-	volatile u32 EU23;		/* SDMA + 0xcc */
-	volatile u32 EU24;		/* SDMA + 0xd0 */
-	volatile u32 EU25;		/* SDMA + 0xd4 */
-	volatile u32 EU26;		/* SDMA + 0xd8 */
-	volatile u32 EU27;		/* SDMA + 0xdc */
-	volatile u32 EU30;		/* SDMA + 0xe0 */
-	volatile u32 EU31;		/* SDMA + 0xe4 */
-	volatile u32 EU32;		/* SDMA + 0xe8 */
-	volatile u32 EU33;		/* SDMA + 0xec */
-	volatile u32 EU34;		/* SDMA + 0xf0 */
-	volatile u32 EU35;		/* SDMA + 0xf4 */
-	volatile u32 EU36;		/* SDMA + 0xf8 */
-	volatile u32 EU37;		/* SDMA + 0xfc */
-};
-
-struct mpc5xxx_i2c {
-	volatile u32 madr;		/* I2Cn + 0x00 */
-	volatile u32 mfdr;		/* I2Cn + 0x04 */
-	volatile u32 mcr;		/* I2Cn + 0x08 */
-	volatile u32 msr;		/* I2Cn + 0x0C */
-	volatile u32 mdr;		/* I2Cn + 0x10 */
-};
-
-struct mpc5xxx_spi {
-	volatile u8 cr1;		/* SPI + 0x0F00 */
-	volatile u8 cr2;		/* SPI + 0x0F01 */
-	volatile u8 reserved1[2];
-	volatile u8 brr;		/* SPI + 0x0F04 */
-	volatile u8 sr;			/* SPI + 0x0F05 */
-	volatile u8 reserved2[3];
-	volatile u8 dr;			/* SPI + 0x0F09 */
-	volatile u8 reserved3[3];
-	volatile u8 pdr;		/* SPI + 0x0F0D */
-	volatile u8 reserved4[2];
-	volatile u8 ddr;		/* SPI + 0x0F10 */
-};
-
-
-struct mpc5xxx_gpt {
-	volatile u32 emsr;		/* GPT + Timer# * 0x10 + 0x00 */
-	volatile u32 cir;		/* GPT + Timer# * 0x10 + 0x04 */
-	volatile u32 pwmcr;		/* GPT + Timer# * 0x10 + 0x08 */
-	volatile u32 sr;		/* GPT + Timer# * 0x10 + 0x0c */
-};
-
-struct mpc5xxx_gpt_0_7 {
-	struct mpc5xxx_gpt gpt0;
-	struct mpc5xxx_gpt gpt1;
-	struct mpc5xxx_gpt gpt2;
-	struct mpc5xxx_gpt gpt3;
-	struct mpc5xxx_gpt gpt4;
-	struct mpc5xxx_gpt gpt5;
-	struct mpc5xxx_gpt gpt6;
-	struct mpc5xxx_gpt gpt7;
-};
-
-struct mscan_buffer {
-	volatile u8  idr[0x8];          /* 0x00 */
-	volatile u8  dsr[0x10];         /* 0x08 */
-	volatile u8  dlr;               /* 0x18 */
-	volatile u8  tbpr;              /* 0x19 */      /* This register is not applicable for receive buffers */
-	volatile u16 rsrv1;             /* 0x1A */
-	volatile u8  tsrh;              /* 0x1C */
-	volatile u8  tsrl;              /* 0x1D */
-	volatile u16 rsrv2;             /* 0x1E */
-};
-
-struct mpc5xxx_mscan {
-	volatile u8  canctl0;           /* MSCAN + 0x00 */
-	volatile u8  canctl1;           /* MSCAN + 0x01 */
-	volatile u16 rsrv1;             /* MSCAN + 0x02 */
-	volatile u8  canbtr0;           /* MSCAN + 0x04 */
-	volatile u8  canbtr1;           /* MSCAN + 0x05 */
-	volatile u16 rsrv2;             /* MSCAN + 0x06 */
-	volatile u8  canrflg;           /* MSCAN + 0x08 */
-	volatile u8  canrier;           /* MSCAN + 0x09 */
-	volatile u16 rsrv3;             /* MSCAN + 0x0A */
-	volatile u8  cantflg;           /* MSCAN + 0x0C */
-	volatile u8  cantier;           /* MSCAN + 0x0D */
-	volatile u16 rsrv4;             /* MSCAN + 0x0E */
-	volatile u8  cantarq;           /* MSCAN + 0x10 */
-	volatile u8  cantaak;           /* MSCAN + 0x11 */
-	volatile u16 rsrv5;             /* MSCAN + 0x12 */
-	volatile u8  cantbsel;          /* MSCAN + 0x14 */
-	volatile u8  canidac;           /* MSCAN + 0x15 */
-	volatile u16 rsrv6[3];          /* MSCAN + 0x16 */
-	volatile u8  canrxerr;          /* MSCAN + 0x1C */
-	volatile u8  cantxerr;          /* MSCAN + 0x1D */
-	volatile u16 rsrv7;             /* MSCAN + 0x1E */
-	volatile u8  canidar0;          /* MSCAN + 0x20 */
-	volatile u8  canidar1;          /* MSCAN + 0x21 */
-	volatile u16 rsrv8;             /* MSCAN + 0x22 */
-	volatile u8  canidar2;          /* MSCAN + 0x24 */
-	volatile u8  canidar3;          /* MSCAN + 0x25 */
-	volatile u16 rsrv9;             /* MSCAN + 0x26 */
-	volatile u8  canidmr0;          /* MSCAN + 0x28 */
-	volatile u8  canidmr1;          /* MSCAN + 0x29 */
-	volatile u16 rsrv10;            /* MSCAN + 0x2A */
-	volatile u8  canidmr2;          /* MSCAN + 0x2C */
-	volatile u8  canidmr3;          /* MSCAN + 0x2D */
-	volatile u16 rsrv11;            /* MSCAN + 0x2E */
-	volatile u8  canidar4;          /* MSCAN + 0x30 */
-	volatile u8  canidar5;          /* MSCAN + 0x31 */
-	volatile u16 rsrv12;            /* MSCAN + 0x32 */
-	volatile u8  canidar6;          /* MSCAN + 0x34 */
-	volatile u8  canidar7;          /* MSCAN + 0x35 */
-	volatile u16 rsrv13;            /* MSCAN + 0x36 */
-	volatile u8  canidmr4;          /* MSCAN + 0x38 */
-	volatile u8  canidmr5;          /* MSCAN + 0x39 */
-	volatile u16 rsrv14;            /* MSCAN + 0x3A */
-	volatile u8  canidmr6;          /* MSCAN + 0x3C */
-	volatile u8  canidmr7;          /* MSCAN + 0x3D */
-	volatile u16 rsrv15;            /* MSCAN + 0x3E */
-
-	struct mscan_buffer canrxfg;    /* MSCAN + 0x40 */    /* Foreground receive buffer */
-	struct mscan_buffer cantxfg;    /* MSCAN + 0x60 */    /* Foreground transmit buffer */
-	};
-
-/* function prototypes */
-void loadtask(int basetask, int tasks);
-
-/* retrieve configured sdram size connected to a chipselect */
-unsigned long mpc5200_get_sdram_size(unsigned int cs);
-
-/* configure a local plus bus chip select */
-#define MPC5200_BOOTCS 8
-void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg);
-
-/* configure bus speeds. Both dividers are relative to xlb clock */
-int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASMPPC_MPC5XXX_H */
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:16 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:16 +0200
Subject: [PATCH 17/19] MPC5125/FEC: add another FEC driver for the MPC5125 SoC
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-18-git-send-email-jbe@pengutronix.de>

This FEC differs slightly from the one used in the MPC5200. Maybe both can
share the most of the code, but I'm not sure if its worth the effort.
Note: this is tested on a MPC2125 only. It might work on an MPC5121/MPC5123 as
well, but it's untested.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/net/Kconfig       |   5 +
 drivers/net/Makefile      |   1 +
 drivers/net/fec_mpc5125.c | 690 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/fec_mpc5125.h |   0
 include/fec.h             |   2 +-
 5 files changed, 697 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/fec_mpc5125.c
 create mode 100644 drivers/net/fec_mpc5125.h

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c99fcc8..f4714f7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -137,6 +137,11 @@ config DRIVER_NET_MPC5200
 	depends on ARCH_MPC5200
 	select PHYLIB
 
+config DRIVER_NET_MPC5125
+	bool "MPC5125 Ethernet driver"
+	depends on SOC_MPC5125
+	select PHYLIB
+
 config DRIVER_NET_NETX
 	bool "Hilscher Netx ethernet driver"
 	depends on HAS_NETX_ETHER
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1b85778..8912887 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_DRIVER_NET_KS8851_MLL)	+= ks8851_mll.o
 obj-$(CONFIG_DRIVER_NET_MACB)		+= macb.o
 obj-$(CONFIG_DRIVER_NET_MICREL)		+= ksz8864rmn.o
 obj-$(CONFIG_DRIVER_NET_MPC5200)	+= fec_mpc5200.o
+obj-$(CONFIG_DRIVER_NET_MPC5125)	+= fec_mpc5125.o
 obj-$(CONFIG_DRIVER_NET_NETX)		+= netx_eth.o
 obj-$(CONFIG_DRIVER_NET_ORION)		+= orion-gbe.o
 obj-$(CONFIG_DRIVER_NET_RTL8139)	+= rtl8139.o
diff --git a/drivers/net/fec_mpc5125.c b/drivers/net/fec_mpc5125.c
new file mode 100644
index 0000000..3d78db6
--- /dev/null
+++ b/drivers/net/fec_mpc5125.c
@@ -0,0 +1,690 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, Pengutronix
+ *
+ * Based partially on code of:
+ * (C) Copyright 2003-2010
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.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 <driver.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <net.h>
+#include <fec.h>
+#include <linux/phy.h>
+#include <asm/io.h>
+#include <mach/mpc5xxx.h>
+#include <mach/clocks.h>
+
+/*
+ * Please be aware:
+ * External phys needs a preamble to synchronize itself into the bit stream.
+ * This means a '1' bit at the MDIO line for 32 consecutive MDC clocks.
+ * It might be neccessary to enable the pull up at the MDIO line to force it
+ * to the '1' state for this purpose
+ */
+
+/* FEC's register description */
+struct fec5125 {
+	u32	fec_id;
+	u32	ievent;
+	u32	imask;
+	u32	reserved_01;
+	u32	r_des_active;
+	u32	x_des_active;
+	u32	reserved_02[3];
+	u32	ecntrl;
+	u32	reserved_03[6];
+	u32	mii_data;
+	u32	mii_speed;
+	u32	reserved_04[7];
+	u32	mib_control;
+	u32	reserved_05[7];
+	u32	r_cntrl;
+	u32	r_hash;
+	u32	reserved_06[14];
+	u32	x_cntrl;
+	u32	reserved_07[7];
+	u32	paddr1;
+	u32	paddr2;
+	u32	op_pause;
+	u32	reserved_08[10];
+	u32	iaddr1;
+	u32	iaddr2;
+	u32	gaddr1;
+	u32	gaddr2;
+	u32	reserved_09[7];
+	u32	x_wmrk;
+	u32	reserved_10;
+	u32	r_bound;
+	u32	r_fstart;
+	u32	reserved_11[11];
+	u32	r_des_start;
+	u32	x_des_start;
+	u32	r_buff_size;
+	u32	reserved_12[26];
+	u32	dma_control;
+	u32	reserved_13[2];
+	u32	mib1[30];
+	u32	reserved_14[2];
+	u32	mib2[25];
+};
+
+/* RBD bits definitions */
+#define FEC_RBD_EMPTY		0x8000	/* Buffer is empty */
+#define FEC_RBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_RBD_LAST		0x0800	/* Buffer is last in frame(useless) */
+#define FEC_RBD_MISS		0x0100	/* Miss bit for prom mode */
+#define FEC_RBD_BC		0x0080	/* The received frame is broadcast frame */
+#define FEC_RBD_MC		0x0040	/* The received frame is multicast frame */
+#define FEC_RBD_LG		0x0020	/* Frame length violation */
+#define FEC_RBD_NO		0x0010	/* Nonoctet align frame */
+#define FEC_RBD_SH		0x0008	/* Short frame */
+#define FEC_RBD_CR		0x0004	/* CRC error */
+#define FEC_RBD_OV		0x0002	/* Receive FIFO overrun */
+#define FEC_RBD_TR		0x0001	/* Frame is truncated */
+#define FEC_RBD_ERR		(FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \
+					FEC_RBD_OV | FEC_RBD_TR)
+
+/* TBD bits definitions */
+#define FEC_TBD_READY		0x8000	/* Buffer is ready */
+#define FEC_TBD_WRAP		0x2000	/* Last BD in ring */
+#define FEC_TBD_LAST		0x0800	/* Buffer is last in frame */
+#define FEC_TBD_TC		0x0400	/* Transmit the CRC */
+#define FEC_TBD_ABC		0x0200	/* Append bad CRC */
+
+/* MII-related definitios */
+#define FEC_MII_DATA_ST		0x40000000	/* Start of frame delimiter */
+#define FEC_MII_DATA_OP_RD	0x20000000	/* Perform a read operation */
+#define FEC_MII_DATA_OP_WR	0x10000000	/* Perform a write operation */
+#define FEC_MII_DATA_PA_MSK	0x0f800000	/* PHY Address field mask */
+#define FEC_MII_DATA_PA(x)	(((x) << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK)
+#define FEC_MII_DATA_RA_MSK	0x007c0000	/* PHY Register field mask */
+#define FEC_MII_DATA_RA(x)	(((x) << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK)
+#define FEC_MII_DATA_TA		0x00020000	/* Turnaround */
+#define FEC_MII_DATA_DATAMSK	0x0000ffff	/* PHY data field */
+
+#define FEC_MII_DATA_RA_SHIFT	18	/* MII Register address bits */
+#define FEC_MII_DATA_PA_SHIFT	23	/* MII PHY address bits */
+
+#define FEC_IEVENT_HBERR 	0x80000000
+#define FEC_IEVENT_GRA		0x10000000
+#define FEC_IEVENT_BABT		0x20000000
+#define FEC_IEVENT_MII		0x00800000
+#define FEC_IEVENT_XFIFO_ERROR	0x00040000
+#define FEC_IEVENT_RFIFO_ERROR	0x00020000
+
+/* Receive & Transmit Buffer Descriptor definitions */
+struct mpc5125_descriptor {
+	u16 status;
+	u16 dlength;
+	u32 dpointer;
+};
+
+/* BD Numer definitions */
+#define FEC_TBD_NUM		48	/* The user can adjust this value */
+#define FEC_RBD_NUM		32	/* The user can adjust this value */
+
+/* packet size limit */
+#define FEC_MAX_FRAME_LEN	1522	/* recommended default value */
+
+/* Buffer size must be evenly divisible by 16 */
+#define FEC_MAX_PKT_SIZE	((FEC_MAX_FRAME_LEN + 0x10) & (~0xf))
+
+struct mpc5125_frame {
+	unsigned char frame[FEC_MAX_PKT_SIZE];
+};
+
+struct mpc5125_buff_descs {
+	struct mpc5125_descriptor rbd[FEC_RBD_NUM]; /* RBD ring */
+	struct mpc5125_descriptor tbd[FEC_TBD_NUM]; /* TBD ring */
+	struct mpc5125_frame recv_frames[FEC_RBD_NUM]; /* receive buff */
+} ;
+
+struct mpc5125_fec_priv {
+	struct fec5125 *eth;
+	struct mpc5125_buff_descs *bdBase; /* BD rings and recv buffer */
+	size_t rdb_idx; /* next receive BD to read */
+	size_t tdb_idx; /* next transmit BD to send */
+	size_t usedtdb_idx; /* next transmit BD to clean */
+	unsigned clean_tbd_cnt; /* the number of available transmit BDs */
+	unsigned char frame[FEC_MAX_PKT_SIZE];
+	size_t frame_idx;
+
+	phy_interface_t interface; /* transceiver type */
+	u32 phy_flags; /* nowhere used ?? */
+	unsigned phy_addr;
+	struct mii_bus miibus;
+};
+
+static void mpc5125_fec_collect_frame(struct mpc5125_fec_priv *fec,
+					const void *buf, size_t length)
+{
+	memcpy(&fec->frame[fec->frame_idx], buf, length - fec->frame_idx);
+	fec->frame_idx = length; /* FIXME not "+=" here???? */
+}
+
+static void mpc5125_fec_init_buffer_ring(struct mpc5125_fec_priv *fec)
+{
+	void *base;
+
+	base = xzalloc(sizeof(struct mpc5125_buff_descs) + 0x1f);
+	/* this buffer must be quad word aligned */
+	base = (void *)((unsigned)base & ~0xf);
+
+	fec->bdBase = base;
+}
+
+static void mpc5125_fec_activate_transmission(struct mpc5125_fec_priv *fec)
+{
+	/* Activate transmit Buffer Descriptor polling */
+	out_be32(&fec->eth->x_des_active, 0x01000000);
+}
+
+static void mpc5125_fec_disable_transmission(struct mpc5125_fec_priv *fec)
+{
+	/* nothing to be done here */
+}
+
+static void mpc5125_fec_activate_reception(struct mpc5125_fec_priv *fec)
+{
+	out_be32(&fec->eth->r_des_active, 0x01000000);
+}
+
+static void mpc5125_fec_disable_reception(struct mpc5125_fec_priv *fec)
+{
+	/* nothing to be done here */
+}
+
+static void mpc5125_fec_clear_reception_event(struct mpc5125_fec_priv *fec)
+{
+	/* nothing to be done here */
+}
+
+/* keep MII frequency below 2.5 MHz */
+static unsigned mpc5125_fec_limit_mii_clock(void)
+{
+	u32 reg;
+
+	/* MII clock is 1 / (MII_SPEED x 2) */
+	reg = get_ips_clock() + 2500000;
+	reg /= 5000000;
+	return reg + 1;
+}
+
+/* MII-interface related functions */
+static int fec5125_miibus_read(struct mii_bus *bus, int phy_addr, int reg_addr)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)bus->priv;
+	int rc;
+
+	/* clear mii transfer status first */
+	out_be32(&fec->eth->ievent, FEC_IEVENT_MII);
+	/*
+	 * reading from any PHY's register is done by properly
+	 * programming the FEC's MII data register.
+	 */
+	out_be32(&fec->eth->mii_data, FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD |
+				FEC_MII_DATA_TA | FEC_MII_DATA_PA(phy_addr) |
+				FEC_MII_DATA_RA(reg_addr));
+
+	rc = wait_on_timeout(500 * MSECOND,
+				in_be32(&fec->eth->ievent) & FEC_IEVENT_MII);
+	if (rc < 0) {
+		dev_err(bus->parent, "MDIO read timed out\n");
+		return rc;
+	}
+
+	/* it's now safe to read the PHY's register */
+	return in_be32(&fec->eth->mii_data) & FEC_MII_DATA_DATAMSK;
+}
+
+static int fec5125_miibus_write(struct mii_bus *bus, int phy_addr,
+						int reg_addr, u16 data)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)bus->priv;
+	int rc;
+
+	/* clear mii transfer status first */
+	out_be32(&fec->eth->ievent, FEC_IEVENT_MII);
+
+	out_be32(&fec->eth->mii_data, FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
+				FEC_MII_DATA_TA | FEC_MII_DATA_PA(phy_addr) |
+				FEC_MII_DATA_RA(reg_addr) | data);
+
+	rc = wait_on_timeout(500 * MSECOND,
+				in_be32(&fec->eth->ievent) & FEC_IEVENT_MII);
+	if (rc < 0)
+		dev_err(bus->parent, "MDIO write timed out\n");
+
+	return rc;
+}
+
+/* initialize the receive buffer descriptors */
+static int mpc5125_fec_rbd_init(struct mpc5125_fec_priv *fec)
+{
+	size_t ix;
+
+	for (ix = 0; ix < FEC_RBD_NUM; ix++) {
+		fec->bdBase->rbd[ix].dpointer = (u32)&fec->bdBase->recv_frames[ix];
+		fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY;
+		fec->bdBase->rbd[ix].dlength = 0;
+	}
+
+	/* let the last buffer descriptor close the ring */
+	fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP;
+	fec->rdb_idx = 0;
+
+	return 0;
+}
+
+/* initialize the transmitt buffer descriptors */
+static void mpc5125_fec_tbd_init(struct mpc5125_fec_priv *fec)
+{
+	int ix;
+
+	for (ix = 0; ix < FEC_TBD_NUM; ix++)
+		fec->bdBase->tbd[ix].status = 0;
+
+	/* let the last buffer descriptor close the ring */
+	fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP;
+
+	fec->tdb_idx = 0;
+	fec->usedtdb_idx = 0;
+	fec->clean_tbd_cnt = FEC_TBD_NUM;
+}
+
+static void mpc5125_fec_rbd_clean(struct mpc5125_fec_priv *fec,
+						struct mpc5125_descriptor *rbd)
+{
+	/* Reset buffer descriptor as empty */
+	if ((fec->rdb_idx) == (FEC_RBD_NUM - 1))
+		rbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
+	else
+		rbd->status = FEC_RBD_EMPTY;
+
+	rbd->dlength = 0;
+
+	/* ensure all written data has hit the memory */
+	barrier();
+
+	/* Now, we have an empty RxBD, restart the engine */
+	mpc5125_fec_activate_reception(fec);
+
+	/* Increment BD count */
+	fec->rdb_idx = (fec->rdb_idx + 1) % FEC_RBD_NUM;
+}
+
+static void mpc5125_fec_tbd_scrub(struct mpc5125_fec_priv *fec)
+{
+	struct mpc5125_descriptor *used_tbd;
+
+	/* process all the consumed TBDs */
+	while (fec->clean_tbd_cnt < FEC_TBD_NUM) {
+		used_tbd = &fec->bdBase->tbd[fec->usedtdb_idx];
+		if (used_tbd->status & FEC_TBD_READY) {
+			return;
+		}
+
+		/* clean this buffer descriptor */
+		if (fec->usedtdb_idx == (FEC_TBD_NUM - 1))
+			used_tbd->status = FEC_TBD_WRAP;
+		else
+			used_tbd->status = 0;
+
+		/* update some indeces for a correct handling of the TBD ring */
+		fec->clean_tbd_cnt++;
+		fec->usedtdb_idx = (fec->usedtdb_idx + 1) % FEC_TBD_NUM;
+	}
+
+	barrier();
+}
+
+static int mpc5125_fec_get_ethaddr(struct eth_device *dev, unsigned char *mac)
+{
+	/* no eeprom */
+	return -ENODEV;
+}
+
+static int mpc5125_fec_set_ethaddr(struct eth_device *dev, unsigned char *mac)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv;
+	u8 currByte;
+	int byte, bit;
+	u32 crc = 0xffffffff;
+
+	/*
+	 * The algorithm used is the following:
+	 * we loop on each of the six bytes of the provided address,
+	 * and we compute the CRC by left-shifting the previous
+	 * value by one position, so that each bit in the current
+	 * byte of the address may contribute the calculation. If
+	 * the latter and the MSB in the CRC are different, then
+	 * the CRC value so computed is also ex-ored with the
+	 * "polynomium generator". The current byte of the address
+	 * is also shifted right by one bit at each iteration.
+	 * This is because the CRC generatore in hardware is implemented
+	 * as a shift-register with as many ex-ores as the radixes
+	 * in the polynomium. This suggests that we represent the
+	 * polynomiumm itself as a 32-bit constant.
+	 */
+	for (byte = 0; byte < 6; byte++) {
+		currByte = mac[byte];
+		for (bit = 0; bit < 8; bit++) {
+			if ((currByte & 0x01) ^ (crc & 0x01)) {
+				crc >>= 1;
+				crc = crc ^ 0xedb88320;
+			} else {
+				crc >>= 1;
+			}
+			currByte >>= 1;
+		}
+	}
+
+	crc = crc >> 26;
+
+	/* Set individual hash table register */
+	if (crc >= 32) {
+		out_be32(&fec->eth->iaddr1, (1 << (crc - 32)));
+		out_be32(&fec->eth->iaddr2, 0);
+	} else {
+		out_be32(&fec->eth->iaddr1, 0);
+		out_be32(&fec->eth->iaddr2, (1 << crc));
+	}
+
+	/* Set physical address */
+	out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) +
+					(mac[2] <<  8) + mac[3]);
+	out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) + 0x8808);
+
+	return 0;
+}
+
+static int mpc5125_fec_init(struct eth_device *dev)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv;
+
+	/* Initilize both BD rings */
+	mpc5125_fec_rbd_init(fec);
+	mpc5125_fec_tbd_init(fec);
+
+	/* Clear FEC-Lite interrupt event register(IEVENT) */
+	out_be32(&fec->eth->ievent, 0xffffffff);
+
+	/* Set interrupt mask register */
+	out_be32(&fec->eth->imask, 0x00000000);
+
+	/* Set transmit fifo watermark register(X_WMRK), default = 64 */
+	out_be32(&fec->eth->x_wmrk, 0x0);
+
+	/* Setup phy interface mode and max frame length */
+	switch (fec->interface) {
+	case PHY_INTERFACE_MODE_MII:
+		out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x024);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x124);
+		break;
+	default:
+		dev_err(&dev->dev, "Unsupported phy interface mode\n");
+		return -EINVAL;
+	}
+
+	/* Setup MII_SPEED and do not drop the Preamble. */
+	out_be32(&fec->eth->mii_speed, (mpc5125_fec_limit_mii_clock()) << 1);
+
+	/* Set Opcode/Pause Duration Register */
+	out_be32(&fec->eth->op_pause, 0x00010020);
+
+	/* Set multicast address filter */
+	out_be32(&fec->eth->gaddr1, 0x00000000);
+	out_be32(&fec->eth->gaddr2, 0x00000000);
+
+	/* Half-duplex, heartbeat disabled */
+	out_be32(&fec->eth->x_cntrl, 0x00000000);
+
+	/* Enable MIB counters */
+	out_be32(&fec->eth->mib_control, 0x0);
+
+	/* Setup recv fifo start and buff size */
+	out_be32(&fec->eth->r_fstart, 0x500);
+	out_be32(&fec->eth->r_buff_size, FEC_MAX_PKT_SIZE);
+
+	/* Setup BD base addresses */
+	out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd);
+	out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd);
+
+	/* DMA Control */
+	out_be32(&fec->eth->dma_control, 0xc0000000);
+
+	/* Enable FEC */
+	setbits_be32(&fec->eth->ecntrl, 0x00000002);
+
+	return 1;
+}
+
+static int mpc5125_fec_open(struct eth_device *edev)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)edev->priv;
+
+	mpc5125_fec_activate_reception(fec);
+
+	return phy_device_connect(edev, &fec->miibus, fec->phy_addr, NULL,
+					fec->phy_flags, fec->interface);
+}
+
+static void mpc5125_fec_halt(struct eth_device *dev)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv;
+	int counter = 0xffff;
+
+	/* mask FEC chip interrupts */
+	out_be32(&fec->eth->imask, 0);
+
+	/* issue graceful stop command to the FEC transmitter if necessary */
+	setbits_be32(&fec->eth->x_cntrl, 0x00000001);
+
+	/* wait for graceful stop to register */
+	while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000)))
+		;
+
+	/* Disable the Ethernet Controller */
+	clrbits_be32(&fec->eth->ecntrl, 0x00000002);
+
+	/* Issue a reset command to the FEC chip */
+	setbits_be32(&fec->eth->ecntrl, 0x1);
+
+	/* wait at least 16 clock cycles */
+	udelay(10);
+}
+
+static int mpc5125_fec_send(struct eth_device *dev, void *eth_data, int data_length)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv;
+	struct mpc5125_descriptor *tbd;
+	int rc;
+
+	/* Clear Tx BD ring at first */
+	mpc5125_fec_tbd_scrub(fec);
+
+	/* Check for valid length of data. */
+	if ((data_length > 1500) || (data_length <= 0))
+		return -EINVAL;
+
+	/* Check the number of vacant TxBDs. */
+	if (fec->clean_tbd_cnt < 1) {
+		dev_err(&dev->dev, "No available TxBDs ...\n");
+		return -ENOMEM;
+	}
+
+	/* Get the first free TxBD to send the mac header */
+	tbd = &fec->bdBase->tbd[fec->tdb_idx];
+	fec->clean_tbd_cnt -= 1;
+	tbd->dlength = data_length;
+	tbd->dpointer = (u32)eth_data;
+	tbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
+	fec->tdb_idx = (fec->tdb_idx + 1) % FEC_TBD_NUM;
+
+	/* ensure all written data has hit the memory */
+	barrier();
+
+	mpc5125_fec_activate_transmission(fec);
+
+	rc = wait_on_timeout(500 * MSECOND,
+				!(in_be16(&tbd->status) & FEC_TBD_READY));
+	if (rc != 0) {
+		dev_err(&dev->dev, "Time out while waiting for transmission...\n");
+	} else {
+		dev_dbg(&dev->dev, "sucessfully sent (%hX)\n", in_be16(&tbd->status));
+	}
+
+	return rc;
+}
+
+static void mpc5125_fec_debug_rx_header(void *buffer, size_t length)
+{
+#ifdef DEBUG_RX_HEADER
+	int i;
+
+	printf ("recv data length 0x%08x data hdr: ", length);
+	for (i = 0; i < 14; i++)
+		printf ("%x ", *((u8*)buffer + i));
+	printf("\n");
+#endif
+}
+
+static int mpc5125_fec_recv(struct eth_device *dev)
+{
+	struct mpc5125_fec_priv *fec = (struct mpc5125_fec_priv *)dev->priv;
+	struct mpc5125_descriptor *pRbd = &fec->bdBase->rbd[fec->rdb_idx];
+	unsigned long ievent;
+	int frame_length = 0;
+
+	/* Check if any critical events have happened */
+	ievent = in_be32(&fec->eth->ievent);
+	out_be32(&fec->eth->ievent, ievent);
+	if (ievent & (FEC_IEVENT_BABT | FEC_IEVENT_XFIFO_ERROR |
+				FEC_IEVENT_RFIFO_ERROR)) {
+		/* BABT, Rx/Tx FIFO errors */
+		mpc5125_fec_halt(dev);
+		mpc5125_fec_init(dev);
+		return 0;
+	}
+
+	if (ievent & FEC_IEVENT_HBERR) {
+		/* Heartbeat error */
+		setbits_be32(&fec->eth->x_cntrl, 0x00000001);
+	}
+
+	if (ievent & FEC_IEVENT_GRA) {
+		/* Graceful stop complete */
+		if (in_be32(&fec->eth->x_cntrl) & 0x00000001) {
+			mpc5125_fec_halt(dev);
+			clrbits_be32(&fec->eth->x_cntrl, 0x00000001);;
+			mpc5125_fec_init(dev);
+		}
+	}
+
+	if (!(pRbd->status & FEC_RBD_EMPTY)) {
+		if (!(pRbd->status & FEC_RBD_ERR) &&
+						((pRbd->dlength - 4) > 14)) {
+			/* calculate payload size */
+			frame_length = pRbd->dlength;
+			if (pRbd->status & FEC_RBD_LAST)
+				frame_length -= - 4;
+
+			mpc5125_fec_debug_rx_header((void *)pRbd->dpointer,
+								pRbd->dlength);
+			mpc5125_fec_collect_frame(fec, (void *)pRbd->dpointer,
+								frame_length);
+			if (pRbd->status & FEC_RBD_LAST) {
+				/* pass it to upper layers on demand */
+				net_receive(dev, fec->frame, frame_length);
+				fec->frame_idx = 0;
+			}
+		}
+
+		/* Reset buffer descriptor as empty */
+		mpc5125_fec_rbd_clean(fec, pRbd);
+	}
+
+	/* Try to fill Buffer Descriptors */
+	out_be32(&fec->eth->r_des_active, 0x01000000);
+
+	return frame_length;
+}
+
+static int mpc5125_fec_probe(struct device_d *dev)
+{
+	struct fec_platform_data *pdata = dev->platform_data;
+	struct eth_device *edev;
+	struct mpc5125_fec_priv *fec;
+
+	edev = (struct eth_device *)xmalloc(sizeof(struct eth_device));
+	fec = (struct mpc5125_fec_priv *)xmalloc(sizeof(*fec));
+	dev->priv = edev;
+	edev->priv = fec;
+	edev->open = mpc5125_fec_open;
+	edev->init = mpc5125_fec_init;
+	edev->send = mpc5125_fec_send;
+	edev->recv = mpc5125_fec_recv;
+	edev->halt = mpc5125_fec_halt;
+	edev->get_ethaddr = mpc5125_fec_get_ethaddr;
+	edev->set_ethaddr = mpc5125_fec_set_ethaddr;
+	edev->parent = dev;
+
+	fec->eth = (struct fec5125 *)dev_request_mem_region(dev, 0);
+
+	mpc5125_fec_init_buffer_ring(fec);
+
+	fec->interface = pdata->xcv_type;
+	fec->phy_addr = pdata->phy_addr;
+
+	mpc5xxx_enable_fec_clock(dev->id);
+
+	fec->miibus.read = fec5125_miibus_read;
+	fec->miibus.write = fec5125_miibus_write;
+
+	fec->miibus.priv = fec;
+	fec->miibus.parent = dev;
+
+	/* do some FEC initialization once */
+
+	/* Clean up space FEC's MIB... */
+	memset(&fec->eth->mib1[0],  0x00, sizeof(fec->eth->mib1));
+	memset(&fec->eth->mib2[0],  0x00, sizeof(fec->eth->mib2));
+	/* disable all interrupts */
+	out_be32(&fec->eth->imask, 0x00000000);
+	/* init the status by clearing all bits */
+	out_be32(&fec->eth->ievent, 0xffffffff);
+
+	mdiobus_register(&fec->miibus);
+
+	eth_register(edev);
+	return 0;
+}
+
+static void mpc5125_fec_remove(struct device_d *dev)
+{
+	struct eth_device *edev = dev->priv;
+
+	mpc5125_fec_halt(edev);
+}
+
+static struct driver_d mpc5125_driver = {
+        .name  = "fec_mpc5125",
+        .probe = mpc5125_fec_probe,
+	.remove = mpc5125_fec_remove,
+};
+device_platform_driver(mpc5125_driver);
diff --git a/drivers/net/fec_mpc5125.h b/drivers/net/fec_mpc5125.h
new file mode 100644
index 0000000..e69de29
diff --git a/include/fec.h b/include/fec.h
index 699761a..8b6fb0e 100644
--- a/include/fec.h
+++ b/include/fec.h
@@ -25,7 +25,7 @@
 
 /*
  * Define the phy connected externally for FEC drivers
- * (like MPC52xx and i.MX27)
+ * (like MPC52xx, MPC512x and i.MX27)
  */
 struct fec_platform_data {
 	phy_interface_t	xcv_type;
-- 
2.1.0



From jbe at pengutronix.de  Tue Oct  7 07:22:13 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Tue,  7 Oct 2014 16:22:13 +0200
Subject: [PATCH 14/19] arch/MPC5xxx: add MPC5125 SoC support
In-Reply-To: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
References: <1412691738-11145-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1412691738-11145-15-git-send-email-jbe@pengutronix.de>

The MPC5125 shares most of the internals with the MPC52000 but differs in
many details. It also differs from the the MPC5121/MPC5123, so the latter
SoCs are not supported yet.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 arch/ppc/include/asm/processor.h                 |  11 +
 arch/ppc/lib/Makefile                            |   2 +-
 arch/ppc/lib/nor-bbu.c                           | 141 ++++++++++
 arch/ppc/mach-mpc5xxx/cpu-mpc5125.c              | 174 ++++++++++++
 arch/ppc/mach-mpc5xxx/include/mach/bbu.h         |  18 ++
 arch/ppc/mach-mpc5xxx/include/mach/clocks.h      |   9 +
 arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h     | 321 +++++++++++++++++++++++
 arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h |  46 ++++
 arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h     |   6 +-
 arch/ppc/mach-mpc5xxx/iomux-mpc5125.c            |  39 +++
 arch/ppc/mach-mpc5xxx/lpc-mpc5125.c              |  73 ++++++
 arch/ppc/mach-mpc5xxx/sdram-mpc5125.c            | 269 +++++++++++++++++++
 arch/ppc/mach-mpc5xxx/speed-mpc5125.c            | 209 +++++++++++++++
 arch/ppc/mach-mpc5xxx/start.S                    |  99 ++++++-
 arch/ppc/mach-mpc5xxx/sys-mpc5125.c              | 136 ++++++++++
 15 files changed, 1549 insertions(+), 4 deletions(-)
 create mode 100644 arch/ppc/lib/nor-bbu.c
 create mode 100644 arch/ppc/mach-mpc5xxx/cpu-mpc5125.c
 create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/bbu.h
 create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
 create mode 100644 arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h
 create mode 100644 arch/ppc/mach-mpc5xxx/iomux-mpc5125.c
 create mode 100644 arch/ppc/mach-mpc5xxx/lpc-mpc5125.c
 create mode 100644 arch/ppc/mach-mpc5xxx/sdram-mpc5125.c
 create mode 100644 arch/ppc/mach-mpc5xxx/speed-mpc5125.c
 create mode 100644 arch/ppc/mach-mpc5xxx/sys-mpc5125.c

diff --git a/arch/ppc/include/asm/processor.h b/arch/ppc/include/asm/processor.h
index e8a9c14..4d5a10f 100644
--- a/arch/ppc/include/asm/processor.h
+++ b/arch/ppc/include/asm/processor.h
@@ -236,6 +236,16 @@
 #define   HID1_ASTME    (1<<13)		/* Address bus streaming mode */
 #define   HID1_ABE      (1<<12)		/* Address broadcast enable */
 #define   HID1_MBDD     (1<<6)		/* optimized sync instruction */
+#define SPRN_HID2	0x3F3
+#define   HID2_LET      (1 << 27)
+#define   HID2_HBE      (1 << 18)
+#define   HID2_IWLCK_000 (0x0 << 13)	/* no ways locked */
+#define   HID2_IWLCK_001 (0x1 << 13)	/* way 0 locked */
+#define   HID2_IWLCK_010 (0x2 << 13)	/* way 0 through way 1 locked */
+#define   HID2_IWLCK_011 (0x3 << 13)	/* way 0 through way 2 locked */
+#define   HID2_IWLCK_100 (0x4 << 13)	/* way 0 through way 3 locked */
+#define   HID2_IWLCK_101 (0x5 << 13)	/* way 0 through way 4 locked */
+#define   HID2_IWLCK_110 (0x6 << 13)	/* way 0 through way 5 locked */
 #define SPRN_IABR	0x3F2	/* Instruction Address Breakpoint Register */
 #ifndef CONFIG_BOOKE
 #define SPRN_IAC1	0x3F4	/* Instruction Address Compare 1 */
@@ -509,6 +519,7 @@
 #define HASH2	SPRN_HASH2	/* Secondary Hash Address Register */
 #define HID0	SPRN_HID0	/* Hardware Implementation Register 0 */
 #define HID1	SPRN_HID1	/* Hardware Implementation Register 1 */
+#define HID2	SPRN_HID2	/* Hardware Implementation Register 2 */
 #define IABR	SPRN_IABR      	/* Instruction Address Breakpoint Register */
 #define IAC1	SPRN_IAC1	/* Instruction Address Register 1 */
 #define IAC2	SPRN_IAC2	/* Instruction Address Register 2 */
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
index ba2f078..99d6225 100644
--- a/arch/ppc/lib/Makefile
+++ b/arch/ppc/lib/Makefile
@@ -9,4 +9,4 @@ obj-$(CONFIG_CMD_BOOTM) += ppclinux.o
 obj-$(CONFIG_MODULES) += module.o
 obj-y += crtsavres.o
 obj-y += reloc.o
-
+obj-$(CONFIG_BAREBOX_UPDATE) += nor-bbu.o
diff --git a/arch/ppc/lib/nor-bbu.c b/arch/ppc/lib/nor-bbu.c
new file mode 100644
index 0000000..3bdd214
--- /dev/null
+++ b/arch/ppc/lib/nor-bbu.c
@@ -0,0 +1,141 @@
+/*
+ * nor-bbu.c - PowerPC generic functions to store barebox into a NOR flash
+ * Copyright (C) 2014 Juergen Borleis, Pengutronix
+ *
+ * Based on imx-bbu-internal.c
+ * Copyright (c) 2012 Sascha Hauer <s.hauer at pengutronix.de>, 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.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <bbu.h>
+#include <mach/bbu.h>
+#include <fs.h>
+#include <linux/stat.h>
+#include <fcntl.h>
+
+#define BBU_FLAG_ERASE			(1 << 0)
+
+/* Actually write an image to NOR target device */
+static int ppc_bbu_write_device(struct bbu_handler *handler,
+		struct bbu_data *data, void *buf, int image_len)
+{
+	int fd, ret;
+
+	fd = open(data->devicefile, O_RDWR | O_CREAT);
+	if (fd < 0)
+		return fd;
+
+	if (handler->flags & BBU_FLAG_ERASE) {
+		debug("%s: unprotecting %s from 0 to 0x%08x\n", __func__,
+				data->devicefile, image_len);
+		ret = protect(fd, image_len, 0, 0);
+		if (ret && ret != -ENOSYS) {
+			printf("unprotecting %s failed with %s\n",
+				data->devicefile, strerror(-ret));
+			goto err_close;
+		}
+
+		debug("%s: erasing %s from 0 to 0x%08x\n", __func__,
+				data->devicefile, image_len);
+		ret = erase(fd, image_len, 0);
+		if (ret) {
+			printf("erasing %s failed with %s\n", data->devicefile,
+					strerror(-ret));
+			goto err_close;
+		}
+	}
+
+	ret = write(fd, buf, image_len);
+	if (ret < 0)
+		goto err_close;
+
+	if (handler->flags & BBU_FLAG_ERASE) {
+		debug("%s: protecting %s from 0 to 0x%08x\n", __func__,
+				data->devicefile, image_len);
+		ret = protect(fd, image_len, 0, 1);
+		if (ret && ret != -ENOSYS) {
+			printf("protecting %s failed with %s\n",
+				data->devicefile, strerror(-ret));
+		}
+	}
+
+	ret = 0;
+
+err_close:
+	close(fd);
+
+	return ret;
+}
+
+static int ppc_bbu_check_prereq(struct bbu_data *data)
+{
+	struct stat s;
+	int ret;
+
+	/*
+	 * Check if the given image is a valid one
+	 * FIXME: currently we have no real chance to detect if the image
+	 * we got is a valid image.
+	 */
+
+	ret = stat(data->devicefile, &s);
+	if (ret != 0) {
+		printf("Cannot stat '%s'. Failed with %s\n", data->devicefile,
+					strerror(-ret));
+		return ret;
+	}
+
+	if (data->len > s.st_size) {
+		printf("'%s' too large for '%s'\n", data->imagefile,
+				data->devicefile);
+		return -EINVAL;
+	}
+
+	ret = bbu_confirm(data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/* write a regular barebox image into an externally connected NOR flash */
+static int ppc_bbu_nor_update(struct bbu_handler *handler, struct bbu_data *data)
+{
+	int ret;
+
+	ret = ppc_bbu_check_prereq(data);
+	if (ret)
+		return ret;
+
+	return ppc_bbu_write_device(handler, data, data->image, data->len);
+}
+
+int ppc_bbu_nor_register_handler(const char *name, const char *devicefile,
+		unsigned long flags)
+{
+	struct bbu_handler *bbu;
+	int ret;
+
+	bbu = xzalloc(sizeof(*bbu));
+	bbu->devicefile = devicefile;
+	bbu->name = name;
+	bbu->flags = flags | BBU_FLAG_ERASE;
+	bbu->handler = ppc_bbu_nor_update;
+
+	ret = bbu_register_handler(bbu);
+	if (ret)
+		free(bbu);
+
+	return ret;
+}
diff --git a/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c b/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c
new file mode 100644
index 0000000..512e2a5
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/cpu-mpc5125.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, Pengutronix
+ *
+ * This code bases partially on:
+ * (C) Copyright 2007-2010 DENX Software Engineering
+ * Copyright (C) 2004-2006 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 <types.h>
+#include <driver.h>
+#include <reset_source.h>
+#include <asm/processor.h>
+#include <mach/mpc5xxx.h>
+#include <asm/io.h>
+
+/* Reset Module */
+struct resetc {
+	u32 rcwl;
+	u32 rcwh;
+	u8 res0[8];
+	u32 rsr;
+	u32 rmr;
+	u32 rpr;
+	u32 rcr;
+	u32 rcer;
+};
+
+/* RSR - Reset Status Register */
+#define MPC512X_RSR_SWSR (1 << 13) /* software soft reset */
+#define MPC512X_RSR_SWHR (1 << 12) /* software hard reset */
+#define MPC512X_RSR_JHRS (1 << 9) /* jtag hreset */
+#define MPC512X_RSR_JSRS (1 << 8) /* jtag sreset status */
+#define MPC512X_RSR_CSHR (1 << 4) /* checkstop reset status */
+#define MPC512X_RSR_SWRS (1 << 3) /* software watchdog reset status */
+#define MPC512X_RSR_BMRS (1 << 2) /* bus monitop reset status */
+#define MPC512X_RSR_SRS (1 << 1) /* soft reset status */
+#define MPC512X_RSR_HRS (1 << 0) /* hard reset status */
+
+/* RMR - Reset Mode Register */
+#define MPC512X_RMR_CSRE (1 << 0) /* checkstop reset enable */
+
+/* RCR - Reset Control Register */
+#define MPC512X_RCR_SWHR (1 << 1) /* software hard reset */
+#define MPC512X_RCR_SWSR (1 << 0) /* software soft reset */
+
+/* RCER - Reset Control Enable Register */
+#define MPC512X_RCER_CRE (1 << 0) /* software hard reset */
+
+static struct resetc * const resetc = (struct resetc *)MPC512X_RESET;
+
+/* called from assembler in start.S */
+int cpu_init(void)
+{
+	/* do it very early, because its required for any delay() */
+	mpc5125_enable_time_base_counter();
+
+	/* RMR - Reset Mode Register - enable checkstop reset */
+	out_be32(&resetc->rmr, MPC512X_RMR_CSRE);
+
+	/* system performance tweaking */
+#ifdef CONFIG_SYS_ACR_PIPE_DEP
+	/* Arbiter pipeline depth */
+	out_be32(&im->arbiter.acr,
+		(im->arbiter.acr & ~ACR_PIPE_DEP) |
+		(CONFIG_SYS_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT)
+	);
+#endif
+
+#ifdef CONFIG_SYS_ACR_RPTCNT
+	/* Arbiter repeat count */
+	out_be32(im->arbiter.acr,
+		(im->arbiter.acr & ~(ACR_RPTCNT)) |
+		(CONFIG_SYS_ACR_RPTCNT << ACR_RPTCNT_SHIFT)
+	);
+#endif
+
+#if 0
+	/* Set IPS-CSB divider: IPS = 1/2 CSB */
+	ips_div = in_be32(&im->clk.scfr[0]);
+	ips_div &= ~(SCFR1_IPS_DIV_MASK);
+	ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT;
+	out_be32(&im->clk.scfr[0], ips_div);
+#endif
+#ifdef SCFR1_LPC_DIV
+	clrsetbits_be32(&im->clk.scfr[0], SCFR1_LPC_DIV_MASK,
+			SCFR1_LPC_DIV << SCFR1_LPC_DIV_SHIFT);
+#endif
+	return 0;
+}
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+	unsigned msr;
+
+	/* Interrupts and MMU off */
+	__asm__ __volatile__ ("mfmsr    %0":"=r" (msr):);
+
+	msr &= ~( MSR_EE | MSR_IR | MSR_DR);
+	__asm__ __volatile__ ("mtmsr    %0"::"r" (msr));
+
+	/* Enable Reset Control Reg - "RSTE" is the magic word that let us go */
+	out_be32(&resetc->rpr, 0x52535445);
+
+	/* Verify Reset Control Reg is enabled */
+	while (!(in_be32(&resetc->rcer) & MPC512X_RCER_CRE))
+		;
+
+	udelay(200);
+
+	/* Perform reset */
+	out_be32(&resetc->rcr, MPC512X_RCR_SWHR);
+
+	while(1)
+		;
+}
+
+/*
+ * the watchdog is always active after reset. To control it we can
+ * write to its 'control register' - but only once. So, after disabling it
+ * there is no way to re-enable it without a hard reset.
+ * If the user don't want to use the watchdog feature, disable it here
+ * forever. If the user wants to use it, start to pet it by registering
+ * the corresponding driver.
+ * The default timeout value after reset is about 130 seconds.
+ * This gives us the time to handle the watchdog at a reasonable
+ * point of initialization time.
+ */
+static int mpc5125_handle_watchdog(void)
+{
+	if (IS_ENABLED(CONFIG_WATCHDOG_MPC5125))
+		add_generic_device("mpc5125wd", 0, NULL, MPC512X_WDT,
+						0x10, IORESOURCE_MEM, NULL);
+	else
+		out_be32((void *)(MPC512X_WDT + 4), 0); /* disable it */
+
+	return 0;
+}
+device_initcall(mpc5125_handle_watchdog);
+
+/* detect the reset source after the framework is up and running */
+static int mpc5125_keep_reset_cause(void)
+{
+	u32 reg;
+
+	reg = in_be32(&resetc->rsr);
+	if (IS_ENABLED(CONFIG_RESET_SOURCE)) {
+		if (reg & MPC512X_RSR_HRS)
+			reset_source_set(RESET_POR);
+		else if (reg & MPC512X_RSR_SRS)
+			reset_source_set(RESET_RST);
+		else if (reg & MPC512X_RSR_SWRS)
+			reset_source_set(RESET_WDG);
+		else if (reg & (MPC512X_RSR_JSRS | MPC512X_RSR_JHRS))
+			reset_source_set(RESET_JTAG);
+		else
+			reset_source_set(RESET_UKWN);
+	}
+	out_be32(&resetc->rsr, reg);
+
+	return 0;
+}
+device_initcall(mpc5125_keep_reset_cause);
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/bbu.h b/arch/ppc/mach-mpc5xxx/include/mach/bbu.h
new file mode 100644
index 0000000..6727d42
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/include/mach/bbu.h
@@ -0,0 +1,18 @@
+#ifndef __MACH_BBU_H
+#define __MACH_BBU_H
+
+#ifdef CONFIG_BAREBOX_UPDATE
+
+int ppc_bbu_nor_register_handler(const char *name, const char *devicefile,
+					unsigned long flags);
+
+#else /* CONFIG_BAREBOX_UPDATE */
+
+static inline int ppc_bbu_nor_register_handler(const char *name,
+				const char *devicefile, unsigned long flags)
+{
+	return -ENOSYS;
+}
+#endif
+
+#endif /* __MACH_BBU_H */
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
index 717a85b..87fdbc6 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/clocks.h
@@ -4,6 +4,7 @@
 /* common clocks */
 unsigned long get_cpu_clock(void);
 unsigned long get_timebase_clock(void);
+void mpc5xxx_enable_psc_clock(unsigned idx);
 
 #if defined(CONFIG_MGT5100) || defined(CONFIG_MPC5200)
 unsigned long get_bus_clock(void);
@@ -11,4 +12,12 @@ unsigned long get_ipb_clock(void);
 unsigned long get_pci_clock(void);
 #endif
 
+#ifdef CONFIG_SOC_MPC5125
+unsigned long get_ips_clock(void);
+unsigned long get_psc_clock(unsigned);
+void mpc5125_enable_psc_fifo_clock(void);
+void mpc5xxx_enable_fec_clock(unsigned idx);
+unsigned long mpc5125_get_psc_clock(unsigned idx);
+#endif
+
 #endif /* __ASM_ARCH_CLOCKS_H */
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
new file mode 100644
index 0000000..ed60f2a
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, 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.
+ */
+
+#ifndef __MPC512X_H__
+#define __MPC512X_H__
+
+#include <asm/types.h>
+#include <sizes.h>
+
+/* reset default */
+#define DEFAULT_MBAR	0xff400000
+
+/*
+ * Memory map after reset:
+ *
+ * 0x00000000 - 0x007fffff LPB-ROM (when BMS = 0)
+ * 0x10000000 - 0x13ffffff system main memory area
+ * 0x30000000 - 0x3001ffff SRAM
+ * 0x40000000 - 0x400fffff NFC
+ * 0xff400000 - 0xff4fffff MBAR + IO area
+ *
+ * Memory map after _start in start.S run:
+ *
+ * 0x00000000 ... 0x7fffffff  system main memory area
+ * 0xf0000000 ... 0xf00fffff  MBAR + IO area (1 MiB)
+ * 0xf0500000 ... 0xff53ffff  SRAM (256 kiB)
+ * 0xf0600000 ... 0xff6fffff  NFC (1 MiB)
+ * 0xfe000000 ... 0xffffffff  ROM (32 MiB)
+ */
+
+#define CFG_MBAR	0xf0000000
+#define CFG_ROM_LOC	0xfe000000
+#define CFG_ROM_SZ	SZ_8M
+#define CFG_SRAM_LOC	0xf0500000
+# define MPC5XXX_SRAM	CFG_SRAM_LOC
+#define CFG_SRAM_SZ	SZ_32K
+# define MPC5XXX_SRAM_SIZE CFG_SRAM_SZ
+#define CFG_NFC_LOC	0xf0600000
+
+#define DEFAULT_DRAM_BASE 0x00000000
+
+/* base address is IMMBAR */
+#define MPC512X_RESET	(CFG_MBAR + 0x00E00)
+#define MPC512X_CLKM	(CFG_MBAR + 0x00f00)
+#define MPC512X_WDT	(CFG_MBAR + 0x00900)
+#define MPC512X_FEC1	(CFG_MBAR + 0x02800)
+#define MPC512X_FEC2	(CFG_MBAR + 0x04800)
+#define MPC512X_DRAMC	(CFG_MBAR + 0x09000)
+#define MPC512X_IOC	(CFG_MBAR + 0x0A000)
+#define MPC512X_LPC	(CFG_MBAR + 0x10000)
+#define MPC512X_PSC0	(CFG_MBAR + 0x11000)
+#define MPC512X_PSC1	(CFG_MBAR + 0x11100)
+#define MPC512X_PSC2	(CFG_MBAR + 0x11200)
+#define MPC512X_PSC3	(CFG_MBAR + 0x11300)
+#define MPC512X_PSC4	(CFG_MBAR + 0x11400)
+#define MPC512X_PSC5	(CFG_MBAR + 0x11500)
+#define MPC512X_PSC6	(CFG_MBAR + 0x11600)
+#define MPC512X_PSC7	(CFG_MBAR + 0x11700)
+#define MPC512X_PSC8	(CFG_MBAR + 0x11800)
+#define MPC512X_PSC9	(CFG_MBAR + 0x11900)
+#define MPC512X_FIFOC	(CFG_MBAR + 0x11f00)
+
+/* System reset offset (PowerPC standard) */
+#define EXC_OFF_SYS_RESET	0x0100
+#define _START_OFFSET		EXC_OFF_SYS_RESET
+
+/* some register offsets from the "Local Access Register Memory Map" */
+#define LPBAW_OFFSET		0x20
+#define LPCS0AW_OFFSET		0x24
+#define SRAMBAR_OFFSET		0xc4
+#define NFSCBAR_OFFSET		0xc8
+#define SWCRR_OFFSET		0x0904
+#define CS_CR_OFFSET		0x20
+
+#ifndef CFG_HID0_INIT
+# define CFG_HID0_INIT		HID0_ICE | HID0_ICFI
+#endif
+#ifndef CFG_HID0_FINAL
+# define CFG_HID0_FINAL		HID0_ICE
+#endif
+#ifndef CFG_SYS_HID2
+# define CFG_SYS_HID2		HID2_HBE
+#endif
+
+#ifndef __ASSEMBLY__
+
+void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size);
+void mpc5125_setup_ram_memory_window(unsigned base, unsigned size);
+unsigned mpc5xxx_get_sdram_size(void);
+void mpc5125_enable_time_base_counter(void);
+
+void mpc5125_setup_ram_memory_window(unsigned base, unsigned size);
+
+enum mpc5125_pinmux_id {
+	io_control_mem = 0,
+	io_control_lpc_clk = 4,
+	io_control_lpc_oe,
+	io_control_lpc_rw,
+	io_control_lpc_cs0,
+	io_control_lpc_ack,
+	io_control_lpc_ax03 = 9,
+	io_control_emb_ax02,
+	io_control_emb_ax01,
+	io_control_emb_ax00 = 12,
+	io_control_emb_ad31 = 13,
+	io_control_emb_ad30,
+	io_control_emb_ad29,
+	io_control_emb_ad28,
+	io_control_emb_ad27,
+	io_control_emb_ad26,
+	io_control_emb_ad25,
+	io_control_emb_ad24,
+	io_control_emb_ad23,
+	io_control_emb_ad22,
+	io_control_emb_ad21,
+	io_control_emb_ad20,
+	io_control_emb_ad19,
+	io_control_emb_ad18,
+	io_control_emb_ad17,
+	io_control_emb_ad16,
+	io_control_emb_ad15,
+	io_control_emb_ad14,
+	io_control_emb_ad13,
+	io_control_emb_ad12,
+	io_control_emb_ad11,
+	io_control_emb_ad10 = 34,
+	io_control_emb_ad9,
+	io_control_emb_ad8,
+	io_control_emb_ad7,
+	io_control_emb_ad6,
+	io_control_emb_ad5,
+	io_control_emb_ad4,
+	io_control_emb_ad3,
+	io_control_emb_ad2,
+	io_control_emb_ad1,
+	io_control_emb_ad0 = 44,
+	io_control_nfc_ce0 = 45,
+	io_control_nfc_rb,
+	io_control_dui_clk,
+	io_control_dui_de,
+	io_control_dui_hsync = 49,
+	io_control_dui_vsync,
+	io_control_dui_ld0 = 51,
+	io_control_dui_ld1,
+	io_control_dui_ld2,
+	io_control_dui_ld3,
+	io_control_dui_ld4,
+	io_control_dui_ld5,
+	io_control_dui_ld6,
+	io_control_dui_ld7,
+	io_control_dui_ld8,
+	io_control_dui_ld9,
+	io_control_dui_ld10,
+	io_control_dui_ld11,
+	io_control_dui_ld12,
+	io_control_dui_ld13,
+	io_control_dui_ld14,
+	io_control_dui_ld15,
+	io_control_dui_ld16,
+	io_control_dui_ld17,
+	io_control_dui_ld18,
+	io_control_dui_ld19,
+	io_control_dui_ld20,
+	io_control_dui_ld21,
+	io_control_dui_ld22,
+	io_control_dui_ld23 = 74,
+	io_control_i2c2_scl = 75,
+	io_control_i2c2_sda = 76,
+	io_control_can1_tx = 77,
+	io_control_can2_tx = 78,
+	io_control_i2c1_scl = 79,
+	io_control_i2c1_sda = 80,
+/* No pin control register for can1_rx and can2_rx */
+	io_control_fec1_txd2 = 81,
+	io_control_fec1_txd3,
+	io_control_fec1_rxd2,
+	io_control_fec1_rxd3,
+	io_control_fec1_crs,
+	io_control_fec1_txerr,
+	io_control_fec1_rxd1,
+	io_control_fec1_txd1,
+	io_control_fec1_mdc,
+	io_control_fec1_rxerr,
+	io_control_fec1_mdio,
+	io_control_fec1_rxd0,
+	io_control_fec1_txd0,
+	io_control_fec1_txclk,
+	io_control_fec1_rxclk,
+	io_control_fec1_rxdv,
+	io_control_fec1_txen,
+	io_control_fec1_col,
+	io_control_usb1_data0 = 99,
+	io_control_usb1_data1,
+	io_control_usb1_data2,
+	io_control_usb1_data3,
+	io_control_usb1_data4,
+	io_control_usb1_data5,
+	io_control_usb1_data6,
+	io_control_usb1_data7,
+	io_control_usb1_stop,
+	io_control_usb1_clk,
+	io_control_usb1_next,
+	io_control_usb1_dir,
+	io_control_sdhc1_clk = 111,
+	io_control_sdhc1_cmd,
+	io_control_sdhc1_d0,
+	io_control_sdhc1_d1,
+	io_control_sdhc1_d2,
+	io_control_sdhc1_d3,
+	io_control_psc_mclk_in,
+	io_control_psc0_0 = 118,
+	io_control_psc0_1,
+	io_control_psc0_2,
+	io_control_psc0_3,
+	io_control_psc0_4,
+	io_control_psc1_0,
+	io_control_psc1_1,
+	io_control_psc1_2,
+	io_control_psc1_3,
+	io_control_psc1_4,
+	io_control_j1850_tx,
+	io_control_j1850_rx,
+};
+
+#define MPC5125_ALTF_0 (0x0 << 5)
+#define MPC5125_ALTF_1 (0x1 << 5)
+#define MPC5125_ALTF_2 (0x2 << 5)
+#define MPC5125_ALTF_3 (0x3 << 5)
+#define MPC5125_PULL_UP (1 << 4)
+#define MPC5125_PULL_DOWN (0 << 4)
+#define MPC5125_PUD_ENA (1 << 3)
+#define MPC5125_ST_ENA (1 << 2)
+
+/*
+ * from the MPC5125 revision 4 (09/2011) datasheet
+ * Slew rate definition for general IOs:
+ *  - configuration 0: 140/183 ns
+ *  - configuration 1: 19/24 ns
+ *  - configuration 2: 9.8/12 ns
+ *  - configuration 3: 1.4/1.6 ns
+ */
+#define MPC5125_SLEW_RATE(x) ((x) & 0x03)
+
+void mpc5125_mux_pin(enum mpc5125_pinmux_id idx, unsigned char mux);
+
+/* SDRAM commands */
+#define DRAM_CMD_NOP		0x01380000
+#define DRAM_CMD_PCHG_ALL	0x01100400
+#define DRAM_CMD_EM2		0x01020000
+#define DRAM_CMD_EM3		0x01030000
+#define DRAM_CMD_EN_DLL		0x01010000
+#define DRAM_CMD_RFSH		0x01080000
+
+#define DDR_COMMAND_CMD_REQ	(1 << 24)
+#define DDR_COMMAND_CMD_MSR	(0 << 16)
+#define DDR_COMMAND_CMD_EMR1	(1 << 16)
+#define DDR_COMMAND_CMD_EMR2	(2 << 16)
+#define DDR_COMMAND_CMD_EMR3	(3 << 16)
+#define DDR_COMMAND_RST_DLL	(1 << 8)
+
+struct sdram_prio {
+	unsigned prioman_config1;
+	unsigned prioman_config2;
+	unsigned hiprio_config;
+	unsigned lut_table0_main_upper;
+	unsigned lut_table0_main_lower;
+	unsigned lut_table1_main_upper;
+	unsigned lut_table1_main_lower;
+	unsigned lut_table2_main_upper;
+	unsigned lut_table2_main_lower;
+	unsigned lut_table3_main_upper;
+	unsigned lut_table3_main_lower;
+	unsigned lut_table4_main_upper;
+	unsigned lut_table4_main_lower;
+	unsigned lut_table0_alt_upper;
+	unsigned lut_table0_alt_lower;
+	unsigned lut_table1_alt_upper;
+	unsigned lut_table1_alt_lower;
+	unsigned lut_table2_alt_upper;
+	unsigned lut_table2_alt_lower;
+	unsigned lut_table3_alt_upper;
+	unsigned lut_table3_alt_lower;
+	unsigned lut_table4_alt_upper;
+	unsigned lut_table4_alt_lower;
+};
+
+struct sdram_conf {
+	struct sdram_prio prio;
+	unsigned mux_ddr;
+	unsigned sys_cfg;
+	unsigned tim_cfg0, tim_cfg1, tim_cfg2;
+	unsigned size;
+	const unsigned *cmds;
+};
+
+void mpc5125_init_sdram(const struct sdram_conf *init_sequence);
+
+struct lpc_config {
+	unsigned cs_ale_timing;
+	unsigned cs_burst;
+	unsigned cs_dead_cyle;
+	unsigned cs_hold_cycle;
+};
+
+void mpc5125_configure_lpc(const struct lpc_config *c);
+void mpc5125_setup_cs(unsigned, unsigned, unsigned, unsigned);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __MPC512X_H__ */
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h
new file mode 100644
index 0000000..ddac8e5
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc512x_fec.h
@@ -0,0 +1,46 @@
+#include <linux/types.h>
+
+/* FEC */
+struct fec {
+	u32 fec_id; /* FEC_ID register */
+	u32 ievent; /* Interrupt event register */
+	u32 imask; /* Interrupt mask register */
+	u32 reserved_01;
+	u32 r_des_active; /* Receive ring updated flag */
+	u32 x_des_active; /* Transmit ring updated flag */
+	u32 reserved_02[3];
+	u32 ecntrl; /* Ethernet control register */
+	u32 reserved_03[6];
+	u32 mii_data; /* MII data register */
+	u32 mii_speed; /* MII speed register */
+	u32 reserved_04[7];
+	u32 mib_control; /* MIB control/status register */
+	u32 reserved_05[7];
+	u32 r_cntrl; /* Receive control register */
+	u32 r_hash; /* Receive hash */
+	u32 reserved_06[14];
+	u32 x_cntrl; /* Transmit control register */
+	u32 reserved_07[7];
+	u32 paddr1; /* Physical address low */
+	u32 paddr2; /* Physical address high + type field */
+	u32 op_pause; /* Opcode + pause duration */
+	u32 reserved_08[10];
+	u32 iaddr1; /* Upper 32 bits of individual hash table */
+	u32 iaddr2; /* Lower 32 bits of individual hash table */
+	u32 gaddr1; /* Upper 32 bits of group hash table */
+	u32 gaddr2; /* Lower 32 bits of group hash table */
+	u32 reserved_09[7];
+	u32 x_wmrk; /* Transmit FIFO watermark */
+	u32 reserved_10;
+	u32 r_bound; /* End of RAM */
+	u32 r_fstart; /* Receive FIFO start address */
+	u32 reserved_11[11];
+	u32 r_des_start; /* Beginning of receive descriptor ring */
+	u32 x_des_start; /* Pointer to beginning of transmit descriptor ring */
+	u32 r_buff_size; /* Receive buffer size */
+	u32 reserved_12[26];
+	u32 dma_control; /* DMA control for IP bus, AMBA IF + DMA revision */
+	u32 reserved_13[2];
+	u32 mib[128]; /* MIB Block Counters */
+	u32 fifo[256]; /*  used by FEC, can only be accessed by DMA */
+};
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
index 2455484..f5f0a75 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
@@ -1,8 +1,10 @@
-#ifndef __ASMPPC_MPC5XXX_H
-#define __ASMPPC_MPC5XXX_H
+#ifndef __MACH_MPC5XXX_H
+#define __MACH_MPC5XXX_H
 
 #if defined(CONFIG_MPC5200) || defined(CONFIG_MGT5100)
 # include <mach/mpc5200.h>
 #else
 # error "Undefined Core CPU"
 #endif
+
+#endif /* __MACH_MPC5XXX_H */
diff --git a/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c b/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c
new file mode 100644
index 0000000..a52010e
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/iomux-mpc5125.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/mpc5xxx.h>
+
+static u8 * const ioc = (u8 * )MPC512X_IOC;
+
+void mpc5125_mux_pin(enum mpc5125_pinmux_id idx, unsigned char mux)
+{
+	out_8(&ioc[idx], mux);
+}
+
+#define IOC_GB_OBE (1 << 0)
+
+static int mpc5125_mux_init(void)
+{
+	/*
+	 * Note: all default muxed pins/features which are outputs are
+	 * *tristated* after reset. Enable them right now
+	 */
+	out_8(&ioc[1], IOC_GB_OBE);
+
+	return 0;
+}
+coredevice_initcall(mpc5125_mux_init);
diff --git a/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c b/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c
new file mode 100644
index 0000000..0e602d5
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/lpc-mpc5125.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, 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.
+ */
+
+#include <common.h>
+#include <types.h>
+#include <mach/mpc5xxx.h>
+#include <asm/io.h>
+
+/* LPC */
+struct lpc {
+	u32	cs_cfg[8]; /* Chip Select N Configuration Registers
+				   No dedicated entry for CS Boot as == CS0 */
+	u32	cs_cr; /* Chip Select Control Register */
+	u32	cs_sr; /* Chip Select Status Register */
+	u32	cs_bcr; /* Chip Select Burst Control Register */
+	u32	cs_dccr; /* Chip Select Deadcycle Control Register */
+	u32	cs_hccr; /* Chip Select Holdcycle Control Register */
+	u32	altr; /* Address Latch Timing Register */
+	u8	res0[0xc8];
+	u32	sclpc_psr; /* SCLPC Packet Size Register */
+	u32	sclpc_sar; /* SCLPC Start Address Register */
+	u32	sclpc_cr; /* SCLPC Control Register */
+	u32	sclpc_er; /* SCLPC Enable Register */
+	u32	sclpc_nar; /* SCLPC NextAddress Register */
+	u32	sclpc_sr; /* SCLPC Status Register */
+	u32	sclpc_bdr; /* SCLPC Bytes Done Register */
+	u32	emb_scr; /* EMB Share Counter Register */
+	u32	emb_pcr; /* EMB Pause Control Register */
+	u8	res1[0x1c];
+	u32	lpc_fdwr; /* LPC RX/TX FIFO Data Word Register */
+	u32	lpc_fsr; /* LPC RX/TX FIFO Status Register */
+	u32	lpc_cr; /* LPC RX/TX FIFO Control Register */
+	u32	lpc_ar; /* LPC RX/TX FIFO Alarm Register */
+};
+
+static struct lpc * const lpc = (struct lpc *)MPC512X_LPC;
+
+void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size);
+
+/* setup one CS line at the LPC bus */
+void mpc5125_setup_cs(unsigned cs, unsigned start, unsigned size, unsigned cfg)
+{
+	/* access window first */
+	mpc5125_setup_access_window(cs, start, size);
+
+	/* access method and timing */
+	out_be32(&lpc->cs_cfg[cs], cfg);
+}
+
+void mpc5125_configure_lpc(const struct lpc_config *c)
+{
+	/* enable the LPC feature */
+	setbits_be32(&lpc->cs_cr, 0x01000000);
+
+	if (c == NULL)
+		return; /* keep the defaults */
+
+	out_be32(&lpc->altr, c->cs_ale_timing);
+	out_be32(&lpc->cs_bcr, c->cs_burst);
+	out_be32(&lpc->cs_dccr, c->cs_dead_cyle);
+	out_be32(&lpc->cs_hccr, c->cs_hold_cycle);
+}
diff --git a/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c b/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c
new file mode 100644
index 0000000..9fc3723
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/sdram-mpc5125.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, Pengutronix
+ *
+ * This code bases partially on:
+ * (C) Copyright 2007-2009 DENX Software Engineering
+ *
+ * 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 <types.h>
+#include <mach/mpc5xxx.h>
+#include <asm/io.h>
+
+/* register description of the MPC5125 memory controller */
+struct mddrc {
+	u32 ddr_sys_config;
+	u32 ddr_time_config0;
+	u32 ddr_time_config1;
+	u32 ddr_time_config2;
+	u32 ddr_command;
+	u32 ddr_compact_command;
+	u32 self_refresh_cmd_0;
+	u32 self_refresh_cmd_1;
+	u32 self_refresh_cmd_2;
+	u32 self_refresh_cmd_3;
+	u32 self_refresh_cmd_4;
+	u32 self_refresh_cmd_5;
+	u32 self_refresh_cmd_6;
+	u32 self_refresh_cmd_7;
+	u32 dqs_config_offset_count;
+	u32 dqs_config_offset_time;
+	u32 DQS_delay_status;
+	u32 res0[0xF];
+	u32 prioman_config1;
+	u32 prioman_config2;
+	u32 hiprio_config;
+	u32 lut_table0_main_upper;
+	u32 lut_table1_main_upper;
+	u32 lut_table2_main_upper;
+	u32 lut_table3_main_upper;
+	u32 lut_table4_main_upper;
+	u32 lut_table0_main_lower;
+	u32 lut_table1_main_lower;
+	u32 lut_table2_main_lower;
+	u32 lut_table3_main_lower;
+	u32 lut_table4_main_lower;
+	u32 lut_table0_alt_upper;
+	u32 lut_table1_alt_upper;
+	u32 lut_table2_alt_upper;
+	u32 lut_table3_alt_upper;
+	u32 lut_table4_alt_upper;
+	u32 lut_table0_alt_lower;
+	u32 lut_table1_alt_lower;
+	u32 lut_table2_alt_lower;
+	u32 lut_table3_alt_lower;
+	u32 lut_table4_alt_lower;
+	u32 performance_monitor_config;
+	u32 event_time_counter;
+	u32 event_time_preset;
+	u32 performance_monitor1_address_low;
+	u32 performance_monitor2_address_low;
+	u32 performance_monitor1_address_hi;
+	u32 performance_monitor2_address_hi;
+	u32 res1[2];
+	u32 performance_monitor1_read_counter;
+	u32 performance_monitor2_read_counter;
+	u32 performance_monitor1_write_counter;
+	u32 performance_monitor2_write_counter;
+	u32 granted_ack_counter0;
+	u32 granted_ack_counter1;
+	u32 granted_ack_counter2;
+	u32 granted_ack_counter3;
+	u32 granted_ack_counter4;
+	u32 cumulative_wait_counter0;
+	u32 cumulative_wait_counter1;
+	u32 cumulative_wait_counter2;
+	u32 cumulative_wait_counter3;
+	u32 cumulative_wait_counter4;
+	u32 summed_priority_counter0;
+	u32 summed_priority_counter1;
+	u32 summed_priority_counter2;
+	u32 summed_priority_counter3;
+	u32 summed_priority_counter4;
+};
+
+/* MDDRC SYS CFG and Timing CFG0 Registers */
+#define MDDRC_SYS_CFG_EN	0xF0000000
+#define MDDRC_SYS_CFG_CKE_MASK	0x40000000
+#define MDDRC_SYS_CFG_CMD_MASK	0x10000000
+#define MDDRC_REFRESH_ZERO_MASK	0x0000FFFF
+
+#define DRAM_DSC_CMD_MODE (1 << 28)
+#define DRAM_DSC_CLK_ON (1 << 29)
+#define DRAM_DSC_CKE (1 << 30)
+#define DRAM_DSC_RST_B (1 << 31)
+
+static struct mddrc * const dramc = (struct mddrc *)MPC512X_DRAMC;
+
+static const unsigned char page_addr[16] = {
+	10, 11, 11, 12, 12, 13, 13, 14, 14, 24, 24, 25, 25, 26, 17, 28,
+};
+
+static const unsigned char bank_addr[16] = {
+	2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3,
+};
+
+static const unsigned char row_addr[8] = {
+	16, 16, 16, 16, 16, 16, 15, 14,
+};
+
+/* note: don't call when already running from SDRAM */
+static unsigned detect_real_memory_size(unsigned slice_count, unsigned full_count)
+{
+	void *p;
+	unsigned u, cnt;
+
+	for (u = full_count - 1; u >= slice_count; u--) {
+		p = (void *)((1 << u) + DEFAULT_DRAM_BASE);
+		out_8(p, u);
+	}
+
+	cnt = in_8((void*)DEFAULT_DRAM_BASE);
+	return 1 << cnt;
+}
+
+/*static*/ const void *fix_main_address(const void *init_sequence)
+{
+	unsigned linked_address = (unsigned)init_sequence;
+	unsigned real_address;
+
+	/* FIXME use get_runtime_offset() instead */
+	real_address = linked_address - CONFIG_TEXT_BASE;
+	real_address += CFG_ROM_LOC;
+
+	return (const void *)real_address;
+}
+
+/*
+ * Note: this function depends on the possibility to map up to
+ * the full 2 GiB memory area (e.g. special mapping must exist)
+ */
+/*static*/ unsigned mpc5125_detect_sdram_size(void)
+{
+	size_t pagei, banki, rowi;
+	unsigned addr_cnt, slice_count, reg;
+	const unsigned char *p;
+
+	reg = in_be32(&dramc->ddr_sys_config);
+	pagei = banki = (reg >> 21) & 0xf;
+	rowi = (reg >> 25) & 0x7;
+
+	p = fix_main_address(&page_addr[pagei]);
+	addr_cnt = *p;
+	p = fix_main_address(&bank_addr[banki]);
+	addr_cnt += *p;
+	slice_count = addr_cnt;
+	p = fix_main_address(&row_addr[rowi]);
+	addr_cnt += *p;
+
+	/* enable up to the full possible SDRAM access window for size detection */
+	mpc5125_setup_ram_memory_window(DEFAULT_DRAM_BASE, 1 << addr_cnt);
+	return detect_real_memory_size(slice_count, addr_cnt);
+}
+
+/*static */void setup_priority_manager(const struct sdram_conf *init_sequence)
+{
+	out_be32(&dramc->prioman_config1, init_sequence->prio.prioman_config1);
+	out_be32(&dramc->prioman_config2, init_sequence->prio.prioman_config2);
+	out_be32(&dramc->hiprio_config, init_sequence->prio.hiprio_config);
+	out_be32(&dramc->lut_table0_main_upper, init_sequence->prio.lut_table0_main_upper);
+	out_be32(&dramc->lut_table0_main_lower, init_sequence->prio.lut_table0_main_lower);
+	out_be32(&dramc->lut_table1_main_upper, init_sequence->prio.lut_table1_main_upper);
+	out_be32(&dramc->lut_table1_main_lower, init_sequence->prio.lut_table1_main_lower);
+	out_be32(&dramc->lut_table2_main_upper, init_sequence->prio.lut_table2_main_upper);
+	out_be32(&dramc->lut_table2_main_lower, init_sequence->prio.lut_table2_main_lower);
+	out_be32(&dramc->lut_table3_main_upper, init_sequence->prio.lut_table3_main_upper);
+	out_be32(&dramc->lut_table3_main_lower, init_sequence->prio.lut_table3_main_lower);
+	out_be32(&dramc->lut_table4_main_upper, init_sequence->prio.lut_table4_main_upper);
+	out_be32(&dramc->lut_table4_main_lower, init_sequence->prio.lut_table4_main_lower);
+	out_be32(&dramc->lut_table0_alt_upper, init_sequence->prio.lut_table0_alt_upper);
+	out_be32(&dramc->lut_table0_alt_lower, init_sequence->prio.lut_table0_alt_lower);
+	out_be32(&dramc->lut_table1_alt_upper, init_sequence->prio.lut_table1_alt_upper);
+	out_be32(&dramc->lut_table1_alt_lower, init_sequence->prio.lut_table1_alt_lower);
+	out_be32(&dramc->lut_table2_alt_upper, init_sequence->prio.lut_table2_alt_upper);
+	out_be32(&dramc->lut_table2_alt_lower, init_sequence->prio.lut_table2_alt_lower);
+	out_be32(&dramc->lut_table3_alt_upper, init_sequence->prio.lut_table3_alt_upper);
+	out_be32(&dramc->lut_table3_alt_lower, init_sequence->prio.lut_table3_alt_lower);
+	out_be32(&dramc->lut_table4_alt_upper, init_sequence->prio.lut_table4_alt_upper);
+	out_be32(&dramc->lut_table4_alt_lower, init_sequence->prio.lut_table4_alt_lower);
+}
+
+/* depends on an enabled core internal timer ('TBEN' in 'SPCR') */
+void mpc5125_low_level_delay(unsigned ticks)
+{
+	uint64_t timeval = get_ticks();
+
+	while ((get_ticks() - timeval) < ticks)
+		;
+}
+
+#define TICKS_PER_US 50
+
+/*static */void startup_dram(const struct sdram_conf *init_sequence)
+{
+	unsigned reg = init_sequence->sys_cfg & ~DRAM_DSC_CKE;
+
+	/*
+	 * the "enable" combination: DRAM controller out of reset,
+	 * clock enabled, command mode -- BUT leave CKE low for now
+	 */
+	reg |= DRAM_DSC_RST_B | DRAM_DSC_CLK_ON | DRAM_DSC_CMD_MODE;
+	out_be32(&dramc->ddr_sys_config, reg);
+
+	/* maintain 500 microseconds of stable power and clock */
+	mpc5125_low_level_delay(500 * TICKS_PER_US);
+
+	/* apply a NOP, it shouldn't harm */
+	out_be32(&dramc->ddr_command, DRAM_CMD_NOP);
+
+	/* now assert CKE (high) */
+	reg |= DRAM_DSC_CKE;
+	out_be32(&dramc->ddr_sys_config, reg);
+}
+
+void mpc5125_init_sdram(const struct sdram_conf *init_sequence)
+{
+	unsigned msize;
+	const unsigned *cmds;
+	size_t u;
+
+	init_sequence = fix_main_address(init_sequence);
+
+	mpc5125_mux_pin(io_control_mem, init_sequence->mux_ddr);
+	startup_dram(init_sequence);
+	setup_priority_manager(init_sequence);
+
+	/* start to setup the external memory */
+	out_be32(&dramc->ddr_time_config0, init_sequence->tim_cfg0 &
+						MDDRC_REFRESH_ZERO_MASK);
+	out_be32(&dramc->ddr_time_config1, init_sequence->tim_cfg1);
+	out_be32(&dramc->ddr_time_config2, init_sequence->tim_cfg2);
+
+	cmds = fix_main_address(&init_sequence->cmds[0]);
+
+	/* Initialize memory with supplied init sequence */
+	for (u = 0; u < init_sequence->size; u++)
+		out_be32(&dramc->ddr_command, cmds[u]);
+
+	/* Start DDRC with final settings */
+	out_be32(&dramc->ddr_time_config0, init_sequence->tim_cfg0);
+	out_be32(&dramc->ddr_sys_config, init_sequence->sys_cfg);
+
+	/* Allow for the DLL to startup before accessing data */
+	mpc5125_low_level_delay(1000 * TICKS_PER_US);
+
+	msize = mpc5125_detect_sdram_size();
+
+	/* size and move the memory to its final destination */
+	mpc5125_setup_ram_memory_window(DEFAULT_DRAM_BASE, msize);
+}
diff --git a/arch/ppc/mach-mpc5xxx/speed-mpc5125.c b/arch/ppc/mach-mpc5xxx/speed-mpc5125.c
new file mode 100644
index 0000000..66d0e88
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/speed-mpc5125.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, Pengutronix
+ *
+ * This code bases partially on:
+ * (C) Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ * Copyright (C) 2004-2006 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 <types.h>
+#include <asm/io.h>
+#include <mach/mpc512x.h>
+
+/* Clock Module register description */
+struct clkm {
+	u32 spmr; /* System PLL Mode Register */
+	u32 sccr[2]; /* System Clock Control Registers */
+	u32 scfr[2]; /* System Clock Frequency Registers */
+	u8 res0[4];
+	u32 bcr; /* Bread Crumb Register */
+	u32 pscccr[12]; /* PSC0-11 Clock Control Registers */
+	u32 spccr; /* SPDIF Clock Control Register */
+	u32 cccr; /* CFM Clock Control Register */
+	u32 dccr; /* DIU Clock Control Register */
+	u32 msccr[4]; /* MSCAN1-4 Clock Control Registers */
+};
+
+#define SPMR_SPMF		0x0F000000
+#define SPMR_SPMF_SHIFT		24
+#define SPMR_CPMF		0x000F0000
+#define SPMR_CPMF_SHIFT		16
+
+#define SCFR1_IPS_DIV_MASK	0x03800000
+#define SCFR1_IPS_DIV_SHIFT	23
+
+#define SCFR2_SYS_DIV		0xFC000000
+#define SCFR2_SYS_DIV_SHIFT	26
+
+#define SCCR_EN_CLK_FEC1	(1 << 13)
+#define SCCR_EN_CLK_FEC2	(1 << 9)
+
+#define PSCCCR_MCLK_DIV_SHIFT	17
+#define PSCCCR_MCLK_DIV_MASK	(0xfffe << PSCCCR_MCLK_DIV_SHIFT)
+#define PSCCCR_MCLK_EN		(1 << 16)
+#define PSCCCR_MCLK_0_SRC_SHIFT	14
+#define PSCCCR_MCLK_0_SRC_MASK	(3 << PSCCCR_MCLK_0_SRC_SHIFT)
+
+static struct clkm * const clkm = (struct clkm *)MPC512X_CLKM;
+
+unsigned long get_timebase_clock(void)
+{
+	return CONFIG_SYS_MPC512X_CLKIN;
+}
+
+static const unsigned char spmf_mult[] = {
+	68, 1, 12, 16,
+	20, 24, 28, 32,
+	36, 40, 44, 48,
+	52, 56, 60, 64
+};
+
+unsigned long get_pll_clk(void)
+{
+	unsigned reg;
+	size_t spmf;
+
+	reg = in_be32(&clkm->spmr);
+	spmf = (reg & SPMR_SPMF) >> SPMR_SPMF_SHIFT;
+	return get_timebase_clock() * spmf_mult[spmf];
+}
+
+static const unsigned char sys_dividors[][2] = {
+	{2, 1}, {5, 2}, {3, 1}, {7, 2}, {4, 1},
+	{9, 2}, {5, 1}, {7, 1}, {6, 1}, {8, 1},
+	{9, 1}, {11, 1}, {10, 1}, {12, 1}, {13, 1},
+	{15, 1}, {14, 1}, {16, 1}, {17, 1}, {19, 1},
+	{18, 1}, {20, 1}, {21, 1}, {23, 1}, {22, 1},
+	{24, 1}, {25, 1}, {27, 1}, {26, 1}, {28, 1},
+	{29, 1}, {31, 1}, {30, 1}, {32, 1}, {33, 1}
+};
+
+unsigned long get_sys_clk(void)
+{
+	unsigned reg;
+	size_t sys_div;
+
+	reg = in_be32(&clkm->scfr[1]);
+	sys_div = (reg & SCFR2_SYS_DIV) >> SCFR2_SYS_DIV_SHIFT;
+	return (get_pll_clk() * sys_dividors[sys_div][1]) / sys_dividors[sys_div][0];
+}
+
+static const unsigned char cpmf_mult[][2] = {
+	{0, 1}, {0, 1}, /* 0 and 1 are not valid */
+	{1, 1}, {3, 2},
+	{2, 1}, {5, 2},
+	{3, 1}, {7, 2},
+	{0, 1}, {0, 1}, /* and all above 7 are not valid too */
+	{0, 1}, {0, 1},
+	{0, 1}, {0, 1},
+	{0, 1}, {0, 1}
+};
+
+unsigned long get_cpu_clk(void)
+{
+	unsigned reg;
+	size_t cpmf;
+
+	reg = in_be32(&clkm->spmr);
+	cpmf = (reg & SPMR_CPMF) >> SPMR_CPMF_SHIFT;
+	return ((get_sys_clk() / 2) * cpmf_mult[cpmf][0]) / cpmf_mult[cpmf][1];
+}
+
+unsigned long get_ips_clock(void)
+{
+	unsigned reg;
+	unsigned long ips_div;
+
+	reg = in_be32(&clkm->scfr[0]);
+	ips_div = (reg & SCFR1_IPS_DIV_MASK) >> SCFR1_IPS_DIV_SHIFT;
+	if (ips_div == 0) {
+		/* in case we cannot get a sane IPS divisor, fail gracefully */
+		pr_debug("IPS clock: invalid divider setting!\n");
+		return 0;
+	}
+
+	return get_sys_clk() / 2 / ips_div;
+}
+
+unsigned long get_psc_clock(unsigned idx)
+{
+	unsigned reg, clk;
+	unsigned long psc_div;
+
+	reg = in_be32(&clkm->pscccr[idx]);
+	if (!(reg & PSCCCR_MCLK_EN))
+		return 0;
+
+	psc_div = (reg & PSCCCR_MCLK_DIV_MASK) >> PSCCCR_MCLK_DIV_SHIFT;
+	if (psc_div == 0) {
+		/* in case we cannot get a sane IPS divisor, fail gracefully */
+		pr_debug("PSC clock: invalid divider setting!\n");
+		return 0;
+	}
+
+	switch (reg & PSCCCR_MCLK_0_SRC_MASK) {
+	case 0x0000:
+		clk = get_ips_clock();
+	case 0x4000:
+		clk = get_timebase_clock();
+	default:
+		pr_debug("PSC clock: unknown source configured: %u\n",
+						reg & PSCCCR_MCLK_0_SRC_MASK);
+		return 0;
+	}
+
+	return clk / (psc_div + 1);
+}
+
+void mpc5125_enable_psc_fifo_clock(void)
+{
+	setbits_be32(&clkm->sccr[0], 0x8000);
+}
+
+void mpc5xxx_enable_psc_clock(unsigned idx)
+{
+	/*
+	 * configure the clock for this unit, it
+	 * should run at full sysclock speed (brute force...)
+	 */
+	out_be32(&clkm->pscccr[idx], PSCCCR_MCLK_EN);
+	/* its now save to enable the clock */
+	setbits_be32(&clkm->sccr[0], 1 << (27 - idx));
+}
+
+void mpc5xxx_enable_fec_clock(unsigned idx)
+{
+	switch (idx) {
+	case 0:
+		setbits_be32(&clkm->sccr[0], SCCR_EN_CLK_FEC1);
+		break;
+	case 1:
+		setbits_be32(&clkm->sccr[0], SCCR_EN_CLK_FEC2);
+		break;
+	default:
+		pr_debug("Enabling clock: unknown FEC index: %u\n", idx);
+	}
+}
+
+static int mpc5125_clks(void)
+{
+	printf("PLL %lu MHz, CPU %lu MHz, Sys %lu MHz, IPS %lu MHz\n",
+		get_pll_clk() / 1000000, get_cpu_clk() / 1000000,
+		get_sys_clk() / 1000000, get_ips_clock() / 1000000);
+
+	return 0;
+}
+postconsole_initcall(mpc5125_clks);
diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index 810a5bb..aadaa3f 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -28,6 +28,7 @@
 
 #include <asm/cache.h>
 #include <asm/mmu.h>
+#include <mach/mpc5xxx.h>
 
 /* We don't want the  MMU yet.
 */
@@ -88,7 +89,9 @@ setup_mbar:
 	lis	r3, CFG_MBAR at h
 	ori	r3, r3, CFG_MBAR at l
 	mtspr	MBAR, r3
+#ifndef CONFIG_ARCH_MPC5125 /* MPC5200 only */
 	rlwinm	r3, r3, 16, 16, 31
+#endif
 	stw	r3, 0(r4)
 
 	/* Initialise the MPC5xxx processor core			*/
@@ -98,7 +101,81 @@ setup_mbar:
 
 	/* initialize some things that are hard to access from C	*/
 	/*--------------------------------------------------------------*/
+#ifdef CONFIG_ARCH_MPC5125
+	lis	r3, CFG_MBAR at h
+	ori	r3, r3, CFG_MBAR at l
+
+	/* enable the LPC based ROM access in the upper address space */
+	lis	r0, CFG_ROM_LOC at h
+	ori	r0, r0, (CFG_ROM_LOC + CFG_ROM_SZ - 1)@h
+	stw	r0, LPCS0AW_OFFSET(r3)
+
+	/* just sync the hardware according to the manual */
+	lwz	r1, LPCS0AW_OFFSET(r3)
+	isync
+
+	/*
+	 * in order to make the CS0 (instead of the BOOTCS) work,
+	 * we must set the LPC master bit first
+	 */
+	lis	r1, MPC512X_IOC at h
+	ori	r1, r1, MPC512X_IOC at l
+	lwz	r0, CS_CR_OFFSET(r1)
+	oris	r0, r0, 0x01000000 at h
+	stw	r0, CS_CR_OFFSET(r1)
+	isync
+
+	/*
+	 * when we still run from lower address space, its now time to jump to
+	 * the just enabled upper address space. We need this step in order
+	 * to move the lower ROM window out of the way.
+	 * (but only, if we not run from RAM)
+	 */
+	bl	1f
+1:	mflr	r0
+	lis	r1, CFG_ROM_LOC at h
+	cmplw	r0, r1
+	bgt	final_destination /* skip if already in upper address space */
+	/*
+	 * to detect if we already running from RAM we just check if the
+	 * BootCS setting is equal to the CS0 setting.
+	 */
+	lwz	r2, LPBAW_OFFSET(r3)
+	lwz	r1, LPCS0AW_OFFSET(r3)
+	cmplw	r1, r2
+	beq	final_destination /* stay in RAM */
+	/*
+	 * Jump into the upper flash memory area
+	 * destination = address of 'final_destination' - TEXT_BASE + CFG_ROM_LOC at h
+	 */
+	lis	r0, (final_destination - TEXT_BASE + CFG_ROM_LOC)@h
+	ori	r0, r0, (final_destination - TEXT_BASE + CFG_ROM_LOC)@l
+	mtlr	r0
+	blr
+
+final_destination:
+	/*
+	 * we are now running from the upper address space from flash or
+	 * from lower address space inside RAM.
+	 * Its save now to move away the flash memory access in the lower
+	 * address space. To do so sync both BOOTCS and CS0 settings.
+	 * For the 'inside RAM' case this should not harm.
+	 */
+	lwz	r1, LPCS0AW_OFFSET(r3)
+	stw	r1, LPBAW_OFFSET(r3)
 
+	/* move NFC out of the way */
+	lis	r0, CFG_NFC_LOC at h
+	stw	r0, NFSCBAR_OFFSET(r3)
+
+	/* move the on-chip SRAM out of the way */
+	lis	r0, CFG_SRAM_LOC at h
+	stw	r0, SRAMBAR_OFFSET(r3)
+
+	/* just sync the hardware according to the manual */
+	lwz	r1, SRAMBAR_OFFSET(r3)
+	isync
+#endif
 	/* set up stack in on-chip SRAM */
 	lis	r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@h
 	ori	r1, r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@l
@@ -116,11 +193,24 @@ setup_mbar:
 	/* r3: IMMR */
 	bl	cpu_init	/* run low-level CPU init code (in Flash)*/
 
+#ifdef CONFIG_ARCH_MPC5125
+	bl	1f
+1:	mflr	r0
+	lis	r9, CFG_ROM_LOC at h
+	cmplw	r0, r9
+	blt	skip_dram_init /* skip if the RAM is already up and running */
 	mr	r3, r21
+#endif
 	/* r3: BOOTFLAG */
 	bl	initdram	/* initialize sdram */
 	/* r3: End of RAM */
 
+#ifdef CONFIG_ARCH_MPC5125
+skip_dram_init:
+	bl	mpc5xxx_get_sdram_size
+	subi	r3,r3,1
+	/* r3: End of RAM */
+#endif
 	b _continue_init
 /*
  * Vector Table
@@ -501,7 +591,14 @@ init_5xxx_core:
 	ori	r3, r3, CFG_HID0_FINAL at l
 	SYNC
 	mtspr	HID0, r3
+#ifdef CONFIG_ARCH_MPC5125
+	lis	r3, CFG_SYS_HID2 at h
+	ori	r3, r3, CFG_SYS_HID2 at l
+	SYNC
+	mtspr	HID2, r3
+	sync
 
+#else
 	/* clear all BAT's						*/
 	/*--------------------------------------------------------------*/
 
@@ -570,7 +667,7 @@ init_5xxx_core:
 
 	/* Done!							*/
 	/*--------------------------------------------------------------*/
-
+#endif
 	blr
 
 /* Cache functions.
diff --git a/arch/ppc/mach-mpc5xxx/sys-mpc5125.c b/arch/ppc/mach-mpc5xxx/sys-mpc5125.c
new file mode 100644
index 0000000..c537669
--- /dev/null
+++ b/arch/ppc/mach-mpc5xxx/sys-mpc5125.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 Juergen Borleis, 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <types.h>
+#include <asm/io.h>
+#include <mach/mpc5xxx.h>
+
+struct law {
+	u32 bar; /* Base Addr Register */
+	u32 ar; /* Attributes Register */
+};
+
+/* System configuration registers for MPC5125 */
+struct sysconf {
+	u32 immrbar;
+	u8 res0[0x1c];
+	u32 lpbaw;
+	u32 lpcsaw[8];
+	u8 res1[0x5c];
+	struct law ddrlaw;
+	u8 res3[0x1c];
+	u32 srambar;
+	u32 nfcbar;
+	u8 res4[0x34];
+	u32 spridr;
+	u32 spcr;
+};
+
+#define MPC512X_SYSCONF_LPCSAW_START(x) (x & 0xffff0000)
+#define MPC512X_SYSCONF_LPCSAW_STOP(x) ((x) >> 16)
+
+#define MPC512X_SPCR_TBEN 0x00400000      /* E300 core time base unit enable */
+
+#define MPC512X_SVR_PART(x) (((x) >> 16) & 0xFFFF) /* Part ID */
+#define MPC512X_SVR_REV(x) (((x) >>  0) & 0xFFFF) /* Revision ID */
+
+/* the MPC512x comes in two revisions. Note: these SoCs are not supported yet */
+#define MPC512x_PART_ID 0x8018
+# define MPC512X_5121E 0x0020
+# define MPC512X_5123 0x0030
+
+/* the MPC5125 comes in one revisions */
+#define MPC5125_PART_ID 0x8019
+# define MPC512X_SPR_5125 0x0010
+
+static struct sysconf * const sysconf = (struct sysconf *)CFG_MBAR;
+
+/*
+ * According to MPC5121e RM, configuring local access windows should
+ * be followed by a dummy read of the config register that was
+ * modified last and an isync.
+ */
+static void sync_law(void *addr)
+{
+        in_be32(addr);
+}
+
+void mpc5125_setup_access_window(unsigned cs, unsigned start, unsigned size)
+{
+	unsigned long long u = start;
+
+	u += size;
+	if (u > 0x100000000) {
+		pr_err("Size for LPC chipselect %d exceeds address space. Limited!\n", cs);
+		size = 0x100000000 - start;
+	}
+
+	out_be32(&sysconf->lpcsaw[cs],
+		MPC512X_SYSCONF_LPCSAW_START(start) |
+		MPC512X_SYSCONF_LPCSAW_STOP(start + size - 1));
+	sync_law(&sysconf->lpcsaw[cs]);
+}
+
+void mpc5125_setup_ram_memory_window(unsigned base, unsigned size)
+{
+	out_be32(&sysconf->ddrlaw.bar, base & 0xFFFFF000);
+	out_be32(&sysconf->ddrlaw.ar, __ilog2(size) - 1);
+	sync_law(&sysconf->ddrlaw.ar);
+}
+
+unsigned mpc5xxx_get_sdram_size(void)
+{
+	return 1 << (in_be32(&sysconf->ddrlaw.ar) + 1);
+}
+
+void mpc5125_enable_time_base_counter(void)
+{
+	setbits_be32(&sysconf->spcr, MPC512X_SPCR_TBEN);
+}
+
+static int mpc5125_check_cpu(void)
+{
+	unsigned svr;
+	unsigned pid, rid;
+
+	svr = in_be32(&sysconf->spridr);
+	pid = MPC512X_SVR_PART(svr);
+	rid = MPC512X_SVR_REV(svr);
+
+	puts("SoC type: ");
+	switch (pid) {
+	case MPC512x_PART_ID:
+		switch (rid) {
+		case MPC512X_5121E:
+			puts("MPC5121e\n");
+			break;
+		case MPC512X_5123:
+			puts ("MPC5123\n");
+			break;
+		default:
+			printf("Unknown MPC512x variant: %x\n", rid);
+		}
+		break;
+	case MPC5125_PART_ID:
+		puts("MPC5125\n");
+		break;
+	default:
+		printf("Unknown MPC51xx part/variant: %x/%x\n", pid, rid);
+	}
+
+	return 0;
+}
+postconsole_initcall(mpc5125_check_cpu);
-- 
2.1.0



From antonynpavlov at gmail.com  Tue Oct  7 08:42:05 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue,  7 Oct 2014 19:42:05 +0400
Subject: [PATCH] clock.c: fix whitespaces
Message-ID: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 common/clock.c | 94 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/common/clock.c b/common/clock.c
index 76ce881..2ee81da 100644
--- a/common/clock.c
+++ b/common/clock.c
@@ -41,25 +41,25 @@ uint64_t time_beginning;
 uint64_t get_time_ns(void)
 {
 	struct clocksource *cs = current_clock;
-        uint64_t cycle_now, cycle_delta;
-        uint64_t ns_offset;
+	uint64_t cycle_now, cycle_delta;
+	uint64_t ns_offset;
 
 	if (!cs)
 		return 0;
 
-        /* read clocksource: */
+	/* read clocksource: */
 	cycle_now = cs->read() & cs->mask;
 
-        /* calculate the delta since the last call: */
-        cycle_delta = (cycle_now - cs->cycle_last) & cs->mask;
+	/* calculate the delta since the last call: */
+	cycle_delta = (cycle_now - cs->cycle_last) & cs->mask;
 
-        /* convert to nanoseconds: */
-        ns_offset = cyc2ns(cs, cycle_delta);
+	/* convert to nanoseconds: */
+	ns_offset = cyc2ns(cs, cycle_delta);
 
 	cs->cycle_last = cycle_now;
 
 	time_ns += ns_offset;
-        return time_ns;
+	return time_ns;
 }
 EXPORT_SYMBOL(get_time_ns);
 
@@ -89,32 +89,32 @@ EXPORT_SYMBOL(get_time_ns);
 
 void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint32_t to, uint32_t maxsec)
 {
-        uint64_t tmp;
-        uint32_t sft, sftacc = 32;
-
-        /*
-         * Calculate the shift factor which is limiting the conversion
-         * range:
-         */
-        tmp = ((uint64_t)maxsec * from) >> 32;
-        while (tmp) {
-                tmp >>=1;
-                sftacc--;
-        }
-
-        /*
-         * Find the conversion shift/mult pair which has the best
-         * accuracy and fits the maxsec conversion range:
-         */
-        for (sft = 32; sft > 0; sft--) {
-                tmp = (uint64_t) to << sft;
-                tmp += from / 2;
-                do_div(tmp, from);
-                if ((tmp >> sftacc) == 0)
-                        break;
-        }
-        *mult = tmp;
-        *shift = sft;
+	uint64_t tmp;
+	uint32_t sft, sftacc = 32;
+
+	/*
+	 * Calculate the shift factor which is limiting the conversion
+	 * range:
+	 */
+	tmp = ((uint64_t)maxsec * from) >> 32;
+	while (tmp) {
+		tmp >>= 1;
+		sftacc--;
+	}
+
+	/*
+	 * Find the conversion shift/mult pair which has the best
+	 * accuracy and fits the maxsec conversion range:
+	 */
+	for (sft = 32; sft > 0; sft--) {
+		tmp = (uint64_t) to << sft;
+		tmp += from / 2;
+		do_div(tmp, from);
+		if ((tmp >> sftacc) == 0)
+			break;
+	}
+	*mult = tmp;
+	*shift = sft;
 }
 
 
@@ -129,19 +129,19 @@ void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint
  */
 uint32_t clocksource_hz2mult(uint32_t hz, uint32_t shift_constant)
 {
-        /*  hz = cyc/(Billion ns)
-         *  mult/2^shift  = ns/cyc
-         *  mult = ns/cyc * 2^shift
-         *  mult = 1Billion/hz * 2^shift
-         *  mult = 1000000000 * 2^shift / hz
-         *  mult = (1000000000<<shift) / hz
-         */
-        uint64_t tmp = ((uint64_t)1000000000) << shift_constant;
-
-        tmp += hz/2; /* round for do_div */
-        do_div(tmp, hz);
-
-        return (uint32_t)tmp;
+	/*  hz = cyc/(Billion ns)
+	 *  mult/2^shift  = ns/cyc
+	 *  mult = ns/cyc * 2^shift
+	 *  mult = 1Billion/hz * 2^shift
+	 *  mult = 1000000000 * 2^shift / hz
+	 *  mult = (1000000000<<shift) / hz
+	 */
+	uint64_t tmp = ((uint64_t)1000000000) << shift_constant;
+
+	tmp += hz/2; /* round for do_div */
+	do_div(tmp, hz);
+
+	return (uint32_t)tmp;
 }
 
 int is_timeout_non_interruptible(uint64_t start_ns, uint64_t time_offset_ns)
-- 
2.1.1



From antonynpavlov at gmail.com  Tue Oct  7 08:42:06 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue,  7 Oct 2014 19:42:06 +0400
Subject: [PATCH] pci: split out device init
In-Reply-To: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
References: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1412696527-3981-2-git-send-email-antonynpavlov@gmail.com>

From: Lucas Stach <dev at lynxeye.de>

To make it reusable and the code more readable.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/pci/pci.c | 137 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 74 insertions(+), 63 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a1b7680..ef998dc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -12,6 +12,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
 LIST_HEAD(pci_root_buses);
 EXPORT_SYMBOL(pci_root_buses);
 static u8 bus_index;
+static resource_size_t last_mem;
+static resource_size_t last_io;
 
 static struct pci_bus *pci_alloc_bus(void)
 {
@@ -45,6 +47,10 @@ void register_pci_controller(struct pci_controller *hose)
 
 	if (hose->set_busno)
 		hose->set_busno(hose, bus->number);
+
+	last_mem = bus->resource[0]->start;
+	last_io = bus->resource[1]->start;
+
 	pci_scan_bus(bus);
 
 	list_add_tail(&bus->node, &pci_root_buses);
@@ -111,27 +117,80 @@ static struct pci_dev *alloc_pci_dev(void)
 	return dev;
 }
 
+static void setup_device(struct pci_dev *dev, int max_bar)
+{
+	int bar, size;
+	u32 mask;
+	u8 cmd;
+
+	pci_read_config_byte(dev, PCI_COMMAND, &cmd);
+	pci_write_config_byte(dev, PCI_COMMAND,
+			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
+	for (bar = 0; bar < max_bar; bar++) {
+		resource_size_t last_addr;
+
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
+		pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
+
+		if (mask == 0 || mask == 0xffffffff) {
+			DBG("  PCI: pbar%d set bad mask\n", bar);
+			continue;
+		}
+
+		if (mask & 0x01) { /* IO */
+			size = -(mask & 0xfffffffe);
+			DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus IO res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
+			dev->resource[bar].flags = IORESOURCE_IO;
+			last_addr = last_io;
+			last_io += size;
+		} else { /* MEM */
+			size = -(mask & 0xfffffff0);
+			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
+			if (last_mem + size > dev->bus->resource[0]->end) {
+				DBG("BAR does not fit within bus mem res\n");
+				return;
+			}
+			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
+			dev->resource[bar].flags = IORESOURCE_MEM;
+			last_addr = last_mem;
+			last_mem += size;
+
+			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
+				dev->resource[bar].flags |= IORESOURCE_MEM_64;
+				pci_write_config_dword(dev,
+				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
+			}
+		}
+
+		dev->resource[bar].start = last_addr;
+		dev->resource[bar].end = last_addr + size - 1;
+		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
+			bar++;
+	}
+
+	pci_write_config_byte(dev, PCI_COMMAND, cmd);
+	list_add_tail(&dev->bus_list, &dev->bus->devices);
+	pci_register_device(dev);
+}
+
 unsigned int pci_scan_bus(struct pci_bus *bus)
 {
+	struct pci_dev *dev;
 	unsigned int devfn, l, max, class;
 	unsigned char cmd, tmp, hdr_type, is_multi = 0;
-	struct pci_dev *dev;
-	resource_size_t last_mem;
-	resource_size_t last_io;
-
-	/* FIXME: use res_start() */
-	last_mem = bus->resource[0]->start;
-	last_io = bus->resource[1]->start;
 
 	DBG("pci_scan_bus for bus %d\n", bus->number);
 	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
 	max = bus->secondary;
 
 	for (devfn = 0; devfn < 0xff; ++devfn) {
-		int bar;
-		u32 old_bar, mask;
-		int size;
-
 		if (PCI_FUNC(devfn) && !is_multi) {
 			/* not a multi-function device */
 			continue;
@@ -169,6 +228,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 		dev->hdr_type = hdr_type;
 
 		DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
+		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
+		    dev->vendor, dev->device);
 
 		switch (hdr_type & 0x7f) {		    /* header type */
 		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
@@ -181,6 +242,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			 */
 			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
 			dev->rom_address = (l == 0xffffffff) ? 0 : l;
+
+			setup_device(dev, 6);
 			break;
 		default:				    /* unknown header */
 		bad:
@@ -189,62 +252,10 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
 			continue;
 		}
 
-		DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
-
 		if (class == PCI_CLASS_BRIDGE_HOST) {
 			DBG("PCI: skip pci host bridge\n");
 			continue;
 		}
-
-		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
-		pci_write_config_byte(dev, PCI_COMMAND,
-				      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-
-		for (bar = 0; bar < 6; bar++) {
-			resource_size_t last_addr;
-
-			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &old_bar);
-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
-			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
-			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, old_bar);
-
-			if (mask == 0 || mask == 0xffffffff) {
-				DBG("  PCI: pbar%d set bad mask\n", bar);
-				continue;
-			}
-
-			if (mask & 0x01) { /* IO */
-				size = -(mask & 0xfffffffe);
-				DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
-				dev->resource[bar].flags = IORESOURCE_IO;
-				last_addr = last_io;
-				last_io += size;
-			} else { /* MEM */
-				size = -(mask & 0xfffffff0);
-				DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
-				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
-				dev->resource[bar].flags = IORESOURCE_MEM;
-				last_addr = last_mem;
-				last_mem += size;
-
-				if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
-				    PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					dev->resource[bar].flags |= IORESOURCE_MEM_64;
-					pci_write_config_dword(dev,
-					       PCI_BASE_ADDRESS_1 + bar * 4, 0);
-				}
-			}
-
-			dev->resource[bar].start = last_addr;
-			dev->resource[bar].end = last_addr + size - 1;
-			if (dev->resource[bar].flags & IORESOURCE_MEM_64)
-				bar++;
-		}
-
-		pci_write_config_byte(dev, PCI_COMMAND, cmd);
-		list_add_tail(&dev->bus_list, &bus->devices);
-		pci_register_device(dev);
 	}
 
 	/*
-- 
2.1.1



From antonynpavlov at gmail.com  Tue Oct  7 08:42:07 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue,  7 Oct 2014 19:42:07 +0400
Subject: [PATCH] clock.c: fix whitespaces
In-Reply-To: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
References: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1412696527-3981-3-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 common/clock.c | 94 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 47 insertions(+), 47 deletions(-)

diff --git a/common/clock.c b/common/clock.c
index 76ce881..2ee81da 100644
--- a/common/clock.c
+++ b/common/clock.c
@@ -41,25 +41,25 @@ uint64_t time_beginning;
 uint64_t get_time_ns(void)
 {
 	struct clocksource *cs = current_clock;
-        uint64_t cycle_now, cycle_delta;
-        uint64_t ns_offset;
+	uint64_t cycle_now, cycle_delta;
+	uint64_t ns_offset;
 
 	if (!cs)
 		return 0;
 
-        /* read clocksource: */
+	/* read clocksource: */
 	cycle_now = cs->read() & cs->mask;
 
-        /* calculate the delta since the last call: */
-        cycle_delta = (cycle_now - cs->cycle_last) & cs->mask;
+	/* calculate the delta since the last call: */
+	cycle_delta = (cycle_now - cs->cycle_last) & cs->mask;
 
-        /* convert to nanoseconds: */
-        ns_offset = cyc2ns(cs, cycle_delta);
+	/* convert to nanoseconds: */
+	ns_offset = cyc2ns(cs, cycle_delta);
 
 	cs->cycle_last = cycle_now;
 
 	time_ns += ns_offset;
-        return time_ns;
+	return time_ns;
 }
 EXPORT_SYMBOL(get_time_ns);
 
@@ -89,32 +89,32 @@ EXPORT_SYMBOL(get_time_ns);
 
 void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint32_t to, uint32_t maxsec)
 {
-        uint64_t tmp;
-        uint32_t sft, sftacc = 32;
-
-        /*
-         * Calculate the shift factor which is limiting the conversion
-         * range:
-         */
-        tmp = ((uint64_t)maxsec * from) >> 32;
-        while (tmp) {
-                tmp >>=1;
-                sftacc--;
-        }
-
-        /*
-         * Find the conversion shift/mult pair which has the best
-         * accuracy and fits the maxsec conversion range:
-         */
-        for (sft = 32; sft > 0; sft--) {
-                tmp = (uint64_t) to << sft;
-                tmp += from / 2;
-                do_div(tmp, from);
-                if ((tmp >> sftacc) == 0)
-                        break;
-        }
-        *mult = tmp;
-        *shift = sft;
+	uint64_t tmp;
+	uint32_t sft, sftacc = 32;
+
+	/*
+	 * Calculate the shift factor which is limiting the conversion
+	 * range:
+	 */
+	tmp = ((uint64_t)maxsec * from) >> 32;
+	while (tmp) {
+		tmp >>= 1;
+		sftacc--;
+	}
+
+	/*
+	 * Find the conversion shift/mult pair which has the best
+	 * accuracy and fits the maxsec conversion range:
+	 */
+	for (sft = 32; sft > 0; sft--) {
+		tmp = (uint64_t) to << sft;
+		tmp += from / 2;
+		do_div(tmp, from);
+		if ((tmp >> sftacc) == 0)
+			break;
+	}
+	*mult = tmp;
+	*shift = sft;
 }
 
 
@@ -129,19 +129,19 @@ void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint
  */
 uint32_t clocksource_hz2mult(uint32_t hz, uint32_t shift_constant)
 {
-        /*  hz = cyc/(Billion ns)
-         *  mult/2^shift  = ns/cyc
-         *  mult = ns/cyc * 2^shift
-         *  mult = 1Billion/hz * 2^shift
-         *  mult = 1000000000 * 2^shift / hz
-         *  mult = (1000000000<<shift) / hz
-         */
-        uint64_t tmp = ((uint64_t)1000000000) << shift_constant;
-
-        tmp += hz/2; /* round for do_div */
-        do_div(tmp, hz);
-
-        return (uint32_t)tmp;
+	/*  hz = cyc/(Billion ns)
+	 *  mult/2^shift  = ns/cyc
+	 *  mult = ns/cyc * 2^shift
+	 *  mult = 1Billion/hz * 2^shift
+	 *  mult = 1000000000 * 2^shift / hz
+	 *  mult = (1000000000<<shift) / hz
+	 */
+	uint64_t tmp = ((uint64_t)1000000000) << shift_constant;
+
+	tmp += hz/2; /* round for do_div */
+	do_div(tmp, hz);
+
+	return (uint32_t)tmp;
 }
 
 int is_timeout_non_interruptible(uint64_t start_ns, uint64_t time_offset_ns)
-- 
2.1.1



From antonynpavlov at gmail.com  Tue Oct  7 08:45:42 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 7 Oct 2014 19:45:42 +0400
Subject: [PATCH] pci: split out device init
In-Reply-To: <1412696527-3981-2-git-send-email-antonynpavlov@gmail.com>
References: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
 <1412696527-3981-2-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20141007194542.51a7baf6e0abec1d3e165ac2@gmail.com>

On Tue,  7 Oct 2014 19:42:06 +0400
Antony Pavlov <antonynpavlov at gmail.com> wrote:

Please ignore this message.

Sorry!

> From: Lucas Stach <dev at lynxeye.de>
> 
> To make it reusable and the code more readable.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>
> ---
>  drivers/pci/pci.c | 137 +++++++++++++++++++++++++++++-------------------------
>  1 file changed, 74 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index a1b7680..ef998dc 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -12,6 +12,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
>  LIST_HEAD(pci_root_buses);
>  EXPORT_SYMBOL(pci_root_buses);
>  static u8 bus_index;
> +static resource_size_t last_mem;
> +static resource_size_t last_io;
>  
>  static struct pci_bus *pci_alloc_bus(void)
>  {
> @@ -45,6 +47,10 @@ void register_pci_controller(struct pci_controller *hose)
>  
>  	if (hose->set_busno)
>  		hose->set_busno(hose, bus->number);
> +
> +	last_mem = bus->resource[0]->start;
> +	last_io = bus->resource[1]->start;
> +
>  	pci_scan_bus(bus);
>  
>  	list_add_tail(&bus->node, &pci_root_buses);
> @@ -111,27 +117,80 @@ static struct pci_dev *alloc_pci_dev(void)
>  	return dev;
>  }
>  
> +static void setup_device(struct pci_dev *dev, int max_bar)
> +{
> +	int bar, size;
> +	u32 mask;
> +	u8 cmd;
> +
> +	pci_read_config_byte(dev, PCI_COMMAND, &cmd);
> +	pci_write_config_byte(dev, PCI_COMMAND,
> +			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
> +
> +	for (bar = 0; bar < max_bar; bar++) {
> +		resource_size_t last_addr;
> +
> +		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
> +		pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
> +
> +		if (mask == 0 || mask == 0xffffffff) {
> +			DBG("  PCI: pbar%d set bad mask\n", bar);
> +			continue;
> +		}
> +
> +		if (mask & 0x01) { /* IO */
> +			size = -(mask & 0xfffffffe);
> +			DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
> +			if (last_mem + size > dev->bus->resource[0]->end) {
> +				DBG("BAR does not fit within bus IO res\n");
> +				return;
> +			}
> +			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
> +			dev->resource[bar].flags = IORESOURCE_IO;
> +			last_addr = last_io;
> +			last_io += size;
> +		} else { /* MEM */
> +			size = -(mask & 0xfffffff0);
> +			DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
> +			if (last_mem + size > dev->bus->resource[0]->end) {
> +				DBG("BAR does not fit within bus mem res\n");
> +				return;
> +			}
> +			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
> +			dev->resource[bar].flags = IORESOURCE_MEM;
> +			last_addr = last_mem;
> +			last_mem += size;
> +
> +			if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
> +			    PCI_BASE_ADDRESS_MEM_TYPE_64) {
> +				dev->resource[bar].flags |= IORESOURCE_MEM_64;
> +				pci_write_config_dword(dev,
> +				       PCI_BASE_ADDRESS_1 + bar * 4, 0);
> +			}
> +		}
> +
> +		dev->resource[bar].start = last_addr;
> +		dev->resource[bar].end = last_addr + size - 1;
> +		if (dev->resource[bar].flags & IORESOURCE_MEM_64)
> +			bar++;
> +	}
> +
> +	pci_write_config_byte(dev, PCI_COMMAND, cmd);
> +	list_add_tail(&dev->bus_list, &dev->bus->devices);
> +	pci_register_device(dev);
> +}
> +
>  unsigned int pci_scan_bus(struct pci_bus *bus)
>  {
> +	struct pci_dev *dev;
>  	unsigned int devfn, l, max, class;
>  	unsigned char cmd, tmp, hdr_type, is_multi = 0;
> -	struct pci_dev *dev;
> -	resource_size_t last_mem;
> -	resource_size_t last_io;
> -
> -	/* FIXME: use res_start() */
> -	last_mem = bus->resource[0]->start;
> -	last_io = bus->resource[1]->start;
>  
>  	DBG("pci_scan_bus for bus %d\n", bus->number);
>  	DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
>  	max = bus->secondary;
>  
>  	for (devfn = 0; devfn < 0xff; ++devfn) {
> -		int bar;
> -		u32 old_bar, mask;
> -		int size;
> -
>  		if (PCI_FUNC(devfn) && !is_multi) {
>  			/* not a multi-function device */
>  			continue;
> @@ -169,6 +228,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
>  		dev->hdr_type = hdr_type;
>  
>  		DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
> +		DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
> +		    dev->vendor, dev->device);
>  
>  		switch (hdr_type & 0x7f) {		    /* header type */
>  		case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
> @@ -181,6 +242,8 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
>  			 */
>  			pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
>  			dev->rom_address = (l == 0xffffffff) ? 0 : l;
> +
> +			setup_device(dev, 6);
>  			break;
>  		default:				    /* unknown header */
>  		bad:
> @@ -189,62 +252,10 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
>  			continue;
>  		}
>  
> -		DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
> -
>  		if (class == PCI_CLASS_BRIDGE_HOST) {
>  			DBG("PCI: skip pci host bridge\n");
>  			continue;
>  		}
> -
> -		pci_read_config_byte(dev, PCI_COMMAND, &cmd);
> -		pci_write_config_byte(dev, PCI_COMMAND,
> -				      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
> -
> -		for (bar = 0; bar < 6; bar++) {
> -			resource_size_t last_addr;
> -
> -			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &old_bar);
> -			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
> -			pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
> -			pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, old_bar);
> -
> -			if (mask == 0 || mask == 0xffffffff) {
> -				DBG("  PCI: pbar%d set bad mask\n", bar);
> -				continue;
> -			}
> -
> -			if (mask & 0x01) { /* IO */
> -				size = -(mask & 0xfffffffe);
> -				DBG("  PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
> -				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
> -				dev->resource[bar].flags = IORESOURCE_IO;
> -				last_addr = last_io;
> -				last_io += size;
> -			} else { /* MEM */
> -				size = -(mask & 0xfffffff0);
> -				DBG("  PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
> -				pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
> -				dev->resource[bar].flags = IORESOURCE_MEM;
> -				last_addr = last_mem;
> -				last_mem += size;
> -
> -				if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
> -				    PCI_BASE_ADDRESS_MEM_TYPE_64) {
> -					dev->resource[bar].flags |= IORESOURCE_MEM_64;
> -					pci_write_config_dword(dev,
> -					       PCI_BASE_ADDRESS_1 + bar * 4, 0);
> -				}
> -			}
> -
> -			dev->resource[bar].start = last_addr;
> -			dev->resource[bar].end = last_addr + size - 1;
> -			if (dev->resource[bar].flags & IORESOURCE_MEM_64)
> -				bar++;
> -		}
> -
> -		pci_write_config_byte(dev, PCI_COMMAND, cmd);
> -		list_add_tail(&dev->bus_list, &bus->devices);
> -		pci_register_device(dev);
>  	}
>  
>  	/*
> -- 
> 2.1.1
> 


-- 
--?
Best regards,
? Antony Pavlov


From u74147 at gmail.com  Tue Oct  7 22:41:03 2014
From: u74147 at gmail.com (Kevin Du Huanpeng)
Date: Wed, 8 Oct 2014 13:41:03 +0800
Subject: No subject
Message-ID: <CANvTkNYb_zj62mcuzTcY5WOiTU07HnSqkiz851wswY0eN59euw@mail.gmail.com>

Hi,
I find that most xxx_defconfig stop linking when console support set
to CONSOLE_NONE
compile log like:
http://paste.ubuntu.com/8518456/

- - - -
  | Symbol: CONSOLE_NONE [=y]                                               |
  | Type  : boolean                                                         |
  | Prompt: none                                                            |
  |   Location:                                                             |
  |     -> General Settings                                                 |
  |       -> console support (<choice> [=y])                                |
  |   Defined at common/Kconfig:522                                         |
  |   Depends on: <choice>                                                  |

- - - -

most error causes by pr_print undefined.

this macro/function is
defined in:
common/console_common.c
declare in:
include/printk.h

when CONSOLE_NONE is defined,
pr_print is not compiled (rid by #ifndef/#endif) with common/console_common.o
but <printk.h> is included allmost anywhere by including <common.h>
- - - -
#ifndef __COMMON_H_
#define __COMMON_H_     1

#include <stdio.h>
...
#include <asm/common.h>
#include <printk.h>
- - - -
so using pr_print always can past compile because it is declared by
including <common.h>.
but breaks link.

I am confusing with CONSOLE_NONE, what is it mean?
1. the board don't have a console?
        is the board still can have a serial port, but not accepts input?
2. where should the debug messages go?
        the serial port is not a console but
        when CONSOLE_NONE defined, printf just a nothing but return a 0,
        but the pr_print() declared but not defined.
- - - -
FILE: include/stdio.h
static inline int printf(const char *fmt, ...)
{
        return 0;
}
- - - -


- - - -
duhuanpeng
(+86)13719074147


From u74147 at gmail.com  Tue Oct  7 22:42:36 2014
From: u74147 at gmail.com (Kevin Du Huanpeng)
Date: Wed, 8 Oct 2014 13:42:36 +0800
Subject: most xxx_defconfig stop linking when console support set to
 CONSOLE_NONE
Message-ID: <CANvTkNYwuCuGQMY40VC=dJxzW8rhBjDA_HE_Mb8AuV9iep7sYw@mail.gmail.com>

Hi,
I find that most xxx_defconfig stop linking when console support set
to CONSOLE_NONE
compile log like:
http://paste.ubuntu.com/8518456/

- - - -
  | Symbol: CONSOLE_NONE [=y]                                               |
  | Type  : boolean                                                         |
  | Prompt: none                                                            |
  |   Location:                                                             |
  |     -> General Settings                                                 |
  |       -> console support (<choice> [=y])                                |
  |   Defined at common/Kconfig:522                                         |
  |   Depends on: <choice>                                                  |

- - - -

most error causes by pr_print undefined.

this macro/function is
defined in:
common/console_common.c
declare in:
include/printk.h

when CONSOLE_NONE is defined,
pr_print is not compiled (rid by #ifndef/#endif) with common/console_common.o
but <printk.h> is included allmost anywhere by including <common.h>
- - - -
#ifndef __COMMON_H_
#define __COMMON_H_     1

#include <stdio.h>
...
#include <asm/common.h>
#include <printk.h>
- - - -
so using pr_print always can past compile because it is declared by
including <common.h>.
but breaks link.

I am confusing with CONSOLE_NONE, what is it mean?
1. the board don't have a console?
        is the board still can have a serial port, but not accepts input?
2. where should the debug messages go?
        the serial port is not a console but
        when CONSOLE_NONE defined, printf just a nothing but return a 0,
        but the pr_print() declared but not defined.
- - - -
FILE: include/stdio.h
static inline int printf(const char *fmt, ...)
{
        return 0;
}
- - - -


- - - -
duhuanpeng
(+86)13719074147


From s.hauer at pengutronix.de  Tue Oct  7 23:08:29 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 8 Oct 2014 08:08:29 +0200
Subject: most xxx_defconfig stop linking when console support set to
 CONSOLE_NONE
In-Reply-To: <CANvTkNYwuCuGQMY40VC=dJxzW8rhBjDA_HE_Mb8AuV9iep7sYw@mail.gmail.com>
References: <CANvTkNYwuCuGQMY40VC=dJxzW8rhBjDA_HE_Mb8AuV9iep7sYw@mail.gmail.com>
Message-ID: <20141008060829.GU4992@pengutronix.de>

Hi Kevin,

On Wed, Oct 08, 2014 at 01:42:36PM +0800, Kevin Du Huanpeng wrote:
> 
> I am confusing with CONSOLE_NONE, what is it mean?
> 1. the board don't have a console?
>         is the board still can have a serial port, but not accepts input?
> 2. where should the debug messages go?
>         the serial port is not a console but
>         when CONSOLE_NONE defined, printf just a nothing but return a 0,
>         but the pr_print() declared but not defined.

CONSOLE_NONE is for boards which a) Don't have anything usable for
console or b) have a console but you want to build a quiet,
non-interactive barebox. The idea is to drop all the strings from the
binary to make it smaller.It seems noone ever used CONSOLE_NONE, so it
bitrotted. The following patch fixes this.

Sascha

----------------------------8<---------------------------

>From fbb191fd416de27148bc977c320e07c95b4ca36c Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer at pengutronix.de>
Date: Wed, 8 Oct 2014 08:05:44 +0200
Subject: [PATCH] console: Fix CONSOLE_NONE support

Without console support we need a static inline version of
pr_print and dev_printf, otherwise we get link errors.

Reported-by: Kevin Du Huanpeng <u74147 at gmail.com>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/printk.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/printk.h b/include/printk.h
index fb63586..22c6c73 100644
--- a/include/printk.h
+++ b/include/printk.h
@@ -21,11 +21,23 @@
 
 /* debugging and troubleshooting/diagnostic helpers. */
 
+#ifndef CONFIG_CONSOLE_NONE
 int pr_print(int level, const char *format, ...)
 	__attribute__ ((format(__printf__, 2, 3)));
 
 int dev_printf(int level, const struct device_d *dev, const char *format, ...)
 	__attribute__ ((format(__printf__, 3, 4)));
+#else
+static inline int pr_print(int level, const char *format, ...)
+{
+	return 0;
+}
+
+static inline int dev_printf(int level, const struct device_d *dev, const char *format, ...)
+{
+	return 0;
+}
+#endif
 
 #define __dev_printf(level, dev, format, args...) \
 	({	\
-- 
2.1.0


-- 
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 Oct  7 23:11:49 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 08:11:49 +0200
Subject: [PATCH] input: Let input support depend on !CONSOLE_NONE
Message-ID: <1412748709-26556-1-git-send-email-s.hauer@pengutronix.de>

Without console support the input devices make no sense, so add
a depends on !CONSOLE_NONE.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/input/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 07545ed..b4e86fd 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -3,6 +3,7 @@
 #
 
 menu "Input device support"
+	depends on !CONSOLE_NONE
 
 config KEYBOARD_GPIO
 	bool "GPIO Buttons"
-- 
2.1.0



From s.hauer at pengutronix.de  Tue Oct  7 23:37:30 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 8 Oct 2014 08:37:30 +0200
Subject: [PATCH 1/2] ARM: tegra30: add environment path to Beaver DT
In-Reply-To: <1412537983-5337-1-git-send-email-dev@lynxeye.de>
References: <1412537983-5337-1-git-send-email-dev@lynxeye.de>
Message-ID: <20141008063730.GX4992@pengutronix.de>

On Sun, Oct 05, 2014 at 09:39:42PM +0200, Lucas Stach wrote:
> Signed-off-by: Lucas Stach <dev at lynxeye.de>
> ---
>  arch/arm/dts/tegra30-beaver.dts | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)

Applied both, thanks

Sascha

> 
> diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts
> index 35b4d7e..94955f9 100644
> --- a/arch/arm/dts/tegra30-beaver.dts
> +++ b/arch/arm/dts/tegra30-beaver.dts
> @@ -11,6 +11,13 @@
>  		rtc1 = "/rtc at 7000e000";
>  	};
>  
> +	chosen {
> +		environment at 0 {
> +			compatible = "barebox,environment";
> +			device-path = &emmc, "partname:boot1";
> +		};
> +	};
> +
>  	memory {
>  		reg = <0x80000000 0x7ff00000>;
>  	};
> @@ -750,7 +757,7 @@
>  		bus-width = <4>;
>  	};
>  
> -	sdhci at 78000600 {
> +	emmc: sdhci at 78000600 {
>  		status = "okay";
>  		bus-width = <8>;
>  		non-removable;
> -- 
> 1.9.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 s.hauer at pengutronix.de  Tue Oct  7 23:39:29 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 8 Oct 2014 08:39:29 +0200
Subject: [PATCH v2 00/19] PCI and Tegra series revamp
In-Reply-To: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
References: <1412444425-2569-1-git-send-email-dev@lynxeye.de>
Message-ID: <20141008063929.GY4992@pengutronix.de>

On Sat, Oct 04, 2014 at 07:40:06PM +0200, Lucas Stach wrote:
> Ok, I got around to work a bit more on this. I now
> actually finished the rtl8169 network driver, so
> this series yields working PCI attached ethernet
> on Tegra30 Beaver.
> 
> For Jetson K1 some work is left to setup the PHYs, but
> that shouldn't be far out. 
> 
> While working on this I stumbled upon a few more issues,
> so I decided to just roll the fixes into this series
> and resend.
> 
> Lucas Stach (19):
>   MIPS: malta: fix pci IO resource assignment
>   pci: split out device init
>   pci: add resource enum
>   pci: properly populate prefetchable BARs
>   pci: setup bridges and traverse buses behind them
>   pci: defer device registration until after bridge setup
>   pci: prettyprint device names
>   pci: track parent<->child relationship
>   commands: lspci: go down into subordinate busses
>   clk: tegra: add PLLE setup functions
>   clk: tegra30: add PCIe clocks
>   i2c: tegra: move to fs initcall
>   ARM: tegra: beaver: enable PEX voltage rail
>   tegra: pmc: add powerdomain handling
>   of: import pci range parser from linux
>   pci: add Tegra host controller driver
>   ARM: tegra: advertise PCI support
>   net: add rtl8169 driver
>   ARM: tegra: enable network related options in defconfig

Applied, thanks

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 Oct  8 02:11:49 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 8 Oct 2014 11:11:49 +0200
Subject: [PATCH 0/4] Add phyFLEX-AM335x support
In-Reply-To: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
References: <1412671237-46551-1-git-send-email-t.gamez@phytec.de>
Message-ID: <20141008091149.GD4992@pengutronix.de>

On Tue, Oct 07, 2014 at 10:40:33AM +0200, Teresa G?mez wrote:
> This patchset adds phyFLEX-AM335x support. This is
> based on Jan's work and was rewitten for device
> tree and multi image support by Stefan. I cleaned up the
> code and rebased it to master.
> 
> Teresa
> 
> Jan Weitzel (2):
>   net: cpsw: Allow gigabit connection
>   net: micrel: Add ksz8081 support
> 
> Stefan M?ller-Klieser (2):
>   boards: Add phytec-phyflex-am335x
>   pfla03: add to am335x_defconfig

Applied, thanks

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 Oct  8 02:13:38 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 8 Oct 2014 11:13:38 +0200
Subject: [PATCH] clock.c: fix whitespaces
In-Reply-To: <1412696527-3981-3-git-send-email-antonynpavlov@gmail.com>
References: <1412696527-3981-1-git-send-email-antonynpavlov@gmail.com>
 <1412696527-3981-3-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20141008091338.GE4992@pengutronix.de>

On Tue, Oct 07, 2014 at 07:42:07PM +0400, Antony Pavlov wrote:
> Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
> ---
>  common/clock.c | 94 +++++++++++++++++++++++++++++-----------------------------
>  1 file changed, 47 insertions(+), 47 deletions(-)

Applied, thanks

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 Oct  8 07:03:58 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:03:58 +0200
Subject: [PATCH 2/5] ARM: nitrogen6x: update 1066MHz 4x128M16 timing from
 U-Boot
In-Reply-To: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
References: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412777041-23714-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg   | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
index 4aa7ec7..c5a286b 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
@@ -1,5 +1,18 @@
+/*
+ * Copyright (C) 2013 Boundary Devices
+ *
+ * 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.
+ */
+
 wm 32 MX6_MMDC_P0_MDPDC			0x00020036
-wm 32 MX6_MMDC_P0_MDSCR			0x00008000
 wm 32 MX6_MMDC_P0_MDCFG0		0x555A7974
 wm 32 MX6_MMDC_P0_MDCFG1		0xDB538F64
 wm 32 MX6_MMDC_P0_MDCFG2		0x01FF00DB
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:03:59 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:03:59 +0200
Subject: [PATCH 3/5] ARM: nitrogen6x: Fix Duallite RAM Timing
In-Reply-To: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
References: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412777041-23714-3-git-send-email-s.hauer@pengutronix.de>

The i.MX6DL only supports up to 800MHz RAM timing, so add the corresponding
file from U-Boot and use it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../800mhz_4x128mx16.imxcfg                        | 50 ++++++++++++++++++++++
 .../flash-header-nitrogen6dl-1g.imxcfg             |  2 +-
 2 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x128mx16.imxcfg

diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x128mx16.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x128mx16.imxcfg
new file mode 100644
index 0000000..936a2f5
--- /dev/null
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x128mx16.imxcfg
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Boundary Devices
+ *
+ * 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.
+ */
+
+wm 32 MX6_MMDC_P0_MDPDC 0x0002002D
+wm 32 MX6_MMDC_P0_MDCFG0 0x40435323
+wm 32 MX6_MMDC_P0_MDCFG1 0xB66E8D63
+wm 32 MX6_MMDC_P0_MDCFG2 0x01FF00DB
+wm 32 MX6_MMDC_P0_MDRWD 0x000026D2
+wm 32 MX6_MMDC_P0_MDOR 0x00431023
+wm 32 MX6_MMDC_P0_MDOTC 0x00333030
+wm 32 MX6_MMDC_P0_MDPDC 0x0002556D
+wm 32 MX6_MMDC_P0_MDASP 0x00000027
+wm 32 MX6_MMDC_P0_MDCTL 0x831A0000
+wm 32 MX6_MMDC_P0_MDSCR 0x04008032
+wm 32 MX6_MMDC_P0_MDSCR 0x00008033
+wm 32 MX6_MMDC_P0_MDSCR 0x00048031
+wm 32 MX6_MMDC_P0_MDSCR 0x13208030
+wm 32 MX6_MMDC_P0_MDSCR 0x04008040
+wm 32 MX6_MMDC_P0_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P1_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P0_MDREF 0x00005800
+wm 32 MX6_MMDC_P0_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P1_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P0_MPDGCTRL0 0x420F020F
+wm 32 MX6_MMDC_P0_MPDGCTRL1 0x01760175
+wm 32 MX6_MMDC_P1_MPDGCTRL0 0x41640171
+wm 32 MX6_MMDC_P1_MPDGCTRL1 0x015E0160
+wm 32 MX6_MMDC_P0_MPRDDLCTL 0x45464B4A
+wm 32 MX6_MMDC_P1_MPRDDLCTL 0x49484A46
+wm 32 MX6_MMDC_P0_MPWRDLCTL 0x40402E32
+wm 32 MX6_MMDC_P1_MPWRDLCTL 0x3A3A3231
+wm 32 MX6_MMDC_P0_MPWLDECTRL0 0x003A003A
+wm 32 MX6_MMDC_P0_MPWLDECTRL1 0x0030002F
+wm 32 MX6_MMDC_P1_MPWLDECTRL0 0x002F0038
+wm 32 MX6_MMDC_P1_MPWLDECTRL1 0x00270039
+wm 32 MX6_MMDC_P0_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P1_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P0_MDSCR 0x00000000
+wm 32 MX6_MMDC_P0_MAPSR 0x00011006
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
index 76fad11..d077a65 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
@@ -7,5 +7,5 @@ dcdofs 0x400
 #include <mach/imx6-ccm-regs.h>
 
 #include "ram-base.imxcfg"
-#include "1066mhz_4x128mx16.imxcfg"
+#include "800mhz_4x128mx16.imxcfg"
 #include "clocks.imxcfg"
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:03:57 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:03:57 +0200
Subject: [PATCH 1/5] ARM: nitrogen6x: whitespace cleanup
Message-ID: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>

Align hex values under each other.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg      | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
index 8175cfe..4aa7ec7 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x128mx16.imxcfg
@@ -14,8 +14,8 @@ wm 32 MX6_MMDC_P0_MDSCR			0x00008033
 wm 32 MX6_MMDC_P0_MDSCR			0x00428031
 wm 32 MX6_MMDC_P0_MDSCR			0x19308030
 wm 32 MX6_MMDC_P0_MDSCR			0x04008040
-wm 32 MX6_MMDC_P0_MPZQHWCTRL	0xA1390003
-wm 32 MX6_MMDC_P1_MPZQHWCTRL	0xA1390003
+wm 32 MX6_MMDC_P0_MPZQHWCTRL		0xA1390003
+wm 32 MX6_MMDC_P1_MPZQHWCTRL		0xA1390003
 wm 32 MX6_MMDC_P0_MDREF			0x00005800
 wm 32 MX6_MMDC_P0_MPODTCTRL		0x00022227
 wm 32 MX6_MMDC_P1_MPODTCTRL		0x00022227
@@ -27,10 +27,10 @@ wm 32 MX6_MMDC_P0_MPRDDLCTL		0x45393B3E
 wm 32 MX6_MMDC_P1_MPRDDLCTL		0x403A3747
 wm 32 MX6_MMDC_P0_MPWRDLCTL		0x40434541
 wm 32 MX6_MMDC_P1_MPWRDLCTL		0x473E4A3B
-wm 32 MX6_MMDC_P0_MPWLDECTRL0	0x0011000E
-wm 32 MX6_MMDC_P0_MPWLDECTRL1	0x000E001B
-wm 32 MX6_MMDC_P1_MPWLDECTRL0	0x00190015
-wm 32 MX6_MMDC_P1_MPWLDECTRL1	0x00070018
+wm 32 MX6_MMDC_P0_MPWLDECTRL0		0x0011000E
+wm 32 MX6_MMDC_P0_MPWLDECTRL1		0x000E001B
+wm 32 MX6_MMDC_P1_MPWLDECTRL0		0x00190015
+wm 32 MX6_MMDC_P1_MPWLDECTRL1		0x00070018
 wm 32 MX6_MMDC_P0_MPMUR0		0x00000800
 wm 32 MX6_MMDC_P1_MPMUR0		0x00000800
 wm 32 MX6_MMDC_P0_MDSCR			0x00000000
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:04:01 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:04:01 +0200
Subject: [PATCH 5/5] ARM: nitrogen6x: remove clock gate manipulation from DCD
In-Reply-To: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
References: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412777041-23714-5-git-send-email-s.hauer@pengutronix.de>

The clock driver will ungate all clocks anyway during startup, so
manipulating them in the DCD has no effect.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/boundarydevices-nitrogen6x/clocks.imxcfg           | 7 -------
 .../boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg  | 1 -
 .../boundarydevices-nitrogen6x/flash-header-nitrogen6q-1g.imxcfg   | 1 -
 3 files changed, 9 deletions(-)
 delete mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/clocks.imxcfg

diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/clocks.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/clocks.imxcfg
deleted file mode 100644
index 55adb60..0000000
--- a/arch/arm/boards/boundarydevices-nitrogen6x/clocks.imxcfg
+++ /dev/null
@@ -1,7 +0,0 @@
-wm 32 MX6_CCM_CCGR0		0x00C03F3F
-wm 32 MX6_CCM_CCGR1		0x0030FC03
-wm 32 MX6_CCM_CCGR2		0x0FFFC000
-wm 32 MX6_CCM_CCGR3		0x3FF00000
-wm 32 MX6_CCM_CCGR4		0x00FFF300
-wm 32 MX6_CCM_CCGR5		0x0F0000C3
-wm 32 MX6_CCM_CCGR6		0x000003FF
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
index d077a65..0773f4d 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
@@ -8,4 +8,3 @@ dcdofs 0x400
 
 #include "ram-base.imxcfg"
 #include "800mhz_4x128mx16.imxcfg"
-#include "clocks.imxcfg"
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-1g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-1g.imxcfg
index ee3145b..bd4134f 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-1g.imxcfg
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-1g.imxcfg
@@ -8,4 +8,3 @@ dcdofs 0x400
 
 #include "ram-base.imxcfg"
 #include "1066mhz_4x128mx16.imxcfg"
-#include "clocks.imxcfg"
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:04:00 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:04:00 +0200
Subject: [PATCH 4/5] ARM: nitrogen6x: Add support for 2GB board variants
In-Reply-To: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
References: <1412777041-23714-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412777041-23714-4-git-send-email-s.hauer@pengutronix.de>

The nitrogen6x have variants with 2GB SDRAM. Add support for them. The
imxcfg files are from U-Boot.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../1066mhz_4x256mx16.imxcfg                       | 50 ++++++++++++++++++++++
 .../800mhz_4x256mx16.imxcfg                        | 50 ++++++++++++++++++++++
 .../flash-header-nitrogen6dl-2g.imxcfg             | 10 +++++
 .../flash-header-nitrogen6q-2g.imxcfg              | 10 +++++
 .../boards/boundarydevices-nitrogen6x/lowlevel.c   | 22 ++++++++++
 images/Makefile.imx                                | 10 +++++
 6 files changed, 152 insertions(+)
 create mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x256mx16.imxcfg
 create mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x256mx16.imxcfg
 create mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-2g.imxcfg
 create mode 100644 arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-2g.imxcfg

diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x256mx16.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x256mx16.imxcfg
new file mode 100644
index 0000000..4d8a715
--- /dev/null
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/1066mhz_4x256mx16.imxcfg
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Boundary Devices
+ *
+ * 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.
+ */
+
+wm 32 MX6_MMDC_P0_MDPDC 0x00020036
+wm 32 MX6_MMDC_P0_MDCFG0 0x898E7974
+wm 32 MX6_MMDC_P0_MDCFG1 0xDB538F64
+wm 32 MX6_MMDC_P0_MDCFG2 0x01FF00DB
+wm 32 MX6_MMDC_P0_MDRWD 0x000026D2
+wm 32 MX6_MMDC_P0_MDOR 0x008E1023
+wm 32 MX6_MMDC_P0_MDOTC 0x09444040
+wm 32 MX6_MMDC_P0_MDPDC 0x00025576
+wm 32 MX6_MMDC_P0_MDASP 0x00000047
+wm 32 MX6_MMDC_P0_MDCTL 0x841A0000
+wm 32 MX6_MMDC_P0_MDSCR 0x04088032
+wm 32 MX6_MMDC_P0_MDSCR 0x00008033
+wm 32 MX6_MMDC_P0_MDSCR 0x00428031
+wm 32 MX6_MMDC_P0_MDSCR 0x19308030
+wm 32 MX6_MMDC_P0_MDSCR 0x04008040
+wm 32 MX6_MMDC_P0_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P1_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P0_MDREF 0x00007800
+wm 32 MX6_MMDC_P0_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P1_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P0_MPDGCTRL0 0x43040319
+wm 32 MX6_MMDC_P0_MPDGCTRL1 0x03040279
+wm 32 MX6_MMDC_P1_MPDGCTRL0 0x43040321
+wm 32 MX6_MMDC_P1_MPDGCTRL1 0x03030251
+wm 32 MX6_MMDC_P0_MPRDDLCTL 0x4d434248
+wm 32 MX6_MMDC_P1_MPRDDLCTL 0x42413c4d
+wm 32 MX6_MMDC_P0_MPWRDLCTL 0x34424543
+wm 32 MX6_MMDC_P1_MPWRDLCTL 0x49324933
+wm 32 MX6_MMDC_P0_MPWLDECTRL0 0x001a0017
+wm 32 MX6_MMDC_P0_MPWLDECTRL1 0x001F001F
+wm 32 MX6_MMDC_P1_MPWLDECTRL0 0x00170027
+wm 32 MX6_MMDC_P1_MPWLDECTRL1 0x000a001f
+wm 32 MX6_MMDC_P0_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P1_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P0_MDSCR 0x00000000
+wm 32 MX6_MMDC_P0_MAPSR 0x00011006
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x256mx16.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x256mx16.imxcfg
new file mode 100644
index 0000000..09c8555
--- /dev/null
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/800mhz_4x256mx16.imxcfg
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Boundary Devices
+ *
+ * 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.
+ */
+
+wm 32 MX6_MMDC_P0_MDPDC 0x0002002D
+wm 32 MX6_MMDC_P0_MDCFG0 0x696C5323
+wm 32 MX6_MMDC_P0_MDCFG1 0xB66E8D63
+wm 32 MX6_MMDC_P0_MDCFG2 0x01FF00DB
+wm 32 MX6_MMDC_P0_MDRWD 0x000026D2
+wm 32 MX6_MMDC_P0_MDOR 0x006C1023
+wm 32 MX6_MMDC_P0_MDOTC 0x00333030
+wm 32 MX6_MMDC_P0_MDPDC 0x0002556D
+wm 32 MX6_MMDC_P0_MDASP 0x00000047
+wm 32 MX6_MMDC_P0_MDCTL 0x841A0000
+wm 32 MX6_MMDC_P0_MDSCR 0x04008032
+wm 32 MX6_MMDC_P0_MDSCR 0x00008033
+wm 32 MX6_MMDC_P0_MDSCR 0x00048031
+wm 32 MX6_MMDC_P0_MDSCR 0x13208030
+wm 32 MX6_MMDC_P0_MDSCR 0x04008040
+wm 32 MX6_MMDC_P0_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P1_MPZQHWCTRL 0xA1390003
+wm 32 MX6_MMDC_P0_MDREF 0x00007800
+wm 32 MX6_MMDC_P0_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P1_MPODTCTRL 0x00022227
+wm 32 MX6_MMDC_P0_MPDGCTRL0 0x42350231
+wm 32 MX6_MMDC_P0_MPDGCTRL1 0x021A0218
+wm 32 MX6_MMDC_P1_MPDGCTRL0 0x42350231
+wm 32 MX6_MMDC_P1_MPDGCTRL1 0x021A0218
+wm 32 MX6_MMDC_P0_MPRDDLCTL 0x4B4B4E49
+wm 32 MX6_MMDC_P1_MPRDDLCTL 0x4B4B4E49
+wm 32 MX6_MMDC_P0_MPWRDLCTL 0x3F3F3035
+wm 32 MX6_MMDC_P1_MPWRDLCTL 0x3F3F3035
+wm 32 MX6_MMDC_P0_MPWLDECTRL0 0x0040003C
+wm 32 MX6_MMDC_P0_MPWLDECTRL1 0x0032003E
+wm 32 MX6_MMDC_P1_MPWLDECTRL0 0x0040003C
+wm 32 MX6_MMDC_P1_MPWLDECTRL1 0x0032003E
+wm 32 MX6_MMDC_P0_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P1_MPMUR0 0x00000800
+wm 32 MX6_MMDC_P0_MDSCR 0x00000000
+wm 32 MX6_MMDC_P0_MAPSR 0x00011006
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-2g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-2g.imxcfg
new file mode 100644
index 0000000..6622c51
--- /dev/null
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-2g.imxcfg
@@ -0,0 +1,10 @@
+soc imx6
+loadaddr 0x20000000
+dcdofs 0x400
+
+#include <mach/imx6-ddr-regs.h>
+#include <mach/imx6dl-ddr-regs.h>
+#include <mach/imx6-ccm-regs.h>
+
+#include "ram-base.imxcfg"
+#include "800mhz_4x256mx16.imxcfg"
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-2g.imxcfg b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-2g.imxcfg
new file mode 100644
index 0000000..89aa21c
--- /dev/null
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/flash-header-nitrogen6q-2g.imxcfg
@@ -0,0 +1,10 @@
+soc imx6
+loadaddr 0x20000000
+dcdofs 0x400
+
+#include <mach/imx6-ddr-regs.h>
+#include <mach/imx6q-ddr-regs.h>
+#include <mach/imx6-ccm-regs.h>
+
+#include "ram-base.imxcfg"
+#include "1066mhz_4x256mx16.imxcfg"
diff --git a/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c b/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c
index 5371be6..a32e29c 100644
--- a/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c
+++ b/arch/arm/boards/boundarydevices-nitrogen6x/lowlevel.c
@@ -17,6 +17,17 @@ ENTRY_FUNCTION(start_imx6q_nitrogen6x_1g, r0, r1, r2)
 	barebox_arm_entry(0x10000000, SZ_1G, fdt);
 }
 
+ENTRY_FUNCTION(start_imx6q_nitrogen6x_2g, r0, r1, r2)
+{
+	void *fdt;
+
+	imx6_cpu_lowlevel_init();
+
+	fdt = __dtb_imx6q_nitrogen6x_start - get_runtime_offset();
+
+	barebox_arm_entry(0x10000000, SZ_2G, fdt);
+}
+
 extern char __dtb_imx6dl_nitrogen6x_start[];
 
 ENTRY_FUNCTION(start_imx6dl_nitrogen6x_1g, r0, r1, r2)
@@ -29,3 +40,14 @@ ENTRY_FUNCTION(start_imx6dl_nitrogen6x_1g, r0, r1, r2)
 
 	barebox_arm_entry(0x10000000, SZ_1G, fdt);
 }
+
+ENTRY_FUNCTION(start_imx6dl_nitrogen6x_2g, r0, r1, r2)
+{
+	void *fdt;
+
+	imx6_cpu_lowlevel_init();
+
+	fdt = __dtb_imx6dl_nitrogen6x_start - get_runtime_offset();
+
+	barebox_arm_entry(0x10000000, SZ_2G, fdt);
+}
diff --git a/images/Makefile.imx b/images/Makefile.imx
index b6ca6c2..23a3d66 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -155,11 +155,21 @@ CFG_start_imx6q_nitrogen6x_1g.pblx.imximg = $(board)/boundarydevices-nitrogen6x/
 FILE_barebox-boundarydevices-imx6q-nitrogen6x-1g.img = start_imx6q_nitrogen6x_1g.pblx.imximg
 image-$(CONFIG_MACH_NITROGEN6X) += barebox-boundarydevices-imx6q-nitrogen6x-1g.img
 
+pblx-$(CONFIG_MACH_NITROGEN6X) += start_imx6q_nitrogen6x_2g
+CFG_start_imx6q_nitrogen6x_2g.pblx.imximg = $(board)/boundarydevices-nitrogen6x/flash-header-nitrogen6q-2g.imxcfg
+FILE_barebox-boundarydevices-imx6q-nitrogen6x-2g.img = start_imx6q_nitrogen6x_2g.pblx.imximg
+image-$(CONFIG_MACH_NITROGEN6X) += barebox-boundarydevices-imx6q-nitrogen6x-2g.img
+
 pblx-$(CONFIG_MACH_NITROGEN6X) += start_imx6dl_nitrogen6x_1g
 CFG_start_imx6dl_nitrogen6x_1g.pblx.imximg = $(board)/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-1g.imxcfg
 FILE_barebox-boundarydevices-imx6dl-nitrogen6x-1g.img = start_imx6dl_nitrogen6x_1g.pblx.imximg
 image-$(CONFIG_MACH_NITROGEN6X) += barebox-boundarydevices-imx6dl-nitrogen6x-1g.img
 
+pblx-$(CONFIG_MACH_NITROGEN6X) += start_imx6dl_nitrogen6x_2g
+CFG_start_imx6dl_nitrogen6x_2g.pblx.imximg = $(board)/boundarydevices-nitrogen6x/flash-header-nitrogen6dl-2g.imxcfg
+FILE_barebox-boundarydevices-imx6dl-nitrogen6x-2g.img = start_imx6dl_nitrogen6x_2g.pblx.imximg
+image-$(CONFIG_MACH_NITROGEN6X) += barebox-boundarydevices-imx6dl-nitrogen6x-2g.img
+
 pblx-$(CONFIG_MACH_TX6X) += start_imx6dl_tx6x_1g
 CFG_start_imx6dl_tx6x_1g.pblx.imximg = $(board)/karo-tx6x/flash-header-tx6dl-1g.imxcfg
 FILE_barebox-karo-imx6dl-tx6x-1g.img = start_imx6dl_tx6x_1g.pblx.imximg
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:05:03 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:05:03 +0200
Subject: [PATCH 1/2] led: trigger: use max_value to turn on led instead of
 hardcoded '1'
Message-ID: <1412777104-19569-1-git-send-email-s.hauer@pengutronix.de>

For PWM LEDs '1' may be really dark. Use max_value instead.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/led-triggers.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/led/led-triggers.c b/drivers/led/led-triggers.c
index c5484d5..adcb9e0 100644
--- a/drivers/led/led-triggers.c
+++ b/drivers/led/led-triggers.c
@@ -90,13 +90,13 @@ void led_trigger(enum led_trigger trigger, enum trigger_type type)
 
 	if (type == TRIGGER_FLASH) {
 		if (is_timeout(triggers[trigger].flash_start, 400 * MSECOND)) {
-			led_set(triggers[trigger].led, 1);
+			led_set(triggers[trigger].led, triggers[trigger].led->max_value);
 			triggers[trigger].flash_start = get_time_ns();
 		}
 		return;
 	}
 
-	led_set(triggers[trigger].led, type == TRIGGER_ENABLE ? 1 : 0);
+	led_set(triggers[trigger].led, type == TRIGGER_ENABLE ? triggers[trigger].led->max_value : 0);
 }
 
 /**
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:05:04 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:05:04 +0200
Subject: [PATCH 2/2] led: trigger: Turn of flashing leds only once
In-Reply-To: <1412777104-19569-1-git-send-email-s.hauer@pengutronix.de>
References: <1412777104-19569-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412777104-19569-2-git-send-email-s.hauer@pengutronix.de>

The current code continuously turns leds off. Preserve the current
led status so that we only turn it off once.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/led/led-triggers.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/led/led-triggers.c b/drivers/led/led-triggers.c
index adcb9e0..dee9367 100644
--- a/drivers/led/led-triggers.c
+++ b/drivers/led/led-triggers.c
@@ -49,6 +49,7 @@
 struct led_trigger_struct {
 	struct led *led;
 	uint64_t flash_start;
+	int flash;
 };
 
 static struct led_trigger_struct triggers[LED_TRIGGER_MAX];
@@ -59,9 +60,10 @@ static void trigger_func(struct poller_struct *poller)
 
 	for (i = 0; i < LED_TRIGGER_MAX; i++) {
 		if (triggers[i].led &&
-		    triggers[i].flash_start &&
+		    triggers[i].flash &&
 		    is_timeout(triggers[i].flash_start, 200 * MSECOND)) {
 			led_set(triggers[i].led, 0);
+			triggers[i].flash = 0;
 		}
 	}
 
@@ -92,6 +94,7 @@ void led_trigger(enum led_trigger trigger, enum trigger_type type)
 		if (is_timeout(triggers[trigger].flash_start, 400 * MSECOND)) {
 			led_set(triggers[trigger].led, triggers[trigger].led->max_value);
 			triggers[trigger].flash_start = get_time_ns();
+			triggers[trigger].flash = 1;
 		}
 		return;
 	}
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:13 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:13 +0200
Subject: [PATCH 4/6] fs: implement fstat
In-Reply-To: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412778255-4153-4-git-send-email-s.hauer@pengutronix.de>

fstat is useful to get information about an already opened file. Add
it to barebox.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/fs.c      | 16 ++++++++++++++++
 include/fs.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/fs/fs.c b/fs/fs.c
index 436f5cb..ffdfa2c 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1472,6 +1472,22 @@ out:
 }
 EXPORT_SYMBOL(lstat);
 
+int fstat(int fd, struct stat *s)
+{
+	FILE *f;
+	struct fs_device_d *fsdev;
+
+	if (check_fd(fd))
+		return -errno;
+
+	f = &files[fd];
+
+	fsdev = f->fsdev;
+
+	return fsdev->driver->stat(&fsdev->dev, f->path, s);
+}
+EXPORT_SYMBOL(fstat);
+
 int mkdir (const char *pathname, mode_t mode)
 {
 	struct fs_driver_d *fsdrv;
diff --git a/include/fs.h b/include/fs.h
index 6eddb23..63e35ca 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -114,6 +114,7 @@ int close(int fd);
 int flush(int fd);
 int lstat(const char *filename, struct stat *s);
 int stat(const char *filename, struct stat *s);
+int fstat(int fd, struct stat *s);
 ssize_t read(int fd, void *buf, size_t count);
 ssize_t pread(int fd, void *buf, size_t count, loff_t offset);
 int ioctl(int fd, int request, void *buf);
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:11 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:11 +0200
Subject: [PATCH 2/6] fs: do not lookup global FILE * when the file is already
 available
In-Reply-To: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412778255-4153-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/fs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fs.c b/fs/fs.c
index 014a36a..04b6408 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -251,7 +251,7 @@ static FILE *get_file(void)
 
 static void put_file(FILE *f)
 {
-	files[f->no].in_use = 0;
+	f->in_use = 0;
 }
 
 static int check_fd(int fd)
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:12 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:12 +0200
Subject: [PATCH 3/6] fs: Store the path in struct filep
In-Reply-To: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412778255-4153-3-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/fs.c      | 5 +++++
 include/fs.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/fs/fs.c b/fs/fs.c
index 04b6408..436f5cb 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -251,6 +251,8 @@ static FILE *get_file(void)
 
 static void put_file(FILE *f)
 {
+	free(f->path);
+	f->path = NULL;
 	f->in_use = 0;
 }
 
@@ -670,6 +672,9 @@ int open(const char *pathname, int flags, ...)
 		if (ret)
 			goto out;
 	}
+
+	f->path = xstrdup(path);
+
 	ret = fsdrv->open(&fsdev->dev, f, path);
 	if (ret)
 		goto out;
diff --git a/include/fs.h b/include/fs.h
index c3ce81a..6eddb23 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -24,6 +24,7 @@ typedef struct dir {
 
 typedef struct filep {
 	struct fs_device_d *fsdev; /* The device this FILE belongs to              */
+	char *path;
 	loff_t pos;            /* current position in stream                   */
 #define FILE_SIZE_STREAM	((loff_t) -1)
 	loff_t size;           /* The size of this inode                       */
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:15 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:15 +0200
Subject: [PATCH 6/6] commands: implement 'diff' command
In-Reply-To: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412778255-4153-6-git-send-email-s.hauer@pengutronix.de>

This command compares two files. It does not show the differences,
it only returns successfully if both files are identical and with
an error if they differ.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/Kconfig  | 10 ++++++++++
 commands/Makefile |  1 +
 commands/diff.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 commands/diff.c

diff --git a/commands/Kconfig b/commands/Kconfig
index d73a393..05d5426 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -811,6 +811,16 @@ config CMD_CP
 	  Options:
 		  -v	verbose
 
+config CMD_DIFF
+	tristate
+	prompt "diff"
+	help
+	  compare two files
+
+	  Usage: diff FILE1 FILE2
+
+	  Returns successfully if the two files are the same, return with an error if not
+
 config CMD_DIRNAME
 	tristate
 	prompt "dirname"
diff --git a/commands/Makefile b/commands/Makefile
index b1cdf33..e53bdde 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -106,3 +106,4 @@ obj-$(CONFIG_CMD_IMD)		+= imd.o
 obj-$(CONFIG_CMD_HWCLOCK)	+= hwclock.o
 obj-$(CONFIG_CMD_USBGADGET)	+= usbgadget.o
 obj-$(CONFIG_CMD_FIRMWARELOAD)	+= firmwareload.o
+obj-$(CONFIG_CMD_DIFF)		+= diff.o
diff --git a/commands/diff.c b/commands/diff.c
new file mode 100644
index 0000000..26eaf88
--- /dev/null
+++ b/commands/diff.c
@@ -0,0 +1,42 @@
+/*
+ * diff - determine if two files differ
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+#include <libfile.h>
+
+static int do_diff(int argc, char *argv[])
+{
+	if (argc != 3)
+		return COMMAND_ERROR_USAGE;
+
+	return diff_file(argv[1], argv[2]);
+}
+
+BAREBOX_CMD_HELP_START(diff)
+BAREBOX_CMD_HELP_TEXT("Returns successfully if the two files are the same, return with an error if not")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(diff)
+	.cmd		= do_diff,
+	BAREBOX_CMD_DESC("compare two files")
+	BAREBOX_CMD_OPTS("FILE1 FILE2")
+	BAREBOX_CMD_GROUP(CMD_GRP_FILE)
+	BAREBOX_CMD_HELP(cmd_diff_help)
+BAREBOX_CMD_END
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:14 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:14 +0200
Subject: [PATCH 5/6] libfile: add diff_file function
In-Reply-To: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412778255-4153-5-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/libfile.h |  2 ++
 lib/libfile.c     | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/include/libfile.h b/include/libfile.h
index 4a25a91..315adb2 100644
--- a/include/libfile.h
+++ b/include/libfile.h
@@ -15,4 +15,6 @@ int write_file(const char *filename, void *buf, size_t size);
 
 int copy_file(const char *src, const char *dst, int verbose);
 
+int diff_file(const char *f1, const char *f2);
+
 #endif /* __LIBFILE_H */
diff --git a/lib/libfile.c b/lib/libfile.c
index c626e2f..1d773e3 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -331,3 +331,74 @@ out:
 	return ret;
 }
 EXPORT_SYMBOL(copy_file);
+
+/**
+ * diff_file - Compare two files
+ * @f1:		The first file
+ * @f2:		The second file
+ *
+ * Return: 0 if both files are identical, 1 if they differ,
+ *         a negative error code if some error occured
+ */
+int diff_file(const char *f1, const char *f2)
+{
+	int fd1, fd2, ret;
+	struct stat s1, s2;
+	void *buf1, *buf2;
+	loff_t left;
+
+	fd1 = open(f1, O_RDONLY);
+	if (fd1 < 0)
+		return -errno;
+
+	fd2 = open(f2, O_RDONLY);
+	if (fd2 < 0) {
+		ret = -errno;
+		goto err_out1;
+	}
+
+	ret = fstat(fd1, &s1);
+	if (ret)
+		goto err_out2;
+
+	ret = fstat(fd2, &s2);
+	if (ret)
+		goto err_out2;
+
+	if (s1.st_size != s2.st_size)
+		return 1;
+
+	buf1 = xmalloc(RW_BUF_SIZE);
+	buf2 = xmalloc(RW_BUF_SIZE);
+
+	left = s1.st_size;
+	while (left) {
+		loff_t now = min(left, (loff_t)RW_BUF_SIZE);
+
+		ret = read_full(fd1, buf1, now);
+		if (ret < 0)
+			goto err_out3;
+
+		ret = read_full(fd2, buf2, now);
+		if (ret < 0)
+			goto err_out3;
+
+		if (memcmp(buf1, buf2, now)) {
+			ret = 1;
+			goto err_out3;
+		}
+
+		left -= now;
+	}
+
+	ret = 0;
+
+err_out3:
+	free(buf1);
+	free(buf2);
+err_out2:
+	close(fd2);
+err_out1:
+	close(fd1);
+	return ret;
+}
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:24:10 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:24:10 +0200
Subject: [PATCH 1/6] fs: store pointer to fsdev instead of dev in struct filep
Message-ID: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>

The struct device_d * in struct filep is never of interest, instead
it is always converted to a struct fs_device_d *, so simplify the code
by storing the struct fs_device_d * directly.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/devfs.c   |  4 ++--
 fs/fs.c      | 75 ++++++++++++++++++++++--------------------------------------
 include/fs.h |  3 +--
 3 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/fs/devfs.c b/fs/devfs.c
index f089c6f..872e19b 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -168,9 +168,9 @@ static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
 
 static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
 {
-	if (f->dev->num_resources < 1)
+	if (f->fsdev->dev.num_resources < 1)
 		return -ENOSPC;
-	if (size > resource_size(&f->dev->resource[0]))
+	if (size > resource_size(&f->fsdev->dev.resource[0]))
 		return -ENOSPC;
 	return 0;
 }
diff --git a/fs/fs.c b/fs/fs.c
index fd3d353..014a36a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -653,7 +653,7 @@ int open(const char *pathname, int flags, ...)
 
 	fsdrv = fsdev->driver;
 
-	f->dev = &fsdev->dev;
+	f->fsdev = fsdev;
 	f->flags = flags;
 
 	if ((flags & O_ACCMODE) && !fsdrv->write) {
@@ -705,7 +705,6 @@ EXPORT_SYMBOL(creat);
 
 int ioctl(int fd, int request, void *buf)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	int ret;
@@ -714,12 +713,11 @@ int ioctl(int fd, int request, void *buf)
 		return -errno;
 
 	f = &files[fd];
-	dev = f->dev;
 
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 
 	if (fsdrv->ioctl)
-		ret = fsdrv->ioctl(dev, f, request, buf);
+		ret = fsdrv->ioctl(&f->fsdev->dev, f, request, buf);
 	else
 		ret = -ENOSYS;
 	if (ret)
@@ -729,13 +727,10 @@ int ioctl(int fd, int request, void *buf)
 
 static ssize_t __read(FILE *f, void *buf, size_t count)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	int ret;
 
-	dev = f->dev;
-
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 
 	if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size)
 		count = f->size - f->pos;
@@ -743,7 +738,7 @@ static ssize_t __read(FILE *f, void *buf, size_t count)
 	if (!count)
 		return 0;
 
-	ret = fsdrv->read(dev, f, buf, count);
+	ret = fsdrv->read(&f->fsdev->dev, f, buf, count);
 
 	if (ret < 0)
 		errno = -ret;
@@ -790,15 +785,12 @@ EXPORT_SYMBOL(read);
 
 static ssize_t __write(FILE *f, const void *buf, size_t count)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	int ret;
 
-	dev = f->dev;
-
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 	if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size) {
-		ret = fsdrv->truncate(dev, f, f->pos + count);
+		ret = fsdrv->truncate(&f->fsdev->dev, f, f->pos + count);
 		if (ret) {
 			if (ret != -ENOSPC)
 				goto out;
@@ -809,7 +801,7 @@ static ssize_t __write(FILE *f, const void *buf, size_t count)
 			f->size = f->pos + count;
 		}
 	}
-	ret = fsdrv->write(dev, f, buf, count);
+	ret = fsdrv->write(&f->fsdev->dev, f, buf, count);
 out:
 	if (ret < 0)
 		errno = -ret;
@@ -856,7 +848,6 @@ EXPORT_SYMBOL(write);
 
 int flush(int fd)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	int ret;
@@ -865,11 +856,10 @@ int flush(int fd)
 		return -errno;
 
 	f = &files[fd];
-	dev = f->dev;
 
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 	if (fsdrv->flush)
-		ret = fsdrv->flush(dev, f);
+		ret = fsdrv->flush(&f->fsdev->dev, f);
 	else
 		ret = 0;
 
@@ -881,7 +871,6 @@ int flush(int fd)
 
 loff_t lseek(int fildes, loff_t offset, int whence)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	loff_t pos;
@@ -891,8 +880,7 @@ loff_t lseek(int fildes, loff_t offset, int whence)
 		return -1;
 
 	f = &files[fildes];
-	dev = f->dev;
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 	if (!fsdrv->lseek) {
 		ret = -ENOSYS;
 		goto out;
@@ -920,7 +908,7 @@ loff_t lseek(int fildes, loff_t offset, int whence)
 		goto out;
 	}
 
-	return fsdrv->lseek(dev, f, pos);
+	return fsdrv->lseek(&f->fsdev->dev, f, pos);
 
 out:
 	if (ret)
@@ -932,7 +920,6 @@ EXPORT_SYMBOL(lseek);
 
 int erase(int fd, size_t count, unsigned long offset)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	int ret;
@@ -945,10 +932,9 @@ int erase(int fd, size_t count, unsigned long offset)
 	if (count > f->size - offset)
 		count = f->size - offset;
 
-	dev = f->dev;
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 	if (fsdrv->erase)
-		ret = fsdrv->erase(dev, f, count, offset);
+		ret = fsdrv->erase(&f->fsdev->dev, f, count, offset);
 	else
 		ret = -ENOSYS;
 
@@ -961,7 +947,6 @@ EXPORT_SYMBOL(erase);
 
 int protect(int fd, size_t count, unsigned long offset, int prot)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	int ret;
@@ -974,10 +959,9 @@ int protect(int fd, size_t count, unsigned long offset, int prot)
 	if (count > f->size - offset)
 		count = f->size - offset;
 
-	dev = f->dev;
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 	if (fsdrv->protect)
-		ret = fsdrv->protect(dev, f, count, offset, prot);
+		ret = fsdrv->protect(&f->fsdev->dev, f, count, offset, prot);
 	else
 		ret = -ENOSYS;
 
@@ -1005,7 +989,6 @@ int protect_file(const char *file, int prot)
 
 void *memmap(int fd, int flags)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	void *retp = (void *)-1;
@@ -1015,12 +998,11 @@ void *memmap(int fd, int flags)
 		return retp;
 
 	f = &files[fd];
-	dev = f->dev;
 
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = f->fsdev->driver;
 
 	if (fsdrv->memmap)
-		ret = fsdrv->memmap(dev, f, &retp, flags);
+		ret = fsdrv->memmap(&f->fsdev->dev, f, &retp, flags);
 	else
 		ret = -EINVAL;
 
@@ -1033,7 +1015,6 @@ EXPORT_SYMBOL(memmap);
 
 int close(int fd)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	FILE *f;
 	int ret;
@@ -1042,10 +1023,9 @@ int close(int fd)
 		return -errno;
 
 	f = &files[fd];
-	dev = f->dev;
 
-	fsdrv = dev_to_fs_driver(dev);
-	ret = fsdrv->close(dev, f);
+	fsdrv = f->fsdev->driver;
+	ret = fsdrv->close(&f->fsdev->dev, f);
 
 	put_file(f);
 
@@ -1152,7 +1132,8 @@ static int fs_match(struct device_d *dev, struct driver_d *drv)
 static int fs_probe(struct device_d *dev)
 {
 	struct fs_device_d *fsdev = dev_to_fs_device(dev);
-	struct fs_driver_d *fsdrv = dev_to_fs_driver(dev);
+	struct driver_d *drv = dev->driver;
+	struct fs_driver_d *fsdrv = container_of(drv, struct fs_driver_d, drv);
 	int ret;
 
 	ret = dev->driver->probe(dev);
@@ -1449,7 +1430,6 @@ EXPORT_SYMBOL(stat);
 
 int lstat(const char *filename, struct stat *s)
 {
-	struct device_d *dev;
 	struct fs_driver_d *fsdrv;
 	struct fs_device_d *fsdev;
 	char *f = normalise_path(filename);
@@ -1466,18 +1446,17 @@ int lstat(const char *filename, struct stat *s)
 		goto out;
 	}
 
-	if (fsdev != fs_dev_root && strcmp(f, fsdev->path)) {
+	if (fsdev != fs_dev_root && strcmp(f, fsdev->path))
 		f += strlen(fsdev->path);
-		dev = &fsdev->dev;
-	} else
-		dev = &fs_dev_root->dev;
+	else
+		fsdev = fs_dev_root;
 
-	fsdrv = dev_to_fs_driver(dev);
+	fsdrv = fsdev->driver;
 
 	if (*f == 0)
 		f = "/";
 
-	ret = fsdrv->stat(dev, f, s);
+	ret = fsdrv->stat(&fsdev->dev, f, s);
 out:
 	free(freep);
 
diff --git a/include/fs.h b/include/fs.h
index b2541a4..c3ce81a 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -23,7 +23,7 @@ typedef struct dir {
 } DIR;
 
 typedef struct filep {
-	struct device_d *dev; /* The device this FILE belongs to              */
+	struct fs_device_d *fsdev; /* The device this FILE belongs to              */
 	loff_t pos;            /* current position in stream                   */
 #define FILE_SIZE_STREAM	((loff_t) -1)
 	loff_t size;           /* The size of this inode                       */
@@ -82,7 +82,6 @@ struct fs_driver_d {
 	unsigned long flags;
 };
 
-#define dev_to_fs_driver(d) container_of(d->driver, struct fs_driver_d, drv)
 #define dev_to_fs_device(d) container_of(d, struct fs_device_d, dev)
 
 extern struct list_head fs_device_list;
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:34:52 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:34:52 +0200
Subject: [PATCH] param: let dev_add_param return the newly created param
Message-ID: <1412778892-22976-1-git-send-email-s.hauer@pengutronix.de>

dev_add_param creates a new parameter so it makes more sense to
return it than to return an error code. Since the return value
is hardly ever checked this is only a small patch.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/globalvar.c | 7 ++++++-
 include/param.h    | 4 ++--
 lib/parameter.c    | 8 +++++---
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/common/globalvar.c b/common/globalvar.c
index 1f9b0cc..c72f147 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -17,7 +17,12 @@ int globalvar_add(const char *name,
 		const char *(*get)(struct device_d *, struct param_d *p),
 		unsigned long flags)
 {
-	return dev_add_param(&global_device, name, set, get, flags);
+	struct param_d *param;
+
+	param = dev_add_param(&global_device, name, set, get, flags);
+	if (IS_ERR(param))
+		return PTR_ERR(param);
+	return 0;
 }
 
 /*
diff --git a/include/param.h b/include/param.h
index 9856a2e..b8dd9b1 100644
--- a/include/param.h
+++ b/include/param.h
@@ -26,7 +26,7 @@ const char *dev_get_param(struct device_d *dev, const char *name);
 int dev_set_param(struct device_d *dev, const char *name, const char *val);
 struct param_d *get_param_by_name(struct device_d *dev, const char *name);
 
-int dev_add_param(struct device_d *dev, const char *name,
+struct param_d *dev_add_param(struct device_d *dev, const char *name,
 		int (*set)(struct device_d *dev, struct param_d *p, const char *val),
 		const char *(*get)(struct device_d *, struct param_d *p),
 		unsigned long flags);
@@ -92,7 +92,7 @@ static inline struct param_d *get_param_by_name(struct device_d *dev,
 	return NULL;
 }
 
-static inline int dev_add_param(struct device_d *dev, char *name,
+static inline struct param_d *dev_add_param(struct device_d *dev, char *name,
 		int (*set)(struct device_d *dev, struct param_d *p, const char *val),
 		const char *(*get)(struct device_d *, struct param_d *p),
 		unsigned long flags)
diff --git a/lib/parameter.c b/lib/parameter.c
index 84a632c..d6f8d16 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -160,7 +160,7 @@ static int __dev_add_param(struct param_d *param, struct device_d *dev, const ch
  * expect the parameter value to be a string which can be freed with free(). Do
  * not use static arrays when using the generic functions.
  */
-int dev_add_param(struct device_d *dev, const char *name,
+struct param_d *dev_add_param(struct device_d *dev, const char *name,
 		int (*set)(struct device_d *dev, struct param_d *p, const char *val),
 		const char *(*get)(struct device_d *dev, struct param_d *param),
 		unsigned long flags)
@@ -171,10 +171,12 @@ int dev_add_param(struct device_d *dev, const char *name,
 	param = xzalloc(sizeof(*param));
 
 	ret = __dev_add_param(param, dev, name, set, get, flags);
-	if (ret)
+	if (ret) {
 		free(param);
+		return ERR_PTR(ret);
+	}
 
-	return ret;
+	return param;
 }
 
 /**
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:46:44 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:46:44 +0200
Subject: [PATCH 3/4] firmware: altera_serial: gpio_set_value returns void
In-Reply-To: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
References: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412779605-25460-3-git-send-email-s.hauer@pengutronix.de>

So do not try to check the return value.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/firmware/altera_serial.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/firmware/altera_serial.c b/drivers/firmware/altera_serial.c
index 23ba3b0..232f1a6 100644
--- a/drivers/firmware/altera_serial.c
+++ b/drivers/firmware/altera_serial.c
@@ -81,9 +81,7 @@ static int altera_spi_open(struct firmware_handler *fh)
 	}
 
 	/* arm the FPGA to await its new firmware */
-	ret = gpio_set_value(this->nconfig_gpio, 1);
-	if (ret)
-		return ret;
+	gpio_set_value(this->nconfig_gpio, 1);
 
 	/* once again, we might need padding the data */
 	this->padding_done = false;
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:46:42 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:46:42 +0200
Subject: [PATCH 1/4] firmware: Add missing include
Message-ID: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/firmware.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/firmware.c b/common/firmware.c
index 2a62a81..a6f75bf 100644
--- a/common/firmware.c
+++ b/common/firmware.c
@@ -17,6 +17,7 @@
 #include <xfuncs.h>
 #include <fcntl.h>
 #include <libbb.h>
+#include <libfile.h>
 #include <fs.h>
 #include <linux/list.h>
 #include <linux/stat.h>
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:46:45 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:46:45 +0200
Subject: [PATCH 4/4] firmware: altera_serial: fix dev_dbg format
In-Reply-To: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
References: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412779605-25460-4-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/firmware/altera_serial.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/altera_serial.c b/drivers/firmware/altera_serial.c
index 232f1a6..00ed629 100644
--- a/drivers/firmware/altera_serial.c
+++ b/drivers/firmware/altera_serial.c
@@ -113,7 +113,7 @@ static int altera_spi_write(struct firmware_handler *fh, const void *buf, size_t
 	u32 dummy;
 	int ret;
 
-	dev_dbg(dev, "Start writing %d bytes.\n", __func__, sz);
+	dev_dbg(dev, "Start writing %d bytes.\n", sz);
 
 	spi_message_init(&m);
 
-- 
2.1.0



From s.hauer at pengutronix.de  Wed Oct  8 07:46:43 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed,  8 Oct 2014 16:46:43 +0200
Subject: [PATCH 2/4] firmware: Let SoCFPGA firmware loader depend on
 ARCH_SOCFPGA
In-Reply-To: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
References: <1412779605-25460-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1412779605-25460-2-git-send-email-s.hauer@pengutronix.de>

This driver does not compile on other architectures and is of no
use there anyway.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/firmware/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 5866063..a907eaf 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -10,5 +10,6 @@ config FIRMWARE_ALTERA_SERIAL
 
 config FIRMWARE_ALTERA_SOCFPGA
 	bool "Altera SoCFPGA fpga loader"
+	depends on ARCH_SOCFPGA
 
 endmenu
-- 
2.1.0



From antonynpavlov at gmail.com  Wed Oct  8 08:32:26 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 8 Oct 2014 19:32:26 +0400
Subject: [PATCH 6/6] commands: implement 'diff' command
In-Reply-To: <1412778255-4153-6-git-send-email-s.hauer@pengutronix.de>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
 <1412778255-4153-6-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20141008193226.0863b6e28861fd5e0adf1dc0@gmail.com>

On Wed,  8 Oct 2014 16:24:15 +0200
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> This command compares two files. It does not show the differences,
> it only returns successfully if both files are identical and with
> an error if they differ.

Here are my two comments:

1. there is the 'cmp' command for simple comparing two files from Unix cmdline.
Can we use 'cmp' name instead of 'diff'?

2. we already can use 
     memcmp -s FILE1 -d FILE2 0 0
   for comparing files :)

> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  commands/Kconfig  | 10 ++++++++++
>  commands/Makefile |  1 +
>  commands/diff.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 commands/diff.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index d73a393..05d5426 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -811,6 +811,16 @@ config CMD_CP
>  	  Options:
>  		  -v	verbose
>  
> +config CMD_DIFF
> +	tristate
> +	prompt "diff"
> +	help
> +	  compare two files
> +
> +	  Usage: diff FILE1 FILE2
> +
> +	  Returns successfully if the two files are the same, return with an error if not
> +
>  config CMD_DIRNAME
>  	tristate
>  	prompt "dirname"
> diff --git a/commands/Makefile b/commands/Makefile
> index b1cdf33..e53bdde 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -106,3 +106,4 @@ obj-$(CONFIG_CMD_IMD)		+= imd.o
>  obj-$(CONFIG_CMD_HWCLOCK)	+= hwclock.o
>  obj-$(CONFIG_CMD_USBGADGET)	+= usbgadget.o
>  obj-$(CONFIG_CMD_FIRMWARELOAD)	+= firmwareload.o
> +obj-$(CONFIG_CMD_DIFF)		+= diff.o
> diff --git a/commands/diff.c b/commands/diff.c
> new file mode 100644
> index 0000000..26eaf88
> --- /dev/null
> +++ b/commands/diff.c
> @@ -0,0 +1,42 @@
> +/*
> + * diff - determine if two files differ
> + *
> + * 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.
> + *
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <complete.h>
> +#include <libfile.h>
> +
> +static int do_diff(int argc, char *argv[])
> +{
> +	if (argc != 3)
> +		return COMMAND_ERROR_USAGE;
> +
> +	return diff_file(argv[1], argv[2]);
> +}
> +
> +BAREBOX_CMD_HELP_START(diff)
> +BAREBOX_CMD_HELP_TEXT("Returns successfully if the two files are the same, return with an error if not")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(diff)
> +	.cmd		= do_diff,
> +	BAREBOX_CMD_DESC("compare two files")
> +	BAREBOX_CMD_OPTS("FILE1 FILE2")
> +	BAREBOX_CMD_GROUP(CMD_GRP_FILE)
> +	BAREBOX_CMD_HELP(cmd_diff_help)
> +BAREBOX_CMD_END
> -- 
> 2.1.0
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
--?
Best regards,
? Antony Pavlov


From s.hauer at pengutronix.de  Wed Oct  8 23:50:35 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 9 Oct 2014 08:50:35 +0200
Subject: [PATCH 6/6] commands: implement 'diff' command
In-Reply-To: <20141008193226.0863b6e28861fd5e0adf1dc0@gmail.com>
References: <1412778255-4153-1-git-send-email-s.hauer@pengutronix.de>
 <1412778255-4153-6-git-send-email-s.hauer@pengutronix.de>
 <20141008193226.0863b6e28861fd5e0adf1dc0@gmail.com>
Message-ID: <20141009065035.GG4992@pengutronix.de>

On Wed, Oct 08, 2014 at 07:32:26PM +0400, Antony Pavlov wrote:
> On Wed,  8 Oct 2014 16:24:15 +0200
> Sascha Hauer <s.hauer at pengutronix.de> wrote:
> 
> > This command compares two files. It does not show the differences,
> > it only returns successfully if both files are identical and with
> > an error if they differ.
> 
> Here are my two comments:
> 
> 1. there is the 'cmp' command for simple comparing two files from Unix cmdline.
> Can we use 'cmp' name instead of 'diff'?

Yes, good idea. 'cmp' seems a better name. I changed it.

> 
> 2. we already can use 
>      memcmp -s FILE1 -d FILE2 0 0
>    for comparing files :)

I know. Admittedly I'm working on stuff where I need the diff_file (now
compare_file) C function. The cmp command is merely a vehicle to not
have the compare_file function unused in the tree until this work is
done ;)

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.trumtrar at pengutronix.de  Thu Oct  9 02:19:28 2014
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu,  9 Oct 2014 11:19:28 +0200
Subject: [PATCH] commands: firmwareload: add CMD_GROUP
Message-ID: <1412846368-32118-1-git-send-email-s.trumtrar@pengutronix.de>

To be able to build the documentation the CMD_GROUP macro needs
to be defined. Without this the firmwareload command breaks "make docs".

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 commands/firmwareload.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/commands/firmwareload.c b/commands/firmwareload.c
index a2596951a795..071f25be99b5 100644
--- a/commands/firmwareload.c
+++ b/commands/firmwareload.c
@@ -62,5 +62,6 @@ BAREBOX_CMD_HELP_END
 BAREBOX_CMD_START(firmwareload)
 	.cmd = do_firmwareload,
 	BAREBOX_CMD_DESC("Program a firmware file into a device")
+	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
 	BAREBOX_CMD_HELP(cmd_firmwareload_help)
 BAREBOX_CMD_END
-- 
2.1.0



From antonynpavlov at gmail.com  Thu Oct  9 13:08:55 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 10 Oct 2014 00:08:55 +0400
Subject: [PATCH 0/2] mips: qemu-malta: add little-endian mode support
Message-ID: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>

Antony Pavlov (2):
  mips: qemu-malta: add little-endian mode support
  Documentation: mips: add little-endian qemu-malta HOWTO

 Documentation/boards/mips/qemu-malta.rst | 24 ++++++++++++++++++++++++
 arch/mips/Kconfig                        |  1 +
 arch/mips/include/asm/gt64120.h          |  7 +++++++
 3 files changed, 32 insertions(+)

-- 
2.1.1



From antonynpavlov at gmail.com  Thu Oct  9 13:08:56 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 10 Oct 2014 00:08:56 +0400
Subject: [PATCH 1/2] mips: qemu-malta: add little-endian mode support
In-Reply-To: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
References: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1412885337-1544-2-git-send-email-antonynpavlov@gmail.com>

We can't just enable SYS_SUPPORTS_LITTLE_ENDIAN for successful
little-endian qemu-malta barebox build. Some byte swapping-related
macros are missed, e.g.:

    arch/mips/mach-malta/pci.c: In function 'pcibios_init':
    arch/mips/mach-malta/pci.c:218:28: error: 'GT_PCI0_CMD_MBYTESWAP_BIT'
    undeclared (first use in this function)
    GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
                              ^

This patch adds necessary macros definition.

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/Kconfig               | 1 +
 arch/mips/include/asm/gt64120.h | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 40d5d83..ed6e1ab 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -43,6 +43,7 @@ config MACH_MIPS_MALTA
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select HAS_DEBUG_LL
 	select GPIOLIB
 	select HW_HAS_PCI
diff --git a/arch/mips/include/asm/gt64120.h b/arch/mips/include/asm/gt64120.h
index 7e783c8..88fa1fa 100644
--- a/arch/mips/include/asm/gt64120.h
+++ b/arch/mips/include/asm/gt64120.h
@@ -76,6 +76,13 @@
 #define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
 #define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
 
+#define GT_PCI0_CMD_MBYTESWAP_SHF       0
+#define GT_PCI0_CMD_MBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT       GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF       16
+#define GT_PCI0_CMD_SBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT       GT_PCI0_CMD_SBYTESWAP_MSK
+
 /*
  * Because of an error/peculiarity in the Galileo chip, we need to swap the
  * bytes when running bigendian.  We also provide non-swapping versions.
-- 
2.1.1



From antonynpavlov at gmail.com  Thu Oct  9 13:08:57 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 10 Oct 2014 00:08:57 +0400
Subject: [PATCH 2/2] Documentation: mips: add little-endian qemu-malta HOWTO
In-Reply-To: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
References: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1412885337-1544-3-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 Documentation/boards/mips/qemu-malta.rst | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/boards/mips/qemu-malta.rst b/Documentation/boards/mips/qemu-malta.rst
index be89ae3..22da600 100644
--- a/Documentation/boards/mips/qemu-malta.rst
+++ b/Documentation/boards/mips/qemu-malta.rst
@@ -1,6 +1,9 @@
 QEMU Malta
 ==========
 
+Big-endian mode
+---------------
+
 QEMU run string::
 
   qemu-system-mips -nodefaults -M malta -m 256 \
@@ -11,6 +14,27 @@ Also you can use GXemul::
 
   gxemul -Q -x -e maltabe -M 256 0xbfc00000:barebox-flash-image
 
+
+Little-endian mode
+------------------
+
+Running little-endian Malta is a bit tricky.
+In little-endian mode the 32bit words in the boot flash image are swapped,
+a neat trick which allows bi-endian firmware.
+
+You have to swap words of ``zbarebox.bin`` image, e.g.::
+
+  echo arch/mips/pbl/zbarebox.bin \
+      | cpio --create \
+      | cpio --extract --swap --unconditional
+
+QEMU run string::
+
+  qemu-system-mipsel -nodefaults -M malta -m 256 \
+      -nographic -serial stdio -monitor null \
+      -bios barebox-flash-image
+
+
 Links
 -----
 
-- 
2.1.1



From luigi.origa at gmail.com  Thu Oct  9 15:24:40 2014
From: luigi.origa at gmail.com (luigi origa)
Date: Fri, 10 Oct 2014 00:24:40 +0200
Subject: Wrong relocation with Mini2440
Message-ID: <CACSabZ-OeOhLW5JC7Tk8OfryUfNx-9sZnGw16BK4kj+1AFts3g@mail.gmail.com>

I'm trying to have barebox working on my mini2440. After many test,
today i got a jtag interface and after some check i found this:

- source s3c24x0_nand_boot -
2: ldr sp, =(TEXT_BASE - SZ_2M) /* Setup a temporary stack in SDRAM */
/*
 * We still run at a location we are not linked to. But lets still running
 * from the internal SRAM, this may speed up the boot
 */
push {lr}
bl nand_boot
pop {lr}
/*
 * Adjust the return address to the correct address in SDRAM
 */
ldr r1, =(TEXT_BASE - SZ_2M)
add lr, lr, r1

mov pc, lr


- compiled s3c24x0_nand_boot -
ROM:00000320 loc_320                                 ; CODE XREF:
s3c24x0_nand_boot+10j
ROM:00000320                 MOV             SP, #0x33C00000
ROM:00000324                 STMFD           SP!, {LR}
ROM:00000328                 BL              nand_boot
ROM:0000032C                 LDMFD           SP!, {LR}
ROM:00000330                 MOV             R1, #0x33C00000
ROM:00000334                 ADD             LR, LR, R1


- source nand_boot -
void __nand_boot_init nand_boot(void)
{
void *dest = _text;
int size = ld_var(_barebox_image_size);
int page = 0;

s3c24x0_nand_load_image(dest, size, page);
}


- compiled nand_boot-
ROM:000001E0                 MOV             R1, R0                  // size
ROM:000001E4                 LDR             R0, =0x33E00000 // *dest
ROM:000001E8                 MOV             R2, #0
ROM:000001EC                 LDMFD           SP!, {R4,LR}
ROM:000001F0                 B               s3c24x0_nand_load_image


0x33c00000 is the sdram stack where the program should be copied from
nand. Unfortunately the function nand_boot copy from nand to sdram
@0x33e00000.

When s3c24x0_nand_boot try to jump in sdram, use  a wrong address
(0x33c00220 instead 0x33e00220).

I don't know if the problem is in "TEXT_BASE - SZ_2M" or "_text".


From s.hauer at pengutronix.de  Thu Oct  9 23:36:51 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 10 Oct 2014 08:36:51 +0200
Subject: [PATCH] commands: firmwareload: add CMD_GROUP
In-Reply-To: <1412846368-32118-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1412846368-32118-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <20141010063651.GK4992@pengutronix.de>

On Thu, Oct 09, 2014 at 11:19:28AM +0200, Steffen Trumtrar wrote:
> To be able to build the documentation the CMD_GROUP macro needs
> to be defined. Without this the firmwareload command breaks "make docs".
> 
> Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>

Applied, thanks

Sascha

> ---
>  commands/firmwareload.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/commands/firmwareload.c b/commands/firmwareload.c
> index a2596951a795..071f25be99b5 100644
> --- a/commands/firmwareload.c
> +++ b/commands/firmwareload.c
> @@ -62,5 +62,6 @@ BAREBOX_CMD_HELP_END
>  BAREBOX_CMD_START(firmwareload)
>  	.cmd = do_firmwareload,
>  	BAREBOX_CMD_DESC("Program a firmware file into a device")
> +	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
>  	BAREBOX_CMD_HELP(cmd_firmwareload_help)
>  BAREBOX_CMD_END
> -- 
> 2.1.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  Thu Oct  9 23:38:21 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 10 Oct 2014 08:38:21 +0200
Subject: [PATCH 0/2] mips: qemu-malta: add little-endian mode support
In-Reply-To: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
References: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20141010063821.GL4992@pengutronix.de>

On Fri, Oct 10, 2014 at 12:08:55AM +0400, Antony Pavlov wrote:
> Antony Pavlov (2):
>   mips: qemu-malta: add little-endian mode support
>   Documentation: mips: add little-endian qemu-malta HOWTO

Hm, nice. Adding big endian support to Arm would not be that simple.

Applied, thanks

Sascha

> 
>  Documentation/boards/mips/qemu-malta.rst | 24 ++++++++++++++++++++++++
>  arch/mips/Kconfig                        |  1 +
>  arch/mips/include/asm/gt64120.h          |  7 +++++++
>  3 files changed, 32 insertions(+)
> 
> -- 
> 2.1.1
> 
> 
> _______________________________________________
> 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 Oct  9 23:42:59 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 10 Oct 2014 08:42:59 +0200
Subject: Wrong relocation with Mini2440
In-Reply-To: <CACSabZ-OeOhLW5JC7Tk8OfryUfNx-9sZnGw16BK4kj+1AFts3g@mail.gmail.com>
References: <CACSabZ-OeOhLW5JC7Tk8OfryUfNx-9sZnGw16BK4kj+1AFts3g@mail.gmail.com>
Message-ID: <20141010064259.GM4992@pengutronix.de>

Hi Luigi,

On Fri, Oct 10, 2014 at 12:24:40AM +0200, luigi origa wrote:
> I'm trying to have barebox working on my mini2440. After many test,
> today i got a jtag interface and after some check i found this:
> 
> - source s3c24x0_nand_boot -
> 2: ldr sp, =(TEXT_BASE - SZ_2M) /* Setup a temporary stack in SDRAM */
> /*
>  * We still run at a location we are not linked to. But lets still running
>  * from the internal SRAM, this may speed up the boot
>  */
> push {lr}
> bl nand_boot
> pop {lr}
> /*
>  * Adjust the return address to the correct address in SDRAM
>  */
> ldr r1, =(TEXT_BASE - SZ_2M)
> add lr, lr, r1
> 
> mov pc, lr
> 
> 
> - compiled s3c24x0_nand_boot -
> ROM:00000320 loc_320                                 ; CODE XREF:
> s3c24x0_nand_boot+10j
> ROM:00000320                 MOV             SP, #0x33C00000
> ROM:00000324                 STMFD           SP!, {LR}
> ROM:00000328                 BL              nand_boot
> ROM:0000032C                 LDMFD           SP!, {LR}
> ROM:00000330                 MOV             R1, #0x33C00000
> ROM:00000334                 ADD             LR, LR, R1
> 
> 
> - source nand_boot -
> void __nand_boot_init nand_boot(void)
> {
> void *dest = _text;
> int size = ld_var(_barebox_image_size);
> int page = 0;
> 
> s3c24x0_nand_load_image(dest, size, page);
> }
> 
> 
> - compiled nand_boot-
> ROM:000001E0                 MOV             R1, R0                  // size
> ROM:000001E4                 LDR             R0, =0x33E00000 // *dest
> ROM:000001E8                 MOV             R2, #0
> ROM:000001EC                 LDMFD           SP!, {R4,LR}
> ROM:000001F0                 B               s3c24x0_nand_load_image
> 
> 
> 0x33c00000 is the sdram stack where the program should be copied from
> nand. Unfortunately the function nand_boot copy from nand to sdram
> @0x33e00000.
> 
> When s3c24x0_nand_boot try to jump in sdram, use  a wrong address
> (0x33c00220 instead 0x33e00220).
> 
> I don't know if the problem is in "TEXT_BASE - SZ_2M" or "_text".

Do you have PBL enabled? Could you enable PBL if not? Additionally
could you revert:

commit 558d72dc5116fc6275ea77c783cc65d6d1a5b521
Author: Michael Olbrich <m.olbrich at pengutronix.de>
Date:   Sun May 18 16:46:29 2014 +0200

    ARM Samsung: fix booting from NAND with pbl
    
    The ARM pbl is linked at (TEXT_BASE - SZ_2M). This conflicts with the temporary
    stack used in s3c24x0_nand_boot. Moving the stack to (TEXT_BASE - SZ_2M) fixes
    this problem. With this patch a compressed barebox with pbl can boot on
    mini2440 from NAND.
    
    Signed-off-by: Michael Olbrich <m.olbrich at pengutronix.de>
    Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>

I suspect This patch fixed booting with PBL enabled but broke booting
without PBL.

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 antonynpavlov at gmail.com  Fri Oct 10 01:43:11 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 10 Oct 2014 12:43:11 +0400
Subject: [PATCH 0/2] mips: qemu-malta: add little-endian mode support
In-Reply-To: <20141010063821.GL4992@pengutronix.de>
References: <1412885337-1544-1-git-send-email-antonynpavlov@gmail.com>
 <20141010063821.GL4992@pengutronix.de>
Message-ID: <20141010124311.f56a5bb12e439de1ac003f31@gmail.com>

On Fri, 10 Oct 2014 08:38:21 +0200
Sascha Hauer <s.hauer at pengutronix.de> wrote:

> On Fri, Oct 10, 2014 at 12:08:55AM +0400, Antony Pavlov wrote:
> > Antony Pavlov (2):
> >   mips: qemu-malta: add little-endian mode support
> >   Documentation: mips: add little-endian qemu-malta HOWTO
> 
> Hm, nice. Adding big endian support to Arm would not be that simple.

Actually most of mips chips supported by barebox are little-endian only
(bcm47xx, loongson, xburst). So all little-endian support work was
already done before.

Malta is bi-endian but I suppose little-endian mode is more popular
so it is handy to have real working little-endian qemu-malta support.
Nevertheless I prefer to use big-endian qemu-malta most of the time
as it does not need this odd boot image file byte swapping (see
Documentation-related second patch in this series).


> > 
> >  Documentation/boards/mips/qemu-malta.rst | 24 ++++++++++++++++++++++++
> >  arch/mips/Kconfig                        |  1 +
> >  arch/mips/include/asm/gt64120.h          |  7 +++++++
> >  3 files changed, 32 insertions(+)
> > 
> > -- 
> > 2.1.1
> > 
> > 
> > _______________________________________________
> > 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 |


-- 
--?
Best regards,
? Antony Pavlov


From t.gamez at phytec.de  Fri Oct 10 02:14:29 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:29 +0200
Subject: [PATCH 2/6] net: cpsw: Fix probe for one port ethernet
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412932473-38216-2-git-send-email-t.gamez@phytec.de>

If only one port is pinned out, probe fails
as the second port phy_id is not found.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 drivers/net/cpsw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 167b2dd..9c8cff3 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -1071,7 +1071,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv)
 				return ret;
 		}
 
-		if (!strncmp(child->name, "slave", 5)) {
+		if (i < priv->num_slaves && !strncmp(child->name, "slave", 5)) {
 			struct cpsw_slave *slave = &priv->slaves[i];
 			uint32_t phy_id[2];
 
@@ -1088,7 +1088,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv)
 		}
 	}
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < priv->num_slaves; i++) {
 		struct cpsw_slave *slave = &priv->slaves[i];
 
 		cpsw_gmii_sel_am335x(slave);
-- 
1.9.1



From t.gamez at phytec.de  Fri Oct 10 02:14:28 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:28 +0200
Subject: [PATCH 1/6] ARM: defconfig: Enable of_display_timings in
 am335x_defconfig
Message-ID: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/configs/am335x_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/am335x_defconfig b/arch/arm/configs/am335x_defconfig
index 6ef9c83..7dcfaed 100644
--- a/arch/arm/configs/am335x_defconfig
+++ b/arch/arm/configs/am335x_defconfig
@@ -79,6 +79,7 @@ CONFIG_CMD_USBGADGET=y
 CONFIG_CMD_BAREBOX_UPDATE=y
 CONFIG_CMD_OF_NODE=y
 CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
 CONFIG_CMD_OFTREE=y
 CONFIG_CMD_TIME=y
 CONFIG_NET=y
-- 
1.9.1



From t.gamez at phytec.de  Fri Oct 10 02:14:31 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:31 +0200
Subject: [PATCH 4/6] phyCORE-AM335x: Strip down device tree
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412932473-38216-4-git-send-email-t.gamez@phytec.de>

The phyCORE-AM335x is a SOM that can be connected to different
carrierboards like PCM-953, phyBOARD-WEGA and phyBOARD-MAIA.

It is enough for the bootloader to support the SOM specific
parts and can be so used also on different carrierboards.

Removed carrierboard specific settings like led and the
second ethernet slave.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/dts/am335x-phytec-phycore.dts | 41 +---------------------------------
 1 file changed, 1 insertion(+), 40 deletions(-)

diff --git a/arch/arm/dts/am335x-phytec-phycore.dts b/arch/arm/dts/am335x-phytec-phycore.dts
index e7e7780..1a1352f 100644
--- a/arch/arm/dts/am335x-phytec-phycore.dts
+++ b/arch/arm/dts/am335x-phytec-phycore.dts
@@ -21,23 +21,6 @@
 			status = "disabled";
 		};
 	};
-
-	gpio-leds {
-		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pcm051_led_pins>;
-
-		led-green {
-			label = "green";
-			gpios = <&gpio1 30 0>;
-			linux,default-trigger = "heartbeat";
-		};
-
-		led-amber {
-			label = "amber";
-			gpios = <&gpio1 31 1>;
-		};
-	};
 };
 
 &am33xx_pinmux {
@@ -72,7 +55,6 @@
 			0xfc (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat0.mmc0_dat0 */
 			0x100 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_clk.mmc0_clk */
 			0x104 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_cmd.mmc0_cmd */
-			0x160 (MUX_MODE7 | INPUT_EN | PULL_UP)	/* spi0_cs1.??, card detect */
 		>;
 	};
 
@@ -86,20 +68,6 @@
 			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd1.rmii1_rxd1 */
 			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd0.rmii1_rxd0 */
 			0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* rmii1_refclk.rmii1_refclk */
-
-			/* Slave 2 */
-			0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a0.rgmii2_tctl */
-			0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a1.rgmii2_rctl */
-			0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a2.rgmii2_td3 */
-			0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a3.rgmii2_td2 */
-			0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a4.rgmii2_td1 */
-			0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a5.rgmii2_td0 */
-			0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)  /* gpmc_a6.rgmii2_tclk */
-			0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a7.rgmii2_rclk */
-			0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a8.rgmii2_rd3 */
-			0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a9.rgmii2_rd2 */
-			0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a10.rgmii2_rd1 */
-			0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)   /* gpmc_a11.rgmii2_rd0 */
 		>;
 	};
 
@@ -224,19 +192,12 @@
 &cpsw_emac0 {
 	phy_id = <&davinci_mdio>, <0>;
 	phy-mode = "rmii";
-	dual_emac_res_vlan = <1>;
-};
-
-&cpsw_emac1 {
-	phy_id = <&davinci_mdio>, <2>;
-	phy-mode = "rgmii";
-	dual_emac_res_vlan = <2>;
 };
 
 &mac {
 	pinctrl-names = "default";
 	pinctrl-0 = <&emac_rmii1_pins>;
-	dual_emac = <1>;
+	slaves = <1>;
 	status = "okay";
 };
 
-- 
1.9.1



From t.gamez at phytec.de  Fri Oct 10 02:14:30 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:30 +0200
Subject: [PATCH 3/6] phyCORE-AM335x: Update default enviroment
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412932473-38216-3-git-send-email-t.gamez@phytec.de>

- Set default bootsource to the $boosource variable
- Pass ip to kernel on all boot options
- mount rootfs rw

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 .../phytec-phycore-am335x/defaultenv-phycore-am335x/boot/mmc   |  7 +++++--
 .../phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand  |  5 ++++-
 .../phytec-phycore-am335x/defaultenv-phycore-am335x/boot/spi   |  4 +++-
 .../defaultenv-phycore-am335x/config-board                     | 10 ++++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/mmc b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/mmc
index 32854d1..6a60761 100644
--- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/mmc
+++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/mmc
@@ -1,5 +1,8 @@
 #!/bin/sh
 
-global.bootm.image=/boot/uImage
+global.bootm.image=/boot/linuximage
 #global.bootm.oftree=/boot/oftree
-global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
+
+bootargs-ip
+
+global.linux.bootargs.dyn.root="root=/dev/mmcblk0p2 rootfstype=ext3 rw rootwait"
diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
index cdfd93d..d9ef145 100644
--- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
+++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
@@ -2,4 +2,7 @@
 
 global.bootm.image="/dev/nand0.kernel.bb"
 #global.bootm.oftree="/env/oftree"
-global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rootfstype=ubifs"
+
+bootargs-ip
+
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/spi b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/spi
index 7a53d84..c87299a 100644
--- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/spi
+++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/spi
@@ -2,5 +2,7 @@
 
 global.bootm.image="/dev/m25p0.kernel"
 
+bootargs-ip
+
 # Use rootfs form NAND for now as rootfs partition < 4MB
-global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rootfstype=ubifs"
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board
index 7f0b2b7..a492ed1 100644
--- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board
+++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/config-board
@@ -5,3 +5,13 @@
 
 global.hostname=pcm051
 global.linux.bootargs.base="console=ttyO0,115200"
+
+if [ $bootsource = mmc ]; then
+	global.boot.default="mmc nand spi net"
+elif [ $boosource = nand ]; then
+	global.boot.default="nand spi mmc net"
+elif [ $boosource = spi ]; then
+	global.boot.default="spi nand mmc net"
+elif [ $boosource = net ]; then
+	global.boot.default="net nand spi mmc"
+fi
-- 
1.9.1



From t.gamez at phytec.de  Fri Oct 10 02:14:32 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:32 +0200
Subject: [PATCH 5/6] ARM: dts: split phyCORE-AM335x device tree
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412932473-38216-5-git-send-email-t.gamez@phytec.de>

To support different module variants, split the phyCORE dts
in dts and dtsi. Configurable parts which are supported by
barebox are spi nor flash and i2c eeprom.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/boards/phytec-phycore-am335x/board.c    |   4 +-
 arch/arm/boards/phytec-phycore-am335x/lowlevel.c |   6 +-
 arch/arm/dts/Makefile                            |   2 +-
 arch/arm/dts/am335x-phytec-phycore-som.dts       |  24 ++
 arch/arm/dts/am335x-phytec-phycore-som.dtsi      | 286 ++++++++++++++++++++++
 arch/arm/dts/am335x-phytec-phycore.dts           | 292 -----------------------
 6 files changed, 316 insertions(+), 298 deletions(-)
 create mode 100644 arch/arm/dts/am335x-phytec-phycore-som.dts
 create mode 100644 arch/arm/dts/am335x-phytec-phycore-som.dtsi
 delete mode 100644 arch/arm/dts/am335x-phytec-phycore.dts

diff --git a/arch/arm/boards/phytec-phycore-am335x/board.c b/arch/arm/boards/phytec-phycore-am335x/board.c
index 035866b..64e3904 100644
--- a/arch/arm/boards/phytec-phycore-am335x/board.c
+++ b/arch/arm/boards/phytec-phycore-am335x/board.c
@@ -34,7 +34,7 @@
 
 static int pcm051_coredevice_init(void)
 {
-	if (!of_machine_is_compatible("phytec,pcm051"))
+	if (!of_machine_is_compatible("phytec,phycore-am335x-som"))
 		return 0;
 
 	am33xx_register_ethaddr(0, 0);
@@ -58,7 +58,7 @@ static char *xloadslots[] = {
 
 static int pcm051_devices_init(void)
 {
-	if (!of_machine_is_compatible("phytec,pcm051"))
+	if (!of_machine_is_compatible("phytec,phycore-am335x-som"))
 		return 0;
 
 	switch (bootsource_get()) {
diff --git a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
index 66bae80..47902d0 100644
--- a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
@@ -117,7 +117,7 @@ struct pcm051_sdram_timings timings[] = {
 	},
 };
 
-extern char __dtb_am335x_phytec_phycore_start[];
+extern char __dtb_am335x_phytec_phycore_som_start[];
 
 /**
  * @brief The basic entry point for board initialization.
@@ -153,7 +153,7 @@ static noinline void pcm051_board_init(int sdram)
 	omap_uart_lowlevel_init((void *)AM33XX_UART0_BASE);
 	putc_ll('>');
 
-	fdt = __dtb_am335x_phytec_phycore_start - get_runtime_offset();
+	fdt = __dtb_am335x_phytec_phycore_som_start - get_runtime_offset();
 
 	am335x_barebox_entry(fdt);
 }
@@ -198,7 +198,7 @@ ENTRY_FUNCTION(start_am33xx_phytec_phycore_sdram, r0, r1, r2)
 {
 	void *fdt;
 
-	fdt = __dtb_am335x_phytec_phycore_start - get_runtime_offset();
+	fdt = __dtb_am335x_phytec_phycore_som_start - get_runtime_offset();
 
 	am335x_barebox_entry(fdt);
 }
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3fcd5f1..65ed022 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -26,7 +26,7 @@ pbl-dtb-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
-pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore.dtb.o
+pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o
 pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += kirkwood-openblocks_a6-bb.dtb.o
diff --git a/arch/arm/dts/am335x-phytec-phycore-som.dts b/arch/arm/dts/am335x-phytec-phycore-som.dts
new file mode 100644
index 0000000..93f09e2
--- /dev/null
+++ b/arch/arm/dts/am335x-phytec-phycore-som.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 Teresa G?mez <t.gamez at phytec.de> Phytec Messtechnik GmbH
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-phytec-phycore-som.dtsi"
+
+/ {
+	model = "Phytec phyCORE AM335x";
+	compatible = "phytec,phycore-am335x-som", "ti,am33xx";
+};
+
+&spi0 {
+	status = "okay";
+};
+
+&eeprom {
+	status = "okay";
+};
diff --git a/arch/arm/dts/am335x-phytec-phycore-som.dtsi b/arch/arm/dts/am335x-phytec-phycore-som.dtsi
new file mode 100644
index 0000000..f1bcb8b
--- /dev/null
+++ b/arch/arm/dts/am335x-phytec-phycore-som.dtsi
@@ -0,0 +1,286 @@
+/ {
+	chosen {
+		linux,stdout-path = &uart0;
+
+		environment-spi {
+			compatible = "barebox,environment";
+			device-path = &flash, "partname:bareboxenv";
+			status = "disabled";
+		};
+
+		environment-nand {
+			compatible = "barebox,environment";
+			device-path = &nand, "partname:bareboxenv";
+			status = "disabled";
+		};
+	};
+};
+
+&am33xx_pinmux {
+	i2c0_pins: pinmux_i2c0_pins {
+			pinctrl-single,pins = <
+			0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
+			0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
+		>;
+	};
+
+	spi0_pins: pinmux_spi0_pins {
+		pinctrl-single,pins = <
+			0x150 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* spi0_clk.spi0_clk */
+			0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* spi0_d0.spi0_d0 */
+			0x158 (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_d1.spi0_d1 */
+			0x15c (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_cs0.spi0_cs0 */
+		>;
+	};
+
+	uart0_pins: pinmux_uart0_pins {
+		pinctrl-single,pins = <
+			0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
+			0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+		>;
+	};
+
+	mmc1_pins: pinmux_mmc1_pins {
+		pinctrl-single,pins = <
+			0xf0 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat3.mmc0_dat3 */
+			0xf4 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat2.mmc0_dat2 */
+			0xf8 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat1.mmc0_dat1 */
+			0xfc (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat0.mmc0_dat0 */
+			0x100 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_clk.mmc0_clk */
+			0x104 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_cmd.mmc0_cmd */
+		>;
+	};
+
+	emac_rmii1_pins: pinmux_emac_rmii1_pins {
+		pinctrl-single,pins = <
+			0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_crs.rmii1_crs_dv */
+			0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxerr.rmii1_rxerr */
+			0x114 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txen.rmii1_txen */
+			0x124 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txd1.rmii1_txd1 */
+			0x128 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txd0.rmii1_txd0 */
+			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd1.rmii1_rxd1 */
+			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd0.rmii1_rxd0 */
+			0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* rmii1_refclk.rmii1_refclk */
+		>;
+	};
+
+	nandflash_pins_s0: nandflash_pins_s0 {
+		pinctrl-single,pins = <
+			0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+			0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+			0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+			0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+			0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+			0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+			0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+			0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+			0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+			0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
+			0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
+			0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
+			0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
+			0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
+			0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
+		>;
+	};
+
+	davinci_mdio_default: davinci_mdio_default {
+		pinctrl-single,pins = <
+			/* MDIO */
+			0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+			0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+		>;
+	};
+
+	pcm051_led_pins: pinmux_pcm051_led_pins {
+		pinctrl-single,pins = <
+			0x80 (MUX_MODE7)
+			0x84 (MUX_MODE7)
+		>;
+	};
+
+	pcm051_user_pins: pinmux_pcm051_user_pins {
+		pinctrl-single,pins = <
+			0x1e4 (PULL_UP |INPUT_EN |MUX_MODE7)
+			0x1e8 (PULL_UP |INPUT_EN |MUX_MODE7)
+		>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+
+	status = "okay";
+	clock-frequency = <400000>;
+
+	eeprom: 24c32 at 52 {
+		status = "disabled";
+		compatible = "atmel,24c32";
+		pagesize = <32>;
+		reg = <0x52>;
+	};
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_pins>;
+	status = "okay";
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins>;
+	status = "disabled";
+
+	flash: m25p80 {
+		compatible = "m25p80";
+		spi-max-frequency = <48000000>;
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 0 {
+			label = "xload";
+			reg = <0x0 0x20000>;
+		};
+
+		partition at 1 {
+			label = "barebox";
+			reg = <0x20000 0x80000>;
+		};
+
+		partition at 2 {
+			label = "bareboxenv";
+			reg = <0xa0000 0x20000>;
+		};
+
+		partition at 3 {
+			label = "oftree";
+			reg = <0xc0000 0x20000>;
+		};
+
+		partition at 4 {
+			label = "kernel";
+			reg = <0xe0000 0x400000>;
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&davinci_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&davinci_mdio_default>;
+	status = "okay";
+};
+
+&phy_sel {
+	rmii-clock-ext;
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rmii";
+};
+
+&mac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emac_rmii1_pins>;
+	slaves = <1>;
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand: nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <8>;
+		ti,nand-ecc-opt = "bch8";
+		gpmc,device-nand = "true";
+		gpmc,device-width = <1>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <30>;
+		gpmc,cs-wr-off-ns = <30>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <30>;
+		gpmc,adv-wr-off-ns = <30>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <20>;
+		gpmc,oe-on-ns = <10>;
+		gpmc,oe-off-ns = <30>;
+		gpmc,access-ns = <30>;
+		gpmc,rd-cycle-ns = <30>;
+		gpmc,wr-cycle-ns = <30>;
+		gpmc,wait-pin = <1>;
+		gpmc,wait-on-read = "true";
+		gpmc,wait-on-write = "true";
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <50>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,wr-access-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		elm_id = <&elm>;
+
+		partition at 0 {
+			label = "xload";
+			reg = <0x0 0x20000>;
+		};
+
+		partition at 1 {
+			label = "xload_backup1";
+			reg = <0x20000 0x20000>;
+		};
+
+		partition at 2 {
+			label = "xload_backup2";
+			reg = <0x40000 0x20000>;
+		};
+
+		partition at 3 {
+			label = "xload_backup3";
+			reg = <0x60000 0x20000>;
+		};
+
+		partition at 4 {
+			label = "barebox";
+			reg = <0x80000 0x80000>;
+		};
+
+		partition at 5 {
+			label = "bareboxenv";
+			reg = <0x100000 0x20000>;
+		};
+
+		partition at 6 {
+			label = "oftree";
+			reg = <0x120000 0x20000>;
+		};
+
+		partition at 7 {
+			label = "kernel";
+			reg = <0x140000 0x800000>;
+		};
+
+		partition at 8 {
+			label = "root";
+			/*
+			 * Size 0x0 extends partition to
+			 * end of nand flash.
+			 */
+			reg = <0x940000 0x0>;
+		};
+	};
+};
diff --git a/arch/arm/dts/am335x-phytec-phycore.dts b/arch/arm/dts/am335x-phytec-phycore.dts
deleted file mode 100644
index 1a1352f..0000000
--- a/arch/arm/dts/am335x-phytec-phycore.dts
+++ /dev/null
@@ -1,292 +0,0 @@
-/dts-v1/;
-
-#include "am33xx.dtsi"
-
-/ {
-	model = "Phytec phyCORE AM335x";
-	compatible = "phytec,phycore-am335x", "phytec,pcm051", "ti,am33xx";
-
-	chosen {
-		linux,stdout-path = &uart0;
-
-		environment-spi {
-			compatible = "barebox,environment";
-			device-path = &flash, "partname:bareboxenv";
-			status = "disabled";
-		};
-
-		environment-nand {
-			compatible = "barebox,environment";
-			device-path = &nand, "partname:bareboxenv";
-			status = "disabled";
-		};
-	};
-};
-
-&am33xx_pinmux {
-	i2c0_pins: pinmux_i2c0_pins {
-			pinctrl-single,pins = <
-			0x188 (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
-			0x18c (PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
-		>;
-	};
-
-	spi0_pins: pinmux_spi0_pins {
-		pinctrl-single,pins = <
-			0x150 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* spi0_clk.spi0_clk */
-			0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* spi0_d0.spi0_d0 */
-			0x158 (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_d1.spi0_d1 */
-			0x15c (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_cs0.spi0_cs0 */
-		>;
-	};
-
-	uart0_pins: pinmux_uart0_pins {
-		pinctrl-single,pins = <
-			0x170 (PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
-			0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
-		>;
-	};
-
-	mmc1_pins: pinmux_mmc1_pins {
-		pinctrl-single,pins = <
-			0xf0 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat3.mmc0_dat3 */
-			0xf4 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat2.mmc0_dat2 */
-			0xf8 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat1.mmc0_dat1 */
-			0xfc (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_dat0.mmc0_dat0 */
-			0x100 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_clk.mmc0_clk */
-			0x104 (MUX_MODE0 | INPUT_EN | PULL_UP)	/* mmc0_cmd.mmc0_cmd */
-		>;
-	};
-
-	emac_rmii1_pins: pinmux_emac_rmii1_pins {
-		pinctrl-single,pins = <
-			0x10c (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_crs.rmii1_crs_dv */
-			0x110 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxerr.rmii1_rxerr */
-			0x114 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txen.rmii1_txen */
-			0x124 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txd1.rmii1_txd1 */
-			0x128 (PIN_OUTPUT | MUX_MODE1)		/* mii1_txd0.rmii1_txd0 */
-			0x13c (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd1.rmii1_rxd1 */
-			0x140 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* mii1_rxd0.rmii1_rxd0 */
-			0x144 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* rmii1_refclk.rmii1_refclk */
-		>;
-	};
-
-	nandflash_pins_s0: nandflash_pins_s0 {
-		pinctrl-single,pins = <
-			0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
-			0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
-			0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
-			0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
-			0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
-			0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
-			0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
-			0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
-			0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
-			0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
-			0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
-			0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
-			0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
-			0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
-			0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
-		>;
-	};
-
-	davinci_mdio_default: davinci_mdio_default {
-		pinctrl-single,pins = <
-			/* MDIO */
-			0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
-			0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
-		>;
-	};
-
-	pcm051_led_pins: pinmux_pcm051_led_pins {
-		pinctrl-single,pins = <
-			0x80 (MUX_MODE7)
-			0x84 (MUX_MODE7)
-		>;
-	};
-
-	pcm051_user_pins: pinmux_pcm051_user_pins {
-		pinctrl-single,pins = <
-			0x1e4 (PULL_UP |INPUT_EN |MUX_MODE7)
-			0x1e8 (PULL_UP |INPUT_EN |MUX_MODE7)
-		>;
-	};
-};
-
-&i2c0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c0_pins>;
-
-	status = "okay";
-	clock-frequency = <400000>;
-
-	eeprom: 24c32 at 52 {
-		compatible = "atmel,24c32";
-		pagesize = <32>;
-		reg = <0x52>;
-	};
-};
-
-&mmc1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc1_pins>;
-	status = "okay";
-};
-
-&spi0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&spi0_pins>;
-	status = "okay";
-
-	flash: m25p80 {
-		compatible = "m25p80";
-		spi-max-frequency = <48000000>;
-		reg = <0>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-		partition at 0 {
-			label = "xload";
-			reg = <0x0 0x20000>;
-		};
-
-		partition at 1 {
-			label = "barebox";
-			reg = <0x20000 0x80000>;
-		};
-
-		partition at 2 {
-			label = "bareboxenv";
-			reg = <0xa0000 0x20000>;
-		};
-
-		partition at 3 {
-			label = "oftree";
-			reg = <0xc0000 0x20000>;
-		};
-
-		partition at 4 {
-			label = "kernel";
-			reg = <0xe0000 0x400000>;
-		};
-	};
-};
-
-&uart0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&uart0_pins>;
-	status = "okay";
-};
-
-&davinci_mdio {
-	pinctrl-names = "default";
-	pinctrl-0 = <&davinci_mdio_default>;
-	status = "okay";
-};
-
-&phy_sel {
-	rmii-clock-ext;
-};
-
-&cpsw_emac0 {
-	phy_id = <&davinci_mdio>, <0>;
-	phy-mode = "rmii";
-};
-
-&mac {
-	pinctrl-names = "default";
-	pinctrl-0 = <&emac_rmii1_pins>;
-	slaves = <1>;
-	status = "okay";
-};
-
-&gpmc {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&nandflash_pins_s0>;
-	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
-	nand: nand at 0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
-		nand-bus-width = <8>;
-		ti,nand-ecc-opt = "bch8";
-		gpmc,device-nand = "true";
-		gpmc,device-width = <1>;
-		gpmc,sync-clk-ps = <0>;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <30>;
-		gpmc,cs-wr-off-ns = <30>;
-		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <30>;
-		gpmc,adv-wr-off-ns = <30>;
-		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <20>;
-		gpmc,oe-on-ns = <10>;
-		gpmc,oe-off-ns = <30>;
-		gpmc,access-ns = <30>;
-		gpmc,rd-cycle-ns = <30>;
-		gpmc,wr-cycle-ns = <30>;
-		gpmc,wait-pin = <1>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
-		gpmc,bus-turnaround-ns = <0>;
-		gpmc,cycle2cycle-delay-ns = <50>;
-		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
-		gpmc,wr-access-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <0>;
-
-		#address-cells = <1>;
-		#size-cells = <1>;
-		elm_id = <&elm>;
-
-		partition at 0 {
-			label = "xload";
-			reg = <0x0 0x20000>;
-		};
-
-		partition at 1 {
-			label = "xload_backup1";
-			reg = <0x20000 0x20000>;
-		};
-
-		partition at 2 {
-			label = "xload_backup2";
-			reg = <0x40000 0x20000>;
-		};
-
-		partition at 3 {
-			label = "xload_backup3";
-			reg = <0x60000 0x20000>;
-		};
-
-		partition at 4 {
-			label = "barebox";
-			reg = <0x80000 0x80000>;
-		};
-
-		partition at 5 {
-			label = "bareboxenv";
-			reg = <0x100000 0x20000>;
-		};
-
-		partition at 6 {
-			label = "oftree";
-			reg = <0x120000 0x20000>;
-		};
-
-		partition at 7 {
-			label = "kernel";
-			reg = <0x140000 0x800000>;
-		};
-
-		partition at 8 {
-			label = "root";
-			/*
-			 * Size 0x0 extends partition to
-			 * end of nand flash.
-			 */
-			reg = <0x940000 0x0>;
-		};
-	};
-};
-- 
1.9.1



From t.gamez at phytec.de  Fri Oct 10 02:14:33 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 10 Oct 2014 11:14:33 +0200
Subject: [PATCH 6/6] phyCORE-AM335x: Add barebox image without SPI NOR
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1412932473-38216-6-git-send-email-t.gamez@phytec.de>

Boards like phyBOARD-WEGA RDK have an phyCORE-AM335x
connected with no SPI NOR flash. Added dts to support this.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/boards/phytec-phycore-am335x/lowlevel.c  | 10 ++++++++++
 arch/arm/dts/Makefile                             |  2 +-
 arch/arm/dts/am335x-phytec-phycore-som-no-spi.dts | 20 ++++++++++++++++++++
 images/Makefile.am33xx                            |  4 ++++
 4 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/am335x-phytec-phycore-som-no-spi.dts

diff --git a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
index 47902d0..55cc667 100644
--- a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
@@ -118,6 +118,7 @@ struct pcm051_sdram_timings timings[] = {
 };
 
 extern char __dtb_am335x_phytec_phycore_som_start[];
+extern char __dtb_am335x_phytec_phycore_som_no_spi_start[];
 
 /**
  * @brief The basic entry point for board initialization.
@@ -202,3 +203,12 @@ ENTRY_FUNCTION(start_am33xx_phytec_phycore_sdram, r0, r1, r2)
 
 	am335x_barebox_entry(fdt);
 }
+
+ENTRY_FUNCTION(start_am33xx_phytec_phycore_no_spi_sdram, r0, r1, r2)
+{
+	void *fdt;
+
+	fdt = __dtb_am335x_phytec_phycore_som_no_spi_start - get_runtime_offset();
+
+	am335x_barebox_entry(fdt);
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 65ed022..ede2b59 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -26,7 +26,7 @@ pbl-dtb-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
-pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o
+pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o am335x-phytec-phycore-som-no-spi.dtb.o
 pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_A6) += kirkwood-openblocks_a6-bb.dtb.o
diff --git a/arch/arm/dts/am335x-phytec-phycore-som-no-spi.dts b/arch/arm/dts/am335x-phytec-phycore-som-no-spi.dts
new file mode 100644
index 0000000..6350706
--- /dev/null
+++ b/arch/arm/dts/am335x-phytec-phycore-som-no-spi.dts
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2014 Teresa G?mez <t.gamez at phytec.de> Phytec Messtechnik GmbH
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-phytec-phycore-som.dtsi"
+
+/ {
+	model = "Phytec phyCORE AM335x";
+	compatible = "phytec,phycore-am335x-som", "ti,am33xx";
+};
+
+&eeprom {
+	status = "okay";
+};
diff --git a/images/Makefile.am33xx b/images/Makefile.am33xx
index 92dd61a..8d58733 100644
--- a/images/Makefile.am33xx
+++ b/images/Makefile.am33xx
@@ -19,6 +19,10 @@ pblx-$(CONFIG_MACH_PCM051) += start_am33xx_phytec_phycore_sdram
 FILE_barebox-am33xx-phytec-phycore.img = start_am33xx_phytec_phycore_sdram.pblx
 am33xx-barebox-$(CONFIG_MACH_PCM051) += barebox-am33xx-phytec-phycore.img
 
+pblx-$(CONFIG_MACH_PCM051) += start_am33xx_phytec_phycore_no_spi_sdram
+FILE_barebox-am33xx-phytec-phycore-no-spi.img = start_am33xx_phytec_phycore_no_spi_sdram.pblx
+am33xx-barebox-$(CONFIG_MACH_PCM051) += barebox-am33xx-phytec-phycore-no-spi.img
+
 pblx-$(CONFIG_MACH_PCM051) += start_am33xx_phytec_phycore_sram_256mb
 FILE_barebox-am33xx-phytec-phycore-mlo-256mb.img = start_am33xx_phytec_phycore_sram_256mb.pblx.mlo
 am33xx-mlo-$(CONFIG_MACH_PCM051) += barebox-am33xx-phytec-phycore-mlo-256mb.img
-- 
1.9.1



From luigi.origa at gmail.com  Fri Oct 10 07:25:54 2014
From: luigi.origa at gmail.com (luigi origa)
Date: Fri, 10 Oct 2014 16:25:54 +0200
Subject: Wrong relocation with Mini2440
In-Reply-To: <20141010064259.GM4992@pengutronix.de>
References: <CACSabZ-OeOhLW5JC7Tk8OfryUfNx-9sZnGw16BK4kj+1AFts3g@mail.gmail.com>
 <20141010064259.GM4992@pengutronix.de>
Message-ID: <CACSabZ957Z_uxOOb3dTaREPhKu+owTy9SHxjYHxTfyTuUMBchg@mail.gmail.com>

I tried enabling pbl with the default values and it works. I tried
also changing the address at 0x33c00000 (instead the default
0x33e00000) with pbl disabled and works again.

Thanks for the help.

Luigi




2014-10-10 8:42 GMT+02:00 Sascha Hauer <s.hauer at pengutronix.de>:
> Hi Luigi,
>
> On Fri, Oct 10, 2014 at 12:24:40AM +0200, luigi origa wrote:
>> I'm trying to have barebox working on my mini2440. After many test,
>> today i got a jtag interface and after some check i found this:
>>
>> - source s3c24x0_nand_boot -
>> 2: ldr sp, =(TEXT_BASE - SZ_2M) /* Setup a temporary stack in SDRAM */
>> /*
>>  * We still run at a location we are not linked to. But lets still running
>>  * from the internal SRAM, this may speed up the boot
>>  */
>> push {lr}
>> bl nand_boot
>> pop {lr}
>> /*
>>  * Adjust the return address to the correct address in SDRAM
>>  */
>> ldr r1, =(TEXT_BASE - SZ_2M)
>> add lr, lr, r1
>>
>> mov pc, lr
>>
>>
>> - compiled s3c24x0_nand_boot -
>> ROM:00000320 loc_320                                 ; CODE XREF:
>> s3c24x0_nand_boot+10 j
>> ROM:00000320                 MOV             SP, #0x33C00000
>> ROM:00000324                 STMFD           SP!, {LR}
>> ROM:00000328                 BL              nand_boot
>> ROM:0000032C                 LDMFD           SP!, {LR}
>> ROM:00000330                 MOV             R1, #0x33C00000
>> ROM:00000334                 ADD             LR, LR, R1
>>
>>
>> - source nand_boot -
>> void __nand_boot_init nand_boot(void)
>> {
>> void *dest = _text;
>> int size = ld_var(_barebox_image_size);
>> int page = 0;
>>
>> s3c24x0_nand_load_image(dest, size, page);
>> }
>>
>>
>> - compiled nand_boot-
>> ROM:000001E0                 MOV             R1, R0                  // size
>> ROM:000001E4                 LDR             R0, =0x33E00000 // *dest
>> ROM:000001E8                 MOV             R2, #0
>> ROM:000001EC                 LDMFD           SP!, {R4,LR}
>> ROM:000001F0                 B               s3c24x0_nand_load_image
>>
>>
>> 0x33c00000 is the sdram stack where the program should be copied from
>> nand. Unfortunately the function nand_boot copy from nand to sdram
>> @0x33e00000.
>>
>> When s3c24x0_nand_boot try to jump in sdram, use  a wrong address
>> (0x33c00220 instead 0x33e00220).
>>
>> I don't know if the problem is in "TEXT_BASE - SZ_2M" or "_text".
>
> Do you have PBL enabled? Could you enable PBL if not? Additionally
> could you revert:
>
> commit 558d72dc5116fc6275ea77c783cc65d6d1a5b521
> Author: Michael Olbrich <m.olbrich at pengutronix.de>
> Date:   Sun May 18 16:46:29 2014 +0200
>
>     ARM Samsung: fix booting from NAND with pbl
>
>     The ARM pbl is linked at (TEXT_BASE - SZ_2M). This conflicts with the temporary
>     stack used in s3c24x0_nand_boot. Moving the stack to (TEXT_BASE - SZ_2M) fixes
>     this problem. With this patch a compressed barebox with pbl can boot on
>     mini2440 from NAND.
>
>     Signed-off-by: Michael Olbrich <m.olbrich at pengutronix.de>
>     Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
>
> I suspect This patch fixed booting with PBL enabled but broke booting
> without PBL.
>
> 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 embedded24 at evers-fischer.de  Mon Oct 13 04:27:20 2014
From: embedded24 at evers-fischer.de (Rolf Evers-Fischer)
Date: Mon, 13 Oct 2014 13:27:20 +0200
Subject: [PATCH] lib: parameter: fixed doku renamed ip -> ipaddr
Message-ID: <1413199640-6317-1-git-send-email-embedded24@evers-fischer.de>

Long time ago all ".ip" parameters have been replaced with ".ipaddr".

Signed-off-by: Rolf Evers-Fischer <embedded24 at evers-fischer.de>
---
 lib/parameter.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/parameter.c b/lib/parameter.c
index 84a632c..c4c30ca 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -776,8 +776,8 @@ with device paramters. Device parameters are always strings, although there
 are functions to interpret them as something else. 'hush' users can access
 parameters as a local variable which have a dot (.) in them. So setting the
 IP address of the first ethernet device is a matter of typing
-'eth0.ip=192.168.0.7' on the console and can then be read back with
-'echo $eth0.ip'. The @ref devinfo_command command shows a summary about all
+'eth0.ipaddr=192.168.0.7' on the console and can then be read back with
+'echo $eth0.ipaddr'. The @ref devinfo_command command shows a summary about all
 devices currently present. If called with a device id as parameter it shows the
 parameters available for a device.
 
-- 
1.9.1



From m.feser at kbs-gmbh.de  Mon Oct 13 07:00:00 2014
From: m.feser at kbs-gmbh.de (Matthias Feser)
Date: Mon, 13 Oct 2014 16:00:00 +0200
Subject: AM335x mehrere MMC-Bootquellen
Message-ID: <198ac8c9.1cfe6ee.1a970f3.504c@kbs-gmbh.de>

Hallo,

ich verwende barebox 2014.07 als Bootloader auf einem Custom-Board mit einer AM335x CPU. Auf dem Board ist per DIP-Schalter (angebunden an einen der SYSBOOT Pins) w?hlbar, ob von einem internen eMMC-Speicher oder einer uSD-Karte gebootet werden soll. Bootloader und Kernel werden zwar von der gew?hlten Quelle geladen, ich scheitere momentan jedoch daran den RootFs Kernelparameter automatisch je nach MMC-Instanz auszuw?hlen (entweder mmcblk0p2 oder mmcblk1p2). Ich m?chte es unbedingt vermeiden den Bootloader zweifach zu bauen. Meine erste Idee war, zwei boot Eintr?ge zu realisieren und dann den globalen Parameter global.boot.default im Boardinitialisierungscode entsprechend zu setzen. Sicherlich gibt es eine bessere L?sung. Ich w?re sehr dankbar um einen Ansatz seitens der Entwickler.

Auch beim Beagleboneblack besteht die M?glichkeit ?ber einen Drucktaster die Bootquelle zu selektieren, hier gibt es jedoch lediglich einen boot Eintrag, der standardm??ig ?ber global.boot.default=sd selektiert wird. Nach meinem Verst?ndnis d?rfte dieses Board grunds?tzlich von der SD-Karte booten.


Mit freundlichem Gru?
Matthias Feser



From CG at eks-engel.de  Mon Oct 13 07:36:28 2014
From: CG at eks-engel.de (Gieseler, Christian)
Date: Mon, 13 Oct 2014 14:36:28 +0000
Subject: AM335x mehrere MMC-Bootquellen
In-Reply-To: <198ac8c9.1cfe6ee.1a970f3.504c@kbs-gmbh.de>
References: <198ac8c9.1cfe6ee.1a970f3.504c@kbs-gmbh.de>
Message-ID: <C9183576C7342045BFDCAE863EB3C37A0B5CE431@EKS-Exchange.eks-engel.local>

Hi Matthias,

> -----Original Message-----
> From: barebox [mailto:barebox-bounces at lists.infradead.org] On Behalf 
> Of Matthias Feser
> Sent: Monday, October 13, 2014 4:00 PM
> To: 'barebox at lists.infradead.org'
> Subject: AM335x mehrere MMC-Bootquellen
> 
> Hallo,
> 
> ich verwende barebox 2014.07 als Bootloader auf einem Custom-Board mit 
> einer AM335x CPU. Auf dem Board ist per DIP-Schalter (angebunden an 
> einen der SYSBOOT Pins) w?hlbar, ob von einem internen eMMC-Speicher 
> oder einer uSD-Karte gebootet werden soll. Bootloader und Kernel 
> werden zwar von der gew?hlten Quelle geladen, ich scheitere momentan 
> jedoch daran den RootFs Kernelparameter automatisch je nach 
> MMC-Instanz auszuw?hlen (entweder mmcblk0p2 oder mmcblk1p2). Ich 
> m?chte es unbedingt vermeiden den Bootloader zweifach zu bauen. Meine 
> erste Idee war, zwei boot Eintr?ge zu realisieren und dann den 
> globalen Parameter global.boot.default im Boardinitialisierungscode entsprechend zu setzen.
> Sicherlich gibt es eine bessere L?sung. Ich w?re sehr dankbar um einen 
> Ansatz seitens der Entwickler.
> 
We use an initscript that does the choice for the kernel commandline entry.
$bootsource_instance should help you:
global linux.bootargs.root="root=/dev/mmcblk${bootsource_instance}p3"


> Auch beim Beagleboneblack besteht die M?glichkeit ?ber einen 
> Drucktaster die Bootquelle zu selektieren, hier gibt es jedoch 
> lediglich einen boot Eintrag, der standardm??ig ?ber 
> global.boot.default=sd selektiert wird. Nach meinem Verst?ndnis d?rfte 
> dieses Board grunds?tzlich von der SD-Karte booten.
> 
I think you are right about booting always from sd card.
As a sample the line from the same iniscript to make the entry depending on the bootsource:
global.boot.default="mci${bootsource_instance}.2"

Please observe that counting up partitions is different in barebox (starting with 0)and linux (starting with1).

Best Regards
Christian Gieseler


From s.hauer at pengutronix.de  Tue Oct 14 02:23:32 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 14 Oct 2014 11:23:32 +0200
Subject: [PATCH 1/6] ARM: defconfig: Enable of_display_timings in
 am335x_defconfig
In-Reply-To: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
References: <1412932473-38216-1-git-send-email-t.gamez@phytec.de>
Message-ID: <20141014092332.GT4992@pengutronix.de>


Applied all, thanks

Sascha

On Fri, Oct 10, 2014 at 11:14:28AM +0200, Teresa G?mez wrote:
> Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
> ---
>  arch/arm/configs/am335x_defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/configs/am335x_defconfig b/arch/arm/configs/am335x_defconfig
> index 6ef9c83..7dcfaed 100644
> --- a/arch/arm/configs/am335x_defconfig
> +++ b/arch/arm/configs/am335x_defconfig
> @@ -79,6 +79,7 @@ CONFIG_CMD_USBGADGET=y
>  CONFIG_CMD_BAREBOX_UPDATE=y
>  CONFIG_CMD_OF_NODE=y
>  CONFIG_CMD_OF_PROPERTY=y
> +CONFIG_CMD_OF_DISPLAY_TIMINGS=y
>  CONFIG_CMD_OFTREE=y
>  CONFIG_CMD_TIME=y
>  CONFIG_NET=y
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> 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 antonynpavlov at gmail.com  Wed Oct 15 05:42:12 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 15 Oct 2014 16:42:12 +0400
Subject: [PATCH 0/3] Add .mailmap file and a tool to maintain it
Message-ID: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>

Base on original u-boot patchseries by Masahiro Yamada.

See http://lists.denx.de/pipermail/u-boot/2014-July/183687.html


Antony Pavlov (2):
  add .mailmap for proper git-shortlog output
  Update .mailmap using scripts/mailmapper

Masahiro Yamada (1):
  scripts: add mailmapper, a tool to create/update mailmap file

 .mailmap           |  16 ++++++
 scripts/mailmapper | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 176 insertions(+)
 create mode 100644 .mailmap
 create mode 100755 scripts/mailmapper

-- 
2.1.1



From antonynpavlov at gmail.com  Wed Oct 15 05:42:13 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 15 Oct 2014 16:42:13 +0400
Subject: [PATCH 1/3] add .mailmap for proper git-shortlog output
In-Reply-To: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
References: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1413376935-2579-2-git-send-email-antonynpavlov@gmail.com>

Based on original u-boot commit by Masahiro Yamada:

  commit 8b90a11f7cf1d06812bc9a02e0bae20cfe40a564
  Author: Masahiro Yamada <yamada.m at jp.panasonic.com>
  Date:   Wed Jul 16 17:49:44 2014 +0900

      add .mailmap for proper git-shortlog output

This is the first version of .mailmap created by hand.
Please see "man git-shortlog" for what this commit is trying to do.

Without this file, for example, "git shortlog -n -s" shows as follows:

  (1)  5428  Sascha Hauer
        968  Jean-Christophe PLAGNIOL-VILLARD
  (2)   811  wdenk
  (2)   525  Wolfgang Denk
        348  Juergen Beisert
           ...
  (3)   154  stroese
  (3)   151  Stefan Roese
           ...
  (1)    48  sascha

And then, with this file, it shows as follows:

  (1)  5476  Sascha Hauer
  (2)  1336  Wolfgang Denk
        968  Jean-Christophe PLAGNIOL-VILLARD
        348  Juergen Beisert
        343  Antony Pavlov
  (3)   305  Stefan Roese

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
Cc: Masahiro Yamada <yamada.m at jp.panasonic.com>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Wolfgang Denk <wd at denx.de>
Cc: Stefan Roese <sr at denx.de>
---
 .mailmap | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..8af4375
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,13 @@
+#
+# This list is used by git-shortlog to fix a few botched name translations
+# in the git archive, either because the author's full name was messed up
+# and/or not always written the same way, making contributions from the
+# same person appearing not to be so or badly displayed.
+#
+# This file can be modified by hand or updated by the following command:
+#  scripts/mailmapper > tmp; mv tmp .mailmap
+#
+
+Sascha Hauer <sascha at nomad.localdomain>
+Stefan Roese <stroese>
+Wolfgang Denk <wdenk>
-- 
2.1.1



From antonynpavlov at gmail.com  Wed Oct 15 05:42:14 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 15 Oct 2014 16:42:14 +0400
Subject: [PATCH 2/3] scripts: add mailmapper,
 a tool to create/update mailmap file
In-Reply-To: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
References: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1413376935-2579-3-git-send-email-antonynpavlov@gmail.com>

From: Masahiro Yamada <yamada.m at jp.panasonic.com>

This tool helps to create/update the mailmap file.

It runs 'git shortlog' internally and searches differently spelled author
names which share the same email address. The author name with the most
commits is asuumed to be a canonical real name. If the number of commits
from the cananonical name is equal to or greater than 'MIN_COMMITS' (=50),
the entry for the cananical name will be output. ('MIN_COMMITS' is used
here because we do not want to create a fat mailmap by adding every author
with only a few commits.)

If there exists a mailmap file specified by the mailmap.file configuration
options or '.mailmap' at the toplevel of the repository, it is used as
a base file.

The base file and the newly added entries are merged together and sorted
alphabetically (but the comment block is kept untouched), and then printed
to standard output.

 Usage
 -----

  scripts/mailmapper

prints the mailmapping to standard output.

  scripts/mailmapper > tmp; mv tmp .mailmap

will be useful for updating '.mailmap' file.

Signed-off-by: Masahiro Yamada <yamada.m at jp.panasonic.com>
Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 scripts/mailmapper | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 160 insertions(+)

diff --git a/scripts/mailmapper b/scripts/mailmapper
new file mode 100755
index 0000000..dd1ddf6
--- /dev/null
+++ b/scripts/mailmapper
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2014, Masahiro Yamada <yamada.m at jp.panasonic.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+'''
+A tool to create/update the mailmap file
+
+The command 'git shortlog' summarizes git log output in a format suitable
+for inclusion in release announcements. Each commit will be grouped by
+author and title.
+
+One problem is that the authors' name and/or email address is sometimes
+spelled differently. The .mailmap feature can be used to coalesce together
+commits by the same persion.
+(See 'man git-shortlog' for furthur information of this feature.)
+
+This tool helps to create/update the mailmap file.
+
+It runs 'git shortlog' internally and searches differently spelled author
+names which share the same email address. The author name with the most
+commits is asuumed to be a canonical real name. If the number of commits
+from the cananonical name is equal to or greater than 'MIN_COMMITS',
+the entry for the cananical name will be output. ('MIN_COMMITS' is used
+here because we do not want to create a fat mailmap by adding every author
+with only a few commits.)
+
+If there exists a mailmap file specified by the mailmap.file configuration
+options or '.mailmap' at the toplevel of the repository, it is used as
+a base file. (The mailmap.file configuration takes precedence over the
+'.mailmap' file if both exist.)
+
+The base file and the newly added entries are merged together and sorted
+alphabetically (but the comment block is kept untouched), and then printed
+to standard output.
+
+Usage
+-----
+
+  scripts/mailmapper
+
+prints the mailmapping to standard output.
+
+  scripts/mailmapper > tmp; mv tmp .mailmap
+
+will be useful for updating '.mailmap' file.
+'''
+
+import sys
+import os
+import subprocess
+
+# The entries only for the canonical names with MIN_COMMITS or more commits.
+# This limitation is used so as not to create a too big mailmap file.
+MIN_COMMITS = 50
+
+try:
+    toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'])
+except subprocess.CalledProcessError:
+    print >> sys.stderr, 'Please run in a git repository.'
+    sys.exit(1)
+
+# strip '\n'
+toplevel = toplevel.rstrip()
+
+# Change the current working directory to the toplevel of the respository
+# for our easier life.
+os.chdir(toplevel)
+
+# First, create 'auther name' vs 'number of commits' database.
+# We assume the name with the most commits as the canonical real name.
+shortlog = subprocess.check_output(['git', 'shortlog', '-s', '-n'])
+
+commits_per_name = {}
+
+for line in shortlog.splitlines():
+    try:
+        commits, name = line.split(None, 1)
+    except ValueError:
+        # ignore lines with an empty author name
+        pass
+    commits_per_name[name] = int(commits)
+
+# Next, coalesce the auther names with the same email address
+shortlog = subprocess.check_output(['git', 'shortlog', '-s', '-n', '-e'])
+
+mail_vs_name = {}
+output = {}
+
+for line in shortlog.splitlines():
+    # tmp, mail = line.rsplit(None, 1) is not safe
+    # because weird email addresses might include whitespaces
+    tmp, mail = line.split('<')
+    mail = '<' + mail.rstrip()
+    try:
+        _, name = tmp.rstrip().split(None, 1)
+    except ValueError:
+        # author name is empty
+        name = ''
+    if mail in mail_vs_name:
+        # another name for the same email address
+        prev_name = mail_vs_name[mail]
+        # Take the name with more commits
+        major_name = sorted([prev_name, name],
+                            key=lambda x: commits_per_name[x] if x else 0)[1]
+        mail_vs_name[mail] = major_name
+        if commits_per_name[major_name] > MIN_COMMITS:
+            output[mail] = major_name
+    else:
+        mail_vs_name[mail] = name
+
+# [1] If there exists a mailmap file at the location pointed to
+#     by the mailmap.file configuration option, update it.
+# [2] If the file .mailmap exists at the toplevel of the repository, update it.
+# [3] Otherwise, create a new mailmap file.
+mailmap_files = []
+
+try:
+    config_mailmap = subprocess.check_output(['git', 'config', 'mailmap.file'])
+except subprocess.CalledProcessError:
+    config_mailmap = ''
+
+config_mailmap = config_mailmap.rstrip()
+if config_mailmap:
+    mailmap_files.append(config_mailmap)
+
+mailmap_files.append('.mailmap')
+
+infile = None
+
+for map_file in mailmap_files:
+    try:
+        infile = open(map_file)
+    except:
+        # Failed to open. Try next.
+        continue
+    break
+
+comment_block = []
+output_lines = []
+
+if infile:
+    for line in infile:
+        if line[0] == '#' or line[0] == '\n':
+            comment_block.append(line)
+        else:
+            output_lines.append(line)
+            break
+    for line in infile:
+        output_lines.append(line)
+    infile.close()
+
+for mail, name in output.items():
+    output_lines.append(name + ' ' + mail + '\n')
+
+output_lines.sort()
+
+sys.stdout.write(''.join(comment_block + output_lines))
-- 
2.1.1



From antonynpavlov at gmail.com  Wed Oct 15 05:42:15 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 15 Oct 2014 16:42:15 +0400
Subject: [PATCH 3/3] Update .mailmap using scripts/mailmapper
In-Reply-To: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
References: <1413376935-2579-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1413376935-2579-4-git-send-email-antonynpavlov@gmail.com>

Based on original u-boot commit by Masahiro Yamada:

  commit e89a07e3636d392869d8d00c9399111e65ee2e88
  Author: Masahiro Yamada <yamada.m at jp.panasonic.com>
  Date:   Wed Jul 16 17:49:46 2014 +0900

      Update .mailmap using scripts/mailmapper

Add more entries to .mailmap for the canonical names with
50 commits or more.

This commit was generated by the following command:

  scripts/mailmapper > tmp; mv tmp .mailmap

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
Cc: Masahiro Yamada <yamada.m at jp.panasonic.com>
Cc: Alexander Shiyan <shc at milas.spb.ru>
Cc: Eric B?nard <eric at eukrea.com>
Cc: Juergen Beisert <jbe at pengutronix.de>
---
 .mailmap | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.mailmap b/.mailmap
index 8af4375..e8e81a0 100644
--- a/.mailmap
+++ b/.mailmap
@@ -8,6 +8,9 @@
 #  scripts/mailmapper > tmp; mv tmp .mailmap
 #
 
+Alexander Shiyan <shc at milas.spb.ru>
+Eric B?nard <eric at eukrea.com>
+Juergen Beisert <jbe at pengutronix.de>
 Sascha Hauer <sascha at nomad.localdomain>
 Stefan Roese <stroese>
 Wolfgang Denk <wdenk>
-- 
2.1.1



From antonynpavlov at gmail.com  Wed Oct 15 22:28:05 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Thu, 16 Oct 2014 09:28:05 +0400
Subject: [PATCH] fixup! Update .mailmap using scripts/mailmapper
Message-ID: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>

MIN_COMMITS = 1 in scripts/mailmapper give us additional
.mailman strings:

+Franck Jullien <franck.jullien at gmail.com>
+Jin Zhengxiong <Jason.Jin at freescale.com>
+Marc Reilly <marc at cpdesign.com.au>
+Nishanth Menon <x0nishan at ti.com>
+Rapha?l Poggi <poggi.raph at gmail.com>
+Vicente Bergas <vicencb at gmail.com>
+Wjatscheslaw Stoljarski <wjatscheslaw.stoljarski at kiwigrid.com>
+gregory hermant <gregory.hermant at calao-systems.com>
+shravan <shravan.k at phytec.in>

I suppose these 9 strings can't make our .mailman file too big.

Also some .mailmap lines are added by hand:

+Robert Schwebel <rsc at thebe.(none)>
+Silvio Fricke <sfricke at data-modul.com>

Alas I don't know how to fix Markus Klotzbuecher's
<Markus Klotzb<FC>mk at pollux.(none)> mail address
with latin-1 character inside it.

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 .mailmap | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/.mailmap b/.mailmap
index e8e81a0..2e51c38 100644
--- a/.mailmap
+++ b/.mailmap
@@ -10,7 +10,18 @@
 
 Alexander Shiyan <shc at milas.spb.ru>
 Eric B?nard <eric at eukrea.com>
+Franck Jullien <franck.jullien at gmail.com>
+Jin Zhengxiong <Jason.Jin at freescale.com>
 Juergen Beisert <jbe at pengutronix.de>
+Marc Reilly <marc at cpdesign.com.au>
+Nishanth Menon <x0nishan at ti.com>
+Rapha?l Poggi <poggi.raph at gmail.com>
+Robert Schwebel <rsc at thebe.(none)>
 Sascha Hauer <sascha at nomad.localdomain>
+Silvio Fricke <sfricke at data-modul.com>
 Stefan Roese <stroese>
+Vicente Bergas <vicencb at gmail.com>
+Wjatscheslaw Stoljarski <wjatscheslaw.stoljarski at kiwigrid.com>
 Wolfgang Denk <wdenk>
+gregory hermant <gregory.hermant at calao-systems.com>
+shravan <shravan.k at phytec.in>
-- 
2.1.1



From voytikd at gmail.com  Thu Oct 16 05:52:20 2014
From: voytikd at gmail.com (Dmitry Voytik)
Date: Thu, 16 Oct 2014 16:52:20 +0400
Subject: [PATCH] usb: ehci-hcd: Correct CLEAR_FEATURE code
Message-ID: <1413463940-9651-1-git-send-email-voytikd@gmail.com>

This commit broke USB on olinuxino board:

  87b9bea USB: host: hub: Use usb_hub_power_on from U-Boot

This patch was ported from U-Boot with small changes. See discussion:
http://lists.denx.de/pipermail/u-boot/2013-May/153920.html

The root cause seems to be a missing mask and missing 'break' in
ehci-hcd.c. Fix both.

Signed-off-by: Dmitry Voytik <voytikd at gmail.com>
---
 drivers/usb/host/ehci-hcd.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 5624552..d2e1296 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -675,21 +675,23 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
 		break;
 	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
 		reg = ehci_readl(status_reg);
+		reg &= ~EHCI_PS_CLEAR;
 		switch (le16_to_cpu(req->value)) {
 		case USB_PORT_FEAT_ENABLE:
 			reg &= ~EHCI_PS_PE;
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
+			reg |= EHCI_PS_PEC;
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC(ehci_readl(&ehci->hccr->cr_hcsparams)))
-				reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
+				reg &= ~ EHCI_PS_PP;
+			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
+			reg |= EHCI_PS_CSC;
 			break;
 		case USB_PORT_FEAT_OVER_CURRENT:
-			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
+			reg |= EHCI_PS_OCC;
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			ehci->portreset &= ~(1 << le16_to_cpu(req->index));
-- 
1.9.1



From nm at ti.com  Thu Oct 16 07:31:26 2014
From: nm at ti.com (Nishanth Menon)
Date: Thu, 16 Oct 2014 09:31:26 -0500
Subject: [PATCH] fixup! Update .mailmap using scripts/mailmapper
In-Reply-To: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>
References: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <543FD6BE.2040008@ti.com>

On 10/16/2014 12:28 AM, Antony Pavlov wrote:
> +Nishanth Menon<x0nishan at ti.com>
Could you use Nishanth Menon <nm at ti.com> ? that has been my updated mail 
address for a few years now.

Thanks and Regards,
Nishanth Menon


From antonynpavlov at gmail.com  Thu Oct 16 07:52:35 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Thu, 16 Oct 2014 18:52:35 +0400
Subject: [PATCH] fixup! Update .mailmap using scripts/mailmapper
In-Reply-To: <543FD6BE.2040008@ti.com>
References: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>
 <543FD6BE.2040008@ti.com>
Message-ID: <20141016185235.a006819140c162c6871d4272@gmail.com>

On Thu, 16 Oct 2014 09:31:26 -0500
Nishanth Menon <nm at ti.com> wrote:

> On 10/16/2014 12:28 AM, Antony Pavlov wrote:
> > +Nishanth Menon<x0nishan at ti.com>
> Could you use Nishanth Menon <nm at ti.com> ? that has been my updated mail 
> address for a few years now.

Please see this quote from git-shortlog man page:

     The .mailmap feature is used to coalesce together commits by the same person in the
     shortlog, where their name and/or email address was spelled differently.

     ...

     In the simple form, each line in the file consists of the canonical real name of an
     author, whitespace, and an email address used in the commit (enclosed by < and >) to
     map to the name.

Also please see this git-log output:

  $ git log --author="Menon"  | grep ^Author: | uniq
  Author: Nishanth Menon <nm at ti.com>
  Author: Nishanth Menon <menon.nishanth at gmail.com>
  Author: Nishanth Menon <x0nishan at ti.com>
  Author: Menon, Nishanth <x0nishan at ti.com>
  Author: Nishanth Menon <x0nishan at ti.com>

This string in the .mailmap file
> > +Nishanth Menon <x0nishan at ti.com>

is used only for mapping "Menon, Nishanth" -> "Nishanth Menon".

Here is git-shortlog output without this string:

$ git shortlog -n -s --author="Menon" 
    35  Nishanth Menon
     4  Menon, Nishanth

So there is no need to add additional string containing <nm at ti.com> to the .mailmap file.

--?
Best regards,
? Antony Pavlov


From s.hauer at pengutronix.de  Fri Oct 17 02:11:28 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 17 Oct 2014 11:11:28 +0200
Subject: [PATCH] fixup! Update .mailmap using scripts/mailmapper
In-Reply-To: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>
References: <1413437285-9300-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20141017091128.GA14443@pengutronix.de>

On Thu, Oct 16, 2014 at 09:28:05AM +0400, Antony Pavlov wrote:
> MIN_COMMITS = 1 in scripts/mailmapper give us additional
> .mailman strings:
> 
> Alas I don't know how to fix Markus Klotzbuecher's
> <Markus Klotzb<FC>mk at pollux.(none)> mail address
> with latin-1 character inside it.
> 
> Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>

Applied the original series and this fixup.

Thanks
  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 dev at lynxeye.de  Mon Oct 20 11:15:29 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:29 +0200
Subject: [PATCH 1/2] reset_source: add thermal reset
Message-ID: <1413828930-12536-1-git-send-email-dev@lynxeye.de>

Some SoCs are able to detect if they got reset
in response to an overtemperature event.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 common/reset_source.c  | 1 +
 include/reset_source.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/common/reset_source.c b/common/reset_source.c
index 6026af1..946670b 100644
--- a/common/reset_source.c
+++ b/common/reset_source.c
@@ -25,6 +25,7 @@ static const char * const reset_src_names[] = {
 	[RESET_WDG] = "WDG",
 	[RESET_WKE] = "WKE",
 	[RESET_JTAG] = "JTAG",
+	[RESET_THERM] = "THERM",
 };
 
 static enum reset_src_type reset_source;
diff --git a/include/reset_source.h b/include/reset_source.h
index bff7f97..6620228 100644
--- a/include/reset_source.h
+++ b/include/reset_source.h
@@ -20,6 +20,7 @@ enum reset_src_type {
 	RESET_WDG,	/* watchdog */
 	RESET_WKE,	/* wake-up (some SoCs can handle this) */
 	RESET_JTAG,	/* JTAG reset */
+	RESET_THERM,	/* SoC shut down because of overtemperature */
 };
 
 #ifdef CONFIG_RESET_SOURCE
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:30 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:30 +0200
Subject: [PATCH 2/2] tegra: pmc: add support for reset src detection
In-Reply-To: <1413828930-12536-1-git-send-email-dev@lynxeye.de>
References: <1413828930-12536-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828930-12536-2-git-send-email-dev@lynxeye.de>

Also activate in defconfig.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/configs/tegra_v7_defconfig            |  1 +
 arch/arm/mach-tegra/include/mach/tegra20-pmc.h |  9 +++++++
 arch/arm/mach-tegra/tegra20-pmc.c              | 33 +++++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig
index 22f5765..3ad67be 100644
--- a/arch/arm/configs/tegra_v7_defconfig
+++ b/arch/arm/configs/tegra_v7_defconfig
@@ -16,6 +16,7 @@ CONFIG_AUTO_COMPLETE=y
 CONFIG_MENU=y
 CONFIG_BLSPEC=y
 CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_RESET_SOURCE=y
 CONFIG_LONGHELP=y
 CONFIG_CMD_IOMEM=y
 CONFIG_CMD_MEMINFO=y
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
index 30ac065..c379544 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
@@ -71,3 +71,12 @@
 #define PMC_PARTID_C0NC			15
 
 #define PMC_SCRATCH(i)			(0x050 + 0x4*i)
+
+#define PMC_RST_STATUS			0x1b4
+#define PMC_RST_STATUS_RST_SRC_SHIFT	0
+#define PMC_RST_STATUS_RST_SRC_MASK	(0x7 << PMC_RST_STATUS_RST_SRC_SHIFT)
+#define PMC_RST_STATUS_RST_SRC_POR	0
+#define PMC_RST_STATUS_RST_SRC_WATCHDOG	1
+#define PMC_RST_STATUS_RST_SRC_SENSOR	2
+#define PMC_RST_STATUS_RST_SRC_SW_MAIN	3
+#define PMC_RST_STATUS_RST_SRC_LP0	4
diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
index d868094..434a7eb 100644
--- a/arch/arm/mach-tegra/tegra20-pmc.c
+++ b/arch/arm/mach-tegra/tegra20-pmc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Lucas Stach <l.stach at pengutronix.de>
+ * Copyright (C) 2013-2014 Lucas Stach <l.stach at pengutronix.de>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -24,6 +24,7 @@
 #include <init.h>
 #include <io.h>
 #include <linux/err.h>
+#include <reset_source.h>
 
 #include <mach/tegra20-pmc.h>
 
@@ -38,6 +39,33 @@ void __noreturn reset_cpu(ulong addr)
 }
 EXPORT_SYMBOL(reset_cpu);
 
+static void tegra20_pmc_detect_reset_cause(void)
+{
+	u32 reg = readl(pmc_base + PMC_RST_STATUS);
+
+	switch ((reg & PMC_RST_STATUS_RST_SRC_MASK) >>
+	         PMC_RST_STATUS_RST_SRC_SHIFT) {
+	case PMC_RST_STATUS_RST_SRC_POR:
+		reset_source_set(RESET_POR);
+		break;
+	case PMC_RST_STATUS_RST_SRC_WATCHDOG:
+		reset_source_set(RESET_WDG);
+		break;
+	case PMC_RST_STATUS_RST_SRC_LP0:
+		reset_source_set(RESET_WKE);
+		break;
+	case PMC_RST_STATUS_RST_SRC_SW_MAIN:
+		reset_source_set(RESET_RST);
+		break;
+	case PMC_RST_STATUS_RST_SRC_SENSOR:
+		reset_source_set(RESET_THERM);
+		break;
+	default:
+		reset_source_set(RESET_UKWN);
+		break;
+	}
+}
+
 static int tegra20_pmc_probe(struct device_d *dev)
 {
 	pmc_base = dev_request_mem_region(dev, 0);
@@ -46,6 +74,9 @@ static int tegra20_pmc_probe(struct device_d *dev)
 		return PTR_ERR(pmc_base);
 	}
 
+	if (IS_ENABLED(CONFIG_RESET_SOURCE))
+		tegra20_pmc_detect_reset_cause();
+
 	return 0;
 }
 
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:55 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:55 +0200
Subject: [PATCH 1/7] imx: ipu-v3: fix typo leading to build warning
Message-ID: <1413828961-12605-1-git-send-email-dev@lynxeye.de>

This PAGE_SIZE clearly should not be there.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/video/imx-ipu-v3/ipu-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/imx-ipu-v3/ipu-common.c b/drivers/video/imx-ipu-v3/ipu-common.c
index c602363..f13cf01 100644
--- a/drivers/video/imx-ipu-v3/ipu-common.c
+++ b/drivers/video/imx-ipu-v3/ipu-common.c
@@ -796,7 +796,7 @@ static int ipu_probe(struct device_d *dev)
 	dev_dbg(dev, "vdi:      0x%p\n",
 			ipu_base + devtype->vdi_ofs);
 
-	ipu->cm_reg = ipu_base + devtype->cm_ofs, PAGE_SIZE;
+	ipu->cm_reg = ipu_base + devtype->cm_ofs;
 	ipu->idmac_reg = ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS;
 	ipu->cpmem_base = ipu_base + devtype->cpmem_ofs;
 
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:56 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:56 +0200
Subject: [PATCH 2/7] dfu: fix possible usage of uninitialized var
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-2-git-send-email-dev@lynxeye.de>

The error path would in fact use the status
variable without it being initialized first.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/usb/gadget/dfu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index 67a0703..351b584 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -207,6 +207,7 @@ dfu_bind(struct usb_configuration *c, struct usb_function *f)
 	dfu->dnreq = usb_ep_alloc_request(c->cdev->gadget->ep0);
 	if (!dfu->dnreq) {
 		printf("usb_ep_alloc_request failed\n");
+		status = -ENOMEM;
 		goto out;
 	}
 	dfu->dnreq->buf = dma_alloc(CONFIG_USBD_DFU_XFER_SIZE);
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:57 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:57 +0200
Subject: [PATCH 3/7] arm: boards: variscite-mx6: check i2c return value
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-3-git-send-email-dev@lynxeye.de>

ret wasn't checked previously.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/boards/variscite-mx6/board.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/variscite-mx6/board.c b/arch/arm/boards/variscite-mx6/board.c
index ce1284f..de74abc 100644
--- a/arch/arm/boards/variscite-mx6/board.c
+++ b/arch/arm/boards/variscite-mx6/board.c
@@ -49,7 +49,7 @@ static int setup_pmic_voltages(void)
 	unsigned char value, rev_id = 0 ;
 	struct i2c_adapter *adapter = NULL;
 	struct i2c_client client;
-	int addr = -1, ret, bus = 0;
+	int addr = -1, bus = 0;
 
 	/* I2C2 bus (2-1 = 1 in barebox numbering) */
 	bus = 1;
@@ -80,7 +80,10 @@ static int setup_pmic_voltages(void)
 
 	/* Set Gigabit Ethernet voltage (SOM v1.1/1.0)*/
         value = 0x60;
-	ret = i2c_write_reg(&client, 0x4a, &value, 1);
+	if (i2c_write_reg(&client, 0x4a, &value, 1) != 1) {
+		pr_err("Set ETH error!\n");
+		return -EIO;
+	}
 
 	/* set VGEN3 to 2.5V */
 	value = 0x77;
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:59 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:59 +0200
Subject: [PATCH 5/7] sha2: fix invalid length check
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-5-git-send-email-dev@lynxeye.de>

length is unsigned an thus can never be <0.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 crypto/sha2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/sha2.c b/crypto/sha2.c
index 26162e8..e495313 100644
--- a/crypto/sha2.c
+++ b/crypto/sha2.c
@@ -208,7 +208,7 @@ static void sha2_update(sha2_context * ctx, const uint8_t * input, size_t length
 	size_t fill;
 	uint32_t left;
 
-	if (length <= 0)
+	if (length = 0)
 		return;
 
 	left = ctx->total[0] & 0x3F;
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:15:58 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:15:58 +0200
Subject: [PATCH 4/7] arm: at91: remove unused variable
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-4-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm/mach-at91/clock.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 7a4282e..a7051c3 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -347,7 +347,6 @@ EXPORT_SYMBOL(clk_get_rate);
 
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	unsigned long	flags;
 	unsigned	prescale;
 	unsigned long	actual;
 	unsigned long	prev = ULONG_MAX;
@@ -376,7 +375,6 @@ EXPORT_SYMBOL(clk_round_rate);
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-	unsigned long	flags;
 	unsigned	prescale;
 	unsigned long	prescale_offset, css_mask;
 	unsigned long	actual;
@@ -421,8 +419,6 @@ EXPORT_SYMBOL(clk_get_parent);
 
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
-	unsigned long	flags;
-
 	if (clk->users)
 		return -EBUSY;
 	if (!clk_is_primary(parent) || !clk_is_programmable(clk))
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:16:01 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:16:01 +0200
Subject: [PATCH 7/7] clk: gate: remove superfluous code
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-7-git-send-email-dev@lynxeye.de>

This code didn't have any effect.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/clk/clk-gate.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 85eba3d..695e19a 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -132,14 +132,5 @@ struct clk *clk_gate(const char *name, const char *parent, void __iomem *reg,
 struct clk *clk_gate_inverted(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, unsigned flags)
 {
-	struct clk *clk;
-	struct clk_gate *g;
-
-	clk = clk_gate(name, parent, reg, shift, flags, CLK_GATE_INVERTED);
-	if (IS_ERR(clk))
-		return clk;
-
-	g = container_of(clk, struct clk_gate, clk);
-
-	return clk;
+	return clk_gate(name, parent, reg, shift, flags, CLK_GATE_INVERTED);
 }
-- 
1.9.3



From dev at lynxeye.de  Mon Oct 20 11:16:00 2014
From: dev at lynxeye.de (Lucas Stach)
Date: Mon, 20 Oct 2014 20:16:00 +0200
Subject: [PATCH 6/7] i2c: at91: fix invalid length check
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <1413828961-12605-6-git-send-email-dev@lynxeye.de>

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 drivers/i2c/busses/i2c-at91.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index deb4ea4..3a644cf 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -140,7 +140,7 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)
 
 static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
 {
-	if (dev->buf_len <= 0)
+	if (!dev->buf_len)
 		return;
 
 	at91_twi_write(dev, AT91_TWI_THR, *dev->buf);
@@ -156,7 +156,7 @@ static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
 
 static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
 {
-	if (dev->buf_len <= 0)
+	if (!dev->buf_len)
 		return;
 
 	*dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
-- 
1.9.3



From alex.aring at gmail.com  Mon Oct 20 14:06:49 2014
From: alex.aring at gmail.com (Alexander Aring)
Date: Mon, 20 Oct 2014 23:06:49 +0200
Subject: [PATCH 5/7] sha2: fix invalid length check
In-Reply-To: <1413828961-12605-5-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
 <1413828961-12605-5-git-send-email-dev@lynxeye.de>
Message-ID: <20141020210647.GA1676@omega>

Hi Lucas,

On Mon, Oct 20, 2014 at 08:15:59PM +0200, Lucas Stach wrote:
> length is unsigned an thus can never be <0.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>
> ---
>  crypto/sha2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/crypto/sha2.c b/crypto/sha2.c
> index 26162e8..e495313 100644
> --- a/crypto/sha2.c
> +++ b/crypto/sha2.c
> @@ -208,7 +208,7 @@ static void sha2_update(sha2_context * ctx, const uint8_t * input, size_t length
>  	size_t fill;
>  	uint32_t left;
>  
> -	if (length <= 0)
> +	if (length = 0)

should be (length == 0).

- Alex


From voice.shen at atmel.com  Mon Oct 20 18:56:54 2014
From: voice.shen at atmel.com (Bo Shen)
Date: Tue, 21 Oct 2014 09:56:54 +0800
Subject: [PATCH 4/7] arm: at91: remove unused variable
In-Reply-To: <1413828961-12605-4-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
 <1413828961-12605-4-git-send-email-dev@lynxeye.de>
Message-ID: <5445BD66.5030603@atmel.com>

Hi Lucas,

On 10/21/2014 02:15 AM, Lucas Stach wrote:
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Acked-by: Bo Shen <voice.shen at atmel.com>

> ---
>   arch/arm/mach-at91/clock.c | 4 ----
>   1 file changed, 4 deletions(-)
>
> diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
> index 7a4282e..a7051c3 100644
> --- a/arch/arm/mach-at91/clock.c
> +++ b/arch/arm/mach-at91/clock.c
> @@ -347,7 +347,6 @@ EXPORT_SYMBOL(clk_get_rate);
>
>   long clk_round_rate(struct clk *clk, unsigned long rate)
>   {
> -	unsigned long	flags;
>   	unsigned	prescale;
>   	unsigned long	actual;
>   	unsigned long	prev = ULONG_MAX;
> @@ -376,7 +375,6 @@ EXPORT_SYMBOL(clk_round_rate);
>
>   int clk_set_rate(struct clk *clk, unsigned long rate)
>   {
> -	unsigned long	flags;
>   	unsigned	prescale;
>   	unsigned long	prescale_offset, css_mask;
>   	unsigned long	actual;
> @@ -421,8 +419,6 @@ EXPORT_SYMBOL(clk_get_parent);
>
>   int clk_set_parent(struct clk *clk, struct clk *parent)
>   {
> -	unsigned long	flags;
> -
>   	if (clk->users)
>   		return -EBUSY;
>   	if (!clk_is_primary(parent) || !clk_is_programmable(clk))
>

Best Regards,
Bo Shen


From voice.shen at atmel.com  Mon Oct 20 19:01:10 2014
From: voice.shen at atmel.com (Bo Shen)
Date: Tue, 21 Oct 2014 10:01:10 +0800
Subject: [PATCH 6/7] i2c: at91: fix invalid length check
In-Reply-To: <1413828961-12605-6-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
 <1413828961-12605-6-git-send-email-dev@lynxeye.de>
Message-ID: <5445BE66.8020803@atmel.com>

Hi Lucas,

On 10/21/2014 02:16 AM, Lucas Stach wrote:
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Acked-by: Bo Shen <voice.shen at atmel.com>

> ---
>   drivers/i2c/busses/i2c-at91.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index deb4ea4..3a644cf 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -140,7 +140,7 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)
>
>   static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
>   {
> -	if (dev->buf_len <= 0)
> +	if (!dev->buf_len)
>   		return;
>
>   	at91_twi_write(dev, AT91_TWI_THR, *dev->buf);
> @@ -156,7 +156,7 @@ static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
>
>   static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
>   {
> -	if (dev->buf_len <= 0)
> +	if (!dev->buf_len)
>   		return;
>
>   	*dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
>

Best Regards,
Bo Shen



From s.hauer at pengutronix.de  Tue Oct 21 03:59:10 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Oct 2014 12:59:10 +0200
Subject: [PATCH] usb: ehci-hcd: Correct CLEAR_FEATURE code
In-Reply-To: <1413463940-9651-1-git-send-email-voytikd@gmail.com>
References: <1413463940-9651-1-git-send-email-voytikd@gmail.com>
Message-ID: <20141021105910.GM14443@pengutronix.de>

On Thu, Oct 16, 2014 at 04:52:20PM +0400, Dmitry Voytik wrote:
> This commit broke USB on olinuxino board:
> 
>   87b9bea USB: host: hub: Use usb_hub_power_on from U-Boot
> 
> This patch was ported from U-Boot with small changes. See discussion:
> http://lists.denx.de/pipermail/u-boot/2013-May/153920.html
> 
> The root cause seems to be a missing mask and missing 'break' in
> ehci-hcd.c. Fix both.
> 
> Signed-off-by: Dmitry Voytik <voytikd at gmail.com>

Applied, thanks

Sascha

> ---
>  drivers/usb/host/ehci-hcd.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 5624552..d2e1296 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -675,21 +675,23 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
>  		break;
>  	case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
>  		reg = ehci_readl(status_reg);
> +		reg &= ~EHCI_PS_CLEAR;
>  		switch (le16_to_cpu(req->value)) {
>  		case USB_PORT_FEAT_ENABLE:
>  			reg &= ~EHCI_PS_PE;
>  			break;
>  		case USB_PORT_FEAT_C_ENABLE:
> -			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
> +			reg |= EHCI_PS_PEC;
>  			break;
>  		case USB_PORT_FEAT_POWER:
>  			if (HCS_PPC(ehci_readl(&ehci->hccr->cr_hcsparams)))
> -				reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
> +				reg &= ~ EHCI_PS_PP;
> +			break;
>  		case USB_PORT_FEAT_C_CONNECTION:
> -			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
> +			reg |= EHCI_PS_CSC;
>  			break;
>  		case USB_PORT_FEAT_OVER_CURRENT:
> -			reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
> +			reg |= EHCI_PS_OCC;
>  			break;
>  		case USB_PORT_FEAT_C_RESET:
>  			ehci->portreset &= ~(1 << le16_to_cpu(req->index));
> -- 
> 1.9.1
> 
> 

-- 
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 Oct 21 04:09:03 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Oct 2014 13:09:03 +0200
Subject: [PATCH 1/7] imx: ipu-v3: fix typo leading to build warning
In-Reply-To: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
Message-ID: <20141021110903.GN14443@pengutronix.de>

On Mon, Oct 20, 2014 at 08:15:55PM +0200, Lucas Stach wrote:
> This PAGE_SIZE clearly should not be there.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Applied all, thanks

Sascha

> ---
>  drivers/video/imx-ipu-v3/ipu-common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/video/imx-ipu-v3/ipu-common.c b/drivers/video/imx-ipu-v3/ipu-common.c
> index c602363..f13cf01 100644
> --- a/drivers/video/imx-ipu-v3/ipu-common.c
> +++ b/drivers/video/imx-ipu-v3/ipu-common.c
> @@ -796,7 +796,7 @@ static int ipu_probe(struct device_d *dev)
>  	dev_dbg(dev, "vdi:      0x%p\n",
>  			ipu_base + devtype->vdi_ofs);
>  
> -	ipu->cm_reg = ipu_base + devtype->cm_ofs, PAGE_SIZE;
> +	ipu->cm_reg = ipu_base + devtype->cm_ofs;
>  	ipu->idmac_reg = ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS;
>  	ipu->cpmem_base = ipu_base + devtype->cpmem_ofs;
>  
> -- 
> 1.9.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 s.hauer at pengutronix.de  Tue Oct 21 04:09:31 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Oct 2014 13:09:31 +0200
Subject: [PATCH 5/7] sha2: fix invalid length check
In-Reply-To: <20141020210647.GA1676@omega>
References: <1413828961-12605-1-git-send-email-dev@lynxeye.de>
 <1413828961-12605-5-git-send-email-dev@lynxeye.de>
 <20141020210647.GA1676@omega>
Message-ID: <20141021110931.GO14443@pengutronix.de>

On Mon, Oct 20, 2014 at 11:06:49PM +0200, Alexander Aring wrote:
> Hi Lucas,
> 
> On Mon, Oct 20, 2014 at 08:15:59PM +0200, Lucas Stach wrote:
> > length is unsigned an thus can never be <0.
> > 
> > Signed-off-by: Lucas Stach <dev at lynxeye.de>
> > ---
> >  crypto/sha2.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/crypto/sha2.c b/crypto/sha2.c
> > index 26162e8..e495313 100644
> > --- a/crypto/sha2.c
> > +++ b/crypto/sha2.c
> > @@ -208,7 +208,7 @@ static void sha2_update(sha2_context * ctx, const uint8_t * input, size_t length
> >  	size_t fill;
> >  	uint32_t left;
> >  
> > -	if (length <= 0)
> > +	if (length = 0)
> 
> should be (length == 0).

Fixed while applying.

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 Oct 21 04:12:10 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 21 Oct 2014 13:12:10 +0200
Subject: [PATCH 1/2] reset_source: add thermal reset
In-Reply-To: <1413828930-12536-1-git-send-email-dev@lynxeye.de>
References: <1413828930-12536-1-git-send-email-dev@lynxeye.de>
Message-ID: <20141021111210.GP14443@pengutronix.de>

On Mon, Oct 20, 2014 at 08:15:29PM +0200, Lucas Stach wrote:
> Some SoCs are able to detect if they got reset
> in response to an overtemperature event.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Applied, thanks

Sascha

> ---
>  common/reset_source.c  | 1 +
>  include/reset_source.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/common/reset_source.c b/common/reset_source.c
> index 6026af1..946670b 100644
> --- a/common/reset_source.c
> +++ b/common/reset_source.c
> @@ -25,6 +25,7 @@ static const char * const reset_src_names[] = {
>  	[RESET_WDG] = "WDG",
>  	[RESET_WKE] = "WKE",
>  	[RESET_JTAG] = "JTAG",
> +	[RESET_THERM] = "THERM",
>  };
>  
>  static enum reset_src_type reset_source;
> diff --git a/include/reset_source.h b/include/reset_source.h
> index bff7f97..6620228 100644
> --- a/include/reset_source.h
> +++ b/include/reset_source.h
> @@ -20,6 +20,7 @@ enum reset_src_type {
>  	RESET_WDG,	/* watchdog */
>  	RESET_WKE,	/* wake-up (some SoCs can handle this) */
>  	RESET_JTAG,	/* JTAG reset */
> +	RESET_THERM,	/* SoC shut down because of overtemperature */
>  };
>  
>  #ifdef CONFIG_RESET_SOURCE
> -- 
> 1.9.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 shc_work at mail.ru  Tue Oct 21 09:34:03 2014
From: shc_work at mail.ru (=?UTF-8?B?QWxleGFuZGVyIFNoaXlhbg==?=)
Date: Tue, 21 Oct 2014 20:34:03 +0400
Subject: =?UTF-8?B?TFBDNDN4eA==?=
Message-ID: <1413909243.628274148@f65.i.mail.ru>

Hello all.

We started developing device which uses NXP LPC43xx CPU. I would like to add
support for this CPU series into barebox.
The problem is that there is no support for this architecture in the Linux kernel,
and it would upset the current concept (the barebox tree is very similar to Linux
tree and we not have any orphan arch-s).
What you recommend to do?

Thanks!
---

From u.kleine-koenig at pengutronix.de  Tue Oct 21 23:41:09 2014
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 22 Oct 2014 08:41:09 +0200
Subject: LPC43xx
In-Reply-To: <1413909243.628274148@f65.i.mail.ru>
References: <1413909243.628274148@f65.i.mail.ru>
Message-ID: <20141022064109.GH8316@pengutronix.de>

Hello,

On Tue, Oct 21, 2014 at 08:34:03PM +0400, Alexander Shiyan wrote:
> We started developing device which uses NXP LPC43xx CPU. I would like to add
> support for this CPU series into barebox.
> The problem is that there is no support for this architecture in the Linux kernel,
> and it would upset the current concept (the barebox tree is very similar to Linux
> tree and we not have any orphan arch-s).
> What you recommend to do?
The two obvious options are:

 - place support for your CPU where it would be for Linux
 - add support for your CPU to Linux

I'm (obviously) not Sascha, but I guess both would be fine.

Best regards
Uwe

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


From s.hauer at pengutronix.de  Wed Oct 22 00:50:53 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Oct 2014 09:50:53 +0200
Subject: LPC43xx
In-Reply-To: <1413909243.628274148@f65.i.mail.ru>
References: <1413909243.628274148@f65.i.mail.ru>
Message-ID: <20141022075053.GW14443@pengutronix.de>

On Tue, Oct 21, 2014 at 08:34:03PM +0400, Alexander Shiyan wrote:
> Hello all.
> 
> We started developing device which uses NXP LPC43xx CPU. I would like to add
> support for this CPU series into barebox.
> The problem is that there is no support for this architecture in the Linux kernel,
> and it would upset the current concept (the barebox tree is very similar to Linux
> tree and we not have any orphan arch-s).
> What you recommend to do?

Just create the architecture for barebox. If the Linux Kernel gets
support for the architecture we can still rename it if we want 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 m.olbrich at pengutronix.de  Wed Oct 22 03:47:52 2014
From: m.olbrich at pengutronix.de (Michael Olbrich)
Date: Wed, 22 Oct 2014 12:47:52 +0200
Subject: [PATCH] EFI: report correct block device size
Message-ID: <1413974872-23330-1-git-send-email-m.olbrich@pengutronix.de>

last_block is a zero-based block number, so the total number of blocks is
last_block + 1

Signed-off-by: Michael Olbrich <m.olbrich at pengutronix.de>
---
 arch/efi/efi/efi-block-io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/efi/efi/efi-block-io.c b/arch/efi/efi/efi-block-io.c
index 00115317fc9b..85603d913d5b 100644
--- a/arch/efi/efi/efi-block-io.c
+++ b/arch/efi/efi/efi-block-io.c
@@ -149,7 +149,7 @@ int efi_bio_probe(struct efi_device *efidev)
 
 	priv->blk.cdev.name = asprintf("disk%d", cdev_find_free_index("disk"));
 	priv->blk.blockbits = ffs(media->block_size) - 1;
-	priv->blk.num_blocks = media->last_block;
+	priv->blk.num_blocks = media->last_block + 1;
 	priv->blk.ops = &efi_bio_ops;
 	priv->blk.dev = &efidev->dev;
 
-- 
2.1.1



From s.hauer at pengutronix.de  Wed Oct 22 06:57:16 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Oct 2014 15:57:16 +0200
Subject: [PATCH] include/environment.h: Add missing include
Message-ID: <1413986236-893-1-git-send-email-s.hauer@pengutronix.de>

include/environment.h uses error codes, so it needs errno.h.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/environment.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/environment.h b/include/environment.h
index a08f597..52eafe9 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -21,6 +21,7 @@
 #define _ENVIRONMENT_H_
 
 #include <linux/list.h>
+#include <errno.h>
 
 /**
  * Managment of a environment variable
-- 
2.1.1



From s.hauer at pengutronix.de  Wed Oct 22 06:58:20 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Oct 2014 15:58:20 +0200
Subject: [PATCH 1/2] ARM i.MX6: mmdc: Only print calibration values of enabled
 phys
Message-ID: <1413986301-27238-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/imx6-mmdc.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/imx6-mmdc.c b/arch/arm/mach-imx/imx6-mmdc.c
index 0e706ce..dc60478 100644
--- a/arch/arm/mach-imx/imx6-mmdc.c
+++ b/arch/arm/mach-imx/imx6-mmdc.c
@@ -516,14 +516,18 @@ int mmdc_do_dqs_calibration(void)
 	pr_debug("\nRead DQS Gating calibration\n");
 	pr_debug("MPDGCTRL0 PHY0 (0x021b083c) = 0x%08X\n", readl(P0_IPS + MPDGCTRL0));
 	pr_debug("MPDGCTRL1 PHY0 (0x021b0840) = 0x%08X\n", readl(P0_IPS + MPDGCTRL1));
-	pr_debug("MPDGCTRL0 PHY1 (0x021b483c) = 0x%08X\n", readl(P1_IPS + MPDGCTRL0));
-	pr_debug("MPDGCTRL1 PHY1 (0x021b4840) = 0x%08X\n", readl(P1_IPS + MPDGCTRL1));
+	if (data_bus_size == 0x2) {
+		pr_debug("MPDGCTRL0 PHY1 (0x021b483c) = 0x%08X\n", readl(P1_IPS + MPDGCTRL0));
+		pr_debug("MPDGCTRL1 PHY1 (0x021b4840) = 0x%08X\n", readl(P1_IPS + MPDGCTRL1));
+	}
 	pr_debug("\nRead calibration\n");
 	pr_debug("MPRDDLCTL PHY0 (0x021b0848) = 0x%08X\n", readl(P0_IPS + MPRDDLCTL));
-	pr_debug("MPRDDLCTL PHY1 (0x021b4848) = 0x%08X\n", readl(P1_IPS + MPRDDLCTL));
+	if (data_bus_size == 0x2)
+		pr_debug("MPRDDLCTL PHY1 (0x021b4848) = 0x%08X\n", readl(P1_IPS + MPRDDLCTL));
 	pr_debug("\nWrite calibration\n");
 	pr_debug("MPWRDLCTL PHY0 (0x021b0850) = 0x%08X\n", readl(P0_IPS + MPWRDLCTL));
-	pr_debug("MPWRDLCTL PHY1 (0x021b4850) = 0x%08X\n", readl(P1_IPS + MPWRDLCTL));
+	if (data_bus_size == 0x2)
+		pr_debug("MPWRDLCTL PHY1 (0x021b4850) = 0x%08X\n", readl(P1_IPS + MPWRDLCTL));
 	pr_debug("\n");
 	/*
 	 * registers below are for debugging purposes
@@ -534,10 +538,12 @@ int mmdc_do_dqs_calibration(void)
 	pr_debug("MPDGHWST1 PHY0 (0x021b0880) = 0x%08X\n", readl(P0_IPS + MPDGHWST1));
 	pr_debug("MPDGHWST2 PHY0 (0x021b0884) = 0x%08X\n", readl(P0_IPS + MPDGHWST2));
 	pr_debug("MPDGHWST3 PHY0 (0x021b0888) = 0x%08X\n", readl(P0_IPS + MPDGHWST3));
-	pr_debug("MPDGHWST0 PHY1 (0x021b487c) = 0x%08X\n", readl(P1_IPS + MPDGHWST0));
-	pr_debug("MPDGHWST1 PHY1 (0x021b4880) = 0x%08X\n", readl(P1_IPS + MPDGHWST1));
-	pr_debug("MPDGHWST2 PHY1 (0x021b4884) = 0x%08X\n", readl(P1_IPS + MPDGHWST2));
-	pr_debug("MPDGHWST3 PHY1 (0x021b4888) = 0x%08X\n", readl(P1_IPS + MPDGHWST3));
+	if (data_bus_size == 0x2) {
+		pr_debug("MPDGHWST0 PHY1 (0x021b487c) = 0x%08X\n", readl(P1_IPS + MPDGHWST0));
+		pr_debug("MPDGHWST1 PHY1 (0x021b4880) = 0x%08X\n", readl(P1_IPS + MPDGHWST1));
+		pr_debug("MPDGHWST2 PHY1 (0x021b4884) = 0x%08X\n", readl(P1_IPS + MPDGHWST2));
+		pr_debug("MPDGHWST3 PHY1 (0x021b4888) = 0x%08X\n", readl(P1_IPS + MPDGHWST3));
+	}
 
 	return errorcount;
 }
-- 
2.1.1



From s.hauer at pengutronix.de  Wed Oct 22 06:58:21 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 22 Oct 2014 15:58:21 +0200
Subject: [PATCH 2/2] ARM i.MX6: mmdc: move calibration result printout to
 separate function
In-Reply-To: <1413986301-27238-1-git-send-email-s.hauer@pengutronix.de>
References: <1413986301-27238-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1413986301-27238-2-git-send-email-s.hauer@pengutronix.de>

To be able to print the results without compiling with DEBUG enabled.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/mach-imx/imx6-mmdc.c              | 55 +++++++++++++++++-------------
 arch/arm/mach-imx/include/mach/imx6-mmdc.h |  1 +
 2 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-imx/imx6-mmdc.c b/arch/arm/mach-imx/imx6-mmdc.c
index dc60478..c460d9b 100644
--- a/arch/arm/mach-imx/imx6-mmdc.c
+++ b/arch/arm/mach-imx/imx6-mmdc.c
@@ -512,40 +512,47 @@ int mmdc_do_dqs_calibration(void)
 	/* poll to make sure the con_ack bit is clear */
 	while (readl(P0_IPS + MDSCR) & 0x00004000) ;
 
-	pr_debug("MMDC registers updated from calibration \n");
-	pr_debug("\nRead DQS Gating calibration\n");
-	pr_debug("MPDGCTRL0 PHY0 (0x021b083c) = 0x%08X\n", readl(P0_IPS + MPDGCTRL0));
-	pr_debug("MPDGCTRL1 PHY0 (0x021b0840) = 0x%08X\n", readl(P0_IPS + MPDGCTRL1));
+	return errorcount;
+}
+
+void mmdc_print_calibration_results(void)
+{
+	int data_bus_size;
+
+	data_bus_size = (readl(P0_IPS + MDCTL) & 0x30000) >> 16;
+
+	printf("MMDC registers updated from calibration \n");
+	printf("\nRead DQS Gating calibration\n");
+	printf("MPDGCTRL0 PHY0 (0x021b083c) = 0x%08X\n", readl(P0_IPS + MPDGCTRL0));
+	printf("MPDGCTRL1 PHY0 (0x021b0840) = 0x%08X\n", readl(P0_IPS + MPDGCTRL1));
 	if (data_bus_size == 0x2) {
-		pr_debug("MPDGCTRL0 PHY1 (0x021b483c) = 0x%08X\n", readl(P1_IPS + MPDGCTRL0));
-		pr_debug("MPDGCTRL1 PHY1 (0x021b4840) = 0x%08X\n", readl(P1_IPS + MPDGCTRL1));
+		printf("MPDGCTRL0 PHY1 (0x021b483c) = 0x%08X\n", readl(P1_IPS + MPDGCTRL0));
+		printf("MPDGCTRL1 PHY1 (0x021b4840) = 0x%08X\n", readl(P1_IPS + MPDGCTRL1));
 	}
-	pr_debug("\nRead calibration\n");
-	pr_debug("MPRDDLCTL PHY0 (0x021b0848) = 0x%08X\n", readl(P0_IPS + MPRDDLCTL));
+	printf("\nRead calibration\n");
+	printf("MPRDDLCTL PHY0 (0x021b0848) = 0x%08X\n", readl(P0_IPS + MPRDDLCTL));
 	if (data_bus_size == 0x2)
-		pr_debug("MPRDDLCTL PHY1 (0x021b4848) = 0x%08X\n", readl(P1_IPS + MPRDDLCTL));
-	pr_debug("\nWrite calibration\n");
-	pr_debug("MPWRDLCTL PHY0 (0x021b0850) = 0x%08X\n", readl(P0_IPS + MPWRDLCTL));
+		printf("MPRDDLCTL PHY1 (0x021b4848) = 0x%08X\n", readl(P1_IPS + MPRDDLCTL));
+	printf("\nWrite calibration\n");
+	printf("MPWRDLCTL PHY0 (0x021b0850) = 0x%08X\n", readl(P0_IPS + MPWRDLCTL));
 	if (data_bus_size == 0x2)
-		pr_debug("MPWRDLCTL PHY1 (0x021b4850) = 0x%08X\n", readl(P1_IPS + MPWRDLCTL));
-	pr_debug("\n");
+		printf("MPWRDLCTL PHY1 (0x021b4850) = 0x%08X\n", readl(P1_IPS + MPWRDLCTL));
+	printf("\n");
 	/*
 	 * registers below are for debugging purposes
 	 * these print out the upper and lower boundaries captured during read DQS gating calibration
 	 */
-	pr_debug("Status registers, upper and lower bounds, for read DQS gating. \n");
-	pr_debug("MPDGHWST0 PHY0 (0x021b087c) = 0x%08X\n", readl(P0_IPS + MPDGHWST0));
-	pr_debug("MPDGHWST1 PHY0 (0x021b0880) = 0x%08X\n", readl(P0_IPS + MPDGHWST1));
-	pr_debug("MPDGHWST2 PHY0 (0x021b0884) = 0x%08X\n", readl(P0_IPS + MPDGHWST2));
-	pr_debug("MPDGHWST3 PHY0 (0x021b0888) = 0x%08X\n", readl(P0_IPS + MPDGHWST3));
+	printf("Status registers, upper and lower bounds, for read DQS gating. \n");
+	printf("MPDGHWST0 PHY0 (0x021b087c) = 0x%08X\n", readl(P0_IPS + MPDGHWST0));
+	printf("MPDGHWST1 PHY0 (0x021b0880) = 0x%08X\n", readl(P0_IPS + MPDGHWST1));
+	printf("MPDGHWST2 PHY0 (0x021b0884) = 0x%08X\n", readl(P0_IPS + MPDGHWST2));
+	printf("MPDGHWST3 PHY0 (0x021b0888) = 0x%08X\n", readl(P0_IPS + MPDGHWST3));
 	if (data_bus_size == 0x2) {
-		pr_debug("MPDGHWST0 PHY1 (0x021b487c) = 0x%08X\n", readl(P1_IPS + MPDGHWST0));
-		pr_debug("MPDGHWST1 PHY1 (0x021b4880) = 0x%08X\n", readl(P1_IPS + MPDGHWST1));
-		pr_debug("MPDGHWST2 PHY1 (0x021b4884) = 0x%08X\n", readl(P1_IPS + MPDGHWST2));
-		pr_debug("MPDGHWST3 PHY1 (0x021b4888) = 0x%08X\n", readl(P1_IPS + MPDGHWST3));
+		printf("MPDGHWST0 PHY1 (0x021b487c) = 0x%08X\n", readl(P1_IPS + MPDGHWST0));
+		printf("MPDGHWST1 PHY1 (0x021b4880) = 0x%08X\n", readl(P1_IPS + MPDGHWST1));
+		printf("MPDGHWST2 PHY1 (0x021b4884) = 0x%08X\n", readl(P1_IPS + MPDGHWST2));
+		printf("MPDGHWST3 PHY1 (0x021b4888) = 0x%08X\n", readl(P1_IPS + MPDGHWST3));
 	}
-
-	return errorcount;
 }
 
 #ifdef MMDC_SOFTWARE_CALIBRATION
diff --git a/arch/arm/mach-imx/include/mach/imx6-mmdc.h b/arch/arm/mach-imx/include/mach/imx6-mmdc.h
index d07950d..6ab8049 100644
--- a/arch/arm/mach-imx/include/mach/imx6-mmdc.h
+++ b/arch/arm/mach-imx/include/mach/imx6-mmdc.h
@@ -52,5 +52,6 @@
 
 int mmdc_do_write_level_calibration(void);
 int mmdc_do_dqs_calibration(void);
+void mmdc_print_calibration_results(void);
 
 #endif /* __MACH_MMDC_H */
-- 
2.1.1



From s.hauer at pengutronix.de  Wed Oct 22 22:32:15 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 23 Oct 2014 07:32:15 +0200
Subject: [PATCH] EFI: report correct block device size
In-Reply-To: <1413974872-23330-1-git-send-email-m.olbrich@pengutronix.de>
References: <1413974872-23330-1-git-send-email-m.olbrich@pengutronix.de>
Message-ID: <20141023053215.GC14443@pengutronix.de>

On Wed, Oct 22, 2014 at 12:47:52PM +0200, Michael Olbrich wrote:
> last_block is a zero-based block number, so the total number of blocks is
> last_block + 1
> 
> Signed-off-by: Michael Olbrich <m.olbrich at pengutronix.de>

Applied, thanks

Sascha

> ---
>  arch/efi/efi/efi-block-io.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/efi/efi/efi-block-io.c b/arch/efi/efi/efi-block-io.c
> index 00115317fc9b..85603d913d5b 100644
> --- a/arch/efi/efi/efi-block-io.c
> +++ b/arch/efi/efi/efi-block-io.c
> @@ -149,7 +149,7 @@ int efi_bio_probe(struct efi_device *efidev)
>  
>  	priv->blk.cdev.name = asprintf("disk%d", cdev_find_free_index("disk"));
>  	priv->blk.blockbits = ffs(media->block_size) - 1;
> -	priv->blk.num_blocks = media->last_block;
> +	priv->blk.num_blocks = media->last_block + 1;
>  	priv->blk.ops = &efi_bio_ops;
>  	priv->blk.dev = &efidev->dev;
>  
> -- 
> 2.1.1
> 
> 
> _______________________________________________
> 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  Wed Oct 22 22:52:02 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 23 Oct 2014 07:52:02 +0200
Subject: [PATCH] lib: parameter: fixed doku renamed ip -> ipaddr
In-Reply-To: <1413199640-6317-1-git-send-email-embedded24@evers-fischer.de>
References: <1413199640-6317-1-git-send-email-embedded24@evers-fischer.de>
Message-ID: <20141023055202.GE14443@pengutronix.de>

On Mon, Oct 13, 2014 at 01:27:20PM +0200, Rolf Evers-Fischer wrote:
> Long time ago all ".ip" parameters have been replaced with ".ipaddr".
> 
> Signed-off-by: Rolf Evers-Fischer <embedded24 at evers-fischer.de>

Applied, thanks

Sascha

> ---
>  lib/parameter.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/parameter.c b/lib/parameter.c
> index 84a632c..c4c30ca 100644
> --- a/lib/parameter.c
> +++ b/lib/parameter.c
> @@ -776,8 +776,8 @@ with device paramters. Device parameters are always strings, although there
>  are functions to interpret them as something else. 'hush' users can access
>  parameters as a local variable which have a dot (.) in them. So setting the
>  IP address of the first ethernet device is a matter of typing
> -'eth0.ip=192.168.0.7' on the console and can then be read back with
> -'echo $eth0.ip'. The @ref devinfo_command command shows a summary about all
> +'eth0.ipaddr=192.168.0.7' on the console and can then be read back with
> +'echo $eth0.ipaddr'. The @ref devinfo_command command shows a summary about all
>  devices currently present. If called with a device id as parameter it shows the
>  parameters available for a device.
>  
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> 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 voytikd at gmail.com  Thu Oct 23 07:21:38 2014
From: voytikd at gmail.com (Dmitry Voytik)
Date: Thu, 23 Oct 2014 18:21:38 +0400
Subject: [PATCH] ARM: imx23-olinuxino: discover usb before ifup
Message-ID: <1414074098-13717-1-git-send-email-voytikd@gmail.com>

i.MX233 in OLinuXino uses LAN9512 for Ethernet connection.
LAN9512 is connected to USB. Execute usb command before bringing
network up.

This patch makes 'ifup eth0' workable.

Signed-off-by: Dmitry Voytik <voytikd at gmail.com>
---
 arch/arm/boards/imx233-olinuxino/env/network/eth0-discover | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 arch/arm/boards/imx233-olinuxino/env/network/eth0-discover

diff --git a/arch/arm/boards/imx233-olinuxino/env/network/eth0-discover b/arch/arm/boards/imx233-olinuxino/env/network/eth0-discover
new file mode 100644
index 0000000..76494fe
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/env/network/eth0-discover
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+#  In OLinuXino board i.MX233 SoC uses LAN9512 (attached to USB) to connect
+#  to an Ethernet LAN.
+
+usb
-- 
1.9.1



From s.hauer at pengutronix.de  Thu Oct 23 14:05:34 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 23 Oct 2014 23:05:34 +0200
Subject: [PATCH] saveenv: Fix saving to specified file
Message-ID: <1414098334-16957-1-git-send-email-s.hauer@pengutronix.de>

Since e805b7d saveenv: provide a zeroed/empty/ignore environment
barebox no longer honors the file argument when the directory
argument is also givin. Fix this.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/saveenv.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/commands/saveenv.c b/commands/saveenv.c
index 9da733e..43f16dc 100644
--- a/commands/saveenv.c
+++ b/commands/saveenv.c
@@ -39,16 +39,16 @@ static int do_saveenv(int argc, char *argv[])
 	}
 
 	/* destination and source are given? */
-	if (argc == optind + 2)
-		dirname = argv[optind + 1];
-	else
+	if (argc - optind < 2)
 		dirname = "/env";
+	else
+		dirname = argv[optind + 1];
 
 	/* destination only given? */
-	if (argc == optind + 1)
-		filename = argv[optind];
-	else
+	if (argc - optind < 1)
 		filename = default_environment_path_get();
+	else
+		filename = argv[optind];
 
 	ret = envfs_save(filename, dirname, envfs_flags);
 
-- 
2.1.1



From u.kleine-koenig at pengutronix.de  Thu Oct 23 15:45:58 2014
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 24 Oct 2014 00:45:58 +0200
Subject: [PATCH 0/3] fixes and sanity checks for mxs pinmuxing
Message-ID: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>

Hello,

this series helped me to find pinmuxing problems on an i.MX28 machine.

The pins either have a pull up, a bit keeper or neither. For example the pin
ENET0_RXD2 has a bit keeper, and so doing

	imx_gpio_mode(ENET0_RXD2 | VE_3_3V | STRENGTH(S8MA) | PULLUP(1))

obviously couldn't enable the pull up as requested. Instead it enabled the bit
keeper. With this series the above call results in a message that the mode is
invalid and the pullup and bitkeeper register settings are not touched.

Note that I didn't test on i.MX23 even though this SoC is affected, too. I
currently don't have an i.MX23 handy, so I couldn't test this part.

Uwe Kleine-K?nig (3):
  mxs: iomux-imx28: Fix keeper/pullup/drive strength/voltage flags
  mxs: iomux-imx23/imx28: unify mode definition
  mxs: iomux-imx23/imx28: add additional checks on mode

 arch/arm/mach-mxs/include/mach/iomux-imx23.h |  61 ---------------
 arch/arm/mach-mxs/include/mach/iomux-imx28.h | 112 +++++++--------------------
 arch/arm/mach-mxs/include/mach/iomux.h       |  82 ++++++++++++++++++++
 arch/arm/mach-mxs/iomux-imx.c                |  23 +++++-
 4 files changed, 127 insertions(+), 151 deletions(-)

-- 
2.1.1



From u.kleine-koenig at pengutronix.de  Thu Oct 23 15:45:59 2014
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 24 Oct 2014 00:45:59 +0200
Subject: [PATCH 1/3] mxs: iomux-imx28: Fix keeper/pullup/drive
 strength/voltage flags
In-Reply-To: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <1414104361-15956-2-git-send-email-u.kleine-koenig@pengutronix.de>

Double check all pin's BK, PE, SE and VE flags and correct wrong
definitions using i.MX28 Applications Processor Reference Manual, Rev 2,
08/2013.

Fixes: b1df39c28c7f (mxs: Add remaining i.MX28 iomux configurations)
Fixes: e2cee7cb6790 (mxs: add support for mx28-evk)
Fixes: 03e61e1bd967 (STM378x: Add i.MX28 architecture)
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 arch/arm/mach-mxs/include/mach/iomux-imx28.h | 52 ++++++++++++++--------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/iomux-imx28.h b/arch/arm/mach-mxs/include/mach/iomux-imx28.h
index 82918cf851b1..c9ab8a93aea2 100644
--- a/arch/arm/mach-mxs/include/mach/iomux-imx28.h
+++ b/arch/arm/mach-mxs/include/mach/iomux-imx28.h
@@ -268,9 +268,9 @@
 #define SSP3_CMD_ENET1_1588_EVENT0_IN (FUNC(2) | PORTF(2, 25) | SE | VE | PE)
 #define SSP3_CMD_GPIO		(FUNC(3) | PORTF(2, 25) | SE | VE | PE)
 #define SSP3_SCK		(FUNC(0) | PORTF(2, 24) | SE | VE | PE)
-#define SSP3_SCK_AUART4_TX	(FUNC(1) | PORTF(2, 24) | SE | VE | PE)
-#define SSP3_SCK_ENET1_1588_EVENT0_OUT (FUNC(2) | PORTF(2, 24) | SE | VE | PE)
-#define SSP3_SCK_GPIO		(FUNC(3) | PORTF(2, 24) | SE | VE | PE)
+#define SSP3_SCK_AUART4_TX	(FUNC(1) | PORTF(2, 24) | SE | VE | BK)
+#define SSP3_SCK_ENET1_1588_EVENT0_OUT (FUNC(2) | PORTF(2, 24) | SE | VE | BK)
+#define SSP3_SCK_GPIO		(FUNC(3) | PORTF(2, 24) | SE | VE | BK)
 #define SSP2_D5			(FUNC(0) | PORTF(2, 21) | SE | VE | PE)
 #define SSP2_D5_SSP2_D2		(FUNC(1) | PORTF(2, 21) | SE | VE | PE)
 #define SSP2_D5_USB0_OC		(FUNC(2) | PORTF(2, 21) | SE | VE | PE)
@@ -291,9 +291,9 @@
 #define SSP2_CMD_AUART2_TX	(FUNC(1) | PORTF(2, 17) | SE | VE | PE)
 #define SSP2_CMD_SAIF0_SDATA2	(FUNC(2) | PORTF(2, 17) | SE | VE | PE)
 #define SSP2_CMD_GPIO		(FUNC(3) | PORTF(2, 17) | SE | VE | PE)
-#define SSP2_SCK		(FUNC(0) | PORTF(2, 16) | SE | VE | PE)
-#define SSP2_SCK_AUART2_RX	(FUNC(1) | PORTF(2, 16) | SE | VE | PE)
-#define SSP2_SCK_SAIF0_SDATA1	(FUNC(2) | PORTF(2, 16) | SE | VE | PE)
+#define SSP2_SCK		(FUNC(0) | PORTF(2, 16) | SE | VE | BK)
+#define SSP2_SCK_AUART2_RX	(FUNC(1) | PORTF(2, 16) | SE | VE | BK)
+#define SSP2_SCK_SAIF0_SDATA1	(FUNC(2) | PORTF(2, 16) | SE | VE | BK)
 #define SSP2_SCK_GPIO		(FUNC(3) | PORTF(2, 16) | SE | VE | PE)
 #define SSP1_D3			(FUNC(0) | PORTF(2, 15) | SE | VE | PE)
 #define SSP1_D3_SSP2_D7		(FUNC(1) | PORTF(2, 15) | SE | VE | PE)
@@ -339,13 +339,13 @@
 #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 LCD_RESET		(FUNC(0) | PORTF(3, 30) | SE | VE | BK)
+#define LCD_RESET_LCD_VSYNC	(FUNC(1) | PORTF(3, 30) | SE | VE | BK)
+#define LCD_RESET_GPIO		(FUNC(3) | PORTF(3, 30) | SE | VE | BK)
+#define PWM4			(FUNC(0) | PORTF(3, 29) | SE | VE | BK)
+#define PWM4_GPIO		(FUNC(3) | PORTF(3, 29) | SE | VE | BK)
+#define PWM3			(FUNC(0) | PORTF(3, 28) | SE | VE | BK)
+#define PWM3_GPIO		(FUNC(3) | PORTF(3, 28) | SE | VE | BK)
 #define SPDIF_TX		(FUNC(0) | PORTF(3, 27) | SE | VE | BK)
 #define SPDIF_TX_ENET1_RX_ER	(FUNC(2) | PORTF(3, 27) | SE | VE | BK)
 #define SPDIF_TX_GPIO		(FUNC(3) | PORTF(3, 27) | SE | VE | BK)
@@ -377,23 +377,23 @@
 #define SAIF0_MCLK_PWM3		(FUNC(1) | PORTF(3, 20) | SE | VE | BK)
 #define SAIF0_MCLK_AUART4_CTS	(FUNC(2) | PORTF(3, 20) | SE | VE | BK)
 #define SAIF0_MCLK_GPIO		(FUNC(3) | PORTF(3, 20) | SE | VE | BK)
-#define PWM2			(FUNC(0) | PORTF(3, 18))
-#define PWM2_USB0_ID		(FUNC(1) | PORTF(3, 18))
-#define PWM2_USB1_OC		(FUNC(2) | PORTF(3, 18))
-#define PWM2_GPIO		(FUNC(3) | PORTF(3, 18))
-#define PWM1			(FUNC(0) | PORTF(3, 17))
-#define PWM1_I2C1_SDA		(FUNC(1) | PORTF(3, 17))
-#define PWM1_DUART_TX		(FUNC(2) | PORTF(3, 17))
-#define PWM1_GPIO		(FUNC(3) | 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 PWM2			(FUNC(0) | PORTF(3, 18) | SE | VE | PE)
+#define PWM2_USB0_ID		(FUNC(1) | PORTF(3, 18) | SE | VE | PE)
+#define PWM2_USB1_OC		(FUNC(2) | PORTF(3, 18) | SE | VE | PE)
+#define PWM2_GPIO		(FUNC(3) | PORTF(3, 18) | SE | VE | PE)
+#define PWM1			(FUNC(0) | PORTF(3, 17) | SE | VE | BK)
+#define PWM1_I2C1_SDA		(FUNC(1) | PORTF(3, 17) | SE | VE | BK)
+#define PWM1_DUART_TX		(FUNC(2) | PORTF(3, 17) | SE | VE | BK)
+#define PWM1_GPIO		(FUNC(3) | PORTF(3, 17) | SE | VE | BK)
+#define PWM0			(FUNC(0) | PORTF(3, 16) | SE | VE | BK)
+#define PWM0_I2C1_SCL		(FUNC(1) | PORTF(3, 16) | SE | VE | BK)
+#define PWM0_DUART_RX		(FUNC(2) | PORTF(3, 16) | SE | VE | BK)
+#define PWM0_GPIO		(FUNC(3) | PORTF(3, 16) | SE | VE | BK)
 #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		(FUNC(0) | PORTF(3, 14) | SE | VE | 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)
-- 
2.1.1



From u.kleine-koenig at pengutronix.de  Thu Oct 23 15:46:01 2014
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 24 Oct 2014 00:46:01 +0200
Subject: [PATCH 3/3] mxs: iomux-imx23/imx28: add additional checks on mode
In-Reply-To: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <1414104361-15956-4-git-send-email-u.kleine-koenig@pengutronix.de>

This catches wrong modes:
 - request to enable the pull up on a pin that doesn't have one.
 - ditto for bit keepers, drive strength and voltage

Additionally only write values for a given pin if the mode has the
corresponding value set.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 arch/arm/mach-mxs/iomux-imx.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-mxs/iomux-imx.c b/arch/arm/mach-mxs/iomux-imx.c
index 24295c5d78aa..84c6ca4ca72a 100644
--- a/arch/arm/mach-mxs/iomux-imx.c
+++ b/arch/arm/mach-mxs/iomux-imx.c
@@ -97,20 +97,35 @@ void imx_gpio_mode(uint32_t m)
 	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
 	writel(reg, IMX_IOMUXC_BASE + reg_offset);
 
+	if (m & ERROR(1))
+		printf("%s: broken mode: 0x%08x\n", __func__, m);
+
+	if ((m & (PE | PEVALID)) == PEVALID)
+		printf("%s: mode specifies PE, but pin not configurable: 0x%08x\n", __func__, m);
+
+	if ((m & (BK | BKVALID)) == BKVALID)
+		printf("%s: mode specifies BK, but pin not configurable: 0x%08x\n", __func__, m);
+
+	if ((m & (SE | SEVALID)) == SEVALID)
+		printf("%s: mode specifies SE, but pin not configurable: 0x%08x\n", __func__, m);
+
+	if ((m & (VE | VEVALID)) == VEVALID)
+		printf("%s: mode specifies VE, but pin not configurable: 0x%08x\n", __func__, m);
+
 	/* some pins are disabled when configured for GPIO */
 	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
 		printf("Cannot configure pad %u to GPIO\n", gpio_pin);
 		return;
 	}
 
-	if (SE_PRESENT(m)) {
+	if (SE_PRESENT(m) && (m & SEVALID)) {
 		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)) {
+	if (VE_PRESENT(m) && (m & VEVALID)) {
 		reg_offset = calc_strength_reg(gpio_pin);
 		if (GET_VOLTAGE(m) == 1)
 			writel(0x1 << (((gpio_pin % 8) << 2) + 2),
@@ -120,14 +135,14 @@ void imx_gpio_mode(uint32_t m)
 				IMX_IOMUXC_BASE + reg_offset + STMP_OFFSET_REG_CLR);
 	}
 
-	if (PE_PRESENT(m)) {
+	if (PE_PRESENT(m) && (m & PEVALID)) {
 		reg_offset = calc_pullup_reg(gpio_pin);
 		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
 				(GET_PULLUP(m) == 1 ?
 				 STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR));
 	}
 
-	if (BK_PRESENT(m)) {
+	if (BK_PRESENT(m) && (m & BKVALID)) {
 		reg_offset = calc_pullup_reg(gpio_pin);
 		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
 				(GET_BITKEEPER(m) == 1 ?
-- 
2.1.1



From u.kleine-koenig at pengutronix.de  Thu Oct 23 15:46:00 2014
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 24 Oct 2014 00:46:00 +0200
Subject: [PATCH 2/3] mxs: iomux-imx23/imx28: unify mode definition
In-Reply-To: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <1414104361-15956-3-git-send-email-u.kleine-koenig@pengutronix.de>

i.MX23 and i.MX28 iomux mode definitions differ for no good reason.

Compared to the two previous definitions this introduces a few flags
that are not used yet but this changes in the next commit to detect
broken definitions.

Apart from different constants this commit intends to be a no-op. If
there are changes in the register values there is either a bug in this
patch or the used mode is broken (e.g. a pullup value is defined for a
pin that has a bitkeeper).

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 arch/arm/mach-mxs/include/mach/iomux-imx23.h | 61 ---------------------
 arch/arm/mach-mxs/include/mach/iomux-imx28.h | 60 --------------------
 arch/arm/mach-mxs/include/mach/iomux.h       | 82 ++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 121 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/iomux-imx23.h b/arch/arm/mach-mxs/include/mach/iomux-imx23.h
index 39d69810ef08..1e225f8fc51b 100644
--- a/arch/arm/mach-mxs/include/mach/iomux-imx23.h
+++ b/arch/arm/mach-mxs/include/mach/iomux-imx23.h
@@ -9,72 +9,11 @@
  * 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
- *                              ^^^_ Register Number
- *                          ^^^^____ Bit offset
- *                        ^^________ Function
- *                       ^__________ Drive strength feature present
- *                      ^___________ Pull up 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
- *           ^______________________ Bit keeper present
- */
 #ifndef __ASM_MACH_IOMUX_MX23_H
 #define __ASM_MACH_IOMUX_MX23_H
 
-/* control pad's function */
-#define FBIT_SHIFT (3)
-#define PORTF(bank,bit)	(((bit) << FBIT_SHIFT) | (bank))
-#define GET_PORTF(x) ((x) & 0x7)
-#define GET_FBITPOS(x) (((x) >> FBIT_SHIFT) & 0xf)
-#define GET_GPIO_NO(x) ((GET_PORTF(x) << 4) + GET_FBITPOS(m))
-#define FUNC_SHIFT 7
-#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 << 19)
-#define GPIO_VALUE(x) ((x) << 20)
-#define GPIO_IN (0 << 19)
-#define GET_GPIODIR(x) (!!((x) & (1 << 19)))
-#define GET_GPIOVAL(x) (!!((x) & (1 << 20)))
-
-/* control pad's drive strength */
-#define SE (1 << 9)
-#define SE_PRESENT(x) (!!((x) & SE))
-#define STRENGTH(x) ((x) << 11)
-#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) >> 11) & 0x3)
-
-/* control pad's pull up / bit keeper feature */
-#define PE (1 << 10)
-#define BK (1 << 21)
-#define PE_PRESENT(x) (!!((x) & PE))
-#define BK_PRESENT(x) (!!((x) & BK))
-#define PULLUP(x) ((x) << 13)
-#define BITKEEPER(x) ((x) << 14)
-#define GET_PULLUP(x) (!!((x) & (1 << 13)))
-#define GET_BITKEEPER(x) (!!((x) & BITKEEPER(1)))
-
-/* control pad's voltage feature */
-#define VE (1 << 14)
-#define VE_PRESENT(x) (!!((x) & VE))
-#define VE_1_8V (0 << 15)
-#define VE_2_5V (0 << 15) /* don't ask my why, RTFM */
-#define GET_VOLTAGE(x) (!!((x) & (1 << 15)))
-
 /* Bank 0, pins 0 ... 15, GPIO pins 0 ... 15 */
 #define GPMI_D15		(FUNC(0) | PORTF(0, 15) | SE | PE)
 #define GPMI_D15_AUART2_TX	(FUNC(1) | PORTF(0, 15) | SE | PE)
diff --git a/arch/arm/mach-mxs/include/mach/iomux-imx28.h b/arch/arm/mach-mxs/include/mach/iomux-imx28.h
index c9ab8a93aea2..6119f3caf98d 100644
--- a/arch/arm/mach-mxs/include/mach/iomux-imx28.h
+++ b/arch/arm/mach-mxs/include/mach/iomux-imx28.h
@@ -10,69 +10,9 @@
  * GNU General Public License for more details.
  */
 
-/* 3322222222221111111111
- * 10987654321098765432109876543210
- *                            ^^^^^_ Bit offset
- *                         ^^^______ Register Number
- *                       ^^_________ Function
- *                      ^___________ Drive strength feature present
- *                     ^____________ Pull up 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
- *          ^_______________________ Bit keeper present
- */
 #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 << 22)
-#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)
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
index 84496c6b8497..a647439303fc 100644
--- a/arch/arm/mach-mxs/include/mach/iomux.h
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -18,10 +18,92 @@
 
 #include <types.h>
 
+/*
+ * The muxable pins on i.MX23 are organized in 4 banks. On i.MX28 there are 7
+ * banks. Each bank has up to 32 pins each. Furthermore for each pin some of the
+ * following properties can be configured:
+ *  - drive strength: 4 mA, 8 mA, 12 mA or 16 mA
+ *  - pull up enabled or bit keeper enabled (a pin cannot have both)
+ *  - voltage: 1.8 V, 2.5 V (i.MX23 only) or 3.3 V (i.MX28 only)
+ *  - function: 0..3, with 3 being the GPIO functionality
+ *
+ * So a configuration for a given pin can be described in an unsigned integer of
+ * length 32:
+ *  - [ 4: 0] bank pin
+ *  - [ 7: 5] bank
+ *  - [    8] 1 iff pin has a switchable pull up
+ *  - [    9] 1 iff pin has a switchable bit keeper
+ *  - [   10] 1 iff pin has switchable drive strength
+ *  - [   11] 1 iff pin has switchable voltage
+ *  - [13:12] function
+ *  - [   14] 1 for enabled pull up
+ *  - [   15] 1 iff [14] is a valid pull up value
+ *  - [   16] 1 for enabled bit keeper
+ *  - [   17] 1 iff [16] is a valid bit keeper value
+ *  - [19:18] value for drive strength i -> i * 4 mA
+ *  - [   20] 1 iff [19:18] is valid
+ *  - [   21] 0 for 1.8 V, 1 for 2.5 V resp. 3.3 V
+ *  - [   22] 1 iff [21] is valid
+ *  - [   23] 1 iff configure as GPIO out if function == 3 (i.e. GPIO)
+ *  - [   24] initial value iff configured as GPIO out
+ *  - [   25] error
+ */
+
+#define BANKPIN(p)	(((p) & 31) | ERROR((p) & ~31))
+#define BANK(b)		((((b) & 7) << 5) | (ERROR((b) & ~7)))
+#define PE		(1 << 8)
+#define BK		(1 << 9)
+#define SE		(1 << 10)
+#define VE		(1 << 11)
+#define FUNC(f)		((((f) & 3) << 12) | (ERROR((f) & ~3)))
+#define PULLUP(p)	((((p) & 1) << 14) | PEVALID | ERROR((p) & ~1))
+#define PEVALID		(1 << 15)
+#define BITKEEPER(b)	((((b) & 1) << 16) | BKVALID | ERROR((b) & ~1))
+#define BKVALID		(1 << 17)
+#define STRENGTH(s)	((((s) & 3) << 18) | SEVALID | ERROR((s) & ~3))
+#define S4MA		0
+#define S8MA		1
+#define S12MA		2
+#define S16MA		3
+#define SEVALID		(1 << 20)
+#define VOLTAGE(v)	((((v) & 1) << 21) | VEVALID | ERROR((v) & ~1))
+#define VE_1_8V		VOLTAGE(0)
+#define VEVALID		(1 << 22)
+
+#define GPIO_OUT	(1 << 23)
+#define GPIO_IN		(0 << 23)
+#define GPIO_VALUE(v)	((((v) & 1) << 24) | ERROR((v) & ~1))
+
+#define ERROR(x)	(!!(x) << 25)
+
+#define GET_GPIO_NO(m)	((m) & 0xff)
+#define GET_FUNC(m)	(((m) >> 12) & 3)
+#define PE_PRESENT(m)	((m) & PE)
+#define GET_PULLUP(m)	(((m) >> 14) & 1)
+#define BK_PRESENT(m)	((m) & BK)
+#define GET_BITKEEPER(m)(((m) >> 16) & 1)
+#define SE_PRESENT(m)	((m) & SE)
+#define GET_STRENGTH(m)	(((m) >> 18) & 3)
+#define VE_PRESENT(m)	((m) & VE)
+#define GET_VOLTAGE(m)	(((m) >> 21) & 1)
+#define GET_GPIODIR(m)	(!!((m) & GPIO_OUT))
+#define GET_GPIOVAL(m)	(!!((m) & GPIO_VALUE(1)))
+#define IS_GPIO		3
+
 #if defined CONFIG_ARCH_IMX23
+/*
+ * The pin definition of i.MX23 are strange. Bank 0's pins 0 .. 15 are defined
+ * using PORTF(0, 0) .. PORTF(0, 15). Its pins 16 .. 31 however use PORTF(1, 0)
+ * .. PORTF(1, 15). So the PORTF macro is more ugly than necessary.
+ */
+# define PORTF(bank,bit)	(BANK((bank) / 2) | BANKPIN((((bank) & 1) << 4) | (bit)) | ERROR((bit) & ~15) | ERROR((bank) & ~7)
+# define VE_2_5V		VOLTAGE(1)
 # include <mach/iomux-imx23.h>
 #endif
+
 #if defined CONFIG_ARCH_IMX28
+# define PORTF(bank,bit)	(BANK(bank) | BANKPIN(bit))
+# define VE_3_3V	VOLTAGE(1)
 # include <mach/iomux-imx28.h>
 #endif
 
-- 
2.1.1



From s.hauer at pengutronix.de  Thu Oct 23 22:53:02 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 24 Oct 2014 07:53:02 +0200
Subject: [PATCH 1/2] filetype: Add XZ filetype support
Message-ID: <1414129983-18986-1-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/filetype.c  | 4 ++++
 include/filetype.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/common/filetype.c b/common/filetype.c
index c8f3582..d98a60e 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -57,6 +57,7 @@ static const struct filetype_str filetype_str[] = {
 	[filetype_ch_image] = { "TI OMAP CH boot image", "ch-image" },
 	[filetype_ch_image_be] = {
 			"TI OMAP CH boot image (big endian)", "ch-image-be" },
+	[filetype_xz_compressed] = { "XZ compressed", "xz" },
 	[filetype_exe] = { "MS-DOS executable", "exe" },
 };
 
@@ -224,6 +225,9 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize)
 	if (buf8[0] == 'B' && buf8[1] == 'Z' && buf8[2] == 'h' &&
 			buf8[3] > '0' && buf8[3] <= '9')
                 return filetype_bzip2;
+	if (buf8[0] == 0xfd && buf8[1] == 0x37 && buf8[2] == 0x7a &&
+			buf8[3] == 0x58 && buf8[4] == 0x5a && buf8[5] == 0x00)
+		return filetype_xz_compressed;
 	if (buf[0] == be32_to_cpu(0xd00dfeed))
 		return filetype_oftree;
 	if (strncmp(buf8, "ANDROID!", 8) == 0)
diff --git a/include/filetype.h b/include/filetype.h
index eedf4b4..ac71775 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -33,6 +33,7 @@ enum filetype {
 	filetype_ch_image,
 	filetype_ch_image_be,
 	filetype_exe,
+	filetype_xz_compressed,
 	filetype_max,
 };
 
-- 
2.1.1



From s.hauer at pengutronix.de  Thu Oct 23 22:53:03 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 24 Oct 2014 07:53:03 +0200
Subject: [PATCH 2/2] Add xz decompression support
In-Reply-To: <1414129983-18986-1-git-send-email-s.hauer@pengutronix.de>
References: <1414129983-18986-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1414129983-18986-2-git-send-email-s.hauer@pengutronix.de>

This adds xz decompression support from the kernel. Both compressing
the barebox binary with xz and decompressing xz files on the commandline
is supported.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/Kconfig         |    5 +
 images/Makefile        |    1 +
 include/linux/xz.h     |  271 +++++++++++
 lib/Kconfig            |    4 +
 lib/Makefile           |    1 +
 lib/decompress_unxz.c  |  376 ++++++++++++++++
 lib/uncompress.c       |    6 +
 lib/xz/xz_crc32.c      |   59 +++
 lib/xz/xz_dec_bcj.c    |  574 +++++++++++++++++++++++
 lib/xz/xz_dec_lzma2.c  | 1175 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/xz/xz_dec_stream.c |  821 +++++++++++++++++++++++++++++++++
 lib/xz/xz_lzma2.h      |  204 +++++++++
 lib/xz/xz_private.h    |  156 +++++++
 lib/xz/xz_stream.h     |   61 +++
 pbl/Kconfig            |    3 +
 pbl/decomp.c           |    4 +
 scripts/Makefile.lib   |   31 ++
 17 files changed, 3752 insertions(+)
 create mode 100644 include/linux/xz.h
 create mode 100644 lib/decompress_unxz.c
 create mode 100644 lib/xz/xz_crc32.c
 create mode 100644 lib/xz/xz_dec_bcj.c
 create mode 100644 lib/xz/xz_dec_lzma2.c
 create mode 100644 lib/xz/xz_dec_stream.c
 create mode 100644 lib/xz/xz_lzma2.h
 create mode 100644 lib/xz/xz_private.h
 create mode 100644 lib/xz/xz_stream.h

diff --git a/common/Kconfig b/common/Kconfig
index 016ba44..a2cce39 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -582,6 +582,7 @@ choice
 	prompt "default compression for in-barebox binaries"
 	default DEFAULT_COMPRESSION_NONE if PBL_IMAGE
 	default DEFAULT_COMPRESSION_LZO if LZO_DECOMPRESS
+	default DEFAULT_COMPRESSION_XZ if XZ_DECOMPRESS
 	default DEFAULT_COMPRESSION_GZIP if ZLIB
 	default DEFAULT_COMPRESSION_LZ4 if LZ4_DECOMPRESS
 	default DEFAULT_COMPRESSION_BZIP2 if BZLIB
@@ -606,6 +607,10 @@ config DEFAULT_COMPRESSION_LZ4
 	bool "lz4"
 	depends on LZ4_DECOMPRESS
 
+config DEFAULT_COMPRESSION_XZ
+	bool "xz"
+	depends on XZ_DECOMPRESS
+
 config DEFAULT_COMPRESSION_NONE
 	bool "no compression"
 
diff --git a/images/Makefile b/images/Makefile
index 738fcb6..c55cbdc 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -82,6 +82,7 @@ $(obj)/%.s: $(obj)/% FORCE
 suffix_$(CONFIG_IMAGE_COMPRESSION_GZIP) = gzip
 suffix_$(CONFIG_IMAGE_COMPRESSION_LZO)  = lzo
 suffix_$(CONFIG_IMAGE_COMPRESSION_LZ4)	= lz4
+suffix_$(CONFIG_IMAGE_COMPRESSION_XZKERN) = xzkern
 suffix_$(CONFIG_IMAGE_COMPRESSION_NONE) = shipped
 
 # barebox.z - compressed barebox binary
diff --git a/include/linux/xz.h b/include/linux/xz.h
new file mode 100644
index 0000000..a3c2b77
--- /dev/null
+++ b/include/linux/xz.h
@@ -0,0 +1,271 @@
+/*
+ * XZ decompressor
+ *
+ * Authors: Lasse Collin <lasse.collin at tukaani.org>
+ *          Igor Pavlov <http://7-zip.org/>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#ifndef XZ_H
+#define XZ_H
+
+#ifdef __KERNEL__
+#	include <linux/stddef.h>
+#	include <linux/types.h>
+#else
+#	include <stddef.h>
+#	include <stdint.h>
+#endif
+
+/* In Linux, this is used to make extern functions static when needed. */
+#ifndef XZ_EXTERN
+#	define XZ_EXTERN extern
+#endif
+
+#ifndef STATIC
+#define STATIC
+#endif
+
+/**
+ * enum xz_mode - Operation mode
+ *
+ * @XZ_SINGLE:              Single-call mode. This uses less RAM than
+ *                          than multi-call modes, because the LZMA2
+ *                          dictionary doesn't need to be allocated as
+ *                          part of the decoder state. All required data
+ *                          structures are allocated at initialization,
+ *                          so xz_dec_run() cannot return XZ_MEM_ERROR.
+ * @XZ_PREALLOC:            Multi-call mode with preallocated LZMA2
+ *                          dictionary buffer. All data structures are
+ *                          allocated at initialization, so xz_dec_run()
+ *                          cannot return XZ_MEM_ERROR.
+ * @XZ_DYNALLOC:            Multi-call mode. The LZMA2 dictionary is
+ *                          allocated once the required size has been
+ *                          parsed from the stream headers. If the
+ *                          allocation fails, xz_dec_run() will return
+ *                          XZ_MEM_ERROR.
+ *
+ * It is possible to enable support only for a subset of the above
+ * modes at compile time by defining XZ_DEC_SINGLE, XZ_DEC_PREALLOC,
+ * or XZ_DEC_DYNALLOC. The xz_dec kernel module is always compiled
+ * with support for all operation modes, but the preboot code may
+ * be built with fewer features to minimize code size.
+ */
+enum xz_mode {
+	XZ_SINGLE,
+	XZ_PREALLOC,
+	XZ_DYNALLOC
+};
+
+/**
+ * enum xz_ret - Return codes
+ * @XZ_OK:                  Everything is OK so far. More input or more
+ *                          output space is required to continue. This
+ *                          return code is possible only in multi-call mode
+ *                          (XZ_PREALLOC or XZ_DYNALLOC).
+ * @XZ_STREAM_END:          Operation finished successfully.
+ * @XZ_UNSUPPORTED_CHECK:   Integrity check type is not supported. Decoding
+ *                          is still possible in multi-call mode by simply
+ *                          calling xz_dec_run() again.
+ *                          Note that this return value is used only if
+ *                          XZ_DEC_ANY_CHECK was defined at build time,
+ *                          which is not used in the kernel. Unsupported
+ *                          check types return XZ_OPTIONS_ERROR if
+ *                          XZ_DEC_ANY_CHECK was not defined at build time.
+ * @XZ_MEM_ERROR:           Allocating memory failed. This return code is
+ *                          possible only if the decoder was initialized
+ *                          with XZ_DYNALLOC. The amount of memory that was
+ *                          tried to be allocated was no more than the
+ *                          dict_max argument given to xz_dec_init().
+ * @XZ_MEMLIMIT_ERROR:      A bigger LZMA2 dictionary would be needed than
+ *                          allowed by the dict_max argument given to
+ *                          xz_dec_init(). This return value is possible
+ *                          only in multi-call mode (XZ_PREALLOC or
+ *                          XZ_DYNALLOC); the single-call mode (XZ_SINGLE)
+ *                          ignores the dict_max argument.
+ * @XZ_FORMAT_ERROR:        File format was not recognized (wrong magic
+ *                          bytes).
+ * @XZ_OPTIONS_ERROR:       This implementation doesn't support the requested
+ *                          compression options. In the decoder this means
+ *                          that the header CRC32 matches, but the header
+ *                          itself specifies something that we don't support.
+ * @XZ_DATA_ERROR:          Compressed data is corrupt.
+ * @XZ_BUF_ERROR:           Cannot make any progress. Details are slightly
+ *                          different between multi-call and single-call
+ *                          mode; more information below.
+ *
+ * In multi-call mode, XZ_BUF_ERROR is returned when two consecutive calls
+ * to XZ code cannot consume any input and cannot produce any new output.
+ * This happens when there is no new input available, or the output buffer
+ * is full while at least one output byte is still pending. Assuming your
+ * code is not buggy, you can get this error only when decoding a compressed
+ * stream that is truncated or otherwise corrupt.
+ *
+ * In single-call mode, XZ_BUF_ERROR is returned only when the output buffer
+ * is too small or the compressed input is corrupt in a way that makes the
+ * decoder produce more output than the caller expected. When it is
+ * (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
+ * is used instead of XZ_BUF_ERROR.
+ */
+enum xz_ret {
+	XZ_OK,
+	XZ_STREAM_END,
+	XZ_UNSUPPORTED_CHECK,
+	XZ_MEM_ERROR,
+	XZ_MEMLIMIT_ERROR,
+	XZ_FORMAT_ERROR,
+	XZ_OPTIONS_ERROR,
+	XZ_DATA_ERROR,
+	XZ_BUF_ERROR
+};
+
+/**
+ * struct xz_buf - Passing input and output buffers to XZ code
+ * @in:         Beginning of the input buffer. This may be NULL if and only
+ *              if in_pos is equal to in_size.
+ * @in_pos:     Current position in the input buffer. This must not exceed
+ *              in_size.
+ * @in_size:    Size of the input buffer
+ * @out:        Beginning of the output buffer. This may be NULL if and only
+ *              if out_pos is equal to out_size.
+ * @out_pos:    Current position in the output buffer. This must not exceed
+ *              out_size.
+ * @out_size:   Size of the output buffer
+ *
+ * Only the contents of the output buffer from out[out_pos] onward, and
+ * the variables in_pos and out_pos are modified by the XZ code.
+ */
+struct xz_buf {
+	const uint8_t *in;
+	size_t in_pos;
+	size_t in_size;
+
+	uint8_t *out;
+	size_t out_pos;
+	size_t out_size;
+};
+
+/**
+ * struct xz_dec - Opaque type to hold the XZ decoder state
+ */
+struct xz_dec;
+
+/**
+ * xz_dec_init() - Allocate and initialize a XZ decoder state
+ * @mode:       Operation mode
+ * @dict_max:   Maximum size of the LZMA2 dictionary (history buffer) for
+ *              multi-call decoding. This is ignored in single-call mode
+ *              (mode == XZ_SINGLE). LZMA2 dictionary is always 2^n bytes
+ *              or 2^n + 2^(n-1) bytes (the latter sizes are less common
+ *              in practice), so other values for dict_max don't make sense.
+ *              In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB,
+ *              512 KiB, and 1 MiB are probably the only reasonable values,
+ *              except for kernel and initramfs images where a bigger
+ *              dictionary can be fine and useful.
+ *
+ * Single-call mode (XZ_SINGLE): xz_dec_run() decodes the whole stream at
+ * once. The caller must provide enough output space or the decoding will
+ * fail. The output space is used as the dictionary buffer, which is why
+ * there is no need to allocate the dictionary as part of the decoder's
+ * internal state.
+ *
+ * Because the output buffer is used as the workspace, streams encoded using
+ * a big dictionary are not a problem in single-call mode. It is enough that
+ * the output buffer is big enough to hold the actual uncompressed data; it
+ * can be smaller than the dictionary size stored in the stream headers.
+ *
+ * Multi-call mode with preallocated dictionary (XZ_PREALLOC): dict_max bytes
+ * of memory is preallocated for the LZMA2 dictionary. This way there is no
+ * risk that xz_dec_run() could run out of memory, since xz_dec_run() will
+ * never allocate any memory. Instead, if the preallocated dictionary is too
+ * small for decoding the given input stream, xz_dec_run() will return
+ * XZ_MEMLIMIT_ERROR. Thus, it is important to know what kind of data will be
+ * decoded to avoid allocating excessive amount of memory for the dictionary.
+ *
+ * Multi-call mode with dynamically allocated dictionary (XZ_DYNALLOC):
+ * dict_max specifies the maximum allowed dictionary size that xz_dec_run()
+ * may allocate once it has parsed the dictionary size from the stream
+ * headers. This way excessive allocations can be avoided while still
+ * limiting the maximum memory usage to a sane value to prevent running the
+ * system out of memory when decompressing streams from untrusted sources.
+ *
+ * On success, xz_dec_init() returns a pointer to struct xz_dec, which is
+ * ready to be used with xz_dec_run(). If memory allocation fails,
+ * xz_dec_init() returns NULL.
+ */
+XZ_EXTERN struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max);
+
+/**
+ * xz_dec_run() - Run the XZ decoder
+ * @s:          Decoder state allocated using xz_dec_init()
+ * @b:          Input and output buffers
+ *
+ * The possible return values depend on build options and operation mode.
+ * See enum xz_ret for details.
+ *
+ * Note that if an error occurs in single-call mode (return value is not
+ * XZ_STREAM_END), b->in_pos and b->out_pos are not modified and the
+ * contents of the output buffer from b->out[b->out_pos] onward are
+ * undefined. This is true even after XZ_BUF_ERROR, because with some filter
+ * chains, there may be a second pass over the output buffer, and this pass
+ * cannot be properly done if the output buffer is truncated. Thus, you
+ * cannot give the single-call decoder a too small buffer and then expect to
+ * get that amount valid data from the beginning of the stream. You must use
+ * the multi-call decoder if you don't want to uncompress the whole stream.
+ */
+XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b);
+
+/**
+ * xz_dec_reset() - Reset an already allocated decoder state
+ * @s:          Decoder state allocated using xz_dec_init()
+ *
+ * This function can be used to reset the multi-call decoder state without
+ * freeing and reallocating memory with xz_dec_end() and xz_dec_init().
+ *
+ * In single-call mode, xz_dec_reset() is always called in the beginning of
+ * xz_dec_run(). Thus, explicit call to xz_dec_reset() is useful only in
+ * multi-call mode.
+ */
+XZ_EXTERN void xz_dec_reset(struct xz_dec *s);
+
+/**
+ * xz_dec_end() - Free the memory allocated for the decoder state
+ * @s:          Decoder state allocated using xz_dec_init(). If s is NULL,
+ *              this function does nothing.
+ */
+XZ_EXTERN void xz_dec_end(struct xz_dec *s);
+
+/*
+ * Standalone build (userspace build or in-kernel build for boot time use)
+ * needs a CRC32 implementation. For normal in-kernel use, kernel's own
+ * CRC32 module is used instead, and users of this module don't need to
+ * care about the functions below.
+ */
+#ifndef XZ_INTERNAL_CRC32
+#	define XZ_INTERNAL_CRC32 1
+#endif
+
+#if XZ_INTERNAL_CRC32
+/*
+ * This must be called before any other xz_* function to initialize
+ * the CRC32 lookup table.
+ */
+XZ_EXTERN void xz_crc32_init(void);
+
+/*
+ * Update CRC32 value using the polynomial from IEEE-802.3. To start a new
+ * calculation, the third argument must be zero. To continue the calculation,
+ * the previously returned value is passed as the third argument.
+ */
+XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc);
+#endif
+
+STATIC int decompress_unxz(unsigned char *in, long in_size,
+		     long (*fill)(void *dest, unsigned long size),
+		     long (*flush)(void *src, unsigned long size),
+		     unsigned char *out, long *in_used,
+		     void (*error)(char *x));
+
+#endif
diff --git a/lib/Kconfig b/lib/Kconfig
index 09a1674..d4095fd 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -18,6 +18,10 @@ config LZ4_DECOMPRESS
 	bool "include lz4 uncompression support"
 	select UNCOMPRESS
 
+config XZ_DECOMPRESS
+	bool "include xz uncompression support"
+	select UNCOMPRESS
+
 config GENERIC_FIND_NEXT_BIT
 	def_bool n
 
diff --git a/lib/Makefile b/lib/Makefile
index 1a34544..a6c7dfb 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,6 +20,7 @@ obj-y			+= make_directory.o
 obj-y			+= math.o
 obj-$(CONFIG_BZLIB)	+= decompress_bunzip2.o
 obj-$(CONFIG_ZLIB)	+= decompress_inflate.o zlib_inflate/
+obj-$(CONFIG_XZ_DECOMPRESS) += decompress_unxz.o xz/
 obj-$(CONFIG_CMDLINE_EDITING)	+= readline.o
 obj-$(CONFIG_SIMPLE_READLINE)	+= readline_simple.o
 obj-$(CONFIG_GLOB)		+= fnmatch.o
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
new file mode 100644
index 0000000..0b6bc83
--- /dev/null
+++ b/lib/decompress_unxz.c
@@ -0,0 +1,376 @@
+/*
+ * Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd
+ *
+ * Author: Lasse Collin <lasse.collin at tukaani.org>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+/*
+ * Important notes about in-place decompression
+ *
+ * At least on x86, the kernel is decompressed in place: the compressed data
+ * is placed to the end of the output buffer, and the decompressor overwrites
+ * most of the compressed data. There must be enough safety margin to
+ * guarantee that the write position is always behind the read position.
+ *
+ * The safety margin for XZ with LZMA2 or BCJ+LZMA2 is calculated below.
+ * Note that the margin with XZ is bigger than with Deflate (gzip)!
+ *
+ * The worst case for in-place decompression is that the beginning of
+ * the file is compressed extremely well, and the rest of the file is
+ * uncompressible. Thus, we must look for worst-case expansion when the
+ * compressor is encoding uncompressible data.
+ *
+ * The structure of the .xz file in case of a compresed kernel is as follows.
+ * Sizes (as bytes) of the fields are in parenthesis.
+ *
+ *    Stream Header (12)
+ *    Block Header:
+ *      Block Header (8-12)
+ *      Compressed Data (N)
+ *      Block Padding (0-3)
+ *      CRC32 (4)
+ *    Index (8-20)
+ *    Stream Footer (12)
+ *
+ * Normally there is exactly one Block, but let's assume that there are
+ * 2-4 Blocks just in case. Because Stream Header and also Block Header
+ * of the first Block don't make the decompressor produce any uncompressed
+ * data, we can ignore them from our calculations. Block Headers of possible
+ * additional Blocks have to be taken into account still. With these
+ * assumptions, it is safe to assume that the total header overhead is
+ * less than 128 bytes.
+ *
+ * Compressed Data contains LZMA2 or BCJ+LZMA2 encoded data. Since BCJ
+ * doesn't change the size of the data, it is enough to calculate the
+ * safety margin for LZMA2.
+ *
+ * LZMA2 stores the data in chunks. Each chunk has a header whose size is
+ * a maximum of 6 bytes, but to get round 2^n numbers, let's assume that
+ * the maximum chunk header size is 8 bytes. After the chunk header, there
+ * may be up to 64 KiB of actual payload in the chunk. Often the payload is
+ * quite a bit smaller though; to be safe, let's assume that an average
+ * chunk has only 32 KiB of payload.
+ *
+ * The maximum uncompressed size of the payload is 2 MiB. The minimum
+ * uncompressed size of the payload is in practice never less than the
+ * payload size itself. The LZMA2 format would allow uncompressed size
+ * to be less than the payload size, but no sane compressor creates such
+ * files. LZMA2 supports storing uncompressible data in uncompressed form,
+ * so there's never a need to create payloads whose uncompressed size is
+ * smaller than the compressed size.
+ *
+ * The assumption, that the uncompressed size of the payload is never
+ * smaller than the payload itself, is valid only when talking about
+ * the payload as a whole. It is possible that the payload has parts where
+ * the decompressor consumes more input than it produces output. Calculating
+ * the worst case for this would be tricky. Instead of trying to do that,
+ * let's simply make sure that the decompressor never overwrites any bytes
+ * of the payload which it is currently reading.
+ *
+ * Now we have enough information to calculate the safety margin. We need
+ *   - 128 bytes for the .xz file format headers;
+ *   - 8 bytes per every 32 KiB of uncompressed size (one LZMA2 chunk header
+ *     per chunk, each chunk having average payload size of 32 KiB); and
+ *   - 64 KiB (biggest possible LZMA2 chunk payload size) to make sure that
+ *     the decompressor never overwrites anything from the LZMA2 chunk
+ *     payload it is currently reading.
+ *
+ * We get the following formula:
+ *
+ *    safety_margin = 128 + uncompressed_size * 8 / 32768 + 65536
+ *                  = 128 + (uncompressed_size >> 12) + 65536
+ *
+ * For comparison, according to arch/x86/boot/compressed/misc.c, the
+ * equivalent formula for Deflate is this:
+ *
+ *    safety_margin = 18 + (uncompressed_size >> 12) + 32768
+ *
+ * Thus, when updating Deflate-only in-place kernel decompressor to
+ * support XZ, the fixed overhead has to be increased from 18+32768 bytes
+ * to 128+65536 bytes.
+ */
+
+/*
+ * STATIC is defined to "static" if we are being built for kernel
+ * decompression (pre-boot code). <linux/decompress/mm.h> will define
+ * STATIC to empty if it wasn't already defined. Since we will need to
+ * know later if we are being used for kernel decompression, we define
+ * XZ_PREBOOT here.
+ */
+#ifdef STATIC
+#	define XZ_PREBOOT
+#endif
+#ifdef __KERNEL__
+#	include <linux/decompress/mm.h>
+#endif
+#define XZ_EXTERN STATIC
+
+#ifndef XZ_PREBOOT
+#	include <malloc.h>
+#	include <linux/xz.h>
+#else
+/*
+ * Use the internal CRC32 code instead of kernel's CRC32 module, which
+ * is not available in early phase of booting.
+ */
+#define XZ_INTERNAL_CRC32 1
+
+/*
+ * For boot time use, we enable only the BCJ filter of the current
+ * architecture or none if no BCJ filter is available for the architecture.
+ */
+#ifdef CONFIG_X86
+#	define XZ_DEC_X86
+#endif
+#ifdef CONFIG_PPC
+#	define XZ_DEC_POWERPC
+#endif
+#ifdef CONFIG_ARM
+#	define XZ_DEC_ARM
+#endif
+#ifdef CONFIG_IA64
+#	define XZ_DEC_IA64
+#endif
+#ifdef CONFIG_SPARC
+#	define XZ_DEC_SPARC
+#endif
+
+/*
+ * This will get the basic headers so that memeq() and others
+ * can be defined.
+ */
+#include "xz/xz_private.h"
+
+/*
+ * Replace the normal allocation functions with the versions from
+ * <linux/decompress/mm.h>. vfree() needs to support vfree(NULL)
+ * when XZ_DYNALLOC is used, but the pre-boot free() doesn't support it.
+ * Workaround it here because the other decompressors don't need it.
+ */
+#undef kmalloc
+#undef kfree
+#undef vmalloc
+#undef vfree
+#define kmalloc(size, flags) malloc(size)
+#define kfree(ptr) free(ptr)
+#define vmalloc(size) malloc(size)
+#define vfree(ptr) do { if (ptr != NULL) free(ptr); } while (0)
+
+/*
+ * FIXME: Not all basic memory functions are provided in architecture-specific
+ * files (yet). We define our own versions here for now, but this should be
+ * only a temporary solution.
+ *
+ * memeq and memzero are not used much and any remotely sane implementation
+ * is fast enough. memcpy/memmove speed matters in multi-call mode, but
+ * the kernel image is decompressed in single-call mode, in which only
+ * memcpy speed can matter and only if there is a lot of uncompressible data
+ * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the
+ * functions below should just be kept small; it's probably not worth
+ * optimizing for speed.
+ */
+
+#ifndef memeq
+static bool memeq(const void *a, const void *b, size_t size)
+{
+	const uint8_t *x = a;
+	const uint8_t *y = b;
+	size_t i;
+
+	for (i = 0; i < size; ++i)
+		if (x[i] != y[i])
+			return false;
+
+	return true;
+}
+#endif
+
+#ifndef memzero
+static void memzero(void *buf, size_t size)
+{
+	uint8_t *b = buf;
+	uint8_t *e = b + size;
+
+	while (b != e)
+		*b++ = '\0';
+}
+#endif
+
+/*
+ * Since we need memmove anyway, would use it as memcpy too.
+ * Commented out for now to avoid breaking things.
+ */
+/*
+#ifndef memcpy
+#	define memcpy memmove
+#endif
+*/
+
+#include "xz/xz_crc32.c"
+#include "xz/xz_dec_stream.c"
+#include "xz/xz_dec_lzma2.c"
+#include "xz/xz_dec_bcj.c"
+
+#endif /* XZ_PREBOOT */
+
+/* Size of the input and output buffers in multi-call mode */
+#define XZ_IOBUF_SIZE 4096
+
+/*
+ * This function implements the API defined in <linux/decompress/generic.h>.
+ *
+ * This wrapper will automatically choose single-call or multi-call mode
+ * of the native XZ decoder API. The single-call mode can be used only when
+ * both input and output buffers are available as a single chunk, i.e. when
+ * fill() and flush() won't be used.
+ */
+STATIC int decompress_unxz(unsigned char *in, long in_size,
+		     long (*fill)(void *dest, unsigned long size),
+		     long (*flush)(void *src, unsigned long size),
+		     unsigned char *out, long *in_used,
+		     void (*error)(char *x))
+{
+	struct xz_buf b;
+	struct xz_dec *s;
+	enum xz_ret ret;
+	bool must_free_in = false;
+
+#if XZ_INTERNAL_CRC32
+	xz_crc32_init();
+#endif
+
+	if (in_used != NULL)
+		*in_used = 0;
+
+	if (fill == NULL && flush == NULL)
+		s = xz_dec_init(XZ_SINGLE, 0);
+	else
+		s = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1);
+
+	if (s == NULL)
+		goto error_alloc_state;
+
+	if (flush == NULL) {
+		b.out = out;
+		b.out_size = (size_t)-1;
+	} else {
+		b.out_size = XZ_IOBUF_SIZE;
+		b.out = malloc(XZ_IOBUF_SIZE);
+		if (b.out == NULL)
+			goto error_alloc_out;
+	}
+
+	if (in == NULL) {
+		must_free_in = true;
+		in = malloc(XZ_IOBUF_SIZE);
+		if (in == NULL)
+			goto error_alloc_in;
+	}
+
+	b.in = in;
+	b.in_pos = 0;
+	b.in_size = in_size;
+	b.out_pos = 0;
+
+	if (fill == NULL && flush == NULL) {
+		ret = xz_dec_run(s, &b);
+	} else {
+		do {
+			if (b.in_pos == b.in_size && fill != NULL) {
+				if (in_used != NULL)
+					*in_used += b.in_pos;
+
+				b.in_pos = 0;
+
+				in_size = fill(in, XZ_IOBUF_SIZE);
+				if (in_size < 0) {
+					/*
+					 * This isn't an optimal error code
+					 * but it probably isn't worth making
+					 * a new one either.
+					 */
+					ret = XZ_BUF_ERROR;
+					break;
+				}
+
+				b.in_size = in_size;
+			}
+
+			ret = xz_dec_run(s, &b);
+
+			if (flush != NULL && (b.out_pos == b.out_size
+					|| (ret != XZ_OK && b.out_pos > 0))) {
+				/*
+				 * Setting ret here may hide an error
+				 * returned by xz_dec_run(), but probably
+				 * it's not too bad.
+				 */
+				if (flush(b.out, b.out_pos) != (long)b.out_pos)
+					ret = XZ_BUF_ERROR;
+
+				b.out_pos = 0;
+			}
+		} while (ret == XZ_OK);
+
+		if (must_free_in)
+			free(in);
+
+		if (flush != NULL)
+			free(b.out);
+	}
+
+	if (in_used != NULL)
+		*in_used += b.in_pos;
+
+	xz_dec_end(s);
+
+	switch (ret) {
+	case XZ_STREAM_END:
+		return 0;
+
+	case XZ_MEM_ERROR:
+		/* This can occur only in multi-call mode. */
+		error("XZ decompressor ran out of memory");
+		break;
+
+	case XZ_FORMAT_ERROR:
+		error("Input is not in the XZ format (wrong magic bytes)");
+		break;
+
+	case XZ_OPTIONS_ERROR:
+		error("Input was encoded with settings that are not "
+				"supported by this XZ decoder");
+		break;
+
+	case XZ_DATA_ERROR:
+	case XZ_BUF_ERROR:
+		error("XZ-compressed data is corrupt");
+		break;
+
+	default:
+		error("Bug in the XZ decompressor");
+		break;
+	}
+
+	return -1;
+
+error_alloc_in:
+	if (flush != NULL)
+		free(b.out);
+
+error_alloc_out:
+	xz_dec_end(s);
+
+error_alloc_state:
+	error("XZ decompressor ran out of memory");
+	return -1;
+}
+
+/*
+ * This macro is used by architecture-specific files to decompress
+ * the kernel image.
+ */
+#define decompress decompress_unxz
diff --git a/lib/uncompress.c b/lib/uncompress.c
index a4225aa..329c9fc 100644
--- a/lib/uncompress.c
+++ b/lib/uncompress.c
@@ -21,6 +21,7 @@
 #include <bunzip2.h>
 #include <gunzip.h>
 #include <lzo.h>
+#include <linux/xz.h>
 #include <linux/decompress/unlz4.h>
 #include <errno.h>
 #include <filetype.h>
@@ -118,6 +119,11 @@ int uncompress(unsigned char *inbuf, int len,
 		compfn = decompress_unlz4;
 		break;
 #endif
+#ifdef CONFIG_XZ_DECOMPRESS
+	case filetype_xz_compressed:
+		compfn = decompress_unxz;
+		break;
+#endif
 	default:
 		err = asprintf("cannot handle filetype %s", file_type_to_string(ft));
 		error_fn(err);
diff --git a/lib/xz/xz_crc32.c b/lib/xz/xz_crc32.c
new file mode 100644
index 0000000..34532d1
--- /dev/null
+++ b/lib/xz/xz_crc32.c
@@ -0,0 +1,59 @@
+/*
+ * CRC32 using the polynomial from IEEE-802.3
+ *
+ * Authors: Lasse Collin <lasse.collin at tukaani.org>
+ *          Igor Pavlov <http://7-zip.org/>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+/*
+ * This is not the fastest implementation, but it is pretty compact.
+ * The fastest versions of xz_crc32() on modern CPUs without hardware
+ * accelerated CRC instruction are 3-5 times as fast as this version,
+ * but they are bigger and use more memory for the lookup table.
+ */
+
+#include "xz_private.h"
+
+/*
+ * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
+ * See <linux/decompress/mm.h> for details.
+ */
+#ifndef STATIC_RW_DATA
+#	define STATIC_RW_DATA static
+#endif
+
+STATIC_RW_DATA uint32_t xz_crc32_table[256];
+
+XZ_EXTERN void xz_crc32_init(void)
+{
+	const uint32_t poly = 0xEDB88320;
+
+	uint32_t i;
+	uint32_t j;
+	uint32_t r;
+
+	for (i = 0; i < 256; ++i) {
+		r = i;
+		for (j = 0; j < 8; ++j)
+			r = (r >> 1) ^ (poly & ~((r & 1) - 1));
+
+		xz_crc32_table[i] = r;
+	}
+
+	return;
+}
+
+XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
+{
+	crc = ~crc;
+
+	while (size != 0) {
+		crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
+		--size;
+	}
+
+	return ~crc;
+}
diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c
new file mode 100644
index 0000000..a768e6d
--- /dev/null
+++ b/lib/xz/xz_dec_bcj.c
@@ -0,0 +1,574 @@
+/*
+ * Branch/Call/Jump (BCJ) filter decoders
+ *
+ * Authors: Lasse Collin <lasse.collin at tukaani.org>
+ *          Igor Pavlov <http://7-zip.org/>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#include "xz_private.h"
+
+/*
+ * The rest of the file is inside this ifdef. It makes things a little more
+ * convenient when building without support for any BCJ filters.
+ */
+#ifdef XZ_DEC_BCJ
+
+struct xz_dec_bcj {
+	/* Type of the BCJ filter being used */
+	enum {
+		BCJ_X86 = 4,        /* x86 or x86-64 */
+		BCJ_POWERPC = 5,    /* Big endian only */
+		BCJ_IA64 = 6,       /* Big or little endian */
+		BCJ_ARM = 7,        /* Little endian only */
+		BCJ_ARMTHUMB = 8,   /* Little endian only */
+		BCJ_SPARC = 9       /* Big or little endian */
+	} type;
+
+	/*
+	 * Return value of the next filter in the chain. We need to preserve
+	 * this information across calls, because we must not call the next
+	 * filter anymore once it has returned XZ_STREAM_END.
+	 */
+	enum xz_ret ret;
+
+	/* True if we are operating in single-call mode. */
+	bool single_call;
+
+	/*
+	 * Absolute position relative to the beginning of the uncompressed
+	 * data (in a single .xz Block). We care only about the lowest 32
+	 * bits so this doesn't need to be uint64_t even with big files.
+	 */
+	uint32_t pos;
+
+	/* x86 filter state */
+	uint32_t x86_prev_mask;
+
+	/* Temporary space to hold the variables from struct xz_buf */
+	uint8_t *out;
+	size_t out_pos;
+	size_t out_size;
+
+	struct {
+		/* Amount of already filtered data in the beginning of buf */
+		size_t filtered;
+
+		/* Total amount of data currently stored in buf  */
+		size_t size;
+
+		/*
+		 * Buffer to hold a mix of filtered and unfiltered data. This
+		 * needs to be big enough to hold Alignment + 2 * Look-ahead:
+		 *
+		 * Type         Alignment   Look-ahead
+		 * x86              1           4
+		 * PowerPC          4           0
+		 * IA-64           16           0
+		 * ARM              4           0
+		 * ARM-Thumb        2           2
+		 * SPARC            4           0
+		 */
+		uint8_t buf[16];
+	} temp;
+};
+
+#ifdef XZ_DEC_X86
+/*
+ * This is used to test the most significant byte of a memory address
+ * in an x86 instruction.
+ */
+static inline int bcj_x86_test_msbyte(uint8_t b)
+{
+	return b == 0x00 || b == 0xFF;
+}
+
+static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	static const bool mask_to_allowed_status[8]
+		= { true, true, true, false, true, false, false, false };
+
+	static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
+
+	size_t i;
+	size_t prev_pos = (size_t)-1;
+	uint32_t prev_mask = s->x86_prev_mask;
+	uint32_t src;
+	uint32_t dest;
+	uint32_t j;
+	uint8_t b;
+
+	if (size <= 4)
+		return 0;
+
+	size -= 4;
+	for (i = 0; i < size; ++i) {
+		if ((buf[i] & 0xFE) != 0xE8)
+			continue;
+
+		prev_pos = i - prev_pos;
+		if (prev_pos > 3) {
+			prev_mask = 0;
+		} else {
+			prev_mask = (prev_mask << (prev_pos - 1)) & 7;
+			if (prev_mask != 0) {
+				b = buf[i + 4 - mask_to_bit_num[prev_mask]];
+				if (!mask_to_allowed_status[prev_mask]
+						|| bcj_x86_test_msbyte(b)) {
+					prev_pos = i;
+					prev_mask = (prev_mask << 1) | 1;
+					continue;
+				}
+			}
+		}
+
+		prev_pos = i;
+
+		if (bcj_x86_test_msbyte(buf[i + 4])) {
+			src = get_unaligned_le32(buf + i + 1);
+			while (true) {
+				dest = src - (s->pos + (uint32_t)i + 5);
+				if (prev_mask == 0)
+					break;
+
+				j = mask_to_bit_num[prev_mask] * 8;
+				b = (uint8_t)(dest >> (24 - j));
+				if (!bcj_x86_test_msbyte(b))
+					break;
+
+				src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
+			}
+
+			dest &= 0x01FFFFFF;
+			dest |= (uint32_t)0 - (dest & 0x01000000);
+			put_unaligned_le32(dest, buf + i + 1);
+			i += 4;
+		} else {
+			prev_mask = (prev_mask << 1) | 1;
+		}
+	}
+
+	prev_pos = i - prev_pos;
+	s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
+	return i;
+}
+#endif
+
+#ifdef XZ_DEC_POWERPC
+static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint32_t instr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		instr = get_unaligned_be32(buf + i);
+		if ((instr & 0xFC000003) == 0x48000001) {
+			instr &= 0x03FFFFFC;
+			instr -= s->pos + (uint32_t)i;
+			instr &= 0x03FFFFFC;
+			instr |= 0x48000001;
+			put_unaligned_be32(instr, buf + i);
+		}
+	}
+
+	return i;
+}
+#endif
+
+#ifdef XZ_DEC_IA64
+static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	static const uint8_t branch_table[32] = {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		4, 4, 6, 6, 0, 0, 7, 7,
+		4, 4, 0, 0, 4, 4, 0, 0
+	};
+
+	/*
+	 * The local variables take a little bit stack space, but it's less
+	 * than what LZMA2 decoder takes, so it doesn't make sense to reduce
+	 * stack usage here without doing that for the LZMA2 decoder too.
+	 */
+
+	/* Loop counters */
+	size_t i;
+	size_t j;
+
+	/* Instruction slot (0, 1, or 2) in the 128-bit instruction word */
+	uint32_t slot;
+
+	/* Bitwise offset of the instruction indicated by slot */
+	uint32_t bit_pos;
+
+	/* bit_pos split into byte and bit parts */
+	uint32_t byte_pos;
+	uint32_t bit_res;
+
+	/* Address part of an instruction */
+	uint32_t addr;
+
+	/* Mask used to detect which instructions to convert */
+	uint32_t mask;
+
+	/* 41-bit instruction stored somewhere in the lowest 48 bits */
+	uint64_t instr;
+
+	/* Instruction normalized with bit_res for easier manipulation */
+	uint64_t norm;
+
+	for (i = 0; i + 16 <= size; i += 16) {
+		mask = branch_table[buf[i] & 0x1F];
+		for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
+			if (((mask >> slot) & 1) == 0)
+				continue;
+
+			byte_pos = bit_pos >> 3;
+			bit_res = bit_pos & 7;
+			instr = 0;
+			for (j = 0; j < 6; ++j)
+				instr |= (uint64_t)(buf[i + j + byte_pos])
+						<< (8 * j);
+
+			norm = instr >> bit_res;
+
+			if (((norm >> 37) & 0x0F) == 0x05
+					&& ((norm >> 9) & 0x07) == 0) {
+				addr = (norm >> 13) & 0x0FFFFF;
+				addr |= ((uint32_t)(norm >> 36) & 1) << 20;
+				addr <<= 4;
+				addr -= s->pos + (uint32_t)i;
+				addr >>= 4;
+
+				norm &= ~((uint64_t)0x8FFFFF << 13);
+				norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
+				norm |= (uint64_t)(addr & 0x100000)
+						<< (36 - 20);
+
+				instr &= (1 << bit_res) - 1;
+				instr |= norm << bit_res;
+
+				for (j = 0; j < 6; j++)
+					buf[i + j + byte_pos]
+						= (uint8_t)(instr >> (8 * j));
+			}
+		}
+	}
+
+	return i;
+}
+#endif
+
+#ifdef XZ_DEC_ARM
+static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		if (buf[i + 3] == 0xEB) {
+			addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
+					| ((uint32_t)buf[i + 2] << 16);
+			addr <<= 2;
+			addr -= s->pos + (uint32_t)i + 8;
+			addr >>= 2;
+			buf[i] = (uint8_t)addr;
+			buf[i + 1] = (uint8_t)(addr >> 8);
+			buf[i + 2] = (uint8_t)(addr >> 16);
+		}
+	}
+
+	return i;
+}
+#endif
+
+#ifdef XZ_DEC_ARMTHUMB
+static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint32_t addr;
+
+	for (i = 0; i + 4 <= size; i += 2) {
+		if ((buf[i + 1] & 0xF8) == 0xF0
+				&& (buf[i + 3] & 0xF8) == 0xF8) {
+			addr = (((uint32_t)buf[i + 1] & 0x07) << 19)
+					| ((uint32_t)buf[i] << 11)
+					| (((uint32_t)buf[i + 3] & 0x07) << 8)
+					| (uint32_t)buf[i + 2];
+			addr <<= 1;
+			addr -= s->pos + (uint32_t)i + 4;
+			addr >>= 1;
+			buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07));
+			buf[i] = (uint8_t)(addr >> 11);
+			buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07));
+			buf[i + 2] = (uint8_t)addr;
+			i += 2;
+		}
+	}
+
+	return i;
+}
+#endif
+
+#ifdef XZ_DEC_SPARC
+static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+	size_t i;
+	uint32_t instr;
+
+	for (i = 0; i + 4 <= size; i += 4) {
+		instr = get_unaligned_be32(buf + i);
+		if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
+			instr <<= 2;
+			instr -= s->pos + (uint32_t)i;
+			instr >>= 2;
+			instr = ((uint32_t)0x40000000 - (instr & 0x400000))
+					| 0x40000000 | (instr & 0x3FFFFF);
+			put_unaligned_be32(instr, buf + i);
+		}
+	}
+
+	return i;
+}
+#endif
+
+/*
+ * Apply the selected BCJ filter. Update *pos and s->pos to match the amount
+ * of data that got filtered.
+ *
+ * NOTE: This is implemented as a switch statement to avoid using function
+ * pointers, which could be problematic in the kernel boot code, which must
+ * avoid pointers to static data (at least on x86).
+ */
+static void bcj_apply(struct xz_dec_bcj *s,
+		      uint8_t *buf, size_t *pos, size_t size)
+{
+	size_t filtered;
+
+	buf += *pos;
+	size -= *pos;
+
+	switch (s->type) {
+#ifdef XZ_DEC_X86
+	case BCJ_X86:
+		filtered = bcj_x86(s, buf, size);
+		break;
+#endif
+#ifdef XZ_DEC_POWERPC
+	case BCJ_POWERPC:
+		filtered = bcj_powerpc(s, buf, size);
+		break;
+#endif
+#ifdef XZ_DEC_IA64
+	case BCJ_IA64:
+		filtered = bcj_ia64(s, buf, size);
+		break;
+#endif
+#ifdef XZ_DEC_ARM
+	case BCJ_ARM:
+		filtered = bcj_arm(s, buf, size);
+		break;
+#endif
+#ifdef XZ_DEC_ARMTHUMB
+	case BCJ_ARMTHUMB:
+		filtered = bcj_armthumb(s, buf, size);
+		break;
+#endif
+#ifdef XZ_DEC_SPARC
+	case BCJ_SPARC:
+		filtered = bcj_sparc(s, buf, size);
+		break;
+#endif
+	default:
+		/* Never reached but silence compiler warnings. */
+		filtered = 0;
+		break;
+	}
+
+	*pos += filtered;
+	s->pos += filtered;
+}
+
+/*
+ * Flush pending filtered data from temp to the output buffer.
+ * Move the remaining mixture of possibly filtered and unfiltered
+ * data to the beginning of temp.
+ */
+static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
+{
+	size_t copy_size;
+
+	copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos);
+	memcpy(b->out + b->out_pos, s->temp.buf, copy_size);
+	b->out_pos += copy_size;
+
+	s->temp.filtered -= copy_size;
+	s->temp.size -= copy_size;
+	memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
+}
+
+/*
+ * The BCJ filter functions are primitive in sense that they process the
+ * data in chunks of 1-16 bytes. To hide this issue, this function does
+ * some buffering.
+ */
+XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
+				     struct xz_dec_lzma2 *lzma2,
+				     struct xz_buf *b)
+{
+	size_t out_start;
+
+	/*
+	 * Flush pending already filtered data to the output buffer. Return
+	 * immediatelly if we couldn't flush everything, or if the next
+	 * filter in the chain had already returned XZ_STREAM_END.
+	 */
+	if (s->temp.filtered > 0) {
+		bcj_flush(s, b);
+		if (s->temp.filtered > 0)
+			return XZ_OK;
+
+		if (s->ret == XZ_STREAM_END)
+			return XZ_STREAM_END;
+	}
+
+	/*
+	 * If we have more output space than what is currently pending in
+	 * temp, copy the unfiltered data from temp to the output buffer
+	 * and try to fill the output buffer by decoding more data from the
+	 * next filter in the chain. Apply the BCJ filter on the new data
+	 * in the output buffer. If everything cannot be filtered, copy it
+	 * to temp and rewind the output buffer position accordingly.
+	 *
+	 * This needs to be always run when temp.size == 0 to handle a special
+	 * case where the output buffer is full and the next filter has no
+	 * more output coming but hasn't returned XZ_STREAM_END yet.
+	 */
+	if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
+		out_start = b->out_pos;
+		memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
+		b->out_pos += s->temp.size;
+
+		s->ret = xz_dec_lzma2_run(lzma2, b);
+		if (s->ret != XZ_STREAM_END
+				&& (s->ret != XZ_OK || s->single_call))
+			return s->ret;
+
+		bcj_apply(s, b->out, &out_start, b->out_pos);
+
+		/*
+		 * As an exception, if the next filter returned XZ_STREAM_END,
+		 * we can do that too, since the last few bytes that remain
+		 * unfiltered are meant to remain unfiltered.
+		 */
+		if (s->ret == XZ_STREAM_END)
+			return XZ_STREAM_END;
+
+		s->temp.size = b->out_pos - out_start;
+		b->out_pos -= s->temp.size;
+		memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
+
+		/*
+		 * If there wasn't enough input to the next filter to fill
+		 * the output buffer with unfiltered data, there's no point
+		 * to try decoding more data to temp.
+		 */
+		if (b->out_pos + s->temp.size < b->out_size)
+			return XZ_OK;
+	}
+
+	/*
+	 * We have unfiltered data in temp. If the output buffer isn't full
+	 * yet, try to fill the temp buffer by decoding more data from the
+	 * next filter. Apply the BCJ filter on temp. Then we hopefully can
+	 * fill the actual output buffer by copying filtered data from temp.
+	 * A mix of filtered and unfiltered data may be left in temp; it will
+	 * be taken care on the next call to this function.
+	 */
+	if (b->out_pos < b->out_size) {
+		/* Make b->out{,_pos,_size} temporarily point to s->temp. */
+		s->out = b->out;
+		s->out_pos = b->out_pos;
+		s->out_size = b->out_size;
+		b->out = s->temp.buf;
+		b->out_pos = s->temp.size;
+		b->out_size = sizeof(s->temp.buf);
+
+		s->ret = xz_dec_lzma2_run(lzma2, b);
+
+		s->temp.size = b->out_pos;
+		b->out = s->out;
+		b->out_pos = s->out_pos;
+		b->out_size = s->out_size;
+
+		if (s->ret != XZ_OK && s->ret != XZ_STREAM_END)
+			return s->ret;
+
+		bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
+
+		/*
+		 * If the next filter returned XZ_STREAM_END, we mark that
+		 * everything is filtered, since the last unfiltered bytes
+		 * of the stream are meant to be left as is.
+		 */
+		if (s->ret == XZ_STREAM_END)
+			s->temp.filtered = s->temp.size;
+
+		bcj_flush(s, b);
+		if (s->temp.filtered > 0)
+			return XZ_OK;
+	}
+
+	return s->ret;
+}
+
+XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call)
+{
+	struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (s != NULL)
+		s->single_call = single_call;
+
+	return s;
+}
+
+XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
+{
+	switch (id) {
+#ifdef XZ_DEC_X86
+	case BCJ_X86:
+#endif
+#ifdef XZ_DEC_POWERPC
+	case BCJ_POWERPC:
+#endif
+#ifdef XZ_DEC_IA64
+	case BCJ_IA64:
+#endif
+#ifdef XZ_DEC_ARM
+	case BCJ_ARM:
+#endif
+#ifdef XZ_DEC_ARMTHUMB
+	case BCJ_ARMTHUMB:
+#endif
+#ifdef XZ_DEC_SPARC
+	case BCJ_SPARC:
+#endif
+		break;
+
+	default:
+		/* Unsupported Filter ID */
+		return XZ_OPTIONS_ERROR;
+	}
+
+	s->type = id;
+	s->ret = XZ_OK;
+	s->pos = 0;
+	s->x86_prev_mask = 0;
+	s->temp.filtered = 0;
+	s->temp.size = 0;
+
+	return XZ_OK;
+}
+
+#endif
diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c
new file mode 100644
index 0000000..08c3c80
--- /dev/null
+++ b/lib/xz/xz_dec_lzma2.c
@@ -0,0 +1,1175 @@
+/*
+ * LZMA2 decoder
+ *
+ * Authors: Lasse Collin <lasse.collin at tukaani.org>
+ *          Igor Pavlov <http://7-zip.org/>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#include "xz_private.h"
+#include "xz_lzma2.h"
+
+/*
+ * Range decoder initialization eats the first five bytes of each LZMA chunk.
+ */
+#define RC_INIT_BYTES 5
+
+/*
+ * Minimum number of usable input buffer to safely decode one LZMA symbol.
+ * The worst case is that we decode 22 bits using probabilities and 26
+ * direct bits. This may decode at maximum of 20 bytes of input. However,
+ * lzma_main() does an extra normalization before returning, thus we
+ * need to put 21 here.
+ */
+#define LZMA_IN_REQUIRED 21
+
+/*
+ * Dictionary (history buffer)
+ *
+ * These are always true:
+ *    start <= pos <= full <= end
+ *    pos <= limit <= end
+ *
+ * In multi-call mode, also these are true:
+ *    end == size
+ *    size <= size_max
+ *    allocated <= size
+ *
+ * Most of these variables are size_t to support single-call mode,
+ * in which the dictionary variables address the actual output
+ * buffer directly.
+ */
+struct dictionary {
+	/* Beginning of the history buffer */
+	uint8_t *buf;
+
+	/* Old position in buf (before decoding more data) */
+	size_t start;
+
+	/* Position in buf */
+	size_t pos;
+
+	/*
+	 * How full dictionary is. This is used to detect corrupt input that
+	 * would read beyond the beginning of the uncompressed stream.
+	 */
+	size_t full;
+
+	/* Write limit; we don't write to buf[limit] or later bytes. */
+	size_t limit;
+
+	/*
+	 * End of the dictionary buffer. In multi-call mode, this is
+	 * the same as the dictionary size. In single-call mode, this
+	 * indicates the size of the output buffer.
+	 */
+	size_t end;
+
+	/*
+	 * Size of the dictionary as specified in Block Header. This is used
+	 * together with "full" to detect corrupt input that would make us
+	 * read beyond the beginning of the uncompressed stream.
+	 */
+	uint32_t size;
+
+	/*
+	 * Maximum allowed dictionary size in multi-call mode.
+	 * This is ignored in single-call mode.
+	 */
+	uint32_t size_max;
+
+	/*
+	 * Amount of memory currently allocated for the dictionary.
+	 * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC,
+	 * size_max is always the same as the allocated size.)
+	 */
+	uint32_t allocated;
+
+	/* Operation mode */
+	enum xz_mode mode;
+};
+
+/* Range decoder */
+struct rc_dec {
+	uint32_t range;
+	uint32_t code;
+
+	/*
+	 * Number of initializing bytes remaining to be read
+	 * by rc_read_init().
+	 */
+	uint32_t init_bytes_left;
+
+	/*
+	 * Buffer from which we read our input. It can be either
+	 * temp.buf or the caller-provided input buffer.
+	 */
+	const uint8_t *in;
+	size_t in_pos;
+	size_t in_limit;
+};
+
+/* Probabilities for a length decoder. */
+struct lzma_len_dec {
+	/* Probability of match length being at least 10 */
+	uint16_t choice;
+
+	/* Probability of match length being at least 18 */
+	uint16_t choice2;
+
+	/* Probabilities for match lengths 2-9 */
+	uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
+
+	/* Probabilities for match lengths 10-17 */
+	uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
+
+	/* Probabilities for match lengths 18-273 */
+	uint16_t high[LEN_HIGH_SYMBOLS];
+};
+
+struct lzma_dec {
+	/* Distances of latest four matches */
+	uint32_t rep0;
+	uint32_t rep1;
+	uint32_t rep2;
+	uint32_t rep3;
+
+	/* Types of the most recently seen LZMA symbols */
+	enum lzma_state state;
+
+	/*
+	 * Length of a match. This is updated so that dict_repeat can
+	 * be called again to finish repeating the whole match.
+	 */
+	uint32_t len;
+
+	/*
+	 * LZMA properties or related bit masks (number of literal
+	 * context bits, a mask dervied from the number of literal
+	 * position bits, and a mask dervied from the number
+	 * position bits)
+	 */
+	uint32_t lc;
+	uint32_t literal_pos_mask; /* (1 << lp) - 1 */
+	uint32_t pos_mask;         /* (1 << pb) - 1 */
+
+	/* If 1, it's a match. Otherwise it's a single 8-bit literal. */
+	uint16_t is_match[STATES][POS_STATES_MAX];
+
+	/* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
+	uint16_t is_rep[STATES];
+
+	/*
+	 * If 0, distance of a repeated match is rep0.
+	 * Otherwise check is_rep1.
+	 */
+	uint16_t is_rep0[STATES];
+
+	/*
+	 * If 0, distance of a repeated match is rep1.
+	 * Otherwise check is_rep2.
+	 */
+	uint16_t is_rep1[STATES];
+
+	/* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
+	uint16_t is_rep2[STATES];
+
+	/*
+	 * If 1, the repeated match has length of one byte. Otherwise
+	 * the length is decoded from rep_len_decoder.
+	 */
+	uint16_t is_rep0_long[STATES][POS_STATES_MAX];
+
+	/*
+	 * Probability tree for the highest two bits of the match
+	 * distance. There is a separate probability tree for match
+	 * lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
+	 */
+	uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
+
+	/*
+	 * Probility trees for additional bits for match distance
+	 * when the distance is in the range [4, 127].
+	 */
+	uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
+
+	/*
+	 * Probability tree for the lowest four bits of a match
+	 * distance that is equal to or greater than 128.
+	 */
+	uint16_t dist_align[ALIGN_SIZE];
+
+	/* Length of a normal match */
+	struct lzma_len_dec match_len_dec;
+
+	/* Length of a repeated match */
+	struct lzma_len_dec rep_len_dec;
+
+	/* Probabilities of literals */
+	uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
+};
+
+struct lzma2_dec {
+	/* Position in xz_dec_lzma2_run(). */
+	enum lzma2_seq {
+		SEQ_CONTROL,
+		SEQ_UNCOMPRESSED_1,
+		SEQ_UNCOMPRESSED_2,
+		SEQ_COMPRESSED_0,
+		SEQ_COMPRESSED_1,
+		SEQ_PROPERTIES,
+		SEQ_LZMA_PREPARE,
+		SEQ_LZMA_RUN,
+		SEQ_COPY
+	} sequence;
+
+	/* Next position after decoding the compressed size of the chunk. */
+	enum lzma2_seq next_sequence;
+
+	/* Uncompressed size of LZMA chunk (2 MiB at maximum) */
+	uint32_t uncompressed;
+
+	/*
+	 * Compressed size of LZMA chunk or compressed/uncompressed
+	 * size of uncompressed chunk (64 KiB at maximum)
+	 */
+	uint32_t compressed;
+
+	/*
+	 * True if dictionary reset is needed. This is false before
+	 * the first chunk (LZMA or uncompressed).
+	 */
+	bool need_dict_reset;
+
+	/*
+	 * True if new LZMA properties are needed. This is false
+	 * before the first LZMA chunk.
+	 */
+	bool need_props;
+};
+
+struct xz_dec_lzma2 {
+	/*
+	 * The order below is important on x86 to reduce code size and
+	 * it shouldn't hurt on other platforms. Everything up to and
+	 * including lzma.pos_mask are in the first 128 bytes on x86-32,
+	 * which allows using smaller instructions to access those
+	 * variables. On x86-64, fewer variables fit into the first 128
+	 * bytes, but this is still the best order without sacrificing
+	 * the readability by splitting the structures.
+	 */
+	struct rc_dec rc;
+	struct dictionary dict;
+	struct lzma2_dec lzma2;
+	struct lzma_dec lzma;
+
+	/*
+	 * Temporary buffer which holds small number of input bytes between
+	 * decoder calls. See lzma2_lzma() for details.
+	 */
+	struct {
+		uint32_t size;
+		uint8_t buf[3 * LZMA_IN_REQUIRED];
+	} temp;
+};
+
+/**************
+ * Dictionary *
+ **************/
+
+/*
+ * Reset the dictionary state. When in single-call mode, set up the beginning
+ * of the dictionary to point to the actual output buffer.
+ */
+static void dict_reset(struct dictionary *dict, struct xz_buf *b)
+{
+	if (DEC_IS_SINGLE(dict->mode)) {
+		dict->buf = b->out + b->out_pos;
+		dict->end = b->out_size - b->out_pos;
+	}
+
+	dict->start = 0;
+	dict->pos = 0;
+	dict->limit = 0;
+	dict->full = 0;
+}
+
+/* Set dictionary write limit */
+static void dict_limit(struct dictionary *dict, size_t out_max)
+{
+	if (dict->end - dict->pos <= out_max)
+		dict->limit = dict->end;
+	else
+		dict->limit = dict->pos + out_max;
+}
+
+/* Return true if at least one byte can be written into the dictionary. */
+static inline bool dict_has_space(const struct dictionary *dict)
+{
+	return dict->pos < dict->limit;
+}
+
+/*
+ * Get a byte from the dictionary at the given distance. The distance is
+ * assumed to valid, or as a special case, zero when the dictionary is
+ * still empty. This special case is needed for single-call decoding to
+ * avoid writing a '\0' to the end of the destination buffer.
+ */
+static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
+{
+	size_t offset = dict->pos - dist - 1;
+
+	if (dist >= dict->pos)
+		offset += dict->end;
+
+	return dict->full > 0 ? dict->buf[offset] : 0;
+}
+
+/*
+ * Put one byte into the dictionary. It is assumed that there is space for it.
+ */
+static inline void dict_put(struct dictionary *dict, uint8_t byte)
+{
+	dict->buf[dict->pos++] = byte;
+
+	if (dict->full < dict->pos)
+		dict->full = dict->pos;
+}
+
+/*
+ * Repeat given number of bytes from the given distance. If the distance is
+ * invalid, false is returned. On success, true is returned and *len is
+ * updated to indicate how many bytes were left to be repeated.
+ */
+static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
+{
+	size_t back;
+	uint32_t left;
+
+	if (dist >= dict->full || dist >= dict->size)
+		return false;
+
+	left = min_t(size_t, dict->limit - dict->pos, *len);
+	*len -= left;
+
+	back = dict->pos - dist - 1;
+	if (dist >= dict->pos)
+		back += dict->end;
+
+	do {
+		dict->buf[dict->pos++] = dict->buf[back++];
+		if (back == dict->end)
+			back = 0;
+	} while (--left > 0);
+
+	if (dict->full < dict->pos)
+		dict->full = dict->pos;
+
+	return true;
+}
+
+/* Copy uncompressed data as is from input to dictionary and output buffers. */
+static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
+			      uint32_t *left)
+{
+	size_t copy_size;
+
+	while (*left > 0 && b->in_pos < b->in_size
+			&& b->out_pos < b->out_size) {
+		copy_size = min(b->in_size - b->in_pos,
+				b->out_size - b->out_pos);
+		if (copy_size > dict->end - dict->pos)
+			copy_size = dict->end - dict->pos;
+		if (copy_size > *left)
+			copy_size = *left;
+
+		*left -= copy_size;
+
+		memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
+		dict->pos += copy_size;
+
+		if (dict->full < dict->pos)
+			dict->full = dict->pos;
+
+		if (DEC_IS_MULTI(dict->mode)) {
+			if (dict->pos == dict->end)
+				dict->pos = 0;
+
+			memcpy(b->out + b->out_pos, b->in + b->in_pos,
+					copy_size);
+		}
+
+		dict->start = dict->pos;
+
+		b->out_pos += copy_size;
+		b->in_pos += copy_size;
+	}
+}
+
+/*
+ * Flush pending data from dictionary to b->out. It is assumed that there is
+ * enough space in b->out. This is guaranteed because caller uses dict_limit()
+ * before decoding data into the dictionary.
+ */
+static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
+{
+	size_t copy_size = dict->pos - dict->start;
+
+	if (DEC_IS_MULTI(dict->mode)) {
+		if (dict->pos == dict->end)
+			dict->pos = 0;
+
+		memcpy(b->out + b->out_pos, dict->buf + dict->start,
+				copy_size);
+	}
+
+	dict->start = dict->pos;
+	b->out_pos += copy_size;
+	return copy_size;
+}
+
+/*****************
+ * Range decoder *
+ *****************/
+
+/* Reset the range decoder. */
+static void rc_reset(struct rc_dec *rc)
+{
+	rc->range = (uint32_t)-1;
+	rc->code = 0;
+	rc->init_bytes_left = RC_INIT_BYTES;
+}
+
+/*
+ * Read the first five initial bytes into rc->code if they haven't been
+ * read already. (Yes, the first byte gets completely ignored.)
+ */
+static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
+{
+	while (rc->init_bytes_left > 0) {
+		if (b->in_pos == b->in_size)
+			return false;
+
+		rc->code = (rc->code << 8) + b->in[b->in_pos++];
+		--rc->init_bytes_left;
+	}
+
+	return true;
+}
+
+/* Return true if there may not be enough input for the next decoding loop. */
+static inline bool rc_limit_exceeded(const struct rc_dec *rc)
+{
+	return rc->in_pos > rc->in_limit;
+}
+
+/*
+ * Return true if it is possible (from point of view of range decoder) that
+ * we have reached the end of the LZMA chunk.
+ */
+static inline bool rc_is_finished(const struct rc_dec *rc)
+{
+	return rc->code == 0;
+}
+
+/* Read the next input byte if needed. */
+static __always_inline void rc_normalize(struct rc_dec *rc)
+{
+	if (rc->range < RC_TOP_VALUE) {
+		rc->range <<= RC_SHIFT_BITS;
+		rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
+	}
+}
+
+/*
+ * Decode one bit. In some versions, this function has been splitted in three
+ * functions so that the compiler is supposed to be able to more easily avoid
+ * an extra branch. In this particular version of the LZMA decoder, this
+ * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3
+ * on x86). Using a non-splitted version results in nicer looking code too.
+ *
+ * NOTE: This must return an int. Do not make it return a bool or the speed
+ * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care,
+ * and it generates 10-20 % faster code than GCC 3.x from this file anyway.)
+ */
+static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
+{
+	uint32_t bound;
+	int bit;
+
+	rc_normalize(rc);
+	bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
+	if (rc->code < bound) {
+		rc->range = bound;
+		*prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
+		bit = 0;
+	} else {
+		rc->range -= bound;
+		rc->code -= bound;
+		*prob -= *prob >> RC_MOVE_BITS;
+		bit = 1;
+	}
+
+	return bit;
+}
+
+/* Decode a bittree starting from the most significant bit. */
+static __always_inline uint32_t rc_bittree(struct rc_dec *rc,
+					   uint16_t *probs, uint32_t limit)
+{
+	uint32_t symbol = 1;
+
+	do {
+		if (rc_bit(rc, &probs[symbol]))
+			symbol = (symbol << 1) + 1;
+		else
+			symbol <<= 1;
+	} while (symbol < limit);
+
+	return symbol;
+}
+
+/* Decode a bittree starting from the least significant bit. */
+static __always_inline void rc_bittree_reverse(struct rc_dec *rc,
+					       uint16_t *probs,
+					       uint32_t *dest, uint32_t limit)
+{
+	uint32_t symbol = 1;
+	uint32_t i = 0;
+
+	do {
+		if (rc_bit(rc, &probs[symbol])) {
+			symbol = (symbol << 1) + 1;
+			*dest += 1 << i;
+		} else {
+			symbol <<= 1;
+		}
+	} while (++i < limit);
+}
+
+/* Decode direct bits (fixed fifty-fifty probability) */
+static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
+{
+	uint32_t mask;
+
+	do {
+		rc_normalize(rc);
+		rc->range >>= 1;
+		rc->code -= rc->range;
+		mask = (uint32_t)0 - (rc->code >> 31);
+		rc->code += rc->range & mask;
+		*dest = (*dest << 1) + (mask + 1);
+	} while (--limit > 0);
+}
+
+/********
+ * LZMA *
+ ********/
+
+/* Get pointer to literal coder probability array. */
+static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
+{
+	uint32_t prev_byte = dict_get(&s->dict, 0);
+	uint32_t low = prev_byte >> (8 - s->lzma.lc);
+	uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
+	return s->lzma.literal[low + high];
+}
+
+/* Decode a literal (one 8-bit byte) */
+static void lzma_literal(struct xz_dec_lzma2 *s)
+{
+	uint16_t *probs;
+	uint32_t symbol;
+	uint32_t match_byte;
+	uint32_t match_bit;
+	uint32_t offset;
+	uint32_t i;
+
+	probs = lzma_literal_probs(s);
+
+	if (lzma_state_is_literal(s->lzma.state)) {
+		symbol = rc_bittree(&s->rc, probs, 0x100);
+	} else {
+		symbol = 1;
+		match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
+		offset = 0x100;
+
+		do {
+			match_bit = match_byte & offset;
+			match_byte <<= 1;
+			i = offset + match_bit + symbol;
+
+			if (rc_bit(&s->rc, &probs[i])) {
+				symbol = (symbol << 1) + 1;
+				offset &= match_bit;
+			} else {
+				symbol <<= 1;
+				offset &= ~match_bit;
+			}
+		} while (symbol < 0x100);
+	}
+
+	dict_put(&s->dict, (uint8_t)symbol);
+	lzma_state_literal(&s->lzma.state);
+}
+
+/* Decode the length of the match into s->lzma.len. */
+static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
+		     uint32_t pos_state)
+{
+	uint16_t *probs;
+	uint32_t limit;
+
+	if (!rc_bit(&s->rc, &l->choice)) {
+		probs = l->low[pos_state];
+		limit = LEN_LOW_SYMBOLS;
+		s->lzma.len = MATCH_LEN_MIN;
+	} else {
+		if (!rc_bit(&s->rc, &l->choice2)) {
+			probs = l->mid[pos_state];
+			limit = LEN_MID_SYMBOLS;
+			s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
+		} else {
+			probs = l->high;
+			limit = LEN_HIGH_SYMBOLS;
+			s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
+					+ LEN_MID_SYMBOLS;
+		}
+	}
+
+	s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
+}
+
+/* Decode a match. The distance will be stored in s->lzma.rep0. */
+static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
+{
+	uint16_t *probs;
+	uint32_t dist_slot;
+	uint32_t limit;
+
+	lzma_state_match(&s->lzma.state);
+
+	s->lzma.rep3 = s->lzma.rep2;
+	s->lzma.rep2 = s->lzma.rep1;
+	s->lzma.rep1 = s->lzma.rep0;
+
+	lzma_len(s, &s->lzma.match_len_dec, pos_state);
+
+	probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
+	dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
+
+	if (dist_slot < DIST_MODEL_START) {
+		s->lzma.rep0 = dist_slot;
+	} else {
+		limit = (dist_slot >> 1) - 1;
+		s->lzma.rep0 = 2 + (dist_slot & 1);
+
+		if (dist_slot < DIST_MODEL_END) {
+			s->lzma.rep0 <<= limit;
+			probs = s->lzma.dist_special + s->lzma.rep0
+					- dist_slot - 1;
+			rc_bittree_reverse(&s->rc, probs,
+					&s->lzma.rep0, limit);
+		} else {
+			rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
+			s->lzma.rep0 <<= ALIGN_BITS;
+			rc_bittree_reverse(&s->rc, s->lzma.dist_align,
+					&s->lzma.rep0, ALIGN_BITS);
+		}
+	}
+}
+
+/*
+ * Decode a repeated match. The distance is one of the four most recently
+ * seen matches. The distance will be stored in s->lzma.rep0.
+ */
+static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
+{
+	uint32_t tmp;
+
+	if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
+		if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
+				s->lzma.state][pos_state])) {
+			lzma_state_short_rep(&s->lzma.state);
+			s->lzma.len = 1;
+			return;
+		}
+	} else {
+		if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
+			tmp = s->lzma.rep1;
+		} else {
+			if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
+				tmp = s->lzma.rep2;
+			} else {
+				tmp = s->lzma.rep3;
+				s->lzma.rep3 = s->lzma.rep2;
+			}
+
+			s->lzma.rep2 = s->lzma.rep1;
+		}
+
+		s->lzma.rep1 = s->lzma.rep0;
+		s->lzma.rep0 = tmp;
+	}
+
+	lzma_state_long_rep(&s->lzma.state);
+	lzma_len(s, &s->lzma.rep_len_dec, pos_state);
+}
+
+/* LZMA decoder core */
+static bool lzma_main(struct xz_dec_lzma2 *s)
+{
+	uint32_t pos_state;
+
+	/*
+	 * If the dictionary was reached during the previous call, try to
+	 * finish the possibly pending repeat in the dictionary.
+	 */
+	if (dict_has_space(&s->dict) && s->lzma.len > 0)
+		dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
+
+	/*
+	 * Decode more LZMA symbols. One iteration may consume up to
+	 * LZMA_IN_REQUIRED - 1 bytes.
+	 */
+	while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
+		pos_state = s->dict.pos & s->lzma.pos_mask;
+
+		if (!rc_bit(&s->rc, &s->lzma.is_match[
+				s->lzma.state][pos_state])) {
+			lzma_literal(s);
+		} else {
+			if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
+				lzma_rep_match(s, pos_state);
+			else
+				lzma_match(s, pos_state);
+
+			if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
+				return false;
+		}
+	}
+
+	/*
+	 * Having the range decoder always normalized when we are outside
+	 * this function makes it easier to correctly handle end of the chunk.
+	 */
+	rc_normalize(&s->rc);
+
+	return true;
+}
+
+/*
+ * Reset the LZMA decoder and range decoder state. Dictionary is nore reset
+ * here, because LZMA state may be reset without resetting the dictionary.
+ */
+static void lzma_reset(struct xz_dec_lzma2 *s)
+{
+	uint16_t *probs;
+	size_t i;
+
+	s->lzma.state = STATE_LIT_LIT;
+	s->lzma.rep0 = 0;
+	s->lzma.rep1 = 0;
+	s->lzma.rep2 = 0;
+	s->lzma.rep3 = 0;
+
+	/*
+	 * All probabilities are initialized to the same value. This hack
+	 * makes the code smaller by avoiding a separate loop for each
+	 * probability array.
+	 *
+	 * This could be optimized so that only that part of literal
+	 * probabilities that are actually required. In the common case
+	 * we would write 12 KiB less.
+	 */
+	probs = s->lzma.is_match[0];
+	for (i = 0; i < PROBS_TOTAL; ++i)
+		probs[i] = RC_BIT_MODEL_TOTAL / 2;
+
+	rc_reset(&s->rc);
+}
+
+/*
+ * Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks
+ * from the decoded lp and pb values. On success, the LZMA decoder state is
+ * reset and true is returned.
+ */
+static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
+{
+	if (props > (4 * 5 + 4) * 9 + 8)
+		return false;
+
+	s->lzma.pos_mask = 0;
+	while (props >= 9 * 5) {
+		props -= 9 * 5;
+		++s->lzma.pos_mask;
+	}
+
+	s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
+
+	s->lzma.literal_pos_mask = 0;
+	while (props >= 9) {
+		props -= 9;
+		++s->lzma.literal_pos_mask;
+	}
+
+	s->lzma.lc = props;
+
+	if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
+		return false;
+
+	s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
+
+	lzma_reset(s);
+
+	return true;
+}
+
+/*********
+ * LZMA2 *
+ *********/
+
+/*
+ * The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't
+ * been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This
+ * wrapper function takes care of making the LZMA decoder's assumption safe.
+ *
+ * As long as there is plenty of input left to be decoded in the current LZMA
+ * chunk, we decode directly from the caller-supplied input buffer until
+ * there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into
+ * s->temp.buf, which (hopefully) gets filled on the next call to this
+ * function. We decode a few bytes from the temporary buffer so that we can
+ * continue decoding from the caller-supplied input buffer again.
+ */
+static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
+{
+	size_t in_avail;
+	uint32_t tmp;
+
+	in_avail = b->in_size - b->in_pos;
+	if (s->temp.size > 0 || s->lzma2.compressed == 0) {
+		tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
+		if (tmp > s->lzma2.compressed - s->temp.size)
+			tmp = s->lzma2.compressed - s->temp.size;
+		if (tmp > in_avail)
+			tmp = in_avail;
+
+		memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
+
+		if (s->temp.size + tmp == s->lzma2.compressed) {
+			memzero(s->temp.buf + s->temp.size + tmp,
+					sizeof(s->temp.buf)
+						- s->temp.size - tmp);
+			s->rc.in_limit = s->temp.size + tmp;
+		} else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
+			s->temp.size += tmp;
+			b->in_pos += tmp;
+			return true;
+		} else {
+			s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
+		}
+
+		s->rc.in = s->temp.buf;
+		s->rc.in_pos = 0;
+
+		if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
+			return false;
+
+		s->lzma2.compressed -= s->rc.in_pos;
+
+		if (s->rc.in_pos < s->temp.size) {
+			s->temp.size -= s->rc.in_pos;
+			memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
+					s->temp.size);
+			return true;
+		}
+
+		b->in_pos += s->rc.in_pos - s->temp.size;
+		s->temp.size = 0;
+	}
+
+	in_avail = b->in_size - b->in_pos;
+	if (in_avail >= LZMA_IN_REQUIRED) {
+		s->rc.in = b->in;
+		s->rc.in_pos = b->in_pos;
+
+		if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
+			s->rc.in_limit = b->in_pos + s->lzma2.compressed;
+		else
+			s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
+
+		if (!lzma_main(s))
+			return false;
+
+		in_avail = s->rc.in_pos - b->in_pos;
+		if (in_avail > s->lzma2.compressed)
+			return false;
+
+		s->lzma2.compressed -= in_avail;
+		b->in_pos = s->rc.in_pos;
+	}
+
+	in_avail = b->in_size - b->in_pos;
+	if (in_avail < LZMA_IN_REQUIRED) {
+		if (in_avail > s->lzma2.compressed)
+			in_avail = s->lzma2.compressed;
+
+		memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
+		s->temp.size = in_avail;
+		b->in_pos += in_avail;
+	}
+
+	return true;
+}
+
+/*
+ * Take care of the LZMA2 control layer, and forward the job of actual LZMA
+ * decoding or copying of uncompressed chunks to other functions.
+ */
+XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
+				       struct xz_buf *b)
+{
+	uint32_t tmp;
+
+	while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
+		switch (s->lzma2.sequence) {
+		case SEQ_CONTROL:
+			/*
+			 * LZMA2 control byte
+			 *
+			 * Exact values:
+			 *   0x00   End marker
+			 *   0x01   Dictionary reset followed by
+			 *          an uncompressed chunk
+			 *   0x02   Uncompressed chunk (no dictionary reset)
+			 *
+			 * Highest three bits (s->control & 0xE0):
+			 *   0xE0   Dictionary reset, new properties and state
+			 *          reset, followed by LZMA compressed chunk
+			 *   0xC0   New properties and state reset, followed
+			 *          by LZMA compressed chunk (no dictionary
+			 *          reset)
+			 *   0xA0   State reset using old properties,
+			 *          followed by LZMA compressed chunk (no
+			 *          dictionary reset)
+			 *   0x80   LZMA chunk (no dictionary or state reset)
+			 *
+			 * For LZMA compressed chunks, the lowest five bits
+			 * (s->control & 1F) are the highest bits of the
+			 * uncompressed size (bits 16-20).
+			 *
+			 * A new LZMA2 stream must begin with a dictionary
+			 * reset. The first LZMA chunk must set new
+			 * properties and reset the LZMA state.
+			 *
+			 * Values that don't match anything described above
+			 * are invalid and we return XZ_DATA_ERROR.
+			 */
+			tmp = b->in[b->in_pos++];
+
+			if (tmp == 0x00)
+				return XZ_STREAM_END;
+
+			if (tmp >= 0xE0 || tmp == 0x01) {
+				s->lzma2.need_props = true;
+				s->lzma2.need_dict_reset = false;
+				dict_reset(&s->dict, b);
+			} else if (s->lzma2.need_dict_reset) {
+				return XZ_DATA_ERROR;
+			}
+
+			if (tmp >= 0x80) {
+				s->lzma2.uncompressed = (tmp & 0x1F) << 16;
+				s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
+
+				if (tmp >= 0xC0) {
+					/*
+					 * When there are new properties,
+					 * state reset is done at
+					 * SEQ_PROPERTIES.
+					 */
+					s->lzma2.need_props = false;
+					s->lzma2.next_sequence
+							= SEQ_PROPERTIES;
+
+				} else if (s->lzma2.need_props) {
+					return XZ_DATA_ERROR;
+
+				} else {
+					s->lzma2.next_sequence
+							= SEQ_LZMA_PREPARE;
+					if (tmp >= 0xA0)
+						lzma_reset(s);
+				}
+			} else {
+				if (tmp > 0x02)
+					return XZ_DATA_ERROR;
+
+				s->lzma2.sequence = SEQ_COMPRESSED_0;
+				s->lzma2.next_sequence = SEQ_COPY;
+			}
+
+			break;
+
+		case SEQ_UNCOMPRESSED_1:
+			s->lzma2.uncompressed
+					+= (uint32_t)b->in[b->in_pos++] << 8;
+			s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
+			break;
+
+		case SEQ_UNCOMPRESSED_2:
+			s->lzma2.uncompressed
+					+= (uint32_t)b->in[b->in_pos++] + 1;
+			s->lzma2.sequence = SEQ_COMPRESSED_0;
+			break;
+
+		case SEQ_COMPRESSED_0:
+			s->lzma2.compressed
+					= (uint32_t)b->in[b->in_pos++] << 8;
+			s->lzma2.sequence = SEQ_COMPRESSED_1;
+			break;
+
+		case SEQ_COMPRESSED_1:
+			s->lzma2.compressed
+					+= (uint32_t)b->in[b->in_pos++] + 1;
+			s->lzma2.sequence = s->lzma2.next_sequence;
+			break;
+
+		case SEQ_PROPERTIES:
+			if (!lzma_props(s, b->in[b->in_pos++]))
+				return XZ_DATA_ERROR;
+
+			s->lzma2.sequence = SEQ_LZMA_PREPARE;
+
+		/* Fall through */
+
+		case SEQ_LZMA_PREPARE:
+			if (s->lzma2.compressed < RC_INIT_BYTES)
+				return XZ_DATA_ERROR;
+
+			if (!rc_read_init(&s->rc, b))
+				return XZ_OK;
+
+			s->lzma2.compressed -= RC_INIT_BYTES;
+			s->lzma2.sequence = SEQ_LZMA_RUN;
+
+		/* Fall through */
+
+		case SEQ_LZMA_RUN:
+			/*
+			 * Set dictionary limit to indicate how much we want
+			 * to be encoded at maximum. Decode new data into the
+			 * dictionary. Flush the new data from dictionary to
+			 * b->out. Check if we finished decoding this chunk.
+			 * In case the dictionary got full but we didn't fill
+			 * the output buffer yet, we may run this loop
+			 * multiple times without changing s->lzma2.sequence.
+			 */
+			dict_limit(&s->dict, min_t(size_t,
+					b->out_size - b->out_pos,
+					s->lzma2.uncompressed));
+			if (!lzma2_lzma(s, b))
+				return XZ_DATA_ERROR;
+
+			s->lzma2.uncompressed -= dict_flush(&s->dict, b);
+
+			if (s->lzma2.uncompressed == 0) {
+				if (s->lzma2.compressed > 0 || s->lzma.len > 0
+						|| !rc_is_finished(&s->rc))
+					return XZ_DATA_ERROR;
+
+				rc_reset(&s->rc);
+				s->lzma2.sequence = SEQ_CONTROL;
+
+			} else if (b->out_pos == b->out_size
+					|| (b->in_pos == b->in_size
+						&& s->temp.size
+						< s->lzma2.compressed)) {
+				return XZ_OK;
+			}
+
+			break;
+
+		case SEQ_COPY:
+			dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
+			if (s->lzma2.compressed > 0)
+				return XZ_OK;
+
+			s->lzma2.sequence = SEQ_CONTROL;
+			break;
+		}
+	}
+
+	return XZ_OK;
+}
+
+XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
+						   uint32_t dict_max)
+{
+	struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (s == NULL)
+		return NULL;
+
+	s->dict.mode = mode;
+	s->dict.size_max = dict_max;
+
+	if (DEC_IS_PREALLOC(mode)) {
+		s->dict.buf = vmalloc(dict_max);
+		if (s->dict.buf == NULL) {
+			kfree(s);
+			return NULL;
+		}
+	} else if (DEC_IS_DYNALLOC(mode)) {
+		s->dict.buf = NULL;
+		s->dict.allocated = 0;
+	}
+
+	return s;
+}
+
+XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
+{
+	/* This limits dictionary size to 3 GiB to keep parsing simpler. */
+	if (props > 39)
+		return XZ_OPTIONS_ERROR;
+
+	s->dict.size = 2 + (props & 1);
+	s->dict.size <<= (props >> 1) + 11;
+
+	if (DEC_IS_MULTI(s->dict.mode)) {
+		if (s->dict.size > s->dict.size_max)
+			return XZ_MEMLIMIT_ERROR;
+
+		s->dict.end = s->dict.size;
+
+		if (DEC_IS_DYNALLOC(s->dict.mode)) {
+			if (s->dict.allocated < s->dict.size) {
+				vfree(s->dict.buf);
+				s->dict.buf = vmalloc(s->dict.size);
+				if (s->dict.buf == NULL) {
+					s->dict.allocated = 0;
+					return XZ_MEM_ERROR;
+				}
+			}
+		}
+	}
+
+	s->lzma.len = 0;
+
+	s->lzma2.sequence = SEQ_CONTROL;
+	s->lzma2.need_dict_reset = true;
+
+	s->temp.size = 0;
+
+	return XZ_OK;
+}
+
+XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
+{
+	if (DEC_IS_MULTI(s->dict.mode))
+		vfree(s->dict.buf);
+
+	kfree(s);
+}
diff --git a/lib/xz/xz_dec_stream.c b/lib/xz/xz_dec_stream.c
new file mode 100644
index 0000000..ac809b1
--- /dev/null
+++ b/lib/xz/xz_dec_stream.c
@@ -0,0 +1,821 @@
+/*
+ * .xz Stream decoder
+ *
+ * Author: Lasse Collin <lasse.collin at tukaani.org>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#include "xz_private.h"
+#include "xz_stream.h"
+
+/* Hash used to validate the Index field */
+struct xz_dec_hash {
+	vli_type unpadded;
+	vli_type uncompressed;
+	uint32_t crc32;
+};
+
+struct xz_dec {
+	/* Position in dec_main() */
+	enum {
+		SEQ_STREAM_HEADER,
+		SEQ_BLOCK_START,
+		SEQ_BLOCK_HEADER,
+		SEQ_BLOCK_UNCOMPRESS,
+		SEQ_BLOCK_PADDING,
+		SEQ_BLOCK_CHECK,
+		SEQ_INDEX,
+		SEQ_INDEX_PADDING,
+		SEQ_INDEX_CRC32,
+		SEQ_STREAM_FOOTER
+	} sequence;
+
+	/* Position in variable-length integers and Check fields */
+	uint32_t pos;
+
+	/* Variable-length integer decoded by dec_vli() */
+	vli_type vli;
+
+	/* Saved in_pos and out_pos */
+	size_t in_start;
+	size_t out_start;
+
+	/* CRC32 value in Block or Index */
+	uint32_t crc32;
+
+	/* Type of the integrity check calculated from uncompressed data */
+	enum xz_check check_type;
+
+	/* Operation mode */
+	enum xz_mode mode;
+
+	/*
+	 * True if the next call to xz_dec_run() is allowed to return
+	 * XZ_BUF_ERROR.
+	 */
+	bool allow_buf_error;
+
+	/* Information stored in Block Header */
+	struct {
+		/*
+		 * Value stored in the Compressed Size field, or
+		 * VLI_UNKNOWN if Compressed Size is not present.
+		 */
+		vli_type compressed;
+
+		/*
+		 * Value stored in the Uncompressed Size field, or
+		 * VLI_UNKNOWN if Uncompressed Size is not present.
+		 */
+		vli_type uncompressed;
+
+		/* Size of the Block Header field */
+		uint32_t size;
+	} block_header;
+
+	/* Information collected when decoding Blocks */
+	struct {
+		/* Observed compressed size of the current Block */
+		vli_type compressed;
+
+		/* Observed uncompressed size of the current Block */
+		vli_type uncompressed;
+
+		/* Number of Blocks decoded so far */
+		vli_type count;
+
+		/*
+		 * Hash calculated from the Block sizes. This is used to
+		 * validate the Index field.
+		 */
+		struct xz_dec_hash hash;
+	} block;
+
+	/* Variables needed when verifying the Index field */
+	struct {
+		/* Position in dec_index() */
+		enum {
+			SEQ_INDEX_COUNT,
+			SEQ_INDEX_UNPADDED,
+			SEQ_INDEX_UNCOMPRESSED
+		} sequence;
+
+		/* Size of the Index in bytes */
+		vli_type size;
+
+		/* Number of Records (matches block.count in valid files) */
+		vli_type count;
+
+		/*
+		 * Hash calculated from the Records (matches block.hash in
+		 * valid files).
+		 */
+		struct xz_dec_hash hash;
+	} index;
+
+	/*
+	 * Temporary buffer needed to hold Stream Header, Block Header,
+	 * and Stream Footer. The Block Header is the biggest (1 KiB)
+	 * so we reserve space according to that. buf[] has to be aligned
+	 * to a multiple of four bytes; the size_t variables before it
+	 * should guarantee this.
+	 */
+	struct {
+		size_t pos;
+		size_t size;
+		uint8_t buf[1024];
+	} temp;
+
+	struct xz_dec_lzma2 *lzma2;
+
+#ifdef XZ_DEC_BCJ
+	struct xz_dec_bcj *bcj;
+	bool bcj_active;
+#endif
+};
+
+#ifdef XZ_DEC_ANY_CHECK
+/* Sizes of the Check field with different Check IDs */
+static const uint8_t check_sizes[16] = {
+	0,
+	4, 4, 4,
+	8, 8, 8,
+	16, 16, 16,
+	32, 32, 32,
+	64, 64, 64
+};
+#endif
+
+/*
+ * Fill s->temp by copying data starting from b->in[b->in_pos]. Caller
+ * must have set s->temp.pos to indicate how much data we are supposed
+ * to copy into s->temp.buf. Return true once s->temp.pos has reached
+ * s->temp.size.
+ */
+static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
+{
+	size_t copy_size = min_t(size_t,
+			b->in_size - b->in_pos, s->temp.size - s->temp.pos);
+
+	memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
+	b->in_pos += copy_size;
+	s->temp.pos += copy_size;
+
+	if (s->temp.pos == s->temp.size) {
+		s->temp.pos = 0;
+		return true;
+	}
+
+	return false;
+}
+
+/* Decode a variable-length integer (little-endian base-128 encoding) */
+static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in,
+			   size_t *in_pos, size_t in_size)
+{
+	uint8_t byte;
+
+	if (s->pos == 0)
+		s->vli = 0;
+
+	while (*in_pos < in_size) {
+		byte = in[*in_pos];
+		++*in_pos;
+
+		s->vli |= (vli_type)(byte & 0x7F) << s->pos;
+
+		if ((byte & 0x80) == 0) {
+			/* Don't allow non-minimal encodings. */
+			if (byte == 0 && s->pos != 0)
+				return XZ_DATA_ERROR;
+
+			s->pos = 0;
+			return XZ_STREAM_END;
+		}
+
+		s->pos += 7;
+		if (s->pos == 7 * VLI_BYTES_MAX)
+			return XZ_DATA_ERROR;
+	}
+
+	return XZ_OK;
+}
+
+/*
+ * Decode the Compressed Data field from a Block. Update and validate
+ * the observed compressed and uncompressed sizes of the Block so that
+ * they don't exceed the values possibly stored in the Block Header
+ * (validation assumes that no integer overflow occurs, since vli_type
+ * is normally uint64_t). Update the CRC32 if presence of the CRC32
+ * field was indicated in Stream Header.
+ *
+ * Once the decoding is finished, validate that the observed sizes match
+ * the sizes possibly stored in the Block Header. Update the hash and
+ * Block count, which are later used to validate the Index field.
+ */
+static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
+{
+	enum xz_ret ret;
+
+	s->in_start = b->in_pos;
+	s->out_start = b->out_pos;
+
+#ifdef XZ_DEC_BCJ
+	if (s->bcj_active)
+		ret = xz_dec_bcj_run(s->bcj, s->lzma2, b);
+	else
+#endif
+		ret = xz_dec_lzma2_run(s->lzma2, b);
+
+	s->block.compressed += b->in_pos - s->in_start;
+	s->block.uncompressed += b->out_pos - s->out_start;
+
+	/*
+	 * There is no need to separately check for VLI_UNKNOWN, since
+	 * the observed sizes are always smaller than VLI_UNKNOWN.
+	 */
+	if (s->block.compressed > s->block_header.compressed
+			|| s->block.uncompressed
+				> s->block_header.uncompressed)
+		return XZ_DATA_ERROR;
+
+	if (s->check_type == XZ_CHECK_CRC32)
+		s->crc32 = xz_crc32(b->out + s->out_start,
+				b->out_pos - s->out_start, s->crc32);
+
+	if (ret == XZ_STREAM_END) {
+		if (s->block_header.compressed != VLI_UNKNOWN
+				&& s->block_header.compressed
+					!= s->block.compressed)
+			return XZ_DATA_ERROR;
+
+		if (s->block_header.uncompressed != VLI_UNKNOWN
+				&& s->block_header.uncompressed
+					!= s->block.uncompressed)
+			return XZ_DATA_ERROR;
+
+		s->block.hash.unpadded += s->block_header.size
+				+ s->block.compressed;
+
+#ifdef XZ_DEC_ANY_CHECK
+		s->block.hash.unpadded += check_sizes[s->check_type];
+#else
+		if (s->check_type == XZ_CHECK_CRC32)
+			s->block.hash.unpadded += 4;
+#endif
+
+		s->block.hash.uncompressed += s->block.uncompressed;
+		s->block.hash.crc32 = xz_crc32(
+				(const uint8_t *)&s->block.hash,
+				sizeof(s->block.hash), s->block.hash.crc32);
+
+		++s->block.count;
+	}
+
+	return ret;
+}
+
+/* Update the Index size and the CRC32 value. */
+static void index_update(struct xz_dec *s, const struct xz_buf *b)
+{
+	size_t in_used = b->in_pos - s->in_start;
+	s->index.size += in_used;
+	s->crc32 = xz_crc32(b->in + s->in_start, in_used, s->crc32);
+}
+
+/*
+ * Decode the Number of Records, Unpadded Size, and Uncompressed Size
+ * fields from the Index field. That is, Index Padding and CRC32 are not
+ * decoded by this function.
+ *
+ * This can return XZ_OK (more input needed), XZ_STREAM_END (everything
+ * successfully decoded), or XZ_DATA_ERROR (input is corrupt).
+ */
+static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
+{
+	enum xz_ret ret;
+
+	do {
+		ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
+		if (ret != XZ_STREAM_END) {
+			index_update(s, b);
+			return ret;
+		}
+
+		switch (s->index.sequence) {
+		case SEQ_INDEX_COUNT:
+			s->index.count = s->vli;
+
+			/*
+			 * Validate that the Number of Records field
+			 * indicates the same number of Records as
+			 * there were Blocks in the Stream.
+			 */
+			if (s->index.count != s->block.count)
+				return XZ_DATA_ERROR;
+
+			s->index.sequence = SEQ_INDEX_UNPADDED;
+			break;
+
+		case SEQ_INDEX_UNPADDED:
+			s->index.hash.unpadded += s->vli;
+			s->index.sequence = SEQ_INDEX_UNCOMPRESSED;
+			break;
+
+		case SEQ_INDEX_UNCOMPRESSED:
+			s->index.hash.uncompressed += s->vli;
+			s->index.hash.crc32 = xz_crc32(
+					(const uint8_t *)&s->index.hash,
+					sizeof(s->index.hash),
+					s->index.hash.crc32);
+			--s->index.count;
+			s->index.sequence = SEQ_INDEX_UNPADDED;
+			break;
+		}
+	} while (s->index.count > 0);
+
+	return XZ_STREAM_END;
+}
+
+/*
+ * Validate that the next four input bytes match the value of s->crc32.
+ * s->pos must be zero when starting to validate the first byte.
+ */
+static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b)
+{
+	do {
+		if (b->in_pos == b->in_size)
+			return XZ_OK;
+
+		if (((s->crc32 >> s->pos) & 0xFF) != b->in[b->in_pos++])
+			return XZ_DATA_ERROR;
+
+		s->pos += 8;
+
+	} while (s->pos < 32);
+
+	s->crc32 = 0;
+	s->pos = 0;
+
+	return XZ_STREAM_END;
+}
+
+#ifdef XZ_DEC_ANY_CHECK
+/*
+ * Skip over the Check field when the Check ID is not supported.
+ * Returns true once the whole Check field has been skipped over.
+ */
+static bool check_skip(struct xz_dec *s, struct xz_buf *b)
+{
+	while (s->pos < check_sizes[s->check_type]) {
+		if (b->in_pos == b->in_size)
+			return false;
+
+		++b->in_pos;
+		++s->pos;
+	}
+
+	s->pos = 0;
+
+	return true;
+}
+#endif
+
+/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
+static enum xz_ret dec_stream_header(struct xz_dec *s)
+{
+	if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
+		return XZ_FORMAT_ERROR;
+
+	if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
+			!= get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
+		return XZ_DATA_ERROR;
+
+	if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
+		return XZ_OPTIONS_ERROR;
+
+	/*
+	 * Of integrity checks, we support only none (Check ID = 0) and
+	 * CRC32 (Check ID = 1). However, if XZ_DEC_ANY_CHECK is defined,
+	 * we will accept other check types too, but then the check won't
+	 * be verified and a warning (XZ_UNSUPPORTED_CHECK) will be given.
+	 */
+	s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
+
+#ifdef XZ_DEC_ANY_CHECK
+	if (s->check_type > XZ_CHECK_MAX)
+		return XZ_OPTIONS_ERROR;
+
+	if (s->check_type > XZ_CHECK_CRC32)
+		return XZ_UNSUPPORTED_CHECK;
+#else
+	if (s->check_type > XZ_CHECK_CRC32)
+		return XZ_OPTIONS_ERROR;
+#endif
+
+	return XZ_OK;
+}
+
+/* Decode the Stream Footer field (the last 12 bytes of the .xz Stream) */
+static enum xz_ret dec_stream_footer(struct xz_dec *s)
+{
+	if (!memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
+		return XZ_DATA_ERROR;
+
+	if (xz_crc32(s->temp.buf + 4, 6, 0) != get_le32(s->temp.buf))
+		return XZ_DATA_ERROR;
+
+	/*
+	 * Validate Backward Size. Note that we never added the size of the
+	 * Index CRC32 field to s->index.size, thus we use s->index.size / 4
+	 * instead of s->index.size / 4 - 1.
+	 */
+	if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
+		return XZ_DATA_ERROR;
+
+	if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->check_type)
+		return XZ_DATA_ERROR;
+
+	/*
+	 * Use XZ_STREAM_END instead of XZ_OK to be more convenient
+	 * for the caller.
+	 */
+	return XZ_STREAM_END;
+}
+
+/* Decode the Block Header and initialize the filter chain. */
+static enum xz_ret dec_block_header(struct xz_dec *s)
+{
+	enum xz_ret ret;
+
+	/*
+	 * Validate the CRC32. We know that the temp buffer is at least
+	 * eight bytes so this is safe.
+	 */
+	s->temp.size -= 4;
+	if (xz_crc32(s->temp.buf, s->temp.size, 0)
+			!= get_le32(s->temp.buf + s->temp.size))
+		return XZ_DATA_ERROR;
+
+	s->temp.pos = 2;
+
+	/*
+	 * Catch unsupported Block Flags. We support only one or two filters
+	 * in the chain, so we catch that with the same test.
+	 */
+#ifdef XZ_DEC_BCJ
+	if (s->temp.buf[1] & 0x3E)
+#else
+	if (s->temp.buf[1] & 0x3F)
+#endif
+		return XZ_OPTIONS_ERROR;
+
+	/* Compressed Size */
+	if (s->temp.buf[1] & 0x40) {
+		if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
+					!= XZ_STREAM_END)
+			return XZ_DATA_ERROR;
+
+		s->block_header.compressed = s->vli;
+	} else {
+		s->block_header.compressed = VLI_UNKNOWN;
+	}
+
+	/* Uncompressed Size */
+	if (s->temp.buf[1] & 0x80) {
+		if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
+				!= XZ_STREAM_END)
+			return XZ_DATA_ERROR;
+
+		s->block_header.uncompressed = s->vli;
+	} else {
+		s->block_header.uncompressed = VLI_UNKNOWN;
+	}
+
+#ifdef XZ_DEC_BCJ
+	/* If there are two filters, the first one must be a BCJ filter. */
+	s->bcj_active = s->temp.buf[1] & 0x01;
+	if (s->bcj_active) {
+		if (s->temp.size - s->temp.pos < 2)
+			return XZ_OPTIONS_ERROR;
+
+		ret = xz_dec_bcj_reset(s->bcj, s->temp.buf[s->temp.pos++]);
+		if (ret != XZ_OK)
+			return ret;
+
+		/*
+		 * We don't support custom start offset,
+		 * so Size of Properties must be zero.
+		 */
+		if (s->temp.buf[s->temp.pos++] != 0x00)
+			return XZ_OPTIONS_ERROR;
+	}
+#endif
+
+	/* Valid Filter Flags always take at least two bytes. */
+	if (s->temp.size - s->temp.pos < 2)
+		return XZ_DATA_ERROR;
+
+	/* Filter ID = LZMA2 */
+	if (s->temp.buf[s->temp.pos++] != 0x21)
+		return XZ_OPTIONS_ERROR;
+
+	/* Size of Properties = 1-byte Filter Properties */
+	if (s->temp.buf[s->temp.pos++] != 0x01)
+		return XZ_OPTIONS_ERROR;
+
+	/* Filter Properties contains LZMA2 dictionary size. */
+	if (s->temp.size - s->temp.pos < 1)
+		return XZ_DATA_ERROR;
+
+	ret = xz_dec_lzma2_reset(s->lzma2, s->temp.buf[s->temp.pos++]);
+	if (ret != XZ_OK)
+		return ret;
+
+	/* The rest must be Header Padding. */
+	while (s->temp.pos < s->temp.size)
+		if (s->temp.buf[s->temp.pos++] != 0x00)
+			return XZ_OPTIONS_ERROR;
+
+	s->temp.pos = 0;
+	s->block.compressed = 0;
+	s->block.uncompressed = 0;
+
+	return XZ_OK;
+}
+
+static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
+{
+	enum xz_ret ret;
+
+	/*
+	 * Store the start position for the case when we are in the middle
+	 * of the Index field.
+	 */
+	s->in_start = b->in_pos;
+
+	while (true) {
+		switch (s->sequence) {
+		case SEQ_STREAM_HEADER:
+			/*
+			 * Stream Header is copied to s->temp, and then
+			 * decoded from there. This way if the caller
+			 * gives us only little input at a time, we can
+			 * still keep the Stream Header decoding code
+			 * simple. Similar approach is used in many places
+			 * in this file.
+			 */
+			if (!fill_temp(s, b))
+				return XZ_OK;
+
+			/*
+			 * If dec_stream_header() returns
+			 * XZ_UNSUPPORTED_CHECK, it is still possible
+			 * to continue decoding if working in multi-call
+			 * mode. Thus, update s->sequence before calling
+			 * dec_stream_header().
+			 */
+			s->sequence = SEQ_BLOCK_START;
+
+			ret = dec_stream_header(s);
+			if (ret != XZ_OK)
+				return ret;
+
+		case SEQ_BLOCK_START:
+			/* We need one byte of input to continue. */
+			if (b->in_pos == b->in_size)
+				return XZ_OK;
+
+			/* See if this is the beginning of the Index field. */
+			if (b->in[b->in_pos] == 0) {
+				s->in_start = b->in_pos++;
+				s->sequence = SEQ_INDEX;
+				break;
+			}
+
+			/*
+			 * Calculate the size of the Block Header and
+			 * prepare to decode it.
+			 */
+			s->block_header.size
+				= ((uint32_t)b->in[b->in_pos] + 1) * 4;
+
+			s->temp.size = s->block_header.size;
+			s->temp.pos = 0;
+			s->sequence = SEQ_BLOCK_HEADER;
+
+		case SEQ_BLOCK_HEADER:
+			if (!fill_temp(s, b))
+				return XZ_OK;
+
+			ret = dec_block_header(s);
+			if (ret != XZ_OK)
+				return ret;
+
+			s->sequence = SEQ_BLOCK_UNCOMPRESS;
+
+		case SEQ_BLOCK_UNCOMPRESS:
+			ret = dec_block(s, b);
+			if (ret != XZ_STREAM_END)
+				return ret;
+
+			s->sequence = SEQ_BLOCK_PADDING;
+
+		case SEQ_BLOCK_PADDING:
+			/*
+			 * Size of Compressed Data + Block Padding
+			 * must be a multiple of four. We don't need
+			 * s->block.compressed for anything else
+			 * anymore, so we use it here to test the size
+			 * of the Block Padding field.
+			 */
+			while (s->block.compressed & 3) {
+				if (b->in_pos == b->in_size)
+					return XZ_OK;
+
+				if (b->in[b->in_pos++] != 0)
+					return XZ_DATA_ERROR;
+
+				++s->block.compressed;
+			}
+
+			s->sequence = SEQ_BLOCK_CHECK;
+
+		case SEQ_BLOCK_CHECK:
+			if (s->check_type == XZ_CHECK_CRC32) {
+				ret = crc32_validate(s, b);
+				if (ret != XZ_STREAM_END)
+					return ret;
+			}
+#ifdef XZ_DEC_ANY_CHECK
+			else if (!check_skip(s, b)) {
+				return XZ_OK;
+			}
+#endif
+
+			s->sequence = SEQ_BLOCK_START;
+			break;
+
+		case SEQ_INDEX:
+			ret = dec_index(s, b);
+			if (ret != XZ_STREAM_END)
+				return ret;
+
+			s->sequence = SEQ_INDEX_PADDING;
+
+		case SEQ_INDEX_PADDING:
+			while ((s->index.size + (b->in_pos - s->in_start))
+					& 3) {
+				if (b->in_pos == b->in_size) {
+					index_update(s, b);
+					return XZ_OK;
+				}
+
+				if (b->in[b->in_pos++] != 0)
+					return XZ_DATA_ERROR;
+			}
+
+			/* Finish the CRC32 value and Index size. */
+			index_update(s, b);
+
+			/* Compare the hashes to validate the Index field. */
+			if (!memeq(&s->block.hash, &s->index.hash,
+					sizeof(s->block.hash)))
+				return XZ_DATA_ERROR;
+
+			s->sequence = SEQ_INDEX_CRC32;
+
+		case SEQ_INDEX_CRC32:
+			ret = crc32_validate(s, b);
+			if (ret != XZ_STREAM_END)
+				return ret;
+
+			s->temp.size = STREAM_HEADER_SIZE;
+			s->sequence = SEQ_STREAM_FOOTER;
+
+		case SEQ_STREAM_FOOTER:
+			if (!fill_temp(s, b))
+				return XZ_OK;
+
+			return dec_stream_footer(s);
+		}
+	}
+
+	/* Never reached */
+}
+
+/*
+ * xz_dec_run() is a wrapper for dec_main() to handle some special cases in
+ * multi-call and single-call decoding.
+ *
+ * In multi-call mode, we must return XZ_BUF_ERROR when it seems clear that we
+ * are not going to make any progress anymore. This is to prevent the caller
+ * from calling us infinitely when the input file is truncated or otherwise
+ * corrupt. Since zlib-style API allows that the caller fills the input buffer
+ * only when the decoder doesn't produce any new output, we have to be careful
+ * to avoid returning XZ_BUF_ERROR too easily: XZ_BUF_ERROR is returned only
+ * after the second consecutive call to xz_dec_run() that makes no progress.
+ *
+ * In single-call mode, if we couldn't decode everything and no error
+ * occurred, either the input is truncated or the output buffer is too small.
+ * Since we know that the last input byte never produces any output, we know
+ * that if all the input was consumed and decoding wasn't finished, the file
+ * must be corrupt. Otherwise the output buffer has to be too small or the
+ * file is corrupt in a way that decoding it produces too big output.
+ *
+ * If single-call decoding fails, we reset b->in_pos and b->out_pos back to
+ * their original values. This is because with some filter chains there won't
+ * be any valid uncompressed data in the output buffer unless the decoding
+ * actually succeeds (that's the price to pay of using the output buffer as
+ * the workspace).
+ */
+XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
+{
+	size_t in_start;
+	size_t out_start;
+	enum xz_ret ret;
+
+	if (DEC_IS_SINGLE(s->mode))
+		xz_dec_reset(s);
+
+	in_start = b->in_pos;
+	out_start = b->out_pos;
+	ret = dec_main(s, b);
+
+	if (DEC_IS_SINGLE(s->mode)) {
+		if (ret == XZ_OK)
+			ret = b->in_pos == b->in_size
+					? XZ_DATA_ERROR : XZ_BUF_ERROR;
+
+		if (ret != XZ_STREAM_END) {
+			b->in_pos = in_start;
+			b->out_pos = out_start;
+		}
+
+	} else if (ret == XZ_OK && in_start == b->in_pos
+			&& out_start == b->out_pos) {
+		if (s->allow_buf_error)
+			ret = XZ_BUF_ERROR;
+
+		s->allow_buf_error = true;
+	} else {
+		s->allow_buf_error = false;
+	}
+
+	return ret;
+}
+
+XZ_EXTERN struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max)
+{
+	struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (s == NULL)
+		return NULL;
+
+	s->mode = mode;
+
+#ifdef XZ_DEC_BCJ
+	s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode));
+	if (s->bcj == NULL)
+		goto error_bcj;
+#endif
+
+	s->lzma2 = xz_dec_lzma2_create(mode, dict_max);
+	if (s->lzma2 == NULL)
+		goto error_lzma2;
+
+	xz_dec_reset(s);
+	return s;
+
+error_lzma2:
+#ifdef XZ_DEC_BCJ
+	xz_dec_bcj_end(s->bcj);
+error_bcj:
+#endif
+	kfree(s);
+	return NULL;
+}
+
+XZ_EXTERN void xz_dec_reset(struct xz_dec *s)
+{
+	s->sequence = SEQ_STREAM_HEADER;
+	s->allow_buf_error = false;
+	s->pos = 0;
+	s->crc32 = 0;
+	memzero(&s->block, sizeof(s->block));
+	memzero(&s->index, sizeof(s->index));
+	s->temp.pos = 0;
+	s->temp.size = STREAM_HEADER_SIZE;
+}
+
+XZ_EXTERN void xz_dec_end(struct xz_dec *s)
+{
+	if (s != NULL) {
+		xz_dec_lzma2_end(s->lzma2);
+#ifdef XZ_DEC_BCJ
+		xz_dec_bcj_end(s->bcj);
+#endif
+		kfree(s);
+	}
+}
diff --git a/lib/xz/xz_lzma2.h b/lib/xz/xz_lzma2.h
new file mode 100644
index 0000000..071d67b
--- /dev/null
+++ b/lib/xz/xz_lzma2.h
@@ -0,0 +1,204 @@
+/*
+ * LZMA2 definitions
+ *
+ * Authors: Lasse Collin <lasse.collin at tukaani.org>
+ *          Igor Pavlov <http://7-zip.org/>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#ifndef XZ_LZMA2_H
+#define XZ_LZMA2_H
+
+/* Range coder constants */
+#define RC_SHIFT_BITS 8
+#define RC_TOP_BITS 24
+#define RC_TOP_VALUE (1 << RC_TOP_BITS)
+#define RC_BIT_MODEL_TOTAL_BITS 11
+#define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS)
+#define RC_MOVE_BITS 5
+
+/*
+ * Maximum number of position states. A position state is the lowest pb
+ * number of bits of the current uncompressed offset. In some places there
+ * are different sets of probabilities for different position states.
+ */
+#define POS_STATES_MAX (1 << 4)
+
+/*
+ * This enum is used to track which LZMA symbols have occurred most recently
+ * and in which order. This information is used to predict the next symbol.
+ *
+ * Symbols:
+ *  - Literal: One 8-bit byte
+ *  - Match: Repeat a chunk of data at some distance
+ *  - Long repeat: Multi-byte match at a recently seen distance
+ *  - Short repeat: One-byte repeat at a recently seen distance
+ *
+ * The symbol names are in from STATE_oldest_older_previous. REP means
+ * either short or long repeated match, and NONLIT means any non-literal.
+ */
+enum lzma_state {
+	STATE_LIT_LIT,
+	STATE_MATCH_LIT_LIT,
+	STATE_REP_LIT_LIT,
+	STATE_SHORTREP_LIT_LIT,
+	STATE_MATCH_LIT,
+	STATE_REP_LIT,
+	STATE_SHORTREP_LIT,
+	STATE_LIT_MATCH,
+	STATE_LIT_LONGREP,
+	STATE_LIT_SHORTREP,
+	STATE_NONLIT_MATCH,
+	STATE_NONLIT_REP
+};
+
+/* Total number of states */
+#define STATES 12
+
+/* The lowest 7 states indicate that the previous state was a literal. */
+#define LIT_STATES 7
+
+/* Indicate that the latest symbol was a literal. */
+static inline void lzma_state_literal(enum lzma_state *state)
+{
+	if (*state <= STATE_SHORTREP_LIT_LIT)
+		*state = STATE_LIT_LIT;
+	else if (*state <= STATE_LIT_SHORTREP)
+		*state -= 3;
+	else
+		*state -= 6;
+}
+
+/* Indicate that the latest symbol was a match. */
+static inline void lzma_state_match(enum lzma_state *state)
+{
+	*state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH;
+}
+
+/* Indicate that the latest state was a long repeated match. */
+static inline void lzma_state_long_rep(enum lzma_state *state)
+{
+	*state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP;
+}
+
+/* Indicate that the latest symbol was a short match. */
+static inline void lzma_state_short_rep(enum lzma_state *state)
+{
+	*state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP;
+}
+
+/* Test if the previous symbol was a literal. */
+static inline bool lzma_state_is_literal(enum lzma_state state)
+{
+	return state < LIT_STATES;
+}
+
+/* Each literal coder is divided in three sections:
+ *   - 0x001-0x0FF: Without match byte
+ *   - 0x101-0x1FF: With match byte; match bit is 0
+ *   - 0x201-0x2FF: With match byte; match bit is 1
+ *
+ * Match byte is used when the previous LZMA symbol was something else than
+ * a literal (that is, it was some kind of match).
+ */
+#define LITERAL_CODER_SIZE 0x300
+
+/* Maximum number of literal coders */
+#define LITERAL_CODERS_MAX (1 << 4)
+
+/* Minimum length of a match is two bytes. */
+#define MATCH_LEN_MIN 2
+
+/* Match length is encoded with 4, 5, or 10 bits.
+ *
+ * Length   Bits
+ *  2-9      4 = Choice=0 + 3 bits
+ * 10-17     5 = Choice=1 + Choice2=0 + 3 bits
+ * 18-273   10 = Choice=1 + Choice2=1 + 8 bits
+ */
+#define LEN_LOW_BITS 3
+#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
+#define LEN_MID_BITS 3
+#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
+#define LEN_HIGH_BITS 8
+#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
+#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
+
+/*
+ * Maximum length of a match is 273 which is a result of the encoding
+ * described above.
+ */
+#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
+
+/*
+ * Different sets of probabilities are used for match distances that have
+ * very short match length: Lengths of 2, 3, and 4 bytes have a separate
+ * set of probabilities for each length. The matches with longer length
+ * use a shared set of probabilities.
+ */
+#define DIST_STATES 4
+
+/*
+ * Get the index of the appropriate probability array for decoding
+ * the distance slot.
+ */
+static inline uint32_t lzma_get_dist_state(uint32_t len)
+{
+	return len < DIST_STATES + MATCH_LEN_MIN
+			? len - MATCH_LEN_MIN : DIST_STATES - 1;
+}
+
+/*
+ * The highest two bits of a 32-bit match distance are encoded using six bits.
+ * This six-bit value is called a distance slot. This way encoding a 32-bit
+ * value takes 6-36 bits, larger values taking more bits.
+ */
+#define DIST_SLOT_BITS 6
+#define DIST_SLOTS (1 << DIST_SLOT_BITS)
+
+/* Match distances up to 127 are fully encoded using probabilities. Since
+ * the highest two bits (distance slot) are always encoded using six bits,
+ * the distances 0-3 don't need any additional bits to encode, since the
+ * distance slot itself is the same as the actual distance. DIST_MODEL_START
+ * indicates the first distance slot where at least one additional bit is
+ * needed.
+ */
+#define DIST_MODEL_START 4
+
+/*
+ * Match distances greater than 127 are encoded in three pieces:
+ *   - distance slot: the highest two bits
+ *   - direct bits: 2-26 bits below the highest two bits
+ *   - alignment bits: four lowest bits
+ *
+ * Direct bits don't use any probabilities.
+ *
+ * The distance slot value of 14 is for distances 128-191.
+ */
+#define DIST_MODEL_END 14
+
+/* Distance slots that indicate a distance <= 127. */
+#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)
+#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
+
+/*
+ * For match distances greater than 127, only the highest two bits and the
+ * lowest four bits (alignment) is encoded using probabilities.
+ */
+#define ALIGN_BITS 4
+#define ALIGN_SIZE (1 << ALIGN_BITS)
+#define ALIGN_MASK (ALIGN_SIZE - 1)
+
+/* Total number of all probability variables */
+#define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE)
+
+/*
+ * LZMA remembers the four most recent match distances. Reusing these
+ * distances tends to take less space than re-encoding the actual
+ * distance value.
+ */
+#define REPS 4
+
+#endif
diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h
new file mode 100644
index 0000000..99b8ade
--- /dev/null
+++ b/lib/xz/xz_private.h
@@ -0,0 +1,156 @@
+/*
+ * Private includes and definitions
+ *
+ * Author: Lasse Collin <lasse.collin at tukaani.org>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#ifndef XZ_PRIVATE_H
+#define XZ_PRIVATE_H
+
+#ifdef __KERNEL__
+#	include <linux/xz.h>
+#	include <linux/kernel.h>
+#	include <asm/unaligned.h>
+	/* XZ_PREBOOT may be defined only via decompress_unxz.c. */
+#	ifndef XZ_PREBOOT
+#		include <string.h>
+#		include <malloc.h>
+#		include <asm/byteorder.h>
+#		ifdef CONFIG_XZ_DEC_X86
+#			define XZ_DEC_X86
+#		endif
+#		ifdef CONFIG_XZ_DEC_POWERPC
+#			define XZ_DEC_POWERPC
+#		endif
+#		ifdef CONFIG_XZ_DEC_IA64
+#			define XZ_DEC_IA64
+#		endif
+#		ifdef CONFIG_XZ_DEC_ARM
+#			define XZ_DEC_ARM
+#		endif
+#		ifdef CONFIG_XZ_DEC_ARMTHUMB
+#			define XZ_DEC_ARMTHUMB
+#		endif
+#		ifdef CONFIG_XZ_DEC_SPARC
+#			define XZ_DEC_SPARC
+#		endif
+#		define memeq(a, b, size) (memcmp(a, b, size) == 0)
+#		define memzero(buf, size) memset(buf, 0, size)
+#	endif
+#	define get_le32(p) le32_to_cpup((const uint32_t *)(p))
+#else
+	/*
+	 * For userspace builds, use a separate header to define the required
+	 * macros and functions. This makes it easier to adapt the code into
+	 * different environments and avoids clutter in the Linux kernel tree.
+	 */
+#	include "xz_config.h"
+#endif
+
+/* If no specific decoding mode is requested, enable support for all modes. */
+#if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \
+		&& !defined(XZ_DEC_DYNALLOC)
+#	define XZ_DEC_SINGLE
+#	define XZ_DEC_PREALLOC
+#	define XZ_DEC_DYNALLOC
+#endif
+
+/*
+ * The DEC_IS_foo(mode) macros are used in "if" statements. If only some
+ * of the supported modes are enabled, these macros will evaluate to true or
+ * false at compile time and thus allow the compiler to omit unneeded code.
+ */
+#ifdef XZ_DEC_SINGLE
+#	define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE)
+#else
+#	define DEC_IS_SINGLE(mode) (false)
+#endif
+
+#ifdef XZ_DEC_PREALLOC
+#	define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC)
+#else
+#	define DEC_IS_PREALLOC(mode) (false)
+#endif
+
+#ifdef XZ_DEC_DYNALLOC
+#	define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC)
+#else
+#	define DEC_IS_DYNALLOC(mode) (false)
+#endif
+
+#if !defined(XZ_DEC_SINGLE)
+#	define DEC_IS_MULTI(mode) (true)
+#elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC)
+#	define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE)
+#else
+#	define DEC_IS_MULTI(mode) (false)
+#endif
+
+/*
+ * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ.
+ * XZ_DEC_BCJ is used to enable generic support for BCJ decoders.
+ */
+#ifndef XZ_DEC_BCJ
+#	if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
+			|| defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
+			|| defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
+			|| defined(XZ_DEC_SPARC)
+#		define XZ_DEC_BCJ
+#	endif
+#endif
+
+/*
+ * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
+ * before calling xz_dec_lzma2_run().
+ */
+XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
+						   uint32_t dict_max);
+
+/*
+ * Decode the LZMA2 properties (one byte) and reset the decoder. Return
+ * XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not
+ * big enough, and XZ_OPTIONS_ERROR if props indicates something that this
+ * decoder doesn't support.
+ */
+XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s,
+					 uint8_t props);
+
+/* Decode raw LZMA2 stream from b->in to b->out. */
+XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
+				       struct xz_buf *b);
+
+/* Free the memory allocated for the LZMA2 decoder. */
+XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s);
+
+#ifdef XZ_DEC_BCJ
+/*
+ * Allocate memory for BCJ decoders. xz_dec_bcj_reset() must be used before
+ * calling xz_dec_bcj_run().
+ */
+XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call);
+
+/*
+ * Decode the Filter ID of a BCJ filter. This implementation doesn't
+ * support custom start offsets, so no decoding of Filter Properties
+ * is needed. Returns XZ_OK if the given Filter ID is supported.
+ * Otherwise XZ_OPTIONS_ERROR is returned.
+ */
+XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id);
+
+/*
+ * Decode raw BCJ + LZMA2 stream. This must be used only if there actually is
+ * a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
+ * must be called directly.
+ */
+XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
+				     struct xz_dec_lzma2 *lzma2,
+				     struct xz_buf *b);
+
+/* Free the memory allocated for the BCJ filters. */
+#define xz_dec_bcj_end(s) kfree(s)
+#endif
+
+#endif
diff --git a/lib/xz/xz_stream.h b/lib/xz/xz_stream.h
new file mode 100644
index 0000000..4b333e3
--- /dev/null
+++ b/lib/xz/xz_stream.h
@@ -0,0 +1,61 @@
+/*
+ * Definitions for handling the .xz file format
+ *
+ * Author: Lasse Collin <lasse.collin at tukaani.org>
+ *
+ * This file has been put into the public domain.
+ * You can do whatever you want with this file.
+ */
+
+#ifndef XZ_STREAM_H
+#define XZ_STREAM_H
+
+#if defined(__KERNEL__) && !XZ_INTERNAL_CRC32
+#	undef crc32
+#	define xz_crc32(buf, size, crc) \
+		(~crc32_le(~(uint32_t)(crc), buf, size))
+#endif
+
+/*
+ * See the .xz file format specification at
+ * http://tukaani.org/xz/xz-file-format.txt
+ * to understand the container format.
+ */
+
+#define STREAM_HEADER_SIZE 12
+
+#define HEADER_MAGIC "\3757zXZ"
+#define HEADER_MAGIC_SIZE 6
+
+#define FOOTER_MAGIC "YZ"
+#define FOOTER_MAGIC_SIZE 2
+
+/*
+ * Variable-length integer can hold a 63-bit unsigned integer or a special
+ * value indicating that the value is unknown.
+ *
+ * Experimental: vli_type can be defined to uint32_t to save a few bytes
+ * in code size (no effect on speed). Doing so limits the uncompressed and
+ * compressed size of the file to less than 256 MiB and may also weaken
+ * error detection slightly.
+ */
+typedef uint64_t vli_type;
+
+#define VLI_MAX ((vli_type)-1 / 2)
+#define VLI_UNKNOWN ((vli_type)-1)
+
+/* Maximum encoded size of a VLI */
+#define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7)
+
+/* Integrity Check types */
+enum xz_check {
+	XZ_CHECK_NONE = 0,
+	XZ_CHECK_CRC32 = 1,
+	XZ_CHECK_CRC64 = 4,
+	XZ_CHECK_SHA256 = 10
+};
+
+/* Maximum possible Check ID */
+#define XZ_CHECK_MAX 15
+
+#endif
diff --git a/pbl/Kconfig b/pbl/Kconfig
index dc31357..117b79d 100644
--- a/pbl/Kconfig
+++ b/pbl/Kconfig
@@ -64,6 +64,9 @@ config IMAGE_COMPRESSION_LZO
 config IMAGE_COMPRESSION_GZIP
 	bool "gzip"
 
+config IMAGE_COMPRESSION_XZKERN
+	bool "xz"
+
 config IMAGE_COMPRESSION_NONE
 	bool "none"
 
diff --git a/pbl/decomp.c b/pbl/decomp.c
index ca0df64..c8014c4 100644
--- a/pbl/decomp.c
+++ b/pbl/decomp.c
@@ -22,6 +22,10 @@
 #include "../../../lib/decompress_inflate.c"
 #endif
 
+#ifdef CONFIG_IMAGE_COMPRESSION_XZKERN
+#include "../../../lib/decompress_unxz.c"
+#endif
+
 #ifdef CONFIG_IMAGE_COMPRESSION_NONE
 STATIC int decompress(u8 *input, int in_len,
 				int (*fill) (void *, unsigned int),
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 05387b2..934ee07 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -205,6 +205,37 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
 %.gz: %
 	$(call if_changed,gzip)
 
+# XZ
+# ---------------------------------------------------------------------------
+# Use xzkern to compress the kernel image and xzmisc to compress other things.
+#
+# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage
+# of the kernel decompressor. A BCJ filter is used if it is available for
+# the target architecture. xzkern also appends uncompressed size of the data
+# using size_append. The .xz format has the size information available at
+# the end of the file too, but it's in more complex format and it's good to
+# avoid changing the part of the boot code that reads the uncompressed size.
+# Note that the bytes added by size_append will make the xz tool think that
+# the file is corrupt. This is expected.
+#
+# xzmisc doesn't use size_append, so it can be used to create normal .xz
+# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very
+# big dictionary would increase the memory usage too much in the multi-call
+# decompression mode. A BCJ filter isn't used either.
+quiet_cmd_xzkern = XZKERN  $@
+cmd_xzkern = (cat $(filter-out FORCE,$^) | \
+	sh $(srctree)/scripts/xz_wrap.sh && \
+	$(call size_append, $(filter-out FORCE,$^))) > $@ || \
+	(rm -f $@ ; false)
+
+quiet_cmd_xzmisc = XZMISC  $@
+cmd_xzmisc = (cat $(filter-out FORCE,$^) | \
+	xz --check=crc32 --lzma2=dict=1MiB) > $@ || \
+	(rm -f $@ ; false)
+
+%.xzkern: %
+	$(call if_changed,xzkern)
+
 # DTC
 # ---------------------------------------------------------------------------
 
-- 
2.1.1



From jbe at pengutronix.de  Fri Oct 24 00:50:21 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Fri, 24 Oct 2014 09:50:21 +0200
Subject: [PATCH 2/3] mxs: iomux-imx23/imx28: unify mode definition
In-Reply-To: <1414104361-15956-3-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1414104361-15956-3-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <201410240950.21973.jbe@pengutronix.de>

Hi Uwe,

On Friday 24 October 2014 00:46:00 Uwe Kleine-K?nig wrote:
> [...]
>  #if defined CONFIG_ARCH_IMX23
> +/*
> + * The pin definition of i.MX23 are strange. Bank 0's pins 0 .. 15 are defined
> + * using PORTF(0, 0) .. PORTF(0, 15). Its pins 16 .. 31 however use PORTF(1, 0)
> + * .. PORTF(1, 15). So the PORTF macro is more ugly than necessary.
> + */ 
> +# define PORTF(bank,bit)	(BANK((bank) / 2) | BANKPIN((((bank) & 1) << 4) | (bit)) | ERROR((bit) & ~15) | ERROR((bank) & ~7)
> +# define VE_2_5V		VOLTAGE(1)
>  # include <mach/iomux-imx23.h>
>  #endif
> +

Looks more like a strange implementation by myself. Did not remember why I have
done it in this way...

jbe

-- 
Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Borleis ? ? ? ? ? ? |
Industrial Linux Solutions               ? ? ?| http://www.pengutronix.de/  |


From jbe at pengutronix.de  Fri Oct 24 00:52:09 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Fri, 24 Oct 2014 09:52:09 +0200
Subject: [PATCH 0/3] fixes and sanity checks for mxs pinmuxing
In-Reply-To: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <201410240952.09412.jbe@pengutronix.de>

On Friday 24 October 2014 00:45:58 Uwe Kleine-K?nig wrote:
> this series helped me to find pinmuxing problems on an i.MX28 machine.
>
> The pins either have a pull up, a bit keeper or neither. For example the
> pin ENET0_RXD2 has a bit keeper, and so doing
>
> 	imx_gpio_mode(ENET0_RXD2 | VE_3_3V | STRENGTH(S8MA) | PULLUP(1))
>
> obviously couldn't enable the pull up as requested. Instead it enabled the
> bit keeper. With this series the above call results in a message that the
> mode is invalid and the pullup and bitkeeper register settings are not
> touched.
>
> Note that I didn't test on i.MX23 even though this SoC is affected, too. I
> currently don't have an i.MX23 handy, so I couldn't test this part.

Nice change set.

Acked-by: Juergen Borleis <jbe at pengutronix.de>

jbe

-- 
Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Borleis ? ? ? ? ? ? |
Industrial Linux Solutions               ? ? ?| http://www.pengutronix.de/  |


From u.kleine-koenig at pengutronix.de  Fri Oct 24 01:19:49 2014
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Fri, 24 Oct 2014 10:19:49 +0200
Subject: [PATCH 2/3] mxs: iomux-imx23/imx28: unify mode definition
In-Reply-To: <201410240950.21973.jbe@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <1414104361-15956-3-git-send-email-u.kleine-koenig@pengutronix.de>
 <201410240950.21973.jbe@pengutronix.de>
Message-ID: <20141024081949.GO8316@pengutronix.de>

Hello J?rgen,

when going to bed yesterday^Wearlier today I remembered that I wantet do
Cc: you for this series. Great you noticed it anyhow :-)

On Fri, Oct 24, 2014 at 09:50:21AM +0200, Juergen Borleis wrote:
> Hi Uwe,
> 
> On Friday 24 October 2014 00:46:00 Uwe Kleine-K?nig wrote:
> > [...]
> >  #if defined CONFIG_ARCH_IMX23
> > +/*
> > + * The pin definition of i.MX23 are strange. Bank 0's pins 0 .. 15 are defined
> > + * using PORTF(0, 0) .. PORTF(0, 15). Its pins 16 .. 31 however use PORTF(1, 0)
> > + * .. PORTF(1, 15). So the PORTF macro is more ugly than necessary.
> > + */ 
> > +# define PORTF(bank,bit)	(BANK((bank) / 2) | BANKPIN((((bank) & 1) << 4) | (bit)) | ERROR((bit) & ~15) | ERROR((bank) & ~7)
> > +# define VE_2_5V		VOLTAGE(1)
> >  # include <mach/iomux-imx23.h>
> >  #endif
> > +
> 
> Looks more like a strange implementation by myself. Did not remember why I have
> done it in this way...
When Sascha is happy with the changes in this series we can clean that
up.

You didn't test that on an i.MX23 machine, do you?

Best regards
Uwe

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


From jbe at pengutronix.de  Fri Oct 24 01:47:17 2014
From: jbe at pengutronix.de (Juergen Borleis)
Date: Fri, 24 Oct 2014 10:47:17 +0200
Subject: [PATCH 2/3] mxs: iomux-imx23/imx28: unify mode definition
In-Reply-To: <20141024081949.GO8316@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <201410240950.21973.jbe@pengutronix.de>
 <20141024081949.GO8316@pengutronix.de>
Message-ID: <201410241047.17687.jbe@pengutronix.de>

Hi Uwe,

On Friday 24 October 2014 10:19:49 Uwe Kleine-K?nig wrote:
> [...]
> >
> > Looks more like a strange implementation by myself. Did not remember why
> > I have done it in this way...
>
> When Sascha is happy with the changes in this series we can clean that
> up.
>
> You didn't test that on an i.MX23 machine, do you?

Not yet. I could test it on our i.MX23 based Chumby (when I will have the time 
to do so...)

jbe

-- 
Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Juergen Borleis ? ? ? ? ? ? |
Industrial Linux Solutions               ? ? ?| http://www.pengutronix.de/  |


From s.hauer at pengutronix.de  Sun Oct 26 22:14:53 2014
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 27 Oct 2014 06:14:53 +0100
Subject: [PATCH 0/3] fixes and sanity checks for mxs pinmuxing
In-Reply-To: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1414104361-15956-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <20141027051453.GV14443@pengutronix.de>

On Fri, Oct 24, 2014 at 12:45:58AM +0200, Uwe Kleine-K?nig wrote:
> Hello,
> 
> this series helped me to find pinmuxing problems on an i.MX28 machine.
> 
> The pins either have a pull up, a bit keeper or neither. For example the pin
> ENET0_RXD2 has a bit keeper, and so doing
> 
> 	imx_gpio_mode(ENET0_RXD2 | VE_3_3V | STRENGTH(S8MA) | PULLUP(1))
> 
> obviously couldn't enable the pull up as requested. Instead it enabled the bit
> keeper. With this series the above call results in a message that the mode is
> invalid and the pullup and bitkeeper register settings are not touched.
> 
> Note that I didn't test on i.MX23 even though this SoC is affected, too. I
> currently don't have an i.MX23 handy, so I couldn't test this part.
> 
> Uwe Kleine-K?nig (3):
>   mxs: iomux-imx28: Fix keeper/pullup/drive strength/voltage flags
>   mxs: iomux-imx23/imx28: unify mode definition
>   mxs: iomux-imx23/imx28: add additional checks on mode

Applied, thanks

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 w.egorov at phytec.de  Tue Oct 28 03:50:36 2014
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 28 Oct 2014 11:50:36 +0100
Subject: [PATCH 2/2] net: cpsw: Set phy device_node pointer in probe
In-Reply-To: <1414493436-23693-1-git-send-email-w.egorov@phytec.de>
References: <1414493436-23693-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1414493436-23693-2-git-send-email-w.egorov@phytec.de>

Set the phy device_node pointer to the equivalent cpsw slave node.
We need this, because phy drivers using this pointer for their configuration.

Create and register the phy device in cpsw_probe(), so that this phy device
can be found later by phy_device_connect() in cpsw_open().

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 drivers/net/cpsw.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 167b2dd..a0621f5 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -1200,6 +1200,19 @@ int cpsw_probe(struct device_d *dev)
 	mdiobus_register(&priv->miibus);
 
 	for (i = 0; i < priv->num_slaves; i++) {
+		struct phy_device *phy;
+
+		phy = mdiobus_scan(&priv->miibus, priv->slaves[i].phy_id);
+		if (IS_ERR(phy)) {
+			ret = PTR_ERR(phy);
+			goto out;
+		}
+
+		phy->dev.device_node = priv->slaves[i].dev.device_node;
+		ret = phy_register_device(phy);
+		if (ret)
+			goto out;
+
 		ret = cpsw_slave_setup(&priv->slaves[i], i, priv);
 		if (ret)
 			goto out;
-- 
1.7.0.4



From w.egorov at phytec.de  Tue Oct 28 03:50:35 2014
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 28 Oct 2014 11:50:35 +0100
Subject: [PATCH 1/2] net: phy: micrel: Add OF conf. support for ksz9031
Message-ID: <1414493436-23693-1-git-send-email-w.egorov@phytec.de>

Adds support for ksz9031 PAD skew configuration over devicetree.
Based on a patch from the linux kernel.

Author: Hubert Chaumette <hchaumette at adeneo-embedded.com>
Original commit: 6e4b82730c7525504fc485b370c7f09e594e2e96

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 drivers/net/phy/micrel.c |   86 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 85 insertions(+), 1 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 88c64e5..c9558da 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -146,6 +146,90 @@ static int ksz9021_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+#define KSZ9031_PS_TO_REG		60
+
+/* Extended registers */
+#define MII_KSZ9031RN_CONTROL_PAD_SKEW	4
+#define MII_KSZ9031RN_RX_DATA_PAD_SKEW	5
+#define MII_KSZ9031RN_TX_DATA_PAD_SKEW	6
+#define MII_KSZ9031RN_CLK_PAD_SKEW	8
+
+static int ksz9031_of_load_skew_values(struct phy_device *phydev,
+					struct device_node *of_node,
+					u16 reg, size_t field_sz,
+					char *field[], u8 numfields)
+{
+	int val[4] = {-1, -2, -3, -4};
+	int matches = 0;
+	u16 mask;
+	u16 maxval;
+	u16 newval;
+	int i;
+
+	for (i = 0; i < numfields; i++)
+		if (!of_property_read_u32(of_node, field[i], val + i))
+			matches++;
+
+	if (!matches)
+		return 0;
+
+	if (matches < numfields)
+		newval = phy_read_mmd_indirect(phydev, reg, 2);
+	else
+		newval = 0;
+
+	maxval = (field_sz == 4) ? 0xf : 0x1f;
+	for (i = 0; i < numfields; i++)
+		if (val[i] != -(i + 1)) {
+			mask = 0xffff;
+			mask ^= maxval << (field_sz * i);
+			newval = (newval & mask) |
+				(((val[i] / KSZ9031_PS_TO_REG) & maxval)
+				<< (field_sz * i));
+		}
+
+	phy_write_mmd_indirect(phydev, reg, 2, newval);
+	return 0;
+}
+
+static int ksz9031_config_init(struct phy_device *phydev)
+{
+	struct device_d *dev = &phydev->dev;
+	struct device_node *of_node = dev->device_node;
+	char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
+	char *rx_data_skews[4] = {
+		"rxd0-skew-ps", "rxd1-skew-ps",
+		"rxd2-skew-ps", "rxd3-skew-ps"
+	};
+	char *tx_data_skews[4] = {
+		"txd0-skew-ps", "txd1-skew-ps",
+		"txd2-skew-ps", "txd3-skew-ps"
+	};
+	char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
+
+	if (!of_node && dev->parent->device_node)
+		of_node = dev->parent->device_node;
+
+	if (of_node) {
+		ksz9031_of_load_skew_values(phydev, of_node,
+				MII_KSZ9031RN_CLK_PAD_SKEW, 5,
+				clk_skews, 2);
+
+		ksz9031_of_load_skew_values(phydev, of_node,
+				MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
+				control_skews, 2);
+
+		ksz9031_of_load_skew_values(phydev, of_node,
+				MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
+				rx_data_skews, 4);
+
+		ksz9031_of_load_skew_values(phydev, of_node,
+				MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
+				tx_data_skews, 4);
+	}
+	return 0;
+}
+
 #define KSZ8873MLL_GLOBAL_CONTROL_4	0x06
 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX	(1 << 6)
 #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED	(1 << 4)
@@ -259,7 +343,7 @@ static struct phy_driver ksphy_driver[] = {
 	.phy_id_mask	= 0x00fffff0,
 	.drv.name	= "Micrel KSZ9031 Gigabit PHY",
 	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause),
-	.config_init	= kszphy_config_init,
+	.config_init	= ksz9031_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 }, {
-- 
1.7.0.4



From voice.shen at atmel.com  Wed Oct 29 01:59:34 2014
From: voice.shen at atmel.com (Bo Shen)
Date: Wed, 29 Oct 2014 16:59:34 +0800
Subject: [PATCH] ARM: atmel: add sama5d4 xplained ultra board support
Message-ID: <1414573174-10013-1-git-send-email-voice.shen@atmel.com>

The sama5d4 xplained ultra board support following features:
  - NAND flash support
  - SPI flash support
  - MMC card support (MCI1)
  - LCD display support (with QT1070)
  - Ethernet support

Signed-off-by: Bo Shen <voice.shen at atmel.com>
---

 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/sama5d4_xplained/Makefile          |   1 +
 .../arm/boards/sama5d4_xplained/env/bin/init_board |  15 +
 arch/arm/boards/sama5d4_xplained/env/config        |  42 +++
 .../arm/boards/sama5d4_xplained/sama5d4_xplained.c | 319 +++++++++++++++++++++
 arch/arm/configs/sama5d4_xplained_defconfig        |  86 ++++++
 arch/arm/mach-at91/Kconfig                         |   5 +
 7 files changed, 469 insertions(+)
 create mode 100644 arch/arm/boards/sama5d4_xplained/Makefile
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/bin/init_board
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/config
 create mode 100644 arch/arm/boards/sama5d4_xplained/sama5d4_xplained.c
 create mode 100644 arch/arm/configs/sama5d4_xplained_defconfig

diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index c80b9c9..84b427e 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_MACH_SABRELITE)			+= freescale-mx6-sabrelite/
 obj-$(CONFIG_MACH_SABRESD)			+= freescale-mx6-sabresd/
 obj-$(CONFIG_MACH_SAMA5D3XEK)			+= sama5d3xek/
 obj-$(CONFIG_MACH_SAMA5D3_XPLAINED)		+= sama5d3_xplained/
+obj-$(CONFIG_MACH_SAMA5D4_XPLAINED)		+= sama5d4_xplained/
 obj-$(CONFIG_MACH_SAMA5D4EK)			+= sama5d4ek/
 obj-$(CONFIG_MACH_SCB9328)			+= scb9328/
 obj-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES)		+= ebv-socrates/
diff --git a/arch/arm/boards/sama5d4_xplained/Makefile b/arch/arm/boards/sama5d4_xplained/Makefile
new file mode 100644
index 0000000..44550f5
--- /dev/null
+++ b/arch/arm/boards/sama5d4_xplained/Makefile
@@ -0,0 +1 @@
+obj-y += sama5d4_xplained.o
diff --git a/arch/arm/boards/sama5d4_xplained/env/bin/init_board b/arch/arm/boards/sama5d4_xplained/env/bin/init_board
new file mode 100644
index 0000000..f3d417e
--- /dev/null
+++ b/arch/arm/boards/sama5d4_xplained/env/bin/init_board
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+
+splash=/env/splash.png
+
+if [ -f ${splash} -a -e /dev/fb0 ]; then
+	splash -o ${splash}
+	fb0.enable=1
+fi
+
+exit 1
diff --git a/arch/arm/boards/sama5d4_xplained/env/config b/arch/arm/boards/sama5d4_xplained/env/config
new file mode 100644
index 0000000..1007345
--- /dev/null
+++ b/arch/arm/boards/sama5d4_xplained/env/config
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# 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.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'nfs', 'tftp', 'nor' or 'nand'
+kernel_loc=nfs
+# can be either 'net', 'nor', 'nand' or 'initrd'
+rootfs_loc=net
+# can be either 'nfs', 'tftp', 'nand' or empty
+oftree_loc=nfs
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root.$rootfs_type
+ubiroot=rootfs
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage=zImage
+#kernelimage=uImage
+#kernelimage=Image
+#kernelimage=Image.lzo
+
+nand_device=atmel_nand
+nand_parts="256k(at91bootstrap),512k(barebox)ro,256k(bareboxenv),256k(bareboxenv2),256k(spare),512k(oftree),6M(kernel),-(rootfs)"
+rootfs_mtdblock_nand=7
+
+m25p80_parts="64k(bootstrap),384k(barebox),256k(bareboxenv),256k(bareboxenv2),128k(oftree),-(updater)"
+
+autoboot_timeout=3
+
+bootargs="console=ttyS0,115200"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m\n# "
diff --git a/arch/arm/boards/sama5d4_xplained/sama5d4_xplained.c b/arch/arm/boards/sama5d4_xplained/sama5d4_xplained.c
new file mode 100644
index 0000000..0126220
--- /dev/null
+++ b/arch/arm/boards/sama5d4_xplained/sama5d4_xplained.c
@@ -0,0 +1,319 @@
+/*
+ * SAMA5D4 XPLAINED ULTRA board configuration.
+ *
+ * Copyright (C) 2014 Atmel Corporation,
+ *		      Bo Shen <voice.shen at atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <common.h>
+#include <net.h>
+#include <init.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <partition.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <io.h>
+#include <mach/hardware.h>
+#include <nand.h>
+#include <sizes.h>
+#include <linux/mtd/nand.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+#include <gpio.h>
+#include <mach/iomux.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91sam9x5_matrix.h>
+#include <input/qt1070.h>
+#include <readkey.h>
+#include <spi/spi.h>
+#include <linux/clk.h>
+
+#if defined(CONFIG_NAND_ATMEL)
+static struct atmel_nand_data nand_pdata = {
+	.ale		= 21,
+	.cle		= 22,
+	.det_pin	= -EINVAL,
+	.rdy_pin	= -EINVAL,
+	.enable_pin	= -EINVAL,
+	.ecc_mode	= NAND_ECC_HW,
+	.pmecc_sector_size = 512,
+	.pmecc_corr_cap = 8,
+	.on_flash_bbt	= 1,
+};
+
+static struct sam9_smc_config cm_nand_smc_config = {
+	.ncs_read_setup		= 1,
+	.nrd_setup		= 1,
+	.ncs_write_setup	= 1,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 3,
+	.nrd_pulse		= 2,
+	.ncs_write_pulse	= 3,
+	.nwe_pulse		= 2,
+
+	.read_cycle		= 5,
+	.write_cycle		= 5,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+	.tdf_cycles		= 3,
+
+	.tclr			= 2,
+	.tadl			= 7,
+	.tar			= 2,
+	.ocms			= 0,
+	.trr			= 3,
+	.twb			= 7,
+	.rbnsel			= 3,
+	.nfsel			= 1,
+};
+
+static void ek_add_device_nand(void)
+{
+	struct clk *clk = clk_get(NULL, "smc_clk");
+
+	clk_enable(clk);
+
+	/* configure chip-select 3 (NAND) */
+	sama5_smc_configure(0, 3, &cm_nand_smc_config);
+
+	at91_add_device_nand(&nand_pdata);
+}
+#else
+static void ek_add_device_nand(void) {}
+#endif
+
+#if defined(CONFIG_DRIVER_NET_MACB)
+static struct macb_platform_data macb0_pdata = {
+	.phy_interface = PHY_INTERFACE_MODE_RMII,
+	.phy_addr = 0,
+};
+
+static void ek_add_device_eth(void)
+{
+	at91_add_device_eth(0, &macb0_pdata);
+}
+#else
+static void ek_add_device_eth(void) {}
+#endif
+
+#if defined(CONFIG_DRIVER_VIDEO_ATMEL_HLCD)
+static struct fb_videomode at91_tft_vga_modes[] = {
+	{
+		.name		= "TM4301",
+		.refresh	= 60,
+		.xres		= 480,		.yres		= 272,
+		.pixclock	= KHZ2PICOS(9000),
+
+		.left_margin	= 2,		.right_margin	= 2,
+		.upper_margin	= 2,		.lower_margin	= 2,
+		.hsync_len	= 41,		.vsync_len	= 11,
+
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+/* Output mode is TFT 24 bits */
+#define BPP_OUT_DEFAULT_LCDCFG5	(LCDC_LCDCFG5_MODE_OUTPUT_24BPP)
+
+static struct atmel_lcdfb_platform_data ek_lcdc_data = {
+	.lcdcon_is_backlight		= true,
+	.default_bpp			= 16,
+	.default_dmacon			= ATMEL_LCDC_DMAEN,
+	.default_lcdcon2		= BPP_OUT_DEFAULT_LCDCFG5,
+	.guard_time			= 9,
+	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
+	.mode_list			= at91_tft_vga_modes,
+	.num_modes			= ARRAY_SIZE(at91_tft_vga_modes),
+};
+
+static void ek_add_device_lcdc(void)
+{
+	/* On sama5d4 xplained ultra board, we use 24bits connection */
+	at91_set_A_periph(AT91_PIN_PA0, 0);	/* LCDD0 */
+	at91_set_A_periph(AT91_PIN_PA1, 0);	/* LCDD1 */
+	at91_set_A_periph(AT91_PIN_PA8, 0);	/* LCDD8 */
+	at91_set_A_periph(AT91_PIN_PA9, 0);	/* LCDD9 */
+	at91_set_A_periph(AT91_PIN_PA16, 0);	/* LCDD16 */
+	at91_set_A_periph(AT91_PIN_PA17, 0);	/* LCDD17 */
+
+	at91_add_device_lcdc(&ek_lcdc_data);
+}
+#else
+static void ek_add_device_lcdc(void) {}
+#endif
+
+#if defined(CONFIG_MCI_ATMEL)
+static struct atmel_mci_platform_data mci1_data = {
+	.bus_width	= 4,
+	.detect_pin	= AT91_PIN_PE3,
+	.wp_pin		= -EINVAL,
+};
+
+static void ek_add_device_mci(void)
+{
+	/* MMC1 */
+	at91_add_device_mci(1, &mci1_data);
+
+	/* power on MCI1 */
+	at91_set_gpio_output(AT91_PIN_PE15, 0);
+}
+#else
+static void ek_add_device_mci(void) {}
+#endif
+
+#if defined(CONFIG_I2C_GPIO)
+struct qt1070_platform_data qt1070_pdata = {
+	.irq_pin	= AT91_PIN_PE10,
+};
+
+static struct i2c_board_info i2c_devices[] = {
+	{
+		.platform_data = &qt1070_pdata,
+		I2C_BOARD_INFO("qt1070", 0x1b),
+	},
+};
+
+static void ek_add_device_i2c(void)
+{
+	at91_set_gpio_input(qt1070_pdata.irq_pin, 0);
+	at91_set_deglitch(qt1070_pdata.irq_pin, 1);
+	at91_add_device_i2c(0, i2c_devices, ARRAY_SIZE(i2c_devices));
+}
+#else
+static void ek_add_device_i2c(void) {}
+#endif
+
+#if defined(CONFIG_DRIVER_SPI_ATMEL)
+static const struct spi_board_info ek_spi_devices[] = {
+	{
+		.name		= "m25p80",
+		.chip_select	= 0,
+		.max_speed_hz	= 30 * 1000 * 1000,
+		.bus_num	= 0,
+	}
+};
+
+static unsigned spi0_standard_cs[] = { AT91_PIN_PC3 };
+static struct at91_spi_platform_data spi_pdata = {
+	.chipselect = spi0_standard_cs,
+	.num_chipselect = ARRAY_SIZE(spi0_standard_cs),
+};
+
+static void ek_add_device_spi(void)
+{
+	spi_register_board_info(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	at91_add_device_spi(0, &spi_pdata);
+}
+#else
+static void ek_add_device_spi(void) {}
+#endif
+
+#ifdef CONFIG_LED_GPIO
+struct gpio_led leds[] = {
+	{
+		.gpio	= AT91_PIN_PD30,
+		.active_low	= 0,
+		.led	= {
+			.name = "d8",
+		},
+	}, {
+		.gpio	= AT91_PIN_PE15,
+		.active_low	= 0,
+		.led	= {
+			.name = "d10",
+		},
+	},
+};
+
+static void ek_add_led(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(leds); i++) {
+		at91_set_gpio_output(leds[i].gpio, leds[i].active_low);
+		led_gpio_register(&leds[i]);
+	}
+	led_set_trigger(LED_TRIGGER_HEARTBEAT, &leds[0].led);
+}
+#else
+static void ek_add_led(void) {}
+#endif
+
+static int sama5d4ek_mem_init(void)
+{
+	at91_add_device_sdram(0);
+
+	return 0;
+}
+mem_initcall(sama5d4ek_mem_init);
+
+static const struct devfs_partition sama5d4ek_nand0_partitions[] = {
+	{
+		.offset = 0x00000,
+		.size = SZ_256K,
+		.flags = DEVFS_PARTITION_FIXED,
+		.name = "at91bootstrap_raw",
+		.bbname = "at91bootstrap",
+	}, {
+		.offset = DEVFS_PARTITION_APPEND,
+		.size = SZ_512K,
+		.flags = DEVFS_PARTITION_FIXED,
+		.name = "bootloader_raw",
+		.bbname = "bootloader",
+	}, {
+		.offset = DEVFS_PARTITION_APPEND,
+		.size = SZ_256K,
+		.flags = DEVFS_PARTITION_FIXED,
+		.name = "env_raw",
+		.bbname = "env0",
+	}, {
+		.offset = DEVFS_PARTITION_APPEND,
+		.size = SZ_256K,
+		.flags = DEVFS_PARTITION_FIXED,
+		.name = "env_raw1",
+		.bbname = "env1",
+	}, {
+		/* sentinel */
+	}
+};
+
+static int sama5d4ek_devices_init(void)
+{
+	ek_add_device_i2c();
+	ek_add_device_nand();
+	ek_add_led();
+	ek_add_device_eth();
+	ek_add_device_spi();
+	ek_add_device_mci();
+	ek_add_device_lcdc();
+
+	devfs_create_partitions("nand0", sama5d4ek_nand0_partitions);
+
+	return 0;
+}
+device_initcall(sama5d4ek_devices_init);
+
+static int sama5d4ek_console_init(void)
+{
+	barebox_set_model("Atmel sama5d4ek");
+	barebox_set_hostname("sama5d4ek");
+
+	at91_register_uart(4, 0);
+
+	return 0;
+}
+console_initcall(sama5d4ek_console_init);
+
+static int sama5d4ek_main_clock(void)
+{
+	at91_set_main_clock(12000000);
+
+	return 0;
+}
+pure_initcall(sama5d4ek_main_clock);
diff --git a/arch/arm/configs/sama5d4_xplained_defconfig b/arch/arm/configs/sama5d4_xplained_defconfig
new file mode 100644
index 0000000..51083fe
--- /dev/null
+++ b/arch/arm/configs/sama5d4_xplained_defconfig
@@ -0,0 +1,86 @@
+CONFIG_ARCH_SAMA5D4=y
+CONFIG_MACH_SAMA5D4_XPLAINED=y
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x60000
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_PBL_IMAGE=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x26f00000
+CONFIG_MALLOC_SIZE=0xA00000
+CONFIG_EXPERIMENTAL=y
+CONFIG_MALLOC_TLSF=y
+CONFIG_PROMPT="A5D4_XPLAINED:"
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_CONSOLE_ACTIVATE_ALL=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/sama5d4ek/env"
+CONFIG_DEBUG_INFO=y
+# CONFIG_CMD_ARM_CPUINFO is not set
+CONFIG_LONGHELP=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SPLASH=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
+CONFIG_NET_NFS=y
+CONFIG_OFDEVICE=y
+CONFIG_DRIVER_NET_MACB=y
+CONFIG_MICREL_PHY=y
+CONFIG_DRIVER_SPI_ATMEL=y
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
+CONFIG_MTD=y
+CONFIG_MTD_RAW_DEVICE=y
+CONFIG_MTD_M25P80=y
+CONFIG_NAND=y
+# CONFIG_NAND_ECC_SOFT is not set
+# CONFIG_NAND_ECC_HW_SYNDROME is not set
+CONFIG_NAND_ATMEL=y
+CONFIG_NAND_ATMEL_PMECC=y
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_ATMEL_HLCD=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_ATMEL=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_QT1070=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+CONFIG_PNG=y
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 8c10c10..9ee4f30 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -492,6 +492,11 @@ config MACH_SAMA5D4EK
 	help
 	  Select this if you are using Atmel's SAMA5D4-EK Evaluation Kit.
 
+config MACH_SAMA5D4_XPLAINED
+	bool "Atmel SAMA5D4 XPLAINED ULTRA Evaluation Kit"
+	help
+	  Select this if you are using Atmel's SAMA5D4_XPLAINED ULTRA Evaluation Kit.
+
 endchoice
 
 endif
-- 
2.1.0.24.g4109c28



From antonynpavlov at gmail.com  Wed Oct 29 08:28:02 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Wed, 29 Oct 2014 18:28:02 +0300
Subject: [PATCH] Documentation: dts: add missed Ingenic Semiconductor vendor
 prefix
Message-ID: <1414596482-829-1-git-send-email-antonynpavlov@gmail.com>

We already have jz4755 and jz4780 Ingenic chips support,
but documentation for Ingenic devicetree vendor prefix is missed.

Based on this linux kernel commit:

    commit 52f31dc5fc817642c0b5a5bc5cdae6ab18e99987
    Author: Paul Burton <paul.burton at imgtec.com>
    Date:   Mon Jul 8 12:12:11 2013 +0100

        devicetree/bindings: add Ingenic Semiconductor vendor prefix

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 dts/Bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dts/Bindings/vendor-prefixes.txt b/dts/Bindings/vendor-prefixes.txt
index ac7269f..0cfdb01 100644
--- a/dts/Bindings/vendor-prefixes.txt
+++ b/dts/Bindings/vendor-prefixes.txt
@@ -65,6 +65,7 @@ ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 iom	Iomega Corporation
 img	Imagination Technologies Ltd.
+ingenic	Ingenic Semiconductor
 intel	Intel Corporation
 intercontrol	Inter Control Group
 isee	ISEE 2007 S.L.
-- 
2.1.1



From shc_work at mail.ru  Thu Oct 30 02:06:09 2014
From: shc_work at mail.ru (Alexander Shiyan)
Date: Thu, 30 Oct 2014 12:06:09 +0300
Subject: [PATCH] treewide: Reuse init_clock() return value for clocksource
 drivers
Message-ID: <1414659969-5509-1-git-send-email-shc_work@mail.ru>

Signed-off-by: Alexander Shiyan <shc_work at mail.ru>
---
 arch/arm/mach-at91/at91rm9200_time.c  | 4 +---
 arch/arm/mach-at91/at91sam926x_time.c | 4 +---
 arch/arm/mach-ep93xx/clocksource.c    | 4 +---
 arch/arm/mach-mxs/clocksource-imx28.c | 3 +--
 arch/arm/mach-netx/clocksource.c      | 4 +---
 arch/arm/mach-pxa/clocksource.c       | 4 +---
 arch/arm/mach-samsung/s3c-timer.c     | 3 +--
 arch/arm/mach-tegra/tegra20-timer.c   | 3 +--
 arch/blackfin/lib/clock.c             | 4 +---
 arch/efi/efi/clocksource.c            | 4 +---
 arch/mips/lib/csrc-r4k.c              | 3 +--
 arch/nios2/lib/clock.c                | 4 +---
 arch/openrisc/lib/clock.c             | 4 +---
 arch/ppc/mach-mpc5xxx/time.c          | 4 +---
 arch/ppc/mach-mpc85xx/time.c          | 4 +---
 arch/sandbox/board/clock.c            | 4 +---
 arch/x86/mach-i386/pit_timer.c        | 3 +--
 drivers/clocksource/amba-sp804.c      | 4 +---
 drivers/clocksource/arm_smp_twd.c     | 4 +---
 drivers/clocksource/bcm2835.c         | 3 +--
 drivers/clocksource/dummy.c           | 3 +--
 drivers/clocksource/mvebu.c           | 4 +---
 drivers/clocksource/nomadik.c         | 4 +---
 drivers/clocksource/orion.c           | 3 +--
 drivers/clocksource/uemd.c            | 4 +---
 25 files changed, 25 insertions(+), 67 deletions(-)

diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 1b73a51..ae0172b 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -70,9 +70,7 @@ static int clocksource_init (void)
 
 	cs.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 core_initcall(clocksource_init);
 
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 06d3e32..789e1ec 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -99,9 +99,7 @@ static int at91_pit_probe(struct device_d *dev)
 
 	cs.mult = clocksource_hz2mult(pit_rate, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 static struct driver_d at91_pit_driver = {
diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c
index 26ab91d..f396d0a 100644
--- a/arch/arm/mach-ep93xx/clocksource.c
+++ b/arch/arm/mach-ep93xx/clocksource.c
@@ -58,9 +58,7 @@ static int clocksource_init(void)
 
 	cs.mult = clocksource_hz2mult(TIMER_FREQ, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/arm/mach-mxs/clocksource-imx28.c b/arch/arm/mach-mxs/clocksource-imx28.c
index 328ca5d..d26aa93 100644
--- a/arch/arm/mach-mxs/clocksource-imx28.c
+++ b/arch/arm/mach-mxs/clocksource-imx28.c
@@ -65,9 +65,8 @@ static int imx28_clocksource_init(void)
 	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;
+	return init_clock(&imx28_cs);
 }
 
 core_initcall(imx28_clocksource_init);
diff --git a/arch/arm/mach-netx/clocksource.c b/arch/arm/mach-netx/clocksource.c
index bfce37a..8f53364 100644
--- a/arch/arm/mach-netx/clocksource.c
+++ b/arch/arm/mach-netx/clocksource.c
@@ -45,9 +45,7 @@ static int clocksource_init (void)
 
 	cs.mult = clocksource_hz2mult(100 * 1000 * 1000, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/arm/mach-pxa/clocksource.c b/arch/arm/mach-pxa/clocksource.c
index 04d090a..c941f15 100644
--- a/arch/arm/mach-pxa/clocksource.c
+++ b/arch/arm/mach-pxa/clocksource.c
@@ -37,9 +37,7 @@ static int clocksource_init(void)
 {
 	cs.mult = clocksource_hz2mult(3250000, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/arm/mach-samsung/s3c-timer.c b/arch/arm/mach-samsung/s3c-timer.c
index fb3cda0..b5118fa 100644
--- a/arch/arm/mach-samsung/s3c-timer.c
+++ b/arch/arm/mach-samsung/s3c-timer.c
@@ -115,8 +115,7 @@ static int s3c_clk_src_init(void)
 	s3c_timer_start();
 
 	cs.mult = clocksource_hz2mult(s3c_get_t4_clk(), cs.shift);
-	init_clock(&cs);
 
-	return 0;
+	return init_clock(&cs);
 }
 core_initcall(s3c_clk_src_init);
diff --git a/arch/arm/mach-tegra/tegra20-timer.c b/arch/arm/mach-tegra/tegra20-timer.c
index ddc70dc..a8e4d7b 100644
--- a/arch/arm/mach-tegra/tegra20-timer.c
+++ b/arch/arm/mach-tegra/tegra20-timer.c
@@ -84,9 +84,8 @@ static int tegra20_timer_probe(struct device_d *dev)
 	writel(reg, timer_base + TIMERUS_USEC_CFG);
 
 	cs.mult = clocksource_hz2mult(1000000, cs.shift);
-	init_clock(&cs);
 
-	return 0;
+	return init_clock(&cs);
 }
 
 static __maybe_unused struct of_device_id tegra20_timer_dt_ids[] = {
diff --git a/arch/blackfin/lib/clock.c b/arch/blackfin/lib/clock.c
index 7a5673f..aaa042a 100644
--- a/arch/blackfin/lib/clock.c
+++ b/arch/blackfin/lib/clock.c
@@ -70,9 +70,7 @@ static int clocksource_init (void)
 
         cs.mult = clocksource_hz2mult(get_cclk(), cs.shift);
 
-        init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/efi/efi/clocksource.c b/arch/efi/efi/clocksource.c
index 2f33b43..c92c35b 100644
--- a/arch/efi/efi/clocksource.c
+++ b/arch/efi/efi/clocksource.c
@@ -54,7 +54,5 @@ int efi_clocksource_init(void)
 
 	freq = ticks_freq();
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
diff --git a/arch/mips/lib/csrc-r4k.c b/arch/mips/lib/csrc-r4k.c
index c699f2b..5c3f18f 100644
--- a/arch/mips/lib/csrc-r4k.c
+++ b/arch/mips/lib/csrc-r4k.c
@@ -38,8 +38,7 @@ static struct clocksource cs = {
 static int clocksource_init(void)
 {
 	cs.mult = clocksource_hz2mult(100000000, cs.shift);
-	init_clock(&cs);
 
-	return 0;
+	return init_clock(&cs);
 }
 core_initcall(clocksource_init);
diff --git a/arch/nios2/lib/clock.c b/arch/nios2/lib/clock.c
index 67cc778..28aed02 100644
--- a/arch/nios2/lib/clock.c
+++ b/arch/nios2/lib/clock.c
@@ -49,9 +49,7 @@ static int clocksource_init(void)
 
 	cs.mult = clocksource_hz2mult(NIOS_SOPC_TIMER_FREQ, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/openrisc/lib/clock.c b/arch/openrisc/lib/clock.c
index 4f36f27..a171214 100644
--- a/arch/openrisc/lib/clock.c
+++ b/arch/openrisc/lib/clock.c
@@ -38,9 +38,7 @@ static int clocksource_init(void)
 	mtspr(SPR_TTMR, SPR_TTMR_CR | 0xFFFFFF);
 	cs.mult = clocksource_hz2mult(OPENRISC_TIMER_FREQ, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/ppc/mach-mpc5xxx/time.c b/arch/ppc/mach-mpc5xxx/time.c
index 8ba0c5c..699a66d 100644
--- a/arch/ppc/mach-mpc5xxx/time.c
+++ b/arch/ppc/mach-mpc5xxx/time.c
@@ -41,9 +41,7 @@ static int clocksource_init(void)
 
 	cs.mult = clocksource_hz2mult(get_timebase_clock(), cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/ppc/mach-mpc85xx/time.c b/arch/ppc/mach-mpc85xx/time.c
index 985ec09..9014fce 100644
--- a/arch/ppc/mach-mpc85xx/time.c
+++ b/arch/ppc/mach-mpc85xx/time.c
@@ -41,9 +41,7 @@ static int clocksource_init(void)
 	clocks_calc_mult_shift(&cs.mult, &cs.shift,
 				fsl_get_timebase_clock(), NSEC_PER_SEC, 10);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/sandbox/board/clock.c b/arch/sandbox/board/clock.c
index 137e20b..bdea89f 100644
--- a/arch/sandbox/board/clock.c
+++ b/arch/sandbox/board/clock.c
@@ -37,9 +37,7 @@ static int clocksource_init (void)
 {
 	cs.mult = clocksource_hz2mult(1000 * 1000 * 1000, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/arch/x86/mach-i386/pit_timer.c b/arch/x86/mach-i386/pit_timer.c
index fbc7a10..857ba31 100644
--- a/arch/x86/mach-i386/pit_timer.c
+++ b/arch/x86/mach-i386/pit_timer.c
@@ -59,9 +59,8 @@ static struct clocksource cs = {
 static int clocksource_init (void)
 {
 	cs.mult = clocksource_hz2mult(1193182, cs.shift);
-	init_clock(&cs);
 
-	return 0;
+	return init_clock(&cs);
 }
 
 core_initcall(clocksource_init);
diff --git a/drivers/clocksource/amba-sp804.c b/drivers/clocksource/amba-sp804.c
index fedcb64..c5ad994 100644
--- a/drivers/clocksource/amba-sp804.c
+++ b/drivers/clocksource/amba-sp804.c
@@ -66,9 +66,7 @@ static int sp804_probe(struct amba_device *dev, const struct amba_id *id)
 
 	sp804_clksrc.mult = clocksource_hz2mult(tick_rate, sp804_clksrc.shift);
 
-	init_clock(&sp804_clksrc);
-
-	return 0;
+	return init_clock(&sp804_clksrc);
 }
 
 static struct amba_id sp804_ids[] = {
diff --git a/drivers/clocksource/arm_smp_twd.c b/drivers/clocksource/arm_smp_twd.c
index 72045b0..c0296cd 100644
--- a/drivers/clocksource/arm_smp_twd.c
+++ b/drivers/clocksource/arm_smp_twd.c
@@ -86,9 +86,7 @@ static int smp_twd_probe(struct device_d *dev)
 
 	smp_twd_clksrc.mult = clocksource_hz2mult(tick_rate, smp_twd_clksrc.shift);
 
-	init_clock(&smp_twd_clksrc);
-
-	return 0;
+	return init_clock(&smp_twd_clksrc);
 }
 
 static __maybe_unused struct of_device_id smp_twd_compatible[] = {
diff --git a/drivers/clocksource/bcm2835.c b/drivers/clocksource/bcm2835.c
index c0b1aae..0cb8e57 100644
--- a/drivers/clocksource/bcm2835.c
+++ b/drivers/clocksource/bcm2835.c
@@ -66,9 +66,8 @@ static int bcm2835_cs_probe(struct device_d *dev)
 		return PTR_ERR(stc_base);
 
 	clocks_calc_mult_shift(&bcm2835_stc.mult, &bcm2835_stc.shift, rate, NSEC_PER_SEC, 60);
-	init_clock(&bcm2835_stc);
 
-	return 0;
+	return init_clock(&bcm2835_stc);
 }
 
 static __maybe_unused struct of_device_id bcm2835_cs_dt_ids[] = {
diff --git a/drivers/clocksource/dummy.c b/drivers/clocksource/dummy.c
index 154a8cd..96f9b6e 100644
--- a/drivers/clocksource/dummy.c
+++ b/drivers/clocksource/dummy.c
@@ -49,8 +49,7 @@ static int clocksource_init(void)
 
 	pr_debug("clocksource_init: mult=%08x, shift=%08x\n",
 			dummy_cs.mult, dummy_cs.shift);
-	init_clock(&dummy_cs);
 
-	return 0;
+	return init_clock(&dummy_cs);
 }
 pure_initcall(clocksource_init);
diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c
index b8fa985..88db0b0 100644
--- a/drivers/clocksource/mvebu.c
+++ b/drivers/clocksource/mvebu.c
@@ -88,9 +88,7 @@ static int mvebu_timer_probe(struct device_d *dev)
 
 	cs.mult = clocksource_hz2mult(rate, cs.shift);
 
-	init_clock(&cs);
-
-	return 0;
+	return init_clock(&cs);
 }
 
 static struct of_device_id mvebu_timer_dt_ids[] = {
diff --git a/drivers/clocksource/nomadik.c b/drivers/clocksource/nomadik.c
index d7edf06..48f4715 100644
--- a/drivers/clocksource/nomadik.c
+++ b/drivers/clocksource/nomadik.c
@@ -132,9 +132,7 @@ static int nmdk_mtu_probe(struct device_d *dev)
 
 	nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
 
-	init_clock(&nmdk_clksrc);
-
-	return 0;
+	return init_clock(&nmdk_clksrc);
 }
 
 static struct driver_d nmdk_mtu_driver = {
diff --git a/drivers/clocksource/orion.c b/drivers/clocksource/orion.c
index a1dafd8..2e40b49 100644
--- a/drivers/clocksource/orion.c
+++ b/drivers/clocksource/orion.c
@@ -62,9 +62,8 @@ static int orion_timer_probe(struct device_d *dev)
 		     timer_base + TIMER_CTRL);
 
 	clksrc.mult = clocksource_hz2mult(clk_get_rate(tclk), clksrc.shift);
-	init_clock(&clksrc);
 
-	return 0;
+	return init_clock(&clksrc);
 }
 
 static struct of_device_id orion_timer_dt_ids[] = {
diff --git a/drivers/clocksource/uemd.c b/drivers/clocksource/uemd.c
index 6c37de5..d4291dd 100644
--- a/drivers/clocksource/uemd.c
+++ b/drivers/clocksource/uemd.c
@@ -105,9 +105,7 @@ static int uemd_timer_probe(struct device_d *dev)
 	clocks_calc_mult_shift(&uemd_cs.mult, &uemd_cs.shift,
 		clk_get_rate(timer_clk), NSEC_PER_SEC, 10);
 
-	init_clock(&uemd_cs);
-
-	return 0;
+	return init_clock(&uemd_cs);
 }
 
 static __maybe_unused struct of_device_id uemd_timer_dt_ids[] = {
-- 
2.0.4



From shc_work at mail.ru  Thu Oct 30 03:32:31 2014
From: shc_work at mail.ru (Alexander Shiyan)
Date: Thu, 30 Oct 2014 13:32:31 +0300
Subject: [PATCH] serial: ns16550: Remove unused fields from NS16550_plat
 structure
Message-ID: <1414665151-7229-1-git-send-email-shc_work@mail.ru>

Signed-off-by: Alexander Shiyan <shc_work at mail.ru>
---
 include/ns16550.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/ns16550.h b/include/ns16550.h
index 876bb04..ccf950b 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -34,9 +34,6 @@ struct NS16550_plat {
 	/** Clock speed */
 	unsigned int clock;
 	int shift;
-	unsigned int flags;
-	int mmio;
-#define NS16650_FLAG_DISABLE_FIFO	1
 };
 
 #endif				/* __NS16650_PLATFORM_H_ */
-- 
2.0.4



From w.egorov at phytec.de  Thu Oct 30 05:01:36 2014
From: w.egorov at phytec.de (Wadim Egorov)
Date: Thu, 30 Oct 2014 13:01:36 +0100
Subject: [For next PATCH 2/2] phyFLEX: Select RMII2_CRS_DV on GPMC_A9 pin
In-Reply-To: <1414670496-25123-1-git-send-email-w.egorov@phytec.de>
References: <1414670496-25123-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1414670496-25123-2-git-send-email-w.egorov@phytec.de>

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/boards/phytec-phyflex-am335x/board.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boards/phytec-phyflex-am335x/board.c b/arch/arm/boards/phytec-phyflex-am335x/board.c
index 12fad8f..cf7dd2e 100644
--- a/arch/arm/boards/phytec-phyflex-am335x/board.c
+++ b/arch/arm/boards/phytec-phyflex-am335x/board.c
@@ -89,6 +89,8 @@ static int pfla03_devices_init(void)
 	armlinux_set_architecture(MACH_TYPE_PFLA03);
 	defaultenv_append_directory(defaultenv_phyflex_am335x);
 
+	am33xx_select_rmii2_crs_dv();
+
 	am33xx_bbu_spi_nor_mlo_register_handler("MLO.spi", "/dev/m25p0.xload");
 	am33xx_bbu_spi_nor_register_handler("spi", "/dev/m25p0.barebox");
 	am33xx_bbu_nand_xloadslots_register_handler("MLO.nand",
-- 
1.7.0.4



From w.egorov at phytec.de  Thu Oct 30 05:01:35 2014
From: w.egorov at phytec.de (Wadim Egorov)
Date: Thu, 30 Oct 2014 13:01:35 +0100
Subject: [For next PATCH 1/2] arm: am33xx: Add rmii2_crs_dv mux selection in
 SMA2 register
Message-ID: <1414670496-25123-1-git-send-email-w.egorov@phytec.de>

"Silicon revision 1.0 devices only provide the MMC2_DAT7 signal when Mode3 is
selected. Silicon revision 2.0 and newer devices implement another level of
pin multiplexing which provides the original MMC2_DAT7 signal or RMII2_CRS_DV
signal when Mode3 is selected. This new level of of pin multiplexing is
selected with bit zero of the SMA2 register."

See AM335x Sitara Processors Manual.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/mach-omap/am33xx_generic.c              |   12 ++++++++++++
 arch/arm/mach-omap/include/mach/am33xx-generic.h |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c
index f293134..12764bc 100644
--- a/arch/arm/mach-omap/am33xx_generic.c
+++ b/arch/arm/mach-omap/am33xx_generic.c
@@ -428,3 +428,15 @@ void am335x_sdram_init(int ioctrl, const struct am33xx_cmd_control *cmd_ctrl,
 
 	am33xx_config_sdram(emif_regs);
 }
+
+#define AM33XX_CONTROL_SMA2_OFS	0x1320
+
+/**
+ * am33xx_select_rmii2_crs_dv - Select RMII2_CRS_DV on GPMC_A9 pin in MODE3
+ */
+void am33xx_select_rmii2_crs_dv(void)
+{
+	uint32_t val = readl(AM33XX_CTRL_BASE + AM33XX_CONTROL_SMA2_OFS);
+	val |= 0x00000001;
+	writel(val, AM33XX_CTRL_BASE + AM33XX_CONTROL_SMA2_OFS);
+}
diff --git a/arch/arm/mach-omap/include/mach/am33xx-generic.h b/arch/arm/mach-omap/include/mach/am33xx-generic.h
index 6c85d51..1264e7e 100644
--- a/arch/arm/mach-omap/include/mach/am33xx-generic.h
+++ b/arch/arm/mach-omap/include/mach/am33xx-generic.h
@@ -33,5 +33,6 @@ void __noreturn am33xx_reset_cpu(unsigned long addr);
 void am33xx_enable_per_clocks(void);
 int am33xx_init(void);
 int am33xx_devices_init(void);
+void am33xx_select_rmii2_crs_dv(void);
 
 #endif /* __MACH_AM33XX_GENERIC_H */
-- 
1.7.0.4



From t.gamez at phytec.de  Thu Oct 30 05:02:51 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Thu, 30 Oct 2014 13:02:51 +0100
Subject: [For next PATCH 2/3] ARM: am335x: Add register of boot devices
In-Reply-To: <1414670572-43351-1-git-send-email-t.gamez@phytec.de>
References: <1414670572-43351-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1414670572-43351-2-git-send-email-t.gamez@phytec.de>

Add support for registering disabled boot devices from oftree.
Creating a device tree with all bootable devices disabled, makes
it possible to only enable and register the devices needed to
load the next stage bootloader.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/mach-omap/am33xx_generic.c              | 31 ++++++++++++++++++++++++
 arch/arm/mach-omap/include/mach/am33xx-generic.h |  1 +
 2 files changed, 32 insertions(+)

diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c
index f293134..a04e8c7 100644
--- a/arch/arm/mach-omap/am33xx_generic.c
+++ b/arch/arm/mach-omap/am33xx_generic.c
@@ -428,3 +428,34 @@ void am335x_sdram_init(int ioctrl, const struct am33xx_cmd_control *cmd_ctrl,
 
 	am33xx_config_sdram(emif_regs);
 }
+
+int am33xx_of_register_bootdevice(void)
+{
+	struct device_d *dev;
+
+	switch (bootsource_get()) {
+	case BOOTSOURCE_MMC:
+		if (bootsource_get_instance() == 0)
+			dev = of_register_disabled_device_by_name("mmc at 48060000");
+		else
+			dev = of_register_disabled_device_by_name("mmc at 481d8000");
+		break;
+	case BOOTSOURCE_NAND:
+		dev = of_register_disabled_device_by_name("gpmc at 50000000");
+		break;
+	case BOOTSOURCE_SPI:
+		dev = of_register_disabled_device_by_name("spi at 48030000");
+		break;
+	default:
+		/* Use nand fallback */
+		dev = of_register_disabled_device_by_name("gpmc at 50000000");
+		break;
+	}
+
+	if (!dev) {
+		printf("Unable to register boot device\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap/include/mach/am33xx-generic.h b/arch/arm/mach-omap/include/mach/am33xx-generic.h
index 6c85d51..7312061 100644
--- a/arch/arm/mach-omap/include/mach/am33xx-generic.h
+++ b/arch/arm/mach-omap/include/mach/am33xx-generic.h
@@ -33,5 +33,6 @@ void __noreturn am33xx_reset_cpu(unsigned long addr);
 void am33xx_enable_per_clocks(void);
 int am33xx_init(void);
 int am33xx_devices_init(void);
+int am33xx_of_register_bootdevice(void);
 
 #endif /* __MACH_AM33XX_GENERIC_H */
-- 
1.9.1



From t.gamez at phytec.de  Thu Oct 30 05:02:50 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Thu, 30 Oct 2014 13:02:50 +0100
Subject: [For next PATCH 1/3] of: Add of_register_disabled_device functions
Message-ID: <1414670572-43351-1-git-send-email-t.gamez@phytec.de>

Function to enable and register a disabled device.
The devices can be registered using the
device node with of_register_disabled_device() or
with the device node name/path by using the
of_register_disabled_device_by_name() function.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 drivers/of/platform.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/of.h          | 14 ++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c417cfd..e4a3042 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -197,6 +197,49 @@ static struct device_d *of_platform_device_create(struct device_node *np,
 	return NULL;
 }
 
+/**
+ * of_register_disabled_device - Enable and register device
+ * @np: pointer to node to enable create device for
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+struct device_d *of_register_disabled_device(struct device_node *np)
+{
+	struct device_d *dev;
+
+	of_device_enable(np);
+
+	dev = of_platform_device_create(np, NULL);
+	if (!dev)
+		return NULL;
+
+	return dev;
+}
+EXPORT_SYMBOL(of_register_disabled_device);
+
+/**
+ * of_register_disabled_device - Enable and register device by name
+ * @name: name or path of the device node
+ *
+ * Returns pointer to created platform device, or NULL if a device was not
+ * registered. Unavailable devices will not get registered.
+ */
+struct device_d *of_register_disabled_device_by_name(const char *name)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_name(NULL, name);
+	if (!node)
+		node = of_find_node_by_path(name);
+
+	if (!node)
+		return NULL;
+
+	return of_register_disabled_device(node);
+}
+EXPORT_SYMBOL(of_register_disabled_device_by_name);
+
 #ifdef CONFIG_ARM_AMBA
 static struct device_d *of_amba_device_create(struct device_node *np)
 {
diff --git a/include/of.h b/include/of.h
index 29694a9..67b1937 100644
--- a/include/of.h
+++ b/include/of.h
@@ -227,6 +227,8 @@ extern int of_platform_populate(struct device_node *root,
 				const struct of_device_id *matches,
 				struct device_d *parent);
 extern struct device_d *of_find_device_by_node(struct device_node *np);
+extern struct device_d *of_register_disabled_device(struct device_node *np);
+extern struct device_d *of_register_disabled_device_by_name(const char *name);
 
 struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node);
 int of_parse_partitions(struct cdev *cdev, struct device_node *node);
@@ -582,6 +584,18 @@ static inline struct device_d *of_find_device_by_node(struct device_node *np)
 {
 	return NULL;
 }
+
+static inline struct device_d *of_register_disabled_device(
+				struct device_node *np)
+{
+	return NULL;
+}
+
+static inline struct device_d *of_register_disabled_device_by_name(
+				const char *name)
+{
+	return NULL;
+}
 #endif
 
 #define for_each_node_by_name(dn, name) \
-- 
1.9.1



From t.gamez at phytec.de  Thu Oct 30 05:02:52 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Thu, 30 Oct 2014 13:02:52 +0100
Subject: [For next PATCH 3/3] ARM: am335x: phyCORE-AM335x: Create new dts for
 MLO
In-Reply-To: <1414670572-43351-1-git-send-email-t.gamez@phytec.de>
References: <1414670572-43351-1-git-send-email-t.gamez@phytec.de>
Message-ID: <1414670572-43351-3-git-send-email-t.gamez@phytec.de>

Use a mlo device tree with all bootable devices disabled.
The bootsource is checked in the board file and only the
needed device is enabled and registered.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 arch/arm/boards/phytec-phycore-am335x/board.c    |  3 +++
 arch/arm/boards/phytec-phycore-am335x/lowlevel.c |  3 ++-
 arch/arm/dts/Makefile                            |  2 +-
 arch/arm/dts/am335x-phytec-phycore-som-mlo.dts   | 28 ++++++++++++++++++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/dts/am335x-phytec-phycore-som-mlo.dts

diff --git a/arch/arm/boards/phytec-phycore-am335x/board.c b/arch/arm/boards/phytec-phycore-am335x/board.c
index 64e3904..a72cebd 100644
--- a/arch/arm/boards/phytec-phycore-am335x/board.c
+++ b/arch/arm/boards/phytec-phycore-am335x/board.c
@@ -83,6 +83,9 @@ static int pcm051_devices_init(void)
 		xloadslots, ARRAY_SIZE(xloadslots));
 	am33xx_bbu_nand_register_handler("nand", "/dev/nand0.barebox.bb");
 
+	if (IS_ENABLED(CONFIG_SHELL_NONE))
+		return am33xx_of_register_bootdevice();
+
 	return 0;
 }
 device_initcall(pcm051_devices_init);
diff --git a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
index 55cc667..5ab8b5b 100644
--- a/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-am335x/lowlevel.c
@@ -118,6 +118,7 @@ struct pcm051_sdram_timings timings[] = {
 };
 
 extern char __dtb_am335x_phytec_phycore_som_start[];
+extern char __dtb_am335x_phytec_phycore_som_mlo_start[];
 extern char __dtb_am335x_phytec_phycore_som_no_spi_start[];
 
 /**
@@ -154,7 +155,7 @@ static noinline void pcm051_board_init(int sdram)
 	omap_uart_lowlevel_init((void *)AM33XX_UART0_BASE);
 	putc_ll('>');
 
-	fdt = __dtb_am335x_phytec_phycore_som_start - get_runtime_offset();
+	fdt = __dtb_am335x_phytec_phycore_som_mlo_start - get_runtime_offset();
 
 	am335x_barebox_entry(fdt);
 }
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index a9e9ee7..d8160fe 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -26,7 +26,7 @@ pbl-dtb-$(CONFIG_MACH_NVIDIA_JETSON) += tegra124-jetson-tk1.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCA100) += imx27-phytec-phycard-s-rdk-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCAAXL3) += imx6q-phytec-pbaa03.dtb.o
 pbl-dtb-$(CONFIG_MACH_PCM038) += imx27-phytec-phycore-rdk.dtb.o
-pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o am335x-phytec-phycore-som-no-spi.dtb.o
+pbl-dtb-$(CONFIG_MACH_PCM051) += am335x-phytec-phycore-som.dtb.o am335x-phytec-phycore-som-no-spi.dtb.o am335x-phytec-phycore-som-mlo.dtb.o
 pbl-dtb-$(CONFIG_MACH_PFLA03) += am335x-phytec-phyflex.dtb.o
 pbl-dtb-$(CONFIG_MACH_PHYTEC_PFLA02) += imx6s-phytec-pbab01.dtb.o imx6dl-phytec-pbab01.dtb.o imx6q-phytec-pbab01.dtb.o
 pbl-dtb-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += armada-xp-openblocks-ax3-4-bb.dtb.o
diff --git a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
new file mode 100644
index 0000000..4117439
--- /dev/null
+++ b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 Teresa G?mez <t.gamez at phytec.de> PHYTEC Messtechnik GmbH
+ *
+ * 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.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-phytec-phycore-som.dtsi"
+
+/ {
+	model = "Phytec phyCORE AM335x";
+	compatible = "phytec,phycore-am335x-som", "ti,am33xx";
+};
+
+/* Keep all boosources disabled, we enable and register them
+ * later while booting.
+ */
+
+&mmc1 {
+	status = "disabled";
+};
+
+&gpmc {
+	status = "disabled";
+};
-- 
1.9.1



From antonynpavlov at gmail.com  Thu Oct 30 05:30:38 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Thu, 30 Oct 2014 15:30:38 +0300
Subject: [PATCH 1/2] Typoes:  "whith" -> "with"
In-Reply-To: <1414672239-9998-1-git-send-email-antonynpavlov@gmail.com>
References: <1414672239-9998-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1414672239-9998-2-git-send-email-antonynpavlov@gmail.com>

This patch is based on linux kernel commit

    commit e1b8513d21845fbeb93d6d2c4973db874385059f
    Author: Robert P. J. Day <rpjday at crashcourse.ca>
    Date:   Sun Feb 3 15:14:02 2008 +0200

        Typoes:  "whith" -> "with"

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
Cc: Robert P. J. Day <rpjday at crashcourse.ca>
---
 Makefile          | 2 +-
 drivers/mci/mxs.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index d959f57..c5f965e 100644
--- a/Makefile
+++ b/Makefile
@@ -1137,7 +1137,7 @@ endif #ifeq ($(mixed-targets),1)
 # Single targets
 # ---------------------------------------------------------------------------
 # Single targets are compatible with:
-# - build whith mixed source and output
+# - build with mixed source and output
 # - build with separate output dir 'make O=...'
 # - external modules
 #
diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c
index 6e02d46..738bde9 100644
--- a/drivers/mci/mxs.c
+++ b/drivers/mci/mxs.c
@@ -152,7 +152,7 @@ static void mxs_mci_setup_timeout(struct mxs_mci_host *mxs_mci, unsigned to)
  * @return 0 on success, negative values else
  *
  * @note This routine uses PIO to read in the data bytes from the FIFO. This
- * may fail whith high clock speeds. If you receive -EIO errors you can try
+ * may fail with high clock speeds. If you receive -EIO errors you can try
  * again with reduced clock speeds.
  */
 static int mxs_mci_read_data(struct mxs_mci_host *mxs_mci, void *buffer, unsigned length)
-- 
2.1.1



From antonynpavlov at gmail.com  Thu Oct 30 05:30:37 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Thu, 30 Oct 2014 15:30:37 +0300
Subject: [PATCH 0/2] fix typos (import from linux kernel)
Message-ID: <1414672239-9998-1-git-send-email-antonynpavlov@gmail.com>

Antony Pavlov (2):
  Typoes:  "whith" -> "with"
  Makefile: fix typos

 Makefile          | 7 +++----
 drivers/mci/mxs.c | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

-- 
2.1.1



From antonynpavlov at gmail.com  Thu Oct 30 05:30:39 2014
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Thu, 30 Oct 2014 15:30:39 +0300
Subject: [PATCH 2/2] Makefile: fix typos
In-Reply-To: <1414672239-9998-1-git-send-email-antonynpavlov@gmail.com>
References: <1414672239-9998-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1414672239-9998-3-git-send-email-antonynpavlov@gmail.com>

This patch is based on these linux kernel commits:

    commit d384e35a25445bb60457b7dab8cffe178c6b7ecb
    Author: Linus Nilsson <lajnold at acc.umu.se>
    Date:   Sun Jan 20 17:10:01 2008 +0100

        Makefile: Change typoed 'behavour' to 'behaviour'

    commit fe8d0a41081d6d0912386f3672ccc0bf1d675630
    Author: Kirill Smelkov <kirr at mns.spb.ru>
    Date:   Thu Apr 9 15:34:34 2009 +0400

        kbuild: fix a few typos in top-level Makefile

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 Makefile | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index c5f965e..8eb50d4 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ NAME = None
 
 # Do not:
 # o  use make's built-in rules and variables
-#    (this increases performance and avoid hard-to-debug behavour);
+#    (this increases performance and avoids hard-to-debug behaviour);
 # o  print "Entering directory ...";
 MAKEFLAGS += -rR --no-print-directory
 
@@ -1211,6 +1211,5 @@ FORCE:
 Makefile: ;
 
 # Declare the contents of the .PHONY variable as phony.  We keep that
-# information in a variable se we can use it in if_changed and friends.
+# information in a variable so we can use it in if_changed and friends.
 .PHONY: $(PHONY)
-
-- 
2.1.1



From t.gamez at phytec.de  Fri Oct 31 01:09:10 2014
From: t.gamez at phytec.de (=?UTF-8?q?Teresa=20G=C3=A1mez?=)
Date: Fri, 31 Oct 2014 09:09:10 +0100
Subject: [For next PATCH] boards: defaultenv: Fix nand bootargs for AM335x
 boards.
Message-ID: <1414742950-32650-1-git-send-email-t.gamez@phytec.de>

Update nand bootargs for phyFLEX-AM335x and phyCORE-AM335x
to support modern kernels.

Signed-off-by: Teresa G?mez <t.gamez at phytec.de>
---
 .../boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand    | 2 +-
 .../boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
index d9ef145..1dfbef9 100644
--- a/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
+++ b/arch/arm/boards/phytec-phycore-am335x/defaultenv-phycore-am335x/boot/nand
@@ -5,4 +5,4 @@ global.bootm.image="/dev/nand0.kernel.bb"
 
 bootargs-ip
 
-global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=root rw rootfstype=ubifs"
diff --git a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
index d9ef145..1dfbef9 100644
--- a/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
+++ b/arch/arm/boards/phytec-phyflex-am335x/defaultenv-phyflex-am335x/boot/nand
@@ -5,4 +5,4 @@ global.bootm.image="/dev/nand0.kernel.bb"
 
 bootargs-ip
 
-global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=nand0.root,2048 rw rootfstype=ubifs"
+global.linux.bootargs.dyn.root="root=ubi0:root ubi.mtd=root rw rootfstype=ubifs"
-- 
1.9.1



