From ezequiel at vanguardiasur.com.ar  Sat May  2 09:50:42 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sat, 02 May 2015 13:50:42 -0300
Subject: Regression on next (Re: [PATCH 3/3] driver: Call bus->remove instead
 of driver->remove)
In-Reply-To: <1426573554-14478-3-git-send-email-s.hauer@pengutronix.de>
References: <1426573554-14478-1-git-send-email-s.hauer@pengutronix.de>
 <1426573554-14478-3-git-send-email-s.hauer@pengutronix.de>
Message-ID: <55450062.6050205@vanguardiasur.com.ar>

Hi Sascha,

On 03/17/2015 03:25 AM, Sascha Hauer wrote:
> In devices_shutdown we should call the busses remove function
> which in turn calls the drivers remove function. Otherwise for
> example PCI devices never get removed since they do not have
> a remove function but a pcidev->remove function instead.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/base/driver.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> index 453966b..590c97c 100644
> --- a/drivers/base/driver.c
> +++ b/drivers/base/driver.c
> @@ -399,8 +399,8 @@ void devices_shutdown(void)
>  	struct device_d *dev;
>  
>  	list_for_each_entry(dev, &active, active) {
> -		if (dev->driver->remove)
> -			dev->driver->remove(dev);
> +		if (dev->bus->remove)
> +			dev->bus->remove(dev);
>  	}
>  }
>  
> 

This commit caused a regression on the Openblocks A6 board, which now freezes
when calling devices_shutdown. The problem is that calling bus->remove makes
the remove() of the PHY driver called twice.

This happened because the mdio bus device (mdio-mvebu) was registered first,
and the phy0 device was be registered later, and attached to the mdio bus.

Upon device shutdown, when iterating through the active device list,
the phy0 device is removed before mdio-mvebu. Then, when the mdio bus device
is removed, the phy0 device is removed again, here:

mdio_bus_remove(on mdio-mvebu)
  mvebu_mdio_remove
    mdiobus_unregister
      unregister_device
        mdio_bus_remove(on phy0)
        
This is currently the case for the Kirkwood Openblocks A6 board, where a double
free(dev->cdev.name) in mdio_bus_remove causes a silent freeze when booting
Linux.

I tried something like this:

@@ -446,12 +450,14 @@ const char *dev_id(const struct device_d *dev)
  void devices_shutdown(void)
 {
-	struct device_d *dev;
+	struct device_d *dev, *tmpdev;
+	struct bus_type *bus;
+
+	for_each_bus(bus)
+		list_for_each_entry_safe(dev, tmpdev, &(bus)->device_list, bus_list)
+			if (dev->is_active && dev->bus->remove)
+				dev->bus->remove(dev);
 -	list_for_each_entry(dev, &active, active) {
-		if (dev->bus->remove)
-			dev->bus->remove(dev);
-	}
 }

But then realise this messes the remove order, and so will probably
break some other case :(

--
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From ezequiel at vanguardiasur.com.ar  Sat May  2 09:53:16 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sat, 02 May 2015 13:53:16 -0300
Subject: [PATCH 01/13] net: phy: Support Marvell 88E1318S PHY
In-Reply-To: <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1428627830-17281-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <554500FC.2050607@vanguardiasur.com.ar>

Hi Sebastian,

On 04/09/2015 10:03 PM, Sebastian Hesselbarth wrote:
> This adds support for the Marvell 88E1318S Gigabit Ethernet PHY.
> 
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> ---
> Cc: barebox at lists.infradead.org
> ---
>  drivers/net/phy/marvell.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index aaf9f53451f4..6409f14ae2e2 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -35,6 +35,9 @@
>  #define MII_88E1121_PHY_MSCR_DELAY_MASK	\
>  	(MII_88E1121_PHY_MSCR_RX_DELAY | MII_88E1121_PHY_MSCR_TX_DELAY)
>  
> +#define MII_88E1318S_PHY_MSCR1_REG	16
> +#define MII_88E1318S_PHY_MSCR1_PAD_ODD	BIT(6)
> +
>  #define MII_88E1540_LED_PAGE		0x3
>  #define MII_88E1540_LED_CONTROL		0x10
>  
> @@ -214,6 +217,25 @@ static int m88e1121_config_init(struct phy_device *phydev)
>  	return 0;
>  }
>  
> +static int m88e1318s_config_init(struct phy_device *phydev)
> +{
> +	u16 reg;
> +	int ret;
> +
> +	ret = phy_write(phydev, MII_MARVELL_PHY_PAGE,
> +			MII_88E1121_PHY_MSCR_PAGE);
> +	if (ret < 0)
> +		return ret;
> +
> +	reg = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG);
> +	reg |= MII_88E1318S_PHY_MSCR1_PAD_ODD;
> +	ret = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, reg);
> +	if (ret < 0)
> +		return ret;
> +
> +	return m88e1121_config_init(phydev);
> +}
> +
>  static struct phy_driver marvell_phys[] = {
>  	{
>  		.phy_id		= MARVELL_PHY_ID_88E1121R,
> @@ -225,6 +247,15 @@ static struct phy_driver marvell_phys[] = {
>  		.read_status	= marvell_read_status,
>  	},
>  	{
> +		.phy_id		= MARVELL_PHY_ID_88E1318S,
> +		.phy_id_mask	= MARVELL_PHY_ID_MASK,
> +		.drv.name	= "Marvell 88E1318S",
> +		.features	= PHY_GBIT_FEATURES,
> +		.config_init	= m88e1318s_config_init,
> +		.config_aneg	= genphy_config_aneg,
> +		.read_status	= marvell_read_status,
> +	},
> +	{
>  		.phy_id		= MARVELL_PHY_ID_88E1543,
>  		.phy_id_mask	= MARVELL_PHY_ID_MASK,
>  		.drv.name	= "Marvell 88E1543",
> 

With this commit, the Openblocks A6 PHY is not brought up, and so
network is broken.

I'll look into it (unless you have an idea),
-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From ezequiel at vanguardiasur.com.ar  Sat May  2 13:28:14 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sat, 02 May 2015 17:28:14 -0300
Subject: [PATCH 01/13] net: phy: Support Marvell 88E1318S PHY
In-Reply-To: <554500FC.2050607@vanguardiasur.com.ar>
References: <1428627830-17281-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
 <554500FC.2050607@vanguardiasur.com.ar>
Message-ID: <5545335E.1000700@vanguardiasur.com.ar>



On 05/02/2015 01:53 PM, Ezequiel Garcia wrote:
> Hi Sebastian,
> 
> On 04/09/2015 10:03 PM, Sebastian Hesselbarth wrote:
>> This adds support for the Marvell 88E1318S Gigabit Ethernet PHY.
>>
>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
>> ---
>> Cc: barebox at lists.infradead.org
>> ---
>>  drivers/net/phy/marvell.c | 31 +++++++++++++++++++++++++++++++
>>  1 file changed, 31 insertions(+)
>>
>> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
>> index aaf9f53451f4..6409f14ae2e2 100644
>> --- a/drivers/net/phy/marvell.c
>> +++ b/drivers/net/phy/marvell.c
>> @@ -35,6 +35,9 @@
>>  #define MII_88E1121_PHY_MSCR_DELAY_MASK	\
>>  	(MII_88E1121_PHY_MSCR_RX_DELAY | MII_88E1121_PHY_MSCR_TX_DELAY)
>>  
>> +#define MII_88E1318S_PHY_MSCR1_REG	16
>> +#define MII_88E1318S_PHY_MSCR1_PAD_ODD	BIT(6)
>> +
>>  #define MII_88E1540_LED_PAGE		0x3
>>  #define MII_88E1540_LED_CONTROL		0x10
>>  
>> @@ -214,6 +217,25 @@ static int m88e1121_config_init(struct phy_device *phydev)
>>  	return 0;
>>  }
>>  
>> +static int m88e1318s_config_init(struct phy_device *phydev)
>> +{
>> +	u16 reg;
>> +	int ret;
>> +
>> +	ret = phy_write(phydev, MII_MARVELL_PHY_PAGE,
>> +			MII_88E1121_PHY_MSCR_PAGE);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	reg = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG);
>> +	reg |= MII_88E1318S_PHY_MSCR1_PAD_ODD;
>> +	ret = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, reg);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	return m88e1121_config_init(phydev);
>> +}
>> +
>>  static struct phy_driver marvell_phys[] = {
>>  	{
>>  		.phy_id		= MARVELL_PHY_ID_88E1121R,
>> @@ -225,6 +247,15 @@ static struct phy_driver marvell_phys[] = {
>>  		.read_status	= marvell_read_status,
>>  	},
>>  	{
>> +		.phy_id		= MARVELL_PHY_ID_88E1318S,
>> +		.phy_id_mask	= MARVELL_PHY_ID_MASK,
>> +		.drv.name	= "Marvell 88E1318S",
>> +		.features	= PHY_GBIT_FEATURES,
>> +		.config_init	= m88e1318s_config_init,
>> +		.config_aneg	= genphy_config_aneg,
>> +		.read_status	= marvell_read_status,
>> +	},
>> +	{
>>  		.phy_id		= MARVELL_PHY_ID_88E1543,
>>  		.phy_id_mask	= MARVELL_PHY_ID_MASK,
>>  		.drv.name	= "Marvell 88E1543",
>>
> 
> With this commit, the Openblocks A6 PHY is not brought up, and so
> network is broken.
> 
> I'll look into it (unless you have an idea),
> 

Hm.. the devicetree needs to specify the phy-mode:

diff --git a/dts/src/arm/kirkwood-openblocks_a6.dts b/dts/src/arm/kirkwood-openblocks_a6.dts
index fb9dc22..c53e37f 100644
--- a/dts/src/arm/kirkwood-openblocks_a6.dts
+++ b/dts/src/arm/kirkwood-openblocks_a6.dts
@@ -171,6 +171,7 @@
 &eth0 {
        status = "okay";
        ethernet0-port at 0 {
+               phy-mode = "rgmii-id";
                phy-handle = <&ethphy0>;
        };
 };

However, network works really crappy even after this change (either in barebox or in Linux).
-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From andrew.smirnov at gmail.com  Sat May  2 19:26:12 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:12 -0700
Subject: [RFC, PATCH] i.MX: Add provisions to boot from IRAM
Message-ID: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>

This commit add a very basic code to allow Barebox to be booted from
IRAM. Given that the amount of IRAM on most i.MX variants is
insufficient to contain a copy of Barebox with any reasonable degree
of functionality this code uses IRAM only as a temporary location and
eventually bootstraps from DRAM. But the presense of the intermediate
IRAM-only stage allows to add provisions to test the area of DRAM that
Barebox would be using to facilitate various testing scenarious.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/freescale-mx51-babbage/Makefile    |  3 ++
 .../flash-header-imx51-babbage-xload.imxcfg        | 59 ++++++++++++++++++++++
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c  | 25 +++++++++
 arch/arm/configs/imx_v7-xload_defconfig            | 46 +++++++++++++++++
 arch/arm/mach-imx/Kconfig                          | 15 ++++++
 arch/arm/mach-imx/Makefile                         |  1 +
 arch/arm/mach-imx/xload.c                          | 54 ++++++++++++++++++++
 images/Makefile.imx                                | 20 +++++++-
 8 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
 create mode 100644 arch/arm/configs/imx_v7-xload_defconfig
 create mode 100644 arch/arm/mach-imx/xload.c

diff --git a/arch/arm/boards/freescale-mx51-babbage/Makefile b/arch/arm/boards/freescale-mx51-babbage/Makefile
index 6252c88..31b8fcd 100644
--- a/arch/arm/boards/freescale-mx51-babbage/Makefile
+++ b/arch/arm/boards/freescale-mx51-babbage/Makefile
@@ -1,3 +1,6 @@
 obj-y += board.o flash-header-imx51-babbage.dcd.o
 extra-y += flash-header-imx51-babbage.dcd.S flash-header-imx51-babbage.dcd
 lwl-y += lowlevel.o
+
+obj-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.o
+extra-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.S flash-header-imx51-babbage-xload.dcd
diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
new file mode 100644
index 0000000..a04ac75
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
@@ -0,0 +1,59 @@
+loadaddr CONFIG_ARCH_IMX_UNUSED_IRAM_BASE
+soc imx51
+dcdofs 0x400
+wm 32 0x73fa88a0 0x00000200
+wm 32 0x73fa850c 0x000020c5
+wm 32 0x73fa8510 0x000020c5
+wm 32 0x73fa883c 0x00000002
+wm 32 0x73fa8848 0x00000002
+wm 32 0x73fa84b8 0x000000e7
+wm 32 0x73fa84bc 0x00000045
+wm 32 0x73fa84c0 0x00000045
+wm 32 0x73fa84c4 0x00000045
+wm 32 0x73fa84c8 0x00000045
+wm 32 0x73fa8820 0x00000000
+wm 32 0x73fa84a4 0x00000003
+wm 32 0x73fa84a8 0x00000003
+wm 32 0x73fa84ac 0x000000e3
+wm 32 0x73fa84b0 0x000000e3
+wm 32 0x73fa84b4 0x000000e3
+wm 32 0x73fa84cc 0x000000e3
+wm 32 0x73fa84d0 0x000000e2
+wm 32 0x73fa882c 0x00000004
+wm 32 0x73fa88a4 0x00000004
+wm 32 0x73fa88ac 0x00000004
+wm 32 0x73fa88b8 0x00000004
+wm 32 0x83fd9000 0x82a20000
+wm 32 0x83fd9008 0x82a20000
+wm 32 0x83fd9010 0x000ad0d0
+wm 32 0x83fd9004 0x3f3584ab
+wm 32 0x83fd900c 0x3f3584ab
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x0000801a
+wm 32 0x83fd9014 0x0000801b
+wm 32 0x83fd9014 0x00448019
+wm 32 0x83fd9014 0x07328018
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x06328018
+wm 32 0x83fd9014 0x03808019
+wm 32 0x83fd9014 0x00408019
+wm 32 0x83fd9014 0x00008000
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x0000801e
+wm 32 0x83fd9014 0x0000801f
+wm 32 0x83fd9014 0x0000801d
+wm 32 0x83fd9014 0x0732801c
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x0632801c
+wm 32 0x83fd9014 0x0380801d
+wm 32 0x83fd9014 0x0040801d
+wm 32 0x83fd9014 0x00008004
+wm 32 0x83fd9000 0xb2a20000
+wm 32 0x83fd9008 0xb2a20000
+wm 32 0x83fd9010 0x000ad6d0
+wm 32 0x83fd9034 0x90000000
+wm 32 0x83fd9014 0x00000000
diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index 3bb8614..e308553 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -3,6 +3,7 @@
 #include <common.h>
 #include <mach/esdctl.h>
 #include <mach/generic.h>
+#include <asm/cache.h>
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>

@@ -53,3 +54,27 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)

 	imx51_barebox_entry(fdt);
 }
+
+static noinline void babbage_entry(void)
+{
+	arm_early_mmu_cache_invalidate();
+
+	relocate_to_current_adr();
+	setup_c();
+
+	puts_ll("lowlevel init done\n");
+
+	imx51_barebox_entry(NULL);
+}
+
+ENTRY_FUNCTION(start_imx51_babbage_xload, r0, r1, r2)
+{
+	imx5_cpu_lowlevel_init();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
+	arm_setup_stack(0x20000000 - 16);
+
+	babbage_entry();
+}
diff --git a/arch/arm/configs/imx_v7-xload_defconfig b/arch/arm/configs/imx_v7-xload_defconfig
new file mode 100644
index 0000000..41293fb
--- /dev/null
+++ b/arch/arm/configs/imx_v7-xload_defconfig
@@ -0,0 +1,46 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX_IMXIMAGE=y
+CONFIG_ARCH_IMX_XLOAD=y
+
+CONFIG_ARCH_IMX51=y
+CONFIG_IMX_MULTI_BOARDS=y
+CONFIG_MACH_FREESCALE_MX51_PDK=y
+
+CONFIG_THUMB2_BAREBOX=y
+# CONFIG_CMD_ARM_CPUINFO is not set
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x0
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_DUMMY=y
+CONFIG_RELOCATABLE=y
+CONFIG_BAUDRATE=115200
+CONFIG_SHELL_NONE=y
+
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_IMX51_UART=y
+CONFIG_DEBUG_IMX_UART_PORT=1
+
+CONFIG_HAS_DEBUG_LL=y
+# CONFIG_ERRNO_MESSAGES is not set
+# CONFIG_TIMESTAMP is not set
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+CONFIG_DRIVER_SERIAL_IMX=y
+
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+# CONFIG_MCI_WRITE is not set
+
+CONFIG_MCI_IMX_ESDHC=y
+
+CONFIG_EEPROM_AT25=y
+
+CONFIG_WATCHDOG_IMX_RESET_SOURCE=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_IMX=y
+
+# CONFIG_FS_RAMFS is not set
+# CONFIG_FS_DEVFS is not set
+CONFIG_FS_FAT=y
+CONFIG_BOOTSTRAP=y
+CONFIG_BOOTSTRAP_DISK=y
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c713477..3ccd060 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -68,6 +68,21 @@ config ARCH_IMX_IMXIMAGE
 	help
 	  if enabled the imx-image tool is compiled

+config ARCH_IMX_XLOAD
+	bool
+	depends on ARCH_IMX51
+	prompt "Build preloader image"
+
+config ARCH_IMX_UNUSED_IRAM_BASE
+       hex
+       depends on ARCH_IMX_XLOAD
+       default 0x1ffe2000 if ARCH_IMX51
+
+config ARCH_IMX_UNUSED_IRAM_SIZE
+       hex
+       depends on ARCH_IMX_XLOAD
+       default 0x16000 if ARCH_IMX51
+
 choice
 	depends on ARCH_IMX_INTERNAL_BOOT
 	prompt "Internal boot source"
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index ae953b1..0320d1c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -12,6 +12,7 @@ pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
 obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o
 lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
 obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
+obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_IMX_OCOTP)	+= ocotp.o
 obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/xload.c b/arch/arm/mach-imx/xload.c
new file mode 100644
index 0000000..07d6520
--- /dev/null
+++ b/arch/arm/mach-imx/xload.c
@@ -0,0 +1,54 @@
+#include <bootsource.h>
+#include <bootstrap.h>
+#include <common.h>
+#include <malloc.h>
+#include <init.h>
+#include <envfs.h>
+#include <linux/sizes.h>
+#include <fs.h>
+#include <io.h>
+
+#include <linux/clkdev.h>
+#include <linux/stat.h>
+#include <linux/clk.h>
+
+#include <mach/devices-imx51.h>
+
+static __noreturn int imx_xload(void)
+{
+	enum bootsource bootsource = bootsource_get();
+	void *buf;
+
+	switch (bootsource) {
+	case BOOTSOURCE_MMC:
+		buf = bootstrap_read_disk("disk0.0", "fat");
+		break;
+	default:
+		pr_err("unknown bootsource %d\n", bootsource);
+		hang();
+	}
+
+	if (!buf) {
+		pr_err("failed to load barebox.bin\n");
+		hang();
+	}
+
+	pr_info("starting bootloader...\n");
+
+	bootstrap_boot(buf, 0);
+
+	hang();
+}
+
+static int imx_devices_init(void)
+{
+#ifdef CONFIG_MCI_IMX_ESDHC
+	imx51_add_mmc0(NULL);
+	imx51_add_mmc1(NULL);
+#endif
+
+	barebox_main = imx_xload;
+
+	return 0;
+}
+coredevice_initcall(imx_devices_init);
diff --git a/images/Makefile.imx b/images/Makefile.imx
index 415b294..6b44958 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -4,8 +4,15 @@

 # %.imximg - convert into i.MX image
 # ----------------------------------------------------------------
+
+ifdef CONFIG_ARCH_IMX_XLOAD
+$(obj)/%.imximg: $(obj)/% FORCE
+	$(call cmd,check_file_size,$<,$(CONFIG_ARCH_IMX_UNUSED_IRAM_SIZE))
+	$(call if_changed,imx_image)
+else
 $(obj)/%.imximg: $(obj)/% FORCE
 	$(call if_changed,imx_image)
+endif

 # ----------------------- i.MX25 based boards ---------------------------
 pblx-$(CONFIG_MACH_TX25) += start_imx25_karo_tx25
@@ -29,7 +36,18 @@ image-$(CONFIG_MACH_PCM038) += barebox-phytec-phycore-imx27.img
 pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage
 CFG_start_imx51_babbage.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg
 FILE_barebox-freescale-imx51-babbage.img = start_imx51_babbage.pblx.imximg
-image-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img
+imx-barebox-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img
+
+pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage_xload
+CFG_start_imx51_babbage_xload.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
+FILE_barebox-freescale-imx51-babbage-xload.img = start_imx51_babbage_xload.pblx.imximg
+imx-xload-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage-xload.img
+
+ifdef CONFIG_ARCH_IMX_XLOAD
+image-y += $(imx-xload-y)
+else
+image-y += $(imx-barebox-y)
+endif

 pblx-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += start_imx51_genesi_efikasb
 CFG_start_imx51_genesi_efikasb.pblx.imximg = $(board)/efika-mx-smartbook/flash-header-imx51-genesi-efikasb.imxcfg
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:13 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:13 -0700
Subject: [PATCH 1/8] i.MX: Move UART definitions into a separate file
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-2-git-send-email-andrew.smirnov@gmail.com>

Move UART definitions into a separate file to avoid redefinition in
<mach/debug_ll.h> and magical constants in low level UART
initialization code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h |   9 +--
 arch/arm/mach-imx/include/mach/serial.h   | 112 ++++++++++++++++++++++++++++++
 drivers/serial/serial_imx.c               | 108 +---------------------------
 3 files changed, 114 insertions(+), 115 deletions(-)
 create mode 100644 arch/arm/mach-imx/include/mach/serial.h

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index f34eaa1..1c9f3a6 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -12,6 +12,7 @@
 #include <mach/imx51-regs.h>
 #include <mach/imx53-regs.h>
 #include <mach/imx6-regs.h>
+#include <mach/serial.h>

 #ifdef CONFIG_DEBUG_LL

@@ -40,14 +41,6 @@
 #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
 #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)

-#define URTX0		0x40		/* Transmitter Register */
-
-#define UCR1		0x80		/* Control Register 1 */
-#define UCR1_UARTEN	(1 << 0)	/* UART enabled */
-
-#define USR2		0x98		/* Status Register 2 */
-#define USR2_TXDC	(1 << 3)	/* Transmitter complete */
-
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
diff --git a/arch/arm/mach-imx/include/mach/serial.h b/arch/arm/mach-imx/include/mach/serial.h
new file mode 100644
index 0000000..b999c58
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/serial.h
@@ -0,0 +1,112 @@
+#ifndef __MACH_SERIAL_H__
+#define __MACH_SERIAL_H__
+
+#define URXD0	0x0	/* Receiver Register */
+#define URTX0	0x40	/* Transmitter Register */
+#define UCR1	0x80	/* Control Register 1 */
+#define UCR2	0x84	/* Control Register 2 */
+#define UCR3	0x88	/* Control Register 3 */
+#define UCR4	0x8c	/* Control Register 4 */
+#define UFCR	0x90	/* FIFO Control Register */
+#define USR1	0x94	/* Status Register 1 */
+#define USR2	0x98	/* Status Register 2 */
+#define UESC	0x9c	/* Escape Character Register */
+#define UTIM	0xa0	/* Escape Timer Register */
+#define UBIR	0xa4	/* BRM Incremental Register */
+#define UBMR	0xa8	/* BRM Modulator Register */
+#define UBRC	0xac	/* Baud Rate Count Register */
+
+/* UART Control Register Bit Fields.*/
+#define  URXD_CHARRDY    (1<<15)
+#define  URXD_ERR        (1<<14)
+#define  URXD_OVRRUN     (1<<13)
+#define  URXD_FRMERR     (1<<12)
+#define  URXD_BRK        (1<<11)
+#define  URXD_PRERR      (1<<10)
+#define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
+#define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
+#define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
+#define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
+#define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
+#define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
+#define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
+#define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
+#define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
+#define  UCR1_SNDBRK     (1<<4)	 /* Send break */
+#define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
+#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
+#define  UCR1_DOZE       (1<<1)	 /* Doze */
+#define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
+#define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
+#define  UCR2_IRTS  	 (1<<14) /* Ignore RTS pin */
+#define  UCR2_CTSC  	 (1<<13) /* CTS pin control */
+#define  UCR2_CTS        (1<<12) /* Clear to send */
+#define  UCR2_ESCEN      (1<<11) /* Escape enable */
+#define  UCR2_PREN       (1<<8)  /* Parity enable */
+#define  UCR2_PROE       (1<<7)  /* Parity odd/even */
+#define  UCR2_STPB       (1<<6)	 /* Stop */
+#define  UCR2_WS         (1<<5)	 /* Word size */
+#define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
+#define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
+#define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
+#define  UCR2_SRST 	 (1<<0)	 /* SW reset */
+#define  UCR3_DTREN 	 (1<<13) /* DTR interrupt enable */
+#define  UCR3_PARERREN   (1<<12) /* Parity enable */
+#define  UCR3_FRAERREN   (1<<11) /* Frame error interrupt enable */
+#define  UCR3_DSR        (1<<10) /* Data set ready */
+#define  UCR3_DCD        (1<<9)  /* Data carrier detect */
+#define  UCR3_RI         (1<<8)  /* Ring indicator */
+#define  UCR3_ADNIMP     (1<<7)  /* Autobaud Detection Not Improved */
+#define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
+#define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
+#define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
+#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz (i.MXL / i.MX1) */
+#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz (i.MXL / i.MX1) */
+#define  UCR3_RXDMUXSEL  (1<<2)  /* RXD Muxed input select (i.MX27) */
+#define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
+#define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
+#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
+#define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
+#define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
+#define  UCR4_REF16 	 (1<<6)  /* Ref freq 16 MHz */
+#define  UCR4_IRSC  	 (1<<5)  /* IR special case */
+#define  UCR4_TCEN  	 (1<<3)  /* Transmit complete interrupt enable */
+#define  UCR4_BKEN  	 (1<<2)  /* Break condition interrupt enable */
+#define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */
+#define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
+#define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
+#define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
+#define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
+#define  USR1_RTSS  	 (1<<14) /* RTS pin status */
+#define  USR1_TRDY  	 (1<<13) /* Transmitter ready interrupt/dma flag */
+#define  USR1_RTSD  	 (1<<12) /* RTS delta */
+#define  USR1_ESCF  	 (1<<11) /* Escape seq interrupt flag */
+#define  USR1_FRAMERR    (1<<10) /* Frame error interrupt flag */
+#define  USR1_RRDY       (1<<9)	 /* Receiver ready interrupt/dma flag */
+#define  USR1_TIMEOUT    (1<<7)	 /* Receive timeout interrupt status */
+#define  USR1_RXDS  	 (1<<6)	 /* Receiver idle interrupt flag */
+#define  USR1_AIRINT	 (1<<5)	 /* Async IR wake interrupt flag */
+#define  USR1_AWAKE 	 (1<<4)	 /* Aysnc wake interrupt flag */
+#define  USR2_ADET  	 (1<<15) /* Auto baud rate detect complete */
+#define  USR2_TXFE  	 (1<<14) /* Transmit buffer FIFO empty */
+#define  USR2_DTRF  	 (1<<13) /* DTR edge interrupt flag */
+#define  USR2_IDLE  	 (1<<12) /* Idle condition */
+#define  USR2_IRINT 	 (1<<8)	 /* Serial infrared interrupt flag */
+#define  USR2_WAKE  	 (1<<7)	 /* Wake */
+#define  USR2_RTSF  	 (1<<4)	 /* RTS edge interrupt flag */
+#define  USR2_TXDC  	 (1<<3)	 /* Transmitter complete */
+#define  USR2_BRCD  	 (1<<2)	 /* Break condition */
+#define  USR2_ORE        (1<<1)	 /* Overrun error */
+#define  USR2_RDR        (1<<0)	 /* Recv data ready */
+#define  UTS_FRCPERR	 (1<<13) /* Force parity error */
+#define  UTS_LOOP        (1<<12) /* Loop tx and rx */
+#define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
+#define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
+#define  UTS_TXFULL 	 (1<<4)	 /* TxFIFO full */
+#define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
+#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
+
+
+#endif	/* __MACH_SERIAL_H__ */
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index cd954c2..e197be8 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -23,113 +23,7 @@
 #include <of.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-
-#define URXD0	0x0	/* Receiver Register */
-#define URTX0	0x40	/* Transmitter Register */
-#define UCR1	0x80	/* Control Register 1 */
-#define UCR2	0x84	/* Control Register 2 */
-#define UCR3	0x88	/* Control Register 3 */
-#define UCR4	0x8c	/* Control Register 4 */
-#define UFCR	0x90	/* FIFO Control Register */
-#define USR1	0x94	/* Status Register 1 */
-#define USR2	0x98	/* Status Register 2 */
-#define UESC	0x9c	/* Escape Character Register */
-#define UTIM	0xa0	/* Escape Timer Register */
-#define UBIR	0xa4	/* BRM Incremental Register */
-#define UBMR	0xa8	/* BRM Modulator Register */
-#define UBRC	0xac	/* Baud Rate Count Register */
-
-/* UART Control Register Bit Fields.*/
-#define  URXD_CHARRDY    (1<<15)
-#define  URXD_ERR        (1<<14)
-#define  URXD_OVRRUN     (1<<13)
-#define  URXD_FRMERR     (1<<12)
-#define  URXD_BRK        (1<<11)
-#define  URXD_PRERR      (1<<10)
-#define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
-#define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
-#define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
-#define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
-#define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
-#define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
-#define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
-#define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
-#define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
-#define  UCR1_SNDBRK     (1<<4)	 /* Send break */
-#define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
-#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
-#define  UCR1_DOZE       (1<<1)	 /* Doze */
-#define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
-#define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
-#define  UCR2_IRTS  	 (1<<14) /* Ignore RTS pin */
-#define  UCR2_CTSC  	 (1<<13) /* CTS pin control */
-#define  UCR2_CTS        (1<<12) /* Clear to send */
-#define  UCR2_ESCEN      (1<<11) /* Escape enable */
-#define  UCR2_PREN       (1<<8)  /* Parity enable */
-#define  UCR2_PROE       (1<<7)  /* Parity odd/even */
-#define  UCR2_STPB       (1<<6)	 /* Stop */
-#define  UCR2_WS         (1<<5)	 /* Word size */
-#define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
-#define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
-#define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
-#define  UCR2_SRST 	 (1<<0)	 /* SW reset */
-#define  UCR3_DTREN 	 (1<<13) /* DTR interrupt enable */
-#define  UCR3_PARERREN   (1<<12) /* Parity enable */
-#define  UCR3_FRAERREN   (1<<11) /* Frame error interrupt enable */
-#define  UCR3_DSR        (1<<10) /* Data set ready */
-#define  UCR3_DCD        (1<<9)  /* Data carrier detect */
-#define  UCR3_RI         (1<<8)  /* Ring indicator */
-#define  UCR3_ADNIMP     (1<<7)  /* Autobaud Detection Not Improved */
-#define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
-#define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
-#define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
-#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz (i.MXL / i.MX1) */
-#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz (i.MXL / i.MX1) */
-#define  UCR3_RXDMUXSEL  (1<<2)  /* RXD Muxed input select (i.MX27) */
-#define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
-#define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
-#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
-#define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
-#define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
-#define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
-#define  UCR4_REF16 	 (1<<6)  /* Ref freq 16 MHz */
-#define  UCR4_IRSC  	 (1<<5)  /* IR special case */
-#define  UCR4_TCEN  	 (1<<3)  /* Transmit complete interrupt enable */
-#define  UCR4_BKEN  	 (1<<2)  /* Break condition interrupt enable */
-#define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */
-#define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
-#define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
-#define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
-#define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
-#define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
-#define  USR1_RTSS  	 (1<<14) /* RTS pin status */
-#define  USR1_TRDY  	 (1<<13) /* Transmitter ready interrupt/dma flag */
-#define  USR1_RTSD  	 (1<<12) /* RTS delta */
-#define  USR1_ESCF  	 (1<<11) /* Escape seq interrupt flag */
-#define  USR1_FRAMERR    (1<<10) /* Frame error interrupt flag */
-#define  USR1_RRDY       (1<<9)	 /* Receiver ready interrupt/dma flag */
-#define  USR1_TIMEOUT    (1<<7)	 /* Receive timeout interrupt status */
-#define  USR1_RXDS  	 (1<<6)	 /* Receiver idle interrupt flag */
-#define  USR1_AIRINT	 (1<<5)	 /* Async IR wake interrupt flag */
-#define  USR1_AWAKE 	 (1<<4)	 /* Aysnc wake interrupt flag */
-#define  USR2_ADET  	 (1<<15) /* Auto baud rate detect complete */
-#define  USR2_TXFE  	 (1<<14) /* Transmit buffer FIFO empty */
-#define  USR2_DTRF  	 (1<<13) /* DTR edge interrupt flag */
-#define  USR2_IDLE  	 (1<<12) /* Idle condition */
-#define  USR2_IRINT 	 (1<<8)	 /* Serial infrared interrupt flag */
-#define  USR2_WAKE  	 (1<<7)	 /* Wake */
-#define  USR2_RTSF  	 (1<<4)	 /* RTS edge interrupt flag */
-#define  USR2_TXDC  	 (1<<3)	 /* Transmitter complete */
-#define  USR2_BRCD  	 (1<<2)	 /* Break condition */
-#define  USR2_ORE        (1<<1)	 /* Overrun error */
-#define  USR2_RDR        (1<<0)	 /* Recv data ready */
-#define  UTS_FRCPERR	 (1<<13) /* Force parity error */
-#define  UTS_LOOP        (1<<12) /* Loop tx and rx */
-#define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
-#define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
-#define  UTS_TXFULL 	 (1<<4)	 /* TxFIFO full */
-#define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
-#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
+#include <mach/serial.h>

 /*
  * create default values for different platforms
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:14 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:14 -0700
Subject: [PATCH 2/8] i.MX: serial: Add constants for UART clock divisor
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-3-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/serial.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-imx/include/mach/serial.h b/arch/arm/mach-imx/include/mach/serial.h
index b999c58..3890fd5 100644
--- a/arch/arm/mach-imx/include/mach/serial.h
+++ b/arch/arm/mach-imx/include/mach/serial.h
@@ -77,6 +77,13 @@
 #define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
 #define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
 #define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV6	  (0b000<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV5	  (0b001<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV4	  (0b010<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV3	  (0b011<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV2	  (0b100<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV1	  (0b101<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV7	  (0b110<<7)  /* Reference freq divider mask */
 #define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
 #define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
 #define  USR1_RTSS  	 (1<<14) /* RTS pin status */
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:15 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:15 -0700
Subject: [PATCH 3/8] i.MX: serial: Add baud rate calculation convenience
 functions
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-4-git-send-email-andrew.smirnov@gmail.com>

Add two functions to calculate values for UBMR and UBIR
registers. This way both early serial initalization code and
serial_imx.c can use them and not duplicate the code.

Singed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/serial.h | 9 +++++++++
 drivers/serial/serial_imx.c             | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/serial.h b/arch/arm/mach-imx/include/mach/serial.h
index 3890fd5..212eeeb 100644
--- a/arch/arm/mach-imx/include/mach/serial.h
+++ b/arch/arm/mach-imx/include/mach/serial.h
@@ -115,5 +115,14 @@
 #define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
 #define  UTS_SOFTRST	 (1<<0)	 /* Software reset */

+static inline int baudrate_to_ubir(int baudrate)
+{
+	return baudrate / 100 - 1;
+}
+
+static inline int refclock_to_ubmr(int clock_hz)
+{
+	return clock_hz / 1600 - 1;
+}

 #endif	/* __MACH_SERIAL_H__ */
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index e197be8..8c4e829 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -178,9 +178,9 @@ static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate)
 	writel(val, regs + UCR1);

 	/* Set the numerator value minus one of the BRM ratio */
-	writel((baudrate / 100) - 1, regs + UBIR);
+	writel(baudrate_to_ubir(baudrate), regs + UBIR);
 	/* Set the denominator value minus one of the BRM ratio    */
-	writel((imx_serial_reffreq(priv) / 1600) - 1, regs + UBMR);
+	writel(refclock_to_ubmr(imx_serial_reffreq(priv)), regs + UBMR);

 	writel(ucr1, regs + UCR1);

--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:16 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:16 -0700
Subject: [PATCH 4/8] i.MX51: babbage: Implement CONFIG_DEBUG_LL
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-5-git-send-email-andrew.smirnov@gmail.com>

Implement bits of configuraion needed to configure early debug output
support.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c | 58 +++++++++++++++++++++++
 arch/arm/mach-imx/include/mach/clock-imx51_53.h   |  5 +-
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index 0f453f3..0135cb4 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -1,9 +1,63 @@
+#include <debug_ll.h>
+#include <mach/clock-imx51_53.h>
 #include <common.h>
 #include <mach/esdctl.h>
 #include <mach/generic.h>
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>

+#ifdef CONFIG_DEBUG_LL
+static inline void setup_uart(void)
+{
+
+	void __iomem *uartbase =
+	  (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
+				CONFIG_DEBUG_IMX_UART_PORT);
+	void __iomem *iomuxbase = (void *)MX51_IOMUXC_BASE_ADDR;
+	void __iomem *ccmbase = (void *)MX51_CCM_BASE_ADDR;
+
+	/*
+	 * Restore CCM values that might be changed by the Mask ROM
+	 * code.
+	 *
+	 * Source: RealView debug scripts provided by Freescale
+	 */
+	writel(MX5_CCM_CBCDR_RESET_VALUE,  ccmbase + MX5_CCM_CBCDR);
+	writel(MX5_CCM_CSCMR1_RESET_VALUE, ccmbase + MX5_CCM_CSCMR1);
+	writel(MX5_CCM_CSCDR1_RESET_VALUE, ccmbase + MX5_CCM_CSCDR1);
+
+	/*
+	 * The code below should be more or less a "moral equivalent"
+	 * of:
+	 *	 MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+	 *
+	 * in device tree
+	 */
+	writel(0x00000000, iomuxbase + 0x022c);
+	writel(0x000001c5, iomuxbase + 0x061c);
+
+	writel(0x00000000, uartbase + UCR1);
+
+	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
+	       uartbase + UCR2);
+	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
+	       uartbase + UCR3);
+	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
+	       uartbase + UFCR);
+
+	writel(baudrate_to_ubir(115200), uartbase + UBIR);
+	writel(refclock_to_ubmr(54000000), uartbase + UBMR);
+
+	writel(UCR1_UARTEN, uartbase + UCR1);
+
+	putc_ll('>');
+}
+#else
+static inline void setup_uart(void)
+{
+}
+#endif	/* CONFIG_DEBUG_LL */
+
 extern char __dtb_imx51_babbage_start[];

 ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)
@@ -11,6 +65,10 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)
 	void *fdt;

 	imx5_cpu_lowlevel_init();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
 	arm_setup_stack(0x20000000 - 16);

 	fdt = __dtb_imx51_babbage_start - get_runtime_offset();
diff --git a/arch/arm/mach-imx/include/mach/clock-imx51_53.h b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
index 6004a6d..0f25dfb 100644
--- a/arch/arm/mach-imx/include/mach/clock-imx51_53.h
+++ b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
@@ -149,6 +149,7 @@
 #define MX5_CCM_CACRR_ARM_PODF_MASK	(0x7)

 /* Define the bits in register CBCDR */
+#define MX5_CCM_CBCDR_RESET_VALUE		(0x19239145)
 #define MX5_CCM_CBCDR_EMI_CLK_SEL		(0x1 << 26)
 #define MX5_CCM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
 #define MX5_CCM_CBCDR_DDR_HF_SEL_OFFSET		(30)
@@ -193,6 +194,7 @@
 #define MX5_CCM_CBCMR_PERCLK_IPG_CLK_SEL	(0x1 << 0)

 /* Define the bits in register CSCMR1 */
+#define MX5_CCM_CSCMR1_RESET_VALUE			(0xa6a2a020)
 #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET		(30)
 #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK		(0x3 << 30)
 #define MX5_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET		(28)
@@ -259,6 +261,7 @@
 #define MX5_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK		(0x3)

 /* Define the bits in register CSCDR1 */
+#define MX5_CCM_CSCDR1_RESET_VALUE			(0x00c30318)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET	(22)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK	(0x7 << 22)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET	(19)
@@ -585,5 +588,3 @@
 #define MX5_SRPGC_EMI_PDNSCR	(MX5_SRPGC_EMI_BASE + 0x8)

 #endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
-
-
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:17 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:17 -0700
Subject: [PATCH 5/8] i.MX: serial: Add setup_uart_ll function
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-6-git-send-email-andrew.smirnov@gmail.com>

It appears that all i.MX based boards that support early debug output
inevitably do exactly the same thing with the registers of the UART
peripheral. So to avoid code duplication distill that functionality
into dedicated subroutine.

IMPORTANT: Please note that 'setup_uart_ll' function does add a slight
difference in behaviour by dropping the initialization of ONEMS and
UESC registers since those do not seem to be needed for early UART
functionality

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h | 34 +++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index 1c9f3a6..5b0b33b 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -30,10 +30,12 @@
 #define IMX_DEBUG_SOC MX35
 #elif defined CONFIG_DEBUG_IMX51_UART
 #define IMX_DEBUG_SOC MX51
+#define IMX_DEBUG_UART_REFCLOCK_HZ 54000000
 #elif defined CONFIG_DEBUG_IMX53_UART
 #define IMX_DEBUG_SOC MX53
 #elif defined CONFIG_DEBUG_IMX6Q_UART
 #define IMX_DEBUG_SOC MX6
+#define IMX_DEBUG_UART_REFCLOCK_HZ 80000000
 #else
 #error "unknown i.MX debug uart soc type"
 #endif
@@ -41,6 +43,34 @@
 #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
 #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)

+
+#if defined IMX_DEBUG_UART_REFCLOCK_HZ
+
+static inline void setup_uart_ll(void)
+{
+	void __iomem *uartbase =
+	  (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
+				CONFIG_DEBUG_IMX_UART_PORT);
+
+	writel(0x00000000, uartbase + UCR1);
+
+	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
+	       uartbase + UCR2);
+	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
+	       uartbase + UCR3);
+	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
+	       uartbase + UFCR);
+
+	writel(baudrate_to_ubir(CONFIG_BAUDRATE),
+	       uartbase + UBIR);
+	writel(refclock_to_ubmr(IMX_DEBUG_UART_REFCLOCK_HZ),
+	       uartbase + UBMR);
+
+	writel(UCR1_UARTEN, uartbase + UCR1);
+}
+
+#endif
+
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
@@ -56,5 +86,9 @@ static inline void PUTC_LL(int c)

 	writel(c, base + URTX0);
 }
+#else
+static inline void setup_uart_ll(void)
+{
+}
 #endif /* CONFIG_DEBUG_LL */
 #endif /* __MACH_DEBUG_LL_H__ */
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:18 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:18 -0700
Subject: [PATCH 6/8] i.MX: serial: Convert i.MX51 and i.MX6 to use
 'setup_uart_ll'
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-7-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---

Two boards -- 'guf-santaro' and 'eltec-hipercam' -- were not
converted to use this function because they enable low-level UART
regardless of the value of CONFIG_DEGUG_LL and so converting them to
'setup_uart_ll' would change the behaviour of the image build with
'imx_v7_defconfig'. Should those boards be converted to respect
CONFIG_DEBUG_LL?

Boards 'karo-tx25' and 'tqma53' could be converted but weren't because
I don't have any i.MX25 or i.MX53 based hardware to test on.


 arch/arm/boards/embest-riotboard/lowlevel.c        | 16 +--------------
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c  | 24 +---------------------
 .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c | 11 +---------
 arch/arm/boards/karo-tx6x/lowlevel.c               | 11 +---------
 arch/arm/boards/phytec-phycard-imx6/lowlevel.c     | 11 +---------
 arch/arm/boards/phytec-phyflex-imx6/lowlevel.c     | 11 +---------
 arch/arm/boards/tqma53/lowlevel.c                  | 16 +--------------
 arch/arm/boards/tqma6x/lowlevel.c                  | 18 ++--------------
 arch/arm/boards/variscite-mx6/lowlevel.c           | 11 +---------
 9 files changed, 10 insertions(+), 119 deletions(-)

diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c
index fe21b9a..ccd1a97 100644
--- a/arch/arm/boards/embest-riotboard/lowlevel.c
+++ b/arch/arm/boards/embest-riotboard/lowlevel.c
@@ -10,20 +10,6 @@
 #include <mach/imx6-mmdc.h>
 #include <mach/imx6.h>

-static inline void setup_uart(void)
-{
-	/* Enable UART for lowlevel debugging purposes */
-	writel(0x00000000, 0x021e8080);
-	writel(0x00004027, 0x021e8084);
-	writel(0x00000704, 0x021e8088);
-	writel(0x00000a81, 0x021e8090);
-	writel(0x0000002b, 0x021e809c);
-	writel(0x00013880, 0x021e80b0);
-	writel(0x0000047f, 0x021e80a4);
-	writel(0x0000c34f, 0x021e80a8);
-	writel(0x00000001, 0x021e8080);
-}
-
 extern char __dtb_imx6s_riotboard_start[];

 ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2)
@@ -34,7 +20,7 @@ ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2)

 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x4, 0x020e016c);
-		setup_uart();
+		setup_uart_ll();
 		putc_ll('a');
 	}

diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index 0135cb4..3bb8614 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -6,13 +6,8 @@
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>

-#ifdef CONFIG_DEBUG_LL
 static inline void setup_uart(void)
 {
-
-	void __iomem *uartbase =
-	  (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
-				CONFIG_DEBUG_IMX_UART_PORT);
 	void __iomem *iomuxbase = (void *)MX51_IOMUXC_BASE_ADDR;
 	void __iomem *ccmbase = (void *)MX51_CCM_BASE_ADDR;

@@ -36,27 +31,10 @@ static inline void setup_uart(void)
 	writel(0x00000000, iomuxbase + 0x022c);
 	writel(0x000001c5, iomuxbase + 0x061c);

-	writel(0x00000000, uartbase + UCR1);
-
-	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
-	       uartbase + UCR2);
-	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
-	       uartbase + UCR3);
-	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
-	       uartbase + UFCR);
-
-	writel(baudrate_to_ubir(115200), uartbase + UBIR);
-	writel(refclock_to_ubmr(54000000), uartbase + UBMR);
-
-	writel(UCR1_UARTEN, uartbase + UCR1);
+	setup_uart_ll();

 	putc_ll('>');
 }
-#else
-static inline void setup_uart(void)
-{
-}
-#endif	/* CONFIG_DEBUG_LL */

 extern char __dtb_imx51_babbage_start[];

diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
index 4c5a74e..a8d16cb 100644
--- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
@@ -22,7 +22,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0xffffffff, ccmbase + 0x68);
@@ -38,15 +37,7 @@ static inline void setup_uart(void)
 	writel(0x0, iomuxbase + 0x28);
 	writel(0x1b0b1, iomuxbase + 0x0370);

-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000784, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x0001b0b0, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	setup_uart_ll();

 	putc_ll('>');
 }
diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c
index cd4be5e..3f9fb23 100644
--- a/arch/arm/boards/karo-tx6x/lowlevel.c
+++ b/arch/arm/boards/karo-tx6x/lowlevel.c
@@ -23,7 +23,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x1, iomuxbase + 0x0314);
@@ -39,15 +38,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);

-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000784, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x0001b0b0, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	setup_uart_ll();

 	putc_ll('>');
 }
diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
index dc10649..1d48818 100644
--- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
@@ -27,7 +27,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR);
-	void __iomem *uartbase = IOMEM(MX6_UART3_BASE_ADDR);
 	void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);

 	writel(0x4, iomuxbase + 0x01f8);
@@ -40,15 +39,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);

-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	setup_uart_ll();

 	putc_ll('>');
 }
diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
index ee6d7fb..367d4dc 100644
--- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
@@ -28,7 +28,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART4_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x4, iomuxbase + 0x01f8);
@@ -41,15 +40,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);

-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	setup_uart_ll();

 	putc_ll('>');
 }
diff --git a/arch/arm/boards/tqma53/lowlevel.c b/arch/arm/boards/tqma53/lowlevel.c
index 4e129e4..f3eb1ad 100644
--- a/arch/arm/boards/tqma53/lowlevel.c
+++ b/arch/arm/boards/tqma53/lowlevel.c
@@ -10,26 +10,12 @@

 extern char __dtb_imx53_mba53_start[];

-static inline void setup_uart(void __iomem *base)
-{
-	/* Enable UART for lowlevel debugging purposes */
-	writel(0x00000000, base + 0x80);
-	writel(0x00004027, base + 0x84);
-	writel(0x00000704, base + 0x88);
-	writel(0x00000a81, base + 0x90);
-	writel(0x0000002b, base + 0x9c);
-	writel(0x0001046a, base + 0xb0);
-	writel(0x0000047f, base + 0xa4);
-	writel(0x0000a2c1, base + 0xa8);
-	writel(0x00000001, base + 0x80);
-}
-
 static void __noreturn start_imx53_tqma53_common(void *fdt)
 {
 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x3, MX53_IOMUXC_BASE_ADDR + 0x278);
 		writel(0x3, MX53_IOMUXC_BASE_ADDR + 0x27c);
-		setup_uart((void *)MX53_UART2_BASE_ADDR);
+		setup_uart_ll();
 		putc_ll('>');
 	}

diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c
index 23f3407..1de60d8 100644
--- a/arch/arm/boards/tqma6x/lowlevel.c
+++ b/arch/arm/boards/tqma6x/lowlevel.c
@@ -24,20 +24,6 @@
 #include <mach/imx6-mmdc.h>
 #include <mach/imx6.h>

-static inline void setup_uart(void)
-{
-	/* Enable UART for lowlevel debugging purposes */
-	writel(0x00000000, 0x021e8080);
-	writel(0x00004027, 0x021e8084);
-	writel(0x00000704, 0x021e8088);
-	writel(0x00000a81, 0x021e8090);
-	writel(0x0000002b, 0x021e809c);
-	writel(0x00013880, 0x021e80b0);
-	writel(0x0000047f, 0x021e80a4);
-	writel(0x0000c34f, 0x021e80a8);
-	writel(0x00000001, 0x021e8080);
-}
-
 extern char __dtb_imx6q_mba6x_start[];
 extern char __dtb_imx6dl_mba6x_start[];

@@ -51,7 +37,7 @@ ENTRY_FUNCTION(start_imx6q_mba6x, r0, r1, r2)

 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x2, 0x020e0338);
-		setup_uart();
+		setup_uart_ll();
 		putc_ll('a');
 	}

@@ -72,7 +58,7 @@ ENTRY_FUNCTION(start_imx6dl_mba6x, r0, r1, r2)

 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x2, 0x020e035c);
-		setup_uart();
+		setup_uart_ll();
 		putc_ll('a');
 	}

diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c
index 22e7eae..b0ab424 100644
--- a/arch/arm/boards/variscite-mx6/lowlevel.c
+++ b/arch/arm/boards/variscite-mx6/lowlevel.c
@@ -29,7 +29,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x03, iomuxbase + 0x0280);
@@ -43,15 +42,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);

-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	setup_uart_ll();

 	putc_ll('>');
 }
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:20 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:20 -0700
Subject: [PATCH 8/8] Makefile.lib: Make 'check_file_size' more flexible
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-9-git-send-email-andrew.smirnov@gmail.com>

Make 'check_file_size' more flexible by not hardcoding the file whose
size is going to be checked to '$@'. This way it is possible to use
this subroutine to check the size of files other than the target of
the rule.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 Makefile               | 2 +-
 arch/arm/pbl/Makefile  | 2 +-
 arch/mips/pbl/Makefile | 2 +-
 scripts/Makefile.lib   | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 372d18a..9ed0a1d 100644
--- a/Makefile
+++ b/Makefile
@@ -700,7 +700,7 @@ OBJCOPYFLAGS_barebox.bin = -O binary
 barebox.bin: barebox FORCE
 	$(call if_changed,objcopy)
 ifndef CONFIG_PBL_IMAGE
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 endif

 # By default the uImage load address is 2MB below CONFIG_TEXT_BASE,
diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile
index 4c1788d..1ff39db 100644
--- a/arch/arm/pbl/Makefile
+++ b/arch/arm/pbl/Makefile
@@ -22,7 +22,7 @@ endif

 $(obj)/zbarebox.bin:	$(obj)/zbarebox FORCE
 	$(call if_changed,objcopy)
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 	$(Q)$(kecho) '  Barebox: fix size'
 	$(Q)$(objtree)/scripts/fix_size -i -f $(objtree)/$@ $(FIX_SIZE)
 	$(Q)$(kecho) '  Barebox: $@ is ready'
diff --git a/arch/mips/pbl/Makefile b/arch/mips/pbl/Makefile
index fea1f24..b03bca1 100644
--- a/arch/mips/pbl/Makefile
+++ b/arch/mips/pbl/Makefile
@@ -15,7 +15,7 @@ extra-y       += piggy.gzip piggy.lz4 piggy.lzo piggy.lzma piggy.xzkern piggy.sh

 $(obj)/zbarebox.bin:	$(obj)/zbarebox FORCE
 	$(call if_changed,objcopy)
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 	$(Q)$(kecho) '  Barebox: $@ is ready'

 $(obj)/zbarebox.S: $(obj)/zbarebox FORCE
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 57426d0..e991f33 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -388,10 +388,10 @@ quiet_cmd_ln = LN      $@
 cmd_ln = ln -sf $< $@

 # Check size of a file
-quiet_cmd_check_file_size = CHKSIZE $@
+quiet_cmd_check_file_size = CHKSIZE $2
       cmd_check_file_size = set -e;					\
-	size=`stat -c%s $@`;						\
-	max_size=`printf "%d" $2`;					\
+	size=`stat -c%s $2`;						\
+	max_size=`printf "%d" $3`;					\
 	if [ $$size -gt $$max_size ] ;					\
 	then								\
 		echo "$@ size $$size > of the maximum size $$max_size" >&2;	\
--
2.1.4


From andrew.smirnov at gmail.com  Sat May  2 19:26:19 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat,  2 May 2015 19:26:19 -0700
Subject: [PATCH 7/8] i.MX: serial: Distil common clock ungating code
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430619980-26243-8-git-send-email-andrew.smirnov@gmail.com>

Move all of the common clock ungating code in early UART
initialization into a dedicated subroutine that can be shared by all
of the users.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  9 +--------
 arch/arm/boards/karo-tx6x/lowlevel.c                | 10 +---------
 arch/arm/boards/phytec-phycard-imx6/lowlevel.c      | 10 +---------
 arch/arm/boards/phytec-phyflex-imx6/lowlevel.c      | 10 +---------
 arch/arm/boards/variscite-mx6/lowlevel.c            | 10 +---------
 arch/arm/mach-imx/include/mach/debug_ll.h           | 17 +++++++++++++++++
 6 files changed, 22 insertions(+), 44 deletions(-)

diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
index a8d16cb..fd154df 100644
--- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
@@ -21,16 +21,9 @@

 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
+	ungate_all_peripherals();

 	writel(0x0, iomuxbase + 0x24);
 	writel(0x1b0b1, iomuxbase + 0x036C);
diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c
index 3f9fb23..d7087f5 100644
--- a/arch/arm/boards/karo-tx6x/lowlevel.c
+++ b/arch/arm/boards/karo-tx6x/lowlevel.c
@@ -22,7 +22,6 @@

 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x1, iomuxbase + 0x0314);
@@ -30,14 +29,7 @@ static inline void setup_uart(void)
 	writel(0x1, iomuxbase + 0x0330);
 	writel(0x1, iomuxbase + 0x032c);

-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	ungate_all_peripherals();
 	setup_uart_ll();

 	putc_ll('>');
diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
index 1d48818..c8306ec 100644
--- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
@@ -26,19 +26,11 @@

 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR);
 	void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);

 	writel(0x4, iomuxbase + 0x01f8);

-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	ungate_all_peripherals();
 	setup_uart_ll();

 	putc_ll('>');
diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
index 367d4dc..46f788c 100644
--- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
@@ -27,19 +27,11 @@

 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x4, iomuxbase + 0x01f8);

-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	ungate_all_peripherals();
 	setup_uart_ll();

 	putc_ll('>');
diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c
index b0ab424..01878e6 100644
--- a/arch/arm/boards/variscite-mx6/lowlevel.c
+++ b/arch/arm/boards/variscite-mx6/lowlevel.c
@@ -28,20 +28,12 @@

 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;

 	writel(0x03, iomuxbase + 0x0280);
 	writel(0x03, iomuxbase + 0x0284);

-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	ungate_all_peripherals();
 	setup_uart_ll();

 	putc_ll('>');
diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index 5b0b33b..d831a7d 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -3,6 +3,7 @@

 #include <io.h>
 #include <config.h>
+#include <common.h>
 #include <mach/imx1-regs.h>
 #include <mach/imx21-regs.h>
 #include <mach/imx25-regs.h>
@@ -71,6 +72,18 @@ static inline void setup_uart_ll(void)

 #endif

+#define __IMX_CCM_BASE(soc) soc##_CCM_BASE_ADDR
+#define IMX_CCM_BASE(soc) __IMX_CCM_BASE(soc)
+
+static inline void ungate_all_peripherals(void)
+{
+	int i;
+	void __iomem *ccmbase = IOMEM(IMX_CCM_BASE(IMX_DEBUG_SOC));
+
+	for (i = 0x68; i <= 0x80; i += 4)
+		writel(0xffffffff, ccmbase + i);
+}
+
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
@@ -90,5 +103,9 @@ static inline void PUTC_LL(int c)
 static inline void setup_uart_ll(void)
 {
 }
+
+static inline void ungate_all_peripherals(void)
+{
+}
 #endif /* CONFIG_DEBUG_LL */
 #endif /* __MACH_DEBUG_LL_H__ */
--
2.1.4


From sebastian.hesselbarth at gmail.com  Sun May  3 02:50:28 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Sun, 03 May 2015 11:50:28 +0200
Subject: [PATCH 01/13] net: phy: Support Marvell 88E1318S PHY
In-Reply-To: <5545335E.1000700@vanguardiasur.com.ar>
References: <1428627830-17281-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
 <554500FC.2050607@vanguardiasur.com.ar>
 <5545335E.1000700@vanguardiasur.com.ar>
Message-ID: <5545EF64.4050107@gmail.com>

On 02.05.2015 22:28, Ezequiel Garcia wrote:
> On 05/02/2015 01:53 PM, Ezequiel Garcia wrote:
>> On 04/09/2015 10:03 PM, Sebastian Hesselbarth wrote:
>>> This adds support for the Marvell 88E1318S Gigabit Ethernet PHY.
>>>
>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
[...]
>>
>> With this commit, the Openblocks A6 PHY is not brought up, and so
>> network is broken.
>>
>> I'll look into it (unless you have an idea),
>>
>
> Hm.. the devicetree needs to specify the phy-mode:
>
> diff --git a/dts/src/arm/kirkwood-openblocks_a6.dts b/dts/src/arm/kirkwood-openblocks_a6.dts
> index fb9dc22..c53e37f 100644
> --- a/dts/src/arm/kirkwood-openblocks_a6.dts
> +++ b/dts/src/arm/kirkwood-openblocks_a6.dts
> @@ -171,6 +171,7 @@
>   &eth0 {
>          status = "okay";
>          ethernet0-port at 0 {
> +               phy-mode = "rgmii-id";
>                  phy-handle = <&ethphy0>;
>          };
>   };
>
> However, network works really crappy even after this change (either in barebox or in Linux).

Ezequiel,

RGMII phy-mode would have been my first guess.

Can you define "crappy"  with respect to ethernet?

The patch doesn't do anything different than the linux marvell phy
code would do. Do you have access to A6's u-boot source and can match
up the PHY init sequence?

Sebastian


From r.schwebel at pengutronix.de  Sun May  3 10:55:10 2015
From: r.schwebel at pengutronix.de (Robert Schwebel)
Date: Sun,  3 May 2015 19:55:10 +0200
Subject: [PATCH] Documentation: booting linux: improve doc text
Message-ID: <1430675710-11568-1-git-send-email-r.schwebel@pengutronix.de>

Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
---
 Documentation/user/booting-linux.rst | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 5ef1254..ad32907 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -55,12 +55,13 @@ to free the internal devicetree before calling ``bootm``
 Passing Kernel Arguments
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-Depending on the barebox configuration (``CONFIG_FLEXIBLE_BOOTARGS``) there
-are to ways to pass bootargs to the Kernel. With ``CONFIG_FLEXIBLE_BOOTARGS``
-disabled the bootm command takes the bootargs from the ``bootargs`` environment
-variable. With ``CONFIG_FLEXIBLE_BOOTARGS`` enabled the bootargs are composed
-from different :ref:`global_device` variables. All variables beginning with
-``global.linux.bootargs.`` will be concatenated to the bootargs:
+The simple method to pass bootargs to the kernel is with
+``CONFIG_FLEXIBLE_BOOTARGS`` disabled: in this case the bootm command
+takes the bootargs from the ``bootargs`` environment variable.
+
+With ``CONFIG_FLEXIBLE_BOOTARGS`` enabled, the bootargs are composed
+from different :ref:`global device<global_device>` variables. All variables beginning
+with ``global.linux.bootargs.`` will be concatenated to the bootargs:
 
 .. code-block:: sh
 
-- 
2.1.4



From andrew.smirnov at gmail.com  Sun May  3 13:13:12 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:12 -0700
Subject: [PATCH 1/8] Makefile.lib: Fix i.MX image size after generation
Message-ID: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>

If called with '-b' option 'imx-image' tool prepends barebox header to
the image, but the tool does not fill the data at image size offset
correctly. Call 'fix_size', right after 'imx-image' to fix that.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 scripts/Makefile.lib | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e991f33..c140d16 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -431,7 +431,8 @@ imximg-tmp = $(subst $(comma),_,$(dot-target).imxcfg.tmp)

 quiet_cmd_imx_image = IMX-IMG $@
       cmd_imx_image = $(CPP) $(imxcfg_cpp_flags) -o $(imximg-tmp) $(CFG_$(@F)) ; \
-		      $(objtree)/scripts/imx/imx-image -o $@ -b -c $(imximg-tmp) -f $<
+		      $(objtree)/scripts/imx/imx-image -o $@ -b -c $(imximg-tmp) -f $<; \
+		      $(objtree)/scripts/fix_size -f $@

 quiet_cmd_kwb_image = KWB     $@
       cmd_kwb_image = scripts/kwbimage -p $< $(OPTS_$(@F)) -o $@
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:13 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:13 -0700
Subject: [PATCH 2/8] bootstrap: Fix potential memory leak in 'read_image_head'
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-2-git-send-email-andrew.smirnov@gmail.com>

Original version of 'read_image_head' would not free the memory
allocated for barebox header in cases of any failure. Fix this by
adding a dedicated resourse de-allocation code path.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 704680a..82c7d21 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -35,7 +35,7 @@ static void *read_image_head(const char *name)
 	cdev = cdev_open(name, O_RDONLY);
 	if (!cdev) {
 		bootstrap_err("failed to open partition\n");
-		return NULL;
+		goto free_header;
 	}

 	ret = cdev_read(cdev, header, BAREBOX_HEAD_SIZE, 0, 0);
@@ -43,10 +43,14 @@ static void *read_image_head(const char *name)

 	if (ret != BAREBOX_HEAD_SIZE) {
 		bootstrap_err("failed to read from partition\n");
-		return NULL;
+		goto free_header;
 	}

 	return header;
+
+free_header:
+	free(header);
+	return NULL;
 }

 static unsigned int get_image_size(void *head)
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:14 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:14 -0700
Subject: [PATCH 3/8] bootstrap_read_devfs(): Check for errors from
 devfs_add_partition()
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-3-git-send-email-andrew.smirnov@gmail.com>

Check for errors returned by devfs_add_partition() and bail if there
are any.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 82c7d21..de274a0 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -82,10 +82,17 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	int ret;
 	int size = 0;
 	void *to, *header;
-	struct cdev *cdev;
+	struct cdev *cdev, partition;
 	char *partname = "x";

-	devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname);
+	partition = devfs_add_partition(devname, offset, max_size,
+					DEVFS_PARTITION_FIXED, partname);
+	if (IS_ERR_OR_NULL(partition)) {
+		bootstrap_err("%s: failed to add partition (%ld)\n",
+			      devname, PTR_ERR(partition));
+		return NULL;
+	}
+
 	if (use_bb) {
 		dev_add_bb_dev(partname, "bbx");
 		partname = "bbx";
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:15 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:15 -0700
Subject: [PATCH 4/8] bootstrap_read_devfs(): Close file after we are done with
 it
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-4-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index de274a0..4176819 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -120,6 +120,8 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	}

 	ret = cdev_read(cdev, to, size, 0, 0);
+	cdev_close(cdev);
+
 	if (ret != size) {
 		bootstrap_err("%s: failed to read from %s\n", devname, partname);
 		return NULL;
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:16 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:16 -0700
Subject: [PATCH 5/8] bootstrap_read_devfs(): Fix potential memory leak
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-5-git-send-email-andrew.smirnov@gmail.com>

In case of a failure in one of the cdev_* functions original version
of bootstrap_read_devfs would not release memory allocated for barebox
header or memory allocated for the image. This commit fixes this by
adding resource deallocation code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 4176819..f7f91d6 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -81,7 +81,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 {
 	int ret;
 	int size = 0;
-	void *to, *header;
+	void *to, *header, *result = NULL;
 	struct cdev *cdev, partition;
 	char *partname = "x";

@@ -116,16 +116,21 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	cdev = cdev_open(partname, O_RDONLY);
 	if (!cdev) {
 		bootstrap_err("%s: failed to open %s\n", devname, partname);
-		return NULL;
+		goto free_memory;
 	}

 	ret = cdev_read(cdev, to, size, 0, 0);
 	cdev_close(cdev);

-	if (ret != size) {
+	if (ret != size)
 		bootstrap_err("%s: failed to read from %s\n", devname, partname);
-		return NULL;
-	}
+	else
+		result = to;
+
+free_memory:
+	free(header);
+	if (!result)
+		free(to);

-	return to;
+	return result;
 }
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:17 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:17 -0700
Subject: [PATCH 6/8] bootstrap_read_devfs(): Check for errors from
 dev_add_bb_dev()
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-6-git-send-email-andrew.smirnov@gmail.com>

Check for errors returned by dev_add_bb_dev() and bail if there
are any.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index f7f91d6..359981e 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -94,7 +94,14 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	}

 	if (use_bb) {
-		dev_add_bb_dev(partname, "bbx");
+		ret = dev_add_bb_dev(partname, "bbx");
+		if (ret) {
+			bootstrap_err(
+				"%s: failed to add bad block aware partition (%d)\n",
+				devname, ret);
+			goto exit;
+		}
+
 		partname = "bbx";
 	}

@@ -131,6 +138,6 @@ free_memory:
 	free(header);
 	if (!result)
 		free(to);
-
+exit:
 	return result;
 }
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:18 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:18 -0700
Subject: [PATCH 7/8] bootstrap_read_devfs(): Remove all partitions upon
 function completion
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-7-git-send-email-andrew.smirnov@gmail.com>

Bootstrap_read_devfs does not remove the devices it creates during the
course of its execution which might be considered as a resource
leak. Remedy that by adding the code to remove those devices upon
function completion.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 359981e..d7b5185 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -99,7 +99,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 			bootstrap_err(
 				"%s: failed to add bad block aware partition (%d)\n",
 				devname, ret);
-			goto exit;
+			goto delete_devfs_partition;
 		}

 		partname = "bbx";
@@ -138,6 +138,15 @@ free_memory:
 	free(header);
 	if (!result)
 		free(to);
+
+	if (use_bb) {
+		dev_remove_bb_dev(partname);
+		partname = "x";
+	}
+
+delete_devfs_partition:
+	devfs_del_partition(partname);
+
 exit:
 	return result;
 }
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 13:13:19 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 13:13:19 -0700
Subject: [PATCH 8/8] bootstrap: Warn if image size in BB header is zero
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430683999-5910-8-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index d7b5185..d071eb3 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -58,8 +58,12 @@ static unsigned int get_image_size(void *head)
 	unsigned int ret = 0;
 	unsigned int *psize = head + BAREBOX_HEAD_SIZE_OFFSET;

-	if (is_barebox_head(head))
+	if (is_barebox_head(head)) {
 		ret = *psize;
+		if (!ret)
+			bootstrap_err(
+				"image has correct magic, but the length is zero\n");
+	}
 	debug("Detected barebox image size %u\n", ret);

 	return ret;
--
2.1.4


From mkl at pengutronix.de  Sun May  3 13:28:43 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sun, 3 May 2015 22:28:43 +0200
Subject: [PATCH 1/8] Makefile.lib: Fix i.MX image size after generation
In-Reply-To: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <554684FB.9090707@pengutronix.de>

On 05/03/2015 10:13 PM, Andrey Smirnov wrote:
> If called with '-b' option 'imx-image' tool prepends barebox header to
> the image, but the tool does not fill the data at image size offset
> correctly. Call 'fix_size', right after 'imx-image' to fix that.

What about fixing the tool instead? The imx-image tool in used
imx-habv4, too, see images/Makefile.imxhabv4.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150503/4ca90353/attachment.sig>

From andrew.smirnov at gmail.com  Sun May  3 14:49:06 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun, 3 May 2015 14:49:06 -0700
Subject: [PATCH 1/8] Makefile.lib: Fix i.MX image size after generation
In-Reply-To: <554684FB.9090707@pengutronix.de>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
 <554684FB.9090707@pengutronix.de>
Message-ID: <CAHQ1cqHNQASC5+xZ-Fb46nC_2_vQO4Ee6Vdn9r_4U-K-99XxLQ@mail.gmail.com>

On Sun, May 3, 2015 at 1:28 PM, Marc Kleine-Budde <mkl at pengutronix.de> wrote:
> On 05/03/2015 10:13 PM, Andrey Smirnov wrote:
>> If called with '-b' option 'imx-image' tool prepends barebox header to
>> the image, but the tool does not fill the data at image size offset
>> correctly. Call 'fix_size', right after 'imx-image' to fix that.
>
> What about fixing the tool instead? The imx-image tool in used
> imx-habv4, too, see images/Makefile.imxhabv4.
>

I wasn't sure what would be the most appropriate way to fix this, so I
chose the path of a least resistance. But now that I know that the
tool is used in multiple places -- I agree -- it makes more sense to
fix the problem at its root. I will send the updated patch shortly.

Andrey

> Marc
>
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
>


From andrew.smirnov at gmail.com  Sun May  3 14:55:22 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 14:55:22 -0700
Subject: [PATCH v2 1/8] imx-image: Correctly fill image size in prepended
 header
Message-ID: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>

If called with '-b' option 'imx-image' tool prepends barebox header to
the image, but the tool does not fill the data at image size offset
correctly. Fix that.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---

This patch supercedes the one sent earlier titled:
 "[PATCH 1/8] Makefile.lib: Fix i.MX image size after generation"

 scripts/imx/Makefile    |  2 ++
 scripts/imx/imx-image.c | 12 ++++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
index be0b490..ee0acc1 100644
--- a/scripts/imx/Makefile
+++ b/scripts/imx/Makefile
@@ -6,5 +6,7 @@ always          := $(hostprogs-y)
 HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
 HOSTLOADLIBES_imx-usb-loader  = `pkg-config --libs libusb-1.0`

+HOSTCFLAGS_imx-image.o = -I$(srctree)
+
 imx-usb-loader-objs := imx-usb-loader.o
 imx-image-objs := imx-image.o
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 25ea4d8..c0181df 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -27,6 +27,8 @@
 #include <fcntl.h>
 #include <endian.h>

+#include <include/filetype.h>
+
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
@@ -92,8 +94,11 @@ static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imag
 	struct imx_flash_header *hdr;
 	int dcdsize = curdcd * sizeof(uint32_t);

-	if (add_barebox_header)
+	if (add_barebox_header) {
+		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
 		memcpy(buf, bb_header, sizeof(bb_header));
+		*psize = imagesize;
+	}

 	buf += offset;
 	hdr = buf;
@@ -178,8 +183,11 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag
 	struct imx_flash_header_v2 *hdr;
 	int dcdsize = curdcd * sizeof(uint32_t);

-	if (add_barebox_header)
+	if (add_barebox_header) {
+		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
 		memcpy(buf, bb_header, sizeof(bb_header));
+		*psize = imagesize;
+	}

 	buf += offset;
 	hdr = buf;
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 14:55:23 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 14:55:23 -0700
Subject: [PATCH v2 3/8] bootstrap_read_devfs(): Check for errors from
 devfs_add_partition()
In-Reply-To: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430690125-2257-2-git-send-email-andrew.smirnov@gmail.com>

Check for errors returned by devfs_add_partition() and bail if there
are any.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---

Changes since v1:

 - Fix a compile time error that snuck in during the time the diff was
   being split into multiple patches

 lib/bootstrap/devfs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 82c7d21..ff0540f 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -82,10 +82,17 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	int ret;
 	int size = 0;
 	void *to, *header;
-	struct cdev *cdev;
+	struct cdev *cdev, *partition;
 	char *partname = "x";

-	devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname);
+	partition = devfs_add_partition(devname, offset, max_size,
+					DEVFS_PARTITION_FIXED, partname);
+	if (IS_ERR_OR_NULL(partition)) {
+		bootstrap_err("%s: failed to add partition (%ld)\n",
+			      devname, PTR_ERR(partition));
+		return NULL;
+	}
+
 	if (use_bb) {
 		dev_add_bb_dev(partname, "bbx");
 		partname = "bbx";
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 14:55:24 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 14:55:24 -0700
Subject: [PATCH v2 5/8] bootstrap_read_devfs(): Fix potential memory leak
In-Reply-To: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430690125-2257-3-git-send-email-andrew.smirnov@gmail.com>

In case of a failure in one of the cdev_* functions original version
of bootstrap_read_devfs would not release memory allocated for barebox
header or memory allocated for the image. This commit fixes this by
adding resource deallocation code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---

Changes since v1:

 - Fix a compile time error that snuck in during the time the diff was
   being split into multiple patches

 lib/bootstrap/devfs.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 3c4276f..05a6346 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -81,7 +81,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 {
 	int ret;
 	int size = 0;
-	void *to, *header;
+	void *to, *header, *result = NULL;
 	struct cdev *cdev, *partition;
 	char *partname = "x";

@@ -116,16 +116,21 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	cdev = cdev_open(partname, O_RDONLY);
 	if (!cdev) {
 		bootstrap_err("%s: failed to open %s\n", devname, partname);
-		return NULL;
+		goto free_memory;
 	}

 	ret = cdev_read(cdev, to, size, 0, 0);
 	cdev_close(cdev);

-	if (ret != size) {
+	if (ret != size)
 		bootstrap_err("%s: failed to read from %s\n", devname, partname);
-		return NULL;
-	}
+	else
+		result = to;
+
+free_memory:
+	free(header);
+	if (!result)
+		free(to);

-	return to;
+	return result;
 }
--
2.1.4


From andrew.smirnov at gmail.com  Sun May  3 14:55:25 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun,  3 May 2015 14:55:25 -0700
Subject: [PATCH v2 7/8] bootstrap_read_devfs(): Remove all partitions upon
 function completion
In-Reply-To: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430690125-2257-4-git-send-email-andrew.smirnov@gmail.com>

Bootstrap_read_devfs does not remove the devices it creates during the
course of its execution which might be considered as a resource
leak. Remedy that by adding the code to remove those devices upon
function completion.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---

Changes since v1:

 - Fix a compile time error that snuck in during the time the diff was
   being split into multiple patches

 lib/bootstrap/devfs.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index df4840e..e9bd2bb 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -99,7 +99,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 			bootstrap_err(
 				"%s: failed to add bad block aware partition (%d)\n",
 				devname, ret);
-			goto exit;
+			goto delete_devfs_partition;
 		}

 		partname = "bbx";
@@ -138,6 +138,14 @@ free_memory:
 	free(header);
 	if (!result)
 		free(to);
-exit:
+
+	if (use_bb) {
+		dev_remove_bb_dev(partname);
+		partname = "x";
+	}
+
+delete_devfs_partition:
+	devfs_del_partition(partname);
+
 	return result;
 }
--
2.1.4


From mkl at pengutronix.de  Sun May  3 15:05:43 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 4 May 2015 00:05:43 +0200
Subject: [PATCH v2 1/8] imx-image: Correctly fill image size in prepended
 header
In-Reply-To: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <55469BB7.9070708@pengutronix.de>

On 05/03/2015 11:55 PM, Andrey Smirnov wrote:
> If called with '-b' option 'imx-image' tool prepends barebox header to
> the image, but the tool does not fill the data at image size offset
> correctly. Fix that.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
> 
> This patch supercedes the one sent earlier titled:
>  "[PATCH 1/8] Makefile.lib: Fix i.MX image size after generation"
> 
>  scripts/imx/Makefile    |  2 ++
>  scripts/imx/imx-image.c | 12 ++++++++++--
>  2 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
> index be0b490..ee0acc1 100644
> --- a/scripts/imx/Makefile
> +++ b/scripts/imx/Makefile
> @@ -6,5 +6,7 @@ always          := $(hostprogs-y)
>  HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
>  HOSTLOADLIBES_imx-usb-loader  = `pkg-config --libs libusb-1.0`
> 
> +HOSTCFLAGS_imx-image.o = -I$(srctree)
> +
>  imx-usb-loader-objs := imx-usb-loader.o
>  imx-image-objs := imx-image.o
> diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
> index 25ea4d8..c0181df 100644
> --- a/scripts/imx/imx-image.c
> +++ b/scripts/imx/imx-image.c
> @@ -27,6 +27,8 @@
>  #include <fcntl.h>
>  #include <endian.h>
> 
> +#include <include/filetype.h>
> +
>  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
>  #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
>  #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
> @@ -92,8 +94,11 @@ static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imag
>  	struct imx_flash_header *hdr;
>  	int dcdsize = curdcd * sizeof(uint32_t);
> 
> -	if (add_barebox_header)
> +	if (add_barebox_header) {
> +		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
>  		memcpy(buf, bb_header, sizeof(bb_header));
> +		*psize = imagesize;
> +	}
> 
>  	buf += offset;
>  	hdr = buf;
> @@ -178,8 +183,11 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag
>  	struct imx_flash_header_v2 *hdr;
>  	int dcdsize = curdcd * sizeof(uint32_t);
> 
> -	if (add_barebox_header)
> +	if (add_barebox_header) {
> +		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
>  		memcpy(buf, bb_header, sizeof(bb_header));
> +		*psize = imagesize;
> +	}

In the HAB case, the resulting image will be CSF_LEN bytes bigger, see:
"if (prepare_sign)" below. (A signature + padding will be appended to
the barebox image.)

What does the size in the barebox header mean exactly?

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150504/488324ca/attachment-0001.sig>

From mkl at pengutronix.de  Sun May  3 15:34:20 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 4 May 2015 00:34:20 +0200
Subject: [PATCH v2 1/8] imx-image: Correctly fill image size in prepended
 header
In-Reply-To: <CAHQ1cqEoL1PD4Cg7G52YvosXmsmcg1jckGL9-65_J-=qHc3XvA@mail.gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
 <55469BB7.9070708@pengutronix.de>
 <CAHQ1cqEoL1PD4Cg7G52YvosXmsmcg1jckGL9-65_J-=qHc3XvA@mail.gmail.com>
Message-ID: <5546A26C.6020204@pengutronix.de>

On 05/04/2015 12:24 AM, Andrey Smirnov wrote:
[...]
>> > @@ -178,8 +183,11 @@ static int add_header_v2(void *buf, int offset,
> uint32_t loadaddr, uint32_t imag
>> >       struct imx_flash_header_v2 *hdr;
>> >       int dcdsize = curdcd * sizeof(uint32_t);
>> >
>> > -     if (add_barebox_header)
>> > +     if (add_barebox_header) {
>> > +             uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
>> >               memcpy(buf, bb_header, sizeof(bb_header));
>> > +             *psize = imagesize;
>> > +     }
>>
>> In the HAB case, the resulting image will be CSF_LEN bytes bigger, see:
>> "if (prepare_sign)" below. (A signature + padding will be appended to
>> the barebox image.)
>>
>> What does the size in the barebox header mean exactly?
> 
> I am not aware of all the use-cases, but one of them is in bootstrap
> code where the value of that field is used to determine the size of an
> image to be read from a raw character device.
> 
> Is that information(CSF) needed by barebox itself and not only mask ROM
> code? If not I think there would be no harm in not including those bytes
> in the length field.

When booting the imx6 in HAB mode from SPI-NOR (my usecase for now), the
ROM code sets up the RAM according to the DCD table, copies everything
into the RAM (hdr->boot_data.start hdr->boot_data.size) does some crypto
magic and jumps into the entry point. I think the first 1k if the image
is copied, maybe check summed, but otherwise ignored.

You can move the if (add_barebox_header) block below the if
(prepare_sign) and use hdr->boot_data.size.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150504/76b108ea/attachment.sig>

From sebastian.hesselbarth at gmail.com  Sun May  3 15:47:13 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 04 May 2015 00:47:13 +0200
Subject: [PATCH 01/13] net: phy: Support Marvell 88E1318S PHY
In-Reply-To: <5545EF64.4050107@gmail.com>
References: <1428627830-17281-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
 <554500FC.2050607@vanguardiasur.com.ar>
 <5545335E.1000700@vanguardiasur.com.ar> <5545EF64.4050107@gmail.com>
Message-ID: <5546A571.1000006@gmail.com>

On 03.05.2015 11:50, Sebastian Hesselbarth wrote:
> On 02.05.2015 22:28, Ezequiel Garcia wrote:
>> On 05/02/2015 01:53 PM, Ezequiel Garcia wrote:
>>> On 04/09/2015 10:03 PM, Sebastian Hesselbarth wrote:
>>>> This adds support for the Marvell 88E1318S Gigabit Ethernet PHY.
>>>>
>>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> [...]
>>>
>>> With this commit, the Openblocks A6 PHY is not brought up, and so
>>> network is broken.
>>>
>>> I'll look into it (unless you have an idea),
>>>
>>
>> Hm.. the devicetree needs to specify the phy-mode:
>>
>> diff --git a/dts/src/arm/kirkwood-openblocks_a6.dts
>> b/dts/src/arm/kirkwood-openblocks_a6.dts
>> index fb9dc22..c53e37f 100644
>> --- a/dts/src/arm/kirkwood-openblocks_a6.dts
>> +++ b/dts/src/arm/kirkwood-openblocks_a6.dts
>> @@ -171,6 +171,7 @@
>>   &eth0 {
>>          status = "okay";
>>          ethernet0-port at 0 {
>> +               phy-mode = "rgmii-id";
>>                  phy-handle = <&ethphy0>;
>>          };
>>   };
>>
>> However, network works really crappy even after this change (either in
>> barebox or in Linux).
>
> Ezequiel,
>
> RGMII phy-mode would have been my first guess.
>
> Can you define "crappy"  with respect to ethernet?
>
> The patch doesn't do anything different than the linux marvell phy
> code would do. Do you have access to A6's u-boot source and can match
> up the PHY init sequence?

Maybe we need some 1V8 RGMII setup for A6 too?

https://lkml.org/lkml/2015/5/3/159

It also uses 88e1318 PHY but on A370 and on Kirkwood we also have
IO Configuration 0 register 0xf10100e0, bit 7:
RGMII PADS Voltage, 0 = 3V3, 1 = 1V8

Maybe you double-check it on u-boot first?

Sebastian


From s.hauer at pengutronix.de  Sun May  3 23:29:19 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 08:29:19 +0200
Subject: Regression on next (Re: [PATCH 3/3] driver: Call bus->remove
 instead of driver->remove)
In-Reply-To: <55450062.6050205@vanguardiasur.com.ar>
References: <1426573554-14478-1-git-send-email-s.hauer@pengutronix.de>
 <1426573554-14478-3-git-send-email-s.hauer@pengutronix.de>
 <55450062.6050205@vanguardiasur.com.ar>
Message-ID: <20150504062919.GF6325@pengutronix.de>

Hi Ezequiel,

On Sat, May 02, 2015 at 01:50:42PM -0300, Ezequiel Garcia wrote:
> Hi Sascha,
> 
> On 03/17/2015 03:25 AM, Sascha Hauer wrote:
> > In devices_shutdown we should call the busses remove function
> > which in turn calls the drivers remove function. Otherwise for
> > example PCI devices never get removed since they do not have
> > a remove function but a pcidev->remove function instead.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/base/driver.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> > index 453966b..590c97c 100644
> > --- a/drivers/base/driver.c
> > +++ b/drivers/base/driver.c
> > @@ -399,8 +399,8 @@ void devices_shutdown(void)
> >  	struct device_d *dev;
> >  
> >  	list_for_each_entry(dev, &active, active) {
> > -		if (dev->driver->remove)
> > -			dev->driver->remove(dev);
> > +		if (dev->bus->remove)
> > +			dev->bus->remove(dev);
> >  	}
> >  }
> >  
> > 
> 
> This commit caused a regression on the Openblocks A6 board, which now freezes
> when calling devices_shutdown. The problem is that calling bus->remove makes
> the remove() of the PHY driver called twice.
> 
> This happened because the mdio bus device (mdio-mvebu) was registered first,
> and the phy0 device was be registered later, and attached to the mdio bus.
> 
> Upon device shutdown, when iterating through the active device list,
> the phy0 device is removed before mdio-mvebu. Then, when the mdio bus device
> is removed, the phy0 device is removed again, here:
> 
> mdio_bus_remove(on mdio-mvebu)
>   mvebu_mdio_remove
>     mdiobus_unregister
>       unregister_device
>         mdio_bus_remove(on phy0)
>         
> This is currently the case for the Kirkwood Openblocks A6 board, where a double
> free(dev->cdev.name) in mdio_bus_remove causes a silent freeze when booting
> Linux.

Too bad that happened. I believe the following fixes this, but I have no
hardware to test this on. Could you give this a test? I'll delay the
outstanding release until this is solved.

Sascha

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

>From 15422e3435b0151f1b5d753b19a8578210da9d04 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer at pengutronix.de>
Date: Mon, 4 May 2015 08:16:20 +0200
Subject: [PATCH] net: phy: Do not double remove phy device

This fixes: 80264a8 driver: Call bus->remove instead of driver->remove

On mvebu it happens that:

Upon device shutdown, when iterating through the active device list,
the phy0 device is removed before mdio-mvebu. Then, when the mdio bus
device is removed, the phy0 device is removed again, here:

mdio_bus_remove(on mdio-mvebu)
  mvebu_mdio_remove
    mdiobus_unregister
      unregister_device
        mdio_bus_remove(on phy0)

Fix this by setting the mdio busses phy_map[phy->addr] to NULL when
unregistering the phy device, so that mdiobus_unregister no longer
finds a valid phy_device when iterating over the busses device list.

Reported-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/net/phy/mdio_bus.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index f526cfc..0959c45 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -331,12 +331,14 @@ static void mdio_bus_remove(struct device_d *_dev)
 {
 	struct phy_device *dev = to_phy_device(_dev);
 	struct phy_driver *drv = to_phy_driver(_dev->driver);
+	struct mii_bus *bus = dev->bus;
 
 	if (drv->remove)
 		drv->remove(dev);
 
 	free(dev->cdev.name);
 	devfs_remove(&dev->cdev);
+	bus->phy_map[dev->addr] = NULL;
 }
 
 struct bus_type mdio_bus_type = {
-- 
2.1.4

-- 
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 May  3 23:43:41 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 08:43:41 +0200
Subject: [PATCH 4/8] i.MX51: babbage: Implement CONFIG_DEBUG_LL
In-Reply-To: <1430619980-26243-5-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-5-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504064341.GG6325@pengutronix.de>

On Sat, May 02, 2015 at 07:26:16PM -0700, Andrey Smirnov wrote:
> Implement bits of configuraion needed to configure early debug output
> support.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/boards/freescale-mx51-babbage/lowlevel.c | 58 +++++++++++++++++++++++
>  arch/arm/mach-imx/include/mach/clock-imx51_53.h   |  5 +-
>  2 files changed, 61 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> index 0f453f3..0135cb4 100644
> --- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> +++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> @@ -1,9 +1,63 @@
> +#include <debug_ll.h>
> +#include <mach/clock-imx51_53.h>
>  #include <common.h>
>  #include <mach/esdctl.h>
>  #include <mach/generic.h>
>  #include <asm/barebox-arm-head.h>
>  #include <asm/barebox-arm.h>
> 
> +#ifdef CONFIG_DEBUG_LL
> +static inline void setup_uart(void)
> +{
> +
> +	void __iomem *uartbase =
> +	  (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
> +				CONFIG_DEBUG_IMX_UART_PORT);
> +	void __iomem *iomuxbase = (void *)MX51_IOMUXC_BASE_ADDR;
> +	void __iomem *ccmbase = (void *)MX51_CCM_BASE_ADDR;
> +
> +	/*
> +	 * Restore CCM values that might be changed by the Mask ROM
> +	 * code.
> +	 *
> +	 * Source: RealView debug scripts provided by Freescale
> +	 */
> +	writel(MX5_CCM_CBCDR_RESET_VALUE,  ccmbase + MX5_CCM_CBCDR);
> +	writel(MX5_CCM_CSCMR1_RESET_VALUE, ccmbase + MX5_CCM_CSCMR1);
> +	writel(MX5_CCM_CSCDR1_RESET_VALUE, ccmbase + MX5_CCM_CSCDR1);
> +
> +	/*
> +	 * The code below should be more or less a "moral equivalent"
> +	 * of:
> +	 *	 MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
> +	 *
> +	 * in device tree
> +	 */
> +	writel(0x00000000, iomuxbase + 0x022c);
> +	writel(0x000001c5, iomuxbase + 0x061c);
> +
> +	writel(0x00000000, uartbase + UCR1);
> +
> +	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
> +	       uartbase + UCR2);
> +	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
> +	       uartbase + UCR3);
> +	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
> +	       uartbase + UFCR);
> +
> +	writel(baudrate_to_ubir(115200), uartbase + UBIR);
> +	writel(refclock_to_ubmr(54000000), uartbase + UBMR);
> +
> +	writel(UCR1_UARTEN, uartbase + UCR1);

This is more generic than what I usually do when setting up the UART for
lowlevel debug. I usually hardcode the UBIR/UBMR values in board code.
>From the above we could create a

static inline void imx_uart_init(int reffreq)

int arch/arm/mach-imx/include/mach/debug_ll.h. What do you think?

Sascha

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


From s.hauer at pengutronix.de  Sun May  3 23:53:21 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 08:53:21 +0200
Subject: [PATCH 5/8] i.MX: serial: Add setup_uart_ll function
In-Reply-To: <1430619980-26243-6-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-6-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504065321.GH6325@pengutronix.de>

On Sat, May 02, 2015 at 07:26:17PM -0700, Andrey Smirnov wrote:
> It appears that all i.MX based boards that support early debug output
> inevitably do exactly the same thing with the registers of the UART
> peripheral. So to avoid code duplication distill that functionality
> into dedicated subroutine.
> 
> IMPORTANT: Please note that 'setup_uart_ll' function does add a slight
> difference in behaviour by dropping the initialization of ONEMS and
> UESC registers since those do not seem to be needed for early UART
> functionality
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/mach-imx/include/mach/debug_ll.h | 34 +++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
> index 1c9f3a6..5b0b33b 100644
> --- a/arch/arm/mach-imx/include/mach/debug_ll.h
> +++ b/arch/arm/mach-imx/include/mach/debug_ll.h
> @@ -30,10 +30,12 @@
>  #define IMX_DEBUG_SOC MX35
>  #elif defined CONFIG_DEBUG_IMX51_UART
>  #define IMX_DEBUG_SOC MX51
> +#define IMX_DEBUG_UART_REFCLOCK_HZ 54000000
>  #elif defined CONFIG_DEBUG_IMX53_UART
>  #define IMX_DEBUG_SOC MX53
>  #elif defined CONFIG_DEBUG_IMX6Q_UART
>  #define IMX_DEBUG_SOC MX6
> +#define IMX_DEBUG_UART_REFCLOCK_HZ 80000000
>  #else
>  #error "unknown i.MX debug uart soc type"
>  #endif
> @@ -41,6 +43,34 @@
>  #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
>  #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
> 
> +
> +#if defined IMX_DEBUG_UART_REFCLOCK_HZ
> +
> +static inline void setup_uart_ll(void)
> +{
> +	void __iomem *uartbase =
> +	  (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
> +				CONFIG_DEBUG_IMX_UART_PORT);
> +
> +	writel(0x00000000, uartbase + UCR1);
> +
> +	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
> +	       uartbase + UCR2);
> +	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
> +	       uartbase + UCR3);
> +	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
> +	       uartbase + UFCR);
> +
> +	writel(baudrate_to_ubir(CONFIG_BAUDRATE),
> +	       uartbase + UBIR);
> +	writel(refclock_to_ubmr(IMX_DEBUG_UART_REFCLOCK_HZ),
> +	       uartbase + UBMR);
> +
> +	writel(UCR1_UARTEN, uartbase + UCR1);
> +}
> +
> +#endif

Oh, turns out you did just that. So your patches are just in the wrong
order. You should first introduce this helper and add the babbage board
support later. This helps linear readers like me to not write
unnecessary mails ;)

Please add a imx_uart_ namespace to this function. This helps readers
to understand the scope of this function. Also I'm not sure how much we
can rely on the reference frequencies. Maybe you should use a two staged
approach. Let the imx_uart_setup_ll() function take a int reffreq
argument and add additional wrappers like imx6_uart_setup_ll() which
just calls this function.

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  Sun May  3 23:57:36 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 08:57:36 +0200
Subject: [PATCH 6/8] i.MX: serial: Convert i.MX51 and i.MX6 to use
 'setup_uart_ll'
In-Reply-To: <1430619980-26243-7-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-7-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504065736.GI6325@pengutronix.de>

On Sat, May 02, 2015 at 07:26:18PM -0700, Andrey Smirnov wrote:
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
> 
> Two boards -- 'guf-santaro' and 'eltec-hipercam' -- were not
> converted to use this function because they enable low-level UART
> regardless of the value of CONFIG_DEGUG_LL and so converting them to
> 'setup_uart_ll' would change the behaviour of the image build with
> 'imx_v7_defconfig'. Should those boards be converted to respect
> CONFIG_DEBUG_LL?

Yes, it won't hurt to only initialize the UART when CONFIG_DEBUG_LL is
enabled.

> 
> Boards 'karo-tx25' and 'tqma53' could be converted but weren't because
> I don't have any i.MX25 or i.MX53 based hardware to test on.

No problem, they can still be converted by someone who comes along this
code and has hardware to test.

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:01:19 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:01:19 +0200
Subject: [PATCH 7/8] i.MX: serial: Distil common clock ungating code
In-Reply-To: <1430619980-26243-8-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-8-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504070119.GJ6325@pengutronix.de>

On Sat, May 02, 2015 at 07:26:19PM -0700, Andrey Smirnov wrote:
> Move all of the common clock ungating code in early UART
> initialization into a dedicated subroutine that can be shared by all
> of the users.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  9 +--------
>  arch/arm/boards/karo-tx6x/lowlevel.c                | 10 +---------
>  arch/arm/boards/phytec-phycard-imx6/lowlevel.c      | 10 +---------
>  arch/arm/boards/phytec-phyflex-imx6/lowlevel.c      | 10 +---------
>  arch/arm/boards/variscite-mx6/lowlevel.c            | 10 +---------
>  arch/arm/mach-imx/include/mach/debug_ll.h           | 17 +++++++++++++++++
>  6 files changed, 22 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> index a8d16cb..fd154df 100644
> --- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> +++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> @@ -21,16 +21,9 @@
> 
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
>  	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
> 
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> +	ungate_all_peripherals();
> 
>  	writel(0x0, iomuxbase + 0x24);
>  	writel(0x1b0b1, iomuxbase + 0x036C);
> diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c
> index 3f9fb23..d7087f5 100644
> --- a/arch/arm/boards/karo-tx6x/lowlevel.c
> +++ b/arch/arm/boards/karo-tx6x/lowlevel.c
> @@ -22,7 +22,6 @@
> 
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
>  	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
> 
>  	writel(0x1, iomuxbase + 0x0314);
> @@ -30,14 +29,7 @@ static inline void setup_uart(void)
>  	writel(0x1, iomuxbase + 0x0330);
>  	writel(0x1, iomuxbase + 0x032c);
> 
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> -
> +	ungate_all_peripherals();
>  	setup_uart_ll();
> 
>  	putc_ll('>');
> diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
> index 1d48818..c8306ec 100644
> --- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
> +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
> @@ -26,19 +26,11 @@
> 
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR);
>  	void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);
> 
>  	writel(0x4, iomuxbase + 0x01f8);
> 
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> -
> +	ungate_all_peripherals();
>  	setup_uart_ll();
> 
>  	putc_ll('>');
> diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
> index 367d4dc..46f788c 100644
> --- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
> +++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
> @@ -27,19 +27,11 @@
> 
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
>  	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
> 
>  	writel(0x4, iomuxbase + 0x01f8);
> 
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> -
> +	ungate_all_peripherals();
>  	setup_uart_ll();
> 
>  	putc_ll('>');
> diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c
> index b0ab424..01878e6 100644
> --- a/arch/arm/boards/variscite-mx6/lowlevel.c
> +++ b/arch/arm/boards/variscite-mx6/lowlevel.c
> @@ -28,20 +28,12 @@
> 
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
>  	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
> 
>  	writel(0x03, iomuxbase + 0x0280);
>  	writel(0x03, iomuxbase + 0x0284);
> 
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> -
> +	ungate_all_peripherals();
>  	setup_uart_ll();
> 
>  	putc_ll('>');
> diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
> index 5b0b33b..d831a7d 100644
> --- a/arch/arm/mach-imx/include/mach/debug_ll.h
> +++ b/arch/arm/mach-imx/include/mach/debug_ll.h
> @@ -3,6 +3,7 @@
> 
>  #include <io.h>
>  #include <config.h>
> +#include <common.h>
>  #include <mach/imx1-regs.h>
>  #include <mach/imx21-regs.h>
>  #include <mach/imx25-regs.h>
> @@ -71,6 +72,18 @@ static inline void setup_uart_ll(void)
> 
>  #endif
> 
> +#define __IMX_CCM_BASE(soc) soc##_CCM_BASE_ADDR
> +#define IMX_CCM_BASE(soc) __IMX_CCM_BASE(soc)
> +
> +static inline void ungate_all_peripherals(void)
> +{
> +	int i;
> +	void __iomem *ccmbase = IOMEM(IMX_CCM_BASE(IMX_DEBUG_SOC));
> +
> +	for (i = 0x68; i <= 0x80; i += 4)
> +		writel(0xffffffff, ccmbase + i);
> +}
> +

Please add a imx6_ namespace to this function. The calling code always
knows that it is running on imx6, so you can use IMX6_CCM_BASE_ADDR
directly rather than using soc##_. The function above is imx6 specific
anyway since only this SoC has the gate registers on 0x68..0x80.

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:08:14 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:08:14 +0200
Subject: [PATCH 1/8] i.MX: Move UART definitions into a separate file
In-Reply-To: <1430619980-26243-2-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-2-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504070814.GK6325@pengutronix.de>

On Sat, May 02, 2015 at 07:26:13PM -0700, Andrey Smirnov wrote:
> Move UART definitions into a separate file to avoid redefinition in
> <mach/debug_ll.h> and magical constants in low level UART
> initialization code.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/mach-imx/include/mach/debug_ll.h |   9 +--
>  arch/arm/mach-imx/include/mach/serial.h   | 112 ++++++++++++++++++++++++++++++
>  drivers/serial/serial_imx.c               | 108 +---------------------------
>  3 files changed, 114 insertions(+), 115 deletions(-)
>  create mode 100644 arch/arm/mach-imx/include/mach/serial.h
> 
> diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
> index f34eaa1..1c9f3a6 100644
> --- a/arch/arm/mach-imx/include/mach/debug_ll.h
> +++ b/arch/arm/mach-imx/include/mach/debug_ll.h
> @@ -12,6 +12,7 @@
>  #include <mach/imx51-regs.h>
>  #include <mach/imx53-regs.h>
>  #include <mach/imx6-regs.h>
> +#include <mach/serial.h>
> 
>  #ifdef CONFIG_DEBUG_LL
> 
> @@ -40,14 +41,6 @@
>  #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
>  #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
> 
> -#define URTX0		0x40		/* Transmitter Register */
> -
> -#define UCR1		0x80		/* Control Register 1 */
> -#define UCR1_UARTEN	(1 << 0)	/* UART enabled */
> -
> -#define USR2		0x98		/* Status Register 2 */
> -#define USR2_TXDC	(1 << 3)	/* Transmitter complete */
> -
>  static inline void PUTC_LL(int c)
>  {
>  	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
> diff --git a/arch/arm/mach-imx/include/mach/serial.h b/arch/arm/mach-imx/include/mach/serial.h
> new file mode 100644
> index 0000000..b999c58
> --- /dev/null
> +++ b/arch/arm/mach-imx/include/mach/serial.h

Normally we no longer put register definitions into mach/ since this
limits the driver to a single architecture. In case of the imx UART
driver this (currently) doesn't matter but I think we should use
a place include/ anyway. I think include/serial/imx-uart.h would be
appropriate.

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:14:39 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:14:39 +0200
Subject: [RFC, PATCH] i.MX: Add provisions to boot from IRAM
In-Reply-To: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504071439.GL6325@pengutronix.de>

Hi Andrey,

This series contains very nice cleanups. It needs some polishing, but
the patches are very welcomed.

On Sat, May 02, 2015 at 07:26:12PM -0700, Andrey Smirnov wrote:
> This commit add a very basic code to allow Barebox to be booted from
> IRAM. Given that the amount of IRAM on most i.MX variants is
> insufficient to contain a copy of Barebox with any reasonable degree
> of functionality this code uses IRAM only as a temporary location and
> eventually bootstraps from DRAM. But the presense of the intermediate
> IRAM-only stage allows to add provisions to test the area of DRAM that
> Barebox would be using to facilitate various testing scenarious.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/boards/freescale-mx51-babbage/Makefile    |  3 ++
>  .../flash-header-imx51-babbage-xload.imxcfg        | 59 ++++++++++++++++++++++
>  arch/arm/boards/freescale-mx51-babbage/lowlevel.c  | 25 +++++++++
>  arch/arm/configs/imx_v7-xload_defconfig            | 46 +++++++++++++++++
>  arch/arm/mach-imx/Kconfig                          | 15 ++++++
>  arch/arm/mach-imx/Makefile                         |  1 +
>  arch/arm/mach-imx/xload.c                          | 54 ++++++++++++++++++++
>  images/Makefile.imx                                | 20 +++++++-
>  8 files changed, 222 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
>  create mode 100644 arch/arm/configs/imx_v7-xload_defconfig
>  create mode 100644 arch/arm/mach-imx/xload.c
> 
> diff --git a/arch/arm/boards/freescale-mx51-babbage/Makefile b/arch/arm/boards/freescale-mx51-babbage/Makefile
> index 6252c88..31b8fcd 100644
> --- a/arch/arm/boards/freescale-mx51-babbage/Makefile
> +++ b/arch/arm/boards/freescale-mx51-babbage/Makefile
> @@ -1,3 +1,6 @@
>  obj-y += board.o flash-header-imx51-babbage.dcd.o
>  extra-y += flash-header-imx51-babbage.dcd.S flash-header-imx51-babbage.dcd
>  lwl-y += lowlevel.o
> +
> +obj-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.o
> +extra-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.S flash-header-imx51-babbage-xload.dcd
> diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
> new file mode 100644
> index 0000000..a04ac75
> --- /dev/null
> +++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
> @@ -0,0 +1,59 @@
> +loadaddr CONFIG_ARCH_IMX_UNUSED_IRAM_BASE
> +soc imx51
> +dcdofs 0x400
> +wm 32 0x73fa88a0 0x00000200

Can't this and the rest of this file shared with the regular imxcfg
file?

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:22:09 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:22:09 +0200
Subject: [PATCH] mtd: partition: Fix OF partition fixup
In-Reply-To: <55420919.7050904@pengutronix.de>
References: <1430126650-6382-1-git-send-email-s.hauer@pengutronix.de>
 <55420919.7050904@pengutronix.de>
Message-ID: <20150504072209.GM6325@pengutronix.de>

On Thu, Apr 30, 2015 at 12:51:05PM +0200, Marc Kleine-Budde wrote:
> On 04/27/2015 11:24 AM, Sascha Hauer wrote:
> > To get the number of address cells and size cells we have to use
> > the newly created partition node, not the parent device node. The
> > parent device node returns the address/size cells of the controller
> > node, not the partition node.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> 
> Have you already applied this patch?

Yes, it's applied to master.

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:23:26 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:23:26 +0200
Subject: [PATCH] usb: increase USB_CNTL_TIMEOUT to match linux
In-Reply-To: <1430218309-23741-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1430218309-23741-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <20150504072326.GN6325@pengutronix.de>

On Tue, Apr 28, 2015 at 12:51:49PM +0200, Steffen Trumtrar wrote:
> USB requests should be processed within a timeframe of 5s.
> The linux kernel also uses this timeout value for the control packets.
> 
> For the musb the increase in timeout helps successfully probing USB devices
> (at least on one test hardware), but on the other hand doesn't slow down the
> system, if there are no devices, i.e. the timeout never hits. That means,
> that the USB core correctly aborts instead of timing out.
> Why and how the 100ms was chosen in the first place, can not be deduced from
> the git history, just that it seems to work fine for most boards.
> 
> Change USB_CNTL_TIMEOUT to 5000ms and replace all occurences of
> 	`USB_CNTL_TIMEOUT * x`
> with just
> 	`USB_CNTL_TIMEOUT`,
> as the timeout is now large enough without it.
> 
> Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
> ---
>  drivers/usb/core/usb.c | 4 ++--
>  include/usb/usb.h      | 2 +-
>  2 files changed, 3 insertions(+), 3 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  Mon May  4 00:32:19 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:32:19 +0200
Subject: [PATCH] common: env: make error message more verbose
In-Reply-To: <1430217147-14188-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1430217147-14188-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <20150504073219.GO6325@pengutronix.de>

On Tue, Apr 28, 2015 at 12:32:27PM +0200, Steffen Trumtrar wrote:
> Change the setenv error message from
> 
> 	set parameter: Invalid argument
> 
> to a more helpful
> 
> 	net: cannot set parameter 'nameserver': Invalid argument
> 
> Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
> ---
>  common/env.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/common/env.c b/common/env.c
> index 2e33eb35856b..434170a7468b 100644
> --- a/common/env.c
> +++ b/common/env.c
> @@ -225,8 +225,10 @@ int setenv(const char *_name, const char *value)
>  
>  		errno = -ret;
>  
> -		if (ret < 0)
> -			perror("set parameter");
> +		if (ret < 0) {
> +			dev_err(dev, "cannot set parameter '%s'", par);
> +			perror("");
> +		}

dev may be invalid here, so you shouldn't use dev_err.

After we talked about the missing informations in the setenv failure
path I created the following patch. I applied this one now.

Sascha

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

>From 6d4afd96fc94a3f2d256ef4e8d7c9687a145a701 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer at pengutronix.de>
Date: Tue, 28 Apr 2015 12:43:02 +0200
Subject: [PATCH] setenv: Be more informative when device parameter setting
 fails

When setting a device parameter fails not only the error code
is of interest, but also what the parameter name is, what the
device name is and whether a device was found for this name.
Add this information to the error message.

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

diff --git a/common/env.c b/common/env.c
index 2e33eb3..c98ed73 100644
--- a/common/env.c
+++ b/common/env.c
@@ -218,16 +218,18 @@ int setenv(const char *_name, const char *value)
 
 		*par++ = 0;
 		dev = get_device_by_name(name);
-		if (dev)
+		if (dev) {
 			ret = dev_set_param(dev, par, value);
-		else
+			if (ret)
+				eprintf("%s: set parameter %s: %s\n",
+						dev_name(dev), par, strerror(-ret));
+		} else {
 			ret = -ENODEV;
+			eprintf("set parameter: no such device %s\n", name);
+		}
 
 		errno = -ret;
 
-		if (ret < 0)
-			perror("set parameter");
-
 		goto out;
 	}
 
-- 
2.1.4

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


From s.hauer at pengutronix.de  Mon May  4 00:35:45 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:35:45 +0200
Subject: [PATCH 3/8] bootstrap_read_devfs(): Check for errors from
 devfs_add_partition()
In-Reply-To: <1430683999-5910-3-git-send-email-andrew.smirnov@gmail.com>
References: <1430683999-5910-1-git-send-email-andrew.smirnov@gmail.com>
 <1430683999-5910-3-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504073545.GP6325@pengutronix.de>

On Sun, May 03, 2015 at 01:13:14PM -0700, Andrey Smirnov wrote:
> Check for errors returned by devfs_add_partition() and bail if there
> are any.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  lib/bootstrap/devfs.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
> index 82c7d21..de274a0 100644
> --- a/lib/bootstrap/devfs.c
> +++ b/lib/bootstrap/devfs.c
> @@ -82,10 +82,17 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
>  	int ret;
>  	int size = 0;
>  	void *to, *header;
> -	struct cdev *cdev;
> +	struct cdev *cdev, partition;
>  	char *partname = "x";
> 
> -	devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname);
> +	partition = devfs_add_partition(devname, offset, max_size,
> +					DEVFS_PARTITION_FIXED, partname);
> +	if (IS_ERR_OR_NULL(partition)) {

IS_ERR please. devfs_add_partition() will not return a NULL pointer.

Sascha

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


From s.hauer at pengutronix.de  Mon May  4 00:41:10 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 09:41:10 +0200
Subject: [PATCH v2 1/8] imx-image: Correctly fill image size in prepended
 header
In-Reply-To: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430690125-2257-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150504074110.GQ6325@pengutronix.de>

It seems you only resent the patches from this series you actually
changed. Could you resent *all* patches again next time?

Sascha

On Sun, May 03, 2015 at 02:55:22PM -0700, Andrey Smirnov wrote:
> If called with '-b' option 'imx-image' tool prepends barebox header to
> the image, but the tool does not fill the data at image size offset
> correctly. Fix that.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
> 
> This patch supercedes the one sent earlier titled:
>  "[PATCH 1/8] Makefile.lib: Fix i.MX image size after generation"
> 
>  scripts/imx/Makefile    |  2 ++
>  scripts/imx/imx-image.c | 12 ++++++++++--
>  2 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
> index be0b490..ee0acc1 100644
> --- a/scripts/imx/Makefile
> +++ b/scripts/imx/Makefile
> @@ -6,5 +6,7 @@ always          := $(hostprogs-y)
>  HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
>  HOSTLOADLIBES_imx-usb-loader  = `pkg-config --libs libusb-1.0`
> 
> +HOSTCFLAGS_imx-image.o = -I$(srctree)
> +
>  imx-usb-loader-objs := imx-usb-loader.o
>  imx-image-objs := imx-image.o
> diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
> index 25ea4d8..c0181df 100644
> --- a/scripts/imx/imx-image.c
> +++ b/scripts/imx/imx-image.c
> @@ -27,6 +27,8 @@
>  #include <fcntl.h>
>  #include <endian.h>
> 
> +#include <include/filetype.h>
> +
>  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
>  #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
>  #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
> @@ -92,8 +94,11 @@ static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imag
>  	struct imx_flash_header *hdr;
>  	int dcdsize = curdcd * sizeof(uint32_t);
> 
> -	if (add_barebox_header)
> +	if (add_barebox_header) {
> +		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
>  		memcpy(buf, bb_header, sizeof(bb_header));
> +		*psize = imagesize;
> +	}
> 
>  	buf += offset;
>  	hdr = buf;
> @@ -178,8 +183,11 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag
>  	struct imx_flash_header_v2 *hdr;
>  	int dcdsize = curdcd * sizeof(uint32_t);
> 
> -	if (add_barebox_header)
> +	if (add_barebox_header) {
> +		uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
>  		memcpy(buf, bb_header, sizeof(bb_header));
> +		*psize = imagesize;
> +	}
> 
>  	buf += offset;
>  	hdr = buf;
> --
> 2.1.4
> 
> _______________________________________________
> 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.trumtrar at pengutronix.de  Mon May  4 00:43:59 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Mon, 4 May 2015 09:43:59 +0200
Subject: [PATCH] common: env: make error message more verbose
In-Reply-To: <20150504073219.GO6325@pengutronix.de>
References: <1430217147-14188-1-git-send-email-s.trumtrar@pengutronix.de>
 <20150504073219.GO6325@pengutronix.de>
Message-ID: <20150504074359.GA27811@pengutronix.de>

Hi!

On Mon, May 04, 2015 at 09:32:19AM +0200, Sascha Hauer wrote:
> On Tue, Apr 28, 2015 at 12:32:27PM +0200, Steffen Trumtrar wrote:
> > Change the setenv error message from
> > 
> > 	set parameter: Invalid argument
> > 
> > to a more helpful
> > 
> > 	net: cannot set parameter 'nameserver': Invalid argument
> > 
> > Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
> > ---
> >  common/env.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > diff --git a/common/env.c b/common/env.c
> > index 2e33eb35856b..434170a7468b 100644
> > --- a/common/env.c
> > +++ b/common/env.c
> > @@ -225,8 +225,10 @@ int setenv(const char *_name, const char *value)
> >  
> >  		errno = -ret;
> >  
> > -		if (ret < 0)
> > -			perror("set parameter");
> > +		if (ret < 0) {
> > +			dev_err(dev, "cannot set parameter '%s'", par);
> > +			perror("");
> > +		}
> 
> dev may be invalid here, so you shouldn't use dev_err.
> 

Argh, yeah, of course *facepalm*.

> After we talked about the missing informations in the setenv failure
> path I created the following patch. I applied this one now.

Thanks for fixing.
Steffen

-- 
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  Mon May  4 05:29:20 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:20 +0300
Subject: [PATCH 0/5] MIPS: tplink-mr3020: initial PBL support
Message-ID: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>

This patch series enables PBL for AR9331-based TP-Link MR3020 router.
This makes it possible to implement full-grown bootloader for AR9331-based
boards in the future.

AR9331 lowlevel initialization links:

  * https://github.com/pepe2k/u-boot_mod
  * https://github.com/frantony/barebox/commits/20140507.ar933x.pbl.dirty
  * https://wikidevi.com/wiki/TP-LINK_TL-MR3020#Notes_on_JTAG
  * http://openocd.zylin.com/#/c/2519/
  * http://geektimes.ru/post/245066/
  * http://geektimes.ru/post/249184/
  * http://openocd.zylin.com/#/c/2722/

Antony Pavlov (4):
  MIPS: debug_ll_ns16550.h: drop _ns16550 suffix
  MIPS: mach-ath79: debug_ll.h: add assembler routines
  MIPS: tplink-mr3020: enable nmon
  Documentation: mips: fix tplink-mr3020 instruction

Oleksij Rempel (1):
  MIPS: tplink-mr3020: enable PBL and compression

 Documentation/boards/mips/tplink-mr3020.rst        |   7 +-
 .../img-ci20/include/board/board_pbl_start.h       |   2 +-
 .../loongson-ls1b/include/board/board_pbl_start.h  |   2 +-
 .../netgear-wg102/include/board/board_pbl_start.h  |   6 +-
 .../ritmix-rzx50/include/board/board_pbl_start.h   |   2 +-
 .../tplink-mr3020/include/board/board_pbl_start.h  |  35 ++++++
 arch/mips/include/asm/debug_ll_ns16550.h           |  20 +--
 arch/mips/include/asm/pbl_nmon.h                   |  21 ++--
 arch/mips/mach-ath79/Kconfig                       |   3 +
 arch/mips/mach-ath79/include/mach/debug_ll.h       | 136 ++++++++++++++++++++-
 10 files changed, 199 insertions(+), 35 deletions(-)
 create mode 100644 arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h

-- 
2.1.4



From antonynpavlov at gmail.com  Mon May  4 05:29:21 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:21 +0300
Subject: [PATCH 1/5] MIPS: tplink-mr3020: enable PBL and compression
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1430742565-18714-2-git-send-email-antonynpavlov@gmail.com>

From: Oleksij Rempel <linux at rempel-privat.de>

Signed-off-by: Oleksij Rempel <linux at rempel-privat.de>
Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 .../tplink-mr3020/include/board/board_pbl_start.h  | 32 ++++++++++++++++++++++
 arch/mips/mach-ath79/Kconfig                       |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h
new file mode 100644
index 0000000..f85c5ad
--- /dev/null
+++ b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013, 2015 Antony Pavlov <antonynpavlov at gmail.com>
+ * Copyright (C) 2013 Oleksij Rempel <linux at rempel-privat.de>
+ *
+ * This file is part of barebox.
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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 <asm/pbl_macros.h>
+
+	.macro	board_pbl_start
+	.set	push
+	.set	noreorder
+
+	mips_barebox_10h
+
+	mips_disable_interrupts
+
+	copy_to_link_location	pbl_start
+
+	.set	pop
+	.endm
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index 96fffd3..3fd9cdd 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -9,6 +9,8 @@ choice
 
 config BOARD_TPLINK_MR3020
 	bool "TP-LINK MR3020"
+	select HAVE_PBL_IMAGE
+	select HAVE_IMAGE_COMPRESSION
 
 endchoice
 
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May  4 05:29:23 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:23 +0300
Subject: [PATCH 3/5] MIPS: mach-ath79: debug_ll.h: add assembler routines
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1430742565-18714-4-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/mach-ath79/include/mach/debug_ll.h | 136 ++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 5 deletions(-)

diff --git a/arch/mips/mach-ath79/include/mach/debug_ll.h b/arch/mips/mach-ath79/include/mach/debug_ll.h
index de4c00d..c697318 100644
--- a/arch/mips/mach-ath79/include/mach/debug_ll.h
+++ b/arch/mips/mach-ath79/include/mach/debug_ll.h
@@ -18,17 +18,26 @@
 #ifndef __AR933X_DEBUG_LL__
 #define __AR933X_DEBUG_LL__
 
-#include <io.h>
-#include <linux/bitops.h>
 #include <asm/addrspace.h>
 
-#include <mach/ar71xx_regs.h>
+/* Alas! <mach/ar71xx_regs.h> isn't assembly-tolerant */
+#define AR71XX_APB_BASE     0x18000000
+#define AR933X_UART_BASE    (AR71XX_APB_BASE + 0x00020000)
+
+#define DEBUG_LL_UART_ADDR	KSEG1ADDR(AR933X_UART_BASE)
 
 #define AR933X_UART_DATA_REG            0x00
 #define AR933X_UART_DATA_TX_RX_MASK     0xff
-#define AR933X_UART_DATA_TX_CSR         BIT(9)
+#define AR933X_UART_DATA_TX_CSR		0x200
+#define AR933X_UART_DATA_RX_CSR		0x100
 
-#define DEBUG_LL_UART_ADDR	KSEG1ADDR(AR933X_UART_BASE)
+#ifndef __ASSEMBLY__
+
+#include <io.h>
+
+/*
+ * C macros
+ */
 
 static inline void ar933x_debug_ll_writel(u32 b, int offset)
 {
@@ -52,5 +61,122 @@ static inline void PUTC_LL(int ch)
 	data = (ch & AR933X_UART_DATA_TX_RX_MASK) | AR933X_UART_DATA_TX_CSR;
 	ar933x_debug_ll_writel(data, AR933X_UART_DATA_REG);
 }
+#else /* __ASSEMBLY__ */
+/*
+ * Macros for use in assembly language code
+ */
+
+/*
+ * output a character in a0
+ */
+.macro	debug_ll_outc_a0
+#ifdef CONFIG_DEBUG_LL
+	.set	push
+	.set	reorder
+
+	la	t0, DEBUG_LL_UART_ADDR
+201:
+	lw	t1, AR933X_UART_DATA_REG(t0)	/* get line status */
+	andi	t1, t1, AR933X_UART_DATA_TX_CSR	/* check for transmitter empty */
+	beqz	t1, 201b	/* try again */
+	andi	a0, a0, AR933X_UART_DATA_TX_RX_MASK
+	ori	a0, a0, AR933X_UART_DATA_TX_CSR
+	sw	a0, 0(t0)	/* write the character */
+	.set	pop
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * output a character
+ */
+.macro	debug_ll_outc chr
+#ifdef CONFIG_DEBUG_LL
+	li	a0, \chr
+	debug_ll_outc_a0
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * output a 32-bit value in hex
+ */
+.macro debug_ll_outhexw
+#ifdef CONFIG_DEBUG_LL
+	.set	push
+	.set	reorder
+
+	move	t6, a0
+	li		t5, 32
+
+202:
+	addi	t5, t5, -4
+	srlv	a0, t6, t5
+
+	/* output one hex digit */
+	andi	a0, a0, 15
+	blt	a0, 10, 203f
+
+	addi	a0, a0, ('a' - '9' - 1)
+
+203:
+	addi	a0, a0, '0'
+
+	debug_ll_outc_a0
+
+	bgtz	t5, 202b
+
+	.set	pop
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * check character in input buffer
+ * return value:
+ *  v0 = 0   no character in input buffer
+ *  v0 != 0  character in input buffer
+ */
+/* FIXME: use tstc */
+.macro	debug_ll_tstc
+#ifdef CONFIG_DEBUG_LL
+	.set	push
+	.set	reorder
+
+	la	t0, DEBUG_LL_UART_ADDR
+
+	/* get line status and check for data present */
+	lw	v0, AR933X_UART_DATA_REG(t0)
+	andi	v0, v0, AR933X_UART_DATA_RX_CSR
+
+	.set	pop
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * get character to v0
+ */
+.macro	debug_ll_getc
+#ifdef CONFIG_DEBUG_LL
+	.set	push
+	.set	reorder
+
+	la	t0, DEBUG_LL_UART_ADDR
+204:
+	lw	v0, AR933X_UART_DATA_REG(t0)
+	andi	v0, v0, AR933X_UART_DATA_RX_CSR
+
+	/* try again */
+	beqz	v0, 204b
+
+	/* read a character */
+	lw	v0, AR933X_UART_DATA_REG(t0)
+	andi	v0, v0, AR933X_UART_DATA_TX_RX_MASK
+
+	/* remove the character from the FIFO */
+	li	t1, AR933X_UART_DATA_RX_CSR
+	sw  t1, AR933X_UART_DATA_REG(t0)
+
+	.set	pop
+#endif /* CONFIG_DEBUG_LL */
+.endm
+#endif /* __ASSEMBLY__ */
 
 #endif /* __AR933X_DEBUG_LL__ */
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May  4 05:29:22 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:22 +0300
Subject: [PATCH 2/5] MIPS: debug_ll_ns16550.h: drop _ns16550 suffix
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1430742565-18714-3-git-send-email-antonynpavlov@gmail.com>

This commit makes it possible to have unified debug_ll_*
assembler routines for differrent UART program model.
E.g. we can use debug_ll_putc() routine in common
code without knowledge on exact UART model: ns16550
or ar933x.

Also rename *_check_char -> *_tstc.

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 .../boards/img-ci20/include/board/board_pbl_start.h |  2 +-
 .../loongson-ls1b/include/board/board_pbl_start.h   |  2 +-
 .../netgear-wg102/include/board/board_pbl_start.h   |  6 +++---
 .../ritmix-rzx50/include/board/board_pbl_start.h    |  2 +-
 arch/mips/include/asm/debug_ll_ns16550.h            | 20 ++++++++++----------
 arch/mips/include/asm/pbl_nmon.h                    | 21 ++++++++++-----------
 6 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/arch/mips/boards/img-ci20/include/board/board_pbl_start.h b/arch/mips/boards/img-ci20/include/board/board_pbl_start.h
index 26232f5..42d23c8 100644
--- a/arch/mips/boards/img-ci20/include/board/board_pbl_start.h
+++ b/arch/mips/boards/img-ci20/include/board/board_pbl_start.h
@@ -32,7 +32,7 @@
 
 	debug_ll_ns16550_init
 
-	debug_ll_ns16550_outc '.'
+	debug_ll_outc '.'
 	debug_ll_ns16550_outnl
 
 	mips_nmon
diff --git a/arch/mips/boards/loongson-ls1b/include/board/board_pbl_start.h b/arch/mips/boards/loongson-ls1b/include/board/board_pbl_start.h
index 1a92794..a3c585e 100644
--- a/arch/mips/boards/loongson-ls1b/include/board/board_pbl_start.h
+++ b/arch/mips/boards/loongson-ls1b/include/board/board_pbl_start.h
@@ -30,7 +30,7 @@
 
 	debug_ll_ns16550_init
 
-	debug_ll_ns16550_outc '.'
+	debug_ll_outc '.'
 	debug_ll_ns16550_outnl
 
 	mips_nmon
diff --git a/arch/mips/boards/netgear-wg102/include/board/board_pbl_start.h b/arch/mips/boards/netgear-wg102/include/board/board_pbl_start.h
index d74d2c2..9fb2205 100644
--- a/arch/mips/boards/netgear-wg102/include/board/board_pbl_start.h
+++ b/arch/mips/boards/netgear-wg102/include/board/board_pbl_start.h
@@ -35,7 +35,7 @@
 	pbl_ar2312_rst_uart0
 	debug_ll_ns16550_init
 
-	debug_ll_ns16550_outc 'a'
+	debug_ll_outc 'a'
 	debug_ll_ns16550_outnl
 
 	/* check if SDRAM is already configured,
@@ -60,7 +60,7 @@
 	pbl_probe_mem t0, t1, KSEG1
 	beq t0, t1, sdram_configured
 	 nop
-	debug_ll_ns16550_outc '#'
+	debug_ll_outc '#'
 	debug_ll_ns16550_outnl
 
 1:
@@ -68,7 +68,7 @@
 	 nop
 
 sdram_configured:
-	debug_ll_ns16550_outc 'b'
+	debug_ll_outc 'b'
 	debug_ll_ns16550_outnl
 
 	copy_to_link_location	pbl_start
diff --git a/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h b/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h
index fb914d9..7c2fa0b 100644
--- a/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h
+++ b/arch/mips/boards/ritmix-rzx50/include/board/board_pbl_start.h
@@ -32,7 +32,7 @@
 
 	debug_ll_ns16550_init
 
-	debug_ll_ns16550_outc '.'
+	debug_ll_outc '.'
 	debug_ll_ns16550_outnl
 
 	mips_nmon
diff --git a/arch/mips/include/asm/debug_ll_ns16550.h b/arch/mips/include/asm/debug_ll_ns16550.h
index 032f0a2..a3e1c52 100644
--- a/arch/mips/include/asm/debug_ll_ns16550.h
+++ b/arch/mips/include/asm/debug_ll_ns16550.h
@@ -90,7 +90,7 @@ static __inline__ void PUTC_LL(char ch)
 /*
  * output a character in a0
  */
-.macro	debug_ll_ns16550_outc_a0
+.macro	debug_ll_outc_a0
 #ifdef CONFIG_DEBUG_LL
 	.set	push
 	.set	reorder
@@ -110,10 +110,10 @@ static __inline__ void PUTC_LL(char ch)
 /*
  * output a character
  */
-.macro	debug_ll_ns16550_outc chr
+.macro	debug_ll_outc chr
 #ifdef CONFIG_DEBUG_LL
 	li	a0, \chr
-	debug_ll_ns16550_outc_a0
+	debug_ll_outc_a0
 #endif /* CONFIG_DEBUG_LL */
 .endm
 
@@ -122,15 +122,15 @@ static __inline__ void PUTC_LL(char ch)
  */
 .macro	debug_ll_ns16550_outnl
 #ifdef CONFIG_DEBUG_LL
-	debug_ll_ns16550_outc '\r'
-	debug_ll_ns16550_outc '\n'
+	debug_ll_outc '\r'
+	debug_ll_outc '\n'
 #endif /* CONFIG_DEBUG_LL */
 .endm
 
 /*
  * output a 32-bit value in hex
  */
-.macro debug_ll_ns16550_outhexw
+.macro debug_ll_outhexw
 #ifdef CONFIG_DEBUG_LL
 	.set	push
 	.set	reorder
@@ -151,7 +151,7 @@ static __inline__ void PUTC_LL(char ch)
 203:
 	addi	a0, a0, '0'
 
-	debug_ll_ns16550_outc_a0
+	debug_ll_outc_a0
 
 	bgtz	t5, 202b
 
@@ -165,7 +165,7 @@ static __inline__ void PUTC_LL(char ch)
  *  v0 = 0   no character in input buffer
  *  v0 != 0  character in input buffer
  */
-.macro	debug_ll_ns16550_check_char
+.macro	debug_ll_tstc
 #ifdef CONFIG_DEBUG_LL
 	.set	push
 	.set	reorder
@@ -183,13 +183,13 @@ static __inline__ void PUTC_LL(char ch)
 /*
  * get character to v0
  */
-.macro	debug_ll_ns16550_getc
+.macro	debug_ll_getc
 #ifdef CONFIG_DEBUG_LL
 	.set	push
 	.set	reorder
 
 204:
-	debug_ll_ns16550_check_char
+	debug_ll_tstc
 
 	/* try again */
 	beqz	v0, 204b
diff --git a/arch/mips/include/asm/pbl_nmon.h b/arch/mips/include/asm/pbl_nmon.h
index e7baa4c..90e2da8 100644
--- a/arch/mips/include/asm/pbl_nmon.h
+++ b/arch/mips/include/asm/pbl_nmon.h
@@ -17,8 +17,7 @@
  *
  */
 
-#include <board/debug_ll.h>
-#include <asm/debug_ll_ns16550.h>
+#include <mach/debug_ll.h>
 
 #define CODE_ESC	0x1b
 
@@ -74,7 +73,7 @@ nmon_wait_user:
 
 	nmon_outs	msg_bsp
 
-	debug_ll_ns16550_check_char
+	debug_ll_tstc
 
 	bnez	v0, 3f
 
@@ -91,7 +90,7 @@ msg_nmon_press_any_key:
 	.align	4
 3:
 	/* get received char from ns16550's buffer */
-	debug_ll_ns16550_getc
+	debug_ll_getc
 #endif /* CONFIG_NMON_USER_START */
 
 nmon_main_help:
@@ -102,9 +101,9 @@ nmon_main_help:
 nmon_main:
 	nmon_outs	msg_prompt
 
-	debug_ll_ns16550_getc
+	debug_ll_getc
 
-	/* prepare a0 for debug_ll_ns16550_outc_a0 */
+	/* prepare a0 for debug_ll_outc_a0 */
 	move	a0, v0
 
 	li	v1, 'q'
@@ -137,7 +136,7 @@ nmon_cmd_d:
 	nmon_outs	msg_nl
 
 	lw	a0, (v0)
-	debug_ll_ns16550_outhexw
+	debug_ll_outhexw
 
 	b	nmon_main
 
@@ -170,7 +169,7 @@ nmon_cmd_g:
 	b	nmon_main
 
 _nmon_outc_a0:
-	debug_ll_ns16550_outc_a0
+	debug_ll_outc_a0
 	jr	ra
 
 _nmon_outs:
@@ -178,7 +177,7 @@ _nmon_outs:
 	addi	a1, a1, 1
 	beqz	a0, _nmon_jr_ra_exit
 
-	debug_ll_ns16550_outc_a0
+	debug_ll_outc_a0
 
 	b	_nmon_outs
 
@@ -188,7 +187,7 @@ _nmon_gethexw:
 	li	t2, 0
 
 _get_hex_digit:
-	debug_ll_ns16550_getc
+	debug_ll_getc
 
 	li	v1, CODE_ESC
 	beq	v0, v1, nmon_main
@@ -221,7 +220,7 @@ _get_hex_digit:
 	sub	a3, v0, a3
 
 0:	move	a0, v0
-	debug_ll_ns16550_outc_a0
+	debug_ll_outc_a0
 
 	sll	t2, t2, 4
 	or	t2, t2, a3
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May  4 05:29:24 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:24 +0300
Subject: [PATCH 4/5] MIPS: tplink-mr3020: enable nmon
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1430742565-18714-5-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h | 3 +++
 arch/mips/mach-ath79/Kconfig                                   | 1 +
 2 files changed, 4 insertions(+)

diff --git a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h
index f85c5ad..944a510 100644
--- a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h
+++ b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h
@@ -17,6 +17,7 @@
  */
 
 #include <asm/pbl_macros.h>
+#include <asm/pbl_nmon.h>
 
 	.macro	board_pbl_start
 	.set	push
@@ -26,6 +27,8 @@
 
 	mips_disable_interrupts
 
+	mips_nmon
+
 	copy_to_link_location	pbl_start
 
 	.set	pop
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig
index 3fd9cdd..f730b37 100644
--- a/arch/mips/mach-ath79/Kconfig
+++ b/arch/mips/mach-ath79/Kconfig
@@ -11,6 +11,7 @@ config BOARD_TPLINK_MR3020
 	bool "TP-LINK MR3020"
 	select HAVE_PBL_IMAGE
 	select HAVE_IMAGE_COMPRESSION
+	select HAS_NMON
 
 endchoice
 
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May  4 05:29:25 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon,  4 May 2015 15:29:25 +0300
Subject: [PATCH 5/5] Documentation: mips: fix tplink-mr3020 instruction
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1430742565-18714-6-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 Documentation/boards/mips/tplink-mr3020.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/boards/mips/tplink-mr3020.rst b/Documentation/boards/mips/tplink-mr3020.rst
index c9e092c..8a95e11 100644
--- a/Documentation/boards/mips/tplink-mr3020.rst
+++ b/Documentation/boards/mips/tplink-mr3020.rst
@@ -23,7 +23,8 @@ But you have to encode barebox image in a very special way.
 First obtain ``lzma`` and ``mktplinkfw`` utilities.
 
 The ``lzma`` utility can be obtained in Debian/Ubuntu
-distro by installing lzma package.
+distro by installing lzma package
+(lzma from xz-utils package is unusable).
 
 The ``mktplinkfw`` utility can be obtained from openwrt, e.g.::
 
@@ -36,8 +37,8 @@ The ``mktplinkfw`` utility can be obtained from openwrt, e.g.::
 To convert your barebox.bin to U-Boot-loadable image (``6F01A8C0.img``)
 use this command sequence::
 
-  $ lzma -c -k barebox.bin > barebox.lzma
-  $ ./FW/mktplinkfw -c -H 0x07200103 -W 1 -N TL-WR720N-v3 \
+  $ lzma -c -k barebox-flash-image > barebox.lzma
+  $ ./mktplinkfw -c -H 0x07200103 -W 1 -N TL-WR720N-v3 \
       -s -F 4Mlzma -k barebox.lzma -o 6F01A8C0.img
 
 You must setup tftp-server on host 192.168.0.1.
-- 
2.1.4



From andrew.smirnov at gmail.com  Mon May  4 11:04:25 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Mon, 4 May 2015 11:04:25 -0700
Subject: [PATCH 7/8] i.MX: serial: Distil common clock ungating code
In-Reply-To: <20150504070119.GJ6325@pengutronix.de>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-8-git-send-email-andrew.smirnov@gmail.com>
 <20150504070119.GJ6325@pengutronix.de>
Message-ID: <CAHQ1cqGjdGfVhbLLXf1JeiuTm898uxvMCh7cPXsAphEVfTF6qQ@mail.gmail.com>

> Please add a imx6_ namespace to this function. The calling code always
> knows that it is running on imx6, so you can use IMX6_CCM_BASE_ADDR
> directly rather than using soc##_. The function above is imx6 specific
> anyway since only this SoC has the gate registers on 0x68..0x80.

What about i.MX51? As far as I can tell it is the same as i.MX6 in
this aspect. This function wouldn't have any consumers on i.MX51
architecture, of course, but shouldn't this function have a SoC
variant agnostic name, just for the sake of genericity?


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


From s.hauer at pengutronix.de  Mon May  4 12:52:20 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 4 May 2015 21:52:20 +0200
Subject: [PATCH 7/8] i.MX: serial: Distil common clock ungating code
In-Reply-To: <CAHQ1cqGjdGfVhbLLXf1JeiuTm898uxvMCh7cPXsAphEVfTF6qQ@mail.gmail.com>
References: <1430619980-26243-1-git-send-email-andrew.smirnov@gmail.com>
 <1430619980-26243-8-git-send-email-andrew.smirnov@gmail.com>
 <20150504070119.GJ6325@pengutronix.de>
 <CAHQ1cqGjdGfVhbLLXf1JeiuTm898uxvMCh7cPXsAphEVfTF6qQ@mail.gmail.com>
Message-ID: <20150504195220.GS6325@pengutronix.de>

On Mon, May 04, 2015 at 11:04:25AM -0700, Andrey Smirnov wrote:
> > Please add a imx6_ namespace to this function. The calling code always
> > knows that it is running on imx6, so you can use IMX6_CCM_BASE_ADDR
> > directly rather than using soc##_. The function above is imx6 specific
> > anyway since only this SoC has the gate registers on 0x68..0x80.
> 
> What about i.MX51? As far as I can tell it is the same as i.MX6 in
> this aspect. This function wouldn't have any consumers on i.MX51
> architecture, of course, but shouldn't this function have a SoC
> variant agnostic name, just for the sake of genericity?

On i.MX1/21/25/27/31/35 the function would look different, so when
trying to create a generic function we would need to decide which SoC
we are on. cpu_is_imxxy() doesn't work at that place because it needs
initialisation. #ifdefs do not work because we may have multiple SoC
supports compiled in. Even if we could decide which SoC we are on,
we still need a cascade of if() or #ifdef. Since the caller already
knows the SoC type it's easiest to create SoC specific functions.

If i.MX51 (and i.MX53 probably aswell) is the same as i.MX6 the i.MX6
function could simply call the i.MX5 function.

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 robertemmee02 at outlook.fr  Mon May  4 13:58:01 2015
From: robertemmee02 at outlook.fr (Mr. Michael Uba)
Date: Tue, 05 May 2015 00:58:01 +0400
Subject: CONTACT QUICK EXPRESS COURIER OFFICE.
Message-ID: <201505042058.t44K1kkC018554@kremail.lf2.cuni.cz>

CONTACT QUICK EXPRESS COURIER OFFICE. 

  
I have deposited your ATM Debit Card with the (QECD) delivery service . All you have to do is to contact them at:- (quickexpresscourier at vmail.me) they will give you direction on how your ATM card will be delivered to you. 

  
My agreement with them is to withdraw $5,000 USD daily until the whole of $1.5 USD is completed. I have paid them their delivery charges & insurance coverage fee. 
  

The only fee you will send to them before the delivery is $175 USD for security and paper works only. Also forward your full details to them for confirmation, here is your registration code. QU254522 please, send this code to them to enable them know your parcel. 

  
Thank you. 

  
Mr. Michael Uba


From s.hauer at pengutronix.de  Tue May  5 04:41:56 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 5 May 2015 13:41:56 +0200
Subject: [PATCH 0/5] MIPS: tplink-mr3020: initial PBL support
In-Reply-To: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
References: <1430742565-18714-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20150505114156.GY6325@pengutronix.de>

On Mon, May 04, 2015 at 03:29:20PM +0300, Antony Pavlov wrote:
> This patch series enables PBL for AR9331-based TP-Link MR3020 router.
> This makes it possible to implement full-grown bootloader for AR9331-based
> boards in the future.
> 
> AR9331 lowlevel initialization links:
> 
>   * https://github.com/pepe2k/u-boot_mod
>   * https://github.com/frantony/barebox/commits/20140507.ar933x.pbl.dirty
>   * https://wikidevi.com/wiki/TP-LINK_TL-MR3020#Notes_on_JTAG
>   * http://openocd.zylin.com/#/c/2519/
>   * http://geektimes.ru/post/245066/
>   * http://geektimes.ru/post/249184/
>   * http://openocd.zylin.com/#/c/2722/
> 
> Antony Pavlov (4):
>   MIPS: debug_ll_ns16550.h: drop _ns16550 suffix
>   MIPS: mach-ath79: debug_ll.h: add assembler routines
>   MIPS: tplink-mr3020: enable nmon
>   Documentation: mips: fix tplink-mr3020 instruction
> 
> Oleksij Rempel (1):
>   MIPS: tplink-mr3020: enable PBL and compression

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 ezequiel at vanguardiasur.com.ar  Tue May  5 04:44:13 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 05 May 2015 08:44:13 -0300
Subject: Regression on next (Re: [PATCH 3/3] driver: Call bus->remove
 instead of driver->remove)
In-Reply-To: <20150504062919.GF6325@pengutronix.de>
References: <1426573554-14478-1-git-send-email-s.hauer@pengutronix.de>
 <1426573554-14478-3-git-send-email-s.hauer@pengutronix.de>
 <55450062.6050205@vanguardiasur.com.ar>
 <20150504062919.GF6325@pengutronix.de>
Message-ID: <5548AD0D.2040008@vanguardiasur.com.ar>



On 05/04/2015 03:29 AM, Sascha Hauer wrote:
> Hi Ezequiel,
> 
> On Sat, May 02, 2015 at 01:50:42PM -0300, Ezequiel Garcia wrote:
>> Hi Sascha,
>>
>> On 03/17/2015 03:25 AM, Sascha Hauer wrote:
>>> In devices_shutdown we should call the busses remove function
>>> which in turn calls the drivers remove function. Otherwise for
>>> example PCI devices never get removed since they do not have
>>> a remove function but a pcidev->remove function instead.
>>>
>>> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
>>> ---
>>>  drivers/base/driver.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/base/driver.c b/drivers/base/driver.c
>>> index 453966b..590c97c 100644
>>> --- a/drivers/base/driver.c
>>> +++ b/drivers/base/driver.c
>>> @@ -399,8 +399,8 @@ void devices_shutdown(void)
>>>  	struct device_d *dev;
>>>  
>>>  	list_for_each_entry(dev, &active, active) {
>>> -		if (dev->driver->remove)
>>> -			dev->driver->remove(dev);
>>> +		if (dev->bus->remove)
>>> +			dev->bus->remove(dev);
>>>  	}
>>>  }
>>>  
>>>
>>
>> This commit caused a regression on the Openblocks A6 board, which now freezes
>> when calling devices_shutdown. The problem is that calling bus->remove makes
>> the remove() of the PHY driver called twice.
>>
>> This happened because the mdio bus device (mdio-mvebu) was registered first,
>> and the phy0 device was be registered later, and attached to the mdio bus.
>>
>> Upon device shutdown, when iterating through the active device list,
>> the phy0 device is removed before mdio-mvebu. Then, when the mdio bus device
>> is removed, the phy0 device is removed again, here:
>>
>> mdio_bus_remove(on mdio-mvebu)
>>   mvebu_mdio_remove
>>     mdiobus_unregister
>>       unregister_device
>>         mdio_bus_remove(on phy0)
>>         
>> This is currently the case for the Kirkwood Openblocks A6 board, where a double
>> free(dev->cdev.name) in mdio_bus_remove causes a silent freeze when booting
>> Linux.
> 
> Too bad that happened. I believe the following fixes this, but I have no
> hardware to test this on. Could you give this a test? I'll delay the
> outstanding release until this is solved.
> 
> Sascha
> 
> ----------------------------8<---------------------------
> 
> From 15422e3435b0151f1b5d753b19a8578210da9d04 Mon Sep 17 00:00:00 2001
> From: Sascha Hauer <s.hauer at pengutronix.de>
> Date: Mon, 4 May 2015 08:16:20 +0200
> Subject: [PATCH] net: phy: Do not double remove phy device
> 
> This fixes: 80264a8 driver: Call bus->remove instead of driver->remove
> 
> On mvebu it happens that:
> 
> Upon device shutdown, when iterating through the active device list,
> the phy0 device is removed before mdio-mvebu. Then, when the mdio bus
> device is removed, the phy0 device is removed again, here:
> 
> mdio_bus_remove(on mdio-mvebu)
>   mvebu_mdio_remove
>     mdiobus_unregister
>       unregister_device
>         mdio_bus_remove(on phy0)
> 
> Fix this by setting the mdio busses phy_map[phy->addr] to NULL when
> unregistering the phy device, so that mdiobus_unregister no longer
> finds a valid phy_device when iterating over the busses device list.
> 
> Reported-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>

Tested-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks for the quick fix,
-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From ezequiel at vanguardiasur.com.ar  Tue May  5 05:06:12 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 05 May 2015 09:06:12 -0300
Subject: [PATCH 01/13] net: phy: Support Marvell 88E1318S PHY
In-Reply-To: <5546A571.1000006@gmail.com>
References: <1428627830-17281-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1428627830-17281-2-git-send-email-sebastian.hesselbarth@gmail.com>
 <554500FC.2050607@vanguardiasur.com.ar>
 <5545335E.1000700@vanguardiasur.com.ar> <5545EF64.4050107@gmail.com>
 <5546A571.1000006@gmail.com>
Message-ID: <5548B234.8070408@vanguardiasur.com.ar>

Hi Sebastian,

On 05/03/2015 07:47 PM, Sebastian Hesselbarth wrote:
> On 03.05.2015 11:50, Sebastian Hesselbarth wrote:
>> On 02.05.2015 22:28, Ezequiel Garcia wrote:
>>> On 05/02/2015 01:53 PM, Ezequiel Garcia wrote:
>>>> On 04/09/2015 10:03 PM, Sebastian Hesselbarth wrote:
>>>>> This adds support for the Marvell 88E1318S Gigabit Ethernet PHY.
>>>>>
>>>>> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
>> [...]
>>>>
>>>> With this commit, the Openblocks A6 PHY is not brought up, and so
>>>> network is broken.
>>>>
>>>> I'll look into it (unless you have an idea),
>>>>
>>>
>>> Hm.. the devicetree needs to specify the phy-mode:
>>>
>>> diff --git a/dts/src/arm/kirkwood-openblocks_a6.dts
>>> b/dts/src/arm/kirkwood-openblocks_a6.dts
>>> index fb9dc22..c53e37f 100644
>>> --- a/dts/src/arm/kirkwood-openblocks_a6.dts
>>> +++ b/dts/src/arm/kirkwood-openblocks_a6.dts
>>> @@ -171,6 +171,7 @@
>>>   &eth0 {
>>>          status = "okay";
>>>          ethernet0-port at 0 {
>>> +               phy-mode = "rgmii-id";
>>>                  phy-handle = <&ethphy0>;
>>>          };
>>>   };
>>>
>>> However, network works really crappy even after this change (either in
>>> barebox or in Linux).
>>
>> Ezequiel,
>>
>> RGMII phy-mode would have been my first guess.
>>
>> Can you define "crappy"  with respect to ethernet?
>>

On barebox, I'm seeing tftp making slow progress but with lots and lots of
timeouts. And then on the Linux side, there are many NFSroot disconnects,
and userspace is unresponsive.

I haven't really done any serious measurements.

>> The patch doesn't do anything different than the linux marvell phy
>> code would do.

Yeah, I don't think the issue in on the PHY init.

>> Do you have access to A6's u-boot source and can match
>> up the PHY init sequence?

Yes. Although U-Boot is barely readable, can't see anything interesting
being done with the PHY. (from ftp://ftp.plathome.co.jp/pub/OBSA6/uboot/)

MV_VOID mvEthE1310PhyBasicInit(MV_U32 ethPortNum)
{
        MV_U16 reg;

        /* Set phy address */
        MV_REG_WRITE(ETH_PHY_ADDR_REG(ethPortNum), mvBoardPhyAddrGet(ethPortNum));

        /* reset the phy */
        mvEthPhyRegRead(mvBoardPhyAddrGet(ethPortNum),0,&reg);
        reg |= BIT15;
        mvEthPhyRegWrite(mvBoardPhyAddrGet(ethPortNum),0,reg);
        mvOsDelay(10);

        /* Leds link and activity*/
        mvEthPhyRegWrite(mvBoardPhyAddrGet(ethPortNum),22,0x3);
        mvEthPhyRegRead(mvBoardPhyAddrGet(ethPortNum),16,&reg);
        reg &= ~0xfff;
        reg |= 0x671;
        mvEthPhyRegWrite(mvBoardPhyAddrGet(ethPortNum),16,reg);
        mvEthPhyRegWrite(mvBoardPhyAddrGet(ethPortNum),22,0x0);
}

> 
> Maybe we need some 1V8 RGMII setup for A6 too?
> 
> https://lkml.org/lkml/2015/5/3/159
> 
> IO Configuration 0 register 0xf10100e0, bit 7:

Hm, it seems it's off in U-Boot:

openblocks>> md f10100e0
f10100e0: 1b1b1b1b 011b1b1b 00000000 00000000    ................

-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From antonynpavlov at gmail.com  Tue May  5 05:16:35 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 5 May 2015 15:16:35 +0300
Subject: #define dma_alloc dma_alloc
Message-ID: <20150505151635.dcf30490fbe737e024aa83f6@gmail.com>

Hi, All!

Just out of curiosity, why we need "#define dma_alloc dma_alloc" in dma-related header files?

E.g.
  
  barebox$ git grep "#define dma_alloc dma_alloc"
  arch/arm/include/asm/dma.h:#define dma_alloc dma_alloc
  arch/nios2/include/asm/dma-mapping.h:#define dma_alloc dma_alloc

--?
Best regards,
? Antony Pavlov


From mkl at pengutronix.de  Tue May  5 05:13:16 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 5 May 2015 14:13:16 +0200
Subject: #define dma_alloc dma_alloc
In-Reply-To: <20150505151635.dcf30490fbe737e024aa83f6@gmail.com>
References: <20150505151635.dcf30490fbe737e024aa83f6@gmail.com>
Message-ID: <5548B3DC.7040101@pengutronix.de>

On 05/05/2015 02:16 PM, Antony Pavlov wrote:
> Just out of curiosity, why we need "#define dma_alloc dma_alloc" in dma-related header files?
> 
> E.g.
>   
>   barebox$ git grep "#define dma_alloc dma_alloc"
>   arch/arm/include/asm/dma.h:#define dma_alloc dma_alloc
>   arch/nios2/include/asm/dma-mapping.h:#define dma_alloc dma_alloc

Look if there's a matching "#ifdef dma_alloc".

Marc
-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150505/09c5158e/attachment-0001.sig>

From marcel.behlau at elfin.de  Tue May  5 07:56:10 2015
From: marcel.behlau at elfin.de (Marcel Behlau)
Date: Tue, 05 May 2015 16:56:10 +0200
Subject: Usage of i2c_-Tools in Barebox
Message-ID: <5548DA0A.3050408@elfin.de>

Hi,

i'm using a phyFLEX-i.MX6 SBC and want to communicate with an external 
?C over I2C. I only want to read/set 1 register, so i tried to use the 
builtin i2c_read and i2c_write-Commands. The ?C is connected to i2c-bus 
1 of the device, so i tried to probe the hole bus with "i2c_bus 1 3 30". 
The command only answered with "i2c_probe: No such device". I tried also 
the busses 0-3, with the same result. I searched in the board.c 
sourcecode of the phyflex, but couldn't find i2c related stuff, so i 
think, i have to add the initalisation for the i2c.

Do i have to add the i2c-init in the boards/phytec-pfla02/board.c -file? 
Is there some documenation about this stuff?

Thank in advance,

Marcel

-- 
Dipl. Ing (FH) Marcel Behlau
(Software Developer)

ELFIN GmbH
Siegburger Stra?e 215
50679 K?ln
Germany

Tel: +49 (221) 6778932-0
Fax: +49 (221) 6778932-2
marcel.behlau at elfin.de
www.elfin.de



From s.hauer at pengutronix.de  Tue May  5 08:54:50 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 5 May 2015 17:54:50 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <5548DA0A.3050408@elfin.de>
References: <5548DA0A.3050408@elfin.de>
Message-ID: <20150505155450.GB6325@pengutronix.de>

Hi Marcel,

On Tue, May 05, 2015 at 04:56:10PM +0200, Marcel Behlau wrote:
> Hi,
> 
> i'm using a phyFLEX-i.MX6 SBC and want to communicate with an
> external ?C over I2C. I only want to read/set 1 register, so i tried
> to use the builtin i2c_read and i2c_write-Commands. The ?C is
> connected to i2c-bus 1 of the device, so i tried to probe the hole
> bus with "i2c_bus 1 3 30". The command only answered with
> "i2c_probe: No such device". I tried also the busses 0-3, with the
> same result. I searched in the board.c sourcecode of the phyflex,
> but couldn't find i2c related stuff, so i think, i have to add the
> initalisation for the i2c.
> 
> Do i have to add the i2c-init in the boards/phytec-pfla02/board.c
> -file? Is there some documenation about this stuff?

The phyFLEX board is device tree based. You have to enable the i2c
controller in the dts file (same as you would do in the kernel).
Usually a:

&i2c0 {
	status = "okay";
};

Should be enough. You probably also have to add the proper pinctrl node.

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 May  6 00:09:42 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 6 May 2015 09:09:42 +0200
Subject: v2015.05.0
Message-ID: <20150506070942.GD6325@pengutronix.de>

Another month has passed, here's another release. Most notable this time
is Jean-Christophes work in the crypto area which is a good step towards
future secure boot support. Also worth mentioning is the merge of the
state framework which is used internally here for some time. The state
framework allows to store values in EEPROMs and such. Unlike general
nv variables these values are stored redundantly and are described in
the device tree. The binary format is very compact. These features make
the state framework suitable for small but valuable informations like
the current boot state for redundance boot scenarios.

Sascha

----------------------------------------------------------------
Antony Pavlov (3):
      toshiba_ac100: board.c: drop unused headers
      command: hashsum: Conding style fixup
      net: e1000: add HAS_DMA dependency

Bo Shen (1):
      ARM: atmel: sama5d4_xplained: switch to env2

Jan Luebbe (1):
      duckbill: fix PBL debug prefix

Jean-Christophe PLAGNIOL-VILLARD (28):
      digest: move digest.c to crypto
      digest: introduce digest_{init/update/final/length}
      digest: make it multi-instance
      crypto: add sha384 & sha512 support
      command: add sha384sum and sha512sum support
      password: add support for sha512
      digest: add HMAC support for md5, sha1, sha224, sha256, sha384, sha512
      command: add hmac sum supportfor md5, sha1, sha224, sha256, sha384, sha512
      crypto: digest: digest_file_window: check every digest_xxx return
      crypto: digest: digest_file_window/digest_file/digest_file_by_name drop key params
      digest: add verify callback
      digest: add digest callback
      crypto: hmac: use digest_digest and check the return of every digest_xxx
      crypto: add pbkdf2 hmac key generator
      command: allow runtime usage
      command: rename digest.c to hashsum.c
      command: add generic digest command
      crypto: digest: speficied when a digest need a key to be used
      password: add pbkdf2 support
      command: digest/hashsum: set key at command level
      digest: allow algo to specify their length at runtime
      crypto: prepare to allow multiple digest driver
      crypto: hmac: move register to hmac
      crypto: sha1: switch to linux implementation
      crypto: sha256: switch to linux implementation
      crypto: sha512: switch to linux implementation
      arm: crypto: add sha1 assembly support
      arm: crypto: add sha256 assembly support

Lucas Stach (5):
      images: move board variable to parent makefile
      images: fix Tegra out-of-tree build
      ARM: highbank: select OFTREE
      PCI: register and active bridge device before proceeding to scan
      PCI: fill in bus primary field

Marc Kleine-Budde (8):
      images: mxs: remove not used PREP_ definitions
      commands: dmesg: fi format security warning
      imx-image: add_header_v2(): replace hardcoded 0x400 by offset parameter
      imx-image: replace 0x400 by FLASH_HEADER_OFFSET
      imx-image: introduce HEADER_LEN and replace several 0x1000 and 4096
      imx-image: mx35: increase load image size, due to dobule header
      imx-image: main: make use of round_up instead of open coding it
      imx-image: pad generated image to 4k

Markus Pargmann (2):
      wdog: imx-wd: Introduce ops struct for imx21/imx1
      wdog: imx-wd: Disable watchdog powerdown counter

Mirko Damiani (1):
      net: ping: return an error exit code when connection fails

Robert Jarzmik (2):
      net: smc1111: add a quirk for pxa pxa27x platforms
      ARM: pxa: add mainstone board support

Sascha Hauer (35):
      state: add framework for persistent state handling
      crypto: digest: Make string arguments const
      crypto: digest: Fix coding style
      driver: fix device remove order
      driver: Call remove function only when available
      driver: Call bus->remove instead of driver->remove
      pci: Use standard pr_debug
      pci: fix copy-paste bug
      pci: pci_regs.h: Sync with Linux
      pci: Add pcie-designware driver
      ARM: i.MX: Add imx_clk_gate_exclusive
      ARM: i.MX6: Add PCI clocks
      pci: Add i.MX6 pcie support
      lib: Add hex2bin and bin2hex implementations
      ARM: i.MX6: ocotp: remove useless code
      ARM: Add ELTEC HiPerCam board support
      net: Add Intel e1000 driver
      dts: update to v4.0-rc2
      dts: update to v4.0-rc3
      dts: update to v4.0-rc4
      dts: update to v4.0-rc6
      .mailmap: Fix Juergens name
      Merge branch 'for-next/at91'
      Merge branch 'for-next/crypto'
      Merge branch 'for-next/driver'
      Merge branch 'for-next/dts'
      Merge branch 'for-next/imx'
      Merge branch 'for-next/misc'
      Merge branch 'for-next/net'
      Merge branch 'for-next/pci'
      Merge branch 'for-next/pxa'
      Merge branch 'for-next/state'
      mtd: partition: Fix OF partition fixup
      net: phy: Do not double remove phy device
      Release v2015.05.0

Sebastian Hesselbarth (1):
      USB: xHCI: Sync non-coherent DMA buffers

Steffen Trumtrar (1):
      ARM/MXS/i.MX28: recognize watchdog reset

Teresa G?mez (1):
      ARM: phytec-som-am335x: Remove bootargs-ip from boot scripts

 .mailmap                                           |    2 +-
 .../devicetree/bindings/barebox/barebox,state.rst  |  107 +
 Makefile                                           |    2 +-
 arch/arm/Makefile                                  |    1 +
 arch/arm/boards/Makefile                           |    2 +
 arch/arm/boards/duckbill/lowlevel.c                |    2 +-
 arch/arm/boards/eltec-hipercam/Makefile            |    2 +
 arch/arm/boards/eltec-hipercam/board.c             |   31 +
 .../flash-header-eltec-hipercam.imxcfg             |  105 +
 arch/arm/boards/eltec-hipercam/lowlevel.c          |   56 +
 arch/arm/boards/mainstone/Makefile                 |    2 +
 arch/arm/boards/mainstone/board.c                  |  134 +
 arch/arm/boards/mainstone/env/boot/nor-ubi         |    5 +
 arch/arm/boards/mainstone/env/init/mtdparts-nor    |   11 +
 .../boards/mainstone/env/nv/linux.bootargs.console |    1 +
 arch/arm/boards/mainstone/lowlevel.c               |  264 ++
 .../defaultenv-physom-am335x/boot/mmc              |    2 -
 .../defaultenv-physom-am335x/boot/nand             |    2 -
 .../defaultenv-physom-am335x/boot/spi              |    2 -
 arch/arm/boards/sama5d4_xplained/env/boot/mmc      |    8 +
 arch/arm/boards/sama5d4_xplained/env/boot/nand     |    8 +
 arch/arm/boards/sama5d4_xplained/env/config        |   42 -
 .../arm/boards/sama5d4_xplained/env/init/automount |    5 +
 .../boards/sama5d4_xplained/env/init/mtdparts-nand |    6 +
 .../env/{bin/init_board => init/splash}            |    0
 .../boards/sama5d4_xplained/env/nv/boot.default    |    1 +
 .../sama5d4_xplained/env/nv/linux.bootargs.console |    1 +
 arch/arm/boards/toshiba-ac100/board.c              |    4 -
 arch/arm/configs/at91rm9200ek_defconfig            |    4 +-
 arch/arm/configs/highbank_defconfig                |    4 +-
 arch/arm/configs/imx_v7_defconfig                  |    1 +
 arch/arm/configs/mainstone_defconfig               |  109 +
 arch/arm/configs/mioa701_defconfig                 |    2 +-
 arch/arm/configs/module-mb7707_defconfig           |    4 +-
 arch/arm/configs/nhk8815_defconfig                 |    2 +-
 arch/arm/configs/phytec-phycard-omap3_defconfig    |    6 +-
 arch/arm/configs/rpi_defconfig                     |    4 +-
 arch/arm/configs/sama5d4_xplained_defconfig        |    5 +-
 arch/arm/configs/versatilepb_arm1176_defconfig     |    4 +-
 arch/arm/configs/versatilepb_defconfig             |    4 +-
 arch/arm/configs/vexpress_ca9_defconfig            |    4 +-
 arch/arm/configs/vexpress_defconfig                |    4 +-
 arch/arm/configs/virt2real_defconfig               |    4 +-
 arch/arm/configs/zylonite310_defconfig             |    2 +-
 arch/arm/crypto/Makefile                           |   17 +
 arch/arm/crypto/sha1-armv4-large.S                 |  497 +++
 arch/arm/crypto/sha1_glue.c                        |  137 +
 arch/arm/crypto/sha256-armv4.pl                    |  717 ++++
 arch/arm/crypto/sha256-core.S_shipped              | 2779 ++++++++++++
 arch/arm/crypto/sha256_glue.c                      |  213 +
 arch/arm/crypto/sha256_glue.h                      |   23 +
 arch/arm/dts/Makefile                              |    1 +
 arch/arm/dts/imx6dl-eltec-hipercam.dts             |  324 ++
 arch/arm/mach-at91/Kconfig                         |    1 +
 arch/arm/mach-highbank/Kconfig                     |    1 +
 arch/arm/mach-imx/Kconfig                          |    5 +
 arch/arm/mach-imx/Makefile                         |    2 +-
 arch/arm/mach-imx/clk-gate-exclusive.c             |  103 +
 arch/arm/mach-imx/clk-imx6.c                       |   29 +
 arch/arm/mach-imx/clk.h                            |    3 +
 arch/arm/mach-imx/ocotp.c                          |    2 -
 arch/arm/mach-pxa/Kconfig                          |    5 +
 arch/efi/efi/efi-device.c                          |    3 +-
 arch/mips/configs/img-ci20_defconfig               |    6 +-
 arch/mips/configs/ritmix-rzx50_defconfig           |    6 +-
 arch/mips/configs/tplink-mr3020_defconfig          |    4 +-
 commands/Kconfig                                   |   51 +-
 commands/Makefile                                  |    4 +-
 commands/digest.c                                  |  228 +-
 commands/dmesg.c                                   |    2 +-
 commands/hashsum.c                                 |  194 +
 commands/internal.h                                |    2 +
 commands/state.c                                   |   77 +
 common/Kconfig                                     |   15 +
 common/Makefile                                    |    2 +-
 common/command.c                                   |    2 +
 common/digest.c                                    |  174 -
 common/password.c                                  |   99 +-
 common/state.c                                     | 1198 ++++++
 crypto/Kconfig                                     |   65 +-
 crypto/Makefile                                    |   14 +-
 crypto/digest.c                                    |  282 ++
 crypto/hmac.c                                      |  199 +
 crypto/md5.c                                       |   43 +-
 crypto/pbkdf2.c                                    |   94 +
 crypto/sha1.c                                      |  543 ++-
 crypto/sha2.c                                      |  610 +--
 crypto/sha4.c                                      |  293 ++
 drivers/base/driver.c                              |    9 +-
 drivers/base/platform.c                            |    3 +-
 drivers/i2c/i2c.c                                  |    3 +-
 drivers/misc/Kconfig                               |    4 +
 drivers/misc/Makefile                              |    1 +
 drivers/misc/state.c                               |   81 +
 drivers/mtd/core.c                                 |    4 +-
 drivers/net/Kconfig                                |    9 +
 drivers/net/Makefile                               |    1 +
 drivers/net/e1000.c                                | 4455 ++++++++++++++++++++
 drivers/net/e1000.h                                | 2093 +++++++++
 drivers/net/phy/mdio_bus.c                         |    2 +
 drivers/net/smc91111.c                             |   29 +
 drivers/pci/Kconfig                                |   10 +
 drivers/pci/Makefile                               |    2 +
 drivers/pci/bus.c                                  |    3 +-
 drivers/pci/pci-imx6.c                             |  612 +++
 drivers/pci/pci.c                                  |   45 +-
 drivers/pci/pcie-designware.c                      |  564 +++
 drivers/pci/pcie-designware.h                      |   71 +
 drivers/spi/spi.c                                  |    3 +-
 drivers/usb/host/xhci-hcd.c                        |   23 +-
 drivers/w1/w1.c                                    |    3 +-
 drivers/watchdog/im28wd.c                          |    7 +
 drivers/watchdog/imxwd.c                           |   61 +-
 dts/Bindings/arm/exynos/power_domain.txt           |    2 +
 dts/Bindings/arm/sti.txt                           |    4 +
 dts/Bindings/i2c/i2c-imx.txt                       |    1 +
 dts/Bindings/net/amd-xgbe-phy.txt                  |    4 +
 dts/Bindings/net/apm-xgene-enet.txt                |    5 +-
 dts/Bindings/power/power_domain.txt                |   29 +
 dts/Bindings/serial/{of-serial.txt => 8250.txt}    |    0
 dts/Bindings/serial/axis,etraxfs-uart.txt          |   19 +
 dts/Bindings/serial/snps-dw-apb-uart.txt           |   16 +
 dts/Bindings/submitting-patches.txt                |    3 +
 dts/Bindings/vendor-prefixes.txt                   |    2 +
 dts/Bindings/watchdog/atmel-wdt.txt                |    5 +
 dts/include/dt-bindings/pinctrl/am33xx.h           |    3 +-
 dts/include/dt-bindings/pinctrl/am43xx.h           |    3 +-
 dts/src/arm/am335x-bone-common.dtsi                |    9 +
 dts/src/arm/am335x-bone.dts                        |    8 -
 dts/src/arm/am335x-lxm.dts                         |    4 +
 dts/src/arm/am33xx-clocks.dtsi                     |    6 +-
 dts/src/arm/am437x-idk-evm.dts                     |   25 +-
 dts/src/arm/am43xx-clocks.dtsi                     |   12 +-
 dts/src/arm/am57xx-beagle-x15.dts                  |    8 -
 dts/src/arm/at91sam9260.dtsi                       |    7 +-
 dts/src/arm/at91sam9261.dtsi                       |    9 +-
 dts/src/arm/at91sam9263.dtsi                       |    5 +-
 dts/src/arm/at91sam9g45.dtsi                       |    3 +-
 dts/src/arm/at91sam9n12.dtsi                       |    1 -
 dts/src/arm/at91sam9x5.dtsi                        |    5 +-
 dts/src/arm/dm8168-evm.dts                         |   44 +
 dts/src/arm/dm816x.dtsi                            |   52 +-
 dts/src/arm/dra7-evm.dts                           |   18 +-
 dts/src/arm/dra7.dtsi                              |   10 +-
 dts/src/arm/dra72-evm.dts                          |   18 +-
 dts/src/arm/dra7xx-clocks.dtsi                     |   90 +-
 dts/src/arm/exynos3250.dtsi                        |    2 +
 dts/src/arm/exynos4-cpu-thermal.dtsi               |   52 +
 dts/src/arm/exynos4.dtsi                           |   45 +
 dts/src/arm/exynos4210-trats.dts                   |   19 +
 dts/src/arm/exynos4210-universal_c210.dts          |   57 +
 dts/src/arm/exynos4210.dtsi                        |   38 +-
 dts/src/arm/exynos4212.dtsi                        |    5 +-
 dts/src/arm/exynos4412-odroid-common.dtsi          |   64 +
 dts/src/arm/exynos4412-tmu-sensor-conf.dtsi        |   24 +
 dts/src/arm/exynos4412-trats2.dts                  |   15 +
 dts/src/arm/exynos4412.dtsi                        |    5 +-
 dts/src/arm/exynos4x12.dtsi                        |   12 +
 dts/src/arm/exynos5250.dtsi                        |   44 +-
 dts/src/arm/exynos5420-trip-points.dtsi            |   35 +
 dts/src/arm/exynos5420.dtsi                        |   33 +-
 dts/src/arm/exynos5440-tmu-sensor-conf.dtsi        |   24 +
 dts/src/arm/exynos5440-trip-points.dtsi            |   25 +
 dts/src/arm/exynos5440.dtsi                        |   18 +
 dts/src/arm/imx6qdl-sabresd.dtsi                   |    2 +
 dts/src/arm/imx6sl-evk.dts                         |    2 +
 dts/src/arm/omap2.dtsi                             |    4 +-
 dts/src/arm/omap3-n900.dts                         |    9 +-
 dts/src/arm/omap3.dtsi                             |    8 +-
 dts/src/arm/omap4.dtsi                             |    4 +-
 dts/src/arm/omap5-core-thermal.dtsi                |    2 +-
 dts/src/arm/omap5-gpu-thermal.dtsi                 |    2 +-
 dts/src/arm/omap5.dtsi                             |   12 +-
 dts/src/arm/omap54xx-clocks.dtsi                   |   41 +-
 dts/src/arm/rk3288.dtsi                            |    1 +
 dts/src/arm/sama5d3.dtsi                           |    3 +-
 dts/src/arm/sama5d4.dtsi                           |    9 +-
 dts/src/arm/socfpga.dtsi                           |    8 +-
 dts/src/arm/sun4i-a10-olinuxino-lime.dts           |   16 +
 dts/src/arm/sun4i-a10.dtsi                         |    3 +-
 dts/src/arm/sun5i-a13.dtsi                         |    3 +-
 dts/src/arm/sun7i-a20.dtsi                         |    3 +-
 dts/src/arm64/apm/apm-storm.dtsi                   |    4 +-
 dts/src/arm64/arm/foundation-v8.dts                |    8 +
 dts/src/arm64/arm/juno-clocks.dtsi                 |    2 +-
 dts/src/arm64/arm/juno.dts                         |   14 +
 dts/src/arm64/arm/rtsm_ve-aemv8a.dts               |    8 +
 images/Makefile                                    |    3 +
 images/Makefile.imx                                |    7 +-
 images/Makefile.mvebu                              |    2 -
 images/Makefile.mxs                                |    5 -
 images/Makefile.rockchip                           |    2 -
 images/Makefile.tegra                              |   18 +-
 include/asm-generic/barebox.lds.h                  |    3 +-
 include/command.h                                  |    3 +
 include/crypto/internal.h                          |    9 +
 include/crypto/pbkdf2.h                            |   23 +
 include/crypto/sha.h                               |   95 +
 include/digest.h                                   |  102 +-
 include/init.h                                     |    3 +-
 include/linux/pci_regs.h                           |  769 ++++
 include/mfd/imx6q-iomuxc-gpr.h                     |    8 +
 include/net/smc91111.h                             |    1 +
 include/state.h                                    |   21 +
 net/ping.c                                         |    6 +-
 scripts/imx/imx-image.c                            |   43 +-
 206 files changed, 19103 insertions(+), 1273 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/barebox/barebox,state.rst
 create mode 100644 arch/arm/boards/eltec-hipercam/Makefile
 create mode 100644 arch/arm/boards/eltec-hipercam/board.c
 create mode 100644 arch/arm/boards/eltec-hipercam/flash-header-eltec-hipercam.imxcfg
 create mode 100644 arch/arm/boards/eltec-hipercam/lowlevel.c
 create mode 100644 arch/arm/boards/mainstone/Makefile
 create mode 100644 arch/arm/boards/mainstone/board.c
 create mode 100644 arch/arm/boards/mainstone/env/boot/nor-ubi
 create mode 100644 arch/arm/boards/mainstone/env/init/mtdparts-nor
 create mode 100644 arch/arm/boards/mainstone/env/nv/linux.bootargs.console
 create mode 100644 arch/arm/boards/mainstone/lowlevel.c
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/boot/mmc
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/boot/nand
 delete mode 100644 arch/arm/boards/sama5d4_xplained/env/config
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/init/automount
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/init/mtdparts-nand
 rename arch/arm/boards/sama5d4_xplained/env/{bin/init_board => init/splash} (100%)
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/nv/boot.default
 create mode 100644 arch/arm/boards/sama5d4_xplained/env/nv/linux.bootargs.console
 create mode 100644 arch/arm/configs/mainstone_defconfig
 create mode 100644 arch/arm/crypto/Makefile
 create mode 100644 arch/arm/crypto/sha1-armv4-large.S
 create mode 100644 arch/arm/crypto/sha1_glue.c
 create mode 100644 arch/arm/crypto/sha256-armv4.pl
 create mode 100644 arch/arm/crypto/sha256-core.S_shipped
 create mode 100644 arch/arm/crypto/sha256_glue.c
 create mode 100644 arch/arm/crypto/sha256_glue.h
 create mode 100644 arch/arm/dts/imx6dl-eltec-hipercam.dts
 create mode 100644 arch/arm/mach-imx/clk-gate-exclusive.c
 create mode 100644 commands/hashsum.c
 create mode 100644 commands/internal.h
 create mode 100644 commands/state.c
 delete mode 100644 common/digest.c
 create mode 100644 common/state.c
 create mode 100644 crypto/digest.c
 create mode 100644 crypto/hmac.c
 create mode 100644 crypto/pbkdf2.c
 create mode 100644 crypto/sha4.c
 create mode 100644 drivers/misc/state.c
 create mode 100644 drivers/net/e1000.c
 create mode 100644 drivers/net/e1000.h
 create mode 100644 drivers/pci/pci-imx6.c
 create mode 100644 drivers/pci/pcie-designware.c
 create mode 100644 drivers/pci/pcie-designware.h
 rename dts/Bindings/serial/{of-serial.txt => 8250.txt} (100%)
 create mode 100644 dts/Bindings/serial/axis,etraxfs-uart.txt
 create mode 100644 dts/src/arm/exynos4-cpu-thermal.dtsi
 create mode 100644 dts/src/arm/exynos4412-tmu-sensor-conf.dtsi
 create mode 100644 dts/src/arm/exynos5420-trip-points.dtsi
 create mode 100644 dts/src/arm/exynos5440-tmu-sensor-conf.dtsi
 create mode 100644 dts/src/arm/exynos5440-trip-points.dtsi
 create mode 100644 include/crypto/internal.h
 create mode 100644 include/crypto/pbkdf2.h
 create mode 100644 include/crypto/sha.h
 create mode 100644 include/state.h
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From u.kleine-koenig at pengutronix.de  Wed May  6 00:12:28 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 6 May 2015 09:12:28 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <20150505155450.GB6325@pengutronix.de>
References: <5548DA0A.3050408@elfin.de> <20150505155450.GB6325@pengutronix.de>
Message-ID: <20150506071228.GQ25193@pengutronix.de>

Hello,

On Tue, May 05, 2015 at 05:54:50PM +0200, Sascha Hauer wrote:
> On Tue, May 05, 2015 at 04:56:10PM +0200, Marcel Behlau wrote:
> > i'm using a phyFLEX-i.MX6 SBC and want to communicate with an
> > external ?C over I2C. I only want to read/set 1 register, so i tried
> > to use the builtin i2c_read and i2c_write-Commands. The ?C is
> > connected to i2c-bus 1 of the device, so i tried to probe the hole
> > bus with "i2c_bus 1 3 30". The command only answered with
> > "i2c_probe: No such device". I tried also the busses 0-3, with the
> > same result. I searched in the board.c sourcecode of the phyflex,
> > but couldn't find i2c related stuff, so i think, i have to add the
> > initalisation for the i2c.
> > 
> > Do i have to add the i2c-init in the boards/phytec-pfla02/board.c
> > -file? Is there some documenation about this stuff?
> 
> The phyFLEX board is device tree based. You have to enable the i2c
> controller in the dts file (same as you would do in the kernel).
> Usually a:
> 
> &i2c0 {
> 	status = "okay";
> };
> 
> Should be enough. You probably also have to add the proper pinctrl node.
and enable the i2c driver. You might want to check the output of
devinfo.

Best regards
Uwe

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


From mkl at pengutronix.de  Wed May  6 05:51:30 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:30 +0200
Subject: [PATCH 5/6] watchdog: add static inline no-ops if WD is disabled
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1430916691-12459-5-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 include/watchdog.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/include/watchdog.h b/include/watchdog.h
index 3e2d08e87645..7e37b7c22a8d 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -17,8 +17,25 @@ struct watchdog {
 	int (*set_timeout)(struct watchdog *, unsigned);
 };
 
+#ifdef CONFIG_WATCHDOG
 int watchdog_register(struct watchdog *);
 int watchdog_deregister(struct watchdog *);
 int watchdog_set_timeout(unsigned);
+#else
+static inline int watchdog_register(struct watchdog *w)
+{
+	return 0;
+}
+
+int watchdog_deregister(struct watchdog *w)
+{
+	return 0;
+}
+
+int watchdog_set_timeout(unsigned t)
+{
+	return 0;
+}
+#endif
 
 #endif /* INCLUDE_WATCHDOG_H */
-- 
2.1.4



From mkl at pengutronix.de  Wed May  6 05:51:29 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:29 +0200
Subject: [PATCH 4/6] state: state_new_from_fdt(): remove unused function
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1430916691-12459-4-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c  | 21 ---------------------
 include/state.h |  1 -
 2 files changed, 22 deletions(-)

diff --git a/common/state.c b/common/state.c
index 7f12341bd578..cc44cecb484f 100644
--- a/common/state.c
+++ b/common/state.c
@@ -678,27 +678,6 @@ struct state *state_new_from_node(const char *name, struct device_node *node)
 		return ERR_PTR(ret);
 	}
 
-	return state;
-}
-
-/*
- * state_new_from_fdt - create a new state instance from a fdt binary blob
- *
- * @name	The name of the new state instance
- * @fdt		The fdt binary blob describing the new state instance
- */
-struct state *state_new_from_fdt(const char *name, void *fdt)
-{
-	struct state *state;
-	struct device_node *root;
-
-	root = of_unflatten_dtb(fdt);
-	if (!root)
-		return ERR_PTR(-EINVAL);
-
-	state = state_new_from_node(name, root);
-
-	of_delete_node(root);
 
 	return state;
 }
diff --git a/include/state.h b/include/state.h
index e96d3bfb2e4f..d321451e1490 100644
--- a/include/state.h
+++ b/include/state.h
@@ -9,7 +9,6 @@ int state_backend_dtb_file(struct state *state, const char *path);
 int state_backend_raw_file(struct state *state, const char *path,
 		off_t offset, size_t size);
 
-struct state *state_new_from_fdt(const char *name, void *fdt);
 struct state *state_new_from_node(const char *name, struct device_node *node);
 
 struct state *state_by_name(const char *name);
-- 
2.1.4



From mkl at pengutronix.de  Wed May  6 05:51:28 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:28 +0200
Subject: [PATCH 3/6] state: state_uint32_create: use %u to print unsigned
 variable
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1430916691-12459-3-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/state.c b/common/state.c
index b677a9f01d25..7f12341bd578 100644
--- a/common/state.c
+++ b/common/state.c
@@ -162,7 +162,7 @@ static struct state_variable *state_uint32_create(struct state *state,
 	su32 = xzalloc(sizeof(*su32));
 
 	param = dev_add_param_int(&state->dev, name, state_set_dirty,
-				  NULL, &su32->value, "%d", state);
+				  NULL, &su32->value, "%u", state);
 	if (IS_ERR(param)) {
 		free(su32);
 		return ERR_CAST(param);
-- 
2.1.4



From mkl at pengutronix.de  Wed May  6 05:51:27 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:27 +0200
Subject: [PATCH 2/6] state: documentation: add anchor so that state can be
 referenced later
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1430916691-12459-2-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 Documentation/devicetree/bindings/barebox/barebox,state.rst | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/barebox/barebox,state.rst b/Documentation/devicetree/bindings/barebox/barebox,state.rst
index 42b2a34d3ab0..7156084c9364 100644
--- a/Documentation/devicetree/bindings/barebox/barebox,state.rst
+++ b/Documentation/devicetree/bindings/barebox/barebox,state.rst
@@ -1,4 +1,6 @@
-barebox,state
+.. _barebox,state:
+
+barebox state
 =============
 
 Overview
-- 
2.1.4



From mkl at pengutronix.de  Wed May  6 05:51:26 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:26 +0200
Subject: [PATCH 1/6] fdt: of_unflatten_dtb(): remove left over "root" argument
 from inline doc
Message-ID: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>

In commit

    d384b5639fc1 of: Drop devicetree merge support

the signature of of_unflatten_dtb() was changed, but the inline documentation
was forgotten to adjust. This patch removes the left over "root" argument from
the doc.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 drivers/of/fdt.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index dfa95c38c801..88f0523260ed 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -48,7 +48,6 @@ static inline char *dt_string(struct fdt_header *f, char *strstart, uint32_t ofs
 
 /**
  * of_unflatten_dtb - unflatten a dtb binary blob
- * @root - node in which the fdt blob should be merged into or NULL
  * @infdt - the fdt blob to unflatten
  *
  * Parse a flat device tree binary blob and return a pointer to the
-- 
2.1.4



From mkl at pengutronix.de  Wed May  6 05:51:31 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed,  6 May 2015 14:51:31 +0200
Subject: [PATCH 6/6] startup: introduce postenvironment_initcall
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1430916691-12459-6-git-send-email-mkl@pengutronix.de>

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

To allow init code that depends on the environment being loaded.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/startup.c                  | 28 ++++++++++++++++++----------
 include/asm-generic/barebox.lds.h |  4 +++-
 include/init.h                    |  2 ++
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/common/startup.c b/common/startup.c
index e59b06d533e6..6178fc53531b 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -62,6 +62,24 @@ static int mount_root(void)
 fs_initcall(mount_root);
 #endif
 
+#ifdef CONFIG_ENV_HANDLING
+static int load_environment(void)
+{
+	const char *default_environment_path;
+
+	default_environment_path = default_environment_path_get();
+
+	if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT))
+		defaultenv_load("/env", 0);
+
+	envfs_load(default_environment_path, "/env", 0);
+	nvvar_load();
+
+	return 0;
+}
+environment_initcall(load_environment);
+#endif
+
 int (*barebox_main)(void);
 
 void __noreturn start_barebox(void)
@@ -84,16 +102,6 @@ void __noreturn start_barebox(void)
 
 	pr_debug("initcalls done\n");
 
-	if (IS_ENABLED(CONFIG_ENV_HANDLING)) {
-		char *default_environment_path = default_environment_path_get();
-
-		if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT))
-			defaultenv_load("/env", 0);
-
-		envfs_load(default_environment_path, "/env", 0);
-		nvvar_load();
-	}
-
 	if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) {
 		pr_info("running /env/bin/init...\n");
 
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index e359187d7f85..254397ee97b3 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -34,7 +34,9 @@
 	KEEP(*(.initcall.9))			\
 	KEEP(*(.initcall.10))			\
 	KEEP(*(.initcall.11))			\
-	KEEP(*(.initcall.12))
+	KEEP(*(.initcall.12))			\
+	KEEP(*(.initcall.13))			\
+	KEEP(*(.initcall.14))
 
 #define BAREBOX_CMDS	KEEP(*(SORT_BY_NAME(.barebox_cmd*)))
 
diff --git a/include/init.h b/include/init.h
index 37c7eedf6747..f619c951d377 100644
--- a/include/init.h
+++ b/include/init.h
@@ -39,6 +39,8 @@ typedef int (*initcall_t)(void);
 #define device_initcall(fn)		__define_initcall("10",fn,10)
 #define crypto_initcall(fn)		__define_initcall("11",fn,11)
 #define late_initcall(fn)		__define_initcall("12",fn,12)
+#define environment_initcall(fn)	__define_initcall("13",fn,13)
+#define postenvironment_initcall(fn)	__define_initcall("14",fn,14)
 
 /* section for code used very early when
  * - we're not running from where we linked at
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:31:55 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:31:55 -0700
Subject: [PATCH v3 00/18] i.MX serial cleanup, bootstrap code fixes,
 boot via IRAM
Message-ID: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>

This patch set combines all previously sent patches together:

- Serial cleanups
- Bootstap code fixes/cleanup
- Boot via IRAM

I marked the whole thing as a version 3 since some of the included
patches in some of their incarnations had version 2 and I wanted to
decrease the amount of confusion I was creating :)

Andrey Smirnov (18):
  i.MX: Move UART definitions into a separate file
  i.MX: serial: Add constants for UART clock divisor
  i.MX: serial: Add baud rate calculation convenience functions
  i.MX: serial: Add UART init functions for DEBUG_LL
  i.MX: serial: Convert PUTC_LL to use IOMEM
  i.MX: serial: Convert i.MX51 and i.MX6 to use 'imx*_uart_setup_ll'
  i.MX51: babbage: Implement CONFIG_DEBUG_LL
  i.MX: serial: Distil common clock ungating code
  Makefile.lib: Make 'check_file_size' more flexible
  i.MX: Add provisions to boot from IRAM
  imx-image: Correctly fill image size in prepended header
  bootstrap: Fix potential memory leak in 'read_image_head'
  bootstrap_read_devfs(): Check for errors from devfs_add_partition()
  bootstrap_read_devfs(): Close file after we are done with it
  bootstrap_read_devfs(): Fix potential memory leak
  bootstrap_read_devfs(): Check for errors from dev_add_bb_dev()
  bootstrap_read_devfs(): Remove all partitions upon function completion
  bootstrap: Warn if image size in BB header is zero

 Documentation/boards/imx.rst                       |  27 +++++
 Makefile                                           |   2 +-
 arch/arm/boards/eltec-hipercam/lowlevel.c          |  18 +--
 arch/arm/boards/embest-riotboard/lowlevel.c        |  16 +--
 arch/arm/boards/freescale-mx51-babbage/Makefile    |   3 +
 arch/arm/boards/freescale-mx51-babbage/board.c     |  60 ++++++++++
 .../flash-header-common.imxcfg                     |  58 ++++++++++
 .../flash-header-imx51-babbage-xload.imxcfg        |   3 +
 .../flash-header-imx51-babbage.imxcfg              |  60 +---------
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c  |  67 +++++++++++
 .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  20 +---
 arch/arm/boards/guf-santaro/lowlevel.c             |  18 +--
 arch/arm/boards/karo-tx6x/lowlevel.c               |  21 +---
 arch/arm/boards/phytec-phycard-imx6/lowlevel.c     |  21 +---
 arch/arm/boards/phytec-phyflex-imx6/lowlevel.c     |  21 +---
 arch/arm/boards/tqma6x/lowlevel.c                  |  18 +--
 arch/arm/boards/variscite-mx6/lowlevel.c           |  21 +---
 arch/arm/configs/imx_v7-xload_defconfig            |  52 +++++++++
 arch/arm/mach-imx/Kconfig                          |  15 +++
 arch/arm/mach-imx/Makefile                         |   1 +
 arch/arm/mach-imx/include/mach/clock-imx51_53.h    |   5 +-
 arch/arm/mach-imx/include/mach/debug_ll.h          |  85 ++++++++++++--
 arch/arm/mach-imx/xload.c                          |  52 +++++++++
 arch/arm/pbl/Makefile                              |   2 +-
 arch/mips/pbl/Makefile                             |   2 +-
 drivers/serial/serial_imx.c                        | 112 +-----------------
 images/Makefile.imx                                |  20 +++-
 include/serial/imx-uart.h                          | 128 +++++++++++++++++++++
 lib/bootstrap/devfs.c                              |  59 ++++++++--
 scripts/Makefile.lib                               |   6 +-
 scripts/imx/Makefile                               |   2 +
 scripts/imx/imx-image.c                            |  11 +-
 32 files changed, 658 insertions(+), 348 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg
 create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
 create mode 100644 arch/arm/configs/imx_v7-xload_defconfig
 create mode 100644 arch/arm/mach-imx/xload.c
 create mode 100644 include/serial/imx-uart.h

-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:31:57 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:31:57 -0700
Subject: [PATCH v3 02/18] i.MX: serial: Add constants for UART clock divisor
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-3-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 include/serial/imx-uart.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h
index e40843d..0a01788 100644
--- a/include/serial/imx-uart.h
+++ b/include/serial/imx-uart.h
@@ -77,6 +77,13 @@
 #define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
 #define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
 #define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV6	  (0b000<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV5	  (0b001<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV4	  (0b010<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV3	  (0b011<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV2	  (0b100<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV1	  (0b101<<7)  /* Reference freq divider mask */
+#define	 UFCR_RFDIV7	  (0b110<<7)  /* Reference freq divider mask */
 #define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
 #define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
 #define  USR1_RTSS  	 (1<<14) /* RTS pin status */
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:31:56 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:31:56 -0700
Subject: [PATCH v3 01/18] i.MX: Move UART definitions into a separate file
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-2-git-send-email-andrew.smirnov@gmail.com>

Move UART definitions into a separate file to avoid redefinition in
<mach/debug_ll.h> and magical constants in low level UART
initialization code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h |  10 +--
 drivers/serial/serial_imx.c               | 108 +---------------------------
 include/serial/imx-uart.h                 | 112 ++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 115 deletions(-)
 create mode 100644 include/serial/imx-uart.h

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index f34eaa1..31371e2 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -13,6 +13,8 @@
 #include <mach/imx53-regs.h>
 #include <mach/imx6-regs.h>
 
+#include <serial/imx-uart.h>
+
 #ifdef CONFIG_DEBUG_LL
 
 #ifdef CONFIG_DEBUG_IMX1_UART
@@ -40,14 +42,6 @@
 #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
 #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
 
-#define URTX0		0x40		/* Transmitter Register */
-
-#define UCR1		0x80		/* Control Register 1 */
-#define UCR1_UARTEN	(1 << 0)	/* UART enabled */
-
-#define USR2		0x98		/* Status Register 2 */
-#define USR2_TXDC	(1 << 3)	/* Transmitter complete */
-
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index cd954c2..6ae87fd 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -23,113 +23,7 @@
 #include <of.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-
-#define URXD0	0x0	/* Receiver Register */
-#define URTX0	0x40	/* Transmitter Register */
-#define UCR1	0x80	/* Control Register 1 */
-#define UCR2	0x84	/* Control Register 2 */
-#define UCR3	0x88	/* Control Register 3 */
-#define UCR4	0x8c	/* Control Register 4 */
-#define UFCR	0x90	/* FIFO Control Register */
-#define USR1	0x94	/* Status Register 1 */
-#define USR2	0x98	/* Status Register 2 */
-#define UESC	0x9c	/* Escape Character Register */
-#define UTIM	0xa0	/* Escape Timer Register */
-#define UBIR	0xa4	/* BRM Incremental Register */
-#define UBMR	0xa8	/* BRM Modulator Register */
-#define UBRC	0xac	/* Baud Rate Count Register */
-
-/* UART Control Register Bit Fields.*/
-#define  URXD_CHARRDY    (1<<15)
-#define  URXD_ERR        (1<<14)
-#define  URXD_OVRRUN     (1<<13)
-#define  URXD_FRMERR     (1<<12)
-#define  URXD_BRK        (1<<11)
-#define  URXD_PRERR      (1<<10)
-#define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
-#define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
-#define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
-#define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
-#define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
-#define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
-#define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
-#define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
-#define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
-#define  UCR1_SNDBRK     (1<<4)	 /* Send break */
-#define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
-#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
-#define  UCR1_DOZE       (1<<1)	 /* Doze */
-#define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
-#define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
-#define  UCR2_IRTS  	 (1<<14) /* Ignore RTS pin */
-#define  UCR2_CTSC  	 (1<<13) /* CTS pin control */
-#define  UCR2_CTS        (1<<12) /* Clear to send */
-#define  UCR2_ESCEN      (1<<11) /* Escape enable */
-#define  UCR2_PREN       (1<<8)  /* Parity enable */
-#define  UCR2_PROE       (1<<7)  /* Parity odd/even */
-#define  UCR2_STPB       (1<<6)	 /* Stop */
-#define  UCR2_WS         (1<<5)	 /* Word size */
-#define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
-#define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
-#define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
-#define  UCR2_SRST 	 (1<<0)	 /* SW reset */
-#define  UCR3_DTREN 	 (1<<13) /* DTR interrupt enable */
-#define  UCR3_PARERREN   (1<<12) /* Parity enable */
-#define  UCR3_FRAERREN   (1<<11) /* Frame error interrupt enable */
-#define  UCR3_DSR        (1<<10) /* Data set ready */
-#define  UCR3_DCD        (1<<9)  /* Data carrier detect */
-#define  UCR3_RI         (1<<8)  /* Ring indicator */
-#define  UCR3_ADNIMP     (1<<7)  /* Autobaud Detection Not Improved */
-#define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
-#define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
-#define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
-#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz (i.MXL / i.MX1) */
-#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz (i.MXL / i.MX1) */
-#define  UCR3_RXDMUXSEL  (1<<2)  /* RXD Muxed input select (i.MX27) */
-#define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
-#define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
-#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
-#define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
-#define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
-#define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
-#define  UCR4_REF16 	 (1<<6)  /* Ref freq 16 MHz */
-#define  UCR4_IRSC  	 (1<<5)  /* IR special case */
-#define  UCR4_TCEN  	 (1<<3)  /* Transmit complete interrupt enable */
-#define  UCR4_BKEN  	 (1<<2)  /* Break condition interrupt enable */
-#define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */
-#define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
-#define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
-#define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
-#define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
-#define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
-#define  USR1_RTSS  	 (1<<14) /* RTS pin status */
-#define  USR1_TRDY  	 (1<<13) /* Transmitter ready interrupt/dma flag */
-#define  USR1_RTSD  	 (1<<12) /* RTS delta */
-#define  USR1_ESCF  	 (1<<11) /* Escape seq interrupt flag */
-#define  USR1_FRAMERR    (1<<10) /* Frame error interrupt flag */
-#define  USR1_RRDY       (1<<9)	 /* Receiver ready interrupt/dma flag */
-#define  USR1_TIMEOUT    (1<<7)	 /* Receive timeout interrupt status */
-#define  USR1_RXDS  	 (1<<6)	 /* Receiver idle interrupt flag */
-#define  USR1_AIRINT	 (1<<5)	 /* Async IR wake interrupt flag */
-#define  USR1_AWAKE 	 (1<<4)	 /* Aysnc wake interrupt flag */
-#define  USR2_ADET  	 (1<<15) /* Auto baud rate detect complete */
-#define  USR2_TXFE  	 (1<<14) /* Transmit buffer FIFO empty */
-#define  USR2_DTRF  	 (1<<13) /* DTR edge interrupt flag */
-#define  USR2_IDLE  	 (1<<12) /* Idle condition */
-#define  USR2_IRINT 	 (1<<8)	 /* Serial infrared interrupt flag */
-#define  USR2_WAKE  	 (1<<7)	 /* Wake */
-#define  USR2_RTSF  	 (1<<4)	 /* RTS edge interrupt flag */
-#define  USR2_TXDC  	 (1<<3)	 /* Transmitter complete */
-#define  USR2_BRCD  	 (1<<2)	 /* Break condition */
-#define  USR2_ORE        (1<<1)	 /* Overrun error */
-#define  USR2_RDR        (1<<0)	 /* Recv data ready */
-#define  UTS_FRCPERR	 (1<<13) /* Force parity error */
-#define  UTS_LOOP        (1<<12) /* Loop tx and rx */
-#define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
-#define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
-#define  UTS_TXFULL 	 (1<<4)	 /* TxFIFO full */
-#define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
-#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
+#include <serial/imx-uart.h>
 
 /*
  * create default values for different platforms
diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h
new file mode 100644
index 0000000..e40843d
--- /dev/null
+++ b/include/serial/imx-uart.h
@@ -0,0 +1,112 @@
+#ifndef __IMX_UART_H__
+#define __IMX_UART_H__
+
+#define URXD0	0x0	/* Receiver Register */
+#define URTX0	0x40	/* Transmitter Register */
+#define UCR1	0x80	/* Control Register 1 */
+#define UCR2	0x84	/* Control Register 2 */
+#define UCR3	0x88	/* Control Register 3 */
+#define UCR4	0x8c	/* Control Register 4 */
+#define UFCR	0x90	/* FIFO Control Register */
+#define USR1	0x94	/* Status Register 1 */
+#define USR2	0x98	/* Status Register 2 */
+#define UESC	0x9c	/* Escape Character Register */
+#define UTIM	0xa0	/* Escape Timer Register */
+#define UBIR	0xa4	/* BRM Incremental Register */
+#define UBMR	0xa8	/* BRM Modulator Register */
+#define UBRC	0xac	/* Baud Rate Count Register */
+
+/* UART Control Register Bit Fields.*/
+#define  URXD_CHARRDY    (1<<15)
+#define  URXD_ERR        (1<<14)
+#define  URXD_OVRRUN     (1<<13)
+#define  URXD_FRMERR     (1<<12)
+#define  URXD_BRK        (1<<11)
+#define  URXD_PRERR      (1<<10)
+#define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
+#define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
+#define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
+#define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
+#define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
+#define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
+#define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
+#define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
+#define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
+#define  UCR1_SNDBRK     (1<<4)	 /* Send break */
+#define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
+#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
+#define  UCR1_DOZE       (1<<1)	 /* Doze */
+#define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
+#define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
+#define  UCR2_IRTS  	 (1<<14) /* Ignore RTS pin */
+#define  UCR2_CTSC  	 (1<<13) /* CTS pin control */
+#define  UCR2_CTS        (1<<12) /* Clear to send */
+#define  UCR2_ESCEN      (1<<11) /* Escape enable */
+#define  UCR2_PREN       (1<<8)  /* Parity enable */
+#define  UCR2_PROE       (1<<7)  /* Parity odd/even */
+#define  UCR2_STPB       (1<<6)	 /* Stop */
+#define  UCR2_WS         (1<<5)	 /* Word size */
+#define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
+#define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
+#define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
+#define  UCR2_SRST 	 (1<<0)	 /* SW reset */
+#define  UCR3_DTREN 	 (1<<13) /* DTR interrupt enable */
+#define  UCR3_PARERREN   (1<<12) /* Parity enable */
+#define  UCR3_FRAERREN   (1<<11) /* Frame error interrupt enable */
+#define  UCR3_DSR        (1<<10) /* Data set ready */
+#define  UCR3_DCD        (1<<9)  /* Data carrier detect */
+#define  UCR3_RI         (1<<8)  /* Ring indicator */
+#define  UCR3_ADNIMP     (1<<7)  /* Autobaud Detection Not Improved */
+#define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
+#define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
+#define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
+#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz (i.MXL / i.MX1) */
+#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz (i.MXL / i.MX1) */
+#define  UCR3_RXDMUXSEL  (1<<2)  /* RXD Muxed input select (i.MX27) */
+#define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
+#define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
+#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
+#define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
+#define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
+#define  UCR4_REF16 	 (1<<6)  /* Ref freq 16 MHz */
+#define  UCR4_IRSC  	 (1<<5)  /* IR special case */
+#define  UCR4_TCEN  	 (1<<3)  /* Transmit complete interrupt enable */
+#define  UCR4_BKEN  	 (1<<2)  /* Break condition interrupt enable */
+#define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */
+#define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
+#define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
+#define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
+#define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
+#define  USR1_RTSS  	 (1<<14) /* RTS pin status */
+#define  USR1_TRDY  	 (1<<13) /* Transmitter ready interrupt/dma flag */
+#define  USR1_RTSD  	 (1<<12) /* RTS delta */
+#define  USR1_ESCF  	 (1<<11) /* Escape seq interrupt flag */
+#define  USR1_FRAMERR    (1<<10) /* Frame error interrupt flag */
+#define  USR1_RRDY       (1<<9)	 /* Receiver ready interrupt/dma flag */
+#define  USR1_TIMEOUT    (1<<7)	 /* Receive timeout interrupt status */
+#define  USR1_RXDS  	 (1<<6)	 /* Receiver idle interrupt flag */
+#define  USR1_AIRINT	 (1<<5)	 /* Async IR wake interrupt flag */
+#define  USR1_AWAKE 	 (1<<4)	 /* Aysnc wake interrupt flag */
+#define  USR2_ADET  	 (1<<15) /* Auto baud rate detect complete */
+#define  USR2_TXFE  	 (1<<14) /* Transmit buffer FIFO empty */
+#define  USR2_DTRF  	 (1<<13) /* DTR edge interrupt flag */
+#define  USR2_IDLE  	 (1<<12) /* Idle condition */
+#define  USR2_IRINT 	 (1<<8)	 /* Serial infrared interrupt flag */
+#define  USR2_WAKE  	 (1<<7)	 /* Wake */
+#define  USR2_RTSF  	 (1<<4)	 /* RTS edge interrupt flag */
+#define  USR2_TXDC  	 (1<<3)	 /* Transmitter complete */
+#define  USR2_BRCD  	 (1<<2)	 /* Break condition */
+#define  USR2_ORE        (1<<1)	 /* Overrun error */
+#define  USR2_RDR        (1<<0)	 /* Recv data ready */
+#define  UTS_FRCPERR	 (1<<13) /* Force parity error */
+#define  UTS_LOOP        (1<<12) /* Loop tx and rx */
+#define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
+#define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
+#define  UTS_TXFULL 	 (1<<4)	 /* TxFIFO full */
+#define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
+#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
+
+
+#endif	/* __IMX_UART_H__ */
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:31:58 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:31:58 -0700
Subject: [PATCH v3 03/18] i.MX: serial: Add baud rate calculation convenience
 functions
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-4-git-send-email-andrew.smirnov@gmail.com>

Add two functions to calculate values for UBMR and UBIR
registers. This way both early serial initalization code and
serial_imx.c can use them and not duplicate the code.

Singed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 drivers/serial/serial_imx.c | 4 ++--
 include/serial/imx-uart.h   | 9 +++++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 6ae87fd..12155ad 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -178,9 +178,9 @@ static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate)
 	writel(val, regs + UCR1);
 
 	/* Set the numerator value minus one of the BRM ratio */
-	writel((baudrate / 100) - 1, regs + UBIR);
+	writel(baudrate_to_ubir(baudrate), regs + UBIR);
 	/* Set the denominator value minus one of the BRM ratio    */
-	writel((imx_serial_reffreq(priv) / 1600) - 1, regs + UBMR);
+	writel(refclock_to_ubmr(imx_serial_reffreq(priv)), regs + UBMR);
 
 	writel(ucr1, regs + UCR1);
 
diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h
index 0a01788..7275e6a 100644
--- a/include/serial/imx-uart.h
+++ b/include/serial/imx-uart.h
@@ -115,5 +115,14 @@
 #define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
 #define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
 
+static inline int baudrate_to_ubir(int baudrate)
+{
+	return baudrate / 100 - 1;
+}
+
+static inline int refclock_to_ubmr(int clock_hz)
+{
+	return clock_hz / 1600 - 1;
+}
 
 #endif	/* __IMX_UART_H__ */
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:00 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:00 -0700
Subject: [PATCH v3 05/18] i.MX: serial: Convert PUTC_LL to use IOMEM
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-6-git-send-email-andrew.smirnov@gmail.com>

Convert PUTC_LL to use IOMEM instead of explicit casting to 'void *',
since the former seem to be more appropriate to the situation.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index baf7f53..b9d1796 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -86,8 +86,8 @@ static inline void imx6_uart_setup_ll(void)
 
 static inline void PUTC_LL(int c)
 {
-	void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC,
-			CONFIG_DEBUG_IMX_UART_PORT);
+	void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,
+						 CONFIG_DEBUG_IMX_UART_PORT));
 
 	if (!base)
 		return;
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:31:59 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:31:59 -0700
Subject: [PATCH v3 04/18] i.MX: serial: Add UART init functions for DEBUG_LL
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-5-git-send-email-andrew.smirnov@gmail.com>

It appears that all i.MX51 and i.MX6 based boards that support early
debug output inevitably do exactly the same thing with the registers
of the UART peripheral. So to avoid code duplication three new
subroutines are introduced:

  - imx_uart_setup_ll() that allows user to perform aforementioned
    "same thing" on any arbitrary UART at 'uartbase' and clocked at
    'refclock' Hz.

  - imx6_uart_setup_ll() and imx5_uart_setup_ll() that do those
    actions assuming UART to be the one specified in configuration and
    'refclock' to be equal to what it is when SoC comes out of reset.

NOTE: Please note that 'imx*_uart_setup_ll' functions do add a slight
difference in behaviour by dropping the initialization of ONEMS and
UESC registers since those do not seem to be needed for early UART
functionality

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/include/mach/debug_ll.h | 55 +++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index 31371e2..baf7f53 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -3,6 +3,7 @@
 
 #include <io.h>
 #include <config.h>
+#include <common.h>
 #include <mach/imx1-regs.h>
 #include <mach/imx21-regs.h>
 #include <mach/imx25-regs.h>
@@ -17,6 +18,36 @@
 
 #ifdef CONFIG_DEBUG_LL
 
+#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
+#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
+
+static inline void imx_uart_setup_ll(void __iomem *uartbase,
+				     unsigned int refclock)
+{
+	writel(0x00000000, uartbase + UCR1);
+
+	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
+	       uartbase + UCR2);
+	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
+	       uartbase + UCR3);
+	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
+	       uartbase + UFCR);
+
+	writel(baudrate_to_ubir(CONFIG_BAUDRATE),
+	       uartbase + UBIR);
+	writel(refclock_to_ubmr(refclock),
+	       uartbase + UBMR);
+
+	writel(UCR1_UARTEN, uartbase + UCR1);
+}
+
+#define __imx_uart_setup_ll(refclock)					\
+	do {								\
+		imx_uart_setup_ll(IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,	\
+						      CONFIG_DEBUG_IMX_UART_PORT)), \
+				  refclock);				\
+	} while(0)
+
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define IMX_DEBUG_SOC MX1
 #elif defined CONFIG_DEBUG_IMX21_UART
@@ -39,8 +70,19 @@
 #error "unknown i.MX debug uart soc type"
 #endif
 
-#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
-#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
+static inline void imx51_uart_setup_ll(void)
+{
+#if defined CONFIG_DEBUG_IMX51_UART
+	__imx_uart_setup_ll(54000000);
+#endif
+}
+
+static inline void imx6_uart_setup_ll(void)
+{
+#if defined CONFIG_DEBUG_IMX6Q_UART
+	__imx_uart_setup(80000000);
+#endif
+}
 
 static inline void PUTC_LL(int c)
 {
@@ -57,5 +99,14 @@ static inline void PUTC_LL(int c)
 
 	writel(c, base + URTX0);
 }
+#else
+
+static inline void imx_uart_setup_ll(void __iomem *uartbase,
+				     unsigned int refclock)
+{
+}
+static inline void imx51_uart_setup_ll(void) {}
+static inline void imx6_uart_setup_ll(void)  {}
+
 #endif /* CONFIG_DEBUG_LL */
 #endif /* __MACH_DEBUG_LL_H__ */
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:02 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:02 -0700
Subject: [PATCH v3 07/18] i.MX51: babbage: Implement CONFIG_DEBUG_LL
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-8-git-send-email-andrew.smirnov@gmail.com>

Implement bits of configuraion needed to configure early debug output
support.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c | 42 +++++++++++++++++++++++
 arch/arm/mach-imx/include/mach/clock-imx51_53.h   |  5 +--
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index 0f453f3..ffb0548 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -1,9 +1,47 @@
+#include <debug_ll.h>
+#include <mach/clock-imx51_53.h>
 #include <common.h>
 #include <mach/esdctl.h>
 #include <mach/generic.h>
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>
 
+#ifdef CONFIG_DEBUG_LL
+static inline void setup_uart(void)
+{
+	void __iomem *iomuxbase = IOMEM(MX51_IOMUXC_BASE_ADDR);
+	void __iomem *ccmbase = IOMEM(MX51_CCM_BASE_ADDR);
+
+	/*
+	 * Restore CCM values that might be changed by the Mask ROM
+	 * code.
+	 *
+	 * Source: RealView debug scripts provided by Freescale
+	 */
+	writel(MX5_CCM_CBCDR_RESET_VALUE,  ccmbase + MX5_CCM_CBCDR);
+	writel(MX5_CCM_CSCMR1_RESET_VALUE, ccmbase + MX5_CCM_CSCMR1);
+	writel(MX5_CCM_CSCDR1_RESET_VALUE, ccmbase + MX5_CCM_CSCDR1);
+
+	/*
+	 * The code below should be more or less a "moral equivalent"
+	 * of:
+	 *	 MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+	 *
+	 * in device tree
+	 */
+	writel(0x00000000, iomuxbase + 0x022c);
+	writel(0x000001c5, iomuxbase + 0x061c);
+
+	imx51_uart_setup_ll();
+
+	putc_ll('>');
+}
+#else
+static inline void setup_uart(void)
+{
+}
+#endif	/* CONFIG_DEBUG_LL */
+
 extern char __dtb_imx51_babbage_start[];
 
 ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)
@@ -11,6 +49,10 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)
 	void *fdt;
 
 	imx5_cpu_lowlevel_init();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
 	arm_setup_stack(0x20000000 - 16);
 
 	fdt = __dtb_imx51_babbage_start - get_runtime_offset();
diff --git a/arch/arm/mach-imx/include/mach/clock-imx51_53.h b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
index 6004a6d..0f25dfb 100644
--- a/arch/arm/mach-imx/include/mach/clock-imx51_53.h
+++ b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
@@ -149,6 +149,7 @@
 #define MX5_CCM_CACRR_ARM_PODF_MASK	(0x7)
 
 /* Define the bits in register CBCDR */
+#define MX5_CCM_CBCDR_RESET_VALUE		(0x19239145)
 #define MX5_CCM_CBCDR_EMI_CLK_SEL		(0x1 << 26)
 #define MX5_CCM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
 #define MX5_CCM_CBCDR_DDR_HF_SEL_OFFSET		(30)
@@ -193,6 +194,7 @@
 #define MX5_CCM_CBCMR_PERCLK_IPG_CLK_SEL	(0x1 << 0)
 
 /* Define the bits in register CSCMR1 */
+#define MX5_CCM_CSCMR1_RESET_VALUE			(0xa6a2a020)
 #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET		(30)
 #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK		(0x3 << 30)
 #define MX5_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET		(28)
@@ -259,6 +261,7 @@
 #define MX5_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK		(0x3)
 
 /* Define the bits in register CSCDR1 */
+#define MX5_CCM_CSCDR1_RESET_VALUE			(0x00c30318)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET	(22)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK	(0x7 << 22)
 #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET	(19)
@@ -585,5 +588,3 @@
 #define MX5_SRPGC_EMI_PDNSCR	(MX5_SRPGC_EMI_BASE + 0x8)
 
 #endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
-
-
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:01 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:01 -0700
Subject: [PATCH v3 06/18] i.MX: serial: Convert i.MX51 and i.MX6 to use
 'imx*_uart_setup_ll'
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-7-git-send-email-andrew.smirnov@gmail.com>

NOTE: Boards 'karo-tx25' and 'tqma53' can benefit from this
refactoring as well, but they were not converted because of the lack
of i.MX25 or i.MX53 based hardware to test on.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/eltec-hipercam/lowlevel.c           | 18 ++++++------------
 arch/arm/boards/embest-riotboard/lowlevel.c         | 16 +---------------
 arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c | 11 +----------
 arch/arm/boards/guf-santaro/lowlevel.c              | 19 ++++++-------------
 arch/arm/boards/karo-tx6x/lowlevel.c                | 11 +----------
 arch/arm/boards/phytec-phycard-imx6/lowlevel.c      | 11 +----------
 arch/arm/boards/phytec-phyflex-imx6/lowlevel.c      | 11 +----------
 arch/arm/boards/tqma6x/lowlevel.c                   | 18 ++----------------
 arch/arm/boards/variscite-mx6/lowlevel.c            | 11 +----------
 9 files changed, 20 insertions(+), 106 deletions(-)

diff --git a/arch/arm/boards/eltec-hipercam/lowlevel.c b/arch/arm/boards/eltec-hipercam/lowlevel.c
index 8f11f67..21542e4 100644
--- a/arch/arm/boards/eltec-hipercam/lowlevel.c
+++ b/arch/arm/boards/eltec-hipercam/lowlevel.c
@@ -24,18 +24,10 @@
 
 static void setup_uart(void)
 {
-	void __iomem *uart_base = (void *)0x02020000;
-
 	writel(0x1, 0x020e0330);
-	writel(0x00000000, uart_base + 0x80);
-	writel(0x00004027, uart_base + 0x84);
-	writel(0x00000704, uart_base + 0x88);
-	writel(0x00000a81, uart_base + 0x90);
-	writel(0x0000002b, uart_base + 0x9c);
-	writel(0x00013880, uart_base + 0xb0);
-	writel(0x0000047f, uart_base + 0xa4);
-	writel(0x0000c34f, uart_base + 0xa8);
-	writel(0x00000001, uart_base + 0x80);
+
+	imx6_uart_setup_ll();
+
 	putc_ll('>');
 }
 
@@ -48,7 +40,9 @@ ENTRY_FUNCTION(start_imx6dl_eltec_hipercam, r0, r1, r2)
 	imx6_cpu_lowlevel_init();
 
 	arm_setup_stack(0x00940000 - 8);
-	setup_uart();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
 
 	fdt = __dtb_imx6dl_eltec_hipercam_start - get_runtime_offset();
 
diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c
index fe21b9a..59010da 100644
--- a/arch/arm/boards/embest-riotboard/lowlevel.c
+++ b/arch/arm/boards/embest-riotboard/lowlevel.c
@@ -10,20 +10,6 @@
 #include <mach/imx6-mmdc.h>
 #include <mach/imx6.h>
 
-static inline void setup_uart(void)
-{
-	/* Enable UART for lowlevel debugging purposes */
-	writel(0x00000000, 0x021e8080);
-	writel(0x00004027, 0x021e8084);
-	writel(0x00000704, 0x021e8088);
-	writel(0x00000a81, 0x021e8090);
-	writel(0x0000002b, 0x021e809c);
-	writel(0x00013880, 0x021e80b0);
-	writel(0x0000047f, 0x021e80a4);
-	writel(0x0000c34f, 0x021e80a8);
-	writel(0x00000001, 0x021e8080);
-}
-
 extern char __dtb_imx6s_riotboard_start[];
 
 ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2)
@@ -34,7 +20,7 @@ ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2)
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x4, 0x020e016c);
-		setup_uart();
+		imx6_uart_setup_ll();
 		putc_ll('a');
 	}
 
diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
index 4c5a74e..5fdd9df 100644
--- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
@@ -22,7 +22,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0xffffffff, ccmbase + 0x68);
@@ -38,15 +37,7 @@ static inline void setup_uart(void)
 	writel(0x0, iomuxbase + 0x28);
 	writel(0x1b0b1, iomuxbase + 0x0370);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000784, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x0001b0b0, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c
index 7753cea..3ccabf4 100644
--- a/arch/arm/boards/guf-santaro/lowlevel.c
+++ b/arch/arm/boards/guf-santaro/lowlevel.c
@@ -9,20 +9,11 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *uartbase = (void *)MX6_UART2_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x1, iomuxbase + 0x2b0);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
@@ -38,10 +29,12 @@ ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2)
 
 	arm_setup_stack(0x00920000 - 8);
 
-	for (i = 0x68; i <= 0x80; i += 4)
-		writel(0xffffffff, MX6_CCM_BASE_ADDR + i);
+	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
+		for (i = 0x68; i <= 0x80; i += 4)
+			writel(0xffffffff, MX6_CCM_BASE_ADDR + i);
 
-	setup_uart();
+		setup_uart();
+	}
 
 	fdt = __dtb_imx6q_guf_santaro_start - get_runtime_offset();
 
diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c
index cd4be5e..cb9d4c5 100644
--- a/arch/arm/boards/karo-tx6x/lowlevel.c
+++ b/arch/arm/boards/karo-tx6x/lowlevel.c
@@ -23,7 +23,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x1, iomuxbase + 0x0314);
@@ -39,15 +38,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000784, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x0001b0b0, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
index dc10649..1b8dca4 100644
--- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
@@ -27,7 +27,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR);
-	void __iomem *uartbase = IOMEM(MX6_UART3_BASE_ADDR);
 	void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);
 
 	writel(0x4, iomuxbase + 0x01f8);
@@ -40,15 +39,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
index ee6d7fb..51a2aa8 100644
--- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
@@ -28,7 +28,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART4_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x4, iomuxbase + 0x01f8);
@@ -41,15 +40,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c
index 23f3407..aec84b1 100644
--- a/arch/arm/boards/tqma6x/lowlevel.c
+++ b/arch/arm/boards/tqma6x/lowlevel.c
@@ -24,20 +24,6 @@
 #include <mach/imx6-mmdc.h>
 #include <mach/imx6.h>
 
-static inline void setup_uart(void)
-{
-	/* Enable UART for lowlevel debugging purposes */
-	writel(0x00000000, 0x021e8080);
-	writel(0x00004027, 0x021e8084);
-	writel(0x00000704, 0x021e8088);
-	writel(0x00000a81, 0x021e8090);
-	writel(0x0000002b, 0x021e809c);
-	writel(0x00013880, 0x021e80b0);
-	writel(0x0000047f, 0x021e80a4);
-	writel(0x0000c34f, 0x021e80a8);
-	writel(0x00000001, 0x021e8080);
-}
-
 extern char __dtb_imx6q_mba6x_start[];
 extern char __dtb_imx6dl_mba6x_start[];
 
@@ -51,7 +37,7 @@ ENTRY_FUNCTION(start_imx6q_mba6x, r0, r1, r2)
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x2, 0x020e0338);
-		setup_uart();
+		imx6_uart_setup_ll();
 		putc_ll('a');
 	}
 
@@ -72,7 +58,7 @@ ENTRY_FUNCTION(start_imx6dl_mba6x, r0, r1, r2)
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
 		writel(0x2, 0x020e035c);
-		setup_uart();
+		imx6_uart_setup_ll();
 		putc_ll('a');
 	}
 
diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c
index 22e7eae..7b1b4ab 100644
--- a/arch/arm/boards/variscite-mx6/lowlevel.c
+++ b/arch/arm/boards/variscite-mx6/lowlevel.c
@@ -29,7 +29,6 @@
 static inline void setup_uart(void)
 {
 	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
-	void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x03, iomuxbase + 0x0280);
@@ -43,15 +42,7 @@ static inline void setup_uart(void)
 	writel(0xffffffff, ccmbase + 0x7c);
 	writel(0xffffffff, ccmbase + 0x80);
 
-	writel(0x00000000, uartbase + 0x80);
-	writel(0x00004027, uartbase + 0x84);
-	writel(0x00000704, uartbase + 0x88);
-	writel(0x00000a81, uartbase + 0x90);
-	writel(0x0000002b, uartbase + 0x9c);
-	writel(0x00013880, uartbase + 0xb0);
-	writel(0x0000047f, uartbase + 0xa4);
-	writel(0x0000c34f, uartbase + 0xa8);
-	writel(0x00000001, uartbase + 0x80);
+	imx6_uart_setup_ll();
 
 	putc_ll('>');
 }
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:04 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:04 -0700
Subject: [PATCH v3 09/18] Makefile.lib: Make 'check_file_size' more flexible
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-10-git-send-email-andrew.smirnov@gmail.com>

Make 'check_file_size' more flexible by not hardcoding the file whose
size is going to be checked to '$@'. This way it is possible to use
this subroutine to check the size of files other than the target of
the rule.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 Makefile               | 2 +-
 arch/arm/pbl/Makefile  | 2 +-
 arch/mips/pbl/Makefile | 2 +-
 scripts/Makefile.lib   | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 372d18a..9ed0a1d 100644
--- a/Makefile
+++ b/Makefile
@@ -700,7 +700,7 @@ OBJCOPYFLAGS_barebox.bin = -O binary
 barebox.bin: barebox FORCE
 	$(call if_changed,objcopy)
 ifndef CONFIG_PBL_IMAGE
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 endif
 
 # By default the uImage load address is 2MB below CONFIG_TEXT_BASE,
diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile
index 4c1788d..1ff39db 100644
--- a/arch/arm/pbl/Makefile
+++ b/arch/arm/pbl/Makefile
@@ -22,7 +22,7 @@ endif
 
 $(obj)/zbarebox.bin:	$(obj)/zbarebox FORCE
 	$(call if_changed,objcopy)
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 	$(Q)$(kecho) '  Barebox: fix size'
 	$(Q)$(objtree)/scripts/fix_size -i -f $(objtree)/$@ $(FIX_SIZE)
 	$(Q)$(kecho) '  Barebox: $@ is ready'
diff --git a/arch/mips/pbl/Makefile b/arch/mips/pbl/Makefile
index fea1f24..b03bca1 100644
--- a/arch/mips/pbl/Makefile
+++ b/arch/mips/pbl/Makefile
@@ -15,7 +15,7 @@ extra-y       += piggy.gzip piggy.lz4 piggy.lzo piggy.lzma piggy.xzkern piggy.sh
 
 $(obj)/zbarebox.bin:	$(obj)/zbarebox FORCE
 	$(call if_changed,objcopy)
-	$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+	$(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
 	$(Q)$(kecho) '  Barebox: $@ is ready'
 
 $(obj)/zbarebox.S: $(obj)/zbarebox FORCE
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 57426d0..e991f33 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -388,10 +388,10 @@ quiet_cmd_ln = LN      $@
 cmd_ln = ln -sf $< $@
 
 # Check size of a file
-quiet_cmd_check_file_size = CHKSIZE $@
+quiet_cmd_check_file_size = CHKSIZE $2
       cmd_check_file_size = set -e;					\
-	size=`stat -c%s $@`;						\
-	max_size=`printf "%d" $2`;					\
+	size=`stat -c%s $2`;						\
+	max_size=`printf "%d" $3`;					\
 	if [ $$size -gt $$max_size ] ;					\
 	then								\
 		echo "$@ size $$size > of the maximum size $$max_size" >&2;	\
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:07 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:07 -0700
Subject: [PATCH v3 12/18] bootstrap: Fix potential memory leak in
 'read_image_head'
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-13-git-send-email-andrew.smirnov@gmail.com>

Original version of 'read_image_head' would not free the memory
allocated for barebox header in cases of any failure. Fix this by
adding a dedicated resourse de-allocation code path.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 704680a..82c7d21 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -35,7 +35,7 @@ static void *read_image_head(const char *name)
 	cdev = cdev_open(name, O_RDONLY);
 	if (!cdev) {
 		bootstrap_err("failed to open partition\n");
-		return NULL;
+		goto free_header;
 	}
 
 	ret = cdev_read(cdev, header, BAREBOX_HEAD_SIZE, 0, 0);
@@ -43,10 +43,14 @@ static void *read_image_head(const char *name)
 
 	if (ret != BAREBOX_HEAD_SIZE) {
 		bootstrap_err("failed to read from partition\n");
-		return NULL;
+		goto free_header;
 	}
 
 	return header;
+
+free_header:
+	free(header);
+	return NULL;
 }
 
 static unsigned int get_image_size(void *head)
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:06 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:06 -0700
Subject: [PATCH v3 11/18] imx-image: Correctly fill image size in prepended
 header
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-12-git-send-email-andrew.smirnov@gmail.com>

If called with '-b' option 'imx-image' tool prepends barebox header to
the image, but the tool does not fill the data at image size offset
correctly. Fix that.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 scripts/imx/Makefile    |  2 ++
 scripts/imx/imx-image.c | 11 ++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
index be0b490..ee0acc1 100644
--- a/scripts/imx/Makefile
+++ b/scripts/imx/Makefile
@@ -6,5 +6,7 @@ always          := $(hostprogs-y)
 HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
 HOSTLOADLIBES_imx-usb-loader  = `pkg-config --libs libusb-1.0`
 
+HOSTCFLAGS_imx-image.o = -I$(srctree)
+
 imx-usb-loader-objs := imx-usb-loader.o
 imx-image-objs := imx-image.o
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 25ea4d8..e765c1d 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -27,6 +27,8 @@
 #include <fcntl.h>
 #include <endian.h>
 
+#include <include/filetype.h>
+
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
@@ -91,9 +93,12 @@ static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imag
 {
 	struct imx_flash_header *hdr;
 	int dcdsize = curdcd * sizeof(uint32_t);
+	uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
 
-	if (add_barebox_header)
+	if (add_barebox_header) {
 		memcpy(buf, bb_header, sizeof(bb_header));
+		*psize = imagesize;
+	}
 
 	buf += offset;
 	hdr = buf;
@@ -177,6 +182,7 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag
 {
 	struct imx_flash_header_v2 *hdr;
 	int dcdsize = curdcd * sizeof(uint32_t);
+	uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET;
 
 	if (add_barebox_header)
 		memcpy(buf, bb_header, sizeof(bb_header));
@@ -201,6 +207,9 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag
 		hdr->boot_data.size += CSF_LEN;
 	}
 
+	if (add_barebox_header)
+		*psize = hdr->boot_data.size;
+
 	hdr->dcd_header.tag	= TAG_DCD_HEADER;
 	hdr->dcd_header.length	= htobe16(sizeof(uint32_t) + dcdsize);
 	hdr->dcd_header.version	= DCD_VERSION;
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:09 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:09 -0700
Subject: [PATCH v3 14/18] bootstrap_read_devfs(): Close file after we are done
 with it
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-15-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 0c47cd2..5693431 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -120,6 +120,8 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	}
 
 	ret = cdev_read(cdev, to, size, 0, 0);
+	cdev_close(cdev);
+
 	if (ret != size) {
 		bootstrap_err("%s: failed to read from %s\n", devname, partname);
 		return NULL;
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:03 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:03 -0700
Subject: [PATCH v3 08/18] i.MX: serial: Distil common clock ungating code
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-9-git-send-email-andrew.smirnov@gmail.com>

Move all of the common clock ungating code in early UART
initialization into a dedicated subroutine that can be shared by all
of the users.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  9 +--------
 arch/arm/boards/guf-santaro/lowlevel.c             |  7 ++-----
 arch/arm/boards/karo-tx6x/lowlevel.c               | 10 +---------
 arch/arm/boards/phytec-phycard-imx6/lowlevel.c     | 10 +---------
 arch/arm/boards/phytec-phyflex-imx6/lowlevel.c     | 10 +---------
 arch/arm/boards/variscite-mx6/lowlevel.c           | 10 +---------
 arch/arm/mach-imx/include/mach/debug_ll.h          | 22 ++++++++++++++++++++++
 7 files changed, 29 insertions(+), 49 deletions(-)

diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
index 5fdd9df..af26557 100644
--- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
+++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
@@ -21,16 +21,9 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
+	imx6_ungate_all_peripherals();
 
 	writel(0x0, iomuxbase + 0x24);
 	writel(0x1b0b1, iomuxbase + 0x036C);
diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c
index 3ccabf4..d57502b 100644
--- a/arch/arm/boards/guf-santaro/lowlevel.c
+++ b/arch/arm/boards/guf-santaro/lowlevel.c
@@ -13,6 +13,7 @@ static inline void setup_uart(void)
 
 	writel(0x1, iomuxbase + 0x2b0);
 
+	imx6_ungate_all_peripherals();
 	imx6_uart_setup_ll();
 
 	putc_ll('>');
@@ -29,12 +30,8 @@ ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2)
 
 	arm_setup_stack(0x00920000 - 8);
 
-	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
-		for (i = 0x68; i <= 0x80; i += 4)
-			writel(0xffffffff, MX6_CCM_BASE_ADDR + i);
-
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
-	}
 
 	fdt = __dtb_imx6q_guf_santaro_start - get_runtime_offset();
 
diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c
index cb9d4c5..1e44b1b 100644
--- a/arch/arm/boards/karo-tx6x/lowlevel.c
+++ b/arch/arm/boards/karo-tx6x/lowlevel.c
@@ -22,7 +22,6 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x1, iomuxbase + 0x0314);
@@ -30,14 +29,7 @@ static inline void setup_uart(void)
 	writel(0x1, iomuxbase + 0x0330);
 	writel(0x1, iomuxbase + 0x032c);
 
-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	imx6_ungate_all_peripherals();
 	imx6_uart_setup_ll();
 
 	putc_ll('>');
diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
index 1b8dca4..d85a1ab 100644
--- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c
@@ -26,19 +26,11 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR);
 	void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);
 
 	writel(0x4, iomuxbase + 0x01f8);
 
-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	imx6_ungate_all_peripherals();
 	imx6_uart_setup_ll();
 
 	putc_ll('>');
diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
index 51a2aa8..cd37f88 100644
--- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
+++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c
@@ -27,19 +27,11 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x4, iomuxbase + 0x01f8);
 
-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	imx6_ungate_all_peripherals();
 	imx6_uart_setup_ll();
 
 	putc_ll('>');
diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c
index 7b1b4ab..b0b930d 100644
--- a/arch/arm/boards/variscite-mx6/lowlevel.c
+++ b/arch/arm/boards/variscite-mx6/lowlevel.c
@@ -28,20 +28,12 @@
 
 static inline void setup_uart(void)
 {
-	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
 	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
 
 	writel(0x03, iomuxbase + 0x0280);
 	writel(0x03, iomuxbase + 0x0284);
 
-	writel(0xffffffff, ccmbase + 0x68);
-	writel(0xffffffff, ccmbase + 0x6c);
-	writel(0xffffffff, ccmbase + 0x70);
-	writel(0xffffffff, ccmbase + 0x74);
-	writel(0xffffffff, ccmbase + 0x78);
-	writel(0xffffffff, ccmbase + 0x7c);
-	writel(0xffffffff, ccmbase + 0x80);
-
+	imx6_ungate_all_peripherals();
 	imx6_uart_setup_ll();
 
 	putc_ll('>');
diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index b9d1796..8eb59f6 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -84,6 +84,21 @@ static inline void imx6_uart_setup_ll(void)
 #endif
 }
 
+#define __IMX_CCM_BASE(soc) soc##_CCM_BASE_ADDR
+#define IMX_CCM_BASE(soc) __IMX_CCM_BASE(soc)
+
+static inline void imx_ungate_all_peripherals(void __iomem *ccmbase)
+{
+	int i;
+	for (i = 0x68; i <= 0x80; i += 4)
+		writel(0xffffffff, ccmbase + i);
+}
+
+static inline void imx6_ungate_all_peripherals(void)
+{
+	imx_ungate_all_peripherals(IOMEM(MX6_CCM_BASE_ADDR));
+}
+
 static inline void PUTC_LL(int c)
 {
 	void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,
@@ -105,8 +120,15 @@ static inline void imx_uart_setup_ll(void __iomem *uartbase,
 				     unsigned int refclock)
 {
 }
+
 static inline void imx51_uart_setup_ll(void) {}
 static inline void imx6_uart_setup_ll(void)  {}
 
+static inline void imx_ungate_all_peripherals(void __iomem *ccmbase)
+{
+}
+
+static inline void imx6_ungate_all_peripherals(void) {}
+
 #endif /* CONFIG_DEBUG_LL */
 #endif /* __MACH_DEBUG_LL_H__ */
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:08 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:08 -0700
Subject: [PATCH v3 13/18] bootstrap_read_devfs(): Check for errors from
 devfs_add_partition()
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-14-git-send-email-andrew.smirnov@gmail.com>

Check for errors returned by devfs_add_partition() and bail if there
are any.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 82c7d21..0c47cd2 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -82,10 +82,17 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	int ret;
 	int size = 0;
 	void *to, *header;
-	struct cdev *cdev;
+	struct cdev *cdev, *partition;
 	char *partname = "x";
 
-	devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname);
+	partition = devfs_add_partition(devname, offset, max_size,
+					DEVFS_PARTITION_FIXED, partname);
+	if (IS_ERR(partition)) {
+		bootstrap_err("%s: failed to add partition (%ld)\n",
+			      devname, PTR_ERR(partition));
+		return NULL;
+	}
+
 	if (use_bb) {
 		dev_add_bb_dev(partname, "bbx");
 		partname = "bbx";
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:10 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:10 -0700
Subject: [PATCH v3 15/18] bootstrap_read_devfs(): Fix potential memory leak
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-16-git-send-email-andrew.smirnov@gmail.com>

In case of a failure in one of the cdev_* functions original version
of bootstrap_read_devfs would not release memory allocated for barebox
header or memory allocated for the image. This commit fixes this by
adding resource deallocation code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 5693431..576f151 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -81,7 +81,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 {
 	int ret;
 	int size = 0;
-	void *to, *header;
+	void *to, *header, *result = NULL;
 	struct cdev *cdev, *partition;
 	char *partname = "x";
 
@@ -116,16 +116,21 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	cdev = cdev_open(partname, O_RDONLY);
 	if (!cdev) {
 		bootstrap_err("%s: failed to open %s\n", devname, partname);
-		return NULL;
+		goto free_memory;
 	}
 
 	ret = cdev_read(cdev, to, size, 0, 0);
 	cdev_close(cdev);
 
-	if (ret != size) {
+	if (ret != size)
 		bootstrap_err("%s: failed to read from %s\n", devname, partname);
-		return NULL;
-	}
+	else
+		result = to;
+
+free_memory:
+	free(header);
+	if (!result)
+		free(to);
 
-	return to;
+	return result;
 }
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:13 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:13 -0700
Subject: [PATCH v3 18/18] bootstrap: Warn if image size in BB header is zero
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-19-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index b6edec7..5a64477 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -58,8 +58,12 @@ static unsigned int get_image_size(void *head)
 	unsigned int ret = 0;
 	unsigned int *psize = head + BAREBOX_HEAD_SIZE_OFFSET;
 
-	if (is_barebox_head(head))
+	if (is_barebox_head(head)) {
 		ret = *psize;
+		if (!ret)
+			bootstrap_err(
+				"image has correct magic, but the length is zero\n");
+	}
 	debug("Detected barebox image size %u\n", ret);
 
 	return ret;
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:05 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:05 -0700
Subject: [PATCH v3 10/18] i.MX: Add provisions to boot from IRAM
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-11-git-send-email-andrew.smirnov@gmail.com>

This commit add a very basic code to allow Barebox to be booted from
IRAM. Given that the amount of IRAM on most i.MX variants is
insufficient to contain a copy of Barebox with any reasonable degree
of functionality this code uses IRAM only as a temporary location and
eventually bootstraps from DRAM. But the presense of the intermediate
IRAM-only stage allows to add provisions to test the area of DRAM that
Barebox would be using to facilitate various testing scenarious.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 Documentation/boards/imx.rst                       | 27 ++++++++++
 arch/arm/boards/freescale-mx51-babbage/Makefile    |  3 ++
 arch/arm/boards/freescale-mx51-babbage/board.c     | 60 ++++++++++++++++++++++
 .../flash-header-common.imxcfg                     | 58 +++++++++++++++++++++
 .../flash-header-imx51-babbage-xload.imxcfg        |  3 ++
 .../flash-header-imx51-babbage.imxcfg              | 60 +---------------------
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c  | 25 +++++++++
 arch/arm/configs/imx_v7-xload_defconfig            | 52 +++++++++++++++++++
 arch/arm/mach-imx/Kconfig                          | 15 ++++++
 arch/arm/mach-imx/Makefile                         |  1 +
 arch/arm/mach-imx/xload.c                          | 52 +++++++++++++++++++
 images/Makefile.imx                                | 20 +++++++-
 12 files changed, 317 insertions(+), 59 deletions(-)
 create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg
 create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
 create mode 100644 arch/arm/configs/imx_v7-xload_defconfig
 create mode 100644 arch/arm/mach-imx/xload.c

diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst
index 466f69c..ef1a6a5 100644
--- a/Documentation/boards/imx.rst
+++ b/Documentation/boards/imx.rst
@@ -46,6 +46,33 @@ The images can also always be started second stage::
 
   bootm /mnt/tftp/barebox-freescale-imx51-babbage.img
 
+Internal Boot Mode Through Internal RAM(IRAM)
+---------------------------------------
+
+The Internal Boot Mode Through Internal RAM is supported on:
+
+* i.MX51
+
+As can be easily deduced from its name, the Internal Boot Mode Through
+Internal RAM is just a variant of Internal Boot Mode so all of the
+stated above still applies in this case. What it differs in is the following:
+
+* Boot process is done in two stages(First stage binary can be
+  produced with ``imx_v7-xload_defconfig``)
+* DCD of the first stage image is set such that the image is fetched
+  into an unoccupied area or IRAM
+* First stage image once uncompressed and set up will look for a
+  second stage bootloader on the same media it booted from and start
+  it(see mach-imx/xload.c for more details)
+* Second stage images are just regular i.MX boot images
+
+Since on a typical i.MX SoC unused IRAM area is not enough to run
+anything but a PBL this mode, due to its very limited usability,
+serves only one purpose -- allow for a portion of a bootloader to be
+executed without depending on DRAM to be functional. This peculiarity
+of the mode can be used to implement various memory testing
+scenarious.
+
 USB Boot
 ^^^^^^^^
 
diff --git a/arch/arm/boards/freescale-mx51-babbage/Makefile b/arch/arm/boards/freescale-mx51-babbage/Makefile
index 6252c88..31b8fcd 100644
--- a/arch/arm/boards/freescale-mx51-babbage/Makefile
+++ b/arch/arm/boards/freescale-mx51-babbage/Makefile
@@ -1,3 +1,6 @@
 obj-y += board.o flash-header-imx51-babbage.dcd.o
 extra-y += flash-header-imx51-babbage.dcd.S flash-header-imx51-babbage.dcd
 lwl-y += lowlevel.o
+
+obj-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.o
+extra-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.S flash-header-imx51-babbage-xload.dcd
diff --git a/arch/arm/boards/freescale-mx51-babbage/board.c b/arch/arm/boards/freescale-mx51-babbage/board.c
index 001873b..6650ff3 100644
--- a/arch/arm/boards/freescale-mx51-babbage/board.c
+++ b/arch/arm/boards/freescale-mx51-babbage/board.c
@@ -169,3 +169,63 @@ static int imx51_babbage_init(void)
 	return 0;
 }
 coredevice_initcall(imx51_babbage_init);
+
+#ifdef CONFIG_ARCH_IMX_XLOAD
+
+static int imx51_babbage_xload_init_pinmux(void)
+{
+	static const iomux_v3_cfg_t pinmux[] = {
+		/* (e)CSPI */
+		MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+		MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+		MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+
+		/* (e)CSPI chip select lines */
+		MX51_PAD_CSPI1_SS1__GPIO4_25,
+
+
+		/* eSDHC 1 */
+		MX51_PAD_SD1_CMD__SD1_CMD,
+		MX51_PAD_SD1_CLK__SD1_CLK,
+		MX51_PAD_SD1_DATA0__SD1_DATA0,
+		MX51_PAD_SD1_DATA1__SD1_DATA1,
+		MX51_PAD_SD1_DATA2__SD1_DATA2,
+		MX51_PAD_SD1_DATA3__SD1_DATA3,
+	};
+
+	mxc_iomux_v3_setup_multiple_pads(ARRAY_AND_SIZE(pinmux));
+
+	return 0;
+}
+coredevice_initcall(imx51_babbage_xload_init_pinmux);
+
+static int imx51_babbage_xload_init_devices(void)
+{
+	static int spi0_chipselects[] = {
+		IMX_GPIO_NR(4, 25),
+	};
+
+	static struct spi_imx_master spi0_pdata = {
+		.chipselect = spi0_chipselects,
+		.num_chipselect = ARRAY_SIZE(spi0_chipselects),
+	};
+
+	static const struct spi_board_info spi0_devices[] = {
+		{
+			.name		= "mtd_dataflash",
+			.chip_select	= 0,
+			.max_speed_hz	= 25 * 1000 * 1000,
+			.bus_num	= 0,
+		},
+	};
+
+	imx51_add_mmc0(NULL);
+
+	spi_register_board_info(ARRAY_AND_SIZE(spi0_devices));
+	imx51_add_spi0(&spi0_pdata);
+
+	return 0;
+}
+device_initcall(imx51_babbage_xload_init_devices);
+
+#endif
diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg
new file mode 100644
index 0000000..1332b74
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg
@@ -0,0 +1,58 @@
+soc imx51
+dcdofs 0x400
+wm 32 0x73fa88a0 0x00000200
+wm 32 0x73fa850c 0x000020c5
+wm 32 0x73fa8510 0x000020c5
+wm 32 0x73fa883c 0x00000002
+wm 32 0x73fa8848 0x00000002
+wm 32 0x73fa84b8 0x000000e7
+wm 32 0x73fa84bc 0x00000045
+wm 32 0x73fa84c0 0x00000045
+wm 32 0x73fa84c4 0x00000045
+wm 32 0x73fa84c8 0x00000045
+wm 32 0x73fa8820 0x00000000
+wm 32 0x73fa84a4 0x00000003
+wm 32 0x73fa84a8 0x00000003
+wm 32 0x73fa84ac 0x000000e3
+wm 32 0x73fa84b0 0x000000e3
+wm 32 0x73fa84b4 0x000000e3
+wm 32 0x73fa84cc 0x000000e3
+wm 32 0x73fa84d0 0x000000e2
+wm 32 0x73fa882c 0x00000004
+wm 32 0x73fa88a4 0x00000004
+wm 32 0x73fa88ac 0x00000004
+wm 32 0x73fa88b8 0x00000004
+wm 32 0x83fd9000 0x82a20000
+wm 32 0x83fd9008 0x82a20000
+wm 32 0x83fd9010 0x000ad0d0
+wm 32 0x83fd9004 0x3f3584ab
+wm 32 0x83fd900c 0x3f3584ab
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x0000801a
+wm 32 0x83fd9014 0x0000801b
+wm 32 0x83fd9014 0x00448019
+wm 32 0x83fd9014 0x07328018
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x06328018
+wm 32 0x83fd9014 0x03808019
+wm 32 0x83fd9014 0x00408019
+wm 32 0x83fd9014 0x00008000
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x0000801e
+wm 32 0x83fd9014 0x0000801f
+wm 32 0x83fd9014 0x0000801d
+wm 32 0x83fd9014 0x0732801c
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x0632801c
+wm 32 0x83fd9014 0x0380801d
+wm 32 0x83fd9014 0x0040801d
+wm 32 0x83fd9014 0x00008004
+wm 32 0x83fd9000 0xb2a20000
+wm 32 0x83fd9008 0xb2a20000
+wm 32 0x83fd9010 0x000ad6d0
+wm 32 0x83fd9034 0x90000000
+wm 32 0x83fd9014 0x00000000
diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
new file mode 100644
index 0000000..b249a7d
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
@@ -0,0 +1,3 @@
+loadaddr CONFIG_ARCH_IMX_UNUSED_IRAM_BASE
+
+#include "flash-header-common.imxcfg"
\ No newline at end of file
diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg
index bac6816..cb60e47 100644
--- a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg
+++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg
@@ -1,59 +1,3 @@
 loadaddr 0x90000000
-soc imx51
-dcdofs 0x400
-wm 32 0x73fa88a0 0x00000200
-wm 32 0x73fa850c 0x000020c5
-wm 32 0x73fa8510 0x000020c5
-wm 32 0x73fa883c 0x00000002
-wm 32 0x73fa8848 0x00000002
-wm 32 0x73fa84b8 0x000000e7
-wm 32 0x73fa84bc 0x00000045
-wm 32 0x73fa84c0 0x00000045
-wm 32 0x73fa84c4 0x00000045
-wm 32 0x73fa84c8 0x00000045
-wm 32 0x73fa8820 0x00000000
-wm 32 0x73fa84a4 0x00000003
-wm 32 0x73fa84a8 0x00000003
-wm 32 0x73fa84ac 0x000000e3
-wm 32 0x73fa84b0 0x000000e3
-wm 32 0x73fa84b4 0x000000e3
-wm 32 0x73fa84cc 0x000000e3
-wm 32 0x73fa84d0 0x000000e2
-wm 32 0x73fa882c 0x00000004
-wm 32 0x73fa88a4 0x00000004
-wm 32 0x73fa88ac 0x00000004
-wm 32 0x73fa88b8 0x00000004
-wm 32 0x83fd9000 0x82a20000
-wm 32 0x83fd9008 0x82a20000
-wm 32 0x83fd9010 0x000ad0d0
-wm 32 0x83fd9004 0x3f3584ab
-wm 32 0x83fd900c 0x3f3584ab
-wm 32 0x83fd9014 0x04008008
-wm 32 0x83fd9014 0x0000801a
-wm 32 0x83fd9014 0x0000801b
-wm 32 0x83fd9014 0x00448019
-wm 32 0x83fd9014 0x07328018
-wm 32 0x83fd9014 0x04008008
-wm 32 0x83fd9014 0x00008010
-wm 32 0x83fd9014 0x00008010
-wm 32 0x83fd9014 0x06328018
-wm 32 0x83fd9014 0x03808019
-wm 32 0x83fd9014 0x00408019
-wm 32 0x83fd9014 0x00008000
-wm 32 0x83fd9014 0x0400800c
-wm 32 0x83fd9014 0x0000801e
-wm 32 0x83fd9014 0x0000801f
-wm 32 0x83fd9014 0x0000801d
-wm 32 0x83fd9014 0x0732801c
-wm 32 0x83fd9014 0x0400800c
-wm 32 0x83fd9014 0x00008014
-wm 32 0x83fd9014 0x00008014
-wm 32 0x83fd9014 0x0632801c
-wm 32 0x83fd9014 0x0380801d
-wm 32 0x83fd9014 0x0040801d
-wm 32 0x83fd9014 0x00008004
-wm 32 0x83fd9000 0xb2a20000
-wm 32 0x83fd9008 0xb2a20000
-wm 32 0x83fd9010 0x000ad6d0
-wm 32 0x83fd9034 0x90000000
-wm 32 0x83fd9014 0x00000000
+
+#include "flash-header-common.imxcfg"
\ No newline at end of file
diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index ffb0548..57a324e 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -3,6 +3,7 @@
 #include <common.h>
 #include <mach/esdctl.h>
 #include <mach/generic.h>
+#include <asm/cache.h>
 #include <asm/barebox-arm-head.h>
 #include <asm/barebox-arm.h>
 
@@ -59,3 +60,27 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2)
 
 	imx51_barebox_entry(fdt);
 }
+
+static noinline void babbage_entry(void)
+{
+	arm_early_mmu_cache_invalidate();
+
+	relocate_to_current_adr();
+	setup_c();
+
+	puts_ll("lowlevel init done\n");
+
+	imx51_barebox_entry(NULL);
+}
+
+ENTRY_FUNCTION(start_imx51_babbage_xload, r0, r1, r2)
+{
+	imx5_cpu_lowlevel_init();
+
+	if (IS_ENABLED(CONFIG_DEBUG_LL))
+		setup_uart();
+
+	arm_setup_stack(0x20000000 - 16);
+
+	babbage_entry();
+}
diff --git a/arch/arm/configs/imx_v7-xload_defconfig b/arch/arm/configs/imx_v7-xload_defconfig
new file mode 100644
index 0000000..1d82f98
--- /dev/null
+++ b/arch/arm/configs/imx_v7-xload_defconfig
@@ -0,0 +1,52 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX_IMXIMAGE=y
+CONFIG_ARCH_IMX_XLOAD=y
+
+CONFIG_ARCH_IMX51=y
+CONFIG_IMX_MULTI_BOARDS=y
+CONFIG_MACH_FREESCALE_MX51_PDK=y
+
+CONFIG_THUMB2_BAREBOX=y
+# CONFIG_CMD_ARM_CPUINFO is not set
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x0
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_DUMMY=y
+CONFIG_RELOCATABLE=y
+CONFIG_BAUDRATE=115200
+CONFIG_SHELL_NONE=y
+
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_IMX51_UART=y
+CONFIG_DEBUG_IMX_UART_PORT=1
+
+CONFIG_HAS_DEBUG_LL=y
+
+CONFIG_MTD=y
+# CONFIG_MTD_WRITE is not set
+CONFIG_MTD_DATAFLASH=y
+
+# CONFIG_ERRNO_MESSAGES is not set
+# CONFIG_TIMESTAMP is not set
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+CONFIG_DRIVER_SERIAL_IMX=y
+
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+# CONFIG_MCI_WRITE is not set
+
+CONFIG_MCI_IMX_ESDHC=y
+
+CONFIG_EEPROM_AT25=y
+
+CONFIG_WATCHDOG_IMX_RESET_SOURCE=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_IMX=y
+
+# CONFIG_FS_RAMFS is not set
+# CONFIG_FS_DEVFS is not set
+CONFIG_FS_FAT=y
+CONFIG_BOOTSTRAP=y
+CONFIG_BOOTSTRAP_DISK=y
+CONFIG_BOOTSTRAP_DEVFS=y
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index c713477..3ccd060 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -68,6 +68,21 @@ config ARCH_IMX_IMXIMAGE
 	help
 	  if enabled the imx-image tool is compiled
 
+config ARCH_IMX_XLOAD
+	bool
+	depends on ARCH_IMX51
+	prompt "Build preloader image"
+
+config ARCH_IMX_UNUSED_IRAM_BASE
+       hex
+       depends on ARCH_IMX_XLOAD
+       default 0x1ffe2000 if ARCH_IMX51
+
+config ARCH_IMX_UNUSED_IRAM_SIZE
+       hex
+       depends on ARCH_IMX_XLOAD
+       default 0x16000 if ARCH_IMX51
+
 choice
 	depends on ARCH_IMX_INTERNAL_BOOT
 	prompt "Internal boot source"
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index ae953b1..0320d1c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -12,6 +12,7 @@ pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
 obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o
 lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
 obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
+obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
 obj-$(CONFIG_IMX_IIM)	+= iim.o
 obj-$(CONFIG_IMX_OCOTP)	+= ocotp.o
 obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/xload.c b/arch/arm/mach-imx/xload.c
new file mode 100644
index 0000000..16d56ab
--- /dev/null
+++ b/arch/arm/mach-imx/xload.c
@@ -0,0 +1,52 @@
+#include <bootsource.h>
+#include <bootstrap.h>
+#include <common.h>
+#include <malloc.h>
+#include <init.h>
+#include <envfs.h>
+#include <linux/sizes.h>
+#include <fs.h>
+#include <io.h>
+
+#include <linux/clkdev.h>
+#include <linux/stat.h>
+#include <linux/clk.h>
+
+#include <mach/devices-imx51.h>
+
+static __noreturn int imx_xload(void)
+{
+	enum bootsource bootsource = bootsource_get();
+	void *buf;
+
+	switch (bootsource) {
+	case BOOTSOURCE_MMC:
+		pr_info("booting from MMC\n");
+		buf = bootstrap_read_disk("disk0.0", "fat");
+		break;
+	case BOOTSOURCE_SPI:
+		pr_info("booting from SPI\n");
+		buf = bootstrap_read_devfs("dataflash0", false,
+					   SZ_256K, SZ_1M, SZ_1M);
+		break;
+	default:
+		pr_err("unknown bootsource %d\n", bootsource);
+		hang();
+	}
+
+	if (!buf) {
+		pr_err("failed to load barebox.bin\n");
+		hang();
+	}
+
+	bootstrap_boot(buf, 0);
+
+	hang();
+}
+
+static int imx_devices_init(void)
+{
+	barebox_main = imx_xload;
+	return 0;
+}
+coredevice_initcall(imx_devices_init);
diff --git a/images/Makefile.imx b/images/Makefile.imx
index 415b294..6b44958 100644
--- a/images/Makefile.imx
+++ b/images/Makefile.imx
@@ -4,8 +4,15 @@
 
 # %.imximg - convert into i.MX image
 # ----------------------------------------------------------------
+
+ifdef CONFIG_ARCH_IMX_XLOAD
+$(obj)/%.imximg: $(obj)/% FORCE
+	$(call cmd,check_file_size,$<,$(CONFIG_ARCH_IMX_UNUSED_IRAM_SIZE))
+	$(call if_changed,imx_image)
+else
 $(obj)/%.imximg: $(obj)/% FORCE
 	$(call if_changed,imx_image)
+endif
 
 # ----------------------- i.MX25 based boards ---------------------------
 pblx-$(CONFIG_MACH_TX25) += start_imx25_karo_tx25
@@ -29,7 +36,18 @@ image-$(CONFIG_MACH_PCM038) += barebox-phytec-phycore-imx27.img
 pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage
 CFG_start_imx51_babbage.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg
 FILE_barebox-freescale-imx51-babbage.img = start_imx51_babbage.pblx.imximg
-image-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img
+imx-barebox-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img
+
+pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage_xload
+CFG_start_imx51_babbage_xload.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
+FILE_barebox-freescale-imx51-babbage-xload.img = start_imx51_babbage_xload.pblx.imximg
+imx-xload-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage-xload.img
+
+ifdef CONFIG_ARCH_IMX_XLOAD
+image-y += $(imx-xload-y)
+else
+image-y += $(imx-barebox-y)
+endif
 
 pblx-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += start_imx51_genesi_efikasb
 CFG_start_imx51_genesi_efikasb.pblx.imximg = $(board)/efika-mx-smartbook/flash-header-imx51-genesi-efikasb.imxcfg
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:12 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:12 -0700
Subject: [PATCH v3 17/18] bootstrap_read_devfs(): Remove all partitions upon
 function completion
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-18-git-send-email-andrew.smirnov@gmail.com>

Bootstrap_read_devfs does not remove the devices it creates during the
course of its execution which might be considered as a resource
leak. Remedy that by adding the code to remove those devices upon
function completion.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 48b74f9..b6edec7 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -99,7 +99,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 			bootstrap_err(
 				"%s: failed to add bad block aware partition (%d)\n",
 				devname, ret);
-			goto exit;
+			goto delete_devfs_partition;
 		}
 
 		partname = "bbx";
@@ -138,6 +138,14 @@ free_memory:
 	free(header);
 	if (!result)
 		free(to);
-exit:
+
+	if (use_bb) {
+		dev_remove_bb_dev(partname);
+		partname = "x";
+	}
+
+delete_devfs_partition:
+	devfs_del_partition(partname);
+
 	return result;
 }
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May  6 12:32:11 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed,  6 May 2015 12:32:11 -0700
Subject: [PATCH v3 16/18] bootstrap_read_devfs(): Check for errors from
 dev_add_bb_dev()
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1430940733-4415-17-git-send-email-andrew.smirnov@gmail.com>

Check for errors returned by dev_add_bb_dev() and bail if there
are any.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 lib/bootstrap/devfs.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c
index 576f151..48b74f9 100644
--- a/lib/bootstrap/devfs.c
+++ b/lib/bootstrap/devfs.c
@@ -94,7 +94,14 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset,
 	}
 
 	if (use_bb) {
-		dev_add_bb_dev(partname, "bbx");
+		ret = dev_add_bb_dev(partname, "bbx");
+		if (ret) {
+			bootstrap_err(
+				"%s: failed to add bad block aware partition (%d)\n",
+				devname, ret);
+			goto exit;
+		}
+
 		partname = "bbx";
 	}
 
@@ -131,6 +138,6 @@ free_memory:
 	free(header);
 	if (!result)
 		free(to);
-
+exit:
 	return result;
 }
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May  7 00:15:46 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 09:15:46 +0200
Subject: [PATCH 1/6] fdt: of_unflatten_dtb(): remove left over "root"
 argument from inline doc
In-Reply-To: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
References: <1430916691-12459-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150507071546.GL6325@pengutronix.de>

On Wed, May 06, 2015 at 02:51:26PM +0200, Marc Kleine-Budde wrote:
> In commit
> 
>     d384b5639fc1 of: Drop devicetree merge support
> 
> the signature of of_unflatten_dtb() was changed, but the inline documentation
> was forgotten to adjust. This patch removes the left over "root" argument from
> the doc.
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  drivers/of/fdt.c | 1 -
>  1 file changed, 1 deletion(-)

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  Thu May  7 00:49:26 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu,  7 May 2015 09:49:26 +0200
Subject: [PATCH] ARM: i.MX5: Add missing CONFIG_ prefix in test
Message-ID: <1430984966-25382-1-git-send-email-s.hauer@pengutronix.de>

The variable name misses a CONFIG_ prefix to work as expected.

Fixes: 05a1e4b ARM: i.MX5: Do not register fixed clocks twice

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

diff --git a/arch/arm/mach-imx/clk-imx5.c b/arch/arm/mach-imx/clk-imx5.c
index 8a0d875..6dc3c80 100644
--- a/arch/arm/mach-imx/clk-imx5.c
+++ b/arch/arm/mach-imx/clk-imx5.c
@@ -189,7 +189,7 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba
 	writel(0xffffffff, base + CCM_CCGR6);
 	writel(0xffffffff, base + CCM_CCGR7);
 
-	if (!IS_ENABLED(COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
+	if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
 		clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
 		clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
 	}
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May  7 00:51:08 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 09:51:08 +0200
Subject: [PATCH v3 00/18] i.MX serial cleanup, bootstrap code fixes, boot
 via IRAM
In-Reply-To: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150507075108.GM6325@pengutronix.de>

Hi Andrey,

I applied this series with some small changes.

Thanks
 Sascha

On Wed, May 06, 2015 at 12:31:55PM -0700, Andrey Smirnov wrote:
> This patch set combines all previously sent patches together:
> 
> - Serial cleanups
> - Bootstap code fixes/cleanup
> - Boot via IRAM
> 
> I marked the whole thing as a version 3 since some of the included
> patches in some of their incarnations had version 2 and I wanted to
> decrease the amount of confusion I was creating :)
> 
> Andrey Smirnov (18):
>   i.MX: Move UART definitions into a separate file
>   i.MX: serial: Add constants for UART clock divisor
>   i.MX: serial: Add baud rate calculation convenience functions
>   i.MX: serial: Add UART init functions for DEBUG_LL
>   i.MX: serial: Convert PUTC_LL to use IOMEM
>   i.MX: serial: Convert i.MX51 and i.MX6 to use 'imx*_uart_setup_ll'
>   i.MX51: babbage: Implement CONFIG_DEBUG_LL
>   i.MX: serial: Distil common clock ungating code
>   Makefile.lib: Make 'check_file_size' more flexible
>   i.MX: Add provisions to boot from IRAM
>   imx-image: Correctly fill image size in prepended header
>   bootstrap: Fix potential memory leak in 'read_image_head'
>   bootstrap_read_devfs(): Check for errors from devfs_add_partition()
>   bootstrap_read_devfs(): Close file after we are done with it
>   bootstrap_read_devfs(): Fix potential memory leak
>   bootstrap_read_devfs(): Check for errors from dev_add_bb_dev()
>   bootstrap_read_devfs(): Remove all partitions upon function completion
>   bootstrap: Warn if image size in BB header is zero
> 
>  Documentation/boards/imx.rst                       |  27 +++++
>  Makefile                                           |   2 +-
>  arch/arm/boards/eltec-hipercam/lowlevel.c          |  18 +--
>  arch/arm/boards/embest-riotboard/lowlevel.c        |  16 +--
>  arch/arm/boards/freescale-mx51-babbage/Makefile    |   3 +
>  arch/arm/boards/freescale-mx51-babbage/board.c     |  60 ++++++++++
>  .../flash-header-common.imxcfg                     |  58 ++++++++++
>  .../flash-header-imx51-babbage-xload.imxcfg        |   3 +
>  .../flash-header-imx51-babbage.imxcfg              |  60 +---------
>  arch/arm/boards/freescale-mx51-babbage/lowlevel.c  |  67 +++++++++++
>  .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  20 +---
>  arch/arm/boards/guf-santaro/lowlevel.c             |  18 +--
>  arch/arm/boards/karo-tx6x/lowlevel.c               |  21 +---
>  arch/arm/boards/phytec-phycard-imx6/lowlevel.c     |  21 +---
>  arch/arm/boards/phytec-phyflex-imx6/lowlevel.c     |  21 +---
>  arch/arm/boards/tqma6x/lowlevel.c                  |  18 +--
>  arch/arm/boards/variscite-mx6/lowlevel.c           |  21 +---
>  arch/arm/configs/imx_v7-xload_defconfig            |  52 +++++++++
>  arch/arm/mach-imx/Kconfig                          |  15 +++
>  arch/arm/mach-imx/Makefile                         |   1 +
>  arch/arm/mach-imx/include/mach/clock-imx51_53.h    |   5 +-
>  arch/arm/mach-imx/include/mach/debug_ll.h          |  85 ++++++++++++--
>  arch/arm/mach-imx/xload.c                          |  52 +++++++++
>  arch/arm/pbl/Makefile                              |   2 +-
>  arch/mips/pbl/Makefile                             |   2 +-
>  drivers/serial/serial_imx.c                        | 112 +-----------------
>  images/Makefile.imx                                |  20 +++-
>  include/serial/imx-uart.h                          | 128 +++++++++++++++++++++
>  lib/bootstrap/devfs.c                              |  59 ++++++++--
>  scripts/Makefile.lib                               |   6 +-
>  scripts/imx/Makefile                               |   2 +
>  scripts/imx/imx-image.c                            |  11 +-
>  32 files changed, 658 insertions(+), 348 deletions(-)
>  create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg
>  create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg
>  create mode 100644 arch/arm/configs/imx_v7-xload_defconfig
>  create mode 100644 arch/arm/mach-imx/xload.c
>  create mode 100644 include/serial/imx-uart.h
> 
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> 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 May  7 00:52:40 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 09:52:40 +0200
Subject: [PATCH v3 04/18] i.MX: serial: Add UART init functions for
 DEBUG_LL
In-Reply-To: <1430940733-4415-5-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
 <1430940733-4415-5-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150507075240.GN6325@pengutronix.de>

On Wed, May 06, 2015 at 12:31:59PM -0700, Andrey Smirnov wrote:
> It appears that all i.MX51 and i.MX6 based boards that support early
> debug output inevitably do exactly the same thing with the registers
> of the UART peripheral. So to avoid code duplication three new
> subroutines are introduced:
> 
>   - imx_uart_setup_ll() that allows user to perform aforementioned
>     "same thing" on any arbitrary UART at 'uartbase' and clocked at
>     'refclock' Hz.
> 
>   - imx6_uart_setup_ll() and imx5_uart_setup_ll() that do those
>     actions assuming UART to be the one specified in configuration and
>     'refclock' to be equal to what it is when SoC comes out of reset.
> 
> NOTE: Please note that 'imx*_uart_setup_ll' functions do add a slight
> difference in behaviour by dropping the initialization of ONEMS and
> UESC registers since those do not seem to be needed for early UART
> functionality
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/mach-imx/include/mach/debug_ll.h | 55 +++++++++++++++++++++++++++++--
>  1 file changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
> index 31371e2..baf7f53 100644
> --- a/arch/arm/mach-imx/include/mach/debug_ll.h
> +++ b/arch/arm/mach-imx/include/mach/debug_ll.h
> @@ -3,6 +3,7 @@
>  
>  #include <io.h>
>  #include <config.h>
> +#include <common.h>
>  #include <mach/imx1-regs.h>
>  #include <mach/imx21-regs.h>
>  #include <mach/imx25-regs.h>
> @@ -17,6 +18,36 @@
>  
>  #ifdef CONFIG_DEBUG_LL
>  
> +#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
> +#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
> +
> +static inline void imx_uart_setup_ll(void __iomem *uartbase,
> +				     unsigned int refclock)
> +{
> +	writel(0x00000000, uartbase + UCR1);
> +
> +	writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST,
> +	       uartbase + UCR2);
> +	writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL,
> +	       uartbase + UCR3);
> +	writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF),
> +	       uartbase + UFCR);
> +
> +	writel(baudrate_to_ubir(CONFIG_BAUDRATE),
> +	       uartbase + UBIR);
> +	writel(refclock_to_ubmr(refclock),
> +	       uartbase + UBMR);
> +
> +	writel(UCR1_UARTEN, uartbase + UCR1);
> +}
> +
> +#define __imx_uart_setup_ll(refclock)					\
> +	do {								\
> +		imx_uart_setup_ll(IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,	\
> +						      CONFIG_DEBUG_IMX_UART_PORT)), \
> +				  refclock);				\
> +	} while(0)
> +
>  #ifdef CONFIG_DEBUG_IMX1_UART
>  #define IMX_DEBUG_SOC MX1
>  #elif defined CONFIG_DEBUG_IMX21_UART
> @@ -39,8 +70,19 @@
>  #error "unknown i.MX debug uart soc type"
>  #endif
>  
> -#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR
> -#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num)
> +static inline void imx51_uart_setup_ll(void)
> +{
> +#if defined CONFIG_DEBUG_IMX51_UART
> +	__imx_uart_setup_ll(54000000);
> +#endif
> +}
> +
> +static inline void imx6_uart_setup_ll(void)
> +{
> +#if defined CONFIG_DEBUG_IMX6Q_UART
> +	__imx_uart_setup(80000000);
> +#endif

Typo here, should be __imx_uart_setup_ll like above. I also removed the
#ifdefs which seem unnecessary.

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  Thu May  7 00:56:37 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 09:56:37 +0200
Subject: [PATCH v3 08/18] i.MX: serial: Distil common clock ungating code
In-Reply-To: <1430940733-4415-9-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
 <1430940733-4415-9-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150507075637.GO6325@pengutronix.de>

On Wed, May 06, 2015 at 12:32:03PM -0700, Andrey Smirnov wrote:
> Move all of the common clock ungating code in early UART
> initialization into a dedicated subroutine that can be shared by all
> of the users.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c |  9 +--------
>  arch/arm/boards/guf-santaro/lowlevel.c             |  7 ++-----
>  arch/arm/boards/karo-tx6x/lowlevel.c               | 10 +---------
>  arch/arm/boards/phytec-phycard-imx6/lowlevel.c     | 10 +---------
>  arch/arm/boards/phytec-phyflex-imx6/lowlevel.c     | 10 +---------
>  arch/arm/boards/variscite-mx6/lowlevel.c           | 10 +---------
>  arch/arm/mach-imx/include/mach/debug_ll.h          | 22 ++++++++++++++++++++++
>  7 files changed, 29 insertions(+), 49 deletions(-)
> 
> diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> index 5fdd9df..af26557 100644
> --- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> +++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c
> @@ -21,16 +21,9 @@
>  
>  static inline void setup_uart(void)
>  {
> -	void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR;
>  	void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR;
>  
> -	writel(0xffffffff, ccmbase + 0x68);
> -	writel(0xffffffff, ccmbase + 0x6c);
> -	writel(0xffffffff, ccmbase + 0x70);
> -	writel(0xffffffff, ccmbase + 0x74);
> -	writel(0xffffffff, ccmbase + 0x78);
> -	writel(0xffffffff, ccmbase + 0x7c);
> -	writel(0xffffffff, ccmbase + 0x80);
> +	imx6_ungate_all_peripherals();
>  
>  	writel(0x0, iomuxbase + 0x24);
>  	writel(0x1b0b1, iomuxbase + 0x036C);
> diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c
> index 3ccabf4..d57502b 100644
> --- a/arch/arm/boards/guf-santaro/lowlevel.c
> +++ b/arch/arm/boards/guf-santaro/lowlevel.c
> @@ -13,6 +13,7 @@ static inline void setup_uart(void)
>  
>  	writel(0x1, iomuxbase + 0x2b0);
>  
> +	imx6_ungate_all_peripherals();
>  	imx6_uart_setup_ll();
>  
>  	putc_ll('>');
> @@ -29,12 +30,8 @@ ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2)
>  
>  	arm_setup_stack(0x00920000 - 8);
>  
> -	if (IS_ENABLED(CONFIG_DEBUG_LL)) {
> -		for (i = 0x68; i <= 0x80; i += 4)
> -			writel(0xffffffff, MX6_CCM_BASE_ADDR + i);

This leads to an unused variable warning. Fixed.

> diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
> index b9d1796..8eb59f6 100644
> --- a/arch/arm/mach-imx/include/mach/debug_ll.h
> +++ b/arch/arm/mach-imx/include/mach/debug_ll.h
> @@ -84,6 +84,21 @@ static inline void imx6_uart_setup_ll(void)
>  #endif
>  }
>  
> +#define __IMX_CCM_BASE(soc) soc##_CCM_BASE_ADDR
> +#define IMX_CCM_BASE(soc) __IMX_CCM_BASE(soc)

Unused, removed these.

> +
> +static inline void imx_ungate_all_peripherals(void __iomem *ccmbase)
> +{
> +	int i;
> +	for (i = 0x68; i <= 0x80; i += 4)
> +		writel(0xffffffff, ccmbase + i);
> +}
> +
> +static inline void imx6_ungate_all_peripherals(void)
> +{
> +	imx_ungate_all_peripherals(IOMEM(MX6_CCM_BASE_ADDR));
> +}
> +

I moved these out of the #ifdef CONFIG_DEBUG_LL since it's called from
the boards only when CONFIG_DEBUG_LL is enabled anyway. Even if not, it
may be desirable to be able to just ungate the clocks as a regular
usecase, not just when debugging is enabled. We might move these
functions out of debug_ll some day.

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  Thu May  7 00:57:19 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 09:57:19 +0200
Subject: [PATCH v3 07/18] i.MX51: babbage: Implement CONFIG_DEBUG_LL
In-Reply-To: <1430940733-4415-8-git-send-email-andrew.smirnov@gmail.com>
References: <1430940733-4415-1-git-send-email-andrew.smirnov@gmail.com>
 <1430940733-4415-8-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150507075719.GP6325@pengutronix.de>

On Wed, May 06, 2015 at 12:32:02PM -0700, Andrey Smirnov wrote:
> Implement bits of configuraion needed to configure early debug output
> support.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  arch/arm/boards/freescale-mx51-babbage/lowlevel.c | 42 +++++++++++++++++++++++
>  arch/arm/mach-imx/include/mach/clock-imx51_53.h   |  5 +--
>  2 files changed, 45 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> index 0f453f3..ffb0548 100644
> --- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> +++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
> @@ -1,9 +1,47 @@
> +#include <debug_ll.h>
> +#include <mach/clock-imx51_53.h>
>  #include <common.h>
>  #include <mach/esdctl.h>
>  #include <mach/generic.h>
>  #include <asm/barebox-arm-head.h>
>  #include <asm/barebox-arm.h>
>  
> +#ifdef CONFIG_DEBUG_LL
> +static inline void setup_uart(void)
> +{

I removed the #ifdef, this function called only when CONFIG_DEBUG_LL is
enabled anyway.

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 u.kleine-koenig at pengutronix.de  Thu May  7 01:45:45 2015
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Thu,  7 May 2015 10:45:45 +0200
Subject: [PATCH] devfs: be more lax with partition boundaries
Message-ID: <1430988346-25450-1-git-send-email-u.kleine-koenig@pengutronix.de>

If a partition starts inside its parent device but is too big such that
it extends over the device boundary, just chop it to the device's end.

This matches the behaviour of Linux.

The motivation for this change is that it makes it possible in some
cases to have the partitioning in a device tree fixed and still allow
different flash sizes.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 fs/devfs-core.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index f45f8cadf1b0..d456ebccaf06 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -290,12 +290,20 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
 
 	*end = offset + size;
 
-	if (offset < 0 || *end > cdev->size) {
-		pr_warn("partition %s not completely inside device %s\n",
-				partinfo->name, cdev->name);
+	if (offset < 0 || offset > cdev->size) {
+		pr_warn("start of partition %s not inside of device %s\n",
+			partinfo->name, cdev->name);
 		return ERR_PTR(-EINVAL);
 	}
 
+	if (*end > cdev->size) {
+		pr_warn("end of partition %s after end of device %s, chopping\n",
+			partinfo->name, cdev->name);
+
+		*end = cdev->size;
+		size = *end - offset;
+	}
+
 	if (IS_ENABLED(CONFIG_MTD) && cdev->mtd) {
 		struct mtd_info *mtd;
 
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May  7 01:57:02 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 7 May 2015 10:57:02 +0200
Subject: [PATCH] devfs: be more lax with partition boundaries
In-Reply-To: <1430988346-25450-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1430988346-25450-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <20150507085702.GR6325@pengutronix.de>

On Thu, May 07, 2015 at 10:45:45AM +0200, Uwe Kleine-K?nig wrote:
> If a partition starts inside its parent device but is too big such that
> it extends over the device boundary, just chop it to the device's end.
> 
> This matches the behaviour of Linux.
> 
> The motivation for this change is that it makes it possible in some
> cases to have the partitioning in a device tree fixed and still allow
> different flash sizes.

When doing it someone is probably annoyed about the warning pretty soon.
I know we just talked whether I would accept this patch, but now I
realized that the correct way to extend the last partition to the end of
the device is to use size 0. This works under barebox and Linux.

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 u.kleine-koenig at pengutronix.de  Thu May  7 02:09:17 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Thu, 7 May 2015 11:09:17 +0200
Subject: [PATCH] devfs: be more lax with partition boundaries
In-Reply-To: <20150507085702.GR6325@pengutronix.de>
References: <1430988346-25450-1-git-send-email-u.kleine-koenig@pengutronix.de>
 <20150507085702.GR6325@pengutronix.de>
Message-ID: <20150507090917.GJ12306@pengutronix.de>

Hello Sascha,

On Thu, May 07, 2015 at 10:57:02AM +0200, Sascha Hauer wrote:
> On Thu, May 07, 2015 at 10:45:45AM +0200, Uwe Kleine-K?nig wrote:
> > If a partition starts inside its parent device but is too big such that
> > it extends over the device boundary, just chop it to the device's end.
> > 
> > This matches the behaviour of Linux.
> > 
> > The motivation for this change is that it makes it possible in some
> > cases to have the partitioning in a device tree fixed and still allow
> > different flash sizes.
> 
> When doing it someone is probably annoyed about the warning pretty soon.
> I know we just talked whether I would accept this patch, but now I
well, we talked about a change in barebox that makes it match the
behaviour of Linux. So critic to the actual implementation is fine.

> realized that the correct way to extend the last partition to the end of
> the device is to use size 0. This works under barebox and Linux.
Great. Just tested this and it works fine. (I don't know if Linux really
handles this this way, but barebox does and gives the right explicit
size to Linux.)

\o/
Uwe

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


From marcel.behlau at elfin.de  Thu May  7 04:24:19 2015
From: marcel.behlau at elfin.de (Marcel Behlau)
Date: Thu, 07 May 2015 13:24:19 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <20150506071228.GQ25193@pengutronix.de>
References: <5548DA0A.3050408@elfin.de> <20150505155450.GB6325@pengutronix.de>
 <20150506071228.GQ25193@pengutronix.de>
Message-ID: <554B4B63.7020301@elfin.de>

Hi,

many thanks for your help. I activated the i2c devices in the device 
tree, the pinctrl is already done in the imx6q.dtsi, which is included. 
The used pins are identically with the used pins on the SBC. devinfo 
told me, that the driver "i2c-fsl" is loaded. After rebuild barebox, 
it's possible to probe the bus, but the command only answered with an 
timeout:

barebox at Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ i2c_probe 1 83 83
probing i2c range 0x53 - 0x53 :
i2c2: <i2c_fsl_bus_busy> timeout waiting for I2C bus busy

I'm using barebox-2013.08.0, which is provided by the phytec-bsp.

Thanks in advance,

Marcel


On 06.05.2015 09:12, Uwe Kleine-K?nig wrote:
> Hello,
>
> On Tue, May 05, 2015 at 05:54:50PM +0200, Sascha Hauer wrote:
>> On Tue, May 05, 2015 at 04:56:10PM +0200, Marcel Behlau wrote:
>>> i'm using a phyFLEX-i.MX6 SBC and want to communicate with an
>>> external ?C over I2C. I only want to read/set 1 register, so i tried
>>> to use the builtin i2c_read and i2c_write-Commands. The ?C is
>>> connected to i2c-bus 1 of the device, so i tried to probe the hole
>>> bus with "i2c_bus 1 3 30". The command only answered with
>>> "i2c_probe: No such device". I tried also the busses 0-3, with the
>>> same result. I searched in the board.c sourcecode of the phyflex,
>>> but couldn't find i2c related stuff, so i think, i have to add the
>>> initalisation for the i2c.
>>>
>>> Do i have to add the i2c-init in the boards/phytec-pfla02/board.c
>>> -file? Is there some documenation about this stuff?
>> The phyFLEX board is device tree based. You have to enable the i2c
>> controller in the dts file (same as you would do in the kernel).
>> Usually a:
>>
>> &i2c0 {
>> 	status = "okay";
>> };
>>
>> Should be enough. You probably also have to add the proper pinctrl node.
> and enable the i2c driver. You might want to check the output of
> devinfo.
>
> Best regards
> Uwe
>

-- 
Dipl. Ing (FH) Marcel Behlau
(Software Developer)

ELFIN GmbH
Siegburger Stra?e 215
50679 K?ln
Germany

Tel: +49 (221) 6778932-0
Fax: +49 (221) 6778932-2
marcel.behlau at elfin.de
www.elfin.de



From antonynpavlov at gmail.com  Thu May  7 15:59:33 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 8 May 2015 01:59:33 +0300
Subject: barebox on i.MX 6SoloX
Message-ID: <20150508015933.1e00066aab99376b174ddfcb@gmail.com>

Hi!

I have just readed about new RaspberyPi-like board: UDOO Neo.
See https://www.kickstarter.com/projects/udoo/udoo-neo-raspberry-pi-arduino-wi-fi-bt-40-sensors
for details.

The board's main chip is Freescale i.MX 6SoloX.

I see the arch/arm/mach-imx/imx6.c file in barebox source tree.

I have no knowledge on i.MX family, so my question is:
does barebox already support i.MX 6SoloX?

--?
Best regards,
? Antony Pavlov


From festevam at gmail.com  Thu May  7 16:02:51 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 7 May 2015 20:02:51 -0300
Subject: barebox on i.MX 6SoloX
In-Reply-To: <20150508015933.1e00066aab99376b174ddfcb@gmail.com>
References: <20150508015933.1e00066aab99376b174ddfcb@gmail.com>
Message-ID: <CAOMZO5AfOS8jsCPcS_LGCLoTLAC=gAGN9tAKBCOmUohMeGfZEw@mail.gmail.com>

On Thu, May 7, 2015 at 7:59 PM, Antony Pavlov <antonynpavlov at gmail.com> wrote:
> Hi!
>
> I have just readed about new RaspberyPi-like board: UDOO Neo.
> See https://www.kickstarter.com/projects/udoo/udoo-neo-raspberry-pi-arduino-wi-fi-bt-40-sensors
> for details.
>
> The board's main chip is Freescale i.MX 6SoloX.
>
> I see the arch/arm/mach-imx/imx6.c file in barebox source tree.
>
> I have no knowledge on i.MX family, so my question is:
> does barebox already support i.MX 6SoloX?

Yes, it does. Please check:
arch/arm/boards/freescale-mx6sx-sabresdb/board.c


From antonynpavlov at gmail.com  Thu May  7 22:01:33 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Fri, 8 May 2015 08:01:33 +0300
Subject: barebox on i.MX 6SoloX
In-Reply-To: <CAOMZO5AfOS8jsCPcS_LGCLoTLAC=gAGN9tAKBCOmUohMeGfZEw@mail.gmail.com>
References: <20150508015933.1e00066aab99376b174ddfcb@gmail.com>
 <CAOMZO5AfOS8jsCPcS_LGCLoTLAC=gAGN9tAKBCOmUohMeGfZEw@mail.gmail.com>
Message-ID: <20150508080133.0b514daf8524484a70fd09e6@gmail.com>

On Thu, 7 May 2015 20:02:51 -0300
Fabio Estevam <festevam at gmail.com> wrote:

> On Thu, May 7, 2015 at 7:59 PM, Antony Pavlov <antonynpavlov at gmail.com> wrote:
> > Hi!
> >
> > I have just readed about new RaspberyPi-like board: UDOO Neo.
> > See https://www.kickstarter.com/projects/udoo/udoo-neo-raspberry-pi-arduino-wi-fi-bt-40-sensors
> > for details.
> >
> > The board's main chip is Freescale i.MX 6SoloX.
> >
> > I see the arch/arm/mach-imx/imx6.c file in barebox source tree.
> >
> > I have no knowledge on i.MX family, so my question is:
> > does barebox already support i.MX 6SoloX?
> 
> Yes, it does. Please check:
> arch/arm/boards/freescale-mx6sx-sabresdb/board.c

Thanks!

Now I see that "6sx" is an abbriviation for 6SoloX.

-- 
--?
Best regards,
? Antony Pavlov


From s.hauer at pengutronix.de  Thu May  7 22:12:42 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 May 2015 07:12:42 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <554B4B63.7020301@elfin.de>
References: <5548DA0A.3050408@elfin.de> <20150505155450.GB6325@pengutronix.de>
 <20150506071228.GQ25193@pengutronix.de> <554B4B63.7020301@elfin.de>
Message-ID: <20150508051242.GV6325@pengutronix.de>

On Thu, May 07, 2015 at 01:24:19PM +0200, Marcel Behlau wrote:
> Hi,
> 
> many thanks for your help. I activated the i2c devices in the device
> tree, the pinctrl is already done in the imx6q.dtsi, which is
> included. The used pins are identically with the used pins on the
> SBC. devinfo told me, that the driver "i2c-fsl" is loaded. After
> rebuild barebox, it's possible to probe the bus, but the command
> only answered with an timeout:
> 
> barebox at Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ i2c_probe 1 83 83
> probing i2c range 0x53 - 0x53 :
> i2c2: <i2c_fsl_bus_busy> timeout waiting for I2C bus busy

I *think* this means that the levels on the bus do not properly follow
what the controller wants to do. Maybe pullup missing? An oscilloscope
might help here.

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  Thu May  7 22:19:22 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 8 May 2015 07:19:22 +0200
Subject: [PATCH] Documentation: booting linux: improve doc text
In-Reply-To: <1430675710-11568-1-git-send-email-r.schwebel@pengutronix.de>
References: <1430675710-11568-1-git-send-email-r.schwebel@pengutronix.de>
Message-ID: <20150508051922.GY6325@pengutronix.de>

On Sun, May 03, 2015 at 07:55:10PM +0200, Robert Schwebel wrote:
> Signed-off-by: Robert Schwebel <r.schwebel at pengutronix.de>
> ---
>  Documentation/user/booting-linux.rst | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 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 mpa at pengutronix.de  Fri May  8 01:49:14 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri,  8 May 2015 10:49:14 +0200
Subject: [PATCH] imx6: lowlevel_init: Fix workaround for new i.MX6s chips
Message-ID: <1431074954-28737-1-git-send-email-mpa@pengutronix.de>

This errata workaround was introduced for i.MX6Q, i.MX6D and i.MX6SL.
Old revisions of i.MX6s chips had no problems with the PFD resets.

In a newer i.MX6s revision I had issues with this code when booting in
internal boot mode from NAND or in serial downloader mode. FUSE mode
worked fine although it jumped directly to serial downloader mode.

This patch executes the PFD workaround only for i.MX6Q and i.MX6D which
fixes the issues I saw.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 arch/arm/mach-imx/imx6.c | 48 +++++++++++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 73630e70927a..7508964bf549 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -30,7 +30,8 @@ void imx6_init_lowlevel(void)
 	void __iomem *aips1 = (void *)MX6_AIPS1_ON_BASE_ADDR;
 	void __iomem *aips2 = (void *)MX6_AIPS2_ON_BASE_ADDR;
 	void __iomem *iomux = (void *)MX6_IOMUXC_BASE_ADDR;
-	int is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q;
+	bool is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q;
+	bool is_imx6d = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6D;
 	uint32_t val;
 
 	/*
@@ -67,28 +68,29 @@ void imx6_init_lowlevel(void)
 	 * not output clock after reset, MX6DL and MX6SL have added 396M pfd
 	 * workaround in ROM code, as bus clock need it
 	 */
-	writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
-			BM_ANADIG_PFD_480_PFD2_CLKGATE |
-			BM_ANADIG_PFD_480_PFD1_CLKGATE |
-			BM_ANADIG_PFD_480_PFD0_CLKGATE,
-			MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET);
-	writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
-			(is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) |
-			BM_ANADIG_PFD_528_PFD1_CLKGATE |
-			BM_ANADIG_PFD_528_PFD0_CLKGATE,
-			MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET);
-
-	writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
-			BM_ANADIG_PFD_480_PFD2_CLKGATE |
-			BM_ANADIG_PFD_480_PFD1_CLKGATE |
-			BM_ANADIG_PFD_480_PFD0_CLKGATE,
-			MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR);
-	writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
-			(is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) |
-			BM_ANADIG_PFD_528_PFD2_CLKGATE |
-			BM_ANADIG_PFD_528_PFD1_CLKGATE |
-			BM_ANADIG_PFD_528_PFD0_CLKGATE,
-			MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR);
+	if (is_imx6q || is_imx6d) {
+		writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD2_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD1_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD0_CLKGATE,
+		       MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET);
+		writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
+		       (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) |
+		       BM_ANADIG_PFD_528_PFD1_CLKGATE |
+		       BM_ANADIG_PFD_528_PFD0_CLKGATE,
+		       MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET);
+
+		writel(BM_ANADIG_PFD_480_PFD3_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD2_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD1_CLKGATE |
+		       BM_ANADIG_PFD_480_PFD0_CLKGATE,
+		       MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR);
+		writel(BM_ANADIG_PFD_528_PFD3_CLKGATE |
+		       (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) |
+		       BM_ANADIG_PFD_528_PFD1_CLKGATE |
+		       BM_ANADIG_PFD_528_PFD0_CLKGATE,
+		       MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR);
+	}
 
 	val = readl(iomux + IOMUXC_GPR4);
 	val |= IMX6Q_GPR4_VPU_WR_CACHE_SEL | IMX6Q_GPR4_VPU_RD_CACHE_SEL |
-- 
2.1.4



From s.hauer at pengutronix.de  Mon May 11 06:22:21 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 11 May 2015 15:22:21 +0200
Subject: [PATCH] imx6: lowlevel_init: Fix workaround for new i.MX6s chips
In-Reply-To: <1431074954-28737-1-git-send-email-mpa@pengutronix.de>
References: <1431074954-28737-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150511132221.GL6325@pengutronix.de>

On Fri, May 08, 2015 at 10:49:14AM +0200, Markus Pargmann wrote:
> This errata workaround was introduced for i.MX6Q, i.MX6D and i.MX6SL.
> Old revisions of i.MX6s chips had no problems with the PFD resets.
> 
> In a newer i.MX6s revision I had issues with this code when booting in
> internal boot mode from NAND or in serial downloader mode. FUSE mode
> worked fine although it jumped directly to serial downloader mode.
> 
> This patch executes the PFD workaround only for i.MX6Q and i.MX6D which
> fixes the issues I saw.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> ---
>  arch/arm/mach-imx/imx6.c | 48 +++++++++++++++++++++++++-----------------------
>  1 file changed, 25 insertions(+), 23 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 antonynpavlov at gmail.com  Mon May 11 07:47:17 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Mon, 11 May 2015 17:47:17 +0300
Subject: are some ppc-related patches absent in May-2015 barebox-next?
Message-ID: <20150511174717.fd248fd24a066b26a2b73c7b@gmail.com>

Hi, Sascha and Juergen!

I have had rebased one of my old private branches over May-2015 barebox-next.
I have found that some ppc-related patches are present in my old private branch
but these patches are absent in the May-2015 barebox-next branch.
I'm speaking about this '[RFC] Add PowerPC MPC5125 support'
patchseries http://lists.infradead.org/pipermail/barebox/2014-October/021108.html

At the other hand I can't find any comments on this patchseries in the maillist (so,
there is no 'Applied, thanks!' response on this patcheseries).

AFAIR I have not intentionaly picked any patches from this patchseries to my private branch.
May be these patches for not very long time were in the next branch and were skipped one day?

--?
Best regards,
? Antony Pavlov


From antonynpavlov at gmail.com  Mon May 11 14:00:48 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:48 +0300
Subject: [PATCH v2 0/5] dm9k fixups;
 img-ci20: enable dm9000 ethernet controller
Message-ID: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>

Changes since v1 (http://lists.infradead.org/pipermail/barebox/2014-September):

  * rework 'net: dm9k: add device tree support' completely;
  * add additional comments to 'net: dm9k: show only one phy on miibus';
  * add img-ci20-related patches.


Antony Pavlov (5):
  net: dm9k: show only one phy on miibus
  net: dm9k: add device tree support
  net: dm9k: fix reset routine
  MIPS: img-ci20: enable dm9000 ethernet controller
  MIPS: img-ci20_defconfig: enable network stuff

 arch/mips/configs/img-ci20_defconfig |  11 ++-
 arch/mips/dts/img-ci20.dts           |  15 ++++
 arch/mips/mach-xburst/Kconfig        |   1 +
 drivers/net/dm9k.c                   | 138 ++++++++++++++++++++++++++++++-----
 4 files changed, 143 insertions(+), 22 deletions(-)

-- 
2.1.4



From antonynpavlov at gmail.com  Mon May 11 14:00:49 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:49 +0300
Subject: [PATCH v2 1/5] net: dm9k: show only one phy on miibus
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431378053-18914-2-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 drivers/net/dm9k.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index abcb7ee..5798e16 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -359,6 +359,11 @@ static int dm9k_phy_read(struct mii_bus *bus, int addr, int reg)
 	struct dm9k *priv = bus->priv;
 	struct device_d *dev = &bus->dev;
 
+	/* only internal phy supported by now, so show only one phy on miibus */
+	if (addr != 0) {
+		return 0xffff;
+	}
+
 	/* Fill the phyxcer register into REG_0C */
 	dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
 	dm9k_iow(priv, DM9K_EPCR, 0xc);	/* Issue phyxcer read command */
@@ -378,6 +383,11 @@ static int dm9k_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
 	struct dm9k *priv = bus->priv;
 	struct device_d *dev = &bus->dev;
 
+	/* only internal phy supported by now, so show only one phy on miibus */
+	if (addr != 0) {
+		return 0;
+	}
+
 	/* Fill the phyxcer register into REG_0C */
 	dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
 
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May 11 14:00:50 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:50 +0300
Subject: [PATCH v2 2/5] net: dm9k: add device tree support
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431378053-18914-3-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 drivers/net/dm9k.c | 103 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 16 deletions(-)

diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index 5798e16..4251a91 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -708,17 +708,66 @@ static int dm9k_init_dev(struct eth_device *edev)
 	return 0;
 }
 
+static int dm9000_setup_buswidth(struct device_d *dev, struct dm9k *priv, uint32_t width)
+{
+	switch (width) {
+	case 1:
+		priv->buswidth = IORESOURCE_MEM_8BIT;
+		break;
+	case 2:
+		priv->buswidth = IORESOURCE_MEM_16BIT;
+		break;
+	case 4:
+		priv->buswidth = IORESOURCE_MEM_32BIT;
+		break;
+	default:
+		dev_err(dev, "Wrong io resource size\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int dm9000_parse_dt(struct device_d *dev, struct dm9k *priv)
+{
+	struct device_node *np = dev->device_node;
+	uint32_t prop;
+
+	if (!IS_ENABLED(CONFIG_OFDEVICE) || !np)
+		return -ENODEV;
+
+	if (of_find_property(np, "davicom,no-eeprom", NULL)) {
+		priv->srom = 0;
+	} else {
+		priv->srom = 1;
+	}
+
+	if (of_property_read_u32(np, "reg-io-width", &prop)) {
+		/* Use 8-bit registers by default */
+		prop = 1;
+	}
+
+	return dm9000_setup_buswidth(dev, priv, prop);
+}
+
+static int dm9000_parse_pdata(struct device_d *dev, struct dm9k *priv)
+{
+	struct dm9000_platform_data *pdata = dev->platform_data;
+	uint32_t width;
+
+	priv->srom = pdata->srom;
+
+	width = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK;
+
+	return dm9000_setup_buswidth(dev, priv, width);
+}
+
 static int dm9k_probe(struct device_d *dev)
 {
 	unsigned io_mode;
 	struct eth_device *edev;
 	struct dm9k *priv;
-	struct dm9000_platform_data *pdata;
-
-	if (!dev->platform_data) {
-		dev_err(dev, "No platform_data\n");
-		return -ENODEV;
-	}
+	int ret;
 
 	if (dev->num_resources < 2) {
 		dev_err(dev, "Need 2 resources base and data");
@@ -727,19 +776,28 @@ static int dm9k_probe(struct device_d *dev)
 
 	edev = xzalloc(sizeof(struct eth_device) + sizeof(struct dm9k));
 	edev->priv = (struct dm9k *)(edev + 1);
+	priv = edev->priv;
 
-	pdata = dev->platform_data;
+	if (dev->platform_data) {
+		ret = dm9000_parse_pdata(dev, priv);
+	} else {
+		ret = dm9000_parse_dt(dev, priv);
+	}
 
-	priv = edev->priv;
+	if (ret)
+		goto err;
 
-	priv->buswidth = dev->resource[0].flags & IORESOURCE_MEM_TYPE_MASK;
 	priv->iodata = dev_request_mem_region(dev, 1);
-	if (!priv->iodata)
-		return -EBUSY;
+	if (!priv->iodata) {
+		ret = -EBUSY;
+		goto err;
+	}
+
 	priv->iobase = dev_request_mem_region(dev, 0);
-	if (!priv->iobase)
-		return -EBUSY;
-	priv->srom = pdata->srom;
+	if (!priv->iobase) {
+		ret = -EBUSY;
+		goto err;
+	}
 
 	edev->init = dm9k_init_dev;
 	edev->open = dm9k_eth_open;
@@ -757,8 +815,10 @@ static int dm9k_probe(struct device_d *dev)
 
 	/* RESET device */
 	dm9k_reset(priv);
-	if(dm9k_check_id(priv))
-		return -ENODEV;
+	if (dm9k_check_id(priv)) {
+		ret = -ENODEV;
+		goto err;
+	}
 
 	io_mode = dm9k_ior(priv, DM9K_ISR) >> 6;
 	switch (io_mode) {
@@ -790,10 +850,21 @@ static int dm9k_probe(struct device_d *dev)
 	eth_register(edev);
 
 	return 0;
+
+err:
+	free(edev);
+
+	return ret;
 }
 
+static struct of_device_id dm9000_of_matches[] = {
+	{ .compatible = "davicom,dm9000", },
+	{ /* sentinel */ }
+};
+
 static struct driver_d dm9k_driver = {
 	.name  = "dm9000",
 	.probe = dm9k_probe,
+	.of_compatible = DRV_OF_COMPAT(dm9000_of_matches),
 };
 device_platform_driver(dm9k_driver);
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May 11 14:00:51 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:51 +0300
Subject: [PATCH v2 3/5] net: dm9k: fix reset routine
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431378053-18914-4-git-send-email-antonynpavlov@gmail.com>

Based on Linux's commit:

    commit 09ee9f87d02e779e4fc3f5c29212c733d6d6e349
    Author: Michael Abbott <michael.abbott at diamond.ac.uk>
    Date:   Wed Oct 16 11:41:33 2013 +0300

        dm9000: Implement full reset of DM9000 network device

        A Davicom application note for the DM9000 network device recommends
        performing software reset twice to correctly initialise the device.
        Without this reset some devices fail to initialise correctly on
        system startup.

N.B. DM9000B on MIPS Creator CI20 board needs additional workaround
(see the 'Make all GPIO pins outputs' and 'Power internal PHY' lines).

This workaround was taken from this U-boot's commit:

    commit fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d
    Author: Remy Bohmer <linux at bohmer.net>
    Date:   Tue Jun 3 15:26:24 2008 +0200

        DM9000: Improve eth_reset() routine

        According to the application notes of the DM9000 v1.22 chapter 5.2 bullet 2, the
        reset procedure must be done twice to properly reset the DM9000 by means of software.
        This errata is not needed anymore for the DM9000A, but it does not bother it.

        This change has been tested with DM9000A, DM9000E, DM9000EP.

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 drivers/net/dm9k.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index 4251a91..c3c2a80 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -48,6 +48,7 @@
 # define NCR_FCOL	(1 << 4)
 # define NCR_FDX	(1 << 3)
 # define NCR_LBK	(3 << 1)
+# define NCR_MAC_LBK	(1 << 1)
 # define NCR_RST	(1 << 0)
 
 #define DM9K_NSR	0x01
@@ -472,8 +473,28 @@ static void dm9k_reset(struct dm9k *priv)
 	struct device_d *dev = priv->miibus.parent;
 
 	dev_dbg(dev, "%s\n", __func__);
-	dm9k_iow(priv, DM9K_NCR, NCR_RST);
-	udelay(1000);		/* delay 1ms */
+
+	/* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29
+	 * The essential point is that we have to do a double reset, and the
+	 * instruction is to set LBK into MAC internal loopback mode.
+	 */
+
+	/* Make all GPIO pins outputs */
+	dm9k_iow(priv, DM9K_GPCR, 0x0F);
+	/* Power internal PHY by writing 0 to GPIO0 pin */
+	dm9k_iow(priv, DM9K_GPR, 0);
+
+	dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+	udelay(100); /* Application note says at least 20 us */
+	if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+		dev_err(dev, "dm9000 did not respond to first reset\n");
+
+	dm9k_iow(priv, DM9K_NCR, 0);
+	dm9k_iow(priv, DM9K_NCR, NCR_RST | NCR_MAC_LBK);
+	udelay(100);
+
+	if (dm9k_ior(priv, DM9K_NCR) & NCR_RST)
+		dev_err(dev, "dm9000 did not respond to second reset\n");
 }
 
 static int dm9k_eth_open(struct eth_device *edev)
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May 11 14:00:52 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:52 +0300
Subject: [PATCH v2 4/5] MIPS: img-ci20: enable dm9000 ethernet controller
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431378053-18914-5-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/dts/img-ci20.dts    | 15 +++++++++++++++
 arch/mips/mach-xburst/Kconfig |  1 +
 2 files changed, 16 insertions(+)

diff --git a/arch/mips/dts/img-ci20.dts b/arch/mips/dts/img-ci20.dts
index f2022dd..da2a5bf 100644
--- a/arch/mips/dts/img-ci20.dts
+++ b/arch/mips/dts/img-ci20.dts
@@ -28,6 +28,21 @@
 		device_type = "memory";
 		reg = <0x0 0x10000000>;
 	};
+
+	board {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <>;
+
+		dm9000 at 16000000 {
+			compatible = "davicom,dm9000";
+			davicom,no-eeprom;
+
+			reg = <0x16000000 1   /* addr */
+			       0x16000002 1>; /* data */
+		};
+	};
 };
 
 &uart0 {
diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
index 2598c41..fd106fe 100644
--- a/arch/mips/mach-xburst/Kconfig
+++ b/arch/mips/mach-xburst/Kconfig
@@ -27,6 +27,7 @@ config BOARD_RZX50
 config BOARD_CI20
 	bool "Imagination Creator CI20"
 	select CPU_JZ4780
+	select HAS_DM9000
 
 endchoice
 
-- 
2.1.4



From antonynpavlov at gmail.com  Mon May 11 14:00:53 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 00:00:53 +0300
Subject: [PATCH v2 5/5] MIPS: img-ci20_defconfig: enable network stuff
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431378053-18914-6-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/configs/img-ci20_defconfig | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/mips/configs/img-ci20_defconfig b/arch/mips/configs/img-ci20_defconfig
index 6702c88..28319c5 100644
--- a/arch/mips/configs/img-ci20_defconfig
+++ b/arch/mips/configs/img-ci20_defconfig
@@ -28,15 +28,18 @@ CONFIG_CMD_UIMAGE=y
 CONFIG_CMD_MD5SUM=y
 CONFIG_CMD_GETOPT=y
 CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
 CONFIG_CMD_EDIT=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_OF_NODE=y
 CONFIG_CMD_OF_PROPERTY=y
 CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
 CONFIG_OFDEVICE=y
+CONFIG_DRIVER_NET_DM9K=y
 # CONFIG_SPI is not set
-CONFIG_CLOCKSOURCE_DUMMY=y
 CONFIG_CLOCKSOURCE_DUMMY_RATE=3500
-CONFIG_DIGEST_SHA1_GENERIC=y
-CONFIG_DIGEST_SHA224_GENERIC=y
-CONFIG_DIGEST_SHA256_GENERIC=y
+CONFIG_FS_TFTP=y
-- 
2.1.4



From s.hauer at pengutronix.de  Mon May 11 23:22:39 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 12 May 2015 08:22:39 +0200
Subject: [PATCH v2 0/5] dm9k fixups; img-ci20: enable dm9000 ethernet
 controller
In-Reply-To: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
References: <1431378053-18914-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20150512062239.GO6325@pengutronix.de>

On Tue, May 12, 2015 at 12:00:48AM +0300, Antony Pavlov wrote:
> Changes since v1 (http://lists.infradead.org/pipermail/barebox/2014-September):
> 
>   * rework 'net: dm9k: add device tree support' completely;
>   * add additional comments to 'net: dm9k: show only one phy on miibus';
>   * add img-ci20-related patches.
> 
> 
> Antony Pavlov (5):
>   net: dm9k: show only one phy on miibus
>   net: dm9k: add device tree support
>   net: dm9k: fix reset routine
>   MIPS: img-ci20: enable dm9000 ethernet controller
>   MIPS: img-ci20_defconfig: enable network stuff

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  Mon May 11 23:25:02 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 12 May 2015 08:25:02 +0200
Subject: are some ppc-related patches absent in May-2015 barebox-next?
In-Reply-To: <20150511174717.fd248fd24a066b26a2b73c7b@gmail.com>
References: <20150511174717.fd248fd24a066b26a2b73c7b@gmail.com>
Message-ID: <20150512062502.GP6325@pengutronix.de>

Hi Antony,

On Mon, May 11, 2015 at 05:47:17PM +0300, Antony Pavlov wrote:
> Hi, Sascha and Juergen!
> 
> I have had rebased one of my old private branches over May-2015 barebox-next.
> I have found that some ppc-related patches are present in my old private branch
> but these patches are absent in the May-2015 barebox-next branch.
> I'm speaking about this '[RFC] Add PowerPC MPC5125 support'
> patchseries http://lists.infradead.org/pipermail/barebox/2014-October/021108.html
> 
> At the other hand I can't find any comments on this patchseries in the maillist (so,
> there is no 'Applied, thanks!' response on this patcheseries).
> 
> AFAIR I have not intentionaly picked any patches from this patchseries to my private branch.
> May be these patches for not very long time were in the next branch and were skipped one day?

I think I had some offli[st|ne] review comments which never got
addresses so this series never made it mainline. I assume I had this
series merged to next for testing purposes.

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  Tue May 12 01:45:05 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 11:45:05 +0300
Subject: [PATCH 1/2] MIPS: bcm47xx: use PUTC_LL() from common
 debug_ll_ns16550.h header
In-Reply-To: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
References: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431420306-23337-2-git-send-email-antonynpavlov@gmail.com>

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/mach-bcm47xx/include/mach/debug_ll.h | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
index 9927b4d..3e74e0f 100644
--- a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
+++ b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
@@ -24,16 +24,12 @@
 #include <io.h>
 #include <mach/hardware.h>
 
-#define rbr		0
-#define lsr		5
-#define LSR_THRE	0x20	/* Xmit holding register empty */
+#define DEBUG_LL_UART_SHIFT	0
 
-static __inline__ void PUTC_LL(char ch)
-{
-	void *base = (void *)DEBUG_LL_UART_ADDR;
+#define DEBUG_LL_UART_CLK   (25804800 / 16)
+#define DEBUG_LL_UART_BPS   CONFIG_BAUDRATE
+#define DEBUG_LL_UART_DIVISOR   (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS)
 
-	while (!(__raw_readb(base + lsr) & LSR_THRE));
-	__raw_writeb(ch, base + rbr);
-}
+#include <asm/debug_ll_ns16550.h>
 
 #endif  /* __INCLUDE_ARCH_DEBUG_LL_H__ */
-- 
2.1.4



From antonynpavlov at gmail.com  Tue May 12 01:45:06 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 11:45:06 +0300
Subject: [PATCH 2/2] update dlink-dir-320_defconfig
In-Reply-To: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
References: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <1431420306-23337-3-git-send-email-antonynpavlov@gmail.com>

Just 'make defconfig && mv defconfig arch/mips/configs/dlink-dir-320_defconfig'.

Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
---
 arch/mips/configs/dlink-dir-320_defconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/mips/configs/dlink-dir-320_defconfig b/arch/mips/configs/dlink-dir-320_defconfig
index 4c9a06f..61798bf 100644
--- a/arch/mips/configs/dlink-dir-320_defconfig
+++ b/arch/mips/configs/dlink-dir-320_defconfig
@@ -2,7 +2,6 @@ CONFIG_BUILTIN_DTB=y
 CONFIG_BUILTIN_DTB_NAME="dlink-dir-320"
 CONFIG_MACH_MIPS_BCM47XX=y
 CONFIG_STACK_SIZE=0x7000
-CONFIG_BROKEN=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_HUSH_FANCY_PROMPT=y
 CONFIG_CMDLINE_EDITING=y
@@ -35,9 +34,9 @@ CONFIG_CMD_PING=y
 CONFIG_CMD_TFTP=y
 CONFIG_CMD_ECHO_E=y
 CONFIG_CMD_EDIT=y
+CONFIG_CMD_LOGIN=y
 CONFIG_CMD_MENU=y
 CONFIG_CMD_MENU_MANAGEMENT=y
-CONFIG_CMD_LOGIN=y
 CONFIG_CMD_PASSWD=y
 CONFIG_CMD_READLINE=y
 CONFIG_CMD_TIMEOUT=y
-- 
2.1.4



From antonynpavlov at gmail.com  Tue May 12 01:45:04 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Tue, 12 May 2015 11:45:04 +0300
Subject: [PATCH 0/2] MIPS: bcm47xx: trivial fixes
Message-ID: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>

Antony Pavlov (2):
  MIPS: bcm47xx: use PUTC_LL() from common debug_ll_ns16550.h header
  update dlink-dir-320_defconfig

 arch/mips/configs/dlink-dir-320_defconfig      |  3 +--
 arch/mips/mach-bcm47xx/include/mach/debug_ll.h | 14 +++++---------
 2 files changed, 6 insertions(+), 11 deletions(-)

-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:20:35 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:20:35 +0200
Subject: [PATCH 1/3] mci: imx-esdhc: Use IS_ENABLED() instead of #ifdef
Message-ID: <1431498037-31789-1-git-send-email-s.hauer@pengutronix.de>

To get rid of some #ifdefery.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/imx-esdhc.c | 124 +++++++++++++++++++++++++++---------------------
 1 file changed, 69 insertions(+), 55 deletions(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 8b45500..178967a 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -60,9 +60,10 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
 
 	if (data) {
 		xfertyp |= COMMAND_DPSEL;
-#ifndef CONFIG_MCI_IMX_ESDHC_PIO
-		xfertyp |= TRANSFER_MODE_DMAEN;
-#endif
+
+		if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
+			xfertyp |= TRANSFER_MODE_DMAEN;
+
 		if (data->blocks > 1) {
 			xfertyp |= TRANSFER_MODE_MSBSEL;
 			xfertyp |= TRANSFER_MODE_BCEN;
@@ -89,7 +90,6 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
 	return COMMAND_CMD(cmd->cmdidx) | xfertyp;
 }
 
-#ifdef CONFIG_MCI_IMX_ESDHC_PIO
 /*
  * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
  */
@@ -153,52 +153,84 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 		}
 	}
 }
-#endif
 
 static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
 {
 	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
 	void __iomem *regs = host->regs;
-#ifndef CONFIG_MCI_IMX_ESDHC_PIO
 	u32 wml_value;
 
-	wml_value = data->blocksize/4;
-
-	if (data->flags & MMC_DATA_READ) {
-		if (wml_value > 0x10)
-			wml_value = 0x10;
-
-		esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_RD_WML_MASK, wml_value);
-		esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
-	} else {
-		if (wml_value > 0x80)
-			wml_value = 0x80;
-		if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
-			printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
-			return -ETIMEDOUT;
+	if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) {
+		if (!(data->flags & MMC_DATA_READ)) {
+			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
+				printf("\nThe SD card is locked. "
+					"Can not write to a locked card.\n\n");
+				return -ETIMEDOUT;
+			}
+			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
+		} else {
+			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
 		}
+	} else {
+		wml_value = data->blocksize/4;
+
+		if (data->flags & MMC_DATA_READ) {
+			if (wml_value > 0x10)
+				wml_value = 0x10;
+
+			esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_RD_WML_MASK, wml_value);
+			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
+		} else {
+			if (wml_value > 0x80)
+				wml_value = 0x80;
+			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
+				printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
+				return -ETIMEDOUT;
+			}
 
-		esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK,
-					wml_value << 16);
-		esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
-	}
-#else	/* CONFIG_MCI_IMX_ESDHC_PIO */
-	if (!(data->flags & MMC_DATA_READ)) {
-		if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
-			printf("\nThe SD card is locked. "
-				"Can not write to a locked card.\n\n");
-			return -ETIMEDOUT;
+			esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK,
+						wml_value << 16);
+			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
 		}
-		esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
-	} else
-		esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
-#endif	/* CONFIG_MCI_IMX_ESDHC_PIO */
+	}
 
 	esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
 
 	return 0;
 }
 
+static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
+{
+	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+	void __iomem *regs = host->regs;
+	unsigned int num_bytes = data->blocks * data->blocksize;
+	u32 irqstat;
+
+	if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) {
+		esdhc_pio_read_write(mci, data);
+		return 0;
+	}
+
+	do {
+		irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+
+		if (irqstat & DATA_ERR)
+			return -EIO;
+
+		if (irqstat & IRQSTAT_DTOE)
+			return -ETIMEDOUT;
+	} while (!(irqstat & IRQSTAT_TC) &&
+		(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
+
+	if (data->flags & MMC_DATA_WRITE)
+		dma_sync_single_for_cpu((unsigned long)data->src,
+					num_bytes, DMA_TO_DEVICE);
+	else
+		dma_sync_single_for_cpu((unsigned long)data->dest,
+					num_bytes, DMA_FROM_DEVICE);
+
+	return 0;
+}
 
 /*
  * Sends a command out on the bus.  Takes the mci pointer,
@@ -303,27 +335,9 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
 
 	/* Wait until all of the blocks are transferred */
 	if (data) {
-#ifdef CONFIG_MCI_IMX_ESDHC_PIO
-		esdhc_pio_read_write(mci, data);
-#else
-		do {
-			irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
-
-			if (irqstat & DATA_ERR)
-				return -EIO;
-
-			if (irqstat & IRQSTAT_DTOE)
-				return -ETIMEDOUT;
-		} while (!(irqstat & IRQSTAT_TC) &&
-				(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
-
-		if (data->flags & MMC_DATA_WRITE)
-			dma_sync_single_for_cpu((unsigned long)data->src,
-						num_bytes, DMA_TO_DEVICE);
-		else
-			dma_sync_single_for_cpu((unsigned long)data->dest,
-						num_bytes, DMA_FROM_DEVICE);
-#endif
+		ret = esdhc_do_data(mci, data);
+		if (ret)
+			return ret;
 	}
 
 	esdhc_write32(regs + SDHCI_INT_STATUS, -1);
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:20:36 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:20:36 +0200
Subject: [PATCH 2/3] mci: imx-esdhc: Check for errors in esdhc_pio_read_write
In-Reply-To: <1431498037-31789-1-git-send-email-s.hauer@pengutronix.de>
References: <1431498037-31789-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1431498037-31789-2-git-send-email-s.hauer@pengutronix.de>

esdhc_pio_read_write can fail, so let it return an error code
rather than void.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/imx-esdhc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 178967a..f310213 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -93,7 +93,7 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
 /*
  * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
  */
-static void
+static int
 esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 {
 	struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
@@ -116,7 +116,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 				&& --timeout);
 			if (timeout <= 0) {
 				printf("\nData Read Failed in PIO Mode.");
-				return;
+				return -ETIMEDOUT;
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
 				udelay(100); /* Wait before last byte transfer complete */
@@ -139,7 +139,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 				&& --timeout);
 			if (timeout <= 0) {
 				printf("\nData Write Failed in PIO Mode.");
-				return;
+				return -ETIMEDOUT;
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
 				udelay(100); /* Wait before last byte transfer complete */
@@ -152,6 +152,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 			blocks--;
 		}
 	}
+
+	return 0;
 }
 
 static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
@@ -206,10 +208,8 @@ static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
 	unsigned int num_bytes = data->blocks * data->blocksize;
 	u32 irqstat;
 
-	if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) {
-		esdhc_pio_read_write(mci, data);
-		return 0;
-	}
+	if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO))
+		return esdhc_pio_read_write(mci, data);
 
 	do {
 		irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:20:37 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:20:37 +0200
Subject: [PATCH 3/3] mci: imx-esdhc: Replace printf with dev_*
In-Reply-To: <1431498037-31789-1-git-send-email-s.hauer@pengutronix.de>
References: <1431498037-31789-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1431498037-31789-3-git-send-email-s.hauer@pengutronix.de>

This replaces printf with dev_* since a struct device_d * is
available.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/mci/imx-esdhc.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index f310213..6caf165 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -115,7 +115,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 			while (!(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_BREN)
 				&& --timeout);
 			if (timeout <= 0) {
-				printf("\nData Read Failed in PIO Mode.");
+				dev_err(host->dev, "Data Read Failed\n");
 				return -ETIMEDOUT;
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
@@ -138,7 +138,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
 			while (!(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_BWEN)
 				&& --timeout);
 			if (timeout <= 0) {
-				printf("\nData Write Failed in PIO Mode.");
+				dev_err(host->dev, "Data Write Failed\n");
 				return -ETIMEDOUT;
 			}
 			while (size && (!(irqstat & IRQSTAT_TC))) {
@@ -164,11 +164,8 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
 
 	if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) {
 		if (!(data->flags & MMC_DATA_READ)) {
-			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
-				printf("\nThe SD card is locked. "
-					"Can not write to a locked card.\n\n");
-				return -ETIMEDOUT;
-			}
+			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0)
+				goto err_locked;
 			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
 		} else {
 			esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
@@ -185,10 +182,8 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
 		} else {
 			if (wml_value > 0x80)
 				wml_value = 0x80;
-			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
-				printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
-				return -ETIMEDOUT;
-			}
+			if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0)
+				goto err_locked;
 
 			esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK,
 						wml_value << 16);
@@ -199,6 +194,11 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
 	esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
 
 	return 0;
+
+err_locked:
+	dev_err(host->dev, "Can not write to locked card.\n\n");
+
+	return -ETIMEDOUT;
 }
 
 static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
@@ -512,8 +512,9 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
 	return ret;
 }
 
-static int esdhc_reset(void __iomem *regs)
+static int esdhc_reset(struct fsl_esdhc_host *host)
 {
+	void __iomem *regs = host->regs;
 	uint64_t start;
 
 	/* reset the controller */
@@ -527,7 +528,7 @@ static int esdhc_reset(void __iomem *regs)
 					& SYSCTL_RSTA))
 			break;
 		if (is_timeout(start, 100 * MSECOND)) {
-			printf("MMC/SD: Reset never completed.\n");
+			dev_err(host->dev, "Reset never completed.\n");
 			return -EIO;
 		}
 	}
@@ -564,7 +565,7 @@ static int fsl_esdhc_probe(struct device_d *dev)
 		return PTR_ERR(host->regs);
 
 	/* First reset the eSDHC controller */
-	ret = esdhc_reset(host->regs);
+	ret = esdhc_reset(host);
 	if (ret) {
 		free(host);
 		return ret;
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:23:25 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:23:25 +0200
Subject: [PATCH] console: use regular malloc for log messages
Message-ID: <1431498205-2544-1-git-send-email-s.hauer@pengutronix.de>

Using xfunctions to allocate log messages is not a good idea. Should
we be out of memory the xfunctions will panic which will cause another
allocation, so we deadlock the system with no message going out.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/console_common.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/common/console_common.c b/common/console_common.c
index 41a6929..36bd1dd 100644
--- a/common/console_common.c
+++ b/common/console_common.c
@@ -106,15 +106,23 @@ static void pr_puts(int level, const char *str)
 			log_clean(barebox_log_max_messages - 1);
 
 		if (barebox_log_max_messages >= 0) {
-			log = xzalloc(sizeof(*log));
-			log->msg = xstrdup(str);
+			log = malloc(sizeof(*log));
+			if (!log)
+				goto nolog;
+
+			log->msg = strdup(str);
+			if (!log->msg) {
+				free(log);
+				goto nolog;
+			}
+
 			log->timestamp = get_time_ns();
 			log->level = level;
 			list_add_tail(&log->list, &barebox_logbuf);
 			barebox_logbuf_num_messages++;
 		}
 	}
-
+nolog:
 	if (level > barebox_loglevel)
 		return;
 
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:23:42 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:23:42 +0200
Subject: [PATCH] xfuncs: remove debugging output
Message-ID: <1431498222-2682-1-git-send-email-s.hauer@pengutronix.de>

Adding debug statements to this code path does not make much sense
since when enabled it will massively spam the console.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 lib/xfuncs.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/lib/xfuncs.c b/lib/xfuncs.c
index 86d0013..0e78b67 100644
--- a/lib/xfuncs.c
+++ b/lib/xfuncs.c
@@ -30,8 +30,6 @@ void *xmalloc(size_t size)
 	if (!(p = malloc(size)))
 		panic("ERROR: out of memory\n");
 
-	debug("xmalloc %p (size %zu)\n", p, size);
-
 	return p;
 }
 EXPORT_SYMBOL(xmalloc);
@@ -43,8 +41,6 @@ void *xrealloc(void *ptr, size_t size)
 	if (!(p = realloc(ptr, size)))
 		panic("ERROR: out of memory\n");
 
-	debug("xrealloc %p -> %p (size %zu)\n", ptr, p, size);
-
 	return p;
 }
 EXPORT_SYMBOL(xrealloc);
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 12 23:24:31 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 13 May 2015 08:24:31 +0200
Subject: [PATCH 0/2] MIPS: bcm47xx: trivial fixes
In-Reply-To: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
References: <1431420306-23337-1-git-send-email-antonynpavlov@gmail.com>
Message-ID: <20150513062431.GX6325@pengutronix.de>

On Tue, May 12, 2015 at 11:45:04AM +0300, Antony Pavlov wrote:
> Antony Pavlov (2):
>   MIPS: bcm47xx: use PUTC_LL() from common debug_ll_ns16550.h header
>   update dlink-dir-320_defconfig
> 
>  arch/mips/configs/dlink-dir-320_defconfig      |  3 +--
>  arch/mips/mach-bcm47xx/include/mach/debug_ll.h | 14 +++++---------
>  2 files changed, 6 insertions(+), 11 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 mkl at pengutronix.de  Wed May 13 03:12:26 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:26 +0200
Subject: [PATCH 1/7] state: print name of property of size mismatch is detected
Message-ID: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/state.c b/common/state.c
index cc44cecb484f..d4ce7313be97 100644
--- a/common/state.c
+++ b/common/state.c
@@ -517,8 +517,8 @@ static int state_convert_node_variable(struct state *state,
 
 		if (start_size[1] != sv->size) {
 			dev_err(&state->dev,
-				"size mismatch: type=%s(size=%u) size=%u\n",
-			       type_name, sv->size, start_size[1]);
+				"%s: size mismatch: type=%s(size=%u) size=%u\n",
+				name, type_name, sv->size, start_size[1]);
 			ret = -EOVERFLOW;
 			goto out_free;
 		}
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:27 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:27 +0200
Subject: [PATCH 2/7] state: print proper error message,
 if reg property is not found
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-2-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/state.c b/common/state.c
index d4ce7313be97..5642f0d41855 100644
--- a/common/state.c
+++ b/common/state.c
@@ -512,8 +512,11 @@ static int state_convert_node_variable(struct state *state,
 
 		ret = of_property_read_u32_array(node, "reg", start_size,
 						 ARRAY_SIZE(start_size));
-		if (ret)
+		if (ret) {
+			dev_err(&state->dev,
+				"%s: reg property not found\n", name);
 			goto out_free;
+		}
 
 		if (start_size[1] != sv->size) {
 			dev_err(&state->dev,
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:32 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:32 +0200
Subject: [PATCH 7/7] state: return -EPROBE_DEFER if the backend isn't available
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-7-git-send-email-mkl@pengutronix.de>

From: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 drivers/misc/state.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/state.c b/drivers/misc/state.c
index 9e8a40255348..dbe88715a103 100644
--- a/drivers/misc/state.c
+++ b/drivers/misc/state.c
@@ -52,6 +52,8 @@ static int state_probe(struct device_d *dev)
 	/* guess if of_path is a path, not a phandle */
 	if (of_path[0] == '/') {
 		ret = of_find_path(np, "backend", &path, 0);
+		if (ret == -ENODEV)
+			ret = -EPROBE_DEFER;
 		if (ret)
 			goto out_release;
 	} else {
@@ -66,7 +68,7 @@ static int state_probe(struct device_d *dev)
 
 		dev = of_find_device_by_node(partition_node);
 		if (!list_is_singular(&dev->cdevs)) {
-			ret = -ENODEV;
+			ret = -EPROBE_DEFER;
 			goto out_release;
 		}
 
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:28 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:28 +0200
Subject: [PATCH 3/7] state: make state_release() non static
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-3-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c  | 2 +-
 include/state.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/common/state.c b/common/state.c
index 5642f0d41855..66620a892074 100644
--- a/common/state.c
+++ b/common/state.c
@@ -426,7 +426,7 @@ static struct state *state_new(const char *name)
 	return state;
 }
 
-static void state_release(struct state *state)
+void state_release(struct state *state)
 {
 	list_del(&state->list);
 	unregister_device(&state->dev);
diff --git a/include/state.h b/include/state.h
index d321451e1490..116ec6301c1c 100644
--- a/include/state.h
+++ b/include/state.h
@@ -10,6 +10,7 @@ int state_backend_raw_file(struct state *state, const char *path,
 		off_t offset, size_t size);
 
 struct state *state_new_from_node(const char *name, struct device_node *node);
+void state_release(struct state *state);
 
 struct state *state_by_name(const char *name);
 struct state *state_by_node(const struct device_node *node);
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:31 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:31 +0200
Subject: [PATCH 6/7] state: add fixup to copy state from barebox to kernel
 device tree
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-6-git-send-email-mkl@pengutronix.de>

This patch registers a DT fixup, that copies the state nodes from the active
to the kernel DT. The backend reference will be a phandles.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/common/state.c b/common/state.c
index d6060bb7dff4..ca691d2827fa 100644
--- a/common/state.c
+++ b/common/state.c
@@ -676,6 +676,93 @@ static int state_from_node(struct state *state, struct device_node *node,
 	return ret;
 }
 
+static int of_state_fixup(struct device_node *root, void *ctx)
+{
+	struct state *state = ctx;
+	const char *compatible = "barebox,state";
+	struct device_node *new_node, *node, *parent, *backend_node;
+	struct property *p;
+	int ret;
+	phandle phandle;
+
+	node = of_find_node_by_path_from(root, state->root->full_name);
+	if (node) {
+		/* replace existing node - it will be deleted later */
+		parent = node->parent;
+	} else {
+		char *of_path, *c;
+
+		/* look for parent, remove last '/' from path */
+		of_path = xstrdup(state->root->full_name);
+		c = strrchr(of_path, '/');
+		if (!c)
+			return -ENODEV;
+		*c = '0';
+		parent = of_find_node_by_path(of_path);
+		if (!parent)
+			parent = root;
+
+		free(of_path);
+	}
+
+	/* serialize variable definitions */
+	new_node = state_to_node(state, parent, STATE_CONVERT_FIXUP);
+	if (IS_ERR(new_node))
+		return PTR_ERR(new_node);
+
+	/* compatible */
+	p = of_new_property(new_node, "compatible", compatible,
+			    strlen(compatible) + 1);
+	if (!p) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* backend-type */
+	if (!state->backend) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	p = of_new_property(new_node, "backend-type", state->backend->name,
+			    strlen(state->backend->name) + 1);
+	if (!p) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* backend phandle */
+	backend_node = of_find_node_by_path_from(root, state->backend->of_path);
+	if (!backend_node) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	phandle = of_node_create_phandle(backend_node);
+	ret = of_property_write_u32(new_node, "backend", phandle);
+	if (ret)
+		goto out;
+
+	/* address-cells + size-cells */
+	ret = of_property_write_u32(root, "#address-cells", 1);
+	if (ret)
+		goto out;
+
+	ret = of_property_write_u32(root, "#size-cells", 1);
+	if (ret)
+		goto out;
+
+	/* delete existing node */
+	if (node)
+		of_delete_node(node);
+
+	return 0;
+
+ out:
+	of_delete_node(new_node);
+	return ret;
+}
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
@@ -697,6 +784,11 @@ struct state *state_new_from_node(const char *name, struct device_node *node)
 		return ERR_PTR(ret);
 	}
 
+	ret = of_register_fixup(of_state_fixup, state);
+	if (ret) {
+		state_release(state);
+		return ERR_PTR(ret);
+	}
 
 	return state;
 }
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:30 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:30 +0200
Subject: [PATCH 5/7] state: backend: support phandle and of_path references
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-5-git-send-email-mkl@pengutronix.de>

This patch improves the backend property, it can be either a phandle or a
of_path. During probe() of the state driver the backend property is
dereferenced and the resulting of_path is saved in the state context. In a
later patch it will be used to generate a phandle reference to the backend
during DT fixup.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c       |  9 ++++---
 drivers/misc/state.c | 70 ++++++++++++++++++++++++++++++++++++++++++----------
 include/state.h      |  7 +++---
 3 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/common/state.c b/common/state.c
index 744a6f8250c4..d6060bb7dff4 100644
--- a/common/state.c
+++ b/common/state.c
@@ -54,6 +54,7 @@ struct state_backend {
 	int (*load)(struct state_backend *backend, struct state *state);
 	int (*save)(struct state_backend *backend, struct state *state);
 	const char *name;
+	const char *of_path;
 	const char *path;
 };
 
@@ -903,7 +904,7 @@ out:
  * @state	The state instance to work on
  * @path	The path where the state will be stored to
  */
-int state_backend_dtb_file(struct state *state, const char *path)
+int state_backend_dtb_file(struct state *state, const char *of_path, const char *path)
 {
 	struct state_backend_dtb *backend_dtb;
 	struct state_backend *backend;
@@ -918,6 +919,7 @@ int state_backend_dtb_file(struct state *state, const char *path)
 
 	backend->load = state_backend_dtb_load;
 	backend->save = state_backend_dtb_save;
+	backend->of_path = xstrdup(of_path);
 	backend->path = xstrdup(path);
 	backend->name = "dtb";
 
@@ -1133,8 +1135,8 @@ out_free:
  * device @size may be 0. The two copies are spread to different
  * eraseblocks if approriate for this device.
  */
-int state_backend_raw_file(struct state *state, const char *path, off_t offset,
-		size_t size)
+int state_backend_raw_file(struct state *state, const char *of_path,
+		const char *path, off_t offset, size_t size)
 {
 	struct state_backend_raw *backend_raw;
 	struct state_backend *backend;
@@ -1159,6 +1161,7 @@ int state_backend_raw_file(struct state *state, const char *path, off_t offset,
 
 	backend->load = state_backend_raw_load;
 	backend->save = state_backend_raw_save;
+	backend->of_path = xstrdup(of_path);
 	backend->path = xstrdup(path);
 	backend->name = "raw";
 
diff --git a/drivers/misc/state.c b/drivers/misc/state.c
index 3b07bb93d725..9e8a40255348 100644
--- a/drivers/misc/state.c
+++ b/drivers/misc/state.c
@@ -24,10 +24,12 @@
 static int state_probe(struct device_d *dev)
 {
 	struct device_node *np = dev->device_node;
+	struct device_node *partition_node;
 	struct state *state;
 	const char *alias;
 	const char *backend_type = NULL;
 	int ret;
+	const char *of_path;
 	char *path;
 
 	if (!np)
@@ -41,28 +43,70 @@ static int state_probe(struct device_d *dev)
 	if (IS_ERR(state))
 		return PTR_ERR(state);
 
-	ret = of_find_path(np, "backend", &path, 0);
-	if (ret)
-		return ret;
+	of_path = of_get_property(np, "backend", NULL);
+	if (!of_path) {
+		ret = -ENODEV;
+		goto out_release;
+	}
+
+	/* guess if of_path is a path, not a phandle */
+	if (of_path[0] == '/') {
+		ret = of_find_path(np, "backend", &path, 0);
+		if (ret)
+			goto out_release;
+	} else {
+		struct device_d *dev;
+		struct cdev *cdev;
+
+		partition_node = of_parse_phandle(np, "backend", 0);
+		if (!partition_node) {
+			ret = -ENODEV;
+			goto out_release;
+		}
+
+		dev = of_find_device_by_node(partition_node);
+		if (!list_is_singular(&dev->cdevs)) {
+			ret = -ENODEV;
+			goto out_release;
+		}
+
+		cdev = list_first_entry(&dev->cdevs, struct cdev, devices_list);
+		if (!cdev) {
+			ret = -ENODEV;
+			goto out_release;
+		}
 
-	dev_info(dev, "outpath: %s\n", path);
+		path = asprintf("/dev/%s", cdev->name);
+		of_path = partition_node->full_name;
+	}
 
 	ret = of_property_read_string(np, "backend-type", &backend_type);
-	if (ret)
-		return ret;
-	else if (!strcmp(backend_type, "raw"))
-		ret = state_backend_raw_file(state, path, 0, 0);
-	else if (!strcmp(backend_type, "dtb"))
-		ret = state_backend_dtb_file(state, path);
-	else
+	if (ret) {
+		goto out_free;
+	} else if (!strcmp(backend_type, "raw")) {
+		ret = state_backend_raw_file(state, of_path, path, 0, 0);
+	} else if (!strcmp(backend_type, "dtb")) {
+		ret = state_backend_dtb_file(state, of_path, path);
+	} else {
 		dev_warn(dev, "invalid backend type: %s\n", backend_type);
+		ret = -ENODEV;
+		goto out_free;
+	}
 
 	if (ret)
-		return ret;
+		goto out_free;
 
-	state_load(state);
+	dev_info(dev, "backend: %s, path: %s, of_path: %s\n", backend_type, path, of_path);
+	free(path);
 
+	state_load(state);
 	return 0;
+
+ out_free:
+	free(path);
+ out_release:
+	state_release(state);
+	return ret;
 }
 
 static __maybe_unused struct of_device_id state_ids[] = {
diff --git a/include/state.h b/include/state.h
index 116ec6301c1c..08c4e8654b9e 100644
--- a/include/state.h
+++ b/include/state.h
@@ -5,9 +5,10 @@
 
 struct state;
 
-int state_backend_dtb_file(struct state *state, const char *path);
-int state_backend_raw_file(struct state *state, const char *path,
-		off_t offset, size_t size);
+int state_backend_dtb_file(struct state *state, const char *of_path,
+		const char *path);
+int state_backend_raw_file(struct state *state, const char *of_path,
+		const char *path, off_t offset, size_t size);
 
 struct state *state_new_from_node(const char *name, struct device_node *node);
 void state_release(struct state *state);
-- 
2.1.4



From mkl at pengutronix.de  Wed May 13 03:12:29 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 13 May 2015 12:12:29 +0200
Subject: [PATCH 4/7] state: add functionality to export state description
In-Reply-To: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1431511952-32124-4-git-send-email-mkl@pengutronix.de>

This patch adds the functionality to export the description of the state, but
not the contents of the variables to a DT node. This will be used in a later
patch to "copy" the state description to the kernel device tree during DT
fixup.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 61 ++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 38 insertions(+), 23 deletions(-)

diff --git a/common/state.c b/common/state.c
index 66620a892074..744a6f8250c4 100644
--- a/common/state.c
+++ b/common/state.c
@@ -74,12 +74,20 @@ struct state_variable {
 	void *raw;
 };
 
+enum state_convert {
+	STATE_CONVERT_FROM_NODE,
+	STATE_CONVERT_FROM_NODE_CREATE,
+	STATE_CONVERT_TO_NODE,
+	STATE_CONVERT_FIXUP,
+};
+
 /* A variable type (uint32, enum32) */
 struct variable_type {
 	enum state_variable_type type;
 	const char *type_name;
 	struct list_head list;
-	int (*export)(struct state_variable *, struct device_node *);
+	int (*export)(struct state_variable *, struct device_node *,
+			enum state_convert);
 	int (*import)(struct state_variable *, const struct device_node *);
 	struct state_variable *(*create)(struct state *state,
 			const char *name, struct device_node *);
@@ -126,15 +134,15 @@ static inline struct state_uint32 *to_state_uint32(struct state_variable *s)
 }
 
 static int state_uint32_export(struct state_variable *var,
-		struct device_node *node)
+		struct device_node *node, enum state_convert conv)
 {
 	struct state_uint32 *su32 = to_state_uint32(var);
 	int ret;
 
-	if (su32->value_default) {
+	if (su32->value_default || conv == STATE_CONVERT_FIXUP) {
 		ret = of_property_write_u32(node, "default",
 					    su32->value_default);
-		if (ret)
+		if (ret || conv == STATE_CONVERT_FIXUP)
 			return ret;
 	}
 
@@ -193,16 +201,16 @@ static inline struct state_enum32 *to_state_enum32(struct state_variable *s)
 }
 
 static int state_enum32_export(struct state_variable *var,
-		struct device_node *node)
+		struct device_node *node, enum state_convert conv)
 {
 	struct state_enum32 *enum32 = to_state_enum32(var);
 	int ret, i, len;
 	char *prop, *str;
 
-	if (enum32->value_default) {
+	if (enum32->value_default || conv == STATE_CONVERT_FIXUP) {
 		ret = of_property_write_u32(node, "default",
 					    enum32->value_default);
-		if (ret)
+		if (ret || conv == STATE_CONVERT_FIXUP)
 			return ret;
 	}
 
@@ -309,14 +317,14 @@ static inline struct state_mac *to_state_mac(struct state_variable *s)
 }
 
 static int state_mac_export(struct state_variable *var,
-		struct device_node *node)
+		struct device_node *node, enum state_convert conv)
 {
 	struct state_mac *mac = to_state_mac(var);
 	int ret;
 
 	ret = of_property_write_u8_array(node, "default", mac->value_default,
 					 ARRAY_SIZE(mac->value_default));
-	if (ret)
+	if (ret || conv == STATE_CONVERT_FIXUP)
 		return ret;
 
 	return of_property_write_u8_array(node, "value", mac->value,
@@ -446,12 +454,6 @@ static struct state_variable *state_find_var(struct state *state,
 	return ERR_PTR(-ENOENT);
 }
 
-enum state_convert {
-	STATE_CONVERT_FROM_NODE,
-	STATE_CONVERT_FROM_NODE_CREATE,
-	STATE_CONVERT_TO_NODE,
-};
-
 static int state_convert_node_variable(struct state *state,
 		struct device_node *node, struct device_node *parent,
 		const char *parent_name, enum state_convert conv)
@@ -476,7 +478,8 @@ static int state_convert_node_variable(struct state *state,
 			parent_name, parent_name[0] ? "." : "", short_name);
 	free(short_name);
 
-	if (conv == STATE_CONVERT_TO_NODE)
+	if ((conv == STATE_CONVERT_TO_NODE) ||
+	    (conv == STATE_CONVERT_FIXUP))
 		new_node = of_new_node(parent, node->name);
 
 	for_each_child_of_node(node, child) {
@@ -489,6 +492,15 @@ static int state_convert_node_variable(struct state *state,
 	/* parents are allowed to have no type */
 	ret = of_property_read_string(node, "type", &type_name);
 	if (!list_empty(&node->children) && ret == -EINVAL) {
+		if (conv == STATE_CONVERT_FIXUP) {
+			ret = of_property_write_u32(new_node, "#address-cells", 1);
+			if (ret)
+				goto out_free;
+
+			ret = of_property_write_u32(new_node, "#size-cells", 1);
+			if (ret)
+				goto out_free;
+		}
 		ret = 0;
 		goto out_free;
 	} else if (ret) {
@@ -542,7 +554,8 @@ static int state_convert_node_variable(struct state *state,
 		}
 		free(name);
 
-		if (conv == STATE_CONVERT_TO_NODE) {
+		if ((conv == STATE_CONVERT_TO_NODE) ||
+		    (conv == STATE_CONVERT_FIXUP)) {
 			ret = of_set_property(new_node, "type",
 					      vtype->type_name,
 					      strlen(vtype->type_name) + 1, 1);
@@ -559,8 +572,9 @@ static int state_convert_node_variable(struct state *state,
 		}
 	}
 
-	if (conv == STATE_CONVERT_TO_NODE)
-		ret = vtype->export(sv, new_node);
+	if ((conv == STATE_CONVERT_TO_NODE) ||
+	    (conv == STATE_CONVERT_FIXUP))
+		ret = vtype->export(sv, new_node, conv);
 	else
 		ret = vtype->import(sv, node);
 
@@ -574,20 +588,21 @@ out:
 	return ret;
 }
 
-static struct device_node *state_to_node(struct state *state)
+static struct device_node *state_to_node(struct state *state, struct device_node *parent,
+					 enum state_convert conv)
 {
 	struct device_node *child;
 	struct device_node *root;
 	int ret;
 
-	root = of_new_node(NULL, NULL);
+	root = of_new_node(parent, state->root->name);
 	ret = of_property_write_u32(root, "magic", state->magic);
 	if (ret)
 		goto out;
 
 	for_each_child_of_node(state->root, child) {
 		ret = state_convert_node_variable(state, child, root, "",
-						  STATE_CONVERT_TO_NODE);
+						  conv);
 		if (ret)
 			goto out;
 	}
@@ -845,7 +860,7 @@ static int state_backend_dtb_save(struct state_backend *backend,
 	struct device_node *root;
 	struct fdt_header *fdt;
 
-	root = state_to_node(state);
+	root = state_to_node(state, NULL, STATE_CONVERT_TO_NODE);
 	if (IS_ERR(root))
 		return PTR_ERR(root);
 
-- 
2.1.4



From w.egorov at phytec.de  Wed May 13 03:15:54 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Wed, 13 May 2015 12:15:54 +0200
Subject: [PATCH] ARM: am33xx: Fix SCRM compatible string to match new DT
 compatible string
Message-ID: <1431512154-25432-1-git-send-email-w.egorov@phytec.de>

Commit 461f8cfc7ea788428240271818363333ceff5c4c renamed the SCRM compatible
string in am33xx.dtsi and breaks all am335x based boards.

Rename the SCRM compatible string.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/mach-omap/am33xx_scrm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap/am33xx_scrm.c b/arch/arm/mach-omap/am33xx_scrm.c
index bb0babe..f03fb2b 100644
--- a/arch/arm/mach-omap/am33xx_scrm.c
+++ b/arch/arm/mach-omap/am33xx_scrm.c
@@ -31,7 +31,7 @@ static int am33xx_scrm_probe(struct device_d *dev)
 
 static __maybe_unused struct of_device_id am33xx_scrm_dt_ids[] = {
 	{
-		.compatible = "ti,am3-scrm",
+		.compatible = "ti,am3-scm",
 	}, {
 		/* sentinel */
 	}
-- 
1.9.1



From u.kleine-koenig at pengutronix.de  Wed May 13 05:06:26 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 13 May 2015 14:06:26 +0200
Subject: [PATCH 7/7] state: return -EPROBE_DEFER if the backend isn't
 available
In-Reply-To: <1431511952-32124-7-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
 <1431511952-32124-7-git-send-email-mkl@pengutronix.de>
Message-ID: <20150513120626.GN28888@pengutronix.de>

Hello,

On Wed, May 13, 2015 at 12:12:32PM +0200, Marc Kleine-Budde wrote:
> From: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
BTW, I didn't add this S-o-b on purpose because I didn't consider this
patch done.

> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  drivers/misc/state.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/state.c b/drivers/misc/state.c
> index 9e8a40255348..dbe88715a103 100644
> --- a/drivers/misc/state.c
> +++ b/drivers/misc/state.c
> @@ -52,6 +52,8 @@ static int state_probe(struct device_d *dev)
>  	/* guess if of_path is a path, not a phandle */
>  	if (of_path[0] == '/') {
>  		ret = of_find_path(np, "backend", &path, 0);
> +		if (ret == -ENODEV)
> +			ret = -EPROBE_DEFER;
>  		if (ret)
>  			goto out_release;
>  	} else {
In my testcase I only use this hunk.

> @@ -66,7 +68,7 @@ static int state_probe(struct device_d *dev)
>  
>  		dev = of_find_device_by_node(partition_node);
>  		if (!list_is_singular(&dev->cdevs)) {
> -			ret = -ENODEV;
> +			ret = -EPROBE_DEFER;
>  			goto out_release;
>  		}
This one was done without testing, there is another if below that might
need adaption too (or instead of this one):

                cdev = list_first_entry(&dev->cdevs, struct cdev, devices_list);
                if (!cdev) {
                        ret = -ENODEV;
                        goto out_release;
                }

Best regards
Uwe

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


From s.trumtrar at pengutronix.de  Wed May 13 05:56:22 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Wed, 13 May 2015 14:56:22 +0200
Subject: [PATCH 0/2] Socfpga: Sequencer updates
Message-ID: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>

Hi!

This updates the socfpga_get_sequencer script to handle the new
Quartus 15.0 generated sources.
Luckily the real changes in the code are very minor, so the patch
mostly just removes TCL/ALTERA macros that are useless for barebox.

(Boot)Tested on Sockit/Socrates.

Regards,
Steffen

Steffen Trumtrar (2):
  scripts: update socfpga_sequencer importer for Quartus 15.0
  ARM: socfpga: update sdram calibration to 15.0

 arch/arm/mach-socfpga/include/mach/sequencer.c | 293 +++++--------------------
 arch/arm/mach-socfpga/include/mach/sequencer.h |   2 +
 scripts/coccinelle/misc/altera_sequencer.cocci |   3 +-
 scripts/socfpga_get_sequencer                  |   8 +
 scripts/socfpga_sequencer_defines_defaults     |   4 +
 5 files changed, 75 insertions(+), 235 deletions(-)

-- 
2.1.4



From s.trumtrar at pengutronix.de  Wed May 13 05:56:23 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Wed, 13 May 2015 14:56:23 +0200
Subject: [PATCH 1/2] scripts: update socfpga_sequencer importer to Quartus 15.0
In-Reply-To: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1431521784-27413-2-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 scripts/coccinelle/misc/altera_sequencer.cocci | 3 ++-
 scripts/socfpga_get_sequencer                  | 8 ++++++++
 scripts/socfpga_sequencer_defines_defaults     | 4 ++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/scripts/coccinelle/misc/altera_sequencer.cocci b/scripts/coccinelle/misc/altera_sequencer.cocci
index 9fea239c0c7d..2350e841c0e8 100644
--- a/scripts/coccinelle/misc/altera_sequencer.cocci
+++ b/scripts/coccinelle/misc/altera_sequencer.cocci
@@ -1,7 +1,8 @@
 @r_shadow@
+type T;
 @@
 
-- ...curr_shadow_reg = 0;
+- static T curr_shadow_reg = 0;
 
 @r_out2_delay@
 type T;
diff --git a/scripts/socfpga_get_sequencer b/scripts/socfpga_get_sequencer
index 5e4eb2d0c46c..fb0ea6628b2a 100755
--- a/scripts/socfpga_get_sequencer
+++ b/scripts/socfpga_get_sequencer
@@ -49,6 +49,14 @@ copy_source() {
 
 	echo "  Running coccinelle cleanups..."
 	spatch -sp_file scripts/coccinelle/misc/altera_sequencer.cocci -in_place arch/arm/mach-socfpga/include/mach
+
+	echo "  Cleanup header..."
+	sed -i 's/^static void rw_mgr_mem_calibrate_eye_diag_aid(void);$//g' $tgt
+	sed -i 's/^static void rw_mgr_load_mrs_calib(void);$//g' $tgt
+	sed -i 's/^static void rw_mgr_load_mrs_exec(void);$//g' $tgt
+	sed -i 's/^static void scc_mgr_set_group_dqs_io_and_oct_out2_gradual(uint32_t write_group, uint32_t delay);$//g' $tgt
+	sed -i 's/^static void rw_mgr_incr_vfifo_auto(uint32_t grp);$//g' $tgt
+	sed -i 's/^static void rw_mgr_decr_vfifo_auto(uint32_t grp);$//g' $tgt
 }
 
 copy_source ${ubootsrc}/board/altera/socfpga/sdram/sequencer.c arch/arm/mach-socfpga/include/mach/sequencer.c
diff --git a/scripts/socfpga_sequencer_defines_defaults b/scripts/socfpga_sequencer_defines_defaults
index 19b12b1142bc..3ad1f588f649 100755
--- a/scripts/socfpga_sequencer_defines_defaults
+++ b/scripts/socfpga_sequencer_defines_defaults
@@ -33,6 +33,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define DYNAMIC_CALIBRATION_MODE 0
 #define DISABLE_GUARANTEED_READ 0
 
+#define AP_MODE 0
+#define ADVANCED_ODT_CONTROL 0
 #define ARRIAVGZ 0
 #define ARRIAV 0
 #define AVL_CLK_FREQ 67
@@ -56,6 +58,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define ENABLE_INST_ROM_WRITE 1
 #define ENABLE_MARGIN_REPORT_GEN 0
 #define ENABLE_NON_DESTRUCTIVE_CALIB 0
+#define ENABLE_NON_DES_CAL 0
+#define ENABLE_NON_DES_CAL_TEST 0
 #define ENABLE_SUPER_QUICK_CALIBRATION 0
 #define ENABLE_TCL_DEBUG 0
 #define FAKE_CAL_FAIL 0
-- 
2.1.4



From s.trumtrar at pengutronix.de  Wed May 13 05:56:24 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Wed, 13 May 2015 14:56:24 +0200
Subject: [PATCH 2/2] ARM: socfpga: update sdram calibration to 15.0
In-Reply-To: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1431521784-27413-3-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 arch/arm/mach-socfpga/include/mach/sequencer.c | 293 +++++--------------------
 arch/arm/mach-socfpga/include/mach/sequencer.h |   2 +
 2 files changed, 61 insertions(+), 234 deletions(-)

diff --git a/arch/arm/mach-socfpga/include/mach/sequencer.c b/arch/arm/mach-socfpga/include/mach/sequencer.c
index 90efcc826b4e..c299f754a841 100644
--- a/arch/arm/mach-socfpga/include/mach/sequencer.c
+++ b/arch/arm/mach-socfpga/include/mach/sequencer.c
@@ -48,11 +48,14 @@
  ******************************************************************************
  ******************************************************************************/
 
+#ifndef ARMCOMPILER
+
 // Temporary workaround to place the initial stack pointer at a safe offset from end
 #define STRINGIFY(s)		STRINGIFY_STR(s)
 #define STRINGIFY_STR(s)	#s
 asm(".global __alt_stack_pointer");
 asm("__alt_stack_pointer = " STRINGIFY(STACK_POINTER));
+#endif
 
 #include <mach/sdram.h>
 
@@ -222,18 +225,13 @@ static int check_test_mem(int start)
 
 static void set_failing_group_stage(uint32_t group, uint32_t stage, uint32_t substage)
 {
-	ALTERA_ASSERT(group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
-	// Only set the global stage if there was not been any other failing group
 	if (gbl->error_stage == CAL_STAGE_NIL) {
 		gbl->error_substage = substage;
 		gbl->error_stage = stage;
 		gbl->error_group = group;
-		TCLRPT_SET(debug_summary_report->error_sub_stage, substage);
-		TCLRPT_SET(debug_summary_report->error_stage, stage);
-		TCLRPT_SET(debug_summary_report->error_group, group);
 
 	}
+
 }
 
 static inline void reg_file_set_group(uint32_t set_group)
@@ -292,13 +290,6 @@ static inline void select_curr_shadow_reg_using_rank(uint32_t rank)
 
 static void initialize(void)
 {
-	TRACE_FUNC();
-
-	//USER calibration has control over path to memory 
-
-	// In Hard PHY this is a 2-bit control:
-	// 0: AFI Mux Select
-	// 1: DDIO Mux Select
 	IOWR_32DIRECT(PHY_MGR_MUX_SEL, 0, 0x3);
 
 	//USER memory clock is not stable we begin initialization 
@@ -480,27 +471,18 @@ static void scc_mgr_initialize(void)
 
 static inline void scc_mgr_set_dqs_bus_in_delay(uint32_t read_group, uint32_t delay)
 {
-	ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_IN_DELAY(read_group, delay);
 
 }
 
 static inline void scc_mgr_set_dqs_io_in_delay(uint32_t write_group, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_IO_IN_DELAY(delay);
 
 }
 
 static inline void scc_mgr_set_dqs_en_phase(uint32_t read_group, uint32_t phase)
 {
-	ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_EN_PHASE(read_group, phase);
 
 }
@@ -529,9 +511,6 @@ static void scc_mgr_set_dqs_en_phase_all_ranks(uint32_t read_group, uint32_t pha
 
 static inline void scc_mgr_set_dqdqs_output_phase(uint32_t write_group, uint32_t phase)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQDQS_OUT_PHASE(write_group, phase);
 
 }
@@ -560,9 +539,6 @@ static void scc_mgr_set_dqdqs_output_phase_all_ranks(uint32_t write_group, uint3
 
 static inline void scc_mgr_set_dqs_en_delay(uint32_t read_group, uint32_t delay)
 {
-	ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_EN_DELAY(read_group, delay);
 
 }
@@ -592,8 +568,6 @@ static void scc_mgr_set_oct_out1_delay(uint32_t write_group, uint32_t delay)
 {
 	uint32_t read_group;
 
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
 	// Load the setting in the SCC manager
 	// Although OCT affects only write data, the OCT delay is controlled by the DQS logic block
 	// which is instantiated once per read group. For protocols where a write group consists
@@ -613,8 +587,6 @@ static void scc_mgr_set_oct_out2_delay(uint32_t write_group, uint32_t delay)
 {
 	uint32_t read_group;
 
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
 	// Load the setting in the SCC manager
 	// Although OCT affects only write data, the OCT delay is controlled by the DQS logic block
 	// which is instantiated once per read group. For protocols where a write group consists
@@ -640,9 +612,6 @@ static inline void scc_mgr_set_dq_out1_delay(uint32_t write_group, uint32_t dq_i
 					     uint32_t delay)
 {
 
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
-
 	// Load the setting in the SCC manager
 	WRITE_SCC_DQ_OUT1_DELAY(dq_in_group, delay);
 
@@ -652,9 +621,6 @@ static inline void scc_mgr_set_dq_out2_delay(uint32_t write_group, uint32_t dq_i
 					     uint32_t delay)
 {
 
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
-
 	// Load the setting in the SCC manager
 	WRITE_SCC_DQ_OUT2_DELAY(dq_in_group, delay);
 
@@ -664,9 +630,6 @@ static inline void scc_mgr_set_dq_in_delay(uint32_t write_group, uint32_t dq_in_
 					   uint32_t delay)
 {
 
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dq < RW_MGR_MEM_DATA_WIDTH);
-
 	// Load the setting in the SCC manager
 	WRITE_SCC_DQ_IN_DELAY(dq_in_group, delay);
 
@@ -706,50 +669,29 @@ static inline void scc_mgr_set_hhp_dqse_map(void)
 
 static inline void scc_mgr_set_dqs_out1_delay(uint32_t write_group, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_IO_OUT1_DELAY(delay);
 
 }
 
 static inline void scc_mgr_set_dqs_out2_delay(uint32_t write_group, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DQS_IO_OUT2_DELAY(delay);
 
 }
 
 static inline void scc_mgr_set_dm_out1_delay(uint32_t write_group, uint32_t dm, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DM_IO_OUT1_DELAY(dm, delay);
-
 }
 
 static inline void scc_mgr_set_dm_out2_delay(uint32_t write_group, uint32_t dm, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DM_IO_OUT2_DELAY(dm, delay);
-
 }
 
 static inline void scc_mgr_set_dm_in_delay(uint32_t write_group, uint32_t dm, uint32_t delay)
 {
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-	ALTERA_ASSERT(dm < RW_MGR_NUM_DM_PER_WRITE_GROUP);
-
-	// Load the setting in the SCC manager
 	WRITE_SCC_DM_IO_IN_DELAY(dm, delay);
-
 }
 
 static inline void scc_mgr_set_dm_bypass(uint32_t write_group, uint32_t dm, uint32_t bypass)
@@ -1144,8 +1086,6 @@ static inline void delay_for_n_mem_clocks(const uint32_t clocks)
 	uint8_t outer;
 	uint16_t c_loop;
 
-	TRACE_FUNC("clocks=%lu ... start", clocks);
-
 	afi_clocks = (clocks + AFI_RATE_RATIO - 1) / AFI_RATE_RATIO;	/* scale (rounding up) to get afi clocks */
 
 	// Note, we don't bother accounting for being off a little bit because of a few extra instructions in outer loops
@@ -1204,14 +1144,11 @@ static inline void delay_for_n_mem_clocks(const uint32_t clocks)
 			} while (c_loop-- != 0);
 		}
 	}
-
-	TRACE_FUNC("clocks=%lu ... end", clocks);
 }
 
 // should always use constants as argument to ensure all computations are performed at compile time
 static inline void delay_for_n_ns(const uint32_t nanoseconds)
 {
-	TRACE_FUNC("nanoseconds=%lu ... end", nanoseconds);
 	delay_for_n_mem_clocks((1000 * nanoseconds) / (1000000 / AFI_CLK_FREQ) * AFI_RATE_RATIO);
 }
 
@@ -1230,8 +1167,6 @@ static void rw_mgr_mem_initialize(void)
 {
 	uint32_t r;
 
-	TRACE_FUNC();
-
 	//USER The reset / cke part of initialization is broadcasted to all ranks
 	IOWR_32DIRECT(RW_MGR_SET_CS_AND_ODT_MASK, 0, RW_MGR_RANK_ALL);
 
@@ -1295,6 +1230,7 @@ static void rw_mgr_mem_initialize(void)
 
 			continue;
 		}
+
 		//USER set rank 
 		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_OFF);
 
@@ -1343,8 +1279,6 @@ static void rw_mgr_mem_handoff(void)
 {
 	uint32_t r;
 
-	TRACE_FUNC();
-
 	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r++) {
 		if (param->skip_ranks[r]) {
 			//USER request to skip the rank
@@ -1484,8 +1418,6 @@ static void rw_mgr_mem_calibrate_read_load_patterns(uint32_t rank_bgn, uint32_t
 	uint32_t rank_end =
 	    all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS : (rank_bgn + NUM_RANKS_PER_SHADOW_REG);
 
-	TRACE_FUNC();
-
 	for (r = rank_bgn; r < rank_end; r++) {
 		if (param->skip_ranks[r]) {
 			//USER request to skip the rank
@@ -1794,7 +1726,7 @@ static void rw_mgr_decr_vfifo(uint32_t grp, uint32_t * v)
 
 static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 {
-	uint32_t i, d, v, p, sr;
+	uint32_t i, d, v, p;
 	uint32_t max_working_cnt;
 	uint32_t fail_cnt;
 	t_btfld bit_chk;
@@ -1804,10 +1736,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	uint32_t test_status;
 	uint32_t found_passing_read, found_failing_read, initial_failing_dtap;
 
-	TRACE_FUNC("%lu", grp);
-	BFM_STAGE("find_dqs_en_phase");
-	ALTERA_ASSERT(grp < RW_MGR_MEM_IF_READ_DQS_WIDTH);
-
 	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);
 
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
@@ -1825,9 +1753,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 	}
 	dtaps_per_ptap--;
-	ALTERA_ASSERT(dtaps_per_ptap <= IO_DQS_EN_DELAY_MAX);
 	tmp_delay = 0;
-	TCLRPT_SET(debug_summary_report->computed_dtap_per_ptap, dtaps_per_ptap);
 
 	// VFIFO sweep
 
@@ -1938,35 +1864,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 			}
 		}
 
-		// Record the debug data
-		// Currently dqsen is the same for all ranks
-		for (sr = 0; sr < NUM_SHADOW_REGS; sr++) {
-			TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].work_begin,
-				   work_bgn);
-			if (found_begin) {
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].phase_begin,
-					   p);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].delay_begin,
-					   d);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].vfifo_begin,
-					   v % VFIFO_SIZE);
-			} else if (p == IO_DQS_EN_PHASE_MAX) {
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].phase_begin,
-					   0);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].delay_begin,
-					   0);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].vfifo_begin,
-					   (v + 1) % VFIFO_SIZE);
-			} else {
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].phase_begin,
-					   p + 1);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].delay_begin,
-					   0);
-				TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].vfifo_begin,
-					   v % VFIFO_SIZE);
-			}
-		}
-
 		//USER We have found a working dtap before the ptap found above 
 		if (found_begin == 1) {
 			max_working_cnt++;
@@ -2086,14 +1983,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	BFM_GBL_SET(dqs_enable_right_edge[grp].d, d - 1);
 	BFM_GBL_SET(dqs_enable_right_edge[grp].ps, work_end);
 
-	// Record the debug data
-	for (sr = 0; sr < NUM_SHADOW_REGS; sr++) {
-		TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].work_end, work_end);
-		TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].phase_end, p);
-		TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].delay_end, d - 1);
-		TCLRPT_SET(debug_cal_report->cal_dqsen_margins[sr][grp].vfifo_end, v % VFIFO_SIZE);
-	}
-
 	if (work_end >= work_bgn) {
 		//USER we have a working range 
 	} else {
@@ -2168,7 +2057,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		dtaps_per_ptap = d - initial_failing_dtap;
 	}
 
-	ALTERA_ASSERT(dtaps_per_ptap <= IO_DQS_EN_DELAY_MAX);
 	IOWR_32DIRECT(REG_FILE_DTAPS_PER_PTAP, 0, dtaps_per_ptap);
 
 	DPRINT(2, "find_dqs_en_phase: dtaps_per_ptap=%lu - %lu = %lu", d, initial_failing_dtap,
@@ -2196,12 +2084,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	     d++, tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP) ;
 	DPRINT(2, "new d %ld, tmp_delay=%ld", d, tmp_delay);
 
-	// DQSEN same for all shadow reg
-	for (sr = 0; sr < NUM_SHADOW_REGS; sr++) {
-		TCLRPT_SET(debug_cal_report->cal_dqs_in_margins[sr][grp].dqsen_margin,
-			   max_working_cnt - 1);
-	}
-
 	scc_mgr_set_dqs_en_phase_all_ranks(grp, p - 1);
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
@@ -2543,8 +2425,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	t_btfld bit_chk;
 	uint32_t delay_per_ptap_mid;
 
-	TRACE_FUNC("%lu", grp);
-
 	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);
 
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
@@ -2667,9 +2547,7 @@ static inline uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_
 	uint32_t d;
 	uint32_t r;
 
-	const uint32_t delay_step = IO_IO_IN_DELAY_MAX / (RW_MGR_MEM_DQ_PER_READ_DQS - 1);	/* we start at zero, so have one less dq to devide among */
-
-	TRACE_FUNC("(%lu,%lu,%lu)", write_group, read_group, test_bgn);
+	const uint32_t delay_step = IO_IO_IN_DELAY_MAX / (RW_MGR_MEM_DQ_PER_READ_DQS - 1);
 
 	// try different dq_in_delays since the dq path is shorter than dqs
 
@@ -2725,11 +2603,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn, uint32_t wr
 	int32_t dq_margin, dqs_margin;
 	uint32_t stop;
 
-	TRACE_FUNC("%lu %lu", read_group, test_bgn);
-
-	ALTERA_ASSERT(read_group < RW_MGR_MEM_IF_READ_DQS_WIDTH);
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
 	start_dqs = READ_SCC_DQS_IN_DELAY(read_group);
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
 		start_dqs_en = READ_SCC_DQS_EN_DELAY(read_group);
@@ -3041,8 +2914,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn, uint32_t gr
 	uint32_t dq_margin, dqs_margin;
 	uint32_t start_dqs;
 
-	TRACE_FUNC("%lu %lu", grp, test_bgn);
-
 	//USER per-bit deskew.
 	//USER start of the per-bit sweep with the minimum working delay setting for
 	//USER all bits.
@@ -3177,8 +3048,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo(uint32_t read_group, uint32_t test_bg
 	uint32_t grp_calibrated;
 	uint32_t write_group, write_test_bgn;
 	uint32_t failed_substage;
-
-	TRACE_FUNC("%lu %lu", read_group, test_bgn);
+	uint32_t dqs_in_dtaps, orig_start_dqs;
 
 	//USER update info for sims 
 
@@ -3253,33 +3123,65 @@ static uint32_t rw_mgr_mem_calibrate_vfifo(uint32_t read_group, uint32_t test_bg
 					break;
 				}
 			}
-// case:56390
-			grp_calibrated = 1;
-			if (rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay
-			    (write_group, read_group, test_bgn)) {
-				// USER Read per-bit deskew can be done on a per shadow register basis
+			// Loop over different DQS in delay chains for the purpose of DQS Enable calibration finding one bit working
+			orig_start_dqs = READ_SCC_DQS_IN_DELAY(read_group);
+			for (dqs_in_dtaps = orig_start_dqs;
+			     dqs_in_dtaps <= IO_DQS_IN_DELAY_MAX && grp_calibrated == 0;
+			     dqs_in_dtaps++) {
+
 				for (rank_bgn = 0, sr = 0; rank_bgn < RW_MGR_MEM_NUMBER_OF_RANKS;
 				     rank_bgn += NUM_RANKS_PER_SHADOW_REG, ++sr) {
-					//USER Determine if this set of ranks should be skipped entirely
+
 					if (!param->skip_shadow_regs[sr]) {
 
 						//USER Select shadow register set
 						select_shadow_regs_for_update(rank_bgn, read_group,
 									      1);
 
-						// If doing read after write calibration, do not update FOM now - do it then
-						if (!rw_mgr_mem_calibrate_vfifo_center
-						    (rank_bgn, write_group, read_group, test_bgn, 1,
-						     0)) {
-							grp_calibrated = 0;
-							failed_substage = CAL_SUBSTAGE_VFIFO_CENTER;
+						WRITE_SCC_DQS_IN_DELAY(read_group, dqs_in_dtaps);
+						scc_mgr_load_dqs(read_group);
+						IOWR_32DIRECT(SCC_MGR_UPD, 0, 0);
+					}
+				}
+
+// case:56390
+				grp_calibrated = 1;
+				if (rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay
+				    (write_group, read_group, test_bgn)) {
+					// USER Read per-bit deskew can be done on a per shadow register basis
+					for (rank_bgn = 0, sr = 0;
+					     rank_bgn < RW_MGR_MEM_NUMBER_OF_RANKS;
+					     rank_bgn += NUM_RANKS_PER_SHADOW_REG, ++sr) {
+						//USER Determine if this set of ranks should be skipped entirely
+						if (!param->skip_shadow_regs[sr]) {
+
+							//USER Select shadow register set
+							select_shadow_regs_for_update(rank_bgn,
+										      read_group,
+										      1);
+
+							// Before doing read deskew, set DQS in back to the reserve value
+							WRITE_SCC_DQS_IN_DELAY(read_group,
+									       orig_start_dqs);
+							scc_mgr_load_dqs(read_group);
+							IOWR_32DIRECT(SCC_MGR_UPD, 0, 0);
+
+							// If doing read after write calibration, do not update FOM now - do it then
+							if (!rw_mgr_mem_calibrate_vfifo_center
+							    (rank_bgn, write_group, read_group,
+							     test_bgn, 1, 0)) {
+								grp_calibrated = 0;
+								failed_substage =
+								    CAL_SUBSTAGE_VFIFO_CENTER;
+							}
 						}
 					}
+				} else {
+					grp_calibrated = 0;
+					failed_substage = CAL_SUBSTAGE_DQS_EN_PHASE;
 				}
-			} else {
-				grp_calibrated = 0;
-				failed_substage = CAL_SUBSTAGE_DQS_EN_PHASE;
 			}
+
 		}
 	}
 
@@ -3307,8 +3209,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo(uint32_t g, uint32_t test_bgn)
 	uint32_t grp_calibrated;
 	uint32_t failed_substage;
 
-	TRACE_FUNC("%lu %lu", g, test_bgn);
-
 	//USER update info for sims 
 
 	reg_file_set_stage(CAL_STAGE_VFIFO);
@@ -3380,8 +3280,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_end(uint32_t read_group, uint32_t tes
 	uint32_t grp_calibrated;
 	uint32_t write_group;
 
-	TRACE_FUNC("%lu %lu", read_group, test_bgn);
-
 	//USER update info for sims 
 
 	reg_file_set_stage(CAL_STAGE_VFIFO_AFTER_WRITES);
@@ -3432,9 +3330,6 @@ static uint32_t rw_mgr_mem_calibrate_lfifo(void)
 	uint32_t found_one;
 	t_btfld bit_chk;
 
-	TRACE_FUNC();
-	BFM_STAGE("lfifo");
-
 	//USER update info for sims 
 
 	reg_file_set_stage(CAL_STAGE_LFIFO);
@@ -3588,6 +3483,7 @@ static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group, uint32_t test_
 	}
 
 	IOWR_32DIRECT(RW_MGR_RUN_SINGLE_GROUP, (group << 2), mcc_instruction);
+
 }
 
 //USER Test writes, can check for a single bit pass or multiple bit pass
@@ -3673,7 +3569,7 @@ static inline uint32_t rw_mgr_mem_calibrate_write_test_all_ranks(uint32_t write_
 //USER Write Levelling -- Full Calibration
 static uint32_t rw_mgr_mem_calibrate_wlevel(uint32_t g, uint32_t test_bgn)
 {
-	uint32_t p, d, sr;
+	uint32_t p, d;
 
 	uint32_t num_additional_fr_cycles = 0;
 
@@ -3683,9 +3579,6 @@ static uint32_t rw_mgr_mem_calibrate_wlevel(uint32_t g, uint32_t test_bgn)
 	uint32_t found_begin;
 	uint32_t dtaps_per_ptap;
 
-	TRACE_FUNC("%lu %lu", g, test_bgn);
-	BFM_STAGE("wlevel");
-
 	//USER update info for sims
 
 	reg_file_set_stage(CAL_STAGE_WLEVEL);
@@ -3864,11 +3757,6 @@ static uint32_t rw_mgr_mem_calibrate_wlevel(uint32_t g, uint32_t test_bgn)
 	BFM_GBL_SET(dqs_wlevel_right_edge[g].d, d - 1);
 	BFM_GBL_SET(dqs_wlevel_right_edge[g].ps, work_end);
 
-	for (sr = 0; sr < NUM_SHADOW_REGS; sr++) {
-		TCLRPT_SET(debug_cal_report->cal_dqs_out_margins[sr][g].dqdqs_start, work_bgn);
-		TCLRPT_SET(debug_cal_report->cal_dqs_out_margins[sr][g].dqdqs_end, work_end);
-	}
-
 	//USER center 
 
 	work_mid = (work_bgn + work_end) / 2;
@@ -3926,8 +3814,6 @@ static uint32_t rw_mgr_mem_calibrate_wlevel(uint32_t g, uint32_t test_bgn)
 	uint32_t work_bgn, work_end, work_mid;
 	uint32_t tmp_delay;
 
-	TRACE_FUNC("%lu %lu", g, test_bgn);
-
 	//USER update info for sims
 
 	reg_file_set_stage(CAL_STAGE_WLEVEL);
@@ -4071,11 +3957,6 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn, uint32_t w
 	int32_t end_best = IO_IO_OUT1_DELAY_MAX + 1;
 	int32_t win_best = 0;
 
-	TRACE_FUNC("%lu %lu", write_group, test_bgn);
-	BFM_STAGE("writes_center");
-
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
 	dm_margin = 0;
 
 	start_dqs = READ_SCC_DQS_IO_OUT1_DELAY();
@@ -4302,20 +4183,13 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn, uint32_t w
 		IOWR_32DIRECT(SCC_MGR_UPD, 0, 0);
 	}
 
-	//////////////////////
-	//////////////////////
-	//USER Centre DM 
-	//////////////////////
-	//////////////////////
-
-	BFM_STAGE("dm_center");
-
 	DPRINT(2, "write_center: DM");
 
 	//USER set the left and right edge of each bit to an illegal value 
 	//USER use (IO_IO_OUT1_DELAY_MAX + 1) as an illegal value
 	left_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
 	right_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
+
 	//USER Search for the/part of the window with DM shift
 	for (d = IO_IO_OUT1_DELAY_MAX; d >= 0; d -= DELTA_D) {
 		scc_mgr_apply_group_dm_out1_delay(write_group, d);
@@ -4447,10 +4321,6 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn, uint32_t w
 	uint32_t start_dqs;
 	uint32_t stop;
 
-	TRACE_FUNC("%lu %lu", write_group, test_bgn);
-
-	ALTERA_ASSERT(write_group < RW_MGR_MEM_IF_WRITE_DQS_WIDTH);
-
 	//USER per-bit deskew 
 
 	for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
@@ -4622,9 +4492,6 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn, uint32_t w
 
 static uint32_t rw_mgr_mem_calibrate_writes(uint32_t rank_bgn, uint32_t g, uint32_t test_bgn)
 {
-	//USER update info for sims
-
-	TRACE_FUNC("%lu %lu", g, test_bgn);
 
 	reg_file_set_stage(CAL_STAGE_WRITES);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_WRITES_CENTER);
@@ -4681,8 +4548,6 @@ static void mem_config(void)
 	uint32_t rw_wl_nop_cycles;
 	uint32_t max_latency;
 
-	TRACE_FUNC();
-
 	//USER read in write and read latency 
 
 	wlat = IORD_32DIRECT(MEM_T_WL_ADD, 0);
@@ -4771,8 +4636,6 @@ static void mem_skip_calibrate(void)
 	uint32_t vfifo_offset;
 	uint32_t i, j, r;
 
-	TRACE_FUNC();
-
 	// Need to update every shadow register set used by the interface       
 	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS; r += NUM_RANKS_PER_SHADOW_REG) {
 
@@ -4857,8 +4720,6 @@ static uint32_t mem_calibrate(void)
 	uint32_t group_failed = 0;
 	uint32_t sr_failed = 0;
 
-	TRACE_FUNC();
-
 	// Initialize the data settings
 	DPRINT(1, "Preparing to init data");
 	DPRINT(1, "Init complete");
@@ -4869,9 +4730,6 @@ static uint32_t mem_calibrate(void)
 	gbl->fom_in = 0;
 	gbl->fom_out = 0;
 
-	TCLRPT_SET(debug_summary_report->cal_read_latency, 0);
-	TCLRPT_SET(debug_summary_report->cal_write_latency, 0);
-
 	mem_config();
 
 	if (ARRIAV || CYCLONEV) {
@@ -4991,10 +4849,6 @@ static uint32_t mem_calibrate(void)
 							}
 						}
 						if (sr_failed == 0) {
-							TCLRPT_SET(debug_cal_report->
-								   cal_status_per_group[sr]
-								   [write_group].error_stage,
-								   CAL_STAGE_NIL);
 						} else {
 							group_failed = 1;
 						}
@@ -5057,19 +4911,6 @@ static uint32_t mem_calibrate(void)
 		}
 	}
 
-	TCLRPT_SET(debug_summary_report->cal_write_latency, IORD_32DIRECT(MEM_T_WL_ADD, 0));
-	if (QUARTER_RATE == 1) {
-		// The read latency is in terms of AFI cycles so we multiply by 4 in quarter
-		// rate to get the memory cycles.
-		TCLRPT_SET(debug_summary_report->cal_read_latency, gbl->curr_read_lat * 4);
-	} else if (HALF_RATE == 1) {
-		// The read latency is in terms of AFI cycles so we multiply by 2 in half
-		// rate to get the memory cycles.
-		TCLRPT_SET(debug_summary_report->cal_read_latency, gbl->curr_read_lat * 2);
-	} else {
-		TCLRPT_SET(debug_summary_report->cal_read_latency, gbl->curr_read_lat);
-	}
-
 	//USER Do not remove this line as it makes sure all of our decisions have been applied
 	IOWR_32DIRECT(SCC_MGR_UPD, 0, 0);
 	return 1;
@@ -5077,6 +4918,7 @@ static uint32_t mem_calibrate(void)
 
 static uint32_t run_mem_calibrate(void)
 {
+
 	uint32_t pass;
 	uint32_t debug_info;
 	uint32_t ctrlcfg = IORD_32DIRECT(CTRL_CONFIG_REG, 0);
@@ -5085,10 +4927,6 @@ static uint32_t run_mem_calibrate(void)
 	// This should occur before anything else
 	// Reset pass/fail status shown on afi_cal_success/fail
 	IOWR_32DIRECT(PHY_MGR_CAL_STATUS, 0, PHY_MGR_CAL_RESET);
-
-	TRACE_FUNC();
-
-	BFM_STAGE("calibrate");
 	//stop tracking manger
 
 	IOWR_32DIRECT(CTRL_CONFIG_REG, 0, ctrlcfg & 0xFFBFFFFF);
@@ -5106,10 +4944,6 @@ static uint32_t run_mem_calibrate(void)
 	IOWR_32DIRECT(PHY_MGR_CMD_FIFO_RESET, 0, 0);
 
 	if (pass) {
-		TCLRPT_SET(debug_summary_report->error_stage, CAL_STAGE_NIL);
-
-		BFM_STAGE("handoff");
-
 #ifdef TEST_SIZE
 		if (!check_test_mem(0)) {
 			gbl->error_stage = 0x92;
@@ -5173,14 +5007,6 @@ static uint32_t run_mem_calibrate(void)
 
 	}
 
-	// Mark the reports as being ready to read
-	TCLRPT_SET(debug_summary_report->report_flags, debug_summary_report->report_flags |=
-		   DEBUG_REPORT_STATUS_REPORT_READY);
-	TCLRPT_SET(debug_cal_report->report_flags, debug_cal_report->report_flags |=
-		   DEBUG_REPORT_STATUS_REPORT_READY);
-	TCLRPT_SET(debug_margin_report->report_flags, debug_margin_report->report_flags |=
-		   DEBUG_REPORT_STATUS_REPORT_READY);
-
 	// Set the debug status to show that calibration has ended.
 	// This should occur after everything else
 	return pass;
@@ -5349,7 +5175,6 @@ static int socfpga_mem_calibration(void)
 
 	IPRINT("Preparing to start memory calibration");
 
-	TRACE_FUNC();
 	DPRINT(1,
 	       "%s%s %s ranks=%lu cs/dimm=%lu dq/dqs=%lu,%lu vg/dqs=%lu,%lu dqs=%lu,%lu dq=%lu dm=%lu "
 	       "ptap_delay=%lu dtap_delay=%lu dtap_dqsen_delay=%lu, dll=%lu",
diff --git a/arch/arm/mach-socfpga/include/mach/sequencer.h b/arch/arm/mach-socfpga/include/mach/sequencer.h
index 1671849d6dca..dd0378af34f9 100644
--- a/arch/arm/mach-socfpga/include/mach/sequencer.h
+++ b/arch/arm/mach-socfpga/include/mach/sequencer.h
@@ -65,6 +65,8 @@
 
 #define RW_MGR_LOOPBACK_MODE BASE_RW_MGR + 0x0200
 
+#define RW_MGR_ENABLE_REFRESH BASE_RW_MGR + 0x3000
+
 #define RW_MGR_RANK_NONE 0xFF
 #define RW_MGR_RANK_ALL 0x00
 
-- 
2.1.4



From andrew.smirnov at gmail.com  Wed May 13 19:54:18 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:18 -0700
Subject: [PATCH 01/10] common/memtest.c: Fix incorrect array boundary check
Message-ID: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 common/memtest.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/common/memtest.c b/common/memtest.c
index 25a97d8..3b0bcb7 100644
--- a/common/memtest.c
+++ b/common/memtest.c
@@ -91,8 +91,7 @@ int mem_test(resource_size_t _start,
 	 * '0's and '0' bits through a field of '1's (i.e.
 	 * pattern and ~pattern).
 	 */
-	for (i = 0; i < ARRAY_SIZE(bitpattern)/
-			sizeof(resource_size_t); i++) {
+	for (i = 0; i < ARRAY_SIZE(bitpattern); i++) {
 		val = bitpattern[i];

 		for (; val != 0; val <<= 1) {
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:19 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:19 -0700
Subject: [PATCH 02/10] common/memtest.c: Do not omit offset of 0 from tests
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-2-git-send-email-andrew.smirnov@gmail.com>

Ommiting offset 0 from address line tests allows certain corner cases
of faults to be undetected.

For the "stuck high" case, consider scenario in which all of the
tested address lines are stuck high. In original code first data
filling loop would execute writing data to a single cell multiple
times and second loop would just read data from that cell over and
over again. Adding a write to start[0] should prevent this since it
would cause the second loop to read incorrect data on its first
iteration.

For the "stuck low" case, having any of the tested bits of the address
shorted would effectively "remap" that memory cell to start[0] in this
case excluding start[0] during the verification phase would result in
a false positive result.

Note that both of the changes are present in Michael Barr's code here:
http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/software-based-memory-testing.html

and the code in barebox is based on that code.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 common/memtest.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/common/memtest.c b/common/memtest.c
index 3b0bcb7..9eda788 100644
--- a/common/memtest.c
+++ b/common/memtest.c
@@ -170,6 +170,15 @@ int mem_test(resource_size_t _start,
 	for (offset = 1; offset <= num_words; offset <<= 1)
 		start[offset] = pattern;

+	/*
+	 * Now write anti-pattern at offset 0. If during the previous
+	 * step one of the address lines got stuck high this
+	 * operation would result in a memory cell at power-of-two
+	 * offset being set to anti-pattern which hopefully would be
+	 * detected byt the loop that follows.
+	 */
+	start[0] = anti_pattern;
+
 	printf("Check for address bits stuck high.\n");

 	/*
@@ -187,6 +196,11 @@ int mem_test(resource_size_t _start,
 		}
 	}

+	/*
+	  Restore original value
+	 */
+	start[0] = pattern;
+
 	printf("Check for address bits stuck "
 			"low or shorted.\n");

@@ -196,7 +210,8 @@ int mem_test(resource_size_t _start,
 	for (offset2 = 1; offset2 <= num_words; offset2 <<= 1) {
 		start[offset2] = anti_pattern;

-		for (offset = 1; offset <= num_words; offset <<= 1) {
+		for (offset = 0; offset <= num_words;
+		     offset = (offset) ? offset << 1 : 1) {
 			temp = start[offset];

 			if ((temp != pattern) &&
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:21 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:21 -0700
Subject: [PATCH 04/10] common/memtest.c: Distil common error reporting code
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-4-git-send-email-andrew.smirnov@gmail.com>

Move all of the common code for error message output into a new
function mem_test_report_failure() and convert the rest of the code to
use it.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 common/memtest.c | 53 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 25 deletions(-)

diff --git a/common/memtest.c b/common/memtest.c
index 57e2ad9..d8d1154 100644
--- a/common/memtest.c
+++ b/common/memtest.c
@@ -28,6 +28,17 @@
 #include <errno.h>
 #include <memtest.h>

+static void mem_test_report_failure(const char *failure_description,
+				    resource_size_t expected_value,
+				    resource_size_t actual_value,
+				    volatile resource_size_t *address)
+{
+	printf("FAILURE (%s): "
+	       "expected 0x%08x, actual 0x%08x at address 0x%08x.\n",
+	       failure_description, expected_value, actual_value,
+	       (resource_size_t)address);
+}
+
 int mem_test_bus_integrity(resource_size_t _start,
 			   resource_size_t _end)
 {
@@ -87,9 +98,8 @@ int mem_test_bus_integrity(resource_size_t _start,
 			*dummy = ~val;
 			readback = *start;
 			if (readback != val) {
-				printf("FAILURE (data line): "
-					"expected 0x%08x, actual 0x%08x at address 0x%08x.\n",
-					val, readback, (resource_size_t)start);
+				mem_test_report_failure("data line",
+							val, readback, start);
 				return -EIO;
 			}

@@ -97,10 +107,8 @@ int mem_test_bus_integrity(resource_size_t _start,
 			*dummy = val;
 			readback = *start;
 			if (readback != ~val) {
-				printf("FAILURE (data line): "
-					"Is 0x%08x, should be 0x%08x at address 0x%08x.\n",
-					readback,
-					~val, (resource_size_t)start);
+				mem_test_report_failure("data line",
+							~val, readback, start);
 				return -EIO;
 			}
 		}
@@ -174,11 +182,8 @@ int mem_test_bus_integrity(resource_size_t _start,
 	for (offset = 1; offset <= num_words; offset <<= 1) {
 		temp = start[offset];
 		if (temp != pattern) {
-			printf("FAILURE: Address bit "
-					"stuck high @ 0x%08x:"
-					" expected 0x%08x, actual 0x%08x.\n",
-					(resource_size_t)&start[offset],
-					pattern, temp);
+			mem_test_report_failure("address bit stuck high",
+						pattern, temp, &start[offset]);
 			return -EIO;
 		}
 	}
@@ -203,11 +208,9 @@ int mem_test_bus_integrity(resource_size_t _start,

 			if ((temp != pattern) &&
 					(offset != offset2)) {
-				printf("FAILURE: Address bit stuck"
-						" low or shorted @"
-						" 0x%08x: expected 0x%08x, actual 0x%08x.\n",
-						(resource_size_t)&start[offset],
-						pattern, temp);
+				mem_test_report_failure(
+					"address bit stuck low or shorted",
+					pattern, temp, &start[offset]);
 				return -EIO;
 			}
 		}
@@ -278,10 +281,10 @@ int mem_test_dram(resource_size_t _start,

 		temp = start[offset];
 		if (temp != (offset + 1)) {
-			printf("\nFAILURE (read/write) @ 0x%08x:"
-					" expected 0x%08x, actual 0x%08x.\n",
-					(resource_size_t)&start[offset],
-					(offset + 1), temp);
+			printf("\n");
+			mem_test_report_failure("read/write",
+						(offset + 1),
+						temp, &start[offset]);
 			return -EIO;
 		}

@@ -306,10 +309,10 @@ int mem_test_dram(resource_size_t _start,
 		temp = start[offset];

 		if (temp != anti_pattern) {
-			printf("\nFAILURE (read/write): @ 0x%08x:"
-					" expected 0x%08x, actual 0x%08x.\n",
-					(resource_size_t)&start[offset],
-					anti_pattern, temp);
+			printf("\n");
+			mem_test_report_failure("read/write",
+						anti_pattern,
+						temp, &start[offset]);
 			return -EIO;
 		}

--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:20 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:20 -0700
Subject: [PATCH 03/10] common/memtest.c: Refactor mem_test() into three
 surbroutines
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-3-git-send-email-andrew.smirnov@gmail.com>

Original mem_test() was rather long an contained code to perform two
distinct operations. This patch moves that code into two separate
subroutines and converts mem_test into a high level interface that
calls the subroutines.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 common/memtest.c | 105 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 68 insertions(+), 37 deletions(-)

diff --git a/common/memtest.c b/common/memtest.c
index 9eda788..57e2ad9 100644
--- a/common/memtest.c
+++ b/common/memtest.c
@@ -28,35 +28,22 @@
 #include <errno.h>
 #include <memtest.h>

-static const resource_size_t bitpattern[] = {
-	0x00000001,	/* single bit */
-	0x00000003,	/* two adjacent bits */
-	0x00000007,	/* three adjacent bits */
-	0x0000000F,	/* four adjacent bits */
-	0x00000005,	/* two non-adjacent bits */
-	0x00000015,	/* three non-adjacent bits */
-	0x00000055,	/* four non-adjacent bits */
-	0xAAAAAAAA,	/* alternating 1/0 */
-};
-
-/*
- * Perform a memory test. The complete test
- * loops until interrupted by ctrl-c.
- *
- * Prameters:
- * start: start address for memory test.
- * end: end address of memory test.
- * bus_only: skip integrity check and do only a address/data bus
- *	     testing.
- *
- * Return value can be -EINVAL for invalid parameter or -EINTR
- * if memory test was interrupted.
- */
-int mem_test(resource_size_t _start,
-	       resource_size_t _end, int bus_only)
+int mem_test_bus_integrity(resource_size_t _start,
+			   resource_size_t _end)
 {
-	volatile resource_size_t *start, *dummy, val, readback, offset,
-		offset2, pattern, temp, anti_pattern, num_words;
+	static const resource_size_t bitpattern[] = {
+		0x00000001,	/* single bit */
+		0x00000003,	/* two adjacent bits */
+		0x00000007,	/* three adjacent bits */
+		0x0000000F,	/* four adjacent bits */
+		0x00000005,	/* two non-adjacent bits */
+		0x00000015,	/* three non-adjacent bits */
+		0x00000055,	/* four non-adjacent bits */
+		0xAAAAAAAA,	/* alternating 1/0 */
+	};
+
+	volatile resource_size_t *start, *dummy, num_words, val, readback, offset,
+		offset2, pattern, temp, anti_pattern;
 	int i;

 	_start = ALIGN(_start, sizeof(resource_size_t));
@@ -66,7 +53,7 @@ int mem_test(resource_size_t _start,
 		return -EINVAL;

 	start = (resource_size_t *)_start;
-	/*
+		/*
 	 * Point the dummy to start[1]
 	 */
 	dummy = start + 1;
@@ -227,15 +214,25 @@ int mem_test(resource_size_t _start,
 		start[offset2] = pattern;
 	}

-	/*
-	 * We tested only the bus if != 0
-	 * leaving here
-	 */
-	if (bus_only)
-		return 0;
+	return 0;
+}
+
+int mem_test_dram(resource_size_t _start,
+		  resource_size_t _end)
+{
+	volatile resource_size_t *start, num_words, offset, temp, anti_pattern;
+
+	_start = ALIGN(_start, sizeof(resource_size_t));
+	_end = ALIGN_DOWN(_end, sizeof(resource_size_t)) - 1;
+
+	if (_end <= _start)
+		return -EINVAL;
+
+	start = (resource_size_t *)_start;
+	num_words = (_end - _start + 1)/sizeof(resource_size_t);

 	printf("Starting integrity check of physicaly ram.\n"
-			"Filling ram with patterns...\n");
+	       "Filling ram with patterns...\n");

 	/*
 	 * Description: Test the integrity of a physical
@@ -252,16 +249,17 @@ int mem_test(resource_size_t _start,
 	 * Fill memory with a known pattern.
 	 */
 	init_progression_bar(num_words);
+
 	for (offset = 0; offset < num_words; offset++) {
 		/*
 		 * Every 4K we update the progressbar.
 		 */
+
 		if (!(offset & (SZ_4K - 1))) {
 			if (ctrlc())
 				return -EINTR;
 			show_progress(offset);
 		}
-
 		start[offset] = offset + 1;
 	}
 	show_progress(offset);
@@ -326,3 +324,36 @@ int mem_test(resource_size_t _start,

 	return 0;
 }
+
+/*
+ * Perform a memory test. The complete test
+ * loops until interrupted by ctrl-c.
+ *
+ * Prameters:
+ * start: start address for memory test.
+ * end: end address of memory test.
+ * bus_only: skip integrity check and do only a address/data bus
+ *	     testing.
+ *
+ * Return value can be -EINVAL for invalid parameter or -EINTR
+ * if memory test was interrupted.
+ */
+int mem_test(resource_size_t _start,
+	       resource_size_t _end, int bus_only)
+{
+	int ret;
+
+	ret = mem_test_bus_integrity(_start, _end);
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We tested only the bus if != 0
+	 * leaving here
+	 */
+	if (!bus_only)
+		ret = mem_test_dram(_start, _end);
+
+	return ret;
+}
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:23 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:23 -0700
Subject: [PATCH 06/10] common: pbl: Allow boards to override hang()
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-6-git-send-email-andrew.smirnov@gmail.com>

Add provisions such that board code can re-define the behaviour of
hang() to implement a behaviour better suited for a particular
hardware platform.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 common/startup.c | 15 ++++++++++++++-
 include/common.h | 22 ++++++++++++++++++++++
 pbl/misc.c       | 19 ++++++++++++++++++-
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/common/startup.c b/common/startup.c
index e59b06d..d701fab 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -118,12 +118,25 @@ void __noreturn start_barebox(void)
 	/* NOTREACHED - no way out of command loop except booting */
 }

-void __noreturn hang (void)
+void __noreturn __hang (void)
 {
 	puts ("### ERROR ### Please RESET the board ###\n");
 	for (;;);
 }

+static hang_handler_t hang_handler = __hang;
+
+void __noreturn hang(void)
+{
+	hang_handler();
+}
+
+void set_hang_handler(hang_handler_t handler)
+{
+	hang_handler = handler;
+}
+
+
 void (*board_shutdown)(void);

 /* Everything needed to cleanly shutdown barebox.
diff --git a/include/common.h b/include/common.h
index eef371c..86e755d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -56,7 +56,11 @@
  */
 void reginfo(void);

+typedef void __noreturn (*hang_handler_t)(void);
+
 void __noreturn hang (void);
+void __noreturn __hang (void);
+void set_hang_handler(hang_handler_t handler);

 char *size_human_readable(unsigned long long size);

@@ -193,6 +197,24 @@ void barebox_set_hostname(const char *);
 #define IOMEM(addr)	((void __force __iomem *)(addr))
 #endif

+#if defined(CONFIG_ARM)
+#include <asm/barebox-arm.h>
+
+static inline void *get_true_address(const void *ptr)
+{
+	resource_size_t address = (resource_size_t)ptr;
+
+	address -= get_runtime_offset();
+
+	return (void *)address;
+}
+#else
+static inline void *get_true_address(const void *ptr)
+{
+	return (void *)ptr;
+}
+#endif
+
 /*
  * Check if two regions overlap. returns true if they do, false otherwise
  */
diff --git a/pbl/misc.c b/pbl/misc.c
index 7e76120..3d5a881 100644
--- a/pbl/misc.c
+++ b/pbl/misc.c
@@ -4,11 +4,28 @@
 #include <linux/string.h>
 #include <linux/ctype.h>

-void __noreturn hang(void)
+void __noreturn __hang(void)
 {
 	while (1);
 }

+static hang_handler_t hang_handler = __hang;
+
+void __noreturn hang(void)
+{
+	hang_handler_t *__hand_handler_p = get_true_address(&hang_handler);
+	hang_handler_t __hang_handler    = get_true_address(*__hand_handler_p);
+
+	__hang_handler();
+}
+
+void set_hang_handler(hang_handler_t handler)
+{
+	hang_handler_t *__hang_handler_p = get_true_address(&hang_handler);
+
+	*__hang_handler_p = handler;
+}
+
 void __noreturn panic(const char *fmt, ...)
 {
 	while(1);
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:22 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:22 -0700
Subject: [PATCH 05/10] serial: i.MX: Write settings to a correct register
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-5-git-send-email-andrew.smirnov@gmail.com>

Fix what looks like a copy and past error, where settings for USR1
register were being written to USR2.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 drivers/serial/serial_imx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 12155ad..b7ea14a 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -113,10 +113,10 @@ static int imx_serial_init_port(struct console_device *cdev)
 	writel(val, regs + USR2);

   	/* Clear status flags */
-	val = readl(regs + USR2);
+	val = readl(regs + USR1);
 	val |= USR1_PARITYERR | USR1_RTSD | USR1_ESCF | USR1_FRAMERR | USR1_AIRINT |
 	       USR1_AWAKE;
-	writel(val, regs + USR2);
+	writel(val, regs + USR1);

 	return 0;
 }
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:24 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:24 -0700
Subject: [PATCH 07/10] debug_ll: i.MX: Add support for input to DEBUG_LL
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-7-git-send-email-andrew.smirnov@gmail.com>

Add input support to DEBUG_LL infrastructure and implement it for i.MX

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/Kconfig                          |  1 +
 arch/arm/mach-imx/include/mach/debug_ll.h | 26 ++++++++++++++++++++++++++
 common/Kconfig                            | 11 +++++++++++
 include/debug_ll.h                        | 30 ++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50f3095..47d792b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -103,6 +103,7 @@ config ARCH_IMX
 	select CLKDEV_LOOKUP
 	select WATCHDOG_IMX_RESET_SOURCE
 	select HAS_DEBUG_LL
+	select HAS_DEBUG_LL_INPUT

 config ARCH_MVEBU
 	bool "Marvell EBU platforms"
diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h
index 8eb59f6..3f5a102 100644
--- a/arch/arm/mach-imx/include/mach/debug_ll.h
+++ b/arch/arm/mach-imx/include/mach/debug_ll.h
@@ -114,6 +114,32 @@ static inline void PUTC_LL(int c)

 	writel(c, base + URTX0);
 }
+
+#ifdef CONFIG_DEBUG_LL_INPUT
+static inline bool TSTC_LL(void)
+{
+	void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,
+						 CONFIG_DEBUG_IMX_UART_PORT));
+
+	return readl(base + USR2) & USR2_RDR;
+}
+
+static inline int GETC_LL(void)
+{
+	void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC,
+						 CONFIG_DEBUG_IMX_UART_PORT));
+
+	if (!base)
+		return -EINVAL;
+
+	if (!(readl(base + UCR1) & UCR1_UARTEN))
+		return -EINVAL;
+
+	while (!TSTC_LL());
+
+	return 0xff & readl(base + URXD0);
+}
+#endif
 #else

 static inline void imx_uart_setup_ll(void __iomem *uartbase,
diff --git a/common/Kconfig b/common/Kconfig
index 1c5d14c..4032dcd 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -774,6 +774,15 @@ config DEBUG_LL
 	  This requires SoC specific support. Most SoCs require the debug UART to be
 	  initialized by a debugger or first stage bootloader.

+config DEBUG_LL_INPUT
+        bool
+	depends on DEBUG_LL
+	depends on HAS_DEBUG_LL_INPUT
+	prompt "enable data reception on low level debug port"
+	help
+	  Enable this option if you want to be able to receive data using low
+	  level debug port as well as sending data over it.
+
 choice
 	prompt "Kernel low-level debugging port"
 	depends on DEBUG_LL
@@ -930,3 +939,5 @@ endmenu

 config HAS_DEBUG_LL
 	bool
+config HAS_DEBUG_LL_INPUT
+        bool
diff --git a/include/debug_ll.h b/include/debug_ll.h
index b0eb7cd..4272830 100644
--- a/include/debug_ll.h
+++ b/include/debug_ll.h
@@ -38,6 +38,27 @@ static inline void putc_ll(char value)
 	PUTC_LL(value);
 }

+#if defined (CONFIG_DEBUG_LL_INPUT)
+static inline int tstc_ll(void)
+{
+	return TSTC_LL();
+}
+
+static inline int getc_ll(void)
+{
+	return GETC_LL();
+}
+#else
+static inline int tstc_ll(void)
+{
+	return 0;
+}
+static inline int getc_ll(void)
+{
+	return -ENOTSUPP;
+}
+#endif
+
 static inline void puthex_ll(unsigned long value)
 {
 	int i; unsigned char ch;
@@ -71,6 +92,15 @@ static inline void putc_ll(char value)
 {
 }

+static inline int tstc_ll(void)
+{
+	return 0;
+}
+static inline int getc_ll(void)
+{
+	return -ENOTSUPP;
+}
+
 static inline void puthex_ll(unsigned long value)
 {
 }
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:26 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:26 -0700
Subject: [PATCH 09/10] pbl: Implement ctrlc() using getc_ll()
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-9-git-send-email-andrew.smirnov@gmail.com>

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 pbl/console.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/pbl/console.c b/pbl/console.c
index a9859ad..e34633f 100644
--- a/pbl/console.c
+++ b/pbl/console.c
@@ -30,12 +30,19 @@ int pr_print(int level, const char *fmt, ...)

 	return i;
 }
-
+#ifdef CONFIG_DEBUG_LL_INPUT
 int ctrlc(void)
 {
+	if (tstc_ll() && getc_ll() == 3)
+		return 1;
 	return 0;
 }
-
+#else
+int ctrlc(void)
+{
+	return 0;
+}
+#endif
 void console_putc(unsigned int ch, char c)
 {
 	putc_ll(c);
--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:25 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:25 -0700
Subject: [PATCH 08/10] i.MX51: babbage: Add UART RXD pin configuration
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-8-git-send-email-andrew.smirnov@gmail.com>

Add UART RXD pin pinmux configuration to support input in DEBUG_LL
functions.

Also use appropriate pad configuration constant in TXD pin
configuraion.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/boards/freescale-mx51-babbage/lowlevel.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
index 57a324e..09a7a67 100644
--- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
+++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c
@@ -1,5 +1,6 @@
 #include <debug_ll.h>
 #include <mach/clock-imx51_53.h>
+#include <mach/iomux-mx51.h>
 #include <common.h>
 #include <mach/esdctl.h>
 #include <mach/generic.h>
@@ -27,11 +28,14 @@ static inline void setup_uart(void)
 	 * The code below should be more or less a "moral equivalent"
 	 * of:
 	 *	 MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
-	 *
+	 *       MX51_PAD_UART1_TXD__UART1_RXD 0x1c5
 	 * in device tree
 	 */
 	writel(0x00000000, iomuxbase + 0x022c);
-	writel(0x000001c5, iomuxbase + 0x061c);
+	writel(MX51_UART_PAD_CTRL, iomuxbase + 0x061c);
+	writel(0, iomuxbase + 0x0228);
+	writel(0, iomuxbase + 0x09e4);
+	writel(MX51_UART_PAD_CTRL, iomuxbase + 0x0618);

 	imx51_uart_setup_ll();

--
2.1.4


From andrew.smirnov at gmail.com  Wed May 13 19:54:27 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Wed, 13 May 2015 19:54:27 -0700
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>

Add an option to perform DRAM region validation before using it. The
framework allows individual boards to set up a memory validaion hook
that would be called prior to Barebox using that region of memory.

Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/cpu/start.c               | 14 +-----------
 arch/arm/cpu/uncompress.c          | 32 ++++++++++++++++++++++++---
 arch/arm/include/asm/barebox-arm.h | 28 ++++++++++++++++++++++++
 common/Kconfig                     |  8 +++++++
 common/Makefile                    |  2 +-
 include/common.h                   |  1 +
 include/memtest.h                  | 19 ++++++++++++++++
 lib/Makefile                       |  6 ++++++
 pbl/misc.c                         | 44 ++++++++++++++++++++++++++++++++++++++
 9 files changed, 137 insertions(+), 17 deletions(-)

diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 304ed0c..ee7eb00 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -105,19 +105,7 @@ static noinline __noreturn void __start(unsigned long membase,
 	else
 		malloc_end = (unsigned long)_text;

-	/*
-	 * Maximum malloc space is the Kconfig value if given
-	 * or 1GB.
-	 */
-	if (MALLOC_SIZE > 0) {
-		malloc_start = malloc_end - MALLOC_SIZE;
-		if (malloc_start < membase)
-			malloc_start = membase;
-	} else {
-		malloc_start = malloc_end - (malloc_end - membase) / 2;
-		if (malloc_end - malloc_start > SZ_1G)
-			malloc_start = malloc_end - SZ_1G;
-	}
+	malloc_start = arm_get_malloc_start(membase, malloc_end);

 	pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n",
 			malloc_start, malloc_end - malloc_start);
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index b0b7c6d..853d2a3 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -20,6 +20,7 @@
 #define pr_fmt(fmt) "uncompress.c: " fmt

 #include <common.h>
+#include <memtest.h>
 #include <init.h>
 #include <linux/sizes.h>
 #include <pbl.h>
@@ -47,6 +48,7 @@ static void __noreturn noinline uncompress_start_payload(unsigned long membase,
 	uint32_t pg_len;
 	void __noreturn (*barebox)(unsigned long, unsigned long, void *);
 	uint32_t endmem = membase + memsize;
+	unsigned long malloc_start, malloc_end;
 	unsigned long barebox_base;
 	uint32_t *image_end;
 	void *pg_start;
@@ -64,10 +66,14 @@ static void __noreturn noinline uncompress_start_payload(unsigned long membase,
 		 * to the current address. Otherwise it may be a readonly location.
 		 * Copy and relocate to the start of the memory in this case.
 		 */
-		if (pc > membase && pc < membase + memsize)
+		if (pc > membase && pc < membase + memsize) {
 			relocate_to_current_adr();
-		else
+		} else {
+			validate_memory_range("validating pbl relocation area",
+					      membase,
+					      membase + arm_barebox_image_size() - 1);
 			relocate_to_adr(membase);
+		}
 	}

 	if (IS_ENABLED(CONFIG_RELOCATABLE))
@@ -77,6 +83,21 @@ static void __noreturn noinline uncompress_start_payload(unsigned long membase,

 	setup_c();

+	validate_memory_range("validating barebox decompression area",
+			      barebox_base, endmem - 1);
+
+	/*
+	  We know that when we give control to __start function of
+	  uncompressed image _text would be within the boundaries of
+	  (membase, membase + memsize) so the malloc_end variable
+	  would be set to _text
+	 */
+	malloc_end   = barebox_base;
+	malloc_start = arm_get_malloc_start(membase, malloc_end);
+
+	validate_memory_range("validating malloc area",
+			      malloc_start, malloc_end - 1);
+
 	pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);

 	if (IS_ENABLED(CONFIG_MMU_EARLY)) {
@@ -122,7 +143,12 @@ static void __noreturn noinline uncompress_start_payload(unsigned long membase,
 void __naked __noreturn barebox_arm_entry(unsigned long membase,
 		unsigned long memsize, void *boarddata)
 {
-	arm_setup_stack(membase + memsize - 16);
+	unsigned long stack_end = membase + memsize - 16;
+
+	validate_memory_range("validating stack area",
+			      membase + memsize - STACK_SIZE, stack_end);
+
+	arm_setup_stack(stack_end);

 	uncompress_start_payload(membase, memsize, boarddata);
 }
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index dbc8aaa..f577df7 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -83,6 +83,34 @@ static inline unsigned long arm_barebox_image_place(unsigned long endmem)
 	return endmem;
 }

+static inline unsigned long arm_barebox_image_size(void)
+{
+	/* We assume that 1G is significantly more that Barebox will
+	 * ever try to reserve */
+	return SZ_1G - arm_barebox_image_place(SZ_1G);
+}
+
+static inline unsigned long arm_get_malloc_start(unsigned long membase,
+						 unsigned long malloc_end)
+{
+	unsigned long malloc_start;
+	/*
+	 * Maximum malloc space is the Kconfig value if given
+	 * or 1GB.
+	 */
+	if (MALLOC_SIZE > 0) {
+		malloc_start = malloc_end - MALLOC_SIZE;
+		if (malloc_start < membase)
+			malloc_start = membase;
+	} else {
+		malloc_start = malloc_end - (malloc_end - membase) / 2;
+		if (malloc_end - malloc_start > SZ_1G)
+			malloc_start = malloc_end - SZ_1G;
+	}
+
+	return malloc_start;
+}
+
 #define ENTRY_FUNCTION(name, arg0, arg1, arg2)				\
 	static void __##name(uint32_t, uint32_t, uint32_t);		\
 									\
diff --git a/common/Kconfig b/common/Kconfig
index 4032dcd..5d40dee 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -246,6 +246,14 @@ config MALLOC_SIZE
 	prompt "malloc area size"
 endmenu

+config MEMORY_VALIDATION
+       bool "Validate regions of memory prior to using them"
+       select PBL_CONSOLE
+       help
+         select this option if you want Barebox to perform memory test
+         on regions of DRAM memory that it is about to use for the
+         first time
+
 config BROKEN
 	bool

diff --git a/common/Makefile b/common/Makefile
index 2738238..a634f0d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_BLSPEC)		+= blspec.o
 obj-$(CONFIG_BOOTM)		+= bootm.o
 obj-$(CONFIG_CMD_LOADS)		+= s_record.o
 obj-$(CONFIG_CMD_MEMTEST)	+= memtest.o
+pbl-$(CONFIG_MEMORY_VALIDATION)	+= memtest.o
 obj-$(CONFIG_COMMAND_SUPPORT)	+= command.o
 obj-$(CONFIG_CONSOLE_FULL)	+= console.o
 obj-$(CONFIG_CONSOLE_SIMPLE)	+= console_simple.o
@@ -90,4 +91,3 @@ include/generated/compile.h: FORCE
 	@$($(quiet)chk_compile.h)
 	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
 	"$(UTS_MACHINE)" "$(CC) $(KBUILD_CFLAGS)"
-
diff --git a/include/common.h b/include/common.h
index 86e755d..021637a 100644
--- a/include/common.h
+++ b/include/common.h
@@ -209,6 +209,7 @@ static inline void *get_true_address(const void *ptr)
 	return (void *)address;
 }
 #else
+
 static inline void *get_true_address(const void *ptr)
 {
 	return (void *)ptr;
diff --git a/include/memtest.h b/include/memtest.h
index a337be8..4a426c3 100644
--- a/include/memtest.h
+++ b/include/memtest.h
@@ -8,7 +8,26 @@ struct mem_test_resource {
 	struct list_head list;
 };

+typedef int (*mem_test_handler_t)(resource_size_t _start, resource_size_t _end);
+
 int mem_test(resource_size_t _start,
 		resource_size_t _end, int bus_only);

+#ifdef CONFIG_MEMORY_VALIDATION
+void validate_memory_range(const char *message,
+			   resource_size_t start,
+			   resource_size_t end);
+void set_memory_validation_handler(mem_test_handler_t handler);
+#else
+static inline void validate_memory_range(const char *message,
+					 resource_size_t start,
+					 resource_size_t end)
+{
+}
+
+static inline void set_memory_validation_handler(mem_test_handler_t handler)
+{
+}
+#endif
+
 #endif /* __MEMTEST_H */
diff --git a/lib/Makefile b/lib/Makefile
index 6a3e9fd..3da2c27 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -35,6 +35,12 @@ obj-y			+= random.o
 obj-y			+= lzo/
 obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
 obj-y			+= show_progress.o
+pbl-$(CONFIG_MEMORY_VALIDATION) += show_progress.o
+# The code is going to be used before MMU is set up and unaligned
+# access will cause an exception(there is an unaligned access to the
+# contenst of 'spinchr' in show_progress())
+CFLAGS_pbl-show_progress.o = -mno-unaligned-access
+
 obj-$(CONFIG_LZO_DECOMPRESS)		+= decompress_unlzo.o
 obj-$(CONFIG_LZ4_DECOMPRESS) += decompress_unlz4.o
 obj-$(CONFIG_PROCESS_ESCAPE_SEQUENCE)	+= process_escape_sequence.o
diff --git a/pbl/misc.c b/pbl/misc.c
index 3d5a881..2b446f5 100644
--- a/pbl/misc.c
+++ b/pbl/misc.c
@@ -1,8 +1,10 @@
 #include <common.h>
 #include <init.h>
+#include <memtest.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
+#include <debug_ll.h>

 void __noreturn __hang(void)
 {
@@ -26,6 +28,48 @@ void set_hang_handler(hang_handler_t handler)
 	*__hang_handler_p = handler;
 }

+#ifdef CONFIG_MEMORY_VALIDATION
+
+static mem_test_handler_t mem_test_handler = NULL;
+
+void validate_memory_range(const char *message,
+			   resource_size_t start,
+			   resource_size_t end)
+{
+	int ret;
+	mem_test_handler_t *__mem_test_handler_p = get_true_address(&mem_test_handler);
+	mem_test_handler_t __mem_test_handler    = get_true_address(*__mem_test_handler_p);
+
+	if (__mem_test_handler) {
+		message = get_true_address(message);
+
+		puts_ll(message);
+		putc_ll(' ');
+		putc_ll('[');
+		puthex_ll(start);
+		putc_ll(' ');
+		putc_ll('-');
+		putc_ll(' ');
+		puthex_ll(end);
+		putc_ll(']');
+		putc_ll('\r');
+		putc_ll('\n');
+
+		ret = __mem_test_handler(start, end);
+
+		if (ret < 0)
+			hang();
+	}
+}
+
+void set_memory_validation_handler(mem_test_handler_t handler)
+{
+	mem_test_handler_t *__mem_test_handler_p = get_true_address(&mem_test_handler);
+
+	*__mem_test_handler_p = handler;
+}
+#endif
+
 void __noreturn panic(const char *fmt, ...)
 {
 	while(1);
--
2.1.4


From s.hauer at pengutronix.de  Thu May 14 03:21:22 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 14 May 2015 12:21:22 +0200
Subject: [PATCH 3/4] mtd: Fix function prototype
In-Reply-To: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
References: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1431598883-25668-3-git-send-email-s.hauer@pengutronix.de>

mtd_op_protect must return int instead of size_t.

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

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 1755e76..681dc93 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -191,7 +191,7 @@ static int mtd_op_erase(struct cdev *cdev, size_t count, loff_t offset)
 	return 0;
 }
 
-static ssize_t mtd_op_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
+static int mtd_op_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
 {
 	struct mtd_info *mtd = cdev->priv;
 
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 14 03:21:20 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 14 May 2015 12:21:20 +0200
Subject: [PATCH 1/4] i2c: Use correct format specifier
Message-ID: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>

'count' is of type u16, not size_t.

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

diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 7a6bde0..5d0fa06 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -183,7 +183,7 @@ int i2c_read_reg(struct i2c_client *client, u32 addr, u8 *buf, u16 count)
 	msg->len = i;
 
 	status = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
-	dev_dbg(&client->dev, "%s: %zu@%u --> %d\n", __func__,
+	dev_dbg(&client->dev, "%s: %u@%u --> %d\n", __func__,
 		count, addr, status);
 
 	if (status == ARRAY_SIZE(msg))
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 14 03:21:23 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 14 May 2015 12:21:23 +0200
Subject: [PATCH 4/4] mtd: nand: Fix format specifier
In-Reply-To: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
References: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1431598883-25668-4-git-send-email-s.hauer@pengutronix.de>

'count' is of type size_t, so use %zx.

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

diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index 539c685..8e4600a 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -54,7 +54,7 @@ static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
 	size_t retlen;
 	int ret, bytes = 0, now;
 
-	debug("%s offset: 0x%08llx (raw: 0x%08llx) count: 0x%08x\n",
+	debug("%s offset: 0x%08llx (raw: 0x%08llx) count: 0x%08zx\n",
 			__func__, offset, bb->offset, count);
 
 	while (count) {
@@ -132,7 +132,7 @@ static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
 	struct nand_bb *bb = cdev->priv;
 	int bytes = count, now, wroffs, ret;
 
-	debug("%s offset: 0x%08llx (raw: 0x%08llx) count: 0x%08x\n",
+	debug("%s offset: 0x%08llx (raw: 0x%08llx) count: 0x%08zx\n",
 			__func__, offset, bb->offset, count);
 
 	while (count) {
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 14 03:21:21 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 14 May 2015 12:21:21 +0200
Subject: [PATCH 2/4] mem: Fix memcpy_sz variable types
In-Reply-To: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
References: <1431598883-25668-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1431598883-25668-2-git-send-email-s.hauer@pengutronix.de>

- Drop usage of 'ulong', use unsigned long
- remove unnecessary intermediate casting to unsigned long
- Use proper u8/u16/u32 types. Fixes 64bit systems on which ulong is 64bit

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 fs/fs.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 779f264..a056d83 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1564,14 +1564,11 @@ out:
 }
 EXPORT_SYMBOL(rmdir);
 
-static void memcpy_sz(void *_dst, const void *_src, ulong count, ulong rwsize)
+static void memcpy_sz(void *dst, const void *src, size_t count, int rwsize)
 {
-	ulong dst = (ulong)_dst;
-	ulong src = (ulong)_src;
-
 	/* no rwsize specification given. Do whatever memcpy likes best */
 	if (!rwsize) {
-		memcpy(_dst, _src, count);
+		memcpy(dst, src, count);
 		return;
 	}
 
@@ -1582,13 +1579,13 @@ static void memcpy_sz(void *_dst, const void *_src, ulong count, ulong rwsize)
 	while (count-- > 0) {
 		switch (rwsize) {
 		case 1:
-			*((u_char *)dst) = *((u_char *)src);
+			*((u8 *)dst) = *((u8 *)src);
 			break;
 		case 2:
-			*((ushort *)dst) = *((ushort *)src);
+			*((u16 *)dst) = *((u16 *)src);
 			break;
 		case 4:
-			*((ulong  *)dst) = *((ulong  *)src);
+			*((u32  *)dst) = *((u32  *)src);
 			break;
 		}
 		dst += rwsize;
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 14 22:05:49 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 May 2015 07:05:49 +0200
Subject: [PATCH 5/7] state: backend: support phandle and of_path references
In-Reply-To: <1431511952-32124-5-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
 <1431511952-32124-5-git-send-email-mkl@pengutronix.de>
Message-ID: <20150515050549.GF6325@pengutronix.de>

On Wed, May 13, 2015 at 12:12:30PM +0200, Marc Kleine-Budde wrote:
> This patch improves the backend property, it can be either a phandle or a
> of_path. During probe() of the state driver the backend property is
> dereferenced and the resulting of_path is saved in the state context. In a
> later patch it will be used to generate a phandle reference to the backend
> during DT fixup.
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  common/state.c       |  9 ++++---
>  drivers/misc/state.c | 70 ++++++++++++++++++++++++++++++++++++++++++----------
>  include/state.h      |  7 +++---
>  3 files changed, 67 insertions(+), 19 deletions(-)
> 
> diff --git a/common/state.c b/common/state.c
> index 744a6f8250c4..d6060bb7dff4 100644
> --- a/common/state.c
> +++ b/common/state.c
> @@ -54,6 +54,7 @@ struct state_backend {
>  	int (*load)(struct state_backend *backend, struct state *state);
>  	int (*save)(struct state_backend *backend, struct state *state);
>  	const char *name;
> +	const char *of_path;
>  	const char *path;
>  };
>  
> @@ -903,7 +904,7 @@ out:
>   * @state	The state instance to work on
>   * @path	The path where the state will be stored to
>   */
> -int state_backend_dtb_file(struct state *state, const char *path)
> +int state_backend_dtb_file(struct state *state, const char *of_path, const char *path)
>  {
>  	struct state_backend_dtb *backend_dtb;
>  	struct state_backend *backend;
> @@ -918,6 +919,7 @@ int state_backend_dtb_file(struct state *state, const char *path)
>  
>  	backend->load = state_backend_dtb_load;
>  	backend->save = state_backend_dtb_save;
> +	backend->of_path = xstrdup(of_path);
>  	backend->path = xstrdup(path);
>  	backend->name = "dtb";
>  
> @@ -1133,8 +1135,8 @@ out_free:
>   * device @size may be 0. The two copies are spread to different
>   * eraseblocks if approriate for this device.
>   */
> -int state_backend_raw_file(struct state *state, const char *path, off_t offset,
> -		size_t size)
> +int state_backend_raw_file(struct state *state, const char *of_path,
> +		const char *path, off_t offset, size_t size)
>  {
>  	struct state_backend_raw *backend_raw;
>  	struct state_backend *backend;
> @@ -1159,6 +1161,7 @@ int state_backend_raw_file(struct state *state, const char *path, off_t offset,
>  
>  	backend->load = state_backend_raw_load;
>  	backend->save = state_backend_raw_save;
> +	backend->of_path = xstrdup(of_path);
>  	backend->path = xstrdup(path);
>  	backend->name = "raw";
>  
> diff --git a/drivers/misc/state.c b/drivers/misc/state.c
> index 3b07bb93d725..9e8a40255348 100644
> --- a/drivers/misc/state.c
> +++ b/drivers/misc/state.c
> @@ -24,10 +24,12 @@
>  static int state_probe(struct device_d *dev)
>  {
>  	struct device_node *np = dev->device_node;
> +	struct device_node *partition_node;
>  	struct state *state;
>  	const char *alias;
>  	const char *backend_type = NULL;
>  	int ret;
> +	const char *of_path;
>  	char *path;
>  
>  	if (!np)
> @@ -41,28 +43,70 @@ static int state_probe(struct device_d *dev)
>  	if (IS_ERR(state))
>  		return PTR_ERR(state);
>  
> -	ret = of_find_path(np, "backend", &path, 0);
> -	if (ret)
> -		return ret;
> +	of_path = of_get_property(np, "backend", NULL);
> +	if (!of_path) {
> +		ret = -ENODEV;
> +		goto out_release;
> +	}
> +
> +	/* guess if of_path is a path, not a phandle */
> +	if (of_path[0] == '/') {

Since this also matches to the 47th phandle in the device tree I made
this:

	if (of_path[0] == '/' && len > 1)

And applied up to 6/7

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  Thu May 14 22:12:02 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 May 2015 07:12:02 +0200
Subject: [PATCH] ARM: am33xx: Fix SCRM compatible string to match new DT
 compatible string
In-Reply-To: <1431512154-25432-1-git-send-email-w.egorov@phytec.de>
References: <1431512154-25432-1-git-send-email-w.egorov@phytec.de>
Message-ID: <20150515051202.GG6325@pengutronix.de>

Hi Wadim,

On Wed, May 13, 2015 at 12:15:54PM +0200, Wadim Egorov wrote:
> Commit 461f8cfc7ea788428240271818363333ceff5c4c renamed the SCRM compatible
> string in am33xx.dtsi and breaks all am335x based boards.
> 
> Rename the SCRM compatible string.
> 
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>

Applied to master, thanks. Please mention next time that this should
be applied to master. I realized this time but I might miss it next
time.

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  Thu May 14 22:13:08 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 May 2015 07:13:08 +0200
Subject: [PATCH 0/2] Socfpga: Sequencer updates
In-Reply-To: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1431521784-27413-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <20150515051308.GH6325@pengutronix.de>

On Wed, May 13, 2015 at 02:56:22PM +0200, Steffen Trumtrar wrote:
> Hi!
> 
> This updates the socfpga_get_sequencer script to handle the new
> Quartus 15.0 generated sources.
> Luckily the real changes in the code are very minor, so the patch
> mostly just removes TCL/ALTERA macros that are useless for barebox.
> 
> (Boot)Tested on Sockit/Socrates.

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  Thu May 14 22:25:21 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 May 2015 07:25:21 +0200
Subject: [PATCH 06/10] common: pbl: Allow boards to override hang()
In-Reply-To: <1431572067-4038-6-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-6-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150515052521.GI6325@pengutronix.de>

Hi Andrey,

On Wed, May 13, 2015 at 07:54:23PM -0700, Andrey Smirnov wrote:
> Add provisions such that board code can re-define the behaviour of
> hang() to implement a behaviour better suited for a particular
> hardware platform.

I'm generally fine with being able to overwrite hang(), but the ARM
specific changes here should be an extra patch with an explanation why
this change is necessary. I assume you want to make hang() usable
for early debugging in the PBL when the code is not running at the
address it's linked at. But that's only an assumption.

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  Thu May 14 22:33:25 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 15 May 2015 07:33:25 +0200
Subject: [PATCH 01/10] common/memtest.c: Fix incorrect array boundary check
In-Reply-To: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150515053325.GJ6325@pengutronix.de>

On Wed, May 13, 2015 at 07:54:18PM -0700, Andrey Smirnov wrote:
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> ---
>  common/memtest.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)


I have applied the memtest patches for now. I'll come to the PBL console
input patches next week when I find some time. I think I haven't made my
mind yet whether we really want to have input support in PBL and where
this all leads to. We use functions which were originally meant for
debugging to do regular output with PBL console support. Maybe we should
clean this up and introduce some real early console backend rather than
abusing the debugging functions before we add more features to it.

Sascha


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


From mkl at pengutronix.de  Thu May 14 23:12:50 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 15 May 2015 08:12:50 +0200
Subject: [PATCH 5/7] state: backend: support phandle and of_path references
In-Reply-To: <20150515050549.GF6325@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
 <1431511952-32124-5-git-send-email-mkl@pengutronix.de>
 <20150515050549.GF6325@pengutronix.de>
Message-ID: <55558E62.9090902@pengutronix.de>

On 05/15/2015 07:05 AM, Sascha Hauer wrote:
> On Wed, May 13, 2015 at 12:12:30PM +0200, Marc Kleine-Budde wrote:
>> This patch improves the backend property, it can be either a phandle or a
>> of_path. During probe() of the state driver the backend property is
>> dereferenced and the resulting of_path is saved in the state context. In a
>> later patch it will be used to generate a phandle reference to the backend
>> during DT fixup.
>>
>> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
>> ---
>>  common/state.c       |  9 ++++---
>>  drivers/misc/state.c | 70 ++++++++++++++++++++++++++++++++++++++++++----------
>>  include/state.h      |  7 +++---
>>  3 files changed, 67 insertions(+), 19 deletions(-)
>>
>> diff --git a/common/state.c b/common/state.c
>> index 744a6f8250c4..d6060bb7dff4 100644
>> --- a/common/state.c
>> +++ b/common/state.c
>> @@ -54,6 +54,7 @@ struct state_backend {
>>  	int (*load)(struct state_backend *backend, struct state *state);
>>  	int (*save)(struct state_backend *backend, struct state *state);
>>  	const char *name;
>> +	const char *of_path;
>>  	const char *path;
>>  };
>>  
>> @@ -903,7 +904,7 @@ out:
>>   * @state	The state instance to work on
>>   * @path	The path where the state will be stored to
>>   */
>> -int state_backend_dtb_file(struct state *state, const char *path)
>> +int state_backend_dtb_file(struct state *state, const char *of_path, const char *path)
>>  {
>>  	struct state_backend_dtb *backend_dtb;
>>  	struct state_backend *backend;
>> @@ -918,6 +919,7 @@ int state_backend_dtb_file(struct state *state, const char *path)
>>  
>>  	backend->load = state_backend_dtb_load;
>>  	backend->save = state_backend_dtb_save;
>> +	backend->of_path = xstrdup(of_path);
>>  	backend->path = xstrdup(path);
>>  	backend->name = "dtb";
>>  
>> @@ -1133,8 +1135,8 @@ out_free:
>>   * device @size may be 0. The two copies are spread to different
>>   * eraseblocks if approriate for this device.
>>   */
>> -int state_backend_raw_file(struct state *state, const char *path, off_t offset,
>> -		size_t size)
>> +int state_backend_raw_file(struct state *state, const char *of_path,
>> +		const char *path, off_t offset, size_t size)
>>  {
>>  	struct state_backend_raw *backend_raw;
>>  	struct state_backend *backend;
>> @@ -1159,6 +1161,7 @@ int state_backend_raw_file(struct state *state, const char *path, off_t offset,
>>  
>>  	backend->load = state_backend_raw_load;
>>  	backend->save = state_backend_raw_save;
>> +	backend->of_path = xstrdup(of_path);
>>  	backend->path = xstrdup(path);
>>  	backend->name = "raw";
>>  
>> diff --git a/drivers/misc/state.c b/drivers/misc/state.c
>> index 3b07bb93d725..9e8a40255348 100644
>> --- a/drivers/misc/state.c
>> +++ b/drivers/misc/state.c
>> @@ -24,10 +24,12 @@
>>  static int state_probe(struct device_d *dev)
>>  {
>>  	struct device_node *np = dev->device_node;
>> +	struct device_node *partition_node;
>>  	struct state *state;
>>  	const char *alias;
>>  	const char *backend_type = NULL;
>>  	int ret;
>> +	const char *of_path;
>>  	char *path;
>>  
>>  	if (!np)
>> @@ -41,28 +43,70 @@ static int state_probe(struct device_d *dev)
>>  	if (IS_ERR(state))
>>  		return PTR_ERR(state);
>>  
>> -	ret = of_find_path(np, "backend", &path, 0);
>> -	if (ret)
>> -		return ret;
>> +	of_path = of_get_property(np, "backend", NULL);
>> +	if (!of_path) {
>> +		ret = -ENODEV;
>> +		goto out_release;
>> +	}
>> +
>> +	/* guess if of_path is a path, not a phandle */
>> +	if (of_path[0] == '/') {
> 
> Since this also matches to the 47th phandle in the device tree I made
> this:
> 
> 	if (of_path[0] == '/' && len > 1)

Makes sense.

> And applied up to 6/7

Thanks,
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150515/81ce18d4/attachment.sig>

From u.kleine-koenig at pengutronix.de  Fri May 15 02:28:58 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Fri, 15 May 2015 11:28:58 +0200
Subject: [PATCH 6/7] state: add fixup to copy state from barebox to
 kernel device tree
In-Reply-To: <1431511952-32124-6-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-1-git-send-email-mkl@pengutronix.de>
 <1431511952-32124-6-git-send-email-mkl@pengutronix.de>
Message-ID: <20150515092858.GR28888@pengutronix.de>

On Wed, May 13, 2015 at 12:12:31PM +0200, Marc Kleine-Budde wrote:
> This patch registers a DT fixup, that copies the state nodes from the active
> to the kernel DT. The backend reference will be a phandles.
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  common/state.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 92 insertions(+)
> 
> diff --git a/common/state.c b/common/state.c
> index d6060bb7dff4..ca691d2827fa 100644
> --- a/common/state.c
> +++ b/common/state.c
> @@ -676,6 +676,93 @@ static int state_from_node(struct state *state, struct device_node *node,
>  	return ret;
>  }
>  
> +static int of_state_fixup(struct device_node *root, void *ctx)
> +{
> +	struct state *state = ctx;
> +	const char *compatible = "barebox,state";
> +	struct device_node *new_node, *node, *parent, *backend_node;
> +	struct property *p;
> +	int ret;
> +	phandle phandle;
> +
> +	node = of_find_node_by_path_from(root, state->root->full_name);
> +	if (node) {
> +		/* replace existing node - it will be deleted later */
> +		parent = node->parent;
> +	} else {
> +		char *of_path, *c;
> +
> +		/* look for parent, remove last '/' from path */
> +		of_path = xstrdup(state->root->full_name);
> +		c = strrchr(of_path, '/');
> +		if (!c)
> +			return -ENODEV;
> +		*c = '0';
> +		parent = of_find_node_by_path(of_path);
> +		if (!parent)
> +			parent = root;
> +
> +		free(of_path);
> +	}
> +
> +	/* serialize variable definitions */
> +	new_node = state_to_node(state, parent, STATE_CONVERT_FIXUP);
> +	if (IS_ERR(new_node))
> +		return PTR_ERR(new_node);
> +
> +	/* compatible */
> +	p = of_new_property(new_node, "compatible", compatible,
> +			    strlen(compatible) + 1);
> +	if (!p) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* backend-type */
> +	if (!state->backend) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +
> +	p = of_new_property(new_node, "backend-type", state->backend->name,
> +			    strlen(state->backend->name) + 1);
> +	if (!p) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* backend phandle */
> +	backend_node = of_find_node_by_path_from(root, state->backend->of_path);
> +	if (!backend_node) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +
> +	phandle = of_node_create_phandle(backend_node);
> +	ret = of_property_write_u32(new_node, "backend", phandle);
> +	if (ret)
> +		goto out;
> +
> +	/* address-cells + size-cells */
> +	ret = of_property_write_u32(root, "#address-cells", 1);
> +	if (ret)
> +		goto out;
> +
> +	ret = of_property_write_u32(root, "#size-cells", 1);
> +	if (ret)
> +		goto out;
> +
> +	/* delete existing node */
> +	if (node)
> +		of_delete_node(node);
> +
> +	return 0;
> +
> + out:
> +	of_delete_node(new_node);
> +	return ret;
> +}
> +
>  /*
>   * state_new_from_node - create a new state instance from a device_node
>   *
> @@ -697,6 +784,11 @@ struct state *state_new_from_node(const char *name, struct device_node *node)
>  		return ERR_PTR(ret);
>  	}
>  
> +	ret = of_register_fixup(of_state_fixup, state);
> +	if (ret) {
> +		state_release(state);
> +		return ERR_PTR(ret);
> +	}
This is broken. state_new_from_node is called in state_probe:

	static int state_probe(struct device_d *dev)
	{
		...
		state = state_new_from_node(alias, np);
		...
		ret = of_find_path(np, "backend", &path, 0);
		if (ret)
			return ret;
		...

So if there is an error with the backend (or something else later that
makes the state invalid) the fixup is still registered. So when the
fixup is actually called state might be invalid resulting in
of_state_fixup using possibly overwritten memory.

Best regards
Uwe

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


From yamada.masahiro at socionext.com  Fri May 15 05:58:46 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Fri, 15 May 2015 21:58:46 +0900
Subject: [PATCH] include: introcude include/linux/io.h as a wrapper of asm/io.h
Message-ID: <1431694726-3761-1-git-send-email-yamada.masahiro@socionext.com>

In the latest Linux coding style, <linux/io.h> should be included
rather than <asm/io.h>.  To follow this standard also in barebox,
add include/linux/io.h.  Currently, it just includes <asm/io.h>.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 include/linux/io.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 include/linux/io.h

diff --git a/include/linux/io.h b/include/linux/io.h
new file mode 100644
index 0000000..548b245
--- /dev/null
+++ b/include/linux/io.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2006 PathScale, Inc.  All Rights Reserved.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LINUX_IO_H
+#define _LINUX_IO_H
+
+#include <asm/io.h>
+
+#endif /* _LINUX_IO_H */
-- 
1.9.1



From yamada.masahiro at socionext.com  Fri May 15 06:02:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Fri, 15 May 2015 22:02:47 +0900
Subject: [PATCH v2] include: introduce include/linux/io.h as a wrapper of
 asm/io.h
Message-ID: <1431694967-2416-1-git-send-email-yamada.masahiro@socionext.com>

In the latest Linux coding style, <linux/io.h> should be included
rather than <asm/io.h>.  To follow this standard also in barebox,
add include/linux/io.h.  Currently, it just includes <asm/io.h>.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

Changes in v2:
  - Fix a type s/introcude/introduce/

 include/linux/io.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 include/linux/io.h

diff --git a/include/linux/io.h b/include/linux/io.h
new file mode 100644
index 0000000..548b245
--- /dev/null
+++ b/include/linux/io.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2006 PathScale, Inc.  All Rights Reserved.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LINUX_IO_H
+#define _LINUX_IO_H
+
+#include <asm/io.h>
+
+#endif /* _LINUX_IO_H */
-- 
1.9.1



From u.kleine-koenig at pengutronix.de  Sat May 16 03:12:29 2015
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Sat, 16 May 2015 12:12:29 +0200
Subject: [PATCH] of: add a function to remove an of_fixup
Message-ID: <1431771149-27265-1-git-send-email-u.kleine-koenig@pengutronix.de>

This function is needed when a device that already registered a fixup in
the probe routine fails later to probe completely. Without unregistering
the fixup the function might later be called with invalid data.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 common/oftree.c | 19 +++++++++++++++++++
 include/of.h    |  1 +
 2 files changed, 20 insertions(+)

diff --git a/common/oftree.c b/common/oftree.c
index 50fc95b58820..f75d7b4bfe5d 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -160,6 +160,25 @@ int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context)
 }
 
 /*
+ * Remove a previously registered fixup. Only the first (if any) is removed.
+ * Returns 0 if a match was found (and removed), -ENOENT otherwise.
+ */
+int of_unregister_fixup(int (*fixup)(struct device_node *, void *),
+			void *context)
+{
+	struct of_fixup *of_fixup;
+
+	list_for_each_entry(of_fixup, &of_fixup_list, list) {
+		if (of_fixup->fixup == fixup && of_fixup->context == context) {
+			list_del(&of_fixup->list);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/*
  * Apply registered fixups for the given fdt. The fdt must have
  * enough free space to apply the fixups.
  */
diff --git a/include/of.h b/include/of.h
index e73cd7a446b7..c02f5f49aba4 100644
--- a/include/of.h
+++ b/include/of.h
@@ -243,6 +243,7 @@ struct device_d *of_find_device_by_node_path(const char *path);
 #define OF_FIND_PATH_FLAGS_BB 1		/* return .bb device if available */
 int of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags);
 int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context);
+int of_unregister_fixup(int (*fixup)(struct device_node *, void *), void *context);
 struct device_node *of_find_node_by_alias(struct device_node *root,
 		const char *alias);
 struct device_node *of_find_node_by_path_or_alias(struct device_node *root,
-- 
2.1.4



From u.kleine-koenig at pengutronix.de  Sat May 16 03:15:27 2015
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Sat, 16 May 2015 12:15:27 +0200
Subject: [PATCH] fixup! state: add fixup to copy state from barebox to kernel
 device tree
In-Reply-To: <1431511952-32124-6-git-send-email-mkl@pengutronix.de>
References: <1431511952-32124-6-git-send-email-mkl@pengutronix.de>
Message-ID: <1431771327-27442-1-git-send-email-u.kleine-koenig@pengutronix.de>

of_unregister_fixup must also be called in the release function.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
This depends on the patch "of: add a function to remove an of_fixup" I
just sent to the list
---
 common/state.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/common/state.c b/common/state.c
index fb13ae272db9..bd9c5a712aac 100644
--- a/common/state.c
+++ b/common/state.c
@@ -435,13 +435,6 @@ static struct state *state_new(const char *name)
 	return state;
 }
 
-void state_release(struct state *state)
-{
-	list_del(&state->list);
-	unregister_device(&state->dev);
-	free(state);
-}
-
 static struct state_variable *state_find_var(struct state *state,
 					     const char *name)
 {
@@ -760,6 +753,14 @@ static int of_state_fixup(struct device_node *root, void *ctx)
 	return ret;
 }
 
+void state_release(struct state *state)
+{
+	of_unregister_fixup(of_state_fixup, state);
+	list_del(&state->list);
+	unregister_device(&state->dev);
+	free(state);
+}
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
-- 
2.1.4



From antonynpavlov at gmail.com  Sun May 17 08:47:04 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Sun, 17 May 2015 18:47:04 +0300
Subject: [PATCH v2] include: introduce include/linux/io.h as a wrapper
 of asm/io.h
In-Reply-To: <1431694967-2416-1-git-send-email-yamada.masahiro@socionext.com>
References: <1431694967-2416-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150517184704.9b64228117f4a3addf0f4f12@gmail.com>

On Fri, 15 May 2015 22:02:47 +0900
Masahiro Yamada <yamada.masahiro at socionext.com> wrote:

> In the latest Linux coding style, <linux/io.h> should be included
> rather than <asm/io.h>.  To follow this standard also in barebox,
> add include/linux/io.h.  Currently, it just includes <asm/io.h>.

Hmmm. Barebox already has include/io.h for the same purpose.
And include/io.h is actively used:

~/barebox.git$ git grep "include <io.h>" | wc -l
474



> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> 
> Changes in v2:
>   - Fix a type s/introcude/introduce/
> 
>  include/linux/io.h | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>  create mode 100644 include/linux/io.h
> 
> diff --git a/include/linux/io.h b/include/linux/io.h
> new file mode 100644
> index 0000000..548b245
> --- /dev/null
> +++ b/include/linux/io.h
> @@ -0,0 +1,23 @@
> +/*
> + * Copyright 2006 PathScale, Inc.  All Rights Reserved.
> + *
> + * This file is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
> + */
> +
> +#ifndef _LINUX_IO_H
> +#define _LINUX_IO_H
> +
> +#include <asm/io.h>
> +
> +#endif /* _LINUX_IO_H */
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
--?
Best regards,
? Antony Pavlov


From yamada.masahiro at socionext.com  Sun May 17 18:48:30 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 18 May 2015 10:48:30 +0900
Subject: [PATCH v2] include: introduce include/linux/io.h as a wrapper of
 asm/io.h
In-Reply-To: <20150517184704.9b64228117f4a3addf0f4f12@gmail.com>
References: <1431694967-2416-1-git-send-email-yamada.masahiro@socionext.com>
 <20150517184704.9b64228117f4a3addf0f4f12@gmail.com>
Message-ID: <CAK7LNATTasdDYvzHxu=F8Jcmgh8v3nAQOvrJsrmN0moDDLh6Gw@mail.gmail.com>

2015-05-18 0:47 GMT+09:00 Antony Pavlov <antonynpavlov at gmail.com>:
> On Fri, 15 May 2015 22:02:47 +0900
> Masahiro Yamada <yamada.masahiro at socionext.com> wrote:
>
>> In the latest Linux coding style, <linux/io.h> should be included
>> rather than <asm/io.h>.  To follow this standard also in barebox,
>> add include/linux/io.h.  Currently, it just includes <asm/io.h>.
>
> Hmmm. Barebox already has include/io.h for the same purpose.
> And include/io.h is actively used:
>
> ~/barebox.git$ git grep "include <io.h>" | wc -l
> 474
>

We can replace all of them with sed easily.

Moreover, cpu_read{b,w,l} and cpu_write{b,w,l} turned out unnecessary after all.
Most of C sources use __raw_*.



-- 
Best Regards
Masahiro Yamada


From s.hauer at pengutronix.de  Sun May 17 23:07:26 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 18 May 2015 08:07:26 +0200
Subject: [PATCH] fixup! state: add fixup to copy state from barebox to
 kernel device tree
In-Reply-To: <1431771327-27442-1-git-send-email-u.kleine-koenig@pengutronix.de>
References: <1431511952-32124-6-git-send-email-mkl@pengutronix.de>
 <1431771327-27442-1-git-send-email-u.kleine-koenig@pengutronix.de>
Message-ID: <20150518060726.GM6325@pengutronix.de>

On Sat, May 16, 2015 at 12:15:27PM +0200, Uwe Kleine-K?nig wrote:
> of_unregister_fixup must also be called in the release function.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
> This depends on the patch "of: add a function to remove an of_fixup" I
> just sent to the list
> ---
>  common/state.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)

Applied with said patch beforehand.

Sascha

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


From s.hauer at pengutronix.de  Mon May 18 05:29:50 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 18 May 2015 14:29:50 +0200
Subject: [PATCH v2] include: introduce include/linux/io.h as a wrapper of
 asm/io.h
In-Reply-To: <CAK7LNATTasdDYvzHxu=F8Jcmgh8v3nAQOvrJsrmN0moDDLh6Gw@mail.gmail.com>
References: <1431694967-2416-1-git-send-email-yamada.masahiro@socionext.com>
 <20150517184704.9b64228117f4a3addf0f4f12@gmail.com>
 <CAK7LNATTasdDYvzHxu=F8Jcmgh8v3nAQOvrJsrmN0moDDLh6Gw@mail.gmail.com>
Message-ID: <20150518122950.GT6325@pengutronix.de>

On Mon, May 18, 2015 at 10:48:30AM +0900, Masahiro Yamada wrote:
> 2015-05-18 0:47 GMT+09:00 Antony Pavlov <antonynpavlov at gmail.com>:
> > On Fri, 15 May 2015 22:02:47 +0900
> > Masahiro Yamada <yamada.masahiro at socionext.com> wrote:
> >
> >> In the latest Linux coding style, <linux/io.h> should be included
> >> rather than <asm/io.h>.  To follow this standard also in barebox,
> >> add include/linux/io.h.  Currently, it just includes <asm/io.h>.
> >
> > Hmmm. Barebox already has include/io.h for the same purpose.
> > And include/io.h is actively used:
> >
> > ~/barebox.git$ git grep "include <io.h>" | wc -l
> > 474
> >
> 
> We can replace all of them with sed easily.

I'm with Antony here. I think we can afford our own version of <io.h>.

> 
> Moreover, cpu_read{b,w,l} and cpu_write{b,w,l} turned out unnecessary after all.
> Most of C sources use __raw_*.

Agreed, these could be removed.

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 yamada.masahiro at socionext.com  Mon May 18 18:31:26 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue, 19 May 2015 10:31:26 +0900
Subject: [PATCH] Abolish cpu_read* and cpu_write* accessors
Message-ID: <1431999086-19465-1-git-send-email-yamada.masahiro@socionext.com>

Commit 2e6a88f2101d (add cpu native ordered io accessors) introduced
these macros and then commit be57f20cdd7d (Fix big endian MMIO
primitives) figured out they are equivalent to __raw_{read,write}*.

They turned out unnecessary after all.  Anyway, most source files
use __raw_read* and __raw_write*.

Let's replace a few remaining references and abolish them.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-tegra/include/mach/lowlevel.h  |  4 ++--
 arch/mips/mach-ath79/include/mach/debug_ll.h |  4 ++--
 drivers/mtd/nor/cfi_flash.h                  | 12 ++++++------
 drivers/serial/serial_ar933x.c               |  4 ++--
 drivers/spi/ath79_spi.c                      |  4 ++--
 include/io.h                                 |  8 --------
 6 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
index f1fea86..768b13d 100644
--- a/arch/arm/mach-tegra/include/mach/lowlevel.h
+++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
@@ -111,9 +111,9 @@ u32 tegra_get_odmdata(void)
 		return 0;
 	}
 
-	bctptr = cpu_readl(TEGRA_IRAM_BASE + bctptr_offset);
+	bctptr = __raw_readl(TEGRA_IRAM_BASE + bctptr_offset);
 
-	return cpu_readl(bctptr + odmdata_offset);
+	return __raw_readl(bctptr + odmdata_offset);
 }
 
 static __always_inline
diff --git a/arch/mips/mach-ath79/include/mach/debug_ll.h b/arch/mips/mach-ath79/include/mach/debug_ll.h
index c697318..64db674 100644
--- a/arch/mips/mach-ath79/include/mach/debug_ll.h
+++ b/arch/mips/mach-ath79/include/mach/debug_ll.h
@@ -41,12 +41,12 @@
 
 static inline void ar933x_debug_ll_writel(u32 b, int offset)
 {
-	cpu_writel(b, (u8 *)DEBUG_LL_UART_ADDR + offset);
+	__raw_writel(b, (u8 *)DEBUG_LL_UART_ADDR + offset);
 }
 
 static inline u32 ar933x_debug_ll_readl(int offset)
 {
-	return cpu_readl((u8 *)DEBUG_LL_UART_ADDR + offset);
+	return __raw_readl((u8 *)DEBUG_LL_UART_ADDR + offset);
 }
 
 static inline void PUTC_LL(int ch)
diff --git a/drivers/mtd/nor/cfi_flash.h b/drivers/mtd/nor/cfi_flash.h
index 9aad5c4..aeaf751 100644
--- a/drivers/mtd/nor/cfi_flash.h
+++ b/drivers/mtd/nor/cfi_flash.h
@@ -256,17 +256,17 @@ void flash_make_cmd(struct flash_info *info, u32 cmd, cfiword_t *cmdbuf);
 
 static inline void flash_write8(u8 value, void *addr)
 {
-	cpu_writeb(value, addr);
+	__raw_writeb(value, addr);
 }
 
 static inline void flash_write16(u16 value, void *addr)
 {
-	cpu_writew(value, addr);
+	__raw_writew(value, addr);
 }
 
 static inline void flash_write32(u32 value, void *addr)
 {
-	cpu_writel(value, addr);
+	__raw_writel(value, addr);
 }
 
 static inline void flash_write64(u64 value, void *addr)
@@ -276,17 +276,17 @@ static inline void flash_write64(u64 value, void *addr)
 
 static inline u8 flash_read8(void *addr)
 {
-	return cpu_readb(addr);
+	return __raw_readb(addr);
 }
 
 static inline u16 flash_read16(void *addr)
 {
-	return cpu_readw(addr);
+	return __raw_readw(addr);
 }
 
 static inline u32 flash_read32(void *addr)
 {
-	return cpu_readl(addr);
+	return __raw_readl(addr);
 }
 
 static inline u64 flash_read64(void *addr)
diff --git a/drivers/serial/serial_ar933x.c b/drivers/serial/serial_ar933x.c
index 51184aa..59bb5b2 100644
--- a/drivers/serial/serial_ar933x.c
+++ b/drivers/serial/serial_ar933x.c
@@ -40,7 +40,7 @@ static inline void ar933x_serial_writel(struct console_device *cdev,
 {
 	struct ar933x_uart_priv *priv = cdev->dev->priv;
 
-	cpu_writel(b, priv->base + offset);
+	__raw_writel(b, priv->base + offset);
 }
 
 static inline u32 ar933x_serial_readl(struct console_device *cdev,
@@ -48,7 +48,7 @@ static inline u32 ar933x_serial_readl(struct console_device *cdev,
 {
 	struct ar933x_uart_priv *priv = cdev->dev->priv;
 
-	return cpu_readl(priv->base + offset);
+	return __raw_readl(priv->base + offset);
 }
 
 /*
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 4d71eba..bdb39ef 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -48,12 +48,12 @@ struct ath79_spi {
 
 static inline u32 ath79_spi_rr(struct ath79_spi *sp, int reg)
 {
-	return cpu_readl(sp->regs + reg);
+	return __raw_readl(sp->regs + reg);
 }
 
 static inline void ath79_spi_wr(struct ath79_spi *sp, u32 val, int reg)
 {
-	cpu_writel(val, sp->regs + reg);
+	__raw_writel(val, sp->regs + reg);
 }
 
 static inline void setbits(struct ath79_spi *sp, int bits, int on)
diff --git a/include/io.h b/include/io.h
index 8d885de..8eb56b0 100644
--- a/include/io.h
+++ b/include/io.h
@@ -3,12 +3,4 @@
 
 #include <asm/io.h>
 
-/* cpu_read/cpu_write: cpu native io accessors */
-#define cpu_readb(a)		__raw_readb(a)
-#define cpu_readw(a)		__raw_readw(a)
-#define cpu_readl(a)		__raw_readl(a)
-#define cpu_writeb(v, a)	__raw_writeb((v), (a))
-#define cpu_writew(v, a)	__raw_writew((v), (a))
-#define cpu_writel(v, a)	__raw_writel((v), (a))
-
 #endif /* __IO_H */
-- 
1.9.1



From s.hauer at pengutronix.de  Tue May 19 00:06:13 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 19 May 2015 09:06:13 +0200
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
Message-ID: <20150519070613.GX6325@pengutronix.de>

Hi Andrey,

On Wed, May 13, 2015 at 07:54:27PM -0700, Andrey Smirnov wrote:
> Add an option to perform DRAM region validation before using it. The
> framework allows individual boards to set up a memory validaion hook
> that would be called prior to Barebox using that region of memory.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>

What usecase do you have for this patch? Is it debugging or something
you always want to enable on your hardware? Why must the
validate_memory_range function be board specific?

I see that you call validate_memory_range on potentially large areas of
memory, so I wonder if you can't call validate_memory_range from your
board setup code with the complete memory instead.
I am not very fond of overly using get_runtime_offset to calculate
pointers. Setting callback functions from early code which does not run
on its link address is something I really want to avoid.

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 alexander.richter at atsonline.de  Tue May 19 06:29:21 2015
From: alexander.richter at atsonline.de (Alexander Richter)
Date: Tue, 19 May 2015 15:29:21 +0200
Subject: [PATCH] fixing argumentparser for ubiformat
Message-ID: <555B3AB1.5080208@atsonline.de>


Signed-off-by: Alexander Richter <alexander.richter at atsonline.de>
---
  commands/ubiformat.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/commands/ubiformat.c b/commands/ubiformat.c
index df0b801da92c..e63f16e35124 100644
--- a/commands/ubiformat.c
+++ b/commands/ubiformat.c
@@ -84,7 +84,7 @@ static int parse_opt(int argc, char *argv[])
  		int key;
  		unsigned long int image_seq;
  
-		key = getopt(argc, argv, "nyyqve:x:s:O:f:S:");
+		key = getopt(argc, argv, "nyqve:x:s:O:f:S:Q:");
  		if (key == -1)
  			break;
  
-- 
2.1.4




From mkl at pengutronix.de  Tue May 19 10:37:11 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 19 May 2015 19:37:11 +0200
Subject: [PATCH] habv4: habv4_get_status(): fix warning with no-op static
 inline function
Message-ID: <1432057031-19366-1-git-send-email-mkl@pengutronix.de>

This patch fixes the following warning:

  CC      arch/arm/boards/foo/board.o
  In file included from arch/arm/boards/foo/board.c:22:0:
  include/habv4.h:24:19: warning: function declaration isn't a prototype [-Wstrict-prototypes]
   static inline int habv4_get_status()
                      ^

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 include/habv4.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/habv4.h b/include/habv4.h
index fb6ed99d8207..f9bf74f3b936 100644
--- a/include/habv4.h
+++ b/include/habv4.h
@@ -21,7 +21,7 @@
 #ifdef CONFIG_HABV4
 int habv4_get_status(void);
 #else
-static inline int habv4_get_status()
+static inline int habv4_get_status(void)
 {
 	return -EPERM;
 }
-- 
2.1.4



From mkl at pengutronix.de  Tue May 19 11:45:22 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 19 May 2015 20:45:22 +0200
Subject: [PATCH] arm/crypto: add generated sha256-core.S to gitignore
Message-ID: <1432061122-10953-1-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 arch/arm/crypto/.gitignore | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 arch/arm/crypto/.gitignore

diff --git a/arch/arm/crypto/.gitignore b/arch/arm/crypto/.gitignore
new file mode 100644
index 000000000000..b22a068f76f2
--- /dev/null
+++ b/arch/arm/crypto/.gitignore
@@ -0,0 +1 @@
+/sha256-core.S
-- 
2.1.4



From ayakimov at iptec-inc.com  Tue May 19 12:23:22 2015
From: ayakimov at iptec-inc.com (Andrei Yakimov)
Date: Tue, 19 May 2015 12:23:22 -0700
Subject: drivers/mtd/nand/nand_mrvl_nfc.c
Message-ID: <1432063402.14341.126.camel@andreilinux>

Please,
 change 
  case NAND_CMD_PARAM:
        host->buf_count = 256;
To:
  host->buf_count = 768;

If first copy of parameter page corrupted you will not able
to use ONFI flash.

Andrei 




From s.hauer at pengutronix.de  Tue May 19 23:06:29 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 May 2015 08:06:29 +0200
Subject: [PATCH] Abolish cpu_read* and cpu_write* accessors
In-Reply-To: <1431999086-19465-1-git-send-email-yamada.masahiro@socionext.com>
References: <1431999086-19465-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150520060629.GG6325@pengutronix.de>

On Tue, May 19, 2015 at 10:31:26AM +0900, Masahiro Yamada wrote:
> Commit 2e6a88f2101d (add cpu native ordered io accessors) introduced
> these macros and then commit be57f20cdd7d (Fix big endian MMIO
> primitives) figured out they are equivalent to __raw_{read,write}*.
> 
> They turned out unnecessary after all.  Anyway, most source files
> use __raw_read* and __raw_write*.
> 
> Let's replace a few remaining references and abolish them.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---

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  Tue May 19 23:10:13 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 May 2015 08:10:13 +0200
Subject: [PATCH] fixing argumentparser for ubiformat
In-Reply-To: <555B3AB1.5080208@atsonline.de>
References: <555B3AB1.5080208@atsonline.de>
Message-ID: <20150520061013.GH6325@pengutronix.de>

On Tue, May 19, 2015 at 03:29:21PM +0200, Alexander Richter wrote:
> 
> Signed-off-by: Alexander Richter <alexander.richter at atsonline.de>
> ---
>  commands/ubiformat.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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  Tue May 19 23:11:12 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 May 2015 08:11:12 +0200
Subject: [PATCH] habv4: habv4_get_status(): fix warning with no-op static
 inline function
In-Reply-To: <1432057031-19366-1-git-send-email-mkl@pengutronix.de>
References: <1432057031-19366-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150520061112.GI6325@pengutronix.de>

On Tue, May 19, 2015 at 07:37:11PM +0200, Marc Kleine-Budde wrote:
> This patch fixes the following warning:
> 
>   CC      arch/arm/boards/foo/board.o
>   In file included from arch/arm/boards/foo/board.c:22:0:
>   include/habv4.h:24:19: warning: function declaration isn't a prototype [-Wstrict-prototypes]
>    static inline int habv4_get_status()
>                       ^
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  include/habv4.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

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  Tue May 19 23:11:35 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 May 2015 08:11:35 +0200
Subject: [PATCH] arm/crypto: add generated sha256-core.S to gitignore
In-Reply-To: <1432061122-10953-1-git-send-email-mkl@pengutronix.de>
References: <1432061122-10953-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150520061135.GJ6325@pengutronix.de>

On Tue, May 19, 2015 at 08:45:22PM +0200, Marc Kleine-Budde wrote:
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  arch/arm/crypto/.gitignore | 1 +
>  1 file changed, 1 insertion(+)
>  create mode 100644 arch/arm/crypto/.gitignore

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  Tue May 19 23:19:01 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 20 May 2015 08:19:01 +0200
Subject: drivers/mtd/nand/nand_mrvl_nfc.c
In-Reply-To: <1432063402.14341.126.camel@andreilinux>
References: <1432063402.14341.126.camel@andreilinux>
Message-ID: <20150520061901.GK6325@pengutronix.de>

Hi Andrei,

+Cc Robert Jarzmik <robert.jarzmik at free.fr>

On Tue, May 19, 2015 at 12:23:22PM -0700, Andrei Yakimov wrote:
> Please,
>  change 
>   case NAND_CMD_PARAM:
>         host->buf_count = 256;
> To:
>   host->buf_count = 768;
> 
> If first copy of parameter page corrupted you will not able
> to use ONFI flash.

Thanks for noting. However, like many other opensource projects we
communicate changes and change requests with formalized patches. Please
generate one using git format-patch or similar and send it to the list.
I'll happily make that change then.

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 marcel.behlau at elfin.de  Tue May 19 23:34:23 2015
From: marcel.behlau at elfin.de (Marcel Behlau)
Date: Wed, 20 May 2015 08:34:23 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <20150508051242.GV6325@pengutronix.de>
References: <5548DA0A.3050408@elfin.de> <20150505155450.GB6325@pengutronix.de>
 <20150506071228.GQ25193@pengutronix.de> <554B4B63.7020301@elfin.de>
 <20150508051242.GV6325@pengutronix.de>
Message-ID: <555C2AEF.206@elfin.de>

Hi,

i found the problem. The Pad Mux Register (0x20E008C and 0x20E0090) are 
not initialised. In both registers is a 0x00000005 (reset value), 
instead of 0x00000016. I think, i must specify the value of the mux 
register in the device tree, too. How can i do this?

Thank in advance,

Marcel

md 0x20E008C-0x20E0093

On 08.05.2015 07:12, Sascha Hauer wrote:
> On Thu, May 07, 2015 at 01:24:19PM +0200, Marcel Behlau wrote:
>> Hi,
>>
>> many thanks for your help. I activated the i2c devices in the device
>> tree, the pinctrl is already done in the imx6q.dtsi, which is
>> included. The used pins are identically with the used pins on the
>> SBC. devinfo told me, that the driver "i2c-fsl" is loaded. After
>> rebuild barebox, it's possible to probe the bus, but the command
>> only answered with an timeout:
>>
>> barebox at Phytec phyFLEX-i.MX6 Quad Carrier-Board:/ i2c_probe 1 83 83
>> probing i2c range 0x53 - 0x53 :
>> i2c2: <i2c_fsl_bus_busy> timeout waiting for I2C bus busy
> I *think* this means that the levels on the bus do not properly follow
> what the controller wants to do. Maybe pullup missing? An oscilloscope
> might help here.
>
> Sascha
>

-- 
Dipl. Ing (FH) Marcel Behlau
(Software Developer)

ELFIN GmbH
Siegburger Stra?e 215
50679 K?ln
Germany

Tel: +49 (221) 6778932-0
Fax: +49 (221) 6778932-2
marcel.behlau at elfin.de
www.elfin.de



From robert.jarzmik at free.fr  Wed May 20 11:37:02 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 20 May 2015 20:37:02 +0200
Subject: drivers/mtd/nand/nand_mrvl_nfc.c
In-Reply-To: <20150520061901.GK6325@pengutronix.de> (Sascha Hauer's message of
 "Wed, 20 May 2015 08:19:01 +0200")
References: <1432063402.14341.126.camel@andreilinux>
 <20150520061901.GK6325@pengutronix.de>
Message-ID: <87twv7hz8x.fsf@belgarion.home>

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

> Hi Andrei,
>
> +Cc Robert Jarzmik <robert.jarzmik at free.fr>
>
> On Tue, May 19, 2015 at 12:23:22PM -0700, Andrei Yakimov wrote:
>> Please,
>>  change 
>>   case NAND_CMD_PARAM:
>>         host->buf_count = 256;
>> To:
>>   host->buf_count = 768;
>> 
>> If first copy of parameter page corrupted you will not able
>> to use ONFI flash.
>
> Thanks for noting. However, like many other opensource projects we
> communicate changes and change requests with formalized patches. Please
> generate one using git format-patch or similar and send it to the list.
> I'll happily make that change then.

Same from me, I'll happily review a patch.
May I add also that host->ndcb3 and host->data_size deserve the same change
within the NAND_CMD_PARAM case statement.

Cheers.

-- 
Robert


From ayakimov at iptec-inc.com  Wed May 20 17:30:36 2015
From: ayakimov at iptec-inc.com (Andrei Yakimov)
Date: Wed, 20 May 2015 17:30:36 -0700
Subject: drivers/mtd/nand/nand_mrvl_nfc.c
In-Reply-To: <87twv7hz8x.fsf@belgarion.home>
References: <1432063402.14341.126.camel@andreilinux>
 <20150520061901.GK6325@pengutronix.de> <87twv7hz8x.fsf@belgarion.home>
Message-ID: <1432168236.14341.228.camel@andreilinux>

I would like to provide a patch,
but I do not requesting any changes in baraebox
and not working with it.


I do not working with marvel chips,
do not have any controller description.

I found this problem in my 8313 u-boot elbc and
Scott Wood point me to same the problem in imx driver.

Checking linux drivers, found marvel driver which
looks like have same problem.

Geleral idea - linux nand detection flow, expect
PARAM command extra data will deliver as much data
as needed, each next read will trigger extra transfer
from nand chip. This is not true at least for 
elbc, imx and mrvl controllers ( just by looking
to the driver code).

Any controller with memory buffer and transferring
all data from chip at once and required another
nand commad to do next transfer will need to
be updated to read at least 1536 byte by param
commad.
Existing implementation for this type of controllers
will cause eventual failure on the field as soon 
as first ONFI/Jedec block will go bad unless other
other chip identification (by chip ID) pick it up.

Andrei


On Wed, 2015-05-20 at 20:37 +0200, Robert Jarzmik wrote:
> Sascha Hauer <s.hauer at pengutronix.de> writes:
> 
> > Hi Andrei,
> >
> > +Cc Robert Jarzmik <robert.jarzmik at free.fr>
> >
> > On Tue, May 19, 2015 at 12:23:22PM -0700, Andrei Yakimov wrote:
> >> Please,
> >>  change 
> >>   case NAND_CMD_PARAM:
> >>         host->buf_count = 256;
> >> To:
> >>   host->buf_count = 768;
> >> 
> >> If first copy of parameter page corrupted you will not able
> >> to use ONFI flash.
> >
> > Thanks for noting. However, like many other opensource projects we
> > communicate changes and change requests with formalized patches. Please
> > generate one using git format-patch or similar and send it to the list.
> > I'll happily make that change then.
> 
> Same from me, I'll happily review a patch.
> May I add also that host->ndcb3 and host->data_size deserve the same change
> within the NAND_CMD_PARAM case statement.
> 
> Cheers.
> 




From s.christ at phytec.de  Thu May 21 00:41:49 2015
From: s.christ at phytec.de (Stefan Christ)
Date: Thu, 21 May 2015 09:41:49 +0200
Subject: [PATCH] barebox update: add note after successful update
Message-ID: <1432194109-4340-1-git-send-email-s.christ@phytec.de>

Some users of the barebox_update command forget to erase the external
barebox environment after updating the barebox. Using an old barebox
environment leads to various problems if there were major changes.

So add a gentle reminder after the successful update.

Signed-off-by: Stefan Christ <s.christ at phytec.de>
---
 common/bbu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/common/bbu.c b/common/bbu.c
index 7fb154a..1b125e9 100644
--- a/common/bbu.c
+++ b/common/bbu.c
@@ -113,8 +113,11 @@ int barebox_update(struct bbu_data *data)
 	if (ret == -EINTR)
 		printf("update aborted\n");
 
-	if (!ret)
+	if (!ret) {
 		printf("update succeeded\n");
+		if (IS_ENABLED(CONFIG_ENV_HANDLING))
+			printf("You maybe want to erase the barebox environment.\n");
+	}
 
 	return ret;
 }
-- 
1.9.1



From s.hauer at pengutronix.de  Thu May 21 23:11:03 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:03 +0200
Subject: [PATCH 06/14] ARM: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-7-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/include/asm/posix_types.h | 79 +-------------------------------------
 1 file changed, 1 insertion(+), 78 deletions(-)

diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h
index aee050e..22cae62 100644
--- a/arch/arm/include/asm/posix_types.h
+++ b/arch/arm/include/asm/posix_types.h
@@ -1,78 +1 @@
-/*
- *  linux/include/asm-arm/posix_types.h
- *
- *  Copyright (C) 1996-1998 Russell King.
- *
- * 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.
- *
- *  Changelog:
- *   27-06-1996	RMK	Created
- */
-#ifndef __ARCH_ARM_POSIX_TYPES_H
-#define __ARCH_ARM_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long		__kernel_ino_t;
-typedef unsigned short		__kernel_mode_t;
-typedef unsigned short		__kernel_nlink_t;
-typedef long			__kernel_off_t;
-typedef int			__kernel_pid_t;
-typedef unsigned short		__kernel_ipc_pid_t;
-typedef unsigned short		__kernel_uid_t;
-typedef unsigned short		__kernel_gid_t;
-typedef unsigned int		__kernel_size_t;
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
-typedef long			__kernel_time_t;
-typedef long			__kernel_suseconds_t;
-typedef long			__kernel_clock_t;
-typedef int			__kernel_daddr_t;
-typedef char *			__kernel_caddr_t;
-typedef unsigned short		__kernel_uid16_t;
-typedef unsigned short		__kernel_gid16_t;
-typedef unsigned int		__kernel_uid32_t;
-typedef unsigned int		__kernel_gid32_t;
-
-typedef unsigned short		__kernel_old_uid_t;
-typedef unsigned short		__kernel_old_gid_t;
-
-#ifdef __GNUC__
-typedef long long		__kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int	val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int	__val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef	__FD_SET
-#define __FD_SET(fd, fdsetp) \
-		(((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd, fdsetp) \
-		(((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd, fdsetp) \
-		((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0)
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-		(memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
-
-#endif
-
-#endif
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:00 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:00 +0200
Subject: [PATCH 03/14] introduce bitsperlong.h for remaining architectures
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-4-git-send-email-s.hauer@pengutronix.de>

This introduces the bitsperlong.h file for the remaining architectures.
It's purpose is to define BITS_PER_LONG which in the next step can be used
by a generic posix_types.h file.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/include/asm/bitsperlong.h      |  1 +
 arch/arm/include/asm/types.h            |  2 +-
 arch/blackfin/include/asm/types.h       |  2 +-
 arch/efi/include/asm/bitsperlong.h      | 10 ++++++++++
 arch/efi/include/asm/types.h            |  6 +-----
 arch/openrisc/include/asm/bitsperlong.h |  1 +
 arch/openrisc/include/asm/types.h       |  2 +-
 arch/ppc/include/asm/bitsperlong.h      |  1 +
 arch/ppc/include/asm/types.h            |  2 +-
 arch/sandbox/include/asm/bitsperlong.h  | 10 ++++++++++
 arch/sandbox/include/asm/types.h        |  2 +-
 arch/x86/include/asm/bitsperlong.h      |  1 +
 arch/x86/include/asm/types.h            |  2 +-
 13 files changed, 31 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm/include/asm/bitsperlong.h
 create mode 100644 arch/efi/include/asm/bitsperlong.h
 create mode 100644 arch/openrisc/include/asm/bitsperlong.h
 create mode 100644 arch/ppc/include/asm/bitsperlong.h
 create mode 100644 arch/sandbox/include/asm/bitsperlong.h
 create mode 100644 arch/x86/include/asm/bitsperlong.h

diff --git a/arch/arm/include/asm/bitsperlong.h b/arch/arm/include/asm/bitsperlong.h
new file mode 100644
index 0000000..6dc0bb0
--- /dev/null
+++ b/arch/arm/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index 680e824..1a7f47a 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -31,7 +31,7 @@ typedef unsigned long long __u64;
  */
 #ifdef __KERNEL__
 
-#define BITS_PER_LONG 32
+#include <asm/bitsperlong.h>
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/blackfin/include/asm/types.h b/arch/blackfin/include/asm/types.h
index f1c2dc4..e9d7337 100644
--- a/arch/blackfin/include/asm/types.h
+++ b/arch/blackfin/include/asm/types.h
@@ -73,6 +73,6 @@ typedef unsigned long long u64;
 
 #endif /* __ASSEMBLY__ */
 
-#define BITS_PER_LONG 32
+#include <asm/bitsperlong.h>
 
 #endif
diff --git a/arch/efi/include/asm/bitsperlong.h b/arch/efi/include/asm/bitsperlong.h
new file mode 100644
index 0000000..00c1fc2
--- /dev/null
+++ b/arch/efi/include/asm/bitsperlong.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_BITSPERLONG_H
+#define __ASM_BITSPERLONG_H
+
+#ifdef __x86_64__
+#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
+
+#endif /* __ASM_BITSPERLONG_H */
diff --git a/arch/efi/include/asm/types.h b/arch/efi/include/asm/types.h
index 05122ea..3caac39 100644
--- a/arch/efi/include/asm/types.h
+++ b/arch/efi/include/asm/types.h
@@ -56,11 +56,7 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#ifdef __x86_64__
-#define BITS_PER_LONG 64
-#else
-#define BITS_PER_LONG 32
-#endif
+#include <asm/bitsperlong.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/openrisc/include/asm/bitsperlong.h b/arch/openrisc/include/asm/bitsperlong.h
new file mode 100644
index 0000000..6dc0bb0
--- /dev/null
+++ b/arch/openrisc/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/openrisc/include/asm/types.h b/arch/openrisc/include/asm/types.h
index cacda42..5b6391b 100644
--- a/arch/openrisc/include/asm/types.h
+++ b/arch/openrisc/include/asm/types.h
@@ -62,7 +62,7 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#define BITS_PER_LONG 32
+#include <asm/bitsperlong.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/ppc/include/asm/bitsperlong.h b/arch/ppc/include/asm/bitsperlong.h
new file mode 100644
index 0000000..6dc0bb0
--- /dev/null
+++ b/arch/ppc/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/ppc/include/asm/types.h b/arch/ppc/include/asm/types.h
index 37ef353..6eb3877 100644
--- a/arch/ppc/include/asm/types.h
+++ b/arch/ppc/include/asm/types.h
@@ -39,7 +39,7 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#define BITS_PER_LONG 32
+#include <asm-generic/bitsperlong.h>
 
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
diff --git a/arch/sandbox/include/asm/bitsperlong.h b/arch/sandbox/include/asm/bitsperlong.h
new file mode 100644
index 0000000..00c1fc2
--- /dev/null
+++ b/arch/sandbox/include/asm/bitsperlong.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_BITSPERLONG_H
+#define __ASM_BITSPERLONG_H
+
+#ifdef __x86_64__
+#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
+
+#endif /* __ASM_BITSPERLONG_H */
diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h
index 8944b47..7590a39 100644
--- a/arch/sandbox/include/asm/types.h
+++ b/arch/sandbox/include/asm/types.h
@@ -54,7 +54,7 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#define BITS_PER_LONG 32
+#include <asm-generic/bitsperlong.h>
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/x86/include/asm/bitsperlong.h b/arch/x86/include/asm/bitsperlong.h
new file mode 100644
index 0000000..6dc0bb0
--- /dev/null
+++ b/arch/x86/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index b3fd1f6..d60612f 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -41,7 +41,7 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-#define BITS_PER_LONG 32
+#include <asm-generic/bitsperlong.h>
 
 #endif /* __ASSEMBLY__ */
 
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:02 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:02 +0200
Subject: [PATCH 05/14] remove unused nlink_t
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-6-git-send-email-s.hauer@pengutronix.de>

The nlink_t type is unused in barebox, so drop it. This prevents
compile failures when architectures use the generic posix_types.h
which no longer has __kernel_nlink_t defined.

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

diff --git a/include/linux/types.h b/include/linux/types.h
index 9871a66..ce1a0ec 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -15,7 +15,6 @@ typedef __kernel_fd_set		fd_set;
 typedef __kernel_dev_t		dev_t;
 typedef __kernel_ino_t		ino_t;
 typedef __kernel_mode_t		mode_t;
-typedef __kernel_nlink_t	nlink_t;
 typedef __kernel_off_t		off_t;
 typedef __kernel_pid_t		pid_t;
 typedef __kernel_daddr_t	daddr_t;
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:01 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:01 +0200
Subject: [PATCH 04/14] introduce generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-5-git-send-email-s.hauer@pengutronix.de>

Most types defined in posix_types.h are architecture independent,
so instead of repeating this for each architecture add a generic
file that can be used by architecture code. To use it an architecture
must define BITS_PER_LONG properly in asm/bitsperlong.h.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/asm-generic/posix_types.h | 90 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 include/asm-generic/posix_types.h

diff --git a/include/asm-generic/posix_types.h b/include/asm-generic/posix_types.h
new file mode 100644
index 0000000..136f161
--- /dev/null
+++ b/include/asm-generic/posix_types.h
@@ -0,0 +1,90 @@
+#ifndef __ASM_GENERIC_POSIX_TYPES_H
+#define __ASM_GENERIC_POSIX_TYPES_H
+
+#include <asm/bitsperlong.h>
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.
+ *
+ * First the types that are often defined in different ways across
+ * architectures, so that you can override them.
+ */
+
+#ifndef __kernel_long_t
+typedef long		__kernel_long_t;
+typedef unsigned long	__kernel_ulong_t;
+#endif
+
+#ifndef __kernel_ino_t
+typedef __kernel_ulong_t __kernel_ino_t;
+#endif
+
+#ifndef __kernel_mode_t
+typedef unsigned int	__kernel_mode_t;
+#endif
+
+#ifndef __kernel_pid_t
+typedef int		__kernel_pid_t;
+#endif
+
+#ifndef __kernel_ipc_pid_t
+typedef int		__kernel_ipc_pid_t;
+#endif
+
+#ifndef __kernel_uid_t
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+#endif
+
+#ifndef __kernel_suseconds_t
+typedef __kernel_long_t		__kernel_suseconds_t;
+#endif
+
+#ifndef __kernel_daddr_t
+typedef int		__kernel_daddr_t;
+#endif
+
+#ifndef __kernel_uid32_t
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+#endif
+
+#ifndef __kernel_old_uid_t
+typedef __kernel_uid_t	__kernel_old_uid_t;
+typedef __kernel_gid_t	__kernel_old_gid_t;
+#endif
+
+#ifndef __kernel_old_dev_t
+typedef unsigned int	__kernel_old_dev_t;
+#endif
+
+/*
+ * Most 32 bit architectures use "unsigned int" size_t,
+ * and all 64 bit architectures use "unsigned long" size_t.
+ */
+#ifndef __kernel_size_t
+#if BITS_PER_LONG != 64
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef int		__kernel_ptrdiff_t;
+#else
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_long_t	__kernel_ssize_t;
+typedef __kernel_long_t	__kernel_ptrdiff_t;
+#endif
+#endif
+
+/*
+ * anything below here should be completely generic
+ */
+typedef __kernel_long_t	__kernel_off_t;
+typedef long long	__kernel_loff_t;
+typedef __kernel_long_t	__kernel_time_t;
+typedef __kernel_long_t	__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+
+#endif /* __ASM_GENERIC_POSIX_TYPES_H */
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:04 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:04 +0200
Subject: [PATCH 07/14] blackfin: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-8-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/blackfin/include/asm/posix_types.h | 86 +--------------------------------
 1 file changed, 1 insertion(+), 85 deletions(-)

diff --git a/arch/blackfin/include/asm/posix_types.h b/arch/blackfin/include/asm/posix_types.h
index 9992929..22cae62 100644
--- a/arch/blackfin/include/asm/posix_types.h
+++ b/arch/blackfin/include/asm/posix_types.h
@@ -1,85 +1 @@
-/*
- * barebox - posix_types.h
- *
- * Copyright (c) 2005 blackfin.uclinux.org
- *
- * (C) Copyright 2000-2004
- * 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 __ARCH_BLACKFIN_POSIX_TYPES_H
-#define __ARCH_BLACKFIN_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long __kernel_ino_t;
-typedef unsigned short __kernel_mode_t;
-typedef unsigned short __kernel_nlink_t;
-typedef long __kernel_off_t;
-typedef int __kernel_pid_t;
-typedef unsigned short __kernel_ipc_pid_t;
-typedef unsigned short __kernel_uid_t;
-typedef unsigned short __kernel_gid_t;
-typedef unsigned long __kernel_size_t;
-typedef int __kernel_ssize_t;
-typedef int __kernel_ptrdiff_t;
-typedef long __kernel_time_t;
-typedef long __kernel_suseconds_t;
-typedef long __kernel_clock_t;
-typedef int __kernel_daddr_t;
-typedef char *__kernel_caddr_t;
-typedef unsigned short __kernel_uid16_t;
-typedef unsigned short __kernel_gid16_t;
-typedef unsigned int __kernel_uid32_t;
-typedef unsigned int __kernel_gid32_t;
-
-typedef unsigned short __kernel_old_uid_t;
-typedef unsigned short __kernel_old_gid_t;
-
-#ifdef __GNUC__
-typedef long long __kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int val[2];
-#else				/* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int __val[2];
-#endif				/* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef	__FD_SET
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-
-#undef	__FD_CLR
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-
-#undef	__FD_ISSET
-#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
-
-#endif	/* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-
-#endif
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:10:58 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:10:58 +0200
Subject: [PATCH 01/14] dma: Use generic place for dma_addr_t typedef
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-2-git-send-email-s.hauer@pengutronix.de>

Instead of letting all architectures define their own dma_addr_t use
a common place in include/linux/types.h and use a Kconfig symbol that
architectures can select to define the width of dma_addr_t. The same
is done in the Kernel.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/include/asm/types.h      |  5 -----
 arch/blackfin/include/asm/types.h |  4 ----
 arch/efi/include/asm/types.h      |  4 ----
 arch/mips/Kconfig                 |  1 +
 arch/mips/include/asm/types.h     | 12 ------------
 arch/nios2/include/asm/types.h    |  3 ---
 arch/openrisc/include/asm/types.h |  4 ----
 arch/ppc/include/asm/types.h      |  3 ---
 arch/sandbox/include/asm/types.h  |  4 ----
 common/Kconfig                    |  3 +++
 include/linux/types.h             |  7 +++++++
 11 files changed, 11 insertions(+), 39 deletions(-)

diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index 81bd357..680e824 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -47,11 +47,6 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-/* Dma addresses are 32-bits wide.  */
-
-typedef u32 dma_addr_t;
-typedef u32 dma64_addr_t;
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/blackfin/include/asm/types.h b/arch/blackfin/include/asm/types.h
index 3d2bd35..f1c2dc4 100644
--- a/arch/blackfin/include/asm/types.h
+++ b/arch/blackfin/include/asm/types.h
@@ -69,10 +69,6 @@ typedef unsigned int u32;
 typedef signed long long s64;
 typedef unsigned long long u64;
 
-/* Dma addresses are 32-bits wide. */
-
-typedef u32 dma_addr_t;
-
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/efi/include/asm/types.h b/arch/efi/include/asm/types.h
index 3204448..05122ea 100644
--- a/arch/efi/include/asm/types.h
+++ b/arch/efi/include/asm/types.h
@@ -62,10 +62,6 @@ typedef unsigned long long u64;
 #define BITS_PER_LONG 32
 #endif
 
-/* Dma addresses are 32-bits wide.  */
-
-typedef u32 dma_addr_t;
-
 #endif /* __KERNEL__ */
 
 #endif
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ed6e1ab..aeb5c04 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -269,6 +269,7 @@ config 32BIT
 config 64BIT
 	bool "64-bit barebox"
 	depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+	select ARCH_DMA_ADDR_T_64BIT
 	help
 	  Select this option if you want to build a 64-bit barebox.
 
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index b63687d..4140c92 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -13,18 +13,6 @@
 
 #include <asm-generic/int-ll64.h>
 
-#ifndef __ASSEMBLY__
-
-#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \
-    || defined(CONFIG_64BIT)
-typedef u64 dma_addr_t;
-#else
-typedef u32 dma_addr_t;
-#endif
-typedef u64 dma64_addr_t;
-
-#endif /* __ASSEMBLY__ */
-
 /*
  * We don't use int-l64.h for the kernel anymore but still use it for
  * userspace to avoid code changes.
diff --git a/arch/nios2/include/asm/types.h b/arch/nios2/include/asm/types.h
index 21c3415..0067ea8 100644
--- a/arch/nios2/include/asm/types.h
+++ b/arch/nios2/include/asm/types.h
@@ -3,7 +3,4 @@
 
 #include <asm/int-ll64.h>
 
-typedef u32 dma_addr_t;
-
 #endif
-
diff --git a/arch/openrisc/include/asm/types.h b/arch/openrisc/include/asm/types.h
index 3338fcf..cacda42 100644
--- a/arch/openrisc/include/asm/types.h
+++ b/arch/openrisc/include/asm/types.h
@@ -64,10 +64,6 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
-/* Dma addresses are 32-bits wide.  */
-
-typedef u32 dma_addr_t;
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_TYPES_H */
diff --git a/arch/ppc/include/asm/types.h b/arch/ppc/include/asm/types.h
index 4ebbb9e..37ef353 100644
--- a/arch/ppc/include/asm/types.h
+++ b/arch/ppc/include/asm/types.h
@@ -41,9 +41,6 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
-/* DMA addresses are 32-bits wide */
-typedef u32 dma_addr_t;
-
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/sandbox/include/asm/types.h b/arch/sandbox/include/asm/types.h
index d471d25..8944b47 100644
--- a/arch/sandbox/include/asm/types.h
+++ b/arch/sandbox/include/asm/types.h
@@ -56,10 +56,6 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
-/* Dma addresses are 32-bits wide.  */
-
-typedef u32 dma_addr_t;
-
 #endif /* __KERNEL__ */
 
 #endif
diff --git a/common/Kconfig b/common/Kconfig
index 1c5d14c..3dfb5ac 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -94,6 +94,9 @@ config EFI_DEVICEPATH
 config FILE_LIST
 	bool
 
+config ARCH_DMA_ADDR_T_64BIT
+	bool
+
 menu "General Settings"
 
 config LOCALVERSION
diff --git a/include/linux/types.h b/include/linux/types.h
index c11e148..9871a66 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -158,6 +158,13 @@ typedef __u32 __bitwise __wsum;
 #define __aligned_be64 __be64 __attribute__((aligned(8)))
 #define __aligned_le64 __le64 __attribute__((aligned(8)))
 
+/* A dma_addr_t can hold any valid DMA or bus address for the platform */
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
+#endif /* dma_addr_t */
+
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
 typedef u64 phys_addr_t;
 typedef u64 phys_size_t;
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:08 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:08 +0200
Subject: [PATCH 11/14] ppc: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-12-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/ppc/include/asm/posix_types.h | 109 +------------------------------------
 1 file changed, 1 insertion(+), 108 deletions(-)

diff --git a/arch/ppc/include/asm/posix_types.h b/arch/ppc/include/asm/posix_types.h
index a7af406..22cae62 100644
--- a/arch/ppc/include/asm/posix_types.h
+++ b/arch/ppc/include/asm/posix_types.h
@@ -1,108 +1 @@
-#ifndef _PPC_POSIX_TYPES_H
-#define _PPC_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned int	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef short             __kernel_ipc_pid_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned int	__kernel_old_uid_t;
-typedef unsigned int	__kernel_old_gid_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#ifndef __GNUC__
-
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
-#define	__FD_ZERO(set)	\
-  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
-    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned int *tmp = (unsigned int *)p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-			case 8:
-				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
-				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
-				return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-#endif /* __GNUC__ */
-#endif /* _PPC_POSIX_TYPES_H */
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:10:59 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:10:59 +0200
Subject: [PATCH 02/14] drop __BITS_PER_LONG
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-3-git-send-email-s.hauer@pengutronix.de>

The kernel has __BITS_PER_LONG and BITS_PER_LONG. The formaer
is needed for architectures which support 32bit userspace on a
64bit kernel. This is not relevant for barebox, so drop
__BITS_PER_LONG and use BITS_PER_LONG only.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/mips/include/asm/bitsperlong.h |  4 +---
 include/asm-generic/bitsperlong.h   | 22 ----------------------
 include/asm-generic/swab.h          |  2 +-
 3 files changed, 2 insertions(+), 26 deletions(-)

diff --git a/arch/mips/include/asm/bitsperlong.h b/arch/mips/include/asm/bitsperlong.h
index 3e4c10a..4171216 100644
--- a/arch/mips/include/asm/bitsperlong.h
+++ b/arch/mips/include/asm/bitsperlong.h
@@ -1,8 +1,6 @@
 #ifndef __ASM_MIPS_BITSPERLONG_H
 #define __ASM_MIPS_BITSPERLONG_H
 
-#define __BITS_PER_LONG _MIPS_SZLONG
-
-#include <asm-generic/bitsperlong.h>
+#define BITS_PER_LONG _MIPS_SZLONG
 
 #endif /* __ASM_MIPS_BITSPERLONG_H */
diff --git a/include/asm-generic/bitsperlong.h b/include/asm-generic/bitsperlong.h
index 4ae54e0..bb98650 100644
--- a/include/asm-generic/bitsperlong.h
+++ b/include/asm-generic/bitsperlong.h
@@ -1,32 +1,10 @@
 #ifndef __ASM_GENERIC_BITS_PER_LONG
 #define __ASM_GENERIC_BITS_PER_LONG
 
-/*
- * There seems to be no way of detecting this automatically from user
- * space, so 64 bit architectures should override this in their
- * bitsperlong.h. In particular, an architecture that supports
- * both 32 and 64 bit user space must not rely on CONFIG_64BIT
- * to decide it, but rather check a compiler provided macro.
- */
-#ifndef __BITS_PER_LONG
-#define __BITS_PER_LONG 32
-#endif
-
-#ifdef __KERNEL__
-
 #ifdef CONFIG_64BIT
 #define BITS_PER_LONG 64
 #else
 #define BITS_PER_LONG 32
 #endif /* CONFIG_64BIT */
 
-/*
- * FIXME: The check currently breaks x86-64 build, so it's
- * temporarily disabled. Please fix x86-64 and reenable
- */
-#if 0 && BITS_PER_LONG != __BITS_PER_LONG
-#error Inconsistent word size. Check asm/bitsperlong.h
-#endif
-
-#endif /* __KERNEL__ */
 #endif /* __ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/asm-generic/swab.h b/include/asm-generic/swab.h
index a8e9029..3ab5add 100644
--- a/include/asm-generic/swab.h
+++ b/include/asm-generic/swab.h
@@ -9,7 +9,7 @@
  * valid if the compiler supports 64 bit data types.
  */
 
-#if __BITS_PER_LONG == 32
+#if BITS_PER_LONG == 32
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #define __SWAB_64_THRU_32__
 #endif
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:07 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:07 +0200
Subject: [PATCH 10/14] mips: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-11-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/mips/include/asm/posix_types.h | 130 +-----------------------------------
 1 file changed, 1 insertion(+), 129 deletions(-)

diff --git a/arch/mips/include/asm/posix_types.h b/arch/mips/include/asm/posix_types.h
index bbeb721..c38e24a 100644
--- a/arch/mips/include/asm/posix_types.h
+++ b/arch/mips/include/asm/posix_types.h
@@ -11,134 +11,6 @@
 
 #include <asm/sgidefs.h>
 
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-#if (_MIPS_SZLONG == 32)
-typedef unsigned long	__kernel_nlink_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef unsigned int	__kernel_nlink_t;
-#endif
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef int		__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-#if (_MIPS_SZLONG == 32)
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-#endif
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef long		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-typedef __kernel_uid_t	__kernel_old_uid_t;
-typedef __kernel_gid_t	__kernel_old_gid_t;
-typedef unsigned int	__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long      __kernel_loff_t;
-#endif
-
-typedef struct {
-#if (_MIPS_SZLONG == 32)
-	long	val[2];
-#endif
-#if (_MIPS_SZLONG == 64)
-	int	val[2];
-#endif
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
-{
-	unsigned long *__tmp = __p->fds_bits;
-	int __i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 16:
-			__tmp[0] = 0; __tmp[1] = 0;
-			__tmp[2] = 0; __tmp[3] = 0;
-			__tmp[4] = 0; __tmp[5] = 0;
-			__tmp[6] = 0; __tmp[7] = 0;
-			__tmp[8] = 0; __tmp[9] = 0;
-			__tmp[10] = 0; __tmp[11] = 0;
-			__tmp[12] = 0; __tmp[13] = 0;
-			__tmp[14] = 0; __tmp[15] = 0;
-			return;
-
-		case 8:
-			__tmp[0] = 0; __tmp[1] = 0;
-			__tmp[2] = 0; __tmp[3] = 0;
-			__tmp[4] = 0; __tmp[5] = 0;
-			__tmp[6] = 0; __tmp[7] = 0;
-			return;
-
-		case 4:
-			__tmp[0] = 0; __tmp[1] = 0;
-			__tmp[2] = 0; __tmp[3] = 0;
-			return;
-		}
-	}
-	__i = __FDSET_LONGS;
-	while (__i) {
-		__i--;
-		*__tmp = 0;
-		__tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ASM_POSIX_TYPES_H */
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:10:57 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:10:57 +0200
Subject: Introduce asm-generic/posix_types.h
Message-ID: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>

asm/posix_types.h adds several posix variable types for each architecture.
This is unnecessary code duplication. Since the files are derived from
Linux they have some real differences, but they are irrelevant to barebox.
For example __kernel_mode_t is unsigned int on some architectures and
unsigned short on others. Since we have no userspace we have to stay
compatible to we can use the same type for all architectures. Some
32bit architectures use unsigned long where others use unsigned int, but
since both are 32bit types we can use the same type for all architectures.
Finally there are types which are different between 32bit and 64bit
architectures, these are handled by the BITS_PER_LONG macro defined
in asm/bitsperlong.h which is added for the architectures that do not
have this file already.

----------------------------------------------------------------
Sascha Hauer (14):
      dma: Use generic place for dma_addr_t typedef
      drop __BITS_PER_LONG
      introduce bitsperlong.h for remaining architectures
      introduce generic posix_types.h
      remove unused nlink_t
      ARM: use generic posix_types.h
      blackfin: use generic posix_types.h
      x86: use generic posix_types.h
      openrisc: use generic posix_types.h
      mips: use generic posix_types.h
      ppc: use generic posix_types.h
      sandbox: use generic posix_types.h
      efi: use generic posix_types.h
      nios2: use generic posix_types.h

 arch/arm/include/asm/bitsperlong.h      |   1 +
 arch/arm/include/asm/posix_types.h      |  79 +------------------
 arch/arm/include/asm/types.h            |   7 +-
 arch/blackfin/include/asm/posix_types.h |  86 +--------------------
 arch/blackfin/include/asm/types.h       |   6 +-
 arch/efi/include/asm/bitsperlong.h      |  10 +++
 arch/efi/include/asm/posix_types.h      |  94 +----------------------
 arch/efi/include/asm/types.h            |  10 +--
 arch/mips/Kconfig                       |   1 +
 arch/mips/include/asm/bitsperlong.h     |   4 +-
 arch/mips/include/asm/posix_types.h     | 130 +-------------------------------
 arch/mips/include/asm/types.h           |  12 ---
 arch/nios2/include/asm/posix_types.h    |  78 +------------------
 arch/nios2/include/asm/types.h          |   3 -
 arch/openrisc/include/asm/bitsperlong.h |   1 +
 arch/openrisc/include/asm/posix_types.h |  72 +-----------------
 arch/openrisc/include/asm/types.h       |   6 +-
 arch/ppc/include/asm/bitsperlong.h      |   1 +
 arch/ppc/include/asm/posix_types.h      | 109 +-------------------------
 arch/ppc/include/asm/types.h            |   5 +-
 arch/sandbox/include/asm/bitsperlong.h  |  10 +++
 arch/sandbox/include/asm/posix_types.h  |  94 +----------------------
 arch/sandbox/include/asm/types.h        |   6 +-
 arch/x86/include/asm/bitsperlong.h      |   1 +
 arch/x86/include/asm/posix_types.h      |  45 +----------
 arch/x86/include/asm/types.h            |   2 +-
 common/Kconfig                          |   3 +
 include/asm-generic/bitsperlong.h       |  22 ------
 include/asm-generic/posix_types.h       |  90 ++++++++++++++++++++++
 include/asm-generic/swab.h              |   2 +-
 include/linux/types.h                   |   8 +-
 31 files changed, 143 insertions(+), 855 deletions(-)
 create mode 100644 arch/arm/include/asm/bitsperlong.h
 create mode 100644 arch/efi/include/asm/bitsperlong.h
 create mode 100644 arch/openrisc/include/asm/bitsperlong.h
 create mode 100644 arch/ppc/include/asm/bitsperlong.h
 create mode 100644 arch/sandbox/include/asm/bitsperlong.h
 create mode 100644 arch/x86/include/asm/bitsperlong.h
 create mode 100644 include/asm-generic/posix_types.h


From s.hauer at pengutronix.de  Thu May 21 23:11:05 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:05 +0200
Subject: [PATCH 08/14] x86: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-9-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/x86/include/asm/posix_types.h | 45 +-------------------------------------
 1 file changed, 1 insertion(+), 44 deletions(-)

diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h
index 066f159..22cae62 100644
--- a/arch/x86/include/asm/posix_types.h
+++ b/arch/x86/include/asm/posix_types.h
@@ -1,44 +1 @@
-/*
- * 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.
- *
- *
- */
-
-/**
- * @file
- * @brief x86 posix types
- *
- * Minimal set to make all the other header files copied from the Linux kernel happy
- */
-
-#ifndef _ASM_X86_POSIX_TYPES_H
-#define _ASM_X86_POSIX_TYPES_H
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned short	__kernel_mode_t;
-typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-typedef long long	__kernel_loff_t;
-
-#endif /* _ASM_X86_POSIX_TYPES_H */
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:06 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:06 +0200
Subject: [PATCH 09/14] openrisc: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-10-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/openrisc/include/asm/posix_types.h | 72 +--------------------------------
 1 file changed, 1 insertion(+), 71 deletions(-)

diff --git a/arch/openrisc/include/asm/posix_types.h b/arch/openrisc/include/asm/posix_types.h
index 7f4c942..22cae62 100644
--- a/arch/openrisc/include/asm/posix_types.h
+++ b/arch/openrisc/include/asm/posix_types.h
@@ -1,71 +1 @@
-/*
- * Based on microblaze implementation:
- *  Copyright (C) 2003       John Williams <jwilliams at itee.uq.edu.au>
- *  Copyright (C) 2001,2002  NEC Corporation
- *  Copyright (C) 2001,2002  Miles Bader <miles at gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file COPYING in the main directory of this
- * archive for more details.
- *
- * Written by Miles Bader <miles at gnu.org>
- * Microblaze port by John Williams
- */
-
-#ifndef __ASM_OPENRISC_POSIX_TYPES_H
-#define __ASM_OPENRISC_POSIX_TYPES_H
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned long long __kernel_ino64_t;
-typedef unsigned int	__kernel_mode_t;
-typedef unsigned int	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef long long	__kernel_loff_t;
-typedef int		__kernel_pid_t;
-typedef unsigned short	__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char		*__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int	val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int	__val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef __FD_SET
-#define __FD_SET(fd, fd_set) \
-	__set_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
-#undef __FD_CLR
-#define __FD_CLR(fd, fd_set) \
-	__clear_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
-#undef __FD_ISSET
-#define __FD_ISSET(fd, fd_set) \
-	__test_bit(fd, (void *)&((__kernel_fd_set *)fd_set)->fds_bits)
-#undef __FD_ZERO
-#define __FD_ZERO(fd_set) \
-	memset(fd_set, 0, sizeof(*(fd_set *)fd_set))
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-
-#endif /* __ASM_OPENRISC_POSIX_TYPES_H */
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:09 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:09 +0200
Subject: [PATCH 12/14] sandbox: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-13-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/sandbox/include/asm/posix_types.h | 94 +---------------------------------
 1 file changed, 1 insertion(+), 93 deletions(-)

diff --git a/arch/sandbox/include/asm/posix_types.h b/arch/sandbox/include/asm/posix_types.h
index 6985b8e..22cae62 100644
--- a/arch/sandbox/include/asm/posix_types.h
+++ b/arch/sandbox/include/asm/posix_types.h
@@ -1,93 +1 @@
-#ifndef __ARCH_I386_POSIX_TYPES_H
-#define __ARCH_I386_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned short	__kernel_mode_t;
-typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef unsigned short	__kernel_ipc_pid_t;
-typedef unsigned short	__kernel_uid_t;
-typedef unsigned short	__kernel_gid_t;
-/*
- * Most 32 bit architectures use "unsigned int" size_t,
- * and all 64 bit architectures use "unsigned long" size_t.
- *
- * TODO: It's not clean to use __x86_64__ here. It's better
- * to check on __BITS_PER_LONG here. But this is wrong set in
- * arch/sandbox/include/asm/types.h.
- */
-#ifdef __x86_64__
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-#else
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-#endif
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int	val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int	__val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef	__FD_SET
-#define __FD_SET(fd,fdsetp) \
-		__asm__ __volatile__("btsl %1,%0": \
-			"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd,fdsetp) \
-		__asm__ __volatile__("btrl %1,%0": \
-			"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
-		unsigned char __result; \
-		__asm__ __volatile__("btl %1,%2 ; setb %0" \
-			:"=q" (__result) :"r" ((int) (fd)), \
-			"m" (*(__kernel_fd_set *) (fdsetp))); \
-		__result; }))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-do { \
-	int __d0, __d1; \
-	__asm__ __volatile__("cld ; rep ; stosl" \
-			:"=m" (*(__kernel_fd_set *) (fdsetp)), \
-			  "=&c" (__d0), "=&D" (__d1) \
-			:"a" (0), "1" (__FDSET_LONGS), \
-			"2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \
-} while (0)
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-
-#endif
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:10 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:10 +0200
Subject: [PATCH 13/14] efi: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-14-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/efi/include/asm/posix_types.h | 94 +-------------------------------------
 1 file changed, 1 insertion(+), 93 deletions(-)

diff --git a/arch/efi/include/asm/posix_types.h b/arch/efi/include/asm/posix_types.h
index 6985b8e..22cae62 100644
--- a/arch/efi/include/asm/posix_types.h
+++ b/arch/efi/include/asm/posix_types.h
@@ -1,93 +1 @@
-#ifndef __ARCH_I386_POSIX_TYPES_H
-#define __ARCH_I386_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned short	__kernel_mode_t;
-typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef unsigned short	__kernel_ipc_pid_t;
-typedef unsigned short	__kernel_uid_t;
-typedef unsigned short	__kernel_gid_t;
-/*
- * Most 32 bit architectures use "unsigned int" size_t,
- * and all 64 bit architectures use "unsigned long" size_t.
- *
- * TODO: It's not clean to use __x86_64__ here. It's better
- * to check on __BITS_PER_LONG here. But this is wrong set in
- * arch/sandbox/include/asm/types.h.
- */
-#ifdef __x86_64__
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-#else
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-#endif
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int	val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int	__val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef	__FD_SET
-#define __FD_SET(fd,fdsetp) \
-		__asm__ __volatile__("btsl %1,%0": \
-			"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd,fdsetp) \
-		__asm__ __volatile__("btrl %1,%0": \
-			"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
-		unsigned char __result; \
-		__asm__ __volatile__("btl %1,%2 ; setb %0" \
-			:"=q" (__result) :"r" ((int) (fd)), \
-			"m" (*(__kernel_fd_set *) (fdsetp))); \
-		__result; }))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-do { \
-	int __d0, __d1; \
-	__asm__ __volatile__("cld ; rep ; stosl" \
-			:"=m" (*(__kernel_fd_set *) (fdsetp)), \
-			  "=&c" (__d0), "=&D" (__d1) \
-			:"a" (0), "1" (__FDSET_LONGS), \
-			"2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \
-} while (0)
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
-
-#endif
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:11:11 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:11:11 +0200
Subject: [PATCH 14/14] nios2: use generic posix_types.h
In-Reply-To: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
References: <1432275071-28554-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432275071-28554-15-git-send-email-s.hauer@pengutronix.de>

Use generic asm-generic/posix_types.h instead of repeating the
typedefs.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/nios2/include/asm/posix_types.h | 78 +-----------------------------------
 1 file changed, 1 insertion(+), 77 deletions(-)

diff --git a/arch/nios2/include/asm/posix_types.h b/arch/nios2/include/asm/posix_types.h
index 5a901ff..22cae62 100644
--- a/arch/nios2/include/asm/posix_types.h
+++ b/arch/nios2/include/asm/posix_types.h
@@ -1,77 +1 @@
-/*
- *  arch/arm/include/asm/posix_types.h
- *
- *  Copyright (C) 1996-1998 Russell King.
- *
- * 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.
- *
- *  Changelog:
- *   27-06-1996	RMK	Created
- */
-#ifndef __ARCH_ARM_POSIX_TYPES_H
-#define __ARCH_ARM_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long		__kernel_ino_t;
-typedef unsigned short		__kernel_mode_t;
-typedef unsigned short		__kernel_nlink_t;
-typedef long			__kernel_off_t;
-typedef int			__kernel_pid_t;
-typedef unsigned short		__kernel_ipc_pid_t;
-typedef unsigned short		__kernel_uid_t;
-typedef unsigned short		__kernel_gid_t;
-typedef unsigned long		__kernel_size_t;
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
-typedef long			__kernel_time_t;
-typedef long			__kernel_suseconds_t;
-typedef long			__kernel_clock_t;
-typedef int			__kernel_timer_t;
-typedef int			__kernel_clockid_t;
-typedef int			__kernel_daddr_t;
-typedef char *			__kernel_caddr_t;
-typedef unsigned short		__kernel_uid16_t;
-typedef unsigned short		__kernel_gid16_t;
-typedef unsigned int		__kernel_uid32_t;
-typedef unsigned int		__kernel_gid32_t;
-
-typedef unsigned short		__kernel_old_uid_t;
-typedef unsigned short		__kernel_old_gid_t;
-typedef unsigned short		__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long		__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define __FD_SET(fd, fdsetp) \
-		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd, fdsetp) \
-		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd, fdsetp) \
-		((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-		(memset(fdsetp, 0, sizeof(*(fd_set *)(fdsetp))))
-
-#endif
-
-#endif
+#include <asm-generic/posix_types.h>
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 21 23:41:08 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:41:08 +0200
Subject: Usage of i2c_-Tools in Barebox
In-Reply-To: <555C2AEF.206@elfin.de>
References: <5548DA0A.3050408@elfin.de> <20150505155450.GB6325@pengutronix.de>
 <20150506071228.GQ25193@pengutronix.de> <554B4B63.7020301@elfin.de>
 <20150508051242.GV6325@pengutronix.de> <555C2AEF.206@elfin.de>
Message-ID: <20150522064108.GS6325@pengutronix.de>

On Wed, May 20, 2015 at 08:34:23AM +0200, Marcel Behlau wrote:
> Hi,
> 
> i found the problem. The Pad Mux Register (0x20E008C and 0x20E0090)
> are not initialised. In both registers is a 0x00000005 (reset
> value), instead of 0x00000016. I think, i must specify the value of
> the mux register in the device tree, too. How can i do this?

You have to add a pinctrl node, like this:

&iomuxc {
	imx6s-riotboard {
		pinctrl_i2c1_2: i2c1grp-2 {
			fsl,pins = <
				MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
				MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
			>;
		};
	};
};

...

&i2c1 {
	pinctrl-0 = <&pinctrl_i2c1_2>;
};

See dts/Bindings/pinctrl/fsl,imx-pinctrl.txt and
dts/Bindings/pinctrl/fsl,imx6q-pinctrl.txt for a documentation what the
0x4001b8b1 value means. In short bit30 is for the SION bit and the
remaing bits are for the PAD_CTL register.

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  Thu May 21 23:50:37 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 08:50:37 +0200
Subject: [PATCH] barebox update: add note after successful update
In-Reply-To: <1432194109-4340-1-git-send-email-s.christ@phytec.de>
References: <1432194109-4340-1-git-send-email-s.christ@phytec.de>
Message-ID: <20150522065037.GT6325@pengutronix.de>

On Thu, May 21, 2015 at 09:41:49AM +0200, Stefan Christ wrote:
> Some users of the barebox_update command forget to erase the external
> barebox environment after updating the barebox. Using an old barebox
> environment leads to various problems if there were major changes.
> 
> So add a gentle reminder after the successful update.
> 
> Signed-off-by: Stefan Christ <s.christ at phytec.de>
> ---
>  common/bbu.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/common/bbu.c b/common/bbu.c
> index 7fb154a..1b125e9 100644
> --- a/common/bbu.c
> +++ b/common/bbu.c
> @@ -113,8 +113,11 @@ int barebox_update(struct bbu_data *data)
>  	if (ret == -EINTR)
>  		printf("update aborted\n");
>  
> -	if (!ret)
> +	if (!ret) {
>  		printf("update succeeded\n");
> +		if (IS_ENABLED(CONFIG_ENV_HANDLING))
> +			printf("You maybe want to erase the barebox environment.\n");

How about adding a hint ...using saveenv -z?

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  Fri May 22 00:41:06 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 22 May 2015 09:41:06 +0200
Subject: [PATCH] tlsf malloc: enable 64bit support on 64bit architectures
Message-ID: <1432280466-7055-1-git-send-email-s.hauer@pengutronix.de>

On 64bit architectures TLSF_64BIT should be defined. Decide that
depending on the CONFIG_64BIT symbol. When 64bit support is enabled
all allocations will be aligned to 8 byte boundaries which is necessary
for architectures that do not support unaligned accesses or have
a performance penalty for unaligned accesses.
Also changes the undefined tlsf_decl to 'static'.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/tlsfbits.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/common/tlsfbits.h b/common/tlsfbits.h
index 93466e4..edbac80 100644
--- a/common/tlsfbits.h
+++ b/common/tlsfbits.h
@@ -3,6 +3,10 @@
 
 #include <linux/bitops.h>
 
+#ifdef CONFIG_64BIT
+#define TLSF_64BIT
+#endif
+
 /*
 ** Architecture-specific bit manipulation routines.
 **
@@ -33,7 +37,7 @@ static int tlsf_fls(unsigned int word)
 
 /* Possibly 64-bit version of tlsf_fls. */
 #if defined (TLSF_64BIT)
-tlsf_decl int tlsf_fls_sizet(size_t size)
+static int tlsf_fls_sizet(size_t size)
 {
 	int high = (int)(size >> 32);
 	int bits = 0;
-- 
2.1.4



From s.christ at phytec.de  Fri May 22 04:55:16 2015
From: s.christ at phytec.de (Stefan Christ)
Date: Fri, 22 May 2015 13:55:16 +0200
Subject: [PATCH] barebox update: add note after successful update
In-Reply-To: <20150522065037.GT6325@pengutronix.de>
References: <1432194109-4340-1-git-send-email-s.christ@phytec.de>
 <20150522065037.GT6325@pengutronix.de>
Message-ID: <20150522115515.GB5384@lws-christ>

On Fri, May 22, 2015 at 08:50:37AM +0200, Sascha Hauer wrote:
> On Thu, May 21, 2015 at 09:41:49AM +0200, Stefan Christ wrote:
> > Some users of the barebox_update command forget to erase the external
> > barebox environment after updating the barebox. Using an old barebox
> > environment leads to various problems if there were major changes.
> > 
> > So add a gentle reminder after the successful update.
> > 
> > Signed-off-by: Stefan Christ <s.christ at phytec.de>
> > ---
> >  common/bbu.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/common/bbu.c b/common/bbu.c
> > index 7fb154a..1b125e9 100644
> > --- a/common/bbu.c
> > +++ b/common/bbu.c
> > @@ -113,8 +113,11 @@ int barebox_update(struct bbu_data *data)
> >  	if (ret == -EINTR)
> >  		printf("update aborted\n");
> >  
> > -	if (!ret)
> > +	if (!ret) {
> >  		printf("update succeeded\n");
> > +		if (IS_ENABLED(CONFIG_ENV_HANDLING))
> > +			printf("You maybe want to erase the barebox environment.\n");
> 
> How about adding a hint ...using saveenv -z?

Oh, I didn't know that the "-z" argument exits. Nice.

Ok, but what about the situation when a user boots the barebox from sdcard and
uses the barebox_update handler to flash a barebox to NAND. In such case
'saveenv -z' overwrites the environment on the sdcard.

I've struggled a bit to come up with a short text that covers all these cases.

Mit freundlichen Gr??en / Kind regards,
	Stefan Christ

> 
> 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  Fri May 22 05:09:14 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 22 May 2015 14:09:14 +0200
Subject: [PATCH 1/2] ARM: dts: Add an am33xx include file for MLO size
 reduction
Message-ID: <1432296555-48594-1-git-send-email-w.egorov@phytec.de>

AM335x's MLO size limit is 109K.
The am33xx.dtsi file adds spare and never used nodes to the dtb.
With this patch we add a file to remove the unused nodes and reduce the
size of the dtb.

Including this file will reduce the lzo packed MLO size about 8K.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/dts/strip-am33xx.dtsi | 66 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 arch/arm/dts/strip-am33xx.dtsi

diff --git a/arch/arm/dts/strip-am33xx.dtsi b/arch/arm/dts/strip-am33xx.dtsi
new file mode 100644
index 0000000..fe34edc
--- /dev/null
+++ b/arch/arm/dts/strip-am33xx.dtsi
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * 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.
+ */
+
+/ {
+	aliases {
+		/delete-property/ i2c1;
+		/delete-property/ i2c2;
+		/delete-property/ mmc0;
+		/delete-property/ mmc1;
+		/delete-property/ mmc2;
+		/delete-property/ gpio0;
+		/delete-property/ gpio1;
+		/delete-property/ gpio2;
+		/delete-property/ gpio3;
+		/delete-property/ serial1;
+		/delete-property/ serial2;
+		/delete-property/ serial3;
+		/delete-property/ serial4;
+		/delete-property/ serial5;
+		/delete-property/ d_can0;
+		/delete-property/ d_can1;
+	};
+};
+
+/delete-node/ &gpio0;
+/delete-node/ &gpio1;
+/delete-node/ &gpio2;
+/delete-node/ &gpio3;
+/delete-node/ &uart1;
+/delete-node/ &uart2;
+/delete-node/ &uart3;
+/delete-node/ &uart4;
+/delete-node/ &uart5;
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &mmc2;
+/delete-node/ &mmc3;
+/delete-node/ &hwspinlock;
+/delete-node/ &wdt2;
+/delete-node/ &dcan0;
+/delete-node/ &dcan1;
+/delete-node/ &mailbox;
+/delete-node/ &timer1;
+/delete-node/ &timer2;
+/delete-node/ &timer3;
+/delete-node/ &timer4;
+/delete-node/ &timer5;
+/delete-node/ &timer6;
+/delete-node/ &timer7;
+/delete-node/ &spi1;
+/delete-node/ &epwmss0;
+/delete-node/ &epwmss1;
+/delete-node/ &epwmss2;
+/delete-node/ &lcdc;
+/delete-node/ &tscadc;
+/delete-node/ &sham;
+/delete-node/ &aes;
+/delete-node/ &mcasp0;
+/delete-node/ &mcasp1;
+/delete-node/ &rng;
-- 
1.9.1



From w.egorov at phytec.de  Fri May 22 05:09:15 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 22 May 2015 14:09:15 +0200
Subject: [PATCH 2/2] ARM: dts: Add strip-am33xx.dtsi to PHYTEC MLOs
In-Reply-To: <1432296555-48594-1-git-send-email-w.egorov@phytec.de>
References: <1432296555-48594-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432296555-48594-2-git-send-email-w.egorov@phytec.de>

This patch will reduce the size of the MLO images.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/dts/am335x-phytec-phycard-som-mlo.dts | 1 +
 arch/arm/dts/am335x-phytec-phycore-som-mlo.dts | 1 +
 arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
index 17d9152..c762ee9 100644
--- a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phycard-som.dtsi"
+#include "strip-am33xx.dtsi"
 
 / {
 	model = "Phytec phyCARD AM335x";
diff --git a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
index b08a59e..d056212 100644
--- a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phycore-som.dtsi"
+#include "strip-am33xx.dtsi"
 
 / {
 	model = "Phytec phyCORE AM335x";
diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
index 5294ff5..916979b 100644
--- a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phyflex-som.dtsi"
+#include "strip-am33xx.dtsi"
 
 / {
 	model = "Phytec phyFLEX AM335x";
-- 
1.9.1



From w.egorov at phytec.de  Fri May 22 05:11:16 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 22 May 2015 14:11:16 +0200
Subject: [RFC 1/3] bootsource: Add NET bootsource
Message-ID: <1432296678-375-1-git-send-email-w.egorov@phytec.de>

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 common/bootsource.c  | 1 +
 include/bootsource.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/common/bootsource.c b/common/bootsource.c
index 7f3d51f..707b079 100644
--- a/common/bootsource.c
+++ b/common/bootsource.c
@@ -35,6 +35,7 @@ static const char *bootsource_str[] = {
 	[BOOTSOURCE_ONENAND] = "onenand",
 	[BOOTSOURCE_HD] = "harddisk",
 	[BOOTSOURCE_USB] = "usb",
+	[BOOTSOURCE_NET] = "net",
 };
 
 static enum bootsource bootsource = BOOTSOURCE_UNKNOWN;
diff --git a/include/bootsource.h b/include/bootsource.h
index 4bca9b9..c6d3b3a 100644
--- a/include/bootsource.h
+++ b/include/bootsource.h
@@ -15,6 +15,7 @@ enum bootsource {
 	BOOTSOURCE_ONENAND,
 	BOOTSOURCE_HD,
 	BOOTSOURCE_USB,
+	BOOTSOURCE_NET,
 };
 
 #define BOOTSOURCE_INSTANCE_UNKNOWN	-1
-- 
1.9.1



From w.egorov at phytec.de  Fri May 22 05:11:18 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 22 May 2015 14:11:18 +0200
Subject: [RFC 3/3] ARM: am33xx: Add network boot
In-Reply-To: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
References: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432296678-375-3-git-send-email-w.egorov@phytec.de>

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/mach-omap/Kconfig          |  9 +++++++
 arch/arm/mach-omap/am33xx_generic.c |  3 +++
 arch/arm/mach-omap/xload.c          | 52 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index 444ddf8..bc00d5b 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -110,6 +110,15 @@ config ARCH_TEXT_BASE
 	default 0x80e80000 if MACH_OMAP343xSDP
 	default 0x80e80000 if MACH_BEAGLE
 
+config AM33XX_NET_BOOT
+	bool "enable AM335x network boot"
+	select ENVIRONMENT_VARIABLES
+	select NET_DHCP
+	select FS_TFTP
+	select DRIVER_NET_CPSW
+	default n
+	depends on ARCH_AM33XX && NET
+
 config OMAP4_USBBOOT
 	bool "enable booting from USB"
 	default n
diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c
index ee30351..7ce32f0 100644
--- a/arch/arm/mach-omap/am33xx_generic.c
+++ b/arch/arm/mach-omap/am33xx_generic.c
@@ -145,6 +145,9 @@ static int am33xx_bootsource(void)
 	case 0x44:
 		src = BOOTSOURCE_USB;
 		break;
+	case 0x46:
+		src = BOOTSOURCE_NET;
+		break;
 	default:
 		src = BOOTSOURCE_UNKNOWN;
 	}
diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
index 7c8c350..08490ce 100644
--- a/arch/arm/mach-omap/xload.c
+++ b/arch/arm/mach-omap/xload.c
@@ -13,6 +13,10 @@
 #include <filetype.h>
 #include <xymodem.h>
 #include <mach/generic.h>
+#include <mach/am33xx-generic.h>
+#include <net.h>
+#include <environment.h>
+#include <dhcp.h>
 
 struct omap_barebox_part *barebox_part;
 
@@ -126,7 +130,6 @@ static void *omap_xload_boot_mmc(void)
 		printf("could not read barebox.bin from sd card\n");
 		return NULL;
 	}
-
 	return buf;
 }
 
@@ -224,6 +227,45 @@ static void *omap_serial_boot(void){
 	return buf;
 }
 
+static void *am33xx_net_boot(void)
+{
+	void *buf = NULL;
+	int err;
+	int len;
+	struct dhcp_req_param dhcp_param;
+	const char *bootfile;
+
+	am33xx_register_ethaddr(0, 0);
+
+	memset(&dhcp_param, 0, sizeof(struct dhcp_req_param));
+	dhcp_param.vendor_id = "am335x barebox-mlo";
+	err = dhcp(20, &dhcp_param);
+	if (err) {
+		printf("dhcp failed\n");
+		return NULL;
+	}
+
+	err = mount(ip_to_string(net_get_serverip()), "tftp", "/", NULL);
+	if (err < 0) {
+		printf("Unable to mount.\n");
+		return NULL;
+	}
+
+	bootfile = getenv("bootfile");
+	if (!bootfile) {
+		printf("bootfile not found.\n");
+		return NULL;
+	}
+
+	buf = read_file(bootfile, &len);
+	if (!buf)
+		printf("could not read %s.\n", bootfile);
+
+	umount("/");
+
+	return buf;
+}
+
 /*
  * Replaces the default shell in xload configuration
  */
@@ -264,6 +306,14 @@ static __noreturn int omap_xload(void)
 			func = omap_serial_boot();
 			break;
 		}
+	case BOOTSOURCE_NET:
+		if (IS_ENABLED(CONFIG_AM33XX_NET_BOOT)) {
+			printf("booting from NET\n");
+			func = am33xx_net_boot();
+			break;
+		} else {
+			printf("booting from network not enabled\n");
+		}
 	default:
 		printf("unknown boot source. Fall back to nand\n");
 		func = omap_xload_boot_nand(barebox_part->nand_offset,
-- 
1.9.1



From w.egorov at phytec.de  Fri May 22 05:11:17 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Fri, 22 May 2015 14:11:17 +0200
Subject: [RFC 2/3] net: dhcp: Split dhcp funcionality & add dhcp command
In-Reply-To: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
References: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432296678-375-2-git-send-email-w.egorov@phytec.de>

dhcp/bootp was bound to the command functionality.
This patch splits the dhcp command.
We are now able to use bootp without a shell.

This patch adds also a check for environment variables and globalvar.
So only when ENVIRONMENT_VARIABLES and GLOBALVAR is set, all received
dhcp data will be stored.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 commands/Kconfig  |   1 +
 commands/Makefile |   1 +
 commands/dhcp.c   |  77 +++++++++++++++++++++++++
 include/dhcp.h    |  23 ++++++++
 net/Kconfig       |   4 ++
 net/Makefile      |   2 +-
 net/dhcp.c        | 164 +++++++++++++++++++++---------------------------------
 7 files changed, 171 insertions(+), 101 deletions(-)
 create mode 100644 commands/dhcp.c
 create mode 100644 include/dhcp.h

diff --git a/commands/Kconfig b/commands/Kconfig
index 847ff76..102c3cc 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -1183,6 +1183,7 @@ menu "Network"
 
 config CMD_DHCP
 	bool
+	depends on NET_DHCP
 	prompt "dhcp"
 	help
 	  DHCP client to obtain IP or boot params
diff --git a/commands/Makefile b/commands/Makefile
index b902f58..3698347 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -111,3 +111,4 @@ obj-$(CONFIG_CMD_CMP)		+= cmp.o
 obj-$(CONFIG_CMD_NV)		+= nv.o
 obj-$(CONFIG_CMD_DEFAULTENV)	+= defaultenv.o
 obj-$(CONFIG_CMD_STATE)		+= state.o
+obj-$(CONFIG_CMD_DHCP)		+= dhcp.o
diff --git a/commands/dhcp.c b/commands/dhcp.c
new file mode 100644
index 0000000..9bad9d8
--- /dev/null
+++ b/commands/dhcp.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * Based on work of Sascha Hauer <s.hauer 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+#include <environment.h>
+#include <getopt.h>
+#include <dhcp.h>
+
+static int do_dhcp(int argc, char *argv[])
+{
+	int ret, opt;
+	int retries = DHCP_DEFAULT_RETRY;
+	struct dhcp_req_param dhcp_param;
+
+	getenv_uint("global.dhcp.retries", &retries);
+
+	while ((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
+		switch (opt) {
+		case 'H':
+			dhcp_param.hostname = optarg;
+			break;
+		case 'v':
+			dhcp_param.vendor_id = optarg;
+			break;
+		case 'c':
+			dhcp_param.client_id = optarg;
+			break;
+		case 'u':
+			dhcp_param.client_uuid = optarg;
+			break;
+		case 'U':
+			dhcp_param.user_class = optarg;
+			break;
+		case 'r':
+			retries = simple_strtoul(optarg, NULL, 10);
+			break;
+		}
+	}
+
+	if (!retries) {
+		printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
+		retries = DHCP_DEFAULT_RETRY;
+	}
+
+	ret = dhcp(retries, &dhcp_param);
+
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(dhcp)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-H HOSTNAME", "hostname to send to the DHCP server")
+BAREBOX_CMD_HELP_OPT("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-r RETRY", "retry limit (default 20)");
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(dhcp)
+	.cmd		= do_dhcp,
+	BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params")
+	BAREBOX_CMD_OPTS("[-HvcuUr]")
+	BAREBOX_CMD_GROUP(CMD_GRP_NET)
+	BAREBOX_CMD_HELP(cmd_dhcp_help)
+	BAREBOX_CMD_COMPLETE(empty_complete)
+BAREBOX_CMD_END
diff --git a/include/dhcp.h b/include/dhcp.h
new file mode 100644
index 0000000..2ed11da
--- /dev/null
+++ b/include/dhcp.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DHCP_H__
+#define __DHCP_H__
+
+struct dhcp_req_param {
+	char *hostname;
+	char *vendor_id;
+	char *client_id;
+	char *user_class;
+	char *client_uuid;
+};
+
+int dhcp(int retries, struct dhcp_req_param *param);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 918d776..a890492 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -22,4 +22,8 @@ config NET_IFUP
 	default y
 	bool
 
+config NET_DHCP
+	bool
+	prompt "dhcp support"
+
 endif
diff --git a/net/Makefile b/net/Makefile
index 907dc28..58bf143 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -1,7 +1,7 @@
 obj-$(CONFIG_NET)	+= eth.o
 obj-$(CONFIG_NET)	+= net.o
 obj-$(CONFIG_NET_NFS)	+= nfs.o
-obj-$(CONFIG_CMD_DHCP)	+= dhcp.o
+obj-$(CONFIG_NET_DHCP)	+= dhcp.o
 obj-$(CONFIG_CMD_PING)	+= ping.o
 obj-$(CONFIG_NET_RESOLV)+= dns.o
 obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o
diff --git a/net/dhcp.c b/net/dhcp.c
index 19a8462..2baba7a 100644
--- a/net/dhcp.c
+++ b/net/dhcp.c
@@ -21,9 +21,9 @@
 #include <getopt.h>
 #include <globalvar.h>
 #include <init.h>
+#include <dhcp.h>
 
 #define DHCP_DEFAULT_RETRY 20
-
 #define OPT_SIZE 312	/* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
 
 struct bootp {
@@ -142,7 +142,8 @@ static void env_ip_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
 	IPaddr_t ip;
 
 	ip = net_read_ip(popt);
-	setenv_ip(opt->barebox_var_name, ip);
+	if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+		setenv_ip(opt->barebox_var_name, ip);
 }
 
 static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
@@ -158,10 +159,9 @@ static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen
 
 	if (opt->copy_only_if_valid && !strlen(tmp))
 		return;
-
-	if (opt->barebox_var_name)
+	if (opt->barebox_var_name && IS_ENABLED(EVIRONMENT_VARIABLES))
 		setenv(opt->barebox_var_name, tmp);
-	if (opt->barebox_dhcp_global)
+	if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
 		dhcp_set_barebox_global(opt->barebox_dhcp_global, tmp);
 
 }
@@ -263,10 +263,10 @@ static int dhcp_set_string_options(struct dhcp_param *param, u8 *e)
 	int str_len;
 	char* str = param->data;
 
-	if (!str && param->barebox_var_name)
+	if (!str && param->barebox_var_name && IS_ENABLED(ENVIRONMENT_VARIABLES))
 		str = (char*)getenv(param->barebox_var_name);
 
-	if (!str && param->barebox_dhcp_global)
+	if (!str && param->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
 		str = (char*)dhcp_get_barebox_global(param->barebox_dhcp_global);
 
 	if (!str)
@@ -391,8 +391,10 @@ static void bootp_copy_net_params(struct bootp *bp)
 		net_set_serverip(tmp_ip);
 
 	if (strlen(bp->bp_file) > 0) {
-		setenv("bootfile", bp->bp_file);
-		dhcp_set_barebox_global("bootfile", bp->bp_file);
+		if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+			setenv("bootfile", bp->bp_file);
+		if (IS_ENABLED(CONFIG_GLOBALVAR))
+			dhcp_set_barebox_global("bootfile", bp->bp_file);
 	}
 
 	debug("bootfile: %s\n", bp->bp_file);
@@ -651,87 +653,27 @@ static void dhcp_reset_env(void)
 		if (!opt->barebox_var_name || opt->copy_only_if_valid)
 			continue;
 
-		setenv(opt->barebox_var_name,"");
-		if (opt->barebox_dhcp_global)
-			dhcp_set_barebox_global(opt->barebox_dhcp_global,"");
-	}
-}
-
-static void dhcp_global_add(const char *var)
-{
-	char * var_global = asprintf("dhcp.%s", var);
-
-	if (!var_global)
-		return;
-
-	globalvar_add_simple(var_global, NULL);
-	free(var_global);
-}
-
-static int dhcp_global_init(void)
-{
-	struct dhcp_opt *opt;
-	struct dhcp_param *param;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
-		opt = &dhcp_options[i];
-
-		if (!opt->barebox_dhcp_global)
-			continue;
-
-		dhcp_global_add(opt->barebox_dhcp_global);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
-		param = &dhcp_params[i];
-
-		if (!param->barebox_dhcp_global)
-			continue;
-
-		dhcp_global_add(param->barebox_dhcp_global);
+		if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+			setenv(opt->barebox_var_name, "");
+		if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
+			dhcp_set_barebox_global(opt->barebox_dhcp_global, "");
 	}
-
-	return 0;
 }
-late_initcall(dhcp_global_init);
 
-static int do_dhcp(int argc, char *argv[])
+int dhcp(int retries, struct dhcp_req_param *param)
 {
-	int ret, opt;
-	int retries = DHCP_DEFAULT_RETRY;
+	int ret = 0;
 
 	dhcp_reset_env();
 
-	getenv_uint("global.dhcp.retries", &retries);
-
-	while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
-		switch(opt) {
-		case 'H':
-			dhcp_set_param_data(DHCP_HOSTNAME, optarg);
-			break;
-		case 'v':
-			dhcp_set_param_data(DHCP_VENDOR_ID, optarg);
-			break;
-		case 'c':
-			dhcp_set_param_data(DHCP_CLIENT_ID, optarg);
-			break;
-		case 'u':
-			dhcp_set_param_data(DHCP_CLIENT_UUID, optarg);
-			break;
-		case 'U':
-			dhcp_set_param_data(DHCP_USER_CLASS, optarg);
-			break;
-		case 'r':
-			retries = simple_strtoul(optarg, NULL, 10);
-			break;
-		}
-	}
+	dhcp_set_param_data(DHCP_HOSTNAME, param->hostname);
+	dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id);
+	dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id);
+	dhcp_set_param_data(DHCP_USER_CLASS, param->user_class);
+	dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid);
 
-	if (!retries) {
-		printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
+	if (!retries)
 		retries = DHCP_DEFAULT_RETRY;
-	}
 
 	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
 	if (IS_ERR(dhcp_con)) {
@@ -781,29 +723,50 @@ out1:
 	net_unregister(dhcp_con);
 out:
 	if (ret)
-		printf("dhcp failed: %s\n", strerror(-ret));
+		debug("dhcp failed: %s\n", strerror(-ret));
 
 	return ret;
 }
 
-BAREBOX_CMD_HELP_START(dhcp)
-BAREBOX_CMD_HELP_TEXT("Options:")
-BAREBOX_CMD_HELP_OPT ("-H HOSTNAME", "hostname to send to the DHCP server")
-BAREBOX_CMD_HELP_OPT ("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-r RETRY", "retry limit (default 20)");
-BAREBOX_CMD_HELP_END
-
-BAREBOX_CMD_START(dhcp)
-	.cmd		= do_dhcp,
-	BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params")
-	BAREBOX_CMD_OPTS("[-HvcuUr]")
-	BAREBOX_CMD_GROUP(CMD_GRP_NET)
-	BAREBOX_CMD_HELP(cmd_dhcp_help)
-	BAREBOX_CMD_COMPLETE(empty_complete)
-BAREBOX_CMD_END
+#ifdef CONFIG_GLOBALVAR
+static void dhcp_global_add(const char *var)
+{
+	char *var_global = asprintf("dhcp.%s", var);
+
+	if (!var_global)
+		return;
+
+	globalvar_add_simple(var_global, NULL);
+	free(var_global);
+}
+
+static int dhcp_global_init(void)
+{
+	struct dhcp_opt *opt;
+	struct dhcp_param *param;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
+		opt = &dhcp_options[i];
+
+		if (!opt->barebox_dhcp_global)
+			continue;
+
+		dhcp_global_add(opt->barebox_dhcp_global);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
+		param = &dhcp_params[i];
+
+		if (!param->barebox_dhcp_global)
+			continue;
+
+		dhcp_global_add(param->barebox_dhcp_global);
+	}
+
+	return 0;
+}
+late_initcall(dhcp_global_init);
 
 BAREBOX_MAGICVAR_NAMED(global_dhcp_bootfile, global.dhcp.bootfile, "bootfile returned from DHCP request");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_rootpath, global.dhcp.rootpath, "rootpath returned from DHCP request");
@@ -814,3 +777,4 @@ BAREBOX_MAGICVAR_NAMED(global_dhcp_user_class, global.dhcp.user_class, "user cla
 BAREBOX_MAGICVAR_NAMED(global_dhcp_tftp_server_name, global.dhcp.tftp_server_name, "TFTP server Name returned from DHCP request");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_oftree_file, global.dhcp.oftree_file, "OF tree returned from DHCP request (option 224)");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_retries, global.dhcp.retries, "retry limit");
+#endif
-- 
1.9.1



From andrew.smirnov at gmail.com  Sat May 23 11:13:03 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat, 23 May 2015 11:13:03 -0700
Subject: [PATCH 06/10] common: pbl: Allow boards to override hang()
In-Reply-To: <20150515052521.GI6325@pengutronix.de>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-6-git-send-email-andrew.smirnov@gmail.com>
 <20150515052521.GI6325@pengutronix.de>
Message-ID: <CAHQ1cqFrdyqvw3OKgPKup3dGanOmt8AqhC=N+p7ph=J9nR4n6g@mail.gmail.com>

On Thu, May 14, 2015 at 10:25 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Andrey,
>
> On Wed, May 13, 2015 at 07:54:23PM -0700, Andrey Smirnov wrote:
>> Add provisions such that board code can re-define the behaviour of
>> hang() to implement a behaviour better suited for a particular
>> hardware platform.
>
> I'm generally fine with being able to overwrite hang(), but the ARM
> specific changes here should be an extra patch with an explanation why
> this change is necessary. I assume you want to make hang() usable
> for early debugging in the PBL when the code is not running at the
> address it's linked at. But that's only an assumption.
>

You are correct in your assumption. I'll split the patch in the next
version of the series.


> 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 andrew.smirnov at gmail.com  Sat May 23 11:20:55 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat, 23 May 2015 11:20:55 -0700
Subject: [PATCH 01/10] common/memtest.c: Fix incorrect array boundary check
In-Reply-To: <20150515053325.GJ6325@pengutronix.de>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <20150515053325.GJ6325@pengutronix.de>
Message-ID: <CAHQ1cqFseav5dbRv_uxLX0me4V1Tjn2p8kHvKMPiQi6DLcmNrQ@mail.gmail.com>

On Thu, May 14, 2015 at 10:33 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> On Wed, May 13, 2015 at 07:54:18PM -0700, Andrey Smirnov wrote:
>> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
>> ---
>>  common/memtest.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>
>
> I have applied the memtest patches for now. I'll come to the PBL console
> input patches next week when I find some time. I think I haven't made my
> mind yet whether we really want to have input support in PBL and where
> this all leads to. We use functions which were originally meant for
> debugging to do regular output with PBL console support. Maybe we should
> clean this up and introduce some real early console backend rather than
> abusing the debugging functions before we add more features to it.
>

I agree that it seems to start to look like too much of a code
duplication, FWIW, my main intention with adding input support to PBL
was to allow for more interactivity in hang() handler(like being able
to send a very primitive command to reset the board, instead of
relying on external reset circuitry). I am not sure how this can be
improved, so if you have any ideas of how to better introduce the same
functionality I'll be happy to help on implementing it.

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


From andrew.smirnov at gmail.com  Sat May 23 11:48:41 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sat, 23 May 2015 11:48:41 -0700
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <20150519070613.GX6325@pengutronix.de>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
 <20150519070613.GX6325@pengutronix.de>
Message-ID: <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>

On Tue, May 19, 2015 at 12:06 AM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Andrey,
>
> On Wed, May 13, 2015 at 07:54:27PM -0700, Andrey Smirnov wrote:
>> Add an option to perform DRAM region validation before using it. The
>> framework allows individual boards to set up a memory validaion hook
>> that would be called prior to Barebox using that region of memory.
>>
>> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
>
> What usecase do you have for this patch?

The usecase is to be able to have a hardware verification build of the
boot-loader which can be used to test the boards in manufacturing.

> Is it debugging or something  you always want to enable on your hardware?

I need it to be always enabled only in a special build of the BL.

> Why must the validate_memory_range function be board specific?

Because the choice of a memory validation algorithm depends on many factors:
- Speed vs. how extensive you want your tests to be
- Chosen memory fault model (DDR vs. SRAM would be different)
- etc.

Also various memory controllers also might various degree of low level
control so some might allow the developer to flip more switches and
test more corner cases.

>
> I see that you call validate_memory_range on potentially large areas of
> memory, so I wonder if you can't call validate_memory_range from your
> board setup code with the complete memory instead.

Even with the current algorithm implemented in mem_test() (which ,
having read a number of academic papers on memory testing, I don't
believe is comprehensible enough) testing any significant of memory
takes a very noticeable amount of time. I wanted to spend as little
amount of time without having access to extended Barebox functionality
to communicate with the rest of the world(like networking, proper
serial) as possible so I set up the algorithm the way it is and
configured Barebox to have a small(3MB) heap.

Also, testing all of the memory in PBL code brings up the question of
what is the point of 'memtest' command? If the only comprehensive way
of testing memory is in PBL code than, IMHO, that function is not very
useful.

> I am not very fond of overly using get_runtime_offset to calculate
> pointers. Setting callback functions from early code which does not run
> on its link address is something I really want to avoid.

I agree with you on this point. I don't like that code very much either.

>
> 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 alex.aring at gmail.com  Sat May 23 13:44:30 2015
From: alex.aring at gmail.com (Alexander Aring)
Date: Sat, 23 May 2015 22:44:30 +0200
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
 <20150519070613.GX6325@pengutronix.de>
 <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>
Message-ID: <20150523204429.GA675@omega>

Hi,

On Sat, May 23, 2015 at 11:48:41AM -0700, Andrey Smirnov wrote:
> On Tue, May 19, 2015 at 12:06 AM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > Hi Andrey,
> >
> > On Wed, May 13, 2015 at 07:54:27PM -0700, Andrey Smirnov wrote:
> >> Add an option to perform DRAM region validation before using it. The
> >> framework allows individual boards to set up a memory validaion hook
> >> that would be called prior to Barebox using that region of memory.
> >>
> >> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> >
> > What usecase do you have for this patch?
> 
> The usecase is to be able to have a hardware verification build of the
> boot-loader which can be used to test the boards in manufacturing.
> 
> > Is it debugging or something  you always want to enable on your hardware?
> 
> I need it to be always enabled only in a special build of the BL.
> 
> > Why must the validate_memory_range function be board specific?
> 
> Because the choice of a memory validation algorithm depends on many factors:
> - Speed vs. how extensive you want your tests to be
> - Chosen memory fault model (DDR vs. SRAM would be different)
> - etc.
> 
> Also various memory controllers also might various degree of low level
> control so some might allow the developer to flip more switches and
> test more corner cases.
> 
> >
> > I see that you call validate_memory_range on potentially large areas of
> > memory, so I wonder if you can't call validate_memory_range from your
> > board setup code with the complete memory instead.
> 
> Even with the current algorithm implemented in mem_test() (which ,
> having read a number of academic papers on memory testing, I don't
> believe is comprehensible enough) testing any significant of memory
> takes a very noticeable amount of time. I wanted to spend as little
> amount of time without having access to extended Barebox functionality
> to communicate with the rest of the world(like networking, proper
> serial) as possible so I set up the algorithm the way it is and
> configured Barebox to have a small(3MB) heap.
> 
> Also, testing all of the memory in PBL code brings up the question of
> what is the point of 'memtest' command? If the only comprehensive way

The memtest command enable/disable caches and running the memtest
function. The memtest function is moslty the same like it was when I
touched the code, it's original taken from u-boot code [0]. The memtest
will run on all memory space which is not allocated by barebox
automatically, the command before had some simple "start" and "end"
address parameters and you had some luck if you doesn't hit any core
functionality of barebox.

> of testing memory is in PBL code than, IMHO, that function is not very
> useful.
> 

The memtest function or the memtest command? If I remember correctly
then the memtest function was exported out of memtest command exactly
for the reason to use it in PBL or anywhere for debugging. The memtest
command is just simple to use.

- Alex

[0] http://git.denx.de/?p=u-boot.git;a=blob;f=common/cmd_mem.c;h=2e85d53dd23c02902b6e4973ad3cb2e98bbda678;hb=HEAD#l711


From mkl at pengutronix.de  Sat May 23 13:52:20 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sat, 23 May 2015 22:52:20 +0200
Subject: [PATCH 2/2] commands/Kconfig: fix typo in CMD_BOOTM_OFTREE help
In-Reply-To: <1432414340-6271-1-git-send-email-mkl@pengutronix.de>
References: <1432414340-6271-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432414340-6271-2-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 commands/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/commands/Kconfig b/commands/Kconfig
index 847ff76d1d8b..25c77a85c5dc 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -385,7 +385,7 @@ config CMD_BOOTM_OFTREE
 	  Add support to pass a device tree (a.k.a Open Firmware Tree, oftree). Adds
 	  this command line option:
 
-	  -o DTS  specify device tre
+	  -o DTS  specify device tree
 
 config CMD_BOOTM_OFTREE_UIMAGE
 	bool
-- 
2.1.4



From mkl at pengutronix.de  Sat May 23 13:52:19 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sat, 23 May 2015 22:52:19 +0200
Subject: [PATCH 1/2] bootm: add magicvar description for global.bootm.oftree
Message-ID: <1432414340-6271-1-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 commands/bootm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/commands/bootm.c b/commands/bootm.c
index a65864a6db76..75849a1bac1f 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -183,6 +183,7 @@ BAREBOX_MAGICVAR_NAMED(global_bootm_image, global.bootm.image, "bootm default bo
 BAREBOX_MAGICVAR_NAMED(global_bootm_image_loadaddr, global.bootm.image.loadaddr, "bootm default boot image loadaddr");
 BAREBOX_MAGICVAR_NAMED(global_bootm_initrd, global.bootm.initrd, "bootm default initrd");
 BAREBOX_MAGICVAR_NAMED(global_bootm_initrd_loadaddr, global.bootm.initrd.loadaddr, "bootm default initrd loadaddr");
+BAREBOX_MAGICVAR_NAMED(global_bootm_oftree, global.bootm.oftree, "bootm default oftree");
 
 static struct binfmt_hook binfmt_uimage_hook = {
 	.type = filetype_uimage,
-- 
2.1.4



From mkl at pengutronix.de  Sun May 24 08:46:39 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sun, 24 May 2015 17:46:39 +0200
Subject: [RFC] Keystore design
In-Reply-To: <552B90EA.40801@pengutronix.de>
References: <20150318095930.GT26127@ns203013.ovh.net>
 <552B90EA.40801@pengutronix.de>
Message-ID: <5561F25F.2020201@pengutronix.de>

On 04/13/2015 11:48 AM, Marc Kleine-Budde wrote:
> On 03/18/2015 10:59 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> 	I'm curently looking the implementation for the PKI keystore

Any news from the keystore front? I've patches here to secure the
contents of the state partition by a hmac, so I need an API to request
the shared secret.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150524/38eb7ff7/attachment.sig>

From andrew.smirnov at gmail.com  Sun May 24 11:39:16 2015
From: andrew.smirnov at gmail.com (Andrey Smirnov)
Date: Sun, 24 May 2015 11:39:16 -0700
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <20150523204429.GA675@omega>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
 <20150519070613.GX6325@pengutronix.de>
 <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>
 <20150523204429.GA675@omega>
Message-ID: <CAHQ1cqH-RKa_6FZtKtMMQo_QU-TdA=80kT5CT2+95y5KNaUXPA@mail.gmail.com>

>>
>> Also, testing all of the memory in PBL code brings up the question of
>> what is the point of 'memtest' command? If the only comprehensive way
>
> The memtest command enable/disable caches and running the memtest
> function. The memtest function is moslty the same like it was when I
> touched the code, it's original taken from u-boot code [0]. The memtest
> will run on all memory space which is not allocated by barebox
> automatically, the command before had some simple "start" and "end"
> address parameters and you had some luck if you doesn't hit any core
> functionality of barebox.

I am sorry it looks like I didn't convey my point well enough. I do
understand what the 'memtest' command is doing and I agree that having
arbitrary "start" and "end' points without taking into account what
memory areas are being used internally by Barebox is a recipe for
disaster. At the same time I expects/assume that the majority of the
potential users of that command would be using that command because
they want to perform a full memory test. So what I am trying to say is
because 'memtest' can't really touch reserved memory during
execution(for obvious reasons), unless those regions are explicitly
tested before Barebox starts using them, calling it offers very
limited value(it wouldn't be completely useless, but having big chunks
of untested memory is far from ideal).

>
>> of testing memory is in PBL code than, IMHO, that function is not very
>> useful.
>>
>
> The memtest function or the memtest command? If I remember correctly
> then the memtest function was exported out of memtest command exactly
> for the reason to use it in PBL or anywhere for debugging. The memtest
> command is just simple to use.

I agree that it is very easy to use, but why would you want to use it?
I am having hard time imagining use-case where the user would want to
test only unreserved areas of memory and not need to test anything
else.


>
> - Alex
>
> [0] http://git.denx.de/?p=u-boot.git;a=blob;f=common/cmd_mem.c;h=2e85d53dd23c02902b6e4973ad3cb2e98bbda678;hb=HEAD#l711


From mkl at pengutronix.de  Mon May 25 03:48:44 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 25 May 2015 12:48:44 +0200
Subject: [PATCH] crypto: digest: mark signature argument as const
Message-ID: <1432550924-20953-1-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 crypto/digest.c  | 10 +++++-----
 include/digest.h | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/crypto/digest.c b/crypto/digest.c
index b3f514c8ad73..a90e4ff79f89 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -172,7 +172,7 @@ EXPORT_SYMBOL_GPL(digest_free);
 
 int digest_file_window(struct digest *d, const char *filename,
 		       unsigned char *hash,
-		       unsigned char *sig,
+		       const unsigned char *sig,
 		       ulong start, ulong size)
 {
 	ulong len = 0;
@@ -249,8 +249,8 @@ out:
 EXPORT_SYMBOL_GPL(digest_file_window);
 
 int digest_file(struct digest *d, const char *filename,
-		       unsigned char *hash,
-		       unsigned char *sig)
+		unsigned char *hash,
+		const unsigned char *sig)
 {
 	struct stat st;
 	int ret;
@@ -265,8 +265,8 @@ int digest_file(struct digest *d, const char *filename,
 EXPORT_SYMBOL_GPL(digest_file);
 
 int digest_file_by_name(const char *algo, const char *filename,
-		       unsigned char *hash,
-		       unsigned char *sig)
+			unsigned char *hash,
+			const unsigned char *sig)
 {
 	struct digest *d;
 	int ret;
diff --git a/include/digest.h b/include/digest.h
index 7f8d696eb600..7c6711b32a56 100644
--- a/include/digest.h
+++ b/include/digest.h
@@ -68,14 +68,14 @@ void digest_free(struct digest *d);
 
 int digest_file_window(struct digest *d, const char *filename,
 		       unsigned char *hash,
-		       unsigned char *sig,
+		       const unsigned char *sig,
 		       ulong start, ulong size);
 int digest_file(struct digest *d, const char *filename,
-		       unsigned char *hash,
-		       unsigned char *sig);
+		unsigned char *hash,
+		const unsigned char *sig);
 int digest_file_by_name(const char *algo, const char *filename,
-		       unsigned char *hash,
-		       unsigned char *sig);
+			unsigned char *hash,
+			const unsigned char *sig);
 
 static inline int digest_init(struct digest *d)
 {
-- 
2.1.4



From renaud.barbier at ge.com  Mon May 25 10:47:17 2015
From: renaud.barbier at ge.com (Renaud Barbier)
Date: Mon, 25 May 2015 18:47:17 +0100
Subject: Memtest failed. Error: -22
Message-ID: <55636025.4050508@ge.com>

I just used memtest on a couple of PPC board (freescale mpc8544 and
P1014) and it failed with:

barebox>/ memtest
Memtest failed. Error: -22

This error happens when the space between two regions is smaller than a
page size:
 0x0bf75000 - 0x0ff74fff (size 0x04000000) malloc space
 0x0ff756e8 - 0x0ff7d6e7 (size 0x00008000) stack


In this case, the size - when doing the calculation "size =
PAGE_ALIGN_DOWN(end - start + 1);" - is zero.

The function call ret = alloc_memtest_region(list, start, size);
then fails.

I will not be able to offer a patch until second week of June as I am away.

Renaud.







From s.hauer at pengutronix.de  Mon May 25 23:16:45 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 08:16:45 +0200
Subject: [PATCH 1/2] ARM: dts: Add an am33xx include file for MLO size
 reduction
In-Reply-To: <1432296555-48594-1-git-send-email-w.egorov@phytec.de>
References: <1432296555-48594-1-git-send-email-w.egorov@phytec.de>
Message-ID: <20150526061645.GX6325@pengutronix.de>

On Fri, May 22, 2015 at 02:09:14PM +0200, Wadim Egorov wrote:
> AM335x's MLO size limit is 109K.
> The am33xx.dtsi file adds spare and never used nodes to the dtb.
> With this patch we add a file to remove the unused nodes and reduce the
> size of the dtb.
> 
> Including this file will reduce the lzo packed MLO size about 8K.
> 
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
> ---
>  arch/arm/dts/strip-am33xx.dtsi | 66 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 66 insertions(+)
>  create mode 100644 arch/arm/dts/strip-am33xx.dtsi
> 
> diff --git a/arch/arm/dts/strip-am33xx.dtsi b/arch/arm/dts/strip-am33xx.dtsi

You remove the UARTs not used on *Phytec* boards, they could well be
used on other boards. While I agree for the CAN nodes and many others,
UARTs should be kept. Also the GPIOs can be very useful in the MLO. I
suggest that you either change the name of this file to something less
generic (am33xx-phytec-strip.dtsi) or you make a generic more generic
file and remove the unused UARTs / GPIOs in the board specific dts file.
Whatever you do, please keep the am33xx- at the beginning of the
filename.

Sascha

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


From s.hauer at pengutronix.de  Mon May 25 23:19:28 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 08:19:28 +0200
Subject: [RFC 1/3] bootsource: Add NET bootsource
In-Reply-To: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
References: <1432296678-375-1-git-send-email-w.egorov@phytec.de>
Message-ID: <20150526061928.GY6325@pengutronix.de>

Hi Wadim,

Looks good to me. Since it's marked as RFC I won't apply it, unless you
want me to.

Sascha

On Fri, May 22, 2015 at 02:11:16PM +0200, Wadim Egorov wrote:
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
> ---
>  common/bootsource.c  | 1 +
>  include/bootsource.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/common/bootsource.c b/common/bootsource.c
> index 7f3d51f..707b079 100644
> --- a/common/bootsource.c
> +++ b/common/bootsource.c
> @@ -35,6 +35,7 @@ static const char *bootsource_str[] = {
>  	[BOOTSOURCE_ONENAND] = "onenand",
>  	[BOOTSOURCE_HD] = "harddisk",
>  	[BOOTSOURCE_USB] = "usb",
> +	[BOOTSOURCE_NET] = "net",
>  };
>  
>  static enum bootsource bootsource = BOOTSOURCE_UNKNOWN;
> diff --git a/include/bootsource.h b/include/bootsource.h
> index 4bca9b9..c6d3b3a 100644
> --- a/include/bootsource.h
> +++ b/include/bootsource.h
> @@ -15,6 +15,7 @@ enum bootsource {
>  	BOOTSOURCE_ONENAND,
>  	BOOTSOURCE_HD,
>  	BOOTSOURCE_USB,
> +	BOOTSOURCE_NET,
>  };
>  
>  #define BOOTSOURCE_INSTANCE_UNKNOWN	-1
> -- 
> 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  Mon May 25 23:57:56 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 08:57:56 +0200
Subject: [PATCH 10/10] ARM: pbl: Add an option to validate DRAM
In-Reply-To: <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>
References: <1431572067-4038-1-git-send-email-andrew.smirnov@gmail.com>
 <1431572067-4038-10-git-send-email-andrew.smirnov@gmail.com>
 <20150519070613.GX6325@pengutronix.de>
 <CAHQ1cqECGkwNQp4tgBrj1g6NR01EQHjsbf_omeiN+GPHpaeuhA@mail.gmail.com>
Message-ID: <20150526065756.GZ6325@pengutronix.de>

On Sat, May 23, 2015 at 11:48:41AM -0700, Andrey Smirnov wrote:
> On Tue, May 19, 2015 at 12:06 AM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > Hi Andrey,
> >
> > On Wed, May 13, 2015 at 07:54:27PM -0700, Andrey Smirnov wrote:
> >> Add an option to perform DRAM region validation before using it. The
> >> framework allows individual boards to set up a memory validaion hook
> >> that would be called prior to Barebox using that region of memory.
> >>
> >> Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
> >
> > What usecase do you have for this patch?
> 
> The usecase is to be able to have a hardware verification build of the
> boot-loader which can be used to test the boards in manufacturing.
> 
> > Is it debugging or something  you always want to enable on your hardware?
> 
> I need it to be always enabled only in a special build of the BL.
> 
> > Why must the validate_memory_range function be board specific?
> 
> Because the choice of a memory validation algorithm depends on many factors:
> - Speed vs. how extensive you want your tests to be
> - Chosen memory fault model (DDR vs. SRAM would be different)
> - etc.
> 
> Also various memory controllers also might various degree of low level
> control so some might allow the developer to flip more switches and
> test more corner cases.
> 
> >
> > I see that you call validate_memory_range on potentially large areas of
> > memory, so I wonder if you can't call validate_memory_range from your
> > board setup code with the complete memory instead.
> 
> Even with the current algorithm implemented in mem_test() (which ,
> having read a number of academic papers on memory testing, I don't
> believe is comprehensible enough) testing any significant of memory
> takes a very noticeable amount of time. I wanted to spend as little
> amount of time without having access to extended Barebox functionality
> to communicate with the rest of the world(like networking, proper
> serial) as possible so I set up the algorithm the way it is and
> configured Barebox to have a small(3MB) heap.
> 
> Also, testing all of the memory in PBL code brings up the question of
> what is the point of 'memtest' command? If the only comprehensive way
> of testing memory is in PBL code than, IMHO, that function is not very
> useful.
> 
> > I am not very fond of overly using get_runtime_offset to calculate
> > pointers. Setting callback functions from early code which does not run
> > on its link address is something I really want to avoid.
> 
> I agree with you on this point. I don't like that code very much either.

How about testing only a small fragment of DRAM, say 8MB, in your
lowlevel board code and calling barebox_arm_entry() with the
membase/memsize you previously tested? This way you can make sure that
barebox only uses tested memory without having to test all memory before
calling barebox_arm_entry() and without having to call back into some
testing function.

The newest TLSF implementation also supports pools, so we could add the
full amount of memory later 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 s.hauer at pengutronix.de  Tue May 26 00:19:52 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 09:19:52 +0200
Subject: [PATCH 1/2] bootm: add magicvar description for
 global.bootm.oftree
In-Reply-To: <1432414340-6271-1-git-send-email-mkl@pengutronix.de>
References: <1432414340-6271-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150526071952.GA6325@pengutronix.de>

On Sat, May 23, 2015 at 10:52:19PM +0200, Marc Kleine-Budde wrote:
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  commands/bootm.c | 1 +
>  1 file changed, 1 insertion(+)

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  Tue May 26 00:27:55 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 09:27:55 +0200
Subject: [PATCH] crypto: digest: mark signature argument as const
In-Reply-To: <1432550924-20953-1-git-send-email-mkl@pengutronix.de>
References: <1432550924-20953-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150526072755.GC6325@pengutronix.de>

On Mon, May 25, 2015 at 12:48:44PM +0200, Marc Kleine-Budde wrote:
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  crypto/digest.c  | 10 +++++-----
>  include/digest.h | 10 +++++-----
>  2 files changed, 10 insertions(+), 10 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 alexander.richter at atsonline.de  Tue May 26 02:50:39 2015
From: alexander.richter at atsonline.de (Alexander Richter)
Date: Tue, 26 May 2015 11:50:39 +0200
Subject: bareboxenv - tricky ptxdist behavior
Message-ID: <556441EF.8040702@atsonline.de>

Hallo,

I just used bareboxenv tool in linux userspace after a long troublesome 
trip through ptxdist.
That would not have to be, if the description of "build bareboxenv tool 
for target" in barebox config has said, that i has to enable the tool  
platformconfig.

Perhaps you want to change this behavior or indicate it in the description.

-- 
Alexander Richter


From mkl at pengutronix.de  Tue May 26 04:33:57 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:33:57 +0200
Subject: [PATCH] fixup! state: add fixup to copy state from barebox to kernel
 device tree
Message-ID: <1432640037-31754-1-git-send-email-mkl@pengutronix.de>

During of_state_fixup() we have to write the #address-cells and #size-cells
property of the node we're copying the data to, not the "root" node of the
device tree we're working on.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/state.c b/common/state.c
index cc0e168a7b99..655c9a63e333 100644
--- a/common/state.c
+++ b/common/state.c
@@ -737,11 +737,11 @@ static int of_state_fixup(struct device_node *root, void *ctx)
 		goto out;
 
 	/* address-cells + size-cells */
-	ret = of_property_write_u32(root, "#address-cells", 1);
+	ret = of_property_write_u32(new_node, "#address-cells", 1);
 	if (ret)
 		goto out;
 
-	ret = of_property_write_u32(root, "#size-cells", 1);
+	ret = of_property_write_u32(new_node, "#size-cells", 1);
 	if (ret)
 		goto out;
 
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:46 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:46 +0200
Subject: [PATCH 2/9] state: mtd_get_meminfo: make usage of mtd's meminfo
 compatible to linux
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-3-git-send-email-mkl@pengutronix.de>

This patch makes it possible to share the code with linux.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/state.c b/common/state.c
index c13f7a00c98c..82a21e912206 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1019,7 +1019,7 @@ int state_backend_dtb_file(struct state *state, const char *of_path, const char
 	state->backend = backend;
 
 	ret = mtd_get_meminfo(backend->path, &meminfo);
-	if (!ret && !(meminfo.mtd->flags & MTD_NO_ERASE))
+	if (!ret && !(meminfo.flags & MTD_NO_ERASE))
 		backend_dtb->need_erase = true;
 
 	return 0;
@@ -1268,7 +1268,7 @@ int state_backend_raw_file(struct state *state, const char *of_path,
 	state->backend = backend;
 
 	ret = mtd_get_meminfo(backend->path, &meminfo);
-	if (!ret && !(meminfo.mtd->flags & MTD_NO_ERASE)) {
+	if (!ret && !(meminfo.flags & MTD_NO_ERASE)) {
 		backend_raw->need_erase = true;
 		backend_raw->step = ALIGN(backend_raw->size_full,
 					  meminfo.erasesize);
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:47 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:47 +0200
Subject: [PATCH 3/9] state: backend_raw: remove hard coded limit of two copies
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-4-git-send-email-mkl@pengutronix.de>

Although there is the define RAW_BACKEND_COPIES, the state_backend_raw_save()
function silently assumes exactly two copies. This patch removes that assumtion
by looping over all copies, but saving the one we're read from at the end.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/common/state.c b/common/state.c
index 82a21e912206..79e7f4cc6849 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1167,7 +1167,7 @@ static int state_backend_raw_save(struct state_backend *backend,
 {
 	struct state_backend_raw *backend_raw = container_of(backend,
 			struct state_backend_raw, backend);
-	int ret = 0, size, fd;
+	int ret = 0, size, fd, i;
 	void *buf, *data;
 	struct backend_raw_header *header;
 	struct state_variable *sv;
@@ -1192,10 +1192,17 @@ static int state_backend_raw_save(struct state_backend *backend,
 	if (fd < 0)
 		goto out_free;
 
-	ret = backend_raw_write_one(backend_raw, state, fd,
-				    !backend_raw->num_copy_read, buf, size);
-	if (ret)
-		goto out_close;
+	/* save other slots first */
+	for (i = 0; i < RAW_BACKEND_COPIES; i++) {
+		if (i == backend_raw->num_copy_read)
+			continue;
+
+		ret = backend_raw_write_one(backend_raw, state, fd,
+					    i, buf, size);
+		if (ret)
+			goto out_close;
+
+	}
 
 	ret = backend_raw_write_one(backend_raw, state, fd,
 				    backend_raw->num_copy_read, buf, size);
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:45 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:45 +0200
Subject: [PATCH 1/9] state: mtd_get_meminfo: open path readonly instead of
 readwrite
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-2-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common/state.c b/common/state.c
index cc0e168a7b99..c13f7a00c98c 100644
--- a/common/state.c
+++ b/common/state.c
@@ -900,7 +900,7 @@ static int mtd_get_meminfo(const char *path, struct mtd_info_user *meminfo)
 {
 	int fd, ret;
 
-	fd = open(path, O_RDWR);
+	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		return fd;
 
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:44 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:44 +0200
Subject: [PATCH 0/9] state: updates and cleanups to make code better sharable
 with linux
Message-ID: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>

Hello,

this patch series makes the state code better shareable with linux.

Marc



From mkl at pengutronix.de  Tue May 26 04:37:53 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:53 +0200
Subject: [PATCH 9/9] state: backend_raw: update documentation of struct
 state_backend_raw members
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-10-git-send-email-mkl@pengutronix.de>

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/state.c b/common/state.c
index 4a1e935a3b86..edbfb95fbb5f 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1030,8 +1030,8 @@ int state_backend_dtb_file(struct state *state, const char *of_path, const char
  */
 struct state_backend_raw {
 	struct state_backend backend;
-	unsigned long size_data; /* The raw data size (without magic and crc) */
-	unsigned long size_full;
+	unsigned long size_data; /* The raw data size (without header) */
+	unsigned long size_full; /* The size header + raw data */
 	unsigned long stride; /* The stride size in bytes of the copies */
 	off_t offset; /* offset in the storage file */
 	size_t size; /* size of the storage area */
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:52 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:52 +0200
Subject: [PATCH 8/9] state: backend_raw: add sanity check of data_len during
 load
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-9-git-send-email-mkl@pengutronix.de>

The length of the data must fit into the remaining available space until the
next copy of the data.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/common/state.c b/common/state.c
index 8f6d14c98255..4a1e935a3b86 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1053,14 +1053,18 @@ static int backend_raw_load_one(struct state_backend_raw *backend_raw,
 	uint32_t crc;
 	struct state_variable *sv;
 	struct backend_raw_header header = {};
+	unsigned long max_len;
 	int ret;
 	void *buf;
 
+	max_len = backend_raw->stride;
+
 	ret = lseek(fd, offset, SEEK_SET);
 	if (ret < 0)
 		return ret;
 
 	ret = read_full(fd, &header, sizeof(header));
+	max_len -= sizeof(header);
 	if (ret < 0)
 		return ret;
 
@@ -1079,6 +1083,13 @@ static int backend_raw_load_one(struct state_backend_raw *backend_raw,
 		return -EINVAL;
 	}
 
+	if (header.data_len > max_len) {
+		dev_err(&state->dev,
+			"invalid data_len %u in header, max is %lu\n",
+			header.data_len, max_len);
+		return -EINVAL;
+	}
+
 	buf = xzalloc(header.data_len);
 
 	ret = read_full(fd, buf, header.data_len);
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:48 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:48 +0200
Subject: [PATCH 4/9] state: backend_raw: rename struct state_backend_raw::step
 -> stride
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-5-git-send-email-mkl@pengutronix.de>

This patch renames the member "step" of the struct state_backend_raw to
"stride" and tries to clarifies its meaning.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/common/state.c b/common/state.c
index 79e7f4cc6849..4dae3409049a 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1032,7 +1032,7 @@ struct state_backend_raw {
 	struct state_backend backend;
 	unsigned long size_data; /* The raw data size (without magic and crc) */
 	unsigned long size_full;
-	unsigned long step; /* The step in bytes between two copies */
+	unsigned long stride; /* The stride size in bytes of the copies */
 	off_t offset; /* offset in the storage file */
 	size_t size; /* size of the storage area */
 	int num_copy_read; /* The first successfully read copy */
@@ -1120,7 +1120,7 @@ static int state_backend_raw_load(struct state_backend *backend,
 		return fd;
 
 	for (i = 0; i < RAW_BACKEND_COPIES; i++) {
-		off_t offset = backend_raw->offset + i * backend_raw->step;
+		off_t offset = backend_raw->offset + i * backend_raw->stride;
 
 		ret = backend_raw_load_one(backend_raw, state, fd, offset);
 		if (!ret) {
@@ -1140,7 +1140,7 @@ static int backend_raw_write_one(struct state_backend_raw *backend_raw,
 		struct state *state, int fd, int num, void *buf, size_t size)
 {
 	int ret;
-	off_t offset = backend_raw->offset + num * backend_raw->step;
+	off_t offset = backend_raw->offset + num * backend_raw->stride;
 
 	dev_dbg(&state->dev, "%s: 0x%08lx 0x%08zx\n",
 			__func__, offset, size);
@@ -1277,15 +1277,15 @@ int state_backend_raw_file(struct state *state, const char *of_path,
 	ret = mtd_get_meminfo(backend->path, &meminfo);
 	if (!ret && !(meminfo.flags & MTD_NO_ERASE)) {
 		backend_raw->need_erase = true;
-		backend_raw->step = ALIGN(backend_raw->size_full,
-					  meminfo.erasesize);
+		backend_raw->stride = ALIGN(backend_raw->size_full,
+					    meminfo.erasesize);
 		dev_dbg(&state->dev, "is a mtd, adjust stepsize to %ld\n",
-			backend_raw->step);
+			backend_raw->stride);
 	} else {
-		backend_raw->step = backend_raw->size_full;
+		backend_raw->stride = backend_raw->size_full;
 	}
 
-	if (backend_raw->size / backend_raw->step < RAW_BACKEND_COPIES) {
+	if (backend_raw->size / backend_raw->stride < RAW_BACKEND_COPIES) {
 		dev_err(&state->dev, "not enough space for two copies\n");
 		ret = -ENOSPC;
 		goto err;
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:49 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:49 +0200
Subject: [PATCH 5/9] state: backend_raw: properly align write and erase size
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-6-git-send-email-mkl@pengutronix.de>

This patch makes it easier to share the code with linux, on Linux the ease and
write size have to be aligned. Use stride (which is already aligned to erase
block size) during erase, align size_full to writesize and use it while
writing.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/common/state.c b/common/state.c
index 4dae3409049a..7e5a31ae00a5 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1150,7 +1150,7 @@ static int backend_raw_write_one(struct state_backend_raw *backend_raw,
 		return ret;
 
 	if (backend_raw->need_erase) {
-		ret = erase(fd, backend_raw->size_full, offset);
+		ret = erase(fd, backend_raw->stride, offset);
 		if (ret)
 			return ret;
 	}
@@ -1167,14 +1167,12 @@ static int state_backend_raw_save(struct state_backend *backend,
 {
 	struct state_backend_raw *backend_raw = container_of(backend,
 			struct state_backend_raw, backend);
-	int ret = 0, size, fd, i;
+	int ret = 0, fd, i;
 	void *buf, *data;
 	struct backend_raw_header *header;
 	struct state_variable *sv;
 
-	size = backend_raw->size_data + sizeof(struct backend_raw_header);
-
-	buf = xzalloc(size);
+	buf = xzalloc(backend_raw->size_full);
 
 	header = buf;
 	data = buf + sizeof(*header);
@@ -1198,14 +1196,14 @@ static int state_backend_raw_save(struct state_backend *backend,
 			continue;
 
 		ret = backend_raw_write_one(backend_raw, state, fd,
-					    i, buf, size);
+					    i, buf, backend_raw->size_full);
 		if (ret)
 			goto out_close;
 
 	}
 
 	ret = backend_raw_write_one(backend_raw, state, fd,
-				    backend_raw->num_copy_read, buf, size);
+				    backend_raw->num_copy_read, buf, backend_raw->size_full);
 	if (ret)
 		goto out_close;
 
@@ -1277,6 +1275,8 @@ int state_backend_raw_file(struct state *state, const char *of_path,
 	ret = mtd_get_meminfo(backend->path, &meminfo);
 	if (!ret && !(meminfo.flags & MTD_NO_ERASE)) {
 		backend_raw->need_erase = true;
+		backend_raw->size_full = ALIGN(backend_raw->size_full,
+					       meminfo.writesize);
 		backend_raw->stride = ALIGN(backend_raw->size_full,
 					    meminfo.erasesize);
 		dev_dbg(&state->dev, "is a mtd, adjust stepsize to %ld\n",
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:51 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:51 +0200
Subject: [PATCH 7/9] state: backend_raw: rename backend_raw_write_one() ->
 backend_raw_save_one()
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-8-git-send-email-mkl@pengutronix.de>

Use a consistent naming scheme: backend_raw_save_one() is called from
backend_raw_save().

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/common/state.c b/common/state.c
index 749c8e906851..8f6d14c98255 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1136,7 +1136,7 @@ static int state_backend_raw_load(struct state_backend *backend,
 	return ret;
 }
 
-static int backend_raw_write_one(struct state_backend_raw *backend_raw,
+static int backend_raw_save_one(struct state_backend_raw *backend_raw,
 		struct state *state, int fd, int num, void *buf, size_t size)
 {
 	int ret;
@@ -1195,15 +1195,15 @@ static int state_backend_raw_save(struct state_backend *backend,
 		if (i == backend_raw->num_copy_read)
 			continue;
 
-		ret = backend_raw_write_one(backend_raw, state, fd,
-					    i, buf, backend_raw->size_full);
+		ret = backend_raw_save_one(backend_raw, state, fd,
+					   i, buf, backend_raw->size_full);
 		if (ret)
 			goto out_close;
 
 	}
 
-	ret = backend_raw_write_one(backend_raw, state, fd,
-				    backend_raw->num_copy_read, buf, backend_raw->size_full);
+	ret = backend_raw_save_one(backend_raw, state, fd,
+				   backend_raw->num_copy_read, buf, backend_raw->size_full);
 	if (ret)
 		goto out_close;
 
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 04:37:50 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 13:37:50 +0200
Subject: [PATCH 6/9] state: backend_raw: factor out
 state_backend_raw_file_get_size() into separate function
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432640273-3895-7-git-send-email-mkl@pengutronix.de>

This patch factors out the state_backend_raw_file_get_size() into a separate
function and adds some ifdefs to make this code work under Linux aswell.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/state.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 64 insertions(+), 9 deletions(-)

diff --git a/common/state.c b/common/state.c
index 7e5a31ae00a5..749c8e906851 100644
--- a/common/state.c
+++ b/common/state.c
@@ -1216,6 +1216,60 @@ out_free:
 	return ret;
 }
 
+#ifdef __BAREBOX__
+#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode) || S_ISCHR(s.st_mode))
+#define BLKGET_GIVES_SIZE(s) 0
+#ifndef BLKGETSIZE64
+#define BLKGETSIZE64 -1
+#endif
+#else
+#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode))
+#define BLKGET_GIVES_SIZE(s) (S_ISBLK(s.st_mode))
+#endif
+
+static int state_backend_raw_file_get_size(const char *path, size_t *out_size)
+{
+	struct mtd_info_user meminfo;
+	struct stat s;
+	int ret;
+
+	ret = stat(path, &s);
+	if (ret)
+		return -errno;
+
+	/*
+	 * under Linux, stat() gives the size only on regular files
+	 * under barebox, it works on char dev, too
+	 */
+	if (STAT_GIVES_SIZE(s)) {
+		*out_size = s.st_size;
+		return 0;
+	}
+
+	/* this works under Linux on block devs */
+	if (BLKGET_GIVES_SIZE(s)) {
+		int fd;
+
+		fd = open(path, O_RDONLY);
+		if (fd < 0)
+			return -errno;
+
+		ret = ioctl(fd, BLKGETSIZE64, out_size);
+		close(fd);
+		if (!ret)
+			return 0;
+	}
+
+	/* try mtd next */
+	ret = mtd_get_meminfo(path, &meminfo);
+	if (!ret) {
+		*out_size = meminfo.size;
+		return 0;
+	}
+
+	return ret;
+}
+
 /*
  * state_backend_raw_file - create a raw file backend store for a state instance
  *
@@ -1239,20 +1293,21 @@ int state_backend_raw_file(struct state *state, const char *of_path,
 	struct state_backend_raw *backend_raw;
 	struct state_backend *backend;
 	struct state_variable *sv;
-	int ret;
-	struct stat s;
 	struct mtd_info_user meminfo;
+	size_t path_size = 0;
+	int ret;
 
 	if (state->backend)
 		return -EBUSY;
 
-	ret = stat(path, &s);
-	if (!ret && S_ISCHR(s.st_mode)) {
-		if (size == 0)
-			size = s.st_size;
-		else if (offset + size > s.st_size)
-			return -EINVAL;
-	}
+	ret = state_backend_raw_file_get_size(path, &path_size);
+	if (ret)
+		return ret;
+
+	if (size == 0)
+		size = path_size;
+	else if (offset + size > path_size)
+		return -EINVAL;
 
 	backend_raw = xzalloc(sizeof(*backend_raw));
 	backend = &backend_raw->backend;
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 26 05:22:04 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 14:22:04 +0200
Subject: [PATCH] fixup! state: add fixup to copy state from barebox to
 kernel device tree
In-Reply-To: <1432640037-31754-1-git-send-email-mkl@pengutronix.de>
References: <1432640037-31754-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150526122204.GJ6325@pengutronix.de>

On Tue, May 26, 2015 at 01:33:57PM +0200, Marc Kleine-Budde wrote:
> During of_state_fixup() we have to write the #address-cells and #size-cells
> property of the node we're copying the data to, not the "root" node of the
> device tree we're working on.
> 
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  common/state.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 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  Tue May 26 05:33:59 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 14:33:59 +0200
Subject: [PATCH 0/9] state: updates and cleanups to make code better
 sharable with linux
In-Reply-To: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
References: <1432640273-3895-1-git-send-email-mkl@pengutronix.de>
Message-ID: <20150526123359.GK6325@pengutronix.de>

On Tue, May 26, 2015 at 01:37:44PM +0200, Marc Kleine-Budde wrote:
> Hello,
> 
> this patch series makes the state code better shareable with linux.

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 mkl at pengutronix.de  Tue May 26 05:46:19 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 14:46:19 +0200
Subject: [PATCH 0/2] blspec: improvements
Message-ID: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>

Hello,

the barebox version I'm currently working on has these two patches applied
making booting a bit easier. Are there better options to archive the same goal?

Marc



From mkl at pengutronix.de  Tue May 26 05:46:20 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 14:46:20 +0200
Subject: [PATCH 1/2] blspec: honour default/once entries again and move them
 to a different place
In-Reply-To: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>
References: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432644381-29474-2-git-send-email-mkl@pengutronix.de>

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

Support for default/once entries was lost earlier. This fixes this
and also looks for default/once entries in the loader directory instead
of the loader parent directory. This keeps the bootloader spec files
together under a common loader directory.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/blspec.c          | 35 ++++++++++++++++++++++++++++-------
 scripts/kernel-install.c |  2 +-
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/common/blspec.c b/common/blspec.c
index 3506388eb5fb..11e2a8a53698 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -308,6 +308,29 @@ out:
 	return ret;
 }
 
+static char *read_default_once(const char *root, const char *name)
+{
+	char *str, *res;
+
+	/* Compat: default/once was under root directly */
+	str = read_file_line("%s/%s", root, name);
+
+	if (!str)
+		str = read_file_line("%s/loader/%s", root, name);
+
+	if (!str)
+		return NULL;
+
+	res = strrchr(str, '/');
+	if (!res)
+		return str;
+
+	res = xstrdup(res);
+	free(str);
+
+	return res;
+}
+
 /*
  * blspec_scan_directory - scan over a directory
  *
@@ -323,7 +346,7 @@ int blspec_scan_directory(struct blspec *blspec, const char *root)
 	char *abspath;
 	int ret, found = 0;
 	const char *dirname = "loader/entries";
-	char *entry_default = NULL, *entry_once = NULL, *name, *nfspath = NULL;
+	char *entry_default = NULL, *entry_once = NULL, *nfspath = NULL;
 
 	nfspath = parse_nfs_url(root);
 	if (!IS_ERR(nfspath))
@@ -331,8 +354,8 @@ int blspec_scan_directory(struct blspec *blspec, const char *root)
 
 	pr_info("%s: %s %s\n", __func__, root, dirname);
 
-	entry_default = read_file_line("%s/default", root);
-	entry_once = read_file_line("%s/once", root);
+	entry_default = read_default_once(root, "default");
+	entry_once = read_default_once(root, "once");
 
 	abspath = asprintf("%s/%s", root, dirname);
 
@@ -398,12 +421,10 @@ int blspec_scan_directory(struct blspec *blspec, const char *root)
 
 		found++;
 
-		name = asprintf("%s/%s", dirname, d->d_name);
-		if (entry_default && !strcmp(name, entry_default))
+		if (entry_default && !strcmp(d->d_name, entry_default))
 			entry->boot_default = true;
-		if (entry_once && !strcmp(name, entry_once))
+		if (entry_once && !strcmp(d->d_name, entry_once))
 			entry->boot_once = true;
-		free(name);
 
 		if (entry->cdev) {
 			devname = xstrdup(dev_name(entry->cdev->dev));
diff --git a/scripts/kernel-install.c b/scripts/kernel-install.c
index d943f0288f39..d26864066583 100644
--- a/scripts/kernel-install.c
+++ b/scripts/kernel-install.c
@@ -1118,7 +1118,7 @@ static int do_set_once_default(const char *name, int entry)
 		return -errno;
 	}
 
-	dprintf(fd, "loader/entries/%s\n", e->config_file);
+	dprintf(fd, "%s\n", e->config_file);
 
 	ret = close(fd);
 	if (ret)
-- 
2.1.4



From mkl at pengutronix.de  Tue May 26 05:46:21 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Tue, 26 May 2015 14:46:21 +0200
Subject: [PATCH 2/2] blspec: automatically append bootargs
In-Reply-To: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>
References: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>
Message-ID: <1432644381-29474-3-git-send-email-mkl@pengutronix.de>

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

When bootloader spec is used to boot devices it is often desirable
to boot the same image from different media. Since the fs images
need to contain the root= parameters to tell Linux where to boot
from the images can't be identical on different media.

This patch changes this by introducing a 'appendroot' option for
bootloader spec. If set to true, barebox will construct a Linux
commandline option for the device the bootloader spec entry is found
on.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 common/blspec.c         | 41 ++++++++++++++++++++++++++++++++++++++++-
 drivers/mtd/ubi/kapi.c  |  1 +
 fs/fs.c                 | 13 +++++++++++++
 fs/nfs.c                | 16 ++++++++++++++++
 fs/ubifs/ubifs.c        | 23 +++++++++++++++++++++++
 include/fs.h            |  1 +
 include/linux/mtd/ubi.h |  1 +
 7 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/common/blspec.c b/common/blspec.c
index 11e2a8a53698..c3f0a3138d43 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -622,6 +622,41 @@ int blspec_scan_devicename(struct blspec *blspec, const char *devname)
 	return blspec_scan_device(blspec, dev);
 }
 
+static int blspec_append_root(struct blspec_entry *entry)
+{
+	const char *appendroot;
+	const char *rootarg;
+	struct device_d *fsdev;
+	int ret;
+
+	appendroot = blspec_entry_var_get(entry, "appendroot");
+	if (!appendroot || strcmp(appendroot, "true"))
+		return 0;
+
+	fsdev = get_dev_by_mountpath(entry->rootpath);
+	if (!fsdev) {
+		ret = -EINVAL;
+		pr_err("Cannot get fs device for %s\n", entry->rootpath);
+		goto err_out;
+	}
+
+	rootarg = dev_get_param(fsdev, "linux.bootargs");
+	if (!rootarg) {
+		ret = -EINVAL;
+		pr_err("rootarg not implemented for fs %s\n", dev_name(fsdev));
+		goto err_out;
+	}
+
+	globalvar_add_simple("linux.bootargs.dyn.blspec.appendroot", rootarg);
+
+	return 0;
+
+err_out:
+	pr_err("unable to append root argument\n");
+
+	return ret;
+}
+
 /*
  * blspec_boot - boot an entry
  *
@@ -671,6 +706,10 @@ int blspec_boot(struct blspec_entry *entry, int verbose, int dryrun)
 
 	globalvar_add_simple("linux.bootargs.dyn.blspec", options);
 
+	ret = blspec_append_root(entry);
+	if (ret)
+		goto err_out;
+
 	pr_info("booting %s from %s\n", blspec_entry_var_get(entry, "title"),
 			entry->cdev ? dev_name(entry->cdev->dev) : "none");
 
@@ -689,7 +728,7 @@ int blspec_boot(struct blspec_entry *entry, int verbose, int dryrun)
 	ret = bootm_boot(&data);
 	if (ret)
 		pr_err("Booting failed\n");
-
+err_out:
 	free((char *)data.oftree_file);
 	free((char *)data.initrd_file);
 	free((char *)data.os_file);
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 08cb8dd7e0e7..7fc1aa8d70cc 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -36,6 +36,7 @@ void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
 	di->min_io_size = ubi->min_io_size;
 	di->max_write_size = ubi->max_write_size;
 	di->ro_mode = ubi->ro_mode;
+	di->mtd = ubi->mtd;
 }
 EXPORT_SYMBOL_GPL(ubi_do_get_device_info);
 
diff --git a/fs/fs.c b/fs/fs.c
index a056d83d3d92..b8d3d3468f01 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -225,6 +225,19 @@ struct cdev *get_cdev_by_mountpath(const char *path)
 	return fsdev->cdev;
 }
 
+/*
+ * get_cdev_by_mountpath - return the cdev the given path
+ *                         is mounted on
+ */
+struct device_d *get_dev_by_mountpath(const char *path)
+{
+	struct fs_device_d *fsdev;
+
+	fsdev = get_fsdevice_by_path(path);
+
+	return &fsdev->dev;
+}
+
 char *get_mounted_path(const char *path)
 {
 	struct fs_device_d *fdev;
diff --git a/fs/nfs.c b/fs/nfs.c
index 2738c781d72b..ba00270a8b23 100644
--- a/fs/nfs.c
+++ b/fs/nfs.c
@@ -1306,6 +1306,20 @@ static int nfs_stat(struct device_d *dev, const char *filename, struct stat *s)
 	}
 }
 
+static void nfs_set_rootarg(struct nfs_priv *npriv, struct device_d *dev)
+{
+	char *str;
+	const char *ip;
+
+	ip = ip_to_string(npriv->server);
+	str = asprintf("root=/dev/nfs nfsroot=%s:%s,v3,tcp",
+			ip, npriv->path);
+
+	dev_add_param_fixed(dev, "linux.bootargs", str);
+
+	free(str);
+}
+
 static int nfs_probe(struct device_d *dev)
 {
 	struct fs_device_d *fsdev = dev_to_fs_device(dev);
@@ -1369,6 +1383,8 @@ static int nfs_probe(struct device_d *dev)
 		goto err2;
 	}
 
+	nfs_set_rootarg(npriv, dev);
+
 	free(tmp);
 
 	return 0;
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index 68d90b36e75a..48a68372d062 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -36,6 +36,7 @@
 #include <linux/zlib.h>
 #include <xfuncs.h>
 #include <fcntl.h>
+#include <linux/mtd/mtd.h>
 
 #include "ubifs.h"
 
@@ -584,6 +585,26 @@ static int ubifs_readlink(struct device_d *dev, const char *pathname, char *buf,
 	return 0;
 }
 
+static void ubifs_set_rootarg(struct ubifs_priv *priv, struct device_d *dev)
+{
+	struct ubi_volume_info vi = {};
+	struct ubi_device_info di = {};
+	struct mtd_info *mtd;
+	char *str;
+
+	ubi_get_volume_info(priv->ubi, &vi);
+	ubi_get_device_info(vi.ubi_num, &di);
+
+	mtd = di.mtd;
+
+	str = asprintf("root=ubi0:%s ubi.mtd=%s rootfstype=ubifs",
+			vi.name, mtd->cdev.partname);
+
+	dev_add_param_fixed(dev, "linux.bootargs", str);
+
+	free(str);
+}
+
 static int ubifs_probe(struct device_d *dev)
 {
 	struct fs_device_d *fsdev = dev_to_fs_device(dev);
@@ -612,6 +633,8 @@ static int ubifs_probe(struct device_d *dev)
 		goto err;
 	}
 
+	ubifs_set_rootarg(priv, dev);
+
 	return 0;
 err:
 	ubi_close_volume(priv->ubi);
diff --git a/include/fs.h b/include/fs.h
index f95464de6a01..81a166c37cef 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -174,6 +174,7 @@ char *normalise_link(const char *pathname, const char* symlink);
 char *get_mounted_path(const char *path);
 
 struct cdev *get_cdev_by_mountpath(const char *path);
+struct device_d *get_dev_by_mountpath(const char *path);
 
 /* Register a new filesystem driver */
 int register_fs_driver(struct fs_driver_d *fsdrv);
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 274ec4ee41ea..0614681d731c 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -154,6 +154,7 @@ struct ubi_device_info {
 	int max_write_size;
 	int ro_mode;
 	dev_t cdev;
+	struct mtd_info *mtd;
 };
 
 /*
-- 
2.1.4



From w.egorov at phytec.de  Tue May 26 06:23:10 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 26 May 2015 15:23:10 +0200
Subject: [PATCH v2 1/2] ARM: dts: Add an am33xx include file for MLO size
 reduction
Message-ID: <1432646591-6991-1-git-send-email-w.egorov@phytec.de>

AM335x's MLO size limit is 109K.
The am33xx.dtsi file adds spare and never used nodes to the dtb.
With this patch we add a file to remove the unused nodes and reduce the
size of the dtb.

Including this file will reduce the lzo packed MLO size about 6K.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
v2:
	- rename file to am33xx-strip.dtsi
	- keep gpio* and uart* nodes
---
 arch/arm/dts/am33xx-strip.dtsi | 48 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
 create mode 100644 arch/arm/dts/am33xx-strip.dtsi

diff --git a/arch/arm/dts/am33xx-strip.dtsi b/arch/arm/dts/am33xx-strip.dtsi
new file mode 100644
index 0000000..3dc9a57
--- /dev/null
+++ b/arch/arm/dts/am33xx-strip.dtsi
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * 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.
+ */
+
+/ {
+	aliases {
+		/delete-property/ i2c1;
+		/delete-property/ i2c2;
+		/delete-property/ mmc0;
+		/delete-property/ mmc1;
+		/delete-property/ mmc2;
+		/delete-property/ d_can0;
+		/delete-property/ d_can1;
+	};
+};
+
+/delete-node/ &i2c1;
+/delete-node/ &i2c2;
+/delete-node/ &mmc2;
+/delete-node/ &mmc3;
+/delete-node/ &hwspinlock;
+/delete-node/ &wdt2;
+/delete-node/ &dcan0;
+/delete-node/ &dcan1;
+/delete-node/ &mailbox;
+/delete-node/ &timer1;
+/delete-node/ &timer2;
+/delete-node/ &timer3;
+/delete-node/ &timer4;
+/delete-node/ &timer5;
+/delete-node/ &timer6;
+/delete-node/ &timer7;
+/delete-node/ &spi1;
+/delete-node/ &epwmss0;
+/delete-node/ &epwmss1;
+/delete-node/ &epwmss2;
+/delete-node/ &lcdc;
+/delete-node/ &tscadc;
+/delete-node/ &sham;
+/delete-node/ &aes;
+/delete-node/ &mcasp0;
+/delete-node/ &mcasp1;
+/delete-node/ &rng;
-- 
1.9.1



From w.egorov at phytec.de  Tue May 26 06:23:11 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 26 May 2015 15:23:11 +0200
Subject: [PATCH v2 2/2] ARM: dts: Add am33xx-strip.dtsi to PHYTEC MLOs
In-Reply-To: <1432646591-6991-1-git-send-email-w.egorov@phytec.de>
References: <1432646591-6991-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432646591-6991-2-git-send-email-w.egorov@phytec.de>

This patch will reduce the size of the MLO images.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/dts/am335x-phytec-phycard-som-mlo.dts | 1 +
 arch/arm/dts/am335x-phytec-phycore-som-mlo.dts | 1 +
 arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
index 17d9152..f9ed627 100644
--- a/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phycard-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phycard-som.dtsi"
+#include "am33xx-strip.dtsi"
 
 / {
 	model = "Phytec phyCARD AM335x";
diff --git a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
index b08a59e..f70835f 100644
--- a/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phycore-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phycore-som.dtsi"
+#include "am33xx-strip.dtsi"
 
 / {
 	model = "Phytec phyCORE AM335x";
diff --git a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
index 5294ff5..736d7ef 100644
--- a/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
+++ b/arch/arm/dts/am335x-phytec-phyflex-som-mlo.dts
@@ -9,6 +9,7 @@
 
 #include "am33xx.dtsi"
 #include "am335x-phytec-phyflex-som.dtsi"
+#include "am33xx-strip.dtsi"
 
 / {
 	model = "Phytec phyFLEX AM335x";
-- 
1.9.1



From w.egorov at phytec.de  Tue May 26 06:31:44 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 26 May 2015 15:31:44 +0200
Subject: [RFC v2 1/3] bootsource: Add NET bootsource
Message-ID: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 common/bootsource.c  | 1 +
 include/bootsource.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/common/bootsource.c b/common/bootsource.c
index 7f3d51f..707b079 100644
--- a/common/bootsource.c
+++ b/common/bootsource.c
@@ -35,6 +35,7 @@ static const char *bootsource_str[] = {
 	[BOOTSOURCE_ONENAND] = "onenand",
 	[BOOTSOURCE_HD] = "harddisk",
 	[BOOTSOURCE_USB] = "usb",
+	[BOOTSOURCE_NET] = "net",
 };
 
 static enum bootsource bootsource = BOOTSOURCE_UNKNOWN;
diff --git a/include/bootsource.h b/include/bootsource.h
index 4bca9b9..c6d3b3a 100644
--- a/include/bootsource.h
+++ b/include/bootsource.h
@@ -15,6 +15,7 @@ enum bootsource {
 	BOOTSOURCE_ONENAND,
 	BOOTSOURCE_HD,
 	BOOTSOURCE_USB,
+	BOOTSOURCE_NET,
 };
 
 #define BOOTSOURCE_INSTANCE_UNKNOWN	-1
-- 
1.9.1



From w.egorov at phytec.de  Tue May 26 06:31:46 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 26 May 2015 15:31:46 +0200
Subject: [RFC v2 3/3] ARM: am33xx: Add network boot
In-Reply-To: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
References: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432647106-8295-3-git-send-email-w.egorov@phytec.de>

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
 arch/arm/mach-omap/Kconfig          |  9 +++++++
 arch/arm/mach-omap/am33xx_generic.c |  3 +++
 arch/arm/mach-omap/xload.c          | 52 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index 444ddf8..bc00d5b 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -110,6 +110,15 @@ config ARCH_TEXT_BASE
 	default 0x80e80000 if MACH_OMAP343xSDP
 	default 0x80e80000 if MACH_BEAGLE
 
+config AM33XX_NET_BOOT
+	bool "enable AM335x network boot"
+	select ENVIRONMENT_VARIABLES
+	select NET_DHCP
+	select FS_TFTP
+	select DRIVER_NET_CPSW
+	default n
+	depends on ARCH_AM33XX && NET
+
 config OMAP4_USBBOOT
 	bool "enable booting from USB"
 	default n
diff --git a/arch/arm/mach-omap/am33xx_generic.c b/arch/arm/mach-omap/am33xx_generic.c
index ee30351..7ce32f0 100644
--- a/arch/arm/mach-omap/am33xx_generic.c
+++ b/arch/arm/mach-omap/am33xx_generic.c
@@ -145,6 +145,9 @@ static int am33xx_bootsource(void)
 	case 0x44:
 		src = BOOTSOURCE_USB;
 		break;
+	case 0x46:
+		src = BOOTSOURCE_NET;
+		break;
 	default:
 		src = BOOTSOURCE_UNKNOWN;
 	}
diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
index 7c8c350..08490ce 100644
--- a/arch/arm/mach-omap/xload.c
+++ b/arch/arm/mach-omap/xload.c
@@ -13,6 +13,10 @@
 #include <filetype.h>
 #include <xymodem.h>
 #include <mach/generic.h>
+#include <mach/am33xx-generic.h>
+#include <net.h>
+#include <environment.h>
+#include <dhcp.h>
 
 struct omap_barebox_part *barebox_part;
 
@@ -126,7 +130,6 @@ static void *omap_xload_boot_mmc(void)
 		printf("could not read barebox.bin from sd card\n");
 		return NULL;
 	}
-
 	return buf;
 }
 
@@ -224,6 +227,45 @@ static void *omap_serial_boot(void){
 	return buf;
 }
 
+static void *am33xx_net_boot(void)
+{
+	void *buf = NULL;
+	int err;
+	int len;
+	struct dhcp_req_param dhcp_param;
+	const char *bootfile;
+
+	am33xx_register_ethaddr(0, 0);
+
+	memset(&dhcp_param, 0, sizeof(struct dhcp_req_param));
+	dhcp_param.vendor_id = "am335x barebox-mlo";
+	err = dhcp(20, &dhcp_param);
+	if (err) {
+		printf("dhcp failed\n");
+		return NULL;
+	}
+
+	err = mount(ip_to_string(net_get_serverip()), "tftp", "/", NULL);
+	if (err < 0) {
+		printf("Unable to mount.\n");
+		return NULL;
+	}
+
+	bootfile = getenv("bootfile");
+	if (!bootfile) {
+		printf("bootfile not found.\n");
+		return NULL;
+	}
+
+	buf = read_file(bootfile, &len);
+	if (!buf)
+		printf("could not read %s.\n", bootfile);
+
+	umount("/");
+
+	return buf;
+}
+
 /*
  * Replaces the default shell in xload configuration
  */
@@ -264,6 +306,14 @@ static __noreturn int omap_xload(void)
 			func = omap_serial_boot();
 			break;
 		}
+	case BOOTSOURCE_NET:
+		if (IS_ENABLED(CONFIG_AM33XX_NET_BOOT)) {
+			printf("booting from NET\n");
+			func = am33xx_net_boot();
+			break;
+		} else {
+			printf("booting from network not enabled\n");
+		}
 	default:
 		printf("unknown boot source. Fall back to nand\n");
 		func = omap_xload_boot_nand(barebox_part->nand_offset,
-- 
1.9.1



From w.egorov at phytec.de  Tue May 26 06:31:45 2015
From: w.egorov at phytec.de (Wadim Egorov)
Date: Tue, 26 May 2015 15:31:45 +0200
Subject: [RFC v2 2/3] net: dhcp: Split dhcp funcionality & add dhcp command
In-Reply-To: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
References: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
Message-ID: <1432647106-8295-2-git-send-email-w.egorov@phytec.de>

dhcp/bootp was bound to the command functionality.
This patch splits the dhcp command.
We are now able to use bootp without a shell.

This patch adds also a check for environment variables and globalvar.
So only when ENVIRONMENT_VARIABLES and GLOBALVAR is set, all received
dhcp data will be stored.

Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
---
v2:
	- Added a memset in commands/dhcp.c to clear the dhcp_param variable

Please apply this set.

---
 commands/Kconfig  |   1 +
 commands/Makefile |   1 +
 commands/dhcp.c   |  78 ++++++++++++++++++++++++++
 include/dhcp.h    |  23 ++++++++
 net/Kconfig       |   4 ++
 net/Makefile      |   2 +-
 net/dhcp.c        | 164 +++++++++++++++++++++---------------------------------
 7 files changed, 172 insertions(+), 101 deletions(-)
 create mode 100644 commands/dhcp.c
 create mode 100644 include/dhcp.h

diff --git a/commands/Kconfig b/commands/Kconfig
index 847ff76..102c3cc 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -1183,6 +1183,7 @@ menu "Network"
 
 config CMD_DHCP
 	bool
+	depends on NET_DHCP
 	prompt "dhcp"
 	help
 	  DHCP client to obtain IP or boot params
diff --git a/commands/Makefile b/commands/Makefile
index b902f58..3698347 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -111,3 +111,4 @@ obj-$(CONFIG_CMD_CMP)		+= cmp.o
 obj-$(CONFIG_CMD_NV)		+= nv.o
 obj-$(CONFIG_CMD_DEFAULTENV)	+= defaultenv.o
 obj-$(CONFIG_CMD_STATE)		+= state.o
+obj-$(CONFIG_CMD_DHCP)		+= dhcp.o
diff --git a/commands/dhcp.c b/commands/dhcp.c
new file mode 100644
index 0000000..eb98bfc
--- /dev/null
+++ b/commands/dhcp.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * Based on work of Sascha Hauer <s.hauer 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+#include <environment.h>
+#include <getopt.h>
+#include <dhcp.h>
+
+static int do_dhcp(int argc, char *argv[])
+{
+	int ret, opt;
+	int retries = DHCP_DEFAULT_RETRY;
+	struct dhcp_req_param dhcp_param;
+
+	memset(&dhcp_param, 0, sizeof(struct dhcp_req_param));
+	getenv_uint("global.dhcp.retries", &retries);
+
+	while ((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
+		switch (opt) {
+		case 'H':
+			dhcp_param.hostname = optarg;
+			break;
+		case 'v':
+			dhcp_param.vendor_id = optarg;
+			break;
+		case 'c':
+			dhcp_param.client_id = optarg;
+			break;
+		case 'u':
+			dhcp_param.client_uuid = optarg;
+			break;
+		case 'U':
+			dhcp_param.user_class = optarg;
+			break;
+		case 'r':
+			retries = simple_strtoul(optarg, NULL, 10);
+			break;
+		}
+	}
+
+	if (!retries) {
+		printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
+		retries = DHCP_DEFAULT_RETRY;
+	}
+
+	ret = dhcp(retries, &dhcp_param);
+
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(dhcp)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-H HOSTNAME", "hostname to send to the DHCP server")
+BAREBOX_CMD_HELP_OPT("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests")
+BAREBOX_CMD_HELP_OPT("-r RETRY", "retry limit (default 20)");
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(dhcp)
+	.cmd		= do_dhcp,
+	BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params")
+	BAREBOX_CMD_OPTS("[-HvcuUr]")
+	BAREBOX_CMD_GROUP(CMD_GRP_NET)
+	BAREBOX_CMD_HELP(cmd_dhcp_help)
+	BAREBOX_CMD_COMPLETE(empty_complete)
+BAREBOX_CMD_END
diff --git a/include/dhcp.h b/include/dhcp.h
new file mode 100644
index 0000000..2ed11da
--- /dev/null
+++ b/include/dhcp.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 PHYTEC Messtechnik GmbH,
+ * Author: Wadim Egorov <w.egorov at phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DHCP_H__
+#define __DHCP_H__
+
+struct dhcp_req_param {
+	char *hostname;
+	char *vendor_id;
+	char *client_id;
+	char *user_class;
+	char *client_uuid;
+};
+
+int dhcp(int retries, struct dhcp_req_param *param);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 918d776..a890492 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -22,4 +22,8 @@ config NET_IFUP
 	default y
 	bool
 
+config NET_DHCP
+	bool
+	prompt "dhcp support"
+
 endif
diff --git a/net/Makefile b/net/Makefile
index 907dc28..58bf143 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -1,7 +1,7 @@
 obj-$(CONFIG_NET)	+= eth.o
 obj-$(CONFIG_NET)	+= net.o
 obj-$(CONFIG_NET_NFS)	+= nfs.o
-obj-$(CONFIG_CMD_DHCP)	+= dhcp.o
+obj-$(CONFIG_NET_DHCP)	+= dhcp.o
 obj-$(CONFIG_CMD_PING)	+= ping.o
 obj-$(CONFIG_NET_RESOLV)+= dns.o
 obj-$(CONFIG_NET_NETCONSOLE) += netconsole.o
diff --git a/net/dhcp.c b/net/dhcp.c
index 19a8462..2baba7a 100644
--- a/net/dhcp.c
+++ b/net/dhcp.c
@@ -21,9 +21,9 @@
 #include <getopt.h>
 #include <globalvar.h>
 #include <init.h>
+#include <dhcp.h>
 
 #define DHCP_DEFAULT_RETRY 20
-
 #define OPT_SIZE 312	/* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
 
 struct bootp {
@@ -142,7 +142,8 @@ static void env_ip_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
 	IPaddr_t ip;
 
 	ip = net_read_ip(popt);
-	setenv_ip(opt->barebox_var_name, ip);
+	if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+		setenv_ip(opt->barebox_var_name, ip);
 }
 
 static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
@@ -158,10 +159,9 @@ static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen
 
 	if (opt->copy_only_if_valid && !strlen(tmp))
 		return;
-
-	if (opt->barebox_var_name)
+	if (opt->barebox_var_name && IS_ENABLED(EVIRONMENT_VARIABLES))
 		setenv(opt->barebox_var_name, tmp);
-	if (opt->barebox_dhcp_global)
+	if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
 		dhcp_set_barebox_global(opt->barebox_dhcp_global, tmp);
 
 }
@@ -263,10 +263,10 @@ static int dhcp_set_string_options(struct dhcp_param *param, u8 *e)
 	int str_len;
 	char* str = param->data;
 
-	if (!str && param->barebox_var_name)
+	if (!str && param->barebox_var_name && IS_ENABLED(ENVIRONMENT_VARIABLES))
 		str = (char*)getenv(param->barebox_var_name);
 
-	if (!str && param->barebox_dhcp_global)
+	if (!str && param->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
 		str = (char*)dhcp_get_barebox_global(param->barebox_dhcp_global);
 
 	if (!str)
@@ -391,8 +391,10 @@ static void bootp_copy_net_params(struct bootp *bp)
 		net_set_serverip(tmp_ip);
 
 	if (strlen(bp->bp_file) > 0) {
-		setenv("bootfile", bp->bp_file);
-		dhcp_set_barebox_global("bootfile", bp->bp_file);
+		if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+			setenv("bootfile", bp->bp_file);
+		if (IS_ENABLED(CONFIG_GLOBALVAR))
+			dhcp_set_barebox_global("bootfile", bp->bp_file);
 	}
 
 	debug("bootfile: %s\n", bp->bp_file);
@@ -651,87 +653,27 @@ static void dhcp_reset_env(void)
 		if (!opt->barebox_var_name || opt->copy_only_if_valid)
 			continue;
 
-		setenv(opt->barebox_var_name,"");
-		if (opt->barebox_dhcp_global)
-			dhcp_set_barebox_global(opt->barebox_dhcp_global,"");
-	}
-}
-
-static void dhcp_global_add(const char *var)
-{
-	char * var_global = asprintf("dhcp.%s", var);
-
-	if (!var_global)
-		return;
-
-	globalvar_add_simple(var_global, NULL);
-	free(var_global);
-}
-
-static int dhcp_global_init(void)
-{
-	struct dhcp_opt *opt;
-	struct dhcp_param *param;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
-		opt = &dhcp_options[i];
-
-		if (!opt->barebox_dhcp_global)
-			continue;
-
-		dhcp_global_add(opt->barebox_dhcp_global);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
-		param = &dhcp_params[i];
-
-		if (!param->barebox_dhcp_global)
-			continue;
-
-		dhcp_global_add(param->barebox_dhcp_global);
+		if (IS_ENABLED(ENVIRONMENT_VARIABLES))
+			setenv(opt->barebox_var_name, "");
+		if (opt->barebox_dhcp_global && IS_ENABLED(CONFIG_GLOBALVAR))
+			dhcp_set_barebox_global(opt->barebox_dhcp_global, "");
 	}
-
-	return 0;
 }
-late_initcall(dhcp_global_init);
 
-static int do_dhcp(int argc, char *argv[])
+int dhcp(int retries, struct dhcp_req_param *param)
 {
-	int ret, opt;
-	int retries = DHCP_DEFAULT_RETRY;
+	int ret = 0;
 
 	dhcp_reset_env();
 
-	getenv_uint("global.dhcp.retries", &retries);
-
-	while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
-		switch(opt) {
-		case 'H':
-			dhcp_set_param_data(DHCP_HOSTNAME, optarg);
-			break;
-		case 'v':
-			dhcp_set_param_data(DHCP_VENDOR_ID, optarg);
-			break;
-		case 'c':
-			dhcp_set_param_data(DHCP_CLIENT_ID, optarg);
-			break;
-		case 'u':
-			dhcp_set_param_data(DHCP_CLIENT_UUID, optarg);
-			break;
-		case 'U':
-			dhcp_set_param_data(DHCP_USER_CLASS, optarg);
-			break;
-		case 'r':
-			retries = simple_strtoul(optarg, NULL, 10);
-			break;
-		}
-	}
+	dhcp_set_param_data(DHCP_HOSTNAME, param->hostname);
+	dhcp_set_param_data(DHCP_VENDOR_ID, param->vendor_id);
+	dhcp_set_param_data(DHCP_CLIENT_ID, param->client_id);
+	dhcp_set_param_data(DHCP_USER_CLASS, param->user_class);
+	dhcp_set_param_data(DHCP_CLIENT_UUID, param->client_uuid);
 
-	if (!retries) {
-		printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
+	if (!retries)
 		retries = DHCP_DEFAULT_RETRY;
-	}
 
 	dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
 	if (IS_ERR(dhcp_con)) {
@@ -781,29 +723,50 @@ out1:
 	net_unregister(dhcp_con);
 out:
 	if (ret)
-		printf("dhcp failed: %s\n", strerror(-ret));
+		debug("dhcp failed: %s\n", strerror(-ret));
 
 	return ret;
 }
 
-BAREBOX_CMD_HELP_START(dhcp)
-BAREBOX_CMD_HELP_TEXT("Options:")
-BAREBOX_CMD_HELP_OPT ("-H HOSTNAME", "hostname to send to the DHCP server")
-BAREBOX_CMD_HELP_OPT ("-v ID\t", "DHCP Vendor ID (code 60) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-c ID\t", "DHCP Client ID (code 61) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-u UUID\t", "DHCP Client UUID (code 97) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-U CLASS", "DHCP User class (code 77) submitted in DHCP requests")
-BAREBOX_CMD_HELP_OPT ("-r RETRY", "retry limit (default 20)");
-BAREBOX_CMD_HELP_END
-
-BAREBOX_CMD_START(dhcp)
-	.cmd		= do_dhcp,
-	BAREBOX_CMD_DESC("DHCP client to obtain IP or boot params")
-	BAREBOX_CMD_OPTS("[-HvcuUr]")
-	BAREBOX_CMD_GROUP(CMD_GRP_NET)
-	BAREBOX_CMD_HELP(cmd_dhcp_help)
-	BAREBOX_CMD_COMPLETE(empty_complete)
-BAREBOX_CMD_END
+#ifdef CONFIG_GLOBALVAR
+static void dhcp_global_add(const char *var)
+{
+	char *var_global = asprintf("dhcp.%s", var);
+
+	if (!var_global)
+		return;
+
+	globalvar_add_simple(var_global, NULL);
+	free(var_global);
+}
+
+static int dhcp_global_init(void)
+{
+	struct dhcp_opt *opt;
+	struct dhcp_param *param;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
+		opt = &dhcp_options[i];
+
+		if (!opt->barebox_dhcp_global)
+			continue;
+
+		dhcp_global_add(opt->barebox_dhcp_global);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
+		param = &dhcp_params[i];
+
+		if (!param->barebox_dhcp_global)
+			continue;
+
+		dhcp_global_add(param->barebox_dhcp_global);
+	}
+
+	return 0;
+}
+late_initcall(dhcp_global_init);
 
 BAREBOX_MAGICVAR_NAMED(global_dhcp_bootfile, global.dhcp.bootfile, "bootfile returned from DHCP request");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_rootpath, global.dhcp.rootpath, "rootpath returned from DHCP request");
@@ -814,3 +777,4 @@ BAREBOX_MAGICVAR_NAMED(global_dhcp_user_class, global.dhcp.user_class, "user cla
 BAREBOX_MAGICVAR_NAMED(global_dhcp_tftp_server_name, global.dhcp.tftp_server_name, "TFTP server Name returned from DHCP request");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_oftree_file, global.dhcp.oftree_file, "OF tree returned from DHCP request (option 224)");
 BAREBOX_MAGICVAR_NAMED(global_dhcp_retries, global.dhcp.retries, "retry limit");
+#endif
-- 
1.9.1



From s.hauer at pengutronix.de  Tue May 26 06:50:34 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 15:50:34 +0200
Subject: [PATCH 2/2] blspec: automatically append bootargs
In-Reply-To: <1432644381-29474-3-git-send-email-mkl@pengutronix.de>
References: <1432644381-29474-1-git-send-email-mkl@pengutronix.de>
 <1432644381-29474-3-git-send-email-mkl@pengutronix.de>
Message-ID: <20150526135034.GM6325@pengutronix.de>

On Tue, May 26, 2015 at 02:46:21PM +0200, Marc Kleine-Budde wrote:
> From: Sascha Hauer <s.hauer at pengutronix.de>
> 
> When bootloader spec is used to boot devices it is often desirable
> to boot the same image from different media. Since the fs images
> need to contain the root= parameters to tell Linux where to boot
> from the images can't be identical on different media.
> 
> This patch changes this by introducing a 'appendroot' option for
> bootloader spec. If set to true, barebox will construct a Linux
> commandline option for the device the bootloader spec entry is found
> on.

This should have documentation in Documentation/user/booting-linux.rst.
(which currently lacks information that we can do bootloaderspec via NFS
aswell)

> +static int blspec_append_root(struct blspec_entry *entry)
> +{
> +	const char *appendroot;
> +	const char *rootarg;
> +	struct device_d *fsdev;
> +	int ret;
> +
> +	appendroot = blspec_entry_var_get(entry, "appendroot");
> +	if (!appendroot || strcmp(appendroot, "true"))
> +		return 0;
> +
> +	fsdev = get_dev_by_mountpath(entry->rootpath);
> +	if (!fsdev) {
> +		ret = -EINVAL;
> +		pr_err("Cannot get fs device for %s\n", entry->rootpath);
> +		goto err_out;
> +	}
> +
> +	rootarg = dev_get_param(fsdev, "linux.bootargs");

Better linux.root?

> --- a/drivers/mtd/ubi/kapi.c
> +++ b/drivers/mtd/ubi/kapi.c
> @@ -36,6 +36,7 @@ void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di)
>  	di->min_io_size = ubi->min_io_size;
>  	di->max_write_size = ubi->max_write_size;
>  	di->ro_mode = ubi->ro_mode;
> +	di->mtd = ubi->mtd;
>  }
>  EXPORT_SYMBOL_GPL(ubi_do_get_device_info);
>  
> diff --git a/fs/fs.c b/fs/fs.c
> index a056d83d3d92..b8d3d3468f01 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -225,6 +225,19 @@ struct cdev *get_cdev_by_mountpath(const char *path)
>  	return fsdev->cdev;
>  }
>  
> +/*
> + * get_cdev_by_mountpath - return the cdev the given path
> + *                         is mounted on

s/get_cdev_by_mountpath/get_dev_by_mountpath/

> + */
> +struct device_d *get_dev_by_mountpath(const char *path)
> +{
> +	struct fs_device_d *fsdev;
> +
> +	fsdev = get_fsdevice_by_path(path);
> +
> +	return &fsdev->dev;
> +}
> +
>  char *get_mounted_path(const char *path)
>  {
>  	struct fs_device_d *fdev;
> diff --git a/fs/nfs.c b/fs/nfs.c
> index 2738c781d72b..ba00270a8b23 100644
> --- a/fs/nfs.c
> +++ b/fs/nfs.c
> @@ -1306,6 +1306,20 @@ static int nfs_stat(struct device_d *dev, const char *filename, struct stat *s)
>  	}
>  }
>  
> +static void nfs_set_rootarg(struct nfs_priv *npriv, struct device_d *dev)
> +{
> +	char *str;
> +	const char *ip;
> +
> +	ip = ip_to_string(npriv->server);
> +	str = asprintf("root=/dev/nfs nfsroot=%s:%s,v3,tcp",
> +			ip, npriv->path);

It would be nice to have the NFS options configurable. Maybe from a
global.linux.rootnfsopts variable?

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 May 26 07:10:57 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 16:10:57 +0200
Subject: [PATCH 1/2] Documentation: blspec: Fix typo
Message-ID: <1432649458-4350-1-git-send-email-s.hauer@pengutronix.de>

The device index is missing in the example, add it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 Documentation/user/booting-linux.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 5ef1254..fd1ba56 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -194,7 +194,7 @@ The entry can be listed with the -l option:
         options:    console=ttymxc0,115200 root=PARTUUID=0007CB20-01
         linux:      11ab7c89d02c4f66a4e2474ea25b2b84.15/linux
 
-When on barebox the SD card shows up as ``mmc`` then this entry can be booted with
+When on barebox the SD card shows up as ``mmc1`` then this entry can be booted with
 ``boot mmc1`` or with setting ``global.boot.default`` to ``mmc1``.
 
 Network boot
-- 
2.1.4



From s.hauer at pengutronix.de  Tue May 26 07:10:58 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 26 May 2015 16:10:58 +0200
Subject: [PATCH 2/2] Documentation: blspec: Document blspec over NFS
In-Reply-To: <1432649458-4350-1-git-send-email-s.hauer@pengutronix.de>
References: <1432649458-4350-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432649458-4350-2-git-send-email-s.hauer@pengutronix.de>

We support booting blspec entries found on NFS servers, add documentation
for it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 Documentation/user/booting-linux.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index fd1ba56..ac44cba 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -197,6 +197,13 @@ The entry can be listed with the -l option:
 When on barebox the SD card shows up as ``mmc1`` then this entry can be booted with
 ``boot mmc1`` or with setting ``global.boot.default`` to ``mmc1``.
 
+A bootloader spec entry can also reside on an NFS server in which case a RFC2224
+compatible NFS URI string must be passed to the boot command:
+
+.. code-block:: sh
+
+  boot nfs://nfshost//path/
+
 Network boot
 ------------
 
-- 
2.1.4



From begue.jc at gmail.com  Tue May 26 08:41:06 2015
From: begue.jc at gmail.com (Jean-Christophe BEGUE)
Date: Tue, 26 May 2015 17:41:06 +0200
Subject: Programatically write in a file in the environnent with a hush command
Message-ID: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>

Hello,

I'm trying to pass a value from Barebox to the operating system, using
the usreland command bareboxenv -l.

My problem is : How should I write that status from my hush barebox script?

echo $mystatus > /env/data/my_status_file

The above command doesn't work as '>' is not implemented.

I've the feeling that I'm missing something?

Jean-Christophe BEGUE


From Alexander.Richter at ATSonline.de  Tue May 26 23:08:49 2015
From: Alexander.Richter at ATSonline.de (Alexander Richter)
Date: Wed, 27 May 2015 06:08:49 +0000
Subject: Programatically write in a file in the environnent with a hush
 command
In-Reply-To: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
References: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
Message-ID: <D72B6FFF-645F-41CC-9B99-2ACE13B05BFC@atsonline.de>

Hello,
> Am 26.05.2015 um 17:42 schrieb Jean-Christophe BEGUE <begue.jc at gmail.com>:
> 
> Hello,
> 
> I'm trying to pass a value from Barebox to the operating system, using
> the usreland command bareboxenv -l.
> 
> My problem is : How should I write that status from my hush barebox script?
> 
> echo $mystatus > /env/data/my_status_file
You can use the command nv to create non volatile shell variables. Don?t forget to save the Environment.
> 
> The above command doesn't work as '>' is not implemented.
> 
> I've the feeling that I'm missing something?
> 
To access the new variable (/env/nv/foo.bar) from userspace, you can use the ?bareboxenv? tool

Alexander Richter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.infradead.org/pipermail/barebox/attachments/20150527/5865bf4a/attachment.sig>

From Alexander.Richter at ATSonline.de  Tue May 26 23:24:17 2015
From: Alexander.Richter at ATSonline.de (Alexander Richter)
Date: Wed, 27 May 2015 06:24:17 +0000
Subject: Programatically write in a file in the environnent with a hush
 command
In-Reply-To: <D72B6FFF-645F-41CC-9B99-2ACE13B05BFC@atsonline.de>
References: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
 <D72B6FFF-645F-41CC-9B99-2ACE13B05BFC@atsonline.de>
Message-ID: <97BF8529-638A-49F5-BF3A-51D52D57B774@atsonline.de>


> Am 27.05.2015 um 08:10 schrieb Alexander Richter <alexander.richter at atsonline.de>:
> 
> Hello,
>> Am 26.05.2015 um 17:42 schrieb Jean-Christophe BEGUE <begue.jc at gmail.com>:
>> 
>> Hello,
>> 
>> I'm trying to pass a value from Barebox to the operating system, using
>> the usreland command bareboxenv -l.
>> 
>> My problem is : How should I write that status from my hush barebox script?
>> 
>> echo $mystatus > /env/data/my_status_file
> You can use the command nv to create non volatile shell variables. Don?t forget to save the Environment.
Additionally, a echo -a / -o might be useful in your case.
-a <file>",  "instead of outputting to stdout append to <file>
-o <file>",  "instead of outputting to stdout overwrite <file>
>> 
>> The above command doesn't work as '>' is not implemented.
>> 
>> I've the feeling that I'm missing something?
>> 
> To access the new variable (/env/nv/foo.bar) from userspace, you can use the ?bareboxenv? tool
> 
> Alexander Richter
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


From s.hauer at pengutronix.de  Tue May 26 23:41:45 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 May 2015 08:41:45 +0200
Subject: bareboxenv - tricky ptxdist behavior
In-Reply-To: <556441EF.8040702@atsonline.de>
References: <556441EF.8040702@atsonline.de>
Message-ID: <20150527064145.GO6325@pengutronix.de>

Hi Alexander,

On Tue, May 26, 2015 at 11:50:39AM +0200, Alexander Richter wrote:
> Hallo,
> 
> I just used bareboxenv tool in linux userspace after a long
> troublesome trip through ptxdist.
> That would not have to be, if the description of "build bareboxenv
> tool for target" in barebox config has said, that i has to enable
> the tool  platformconfig.

Is there a "in" missing in the sentence above? There is a platformconfig
in ptxdist, but this is a file or a ptxdist subcommand, not a tool.
Could you clarify what your problem was? I do not really understand.

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 May 26 23:53:00 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 May 2015 08:53:00 +0200
Subject: Programatically write in a file in the environnent with a hush
 command
In-Reply-To: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
References: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
Message-ID: <20150527065300.GP6325@pengutronix.de>

Hi Jean-Christophe,

On Tue, May 26, 2015 at 05:41:06PM +0200, Jean-Christophe BEGUE wrote:
> Hello,
> 
> I'm trying to pass a value from Barebox to the operating system, using
> the usreland command bareboxenv -l.
> 
> My problem is : How should I write that status from my hush barebox script?
> 
> echo $mystatus > /env/data/my_status_file
> 
> The above command doesn't work as '>' is not implemented.
> 
> I've the feeling that I'm missing something?

Besides the ways Alexander just mentioned you could also add something
to the kernel cmdline and parse /proc/cmdline later in userspace.
Still another possibility is to add nodes/properties to the device tree
using the of_* commands.

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 May 26 23:59:10 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 May 2015 08:59:10 +0200
Subject: [PATCH v2 1/2] ARM: dts: Add an am33xx include file for MLO size
 reduction
In-Reply-To: <1432646591-6991-1-git-send-email-w.egorov@phytec.de>
References: <1432646591-6991-1-git-send-email-w.egorov@phytec.de>
Message-ID: <20150527065910.GQ6325@pengutronix.de>

On Tue, May 26, 2015 at 03:23:10PM +0200, Wadim Egorov wrote:
> AM335x's MLO size limit is 109K.
> The am33xx.dtsi file adds spare and never used nodes to the dtb.
> With this patch we add a file to remove the unused nodes and reduce the
> size of the dtb.
> 
> Including this file will reduce the lzo packed MLO size about 6K.
> 
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>

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 May 27 00:00:12 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 27 May 2015 09:00:12 +0200
Subject: [RFC v2 1/3] bootsource: Add NET bootsource
In-Reply-To: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
References: <1432647106-8295-1-git-send-email-w.egorov@phytec.de>
Message-ID: <20150527070012.GR6325@pengutronix.de>

On Tue, May 26, 2015 at 03:31:44PM +0200, Wadim Egorov wrote:
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
> ---
>  common/bootsource.c  | 1 +
>  include/bootsource.h | 1 +
>  2 files changed, 2 insertions(+)

Applied all, 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 Andreas.Geisenhainer at atsonline.de  Wed May 27 01:05:23 2015
From: Andreas.Geisenhainer at atsonline.de (Andreas Geisenhainer)
Date: Wed, 27 May 2015 10:05:23 +0200
Subject: bareboxenv - tricky ptxdist behavior
In-Reply-To: <20150527064145.GO6325@pengutronix.de>
References: <556441EF.8040702@atsonline.de>
 <20150527064145.GO6325@pengutronix.de>
Message-ID: <55657AC3.3040609@atsonline.de>

On 27/05/15 08:41 AM, Sascha Hauer wrote:
> Hi Alexander,
>
> On Tue, May 26, 2015 at 11:50:39AM +0200, Alexander Richter wrote:
>> Hallo,
>>
>> I just used bareboxenv tool in linux userspace after a long
>> troublesome trip through ptxdist.
>> That would not have to be, if the description of "build bareboxenv
>> tool for target" in barebox config has said, that i has to enable
>> the tool  platformconfig.
> Is there a "in" missing in the sentence above? There is a platformconfig
> in ptxdist, but this is a file or a ptxdist subcommand, not a tool.
> Could you clarify what your problem was? I do not really understand.

Let me pitch in here.

Alexander tried to build `bareboxenv` by enabling it
within the barebox.config. He succeeded in doing so.
But the tool did not show up in the final rootfs because
the option "install bareboxenv" from platformconfig was not
enabled.

Yes, the "build bareboxenv" tooltip cleary states that it will
be build. But there's no word about the "install barebox" option
in platformconfig.

At this point we wished for a small hint, pointing us in the right
direction.

I have no idea how to resolve this properly since barebox
(and bareboxenv) can be build without ptxdist and pointing to a
nonexisting (ptxdist-)configuration will get people confused.



regards
Andreas


From begue.jc at gmail.com  Wed May 27 06:52:00 2015
From: begue.jc at gmail.com (Jean-Christophe BEGUE)
Date: Wed, 27 May 2015 15:52:00 +0200
Subject: Programatically write in a file in the environnent with a hush
 command
In-Reply-To: <20150527065300.GP6325@pengutronix.de>
References: <CABP==CLFeG59X3OyMxJrxTzWDg-Xm8dURb-k-JXu3as+pY5mKA@mail.gmail.com>
 <20150527065300.GP6325@pengutronix.de>
Message-ID: <CABP==CKP6xFYV1V2t4KbALGPq0g3ERmmEmkVYHnYE3p=JiOPqg@mail.gmail.com>

I didn't noticed -a and -o options for echo. That suits my needs, but
"nv" is exactly what I'm trying to acheive.

I'll use the kernel command line as well on early phases of my software boot.

Thank you!

Jean-Christophe BEGUE
http://www.devisubox.com


On Wed, May 27, 2015 at 8:53 AM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> Hi Jean-Christophe,
>
> On Tue, May 26, 2015 at 05:41:06PM +0200, Jean-Christophe BEGUE wrote:
>> Hello,
>>
>> I'm trying to pass a value from Barebox to the operating system, using
>> the usreland command bareboxenv -l.
>>
>> My problem is : How should I write that status from my hush barebox script?
>>
>> echo $mystatus > /env/data/my_status_file
>>
>> The above command doesn't work as '>' is not implemented.
>>
>> I've the feeling that I'm missing something?
>
> Besides the ways Alexander just mentioned you could also add something
> to the kernel cmdline and parse /proc/cmdline later in userspace.
> Still another possibility is to add nodes/properties to the device tree
> using the of_* commands.
>
> 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 mkl at pengutronix.de  Wed May 27 08:22:58 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 27 May 2015 17:22:58 +0200
Subject: [PATCH] bootstate: add framework for redundant boot scenarios
Message-ID: <1432740178-7799-1-git-send-email-mkl@pengutronix.de>

There are several use cases where a redundant Linux system is needed. The
barebox,bootstate framework provides the building blocks to model different
use cases without the need to start from the scratch over and over again.

For more information see the included
Documentation/devicetree/bindings/barebox/barebox,bootstate.rst file.

Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 .../bindings/barebox/barebox,bootstate.rst         | 237 +++++++
 arch/sandbox/dts/sandbox.dts                       |  83 +++
 commands/Kconfig                                   |   5 +
 commands/Makefile                                  |   1 +
 commands/bootchooser.c                             | 101 +++
 common/Kconfig                                     |   7 +
 common/Makefile                                    |   1 +
 common/bootstate.c                                 | 776 +++++++++++++++++++++
 drivers/misc/Kconfig                               |   3 +
 drivers/misc/Makefile                              |   1 +
 drivers/misc/bootstate.c                           |  68 ++
 include/bootstate.h                                |  38 +
 12 files changed, 1321 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/barebox/barebox,bootstate.rst
 create mode 100644 commands/bootchooser.c
 create mode 100644 common/bootstate.c
 create mode 100644 drivers/misc/bootstate.c
 create mode 100644 include/bootstate.h

diff --git a/Documentation/devicetree/bindings/barebox/barebox,bootstate.rst b/Documentation/devicetree/bindings/barebox/barebox,bootstate.rst
new file mode 100644
index 000000000000..dd44e31ced80
--- /dev/null
+++ b/Documentation/devicetree/bindings/barebox/barebox,bootstate.rst
@@ -0,0 +1,237 @@
+barebox bootstate
+=================
+
+Overview
+--------
+
+There are several use cases where a redundant Linux system is needed.
+The ``barebox,bootstate`` framework provides the building blocks to
+model different use cases without the need to start from the scratch
+over and over again.
+
+The ``barebox,bootstate`` works on abstract boot targets, each with a
+set of properties and implements an algorithm which selects the
+highest priority target to boot.
+
+A set of boot targets can be described in a devicetree node. This
+node could be part of the regular devicetree blob or it could be an
+extra devicetree for the bootstate.
+
+A bootstate node contains a description of a set of boot targets along
+with a place where to store the mutable state. Currently implemented
+backends are :ref:`barebox,state` and ``nv`` (:ref:`command_nv`)
+variables.
+
+Required properties:
+
+* ``compatible``: should be ``barebox,bootstate``;
+* ``backend-type``: should be ``state`` or ``nv``.
+
+Optional properties:
+
+* ``backend``: phandle to the :ref:`barebox,state` backend
+
+
+boot target nodes - immutable description
+-----------------------------------------
+
+These are subnodes of a bootstate node, each describing a boot
+target. The node name may end with ``@<ADDRESS>``, but the suffix is
+sripped from the target name.
+
+Optional properties:
+
+* ``default_attempts``: If the boot attempts counter is reset, this
+  value is used.
+
+Example::
+
+  bootstate: bootstate {
+  	compatible = "barebox,bootstate";
+  	backend-type = "state";
+  	backend = <&state>;
+
+  	system0 {
+  		default_attempts = <3>;
+  	};
+
+  	system1 {
+  		default_attempts = <3>;
+  	};
+  };
+
+In this example a bootstate, using a :ref:`barebox,state` backend with
+two boot target ``system0`` and ``system1`` is defined. When the boot
+attempts counter is reset, the default value of ``3`` is used for both
+targets.
+
+
+boot target nodes - mutable state
+---------------------------------
+
+The above example uses a :ref:`barebox,state` backend, which requires
+some additional configuration to hold the mutable
+state. :ref:`barebox,state` has to be explicidly configured, while
+``nv`` (:ref:`command_nv`) variables are created on the fly.
+
+The state of each boot target consists of the following ``uint32``
+varibles:
+
+* ``remaining_attempts``: holds the number of remaining boot
+  attempts. This variable is changed the the bootstate algorithm
+  during boot.
+* ``priority``: defines the priority of the boot target. Higher number
+  indicate a higher priority, If two boot target have the same
+  priority the one defined first in the device tree has precedence.
+  The ``priority`` can optionally be changed by the algorithm to 0, if
+  the boot target is decremented to ``0`` remaining boot attempts. A
+  ``priority`` of ``0`` means the boot target is **deactivated** and
+  will not be considered a valid target during further boots. If the
+  remaining attempts counter is reset, a target with priority 0 is
+  **not** changed.
+* ``ok``: this is an opaque value, it's not accessed by the bootstate
+  algorithm. It can be used be the Linux system to track the first
+  boot after an update.
+
+The bootstate can also hold a default watchdog timeout (in seconds),
+which can be activated by the bootstate algorithm.
+
+Example::
+
+  state: state {
+  	magic = <0x4d433230>;
+  	compatible = "barebox,state";
+  	backend-type = "raw";
+  	backend = <&backend_state>;
+  	#address-cells = <1>;
+  	#size-cells = <1>;
+
+  	bootstate {
+  		#address-cells = <1>;
+  		#size-cells = <1>;
+
+  		system0 {
+  			#address-cells = <1>;
+  			#size-cells = <1>;
+
+  			remaining_attempts {
+  				reg = <0x0 0x4>;
+  				type = "uint32";
+  			};
+  			priority {
+  				reg = <0x4 0x4>;
+  				type = "uint32";
+  			};
+  			ok {
+  				reg = <0x8 0x4>;
+  				type = "uint32";
+  			};
+  		};
+
+  		system1 {
+  			#address-cells = <1>;
+  			#size-cells = <1>;
+
+  			remaining_attempts {
+  				reg = <0x10 0x4>;
+  				type = "uint32";
+  			};
+  			priority {
+  				reg = <0x14 0x4>;
+  				type = "uint32";
+  			};
+  			ok {
+  				reg = <0x18 0x4>;
+  				type = "uint32";
+  			};
+  		};
+
+  		watchdog_timeout {
+  			reg = <0x20 0x4>;
+  			type = "uint32";
+  			default = <60>;
+  		};
+  	};
+  };
+
+This example defines two boot target (``system0`` and ``system1``) and
+a watchdog timeout of ``60`` seconds.
+
+
+Backends
+--------
+
+Currently two backends exist. The :ref:`barebox,state` backend is a
+bit more complicated to setup, as all boot target have to be described
+in the referenced :ref:`barebox,state` in the device tree. On the
+upside, the advantages of the (possible redundant storage, etc...) of
+the :ref:`barebox,state` is gained for free.
+
+The :ref:`command_nv` backend is a lot simpler, no special setup is
+needed, it should run on every board, which already implements a
+read/writeable barebox environment.
+
+
+Algorithm
+---------
+
+The low level algorithm is implemented by the
+``bootstate_get_target()`` function. Its job is to iterate over all
+boot sources and return the name (as a string) of the choosen boot
+target.
+
+The algorithm iterates over all boot target defined under the
+associated device tree node and picks the one with the highest
+``priority`` (higher number have a higher priority) where the
+``remaining_attempts`` is greater than zero. A pointer to the name of
+the boot target is returned, the string should be freed via ``free()``.
+
+The behaviour can be modified with the flags paramter. The following
+flags are currently supported:
+
+* ``BOOTCHOOSER_FLAG_ATTEMPTS_KEEP``: the ``remaining_attempts``
+  counter of the choosen boot target is not changed.
+* ``BOOTCHOOSER_FLAG_ATTEMPTS_DEC``: the ``remaining_attempts``
+  counter of the choosen boot target is decremented by one.
+* ``BOOTCHOOSER_FLAG_ATTEMPTS_RESET``: the ``remaining_attempts``
+  counter of all *active* boot targets (those with ``priority > 0``)
+  are reset to their default values as defined in the immutable
+  description by ``default_attempts``.
+* ``BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS``: if used together
+  with ``BOOTCHOOSER_FLAG_ATTEMPTS_DEC`` and the
+  ``remaining_attempts`` counter of the choosen boot target is
+  decremented to ``0``, the boot target is deactivated for further
+  boot attempts (although *this* boot is attemped as usual). This is
+  done by setting the ``priority`` to ``0``.
+* ``BOOTCHOOSER_FLAG_VERBOSE``: increases the verbosity of the output
+
+
+Frontend
+--------
+
+The shell command ``bootchooser`` (:ref:`command_bootchooser`) can be
+used to choose and start a boot target by a shell one-liner. The
+command picks the boot target with the highes priority and calls the
+``boot`` (:ref:`command_boot`) command with the selected boot target
+as its first and only parameter.
+
+The ``bootchooser`` command implements command line paramter versions
+of the above described flags:
+
+* ``-k``: keep boot attempts
+* ``-d``: decrement boot attempts
+* ``-r``: reset boot attempts
+* ``-z``: deactivate on zero remaining attempts
+* ``-v``: verbose output
+
+Next to the standard parameters, these additional options are
+implemented:
+
+* ``-D``: dryrun - do not boot (all other functionality is active) - a
+  specified watchdog timeout will be activated.
+* ``-R``: retry - if booting fails, the chose next target, but
+  decrement its attemts. Note: if the current target has still the
+  highes priority and remaining attemts, it will be selected again.
+* ``-w <TIMEOUT_IN_SEC>``: activate watchdog - if no parameter is
+  given, the timeout from the device tree is used. A given parameter
+  overwrites the device tree default.
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 2595aa13fa62..e2bc8f76c2e3 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -3,5 +3,88 @@
 #include "skeleton.dtsi"
 
 / {
+	aliases {
+		state = &state;
+	};
 
+	state: state {
+		magic = <0x4d433230>;
+		compatible = "barebox,state";
+		backend-type = "dtb";
+		backend = "/fd0";
+
+		bootstate {
+			system0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				remaining_attempts {
+					reg = <0x0 0x4>;
+					type = "uint32";
+				};
+				priority {
+					reg = <0x4 0x4>;
+					type = "uint32";
+				};
+				ok {
+					reg = <0x8 0x4>;
+					type = "uint32";
+				};
+			};
+
+			system1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				remaining_attempts {
+					reg = <0x10 0x4>;
+					type = "uint32";
+				};
+				priority {
+					reg = <0x14 0x4>;
+					type = "uint32";
+				};
+				ok {
+					reg = <0x18 0x4>;
+					type = "uint32";
+				};
+			};
+
+			factory {
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				remaining_attempts {
+					reg = <0x20 0x4>;
+					type = "uint32";
+				};
+				priority {
+					reg = <0x24 0x4>;
+					type = "uint32";
+				};
+				ok {
+					reg = <0x28 0x4>;
+					type = "uint32";
+				};
+			};
+		};
+	};
+
+	bootstate: bootstate {
+		compatible = "barebox,bootstate";
+		backend-type = "state"; // or "nv", or "efivar"
+		backend = <&state>;
+
+		system0 {
+			default_attempts = <3>;
+		};
+
+		system1 {
+			default_attempts = <3>;
+		};
+
+		factory {
+			default_attempts = <3>;
+		};
+	};
 };
diff --git a/commands/Kconfig b/commands/Kconfig
index 25c77a85c5dc..85dd88f7615c 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2101,6 +2101,11 @@ config CMD_STATE
 	depends on STATE
 	prompt "state"
 
+config CMD_BOOTCHOOSER
+	tristate
+	depends on BOOTSTATE
+	prompt "bootchooser"
+
 # end Miscellaneous commands
 endmenu
 
diff --git a/commands/Makefile b/commands/Makefile
index b902f58ec5cc..f51cfb6ed492 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -111,3 +111,4 @@ obj-$(CONFIG_CMD_CMP)		+= cmp.o
 obj-$(CONFIG_CMD_NV)		+= nv.o
 obj-$(CONFIG_CMD_DEFAULTENV)	+= defaultenv.o
 obj-$(CONFIG_CMD_STATE)		+= state.o
+obj-$(CONFIG_CMD_BOOTCHOOSER)	+= bootchooser.o
diff --git a/commands/bootchooser.c b/commands/bootchooser.c
new file mode 100644
index 000000000000..34006175818f
--- /dev/null
+++ b/commands/bootchooser.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe at pengutronix.de>
+ * Copyright (C) 2015 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <bootstate.h>
+#include <command.h>
+#include <common.h>
+#include <getopt.h>
+#include <malloc.h>
+#include <stdio.h>
+
+static int do_bootchooser(int argc, char *argv[])
+{
+	unsigned flags = 0, timeout = 0;
+	char *name = NULL;
+	int opt, ret;
+
+	while ((opt = getopt(argc, argv, "kdrzvDRw::")) > 0) {
+		switch (opt) {
+		case 'k':
+			flags |= BOOTCHOOSER_FLAG_ATTEMPTS_KEEP;
+			break;
+		case 'd':
+			flags |= BOOTCHOOSER_FLAG_ATTEMPTS_DEC;
+			break;
+		case 'r':
+			flags |= BOOTCHOOSER_FLAG_ATTEMPTS_RESET;
+			break;
+		case 'z':
+			flags |= BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS;
+			break;
+		case 'v':
+			flags |= BOOTCHOOSER_FLAG_VERBOSE;
+			break;
+		case 'D':
+			flags |= BOOTCHOOSER_FLAG_DRYRUN;
+			break;
+		case 'R':
+			flags |= BOOTCHOOSER_FLAG_RETRY_WITH_DEC;
+			break;
+		case 'w':
+			if (optarg)
+				timeout = simple_strtoul(optarg, NULL, 0);
+			else
+				flags |= BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE;
+			flags |= BOOTCHOOSER_FLAG_WATCHDOG_ENABLE;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (optind < argc)
+		name = argv[optind];
+
+	if (!(flags & (BOOTCHOOSER_FLAG_ATTEMPTS_KEEP |
+		       BOOTCHOOSER_FLAG_ATTEMPTS_DEC |
+		       BOOTCHOOSER_FLAG_ATTEMPTS_RESET))) {
+		bootstate_info();
+		return 0;
+	}
+
+	if ((flags & BOOTCHOOSER_FLAG_ATTEMPTS_KEEP) &&
+	    (flags & (BOOTCHOOSER_FLAG_ATTEMPTS_DEC | BOOTCHOOSER_FLAG_ATTEMPTS_RESET)))
+		return COMMAND_ERROR_USAGE;
+
+	ret = bootstate_bootchooser(name, flags, timeout);
+
+	return ret ? COMMAND_ERROR : COMMAND_SUCCESS;
+}
+
+BAREBOX_CMD_HELP_START(bootchooser)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-k","keep - boot, don't modify attempts counter")
+BAREBOX_CMD_HELP_OPT ("-d","decrement - boot, but decrement attempts counter by one")
+BAREBOX_CMD_HELP_OPT ("-r","reset - boot, but reset _all_ attempts counter to default")
+BAREBOX_CMD_HELP_OPT ("-z","deactivate choosen target in on zero remaining boot attemts")
+BAREBOX_CMD_HELP_OPT ("-v","verbose output")
+BAREBOX_CMD_HELP_OPT ("-D","dryrun. Do not boot - but handle watchdog and reset.")
+BAREBOX_CMD_HELP_OPT ("-R","retry - boot, retry next boot target and decrement attempts")
+BAREBOX_CMD_HELP_OPT ("-w","activate watchdog, use timeout specified in <BOOTSTATE>.watchdog_timeout")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(bootchooser)
+	.cmd = do_bootchooser,
+	BAREBOX_CMD_DESC("automatically select a boot target and boot")
+	BAREBOX_CMD_OPTS("[-kdrzvDR] -w <TIMEOUT> [BOOTSTATE]")
+	BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+	BAREBOX_CMD_HELP(cmd_bootchooser_help)
+BAREBOX_CMD_END
diff --git a/common/Kconfig b/common/Kconfig
index 3dfb5ac19494..791fd89d4c1e 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -716,6 +716,13 @@ config STATE
 	select OFTREE
 	select PARAMETER
 
+config BOOTSTATE
+	bool "bootstate infrastructure"
+	depends on OF_BAREBOX_DRIVERS
+	select ENVIRONMENT_VARIABLES
+	select OFTREE
+	select PARAMETER
+
 config RESET_SOURCE
 	bool "detect Reset cause"
 	depends on GLOBALVAR
diff --git a/common/Makefile b/common/Makefile
index 2738238c67a8..ed336e257e33 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_RESET_SOURCE)	+= reset_source.o
 obj-$(CONFIG_SHELL_HUSH)	+= hush.o
 obj-$(CONFIG_SHELL_SIMPLE)	+= parser.o
 obj-$(CONFIG_STATE)		+= state.o
+obj-$(CONFIG_BOOTSTATE)		+= bootstate.o
 obj-$(CONFIG_UIMAGE)		+= image.o uimage.o
 obj-$(CONFIG_MENUTREE)		+= menutree.o
 obj-$(CONFIG_EFI_GUID)		+= efi-guid.o
diff --git a/common/bootstate.c b/common/bootstate.c
new file mode 100644
index 000000000000..5baaf03b7bfe
--- /dev/null
+++ b/common/bootstate.c
@@ -0,0 +1,776 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe at pengutronix.de>
+ * Copyright (C) 2015 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <bootstate.h>
+#include <common.h>
+#include <envfs.h>
+#include <environment.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <globalvar.h>
+#include <init.h>
+#include <ioctl.h>
+#include <libbb.h>
+#include <libfile.h>
+#include <malloc.h>
+#include <net.h>
+#include <printk.h>
+#include <state.h>
+#include <stdio.h>
+#include <watchdog.h>
+#include <xfuncs.h>
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mtd/mtd-abi.h>
+#include <linux/mtd/mtd.h>
+
+#include <asm/unaligned.h>
+
+/* list of all registered bootstate instances */
+static LIST_HEAD(bootstate_list);
+
+struct state_backend;
+
+struct bootstate {
+	struct device_d dev;
+	const char *name;
+	struct list_head list;
+	struct list_head targets;
+	struct list_head targets_unsorted;
+	struct bootstate_backend *backend;
+	bool dirty;
+};
+
+struct bootstate_backend {
+	int (*load)(struct bootstate_backend *backend, struct bootstate *bootstate);
+	int (*save)(struct bootstate_backend *backend, struct bootstate *bootstate);
+	const char *name;
+	const char *path;
+};
+
+struct bootstate_target {
+	struct list_head list;
+	struct list_head list_unsorted;
+
+	/* state */
+	unsigned int priority;
+	unsigned int remaining_attempts;
+	bool ok;
+
+	/* spec */
+	const char *name;
+	unsigned int default_attempts;
+};
+
+static void pr_target(struct bootstate *bootstate, struct bootstate_target *target)
+{
+	printf("%s: target: name=%s prio=%u, ok=%d, rem=%u, def=%u\n",
+	       bootstate->name, target->name, target->priority, target->ok,
+	       target->remaining_attempts, target->default_attempts);
+}
+
+static struct bootstate *bootstate_new(const char *name)
+{
+	struct bootstate *bootstate;
+	int ret;
+
+	bootstate = xzalloc(sizeof(*bootstate));
+	safe_strncpy(bootstate->dev.name, name, MAX_DRIVER_NAME);
+	bootstate->name = bootstate->dev.name;
+	bootstate->dev.id = DEVICE_ID_DYNAMIC;
+	INIT_LIST_HEAD(&bootstate->targets);
+	INIT_LIST_HEAD(&bootstate->targets_unsorted);
+
+	ret = register_device(&bootstate->dev);
+	if (ret) {
+		free(bootstate);
+		return ERR_PTR(ret);
+	}
+
+	list_add_tail(&bootstate->list, &bootstate_list);
+
+	return bootstate;
+}
+
+static void bootstate_release(struct bootstate *bootstate)
+{
+	unregister_device(&bootstate->dev);
+	free(bootstate);
+}
+
+static int bootstate_target_compare(struct list_head *a, struct list_head *b)
+{
+	struct bootstate_target *bootstate_a = list_entry(a, struct bootstate_target, list);
+	struct bootstate_target *bootstate_b = list_entry(b, struct bootstate_target, list);
+
+	/* order descending */
+	return bootstate_a->priority >= bootstate_b->priority ? -1 : 1;
+}
+
+static void bootstate_target_add(struct bootstate *bootstate, struct bootstate_target *target)
+{
+	list_del(&target->list);
+	list_add_sort(&target->list, &bootstate->targets, bootstate_target_compare);
+}
+
+static int bootstate_variable_read_u32(const struct bootstate *bootstate,
+				       const char *name, uint32_t *out_val)
+{
+	char *var;
+	int ret;
+
+	var = asprintf("%s.%s.%s", bootstate->backend->path, bootstate->name, name);
+	ret = getenv_uint(var, out_val);
+	free(var);
+
+	return ret;
+}
+
+static int bootstate_backend_variable_read_target_u32(const struct bootstate_backend *backend,
+						      const struct bootstate *bootstate,
+						      const struct bootstate_target *target,
+						      const char *name, uint32_t *out_val)
+{
+	char *var;
+	int ret;
+
+	var = asprintf("%s.%s.%s.%s", backend->path, bootstate->name,
+		       target->name, name);
+	ret = getenv_uint(var, out_val);
+	free(var);
+
+	return ret;
+}
+
+static int bootstate_backend_variable_write_target_u32(const struct bootstate_backend *backend,
+						       const struct bootstate *bootstate,
+						       const struct bootstate_target *target,
+						       const char *name, uint32_t in_val)
+{
+	char *var;
+	char *val;
+	int ret;
+
+	var = asprintf("%s.%s.%s.%s", backend->path, bootstate->name,
+		       target->name, name);
+	val = asprintf("%d", in_val);
+	ret = setenv(var, val);
+	free(val);
+	free(var);
+
+	return ret;
+}
+
+static int bootstate_variable_nv_init_u32(const struct bootstate_backend *backend,
+					  const struct bootstate *bootstate,
+					  const struct bootstate_target *target,
+					  const char *name)
+{
+	char *var;
+	int ret;
+
+	var = asprintf("%s.%s.%s", bootstate->name, target->name, name);
+	ret = nvvar_add(var, "0");
+	free(var);
+
+	return ret;
+}
+
+static struct bootstate_target *bootstate_target_find(const struct bootstate *bootstate,
+						      const char *name)
+{
+	struct bootstate_target *target;
+
+	list_for_each_entry(target, &bootstate->targets, list) {
+		if (!strcmp(target->name, name))
+			return target;
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+static int bootstate_target_from_node(struct bootstate *bootstate, const struct device_node *node, bool create)
+{
+	struct bootstate_target *target;
+	char *name, *indexs;
+	int ret;
+
+	name = xstrdup(node->name);
+	indexs = strchr(name, '@');
+	if (indexs)
+		*indexs++ = 0;
+
+	if (create) {
+		/* create*/
+		target = xzalloc(sizeof(*target));
+
+		target->name = xstrdup(name);
+		list_add_tail(&target->list, &bootstate->targets);
+		list_add_tail(&target->list_unsorted,
+			      &bootstate->targets_unsorted);
+	} else {
+		target = bootstate_target_find(bootstate, name);
+		if (IS_ERR(target)) {
+			int ret = PTR_ERR(target);
+			pr_err("no such boot target: %s: %s\n",
+			       name, strerror(-ret));
+			return ret;
+		}
+	}
+
+	/* init */
+	ret = of_property_read_u32(node, "default_attempts",
+				   &target->default_attempts);
+	if (ret)
+		return ret;
+
+	free(name);
+
+	return 0;
+}
+
+static int bootstate_from_node(struct bootstate *bootstate,
+			       const struct device_node *node, bool create)
+{
+	struct device_node *child;
+	int ret;
+
+	for_each_child_of_node(node, child) {
+		ret = bootstate_target_from_node(bootstate, child, create);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int bootstate_backend_load_one(const struct bootstate_backend *backend,
+				      const struct bootstate *bootstate,
+				      struct bootstate_target *target)
+{
+	uint32_t tmp;
+	int ret;
+
+	ret = bootstate_backend_variable_read_target_u32(backend, bootstate, target,
+							 "remaining_attempts",
+							 &target->remaining_attempts);
+	if (ret)
+		return ret;
+
+	ret = bootstate_backend_variable_read_target_u32(backend, bootstate, target,
+							 "priority", &target->priority);
+	if (ret)
+		return ret;
+
+	ret = bootstate_backend_variable_read_target_u32(backend, bootstate, target,
+							 "ok", &tmp);
+	if (ret)
+		return ret;
+
+	target->ok = !!tmp;
+
+	return ret;
+}
+
+static int bootstate_backend_load(struct bootstate_backend *backend,
+				  struct bootstate *bootstate)
+{
+	struct bootstate_target *target;
+	int ret;
+
+	list_for_each_entry(target, &bootstate->targets_unsorted, list_unsorted) {
+		ret = bootstate_backend_load_one(backend, bootstate, target);
+		if (ret)
+			return ret;
+		bootstate_target_add(bootstate, target);
+	}
+
+	return 0;
+}
+
+static int bootstate_backend_save_one(const struct bootstate_backend *backend,
+				      const struct bootstate *bootstate,
+				      struct bootstate_target *target)
+{
+	int ret;
+
+	ret = bootstate_backend_variable_write_target_u32(backend, bootstate, target,
+							  "remaining_attempts",
+							  target->remaining_attempts);
+	if (ret)
+		return ret;
+
+	ret = bootstate_backend_variable_write_target_u32(backend, bootstate, target,
+							  "priority", target->priority);
+	if (ret)
+		return ret;
+
+	ret = bootstate_backend_variable_write_target_u32(backend, bootstate, target,
+							  "ok", target->ok);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int bootstate_backend_save(const struct bootstate_backend *backend,
+				  const struct bootstate *bootstate)
+{
+	struct bootstate_target *target;
+	int ret;
+
+	list_for_each_entry(target, &bootstate->targets, list) {
+		ret = bootstate_backend_save_one(backend, bootstate, target);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int bootstate_backend_nv_init_one(const struct bootstate_backend *backend,
+					 const struct bootstate *bootstate,
+					 struct bootstate_target *target)
+{
+	int ret;
+
+	ret = bootstate_variable_nv_init_u32(backend, bootstate, target,
+					     "remaining_attempts");
+	if (ret)
+		return ret;
+
+	ret = bootstate_variable_nv_init_u32(backend, bootstate, target,
+					     "priority");
+	if (ret)
+		return ret;
+
+	ret = bootstate_variable_nv_init_u32(backend, bootstate, target,
+					     "ok");
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int bootstate_backend_nv_init(struct bootstate_backend *backend,
+				     struct bootstate *bootstate)
+{
+	struct bootstate_target *target;
+	int ret;
+
+	list_for_each_entry(target, &bootstate->targets_unsorted, list_unsorted) {
+		ret = bootstate_backend_nv_init_one(backend, bootstate, target);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int bootstate_backend_nv_save(struct bootstate_backend *backend,
+				     struct bootstate *bootstate)
+{
+	int ret;
+
+	ret = bootstate_backend_save(backend, bootstate);
+	if (ret)
+		return ret;
+
+	return envfs_save(NULL, NULL, 0);
+}
+
+static int bootstate_backend_nv_load(struct bootstate_backend *backend,
+				     struct bootstate *bootstate)
+{
+	return bootstate_backend_load(backend, bootstate);
+}
+
+struct bootstate_backend_nv {
+	struct bootstate_backend backend;
+};
+
+int bootstate_backend_nv(struct bootstate *bootstate)
+{
+	struct bootstate_backend_nv *backend_nv;
+	struct bootstate_backend *backend;
+
+	if (bootstate->backend)
+		return -EBUSY;
+
+	backend_nv = xzalloc(sizeof(*backend_nv));
+	backend = &backend_nv->backend;
+
+	backend->load = bootstate_backend_nv_load;
+	backend->save = bootstate_backend_nv_save;
+	backend->name = "nv";
+	backend->path = "nv";
+
+	bootstate->backend = backend;
+
+	return bootstate_backend_nv_init(backend, bootstate);
+}
+
+struct bootstate_backend_state {
+	struct bootstate_backend backend;
+	struct state *state;
+};
+
+static int bootstate_backend_state_save(struct bootstate_backend *backend,
+					struct bootstate *bootstate)
+{
+	struct bootstate_backend_state *backend_state =
+		container_of(backend, struct bootstate_backend_state, backend);
+	int ret;
+
+	ret = bootstate_backend_save(backend, bootstate);
+	if (ret)
+		return ret;
+
+	return state_save(backend_state->state);
+}
+
+static int bootstate_backend_state_load(struct bootstate_backend *backend,
+					struct bootstate *bootstate)
+{
+	return bootstate_backend_load(backend, bootstate);
+}
+
+int bootstate_backend_state(struct bootstate *bootstate, const struct device_node *node)
+{
+	struct bootstate_backend_state *backend_state;
+	struct bootstate_backend *backend;
+	const struct device_node *state_node;
+
+	if (bootstate->backend)
+		return -EBUSY;
+
+	backend_state = xzalloc(sizeof(*backend_state));
+	backend = &backend_state->backend;
+
+	backend->load = bootstate_backend_state_load;
+	backend->save = bootstate_backend_state_save;
+	backend->name = "state";
+
+	bootstate->backend = backend;
+
+	state_node = of_parse_phandle(node, "backend", 0);
+	if (!state_node)
+		return -EINVAL;
+
+	backend_state->state = state_by_node(state_node);
+	if (!backend_state->state)
+		return -EINVAL;
+
+	return state_get_name(backend_state->state, &backend->path);
+}
+
+/*
+ * bootstate_new_from_node - create a new bootstate instance from a device_node
+ *
+ * @name	The name of the new bootstate instance
+ * @node	The device_node describing the new bootstate instance
+ */
+struct bootstate *bootstate_new_from_node(const char *name, const struct device_node *node)
+{
+	struct bootstate *bootstate;
+	int ret;
+
+	pr_debug("%s: node=%s, name=%s\n", __func__, node->full_name, name);
+
+	bootstate = bootstate_new(name);
+	if (!bootstate)
+		return ERR_PTR(-EINVAL);
+
+	ret = bootstate_from_node(bootstate, node, true);
+	if (ret) {
+		bootstate_release(bootstate);
+		return ERR_PTR(ret);
+	}
+
+	return bootstate;
+}
+
+/*
+ * bootstate_by_name - find a bootstate instance by name
+ *
+ * @name	The name of the state instance
+ */
+struct bootstate *bootstate_by_name(const char *name)
+{
+	struct bootstate *bs;
+
+	list_for_each_entry(bs, &bootstate_list, list) {
+		if (!strcmp(name, bs->name))
+			return bs;
+	}
+
+	return NULL;
+}
+
+/*
+ * bootstate_load - load a bootstate from the backing store
+ *
+ * @bootstate	The state instance to load
+ */
+static int bootstate_load(struct bootstate *bootstate)
+{
+	int ret;
+
+	if (!bootstate->backend)
+		return -ENOSYS;
+
+	ret = bootstate->backend->load(bootstate->backend, bootstate);
+	if (ret)
+		bootstate->dirty = 1;
+	else
+		bootstate->dirty = 0;
+
+	return ret;
+}
+
+/*
+ * bootstate_save - save a bootstate to the backing store
+ *
+ * @bootstate	The bootstate instance to save
+ */
+static int bootstate_save(struct bootstate *bootstate)
+{
+	int ret;
+
+	if (!bootstate->dirty)
+		return 0;
+
+	if (!bootstate->backend)
+		return -ENOSYS;
+
+	ret = bootstate->backend->save(bootstate->backend, bootstate);
+	if (ret)
+		return ret;
+
+	bootstate->dirty = 0;
+
+	return 0;
+}
+
+void bootstate_info(void)
+{
+	struct bootstate *bootstate;
+
+	printf("registered bootstate instances:\n");
+
+	list_for_each_entry(bootstate, &bootstate_list, list) {
+		printf("%-20s ", bootstate->name);
+		printf("(backend: %s, path: %s)\n",
+		       bootstate->backend->name, bootstate->backend->path);
+	}
+}
+
+#define __BF(arg) [__BOOTCHOOSER_FLAG_##arg##_SHIFT] = __stringify(arg)
+
+static const char * const bootstate_flags_str[] = {
+	__BF(ATTEMPTS_KEEP),
+	__BF(ATTEMPTS_DEC),
+	__BF(ATTEMPTS_RESET),
+	__BF(DEACTIVATE_ON_ZERO_ATTEMPTS),
+	__BF(VERBOSE),
+	__BF(DRYRUN),
+	__BF(RETRY_WITH_DEC),
+	__BF(WATCHDOG_ENABLE),
+	__BF(WATCHDOG_TIMEOUT_FROM_STATE),
+};
+
+#undef __BF
+
+#define pr(verbose, format, args...) \
+	({ \
+		(verbose) ? pr_info((format), ##args) : 0; \
+	})
+
+void _pr_flags(struct bootstate *bootstate, unsigned flags)
+{
+	int i;
+
+	pr_info("%s: flags=0x%08x\n", bootstate->name, flags);
+
+	for (i = 0; i < ARRAY_SIZE(bootstate_flags_str); i++) {
+		if (flags & (1 << i))
+			pr_info("%s: -> %s\n", bootstate->name,
+				bootstate_flags_str[i]);
+	}
+}
+
+#define pr_flags(verbose, bootstate, flags) \
+	({ \
+		(verbose) ? _pr_flags(bootstate, flags) : 0; \
+	})
+
+/*
+ * bootstate_get_target - create a new state instance from a device_node
+ *
+ * @bootstate	the bootstate instance to work in
+ * @flags	supported flags:
+ *		BOOTCHOOSER_FLAG_VERBOSE
+ *		BOOTCHOOSER_FLAG_ATTEMPTS_KEEP
+ *		BOOTCHOOSER_FLAG_ATTEMPTS_DEC
+ *		BOOTCHOOSER_FLAG_ATTEMPTS_RESET
+ *		BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS
+ * @target_out	a string to the choosen boot target is returned via
+ *		this paramater
+ */
+int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **target_out)
+{
+	struct bootstate_target *target;
+	int ret;
+	bool found = false;
+	bool v = flags & BOOTCHOOSER_FLAG_VERBOSE;
+
+	pr_flags(v, bootstate, flags);
+
+	ret = bootstate_load(bootstate);
+	if (ret)
+		return ret;
+
+	if (flags & BOOTCHOOSER_FLAG_ATTEMPTS_RESET) {
+		list_for_each_entry(target, &bootstate->targets, list) {
+			if (target->priority ==  0)
+				continue;
+
+			target->remaining_attempts = target->default_attempts;
+			bootstate->dirty = true;
+
+			pr(v, "%s: target: name=%s setting rem to %d due to %s\n",
+			   bootstate->name, target->name, target->default_attempts,
+			   bootstate_flags_str[__BOOTCHOOSER_FLAG_ATTEMPTS_RESET_SHIFT]);
+		}
+		pr(v, "%s: --------\n", bootstate->name);
+	}
+
+	list_for_each_entry(target, &bootstate->targets, list) {
+		pr_target(bootstate, target);
+
+		if (found)
+			continue;
+
+		if (target->priority == 0) {
+			pr(v, "%s: name=%s prio=%d - trying next\n",
+			   bootstate->name, target->name, target->priority);
+			continue;
+		}
+
+		if (target->remaining_attempts == 0) {
+			pr(v, "%s: name=%s remaining attempts == 0 - trying next\n",
+			   bootstate->name, target->name);
+			continue;
+		}
+
+		if (flags & BOOTCHOOSER_FLAG_ATTEMPTS_DEC) {
+			bootstate->dirty = true;
+			target->remaining_attempts--;
+
+			pr(v, "%s: name=%s decrementing remaining_attempts to %d due to %s\n",
+			   bootstate->name, target->name,
+			   target->remaining_attempts,
+			   bootstate_flags_str[__BOOTCHOOSER_FLAG_ATTEMPTS_DEC_SHIFT]);
+
+			if ((target->remaining_attempts == 0) &&
+			    (flags & BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS)) {
+				target->priority = 0;
+
+				pr(v, "%s: name=%s deactivating target (setting priority = 0) due to %s\n",
+				   bootstate->name, target->name,
+				   bootstate_flags_str[__BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS_SHIFT]);
+			}
+		}
+
+		found = true;
+		*target_out = strdup(target->name);
+		pr_debug("%s: selected target '%s'\n", __func__, target->name);
+		if (!v)
+			goto out;
+
+		pr(v, "%s: --- other bootsources ---\n", bootstate->name);
+	}
+
+ out:
+	bootstate_save(bootstate);
+
+	if (!found)
+		return -ENOENT;
+
+	return 0;
+}
+
+int bootstate_bootchooser(char *name, unsigned flags, unsigned timeout)
+{
+	struct bootstate *bootstate;
+	bool v = flags & BOOTCHOOSER_FLAG_VERBOSE;
+	char *target;
+	int ret;
+
+	if (!name)
+		name = "bootstate";
+
+	bootstate = bootstate_by_name(name);
+	if (!bootstate)
+		return -ENOENT;
+
+	if (flags & BOOTCHOOSER_FLAG_WATCHDOG_ENABLE) {
+		if (flags & BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE) {
+			ret = bootstate_variable_read_u32(bootstate, "watchdog_timeout",
+							  &timeout);
+			if (ret)
+				return ret;
+		}
+
+		if (timeout != 0) {
+			pr(v, "%s: starting watchdog with timeout=%ds\n",
+			   __func__, timeout);
+
+			ret = watchdog_set_timeout(timeout);
+			if (ret)
+				return ret;
+		}
+	}
+
+	while (true) {
+		char *cmd;
+
+		ret = bootstate_get_target(bootstate, flags, &target);
+		if (ret)
+			return ret;
+
+		cmd = asprintf("boot %s", target);
+		free(target);
+		pr_info("%srunning: %s...\n",
+			flags & BOOTCHOOSER_FLAG_DRYRUN ? "not " : "", cmd);
+		if (!(flags & BOOTCHOOSER_FLAG_DRYRUN))
+			ret = run_command(cmd);
+		free(cmd);
+
+		if (flags & BOOTCHOOSER_FLAG_RETRY_WITH_DEC) {
+			flags |= BOOTCHOOSER_FLAG_ATTEMPTS_DEC;
+			flags &= ~(BOOTCHOOSER_FLAG_ATTEMPTS_RESET |
+				   BOOTCHOOSER_FLAG_ATTEMPTS_KEEP);
+			continue;
+		}
+
+		return ret;
+	}
+
+	return -ENOENT;
+}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7a5b14697efd..9b3ac244832b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -19,4 +19,7 @@ config STATE_DRV
 	tristate "state driver"
 	depends on STATE
 
+config BOOTSTATE_DRV
+	tristate "bootstate driver"
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 487e4b8ba2e5..603e14ebb5de 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_JTAG)		+= jtag.o
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_STATE_DRV)		+= state.o
+obj-$(CONFIG_BOOTSTATE_DRV)	+= bootstate.o
diff --git a/drivers/misc/bootstate.c b/drivers/misc/bootstate.c
new file mode 100644
index 000000000000..96b9f23c44da
--- /dev/null
+++ b/drivers/misc/bootstate.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Sascha Hauer <s.hauer at pengutronix.de>
+ * Copyright (C) 2015 Marc Kleine-Budde <mkl at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <bootstate.h>
+#include <driver.h>
+#include <init.h>
+#include <malloc.h>
+#include <of.h>
+#include <string.h>
+
+#include <linux/err.h>
+
+static int bootstate_probe(struct device_d *dev)
+{
+	struct device_node *np = dev->device_node;
+	struct bootstate *bootstate;
+	const char *alias;
+	const char *backend_type = NULL;
+	int ret;
+
+	if (!np)
+		return -EINVAL;
+
+	alias = of_alias_get(np);
+	if (!alias)
+		alias = "bootstate";
+
+	bootstate = bootstate_new_from_node(alias, np);
+	if (IS_ERR(bootstate))
+		return PTR_ERR(bootstate);
+
+	of_property_read_string(np, "backend-type", &backend_type);
+	if (!strcmp(backend_type, "state"))
+		ret = bootstate_backend_state(bootstate, np);
+	else if (!strcmp(backend_type, "nv"))
+		ret = bootstate_backend_nv(bootstate);
+	else
+		return -EINVAL;
+
+	return ret;
+}
+
+static __maybe_unused struct of_device_id bootstate_ids[] = {
+	{
+		.compatible = "barebox,bootstate",
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct driver_d bootstate_driver = {
+	.name = "bootstate",
+	.probe = bootstate_probe,
+	.of_compatible = DRV_OF_COMPAT(bootstate_ids),
+};
+device_platform_driver(bootstate_driver);
diff --git a/include/bootstate.h b/include/bootstate.h
new file mode 100644
index 000000000000..53102c527060
--- /dev/null
+++ b/include/bootstate.h
@@ -0,0 +1,38 @@
+#ifndef __BOOTSTATE_H
+#define __BOOTSTATE_H
+
+#include <of.h>
+
+struct bootstate *bootstate_new_from_node(const char *name, const struct device_node *node);
+struct bootstate *bootstate_find_by_name(const char *name);
+struct bootstate *bootstate_by_name(const char *name);
+void bootstate_info(void);
+int bootstate_backend_nv(struct bootstate *bootstate);
+int bootstate_backend_state(struct bootstate *bootstate, const struct device_node *node);
+
+enum {
+	__BOOTCHOOSER_FLAG_ATTEMPTS_KEEP_SHIFT,
+	__BOOTCHOOSER_FLAG_ATTEMPTS_DEC_SHIFT,
+	__BOOTCHOOSER_FLAG_ATTEMPTS_RESET_SHIFT,
+	__BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS_SHIFT,
+	__BOOTCHOOSER_FLAG_VERBOSE_SHIFT,
+	__BOOTCHOOSER_FLAG_DRYRUN_SHIFT,
+	__BOOTCHOOSER_FLAG_RETRY_WITH_DEC_SHIFT,
+	__BOOTCHOOSER_FLAG_WATCHDOG_ENABLE_SHIFT,
+	__BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE_SHIFT,
+};
+
+#define BOOTCHOOSER_FLAG_ATTEMPTS_KEEP (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_KEEP_SHIFT)
+#define BOOTCHOOSER_FLAG_ATTEMPTS_DEC (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_DEC_SHIFT)
+#define BOOTCHOOSER_FLAG_ATTEMPTS_RESET (1 << __BOOTCHOOSER_FLAG_ATTEMPTS_RESET_SHIFT)
+#define BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS (1 << __BOOTCHOOSER_FLAG_DEACTIVATE_ON_ZERO_ATTEMPTS_SHIFT)
+#define BOOTCHOOSER_FLAG_VERBOSE (1 << __BOOTCHOOSER_FLAG_VERBOSE_SHIFT)
+#define BOOTCHOOSER_FLAG_DRYRUN (1 << __BOOTCHOOSER_FLAG_DRYRUN_SHIFT)
+#define BOOTCHOOSER_FLAG_RETRY_WITH_DEC (1 << __BOOTCHOOSER_FLAG_RETRY_WITH_DEC_SHIFT)
+#define BOOTCHOOSER_FLAG_WATCHDOG_ENABLE (1 << __BOOTCHOOSER_FLAG_WATCHDOG_ENABLE_SHIFT)
+#define BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE (1 << __BOOTCHOOSER_FLAG_WATCHDOG_TIMEOUT_FROM_STATE_SHIFT)
+
+int bootstate_get_target(struct bootstate *bootstate, unsigned flags, char **target_out);
+int bootstate_bootchooser(char *name, unsigned flags, unsigned watchdog_timeout_s);
+
+#endif /* __BOOTSTATE_H */
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:29:32 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:29:32 +0200
Subject: [PATCH] md: use memmap when possible
Message-ID: <1432808972-14822-1-git-send-email-s.hauer@pengutronix.de>

This adds the missing pieces for:

d8a6e1c ARM/mem: handle data aborts gracefully for md

When possible use memmap and directly and dereference the input pointer
directly in memory_display() so that the data abort occurs where we expect
it and not in the md command. With this d8a6e1c can work as expected.

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

diff --git a/commands/md.c b/commands/md.c
index c1361a6..07a03d5 100644
--- a/commands/md.c
+++ b/commands/md.c
@@ -44,6 +44,7 @@ static int do_mem_md(int argc, char *argv[])
 	char *filename = "/dev/mem";
 	int mode = O_RWSIZE_4;
 	int swab = 0;
+	void *map;
 
 	if (argc < 2)
 		return COMMAND_ERROR_USAGE;
@@ -65,6 +66,13 @@ static int do_mem_md(int argc, char *argv[])
 	if (fd < 0)
 		return 1;
 
+	map = memmap(fd, PROT_READ);
+	if (map != (void *)-1) {
+		ret = memory_display(map + start, start, size,
+				mode >> O_RWSIZE_SHIFT, swab);
+		goto out;
+	}
+
 	do {
 		now = min(size, (loff_t)RW_BUF_SIZE);
 		r = read(fd, mem_rw_buf, now);
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:42 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:42 +0200
Subject: [PATCH 08/10] memset command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-9-git-send-email-s.hauer@pengutronix.de>

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

diff --git a/commands/memset.c b/commands/memset.c
index bb5f46d..fc5b659 100644
--- a/commands/memset.c
+++ b/commands/memset.c
@@ -44,7 +44,7 @@ static int do_memset(int argc, char *argv[])
 	int     ret = 1;
 	char	*file = "/dev/mem";
 
-	if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &file,
+	if (mem_parse_options(argc, argv, "bwlqd:", &mode, NULL, &file,
 			NULL) < 0)
 		return 1;
 
@@ -92,6 +92,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b",  "byte access")
 BAREBOX_CMD_HELP_OPT ("-w",  "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l",  "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q",  "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-d FILE",  "write file (default /dev/mem)")
 BAREBOX_CMD_HELP_END
 
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:37 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:37 +0200
Subject: [PATCH 03/10] fs: Add O_RWSIZE_8
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-4-git-send-email-s.hauer@pengutronix.de>

To support native 64bit accesses in memcpy_sz.

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

diff --git a/fs/fs.c b/fs/fs.c
index 779f264..9a79a03 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1590,6 +1590,9 @@ static void memcpy_sz(void *_dst, const void *_src, ulong count, ulong rwsize)
 		case 4:
 			*((ulong  *)dst) = *((ulong  *)src);
 			break;
+		case 8:
+			*((u64  *)dst) = *((u64  *)src);
+			break;
 		}
 		dst += rwsize;
 		src += rwsize;
diff --git a/include/fcntl.h b/include/fcntl.h
index aed741e..501b415 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -17,11 +17,12 @@
 #define O_NOFOLLOW	00400000	/* don't follow links */
 
 /* barebox additional flags */
-#define O_RWSIZE_MASK	00000070
+#define O_RWSIZE_MASK	00000170
 #define O_RWSIZE_SHIFT	3
 #define O_RWSIZE_1      00000010
 #define O_RWSIZE_2      00000020
 #define O_RWSIZE_4      00000040
+#define O_RWSIZE_8      00000100
 
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get close_on_exec */
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:40 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:40 +0200
Subject: [PATCH 06/10] memcmp command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-7-git-send-email-s.hauer@pengutronix.de>

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

diff --git a/commands/memcmp.c b/commands/memcmp.c
index d048150..e079d5f 100644
--- a/commands/memcmp.c
+++ b/commands/memcmp.c
@@ -49,7 +49,7 @@ static int do_memcmp(int argc, char *argv[])
 	int     offset = 0;
 	struct  stat statbuf;
 
-	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
+	if (mem_parse_options(argc, argv, "bwlqs:d:", &mode, &sourcefile,
 			&destfile, NULL) < 0)
 		return 1;
 
@@ -138,6 +138,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b",  "byte access")
 BAREBOX_CMD_HELP_OPT ("-w",  "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l",  "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q",  "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-s FILE", "source file (default /dev/mem)")
 BAREBOX_CMD_HELP_OPT ("-d FILE", "destination file (default /dev/mem)")
 BAREBOX_CMD_HELP_END
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:34 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:34 +0200
Subject: Add 64bit support to mem commands
Message-ID: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>

This series adds 64bit support to the memory commands which can
be quite useful on 64bit architectures. The commands use the
'-q' (for quad) option to switch to 64bit mode.

Sascha

----------------------------------------------------------------
Sascha Hauer (10):
      memory_display: Use consistent types
      memory_display: Add 64bit support
      fs: Add O_RWSIZE_8
      mem commands: suppport parsing 'q' option
      md command: Add 64bit support
      memcmp command: Add 64bit support
      memcpy command: Add 64bit support
      memset command: Add 64bit support
      mm command: Add 64bit support
      mw command: Add 64bit support

 commands/md.c           |  3 ++-
 commands/mem.c          |  3 +++
 commands/memcmp.c       |  3 ++-
 commands/memcpy.c       |  3 ++-
 commands/memset.c       |  3 ++-
 commands/mm.c           | 20 ++++++++++++++++----
 commands/mw.c           | 10 +++++++++-
 common/memory_display.c | 42 ++++++++++++++++++++++++++++--------------
 fs/fs.c                 |  3 +++
 include/fcntl.h         |  3 ++-
 10 files changed, 69 insertions(+), 24 deletions(-)


From s.hauer at pengutronix.de  Thu May 28 03:34:35 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:35 +0200
Subject: [PATCH 01/10] memory_display: Use consistent types
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-2-git-send-email-s.hauer@pengutronix.de>

memory_display uses three different types for 32bit variables, three
types for 16bit variables and three types for 8bit variables. Clean up
this mess and use one type per variable width.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/memory_display.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/common/memory_display.c b/common/memory_display.c
index 7b1d35e..1ad0f05 100644
--- a/common/memory_display.c
+++ b/common/memory_display.c
@@ -6,8 +6,8 @@
 
 int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int swab)
 {
-	ulong linebytes, i;
-	u_char	*cp;
+	unsigned long linebytes, i;
+	unsigned char *cp;
 
 	/* Print the lines.
 	 *
@@ -15,10 +15,10 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 	 * once, and all accesses are with the specified bus width.
 	 */
 	do {
-		char linebuf[DISP_LINE_LEN];
-		uint32_t *uip = (uint   *)linebuf;
-		uint16_t *usp = (ushort *)linebuf;
-		uint8_t *ucp = (u_char *)linebuf;
+		unsigned char linebuf[DISP_LINE_LEN];
+		uint32_t *uip = (uint32_t *)linebuf;
+		uint16_t *usp = (uint16_t *)linebuf;
+		uint8_t *ucp = (uint8_t *)linebuf;
 		unsigned count = 52;
 
 		printf("%08llx:", offs);
@@ -26,9 +26,9 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 
 		for (i = 0; i < linebytes; i += size) {
 			if (size == 4) {
-				u32 res;
+				uint32_t res;
 				data_abort_mask();
-				res = *((uint *)addr);
+				res = *((uint32_t *)addr);
 				if (swab)
 					res = __swab32(res);
 				if (data_abort_unmask()) {
@@ -39,9 +39,9 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 				}
 				*uip++ = res;
 			} else if (size == 2) {
-				u16 res;
+				uint16_t res;
 				data_abort_mask();
-				res = *((ushort *)addr);
+				res = *((uint16_t *)addr);
 				if (swab)
 					res = __swab16(res);
 				if (data_abort_unmask()) {
@@ -52,9 +52,9 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 				}
 				*usp++ = res;
 			} else {
-				u8 res;
+				uint8_t res;
 				data_abort_mask();
-				res = *((u_char *)addr);
+				res = *((uint8_t *)addr);
 				if (data_abort_unmask()) {
 					res = 0xff;
 					count -= printf(" xx");
@@ -70,7 +70,7 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 		while (count--)
 			putchar(' ');
 
-		cp = (uint8_t *)linebuf;
+		cp = linebuf;
 		for (i = 0; i < linebytes; i++) {
 			if ((*cp < 0x20) || (*cp > 0x7e))
 				putchar('.');
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:36 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:36 +0200
Subject: [PATCH 02/10] memory_display: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-3-git-send-email-s.hauer@pengutronix.de>

Add support for showing hexdumps in 64bit width.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 common/memory_display.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/common/memory_display.c b/common/memory_display.c
index 1ad0f05..ea91985 100644
--- a/common/memory_display.c
+++ b/common/memory_display.c
@@ -16,6 +16,7 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 	 */
 	do {
 		unsigned char linebuf[DISP_LINE_LEN];
+		uint64_t *ullp = (uint64_t *)linebuf;
 		uint32_t *uip = (uint32_t *)linebuf;
 		uint16_t *usp = (uint16_t *)linebuf;
 		uint8_t *ucp = (uint8_t *)linebuf;
@@ -25,7 +26,20 @@ int memory_display(const void *addr, loff_t offs, unsigned nbytes, int size, int
 		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
 
 		for (i = 0; i < linebytes; i += size) {
-			if (size == 4) {
+			if (size == 8) {
+				uint64_t res;
+				data_abort_mask();
+				res = *((uint64_t *)addr);
+				if (swab)
+					res = __swab64(res);
+				if (data_abort_unmask()) {
+					res = 0xffffffffffffffffULL;
+					count -= printf(" xxxxxxxxxxxxxxxx");
+				} else {
+					count -= printf(" %016llx", res);
+				}
+				*ullp++ = res;
+			} else if (size == 4) {
 				uint32_t res;
 				data_abort_mask();
 				res = *((uint32_t *)addr);
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:38 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:38 +0200
Subject: [PATCH 04/10] mem commands: suppport parsing 'q' option
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-5-git-send-email-s.hauer@pengutronix.de>

Add 64bit ('q', for quad) support to mem_parse_options

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

diff --git a/commands/mem.c b/commands/mem.c
index 568050d..23c703f 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -84,6 +84,9 @@ int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
 		case 'l':
 			*mode = O_RWSIZE_4;
 			break;
+		case 'q':
+			*mode = O_RWSIZE_8;
+			break;
 		case 's':
 			*sourcefile = optarg;
 			break;
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:41 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:41 +0200
Subject: [PATCH 07/10] memcpy command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-8-git-send-email-s.hauer@pengutronix.de>

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

diff --git a/commands/memcpy.c b/commands/memcpy.c
index 78716b1..9c8b645 100644
--- a/commands/memcpy.c
+++ b/commands/memcpy.c
@@ -47,7 +47,7 @@ static int do_memcpy(int argc, char *argv[])
 	struct stat statbuf;
 	int ret = 0;
 
-	if (mem_parse_options(argc, argv, "bwls:d:", &mode, &sourcefile,
+	if (mem_parse_options(argc, argv, "bwlqs:d:", &mode, &sourcefile,
 			&destfile, NULL) < 0)
 		return 1;
 
@@ -135,6 +135,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b", "byte access")
 BAREBOX_CMD_HELP_OPT ("-w", "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l", "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q", "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-s FILE", "source file (default /dev/mem)")
 BAREBOX_CMD_HELP_OPT ("-d FILE", "write file (default /dev/mem)")
 BAREBOX_CMD_HELP_END
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:39 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:39 +0200
Subject: [PATCH 05/10] md command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-6-git-send-email-s.hauer@pengutronix.de>

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

diff --git a/commands/md.c b/commands/md.c
index 07a03d5..c88259a 100644
--- a/commands/md.c
+++ b/commands/md.c
@@ -49,7 +49,7 @@ static int do_mem_md(int argc, char *argv[])
 	if (argc < 2)
 		return COMMAND_ERROR_USAGE;
 
-	if (mem_parse_options(argc, argv, "bwls:x", &mode, &filename, NULL,
+	if (mem_parse_options(argc, argv, "bwlqs:x", &mode, &filename, NULL,
 			&swab) < 0)
 		return 1;
 
@@ -105,6 +105,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b",  "byte access")
 BAREBOX_CMD_HELP_OPT ("-w",  "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l",  "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q",  "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-s FILE",  "display file (default /dev/mem)")
 BAREBOX_CMD_HELP_OPT ("-x",       "swap bytes at output")
 BAREBOX_CMD_HELP_TEXT("")
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:43 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:43 +0200
Subject: [PATCH 09/10] mm command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-10-git-send-email-s.hauer@pengutronix.de>

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

diff --git a/commands/mm.c b/commands/mm.c
index ff2e746..7c890a6 100644
--- a/commands/mm.c
+++ b/commands/mm.c
@@ -38,9 +38,10 @@ static int do_mem_mm(int argc, char *argv[])
 	u8 val8;
 	u16 val16;
 	u32 val32;
-	u32 value, mask;
+	u64 val64;
+	u64 value, mask;
 
-	if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &filename,
+	if (mem_parse_options(argc, argv, "bwlqd:", &mode, NULL, &filename,
 			&swab) < 0)
 		return 1;
 
@@ -48,8 +49,8 @@ static int do_mem_mm(int argc, char *argv[])
 		return COMMAND_ERROR_USAGE;
 
 	adr = strtoull_suffix(argv[optind++], NULL, 0);
-	value = simple_strtoul(argv[optind++], NULL, 0);
-	mask = simple_strtoul(argv[optind++], NULL, 0);
+	value = simple_strtoull(argv[optind++], NULL, 0);
+	mask = simple_strtoull(argv[optind++], NULL, 0);
 
 	fd = open_and_lseek(filename, mode | O_RDWR, adr);
 	if (fd < 0)
@@ -86,6 +87,16 @@ static int do_mem_mm(int argc, char *argv[])
 		if (ret < 0)
 			goto out_write;
 		break;
+	case O_RWSIZE_8:
+		if (ret < 0)
+			goto out_read;
+		ret = pread(fd, &val64, 8, adr);
+		val64 &= ~mask;
+		val64 |= (value & mask);
+		ret = pwrite(fd, &val64, 8, adr);
+		if (ret < 0)
+			goto out_write;
+		break;
 	}
 
 	close(fd);
@@ -110,6 +121,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b",  "byte access")
 BAREBOX_CMD_HELP_OPT ("-w",  "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l",  "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q",  "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-d FILE",  "write file (default /dev/mem)")
 BAREBOX_CMD_HELP_END
 
-- 
2.1.4



From s.hauer at pengutronix.de  Thu May 28 03:34:44 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 28 May 2015 12:34:44 +0200
Subject: [PATCH 10/10] mw command: Add 64bit support
In-Reply-To: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
References: <1432809284-17362-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1432809284-17362-11-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 commands/mw.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/commands/mw.c b/commands/mw.c
index f0384f6..8ca3c61 100644
--- a/commands/mw.c
+++ b/commands/mw.c
@@ -42,7 +42,7 @@ static int do_mem_mw(int argc, char *argv[])
 	loff_t adr;
 	int swab = 0;
 
-	if (mem_parse_options(argc, argv, "bwld:x", &mode, NULL, &filename,
+	if (mem_parse_options(argc, argv, "bwlqd:x", &mode, NULL, &filename,
 			&swab) < 0)
 		return 1;
 
@@ -59,6 +59,7 @@ static int do_mem_mw(int argc, char *argv[])
 		u8 val8;
 		u16 val16;
 		u32 val32;
+		u64 val64;
 		switch (mode) {
 		case O_RWSIZE_1:
 			val8 = simple_strtoul(argv[optind], NULL, 0);
@@ -76,6 +77,12 @@ static int do_mem_mw(int argc, char *argv[])
 				val32 = __swab32(val32);
 			ret = write(fd, &val32, 4);
 			break;
+		case O_RWSIZE_8:
+			val64 = simple_strtoull(argv[optind], NULL, 0);
+			if (swab)
+				val64 = __swab64(val64);
+			ret = write(fd, &val64, 8);
+			break;
 		}
 		if (ret < 0) {
 			perror("write");
@@ -97,6 +104,7 @@ BAREBOX_CMD_HELP_TEXT("Options:")
 BAREBOX_CMD_HELP_OPT ("-b",  "byte access")
 BAREBOX_CMD_HELP_OPT ("-w",  "word access (16 bit)")
 BAREBOX_CMD_HELP_OPT ("-l",  "long access (32 bit)")
+BAREBOX_CMD_HELP_OPT ("-q",  "quad access (64 bit)")
 BAREBOX_CMD_HELP_OPT ("-d FILE",  "write file (default /dev/mem)")
 BAREBOX_CMD_HELP_END
 
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:02 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:02 +0200
Subject: [PATCH v2 3/8] ARM: dts: socfpga: add qspi node
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-4-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 arch/arm/dts/socfpga.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index afac867c991d..251d87ed4ea2 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -587,6 +587,21 @@
 			status = "disabled";
 		};
 
+		qspi: spi at ff705000 {
+			compatible = "cdns,qspi-nor";
+                        #address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xff705000 0x1000>,
+			      <0xffa00000 0x1000>;
+			interrupts = <0 151 4>;
+			ext-decoder = <0>;  /* external decoder */
+			fifo-depth = <128>;
+			clocks = <&qspi_clk>;
+			clock-names = "qspi_clk";
+			status = "disabled";
+		};
+
+
 		/* Local timer */
 		timer at fffec600 {
 			compatible = "arm,cortex-a9-twd-timer";
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:55:59 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:55:59 +0200
Subject: [PATCH v2 0/8] Socfpga: QSPI support
Message-ID: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>

Hi!

This series adds support for reading,writing and booting from Quad SPI
flash chips on the SoCFPFGA platform.

The driver is based on a patch for linux, which is still in development.
As this driver uses the spi-nor framework, this is imported into barebox, too.
To deduplicate the code base, the m25p80 is also converted to use the spi-nor
framework.

With the QSPI driver in place, support for booting from it is also added.
As the preloader barebox doesn't have a devicetree to go from, the driver doesn't
touch the registers that have already been set up successfully by the Boot ROM code.
If there ever is any other user of the Cadence QSPI core, that does not have a
devicetree to probe from, platform code might have to be added for this initialization.
As there isn't at the moment, I chose to not bother with this.

The cadence-qspi was tested on the Socrates, Sockit and Socdk.
The m25p80 was tested as "m25p80" on a Phycore AM335x SOM.

Regards,
Steffen

Steffen Trumtrar (8):
  mtd: spi-nor: add SPI-NOR framework
  mtd: spi-nor: add cadence quadspi driver
  ARM: dts: socfpga: add qspi node
  ARM: socfpga: socdk add qspi flash
  ARM: socfpga: socrates: add qspi flash
  ARM: socfpga: sockit: add qspi flash
  ARM: socfpga: xload: support qspi bootsource
  mtd: m25p80: use the SPI nor framework

 Documentation/boards/socfpga.rst                  |   56 +-
 arch/arm/dts/socfpga.dtsi                         |   15 +
 arch/arm/dts/socfpga_cyclone5_socdk.dts           |   21 +
 arch/arm/dts/socfpga_cyclone5_sockit.dts          |   20 +
 arch/arm/dts/socfpga_cyclone5_socrates.dts        |   20 +
 arch/arm/mach-socfpga/include/mach/generic.h      |    5 +
 arch/arm/mach-socfpga/include/mach/socfpga-regs.h |    2 +
 arch/arm/mach-socfpga/xload.c                     |   58 +-
 drivers/mtd/Kconfig                               |    1 +
 drivers/mtd/Makefile                              |    1 +
 drivers/mtd/devices/Kconfig                       |    2 +-
 drivers/mtd/devices/m25p80.c                      |  998 +++--------------
 drivers/mtd/spi-nor/Kconfig                       |   15 +
 drivers/mtd/spi-nor/Makefile                      |    2 +
 drivers/mtd/spi-nor/cadence-quadspi.c             | 1211 +++++++++++++++++++++
 drivers/mtd/spi-nor/spi-nor.c                     | 1148 +++++++++++++++++++
 include/linux/mod_devicetable.h                   |    7 +
 include/linux/mtd/spi-nor.h                       |  204 ++++
 include/platform_data/cadence_qspi.h              |    9 +
 19 files changed, 2955 insertions(+), 840 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/Kconfig
 create mode 100644 drivers/mtd/spi-nor/Makefile
 create mode 100644 drivers/mtd/spi-nor/cadence-quadspi.c
 create mode 100644 drivers/mtd/spi-nor/spi-nor.c
 create mode 100644 include/linux/mtd/spi-nor.h
 create mode 100644 include/platform_data/cadence_qspi.h

-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:05 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:05 +0200
Subject: [PATCH v2 6/8] ARM: socfpga: sockit: add qspi flash
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-7-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 arch/arm/dts/socfpga_cyclone5_sockit.dts | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index e8e00aedfc10..1c3fb4d39c0b 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -119,3 +119,23 @@
 		interrupts = <0x0 0xa6 0x4>;
 	};
 };
+
+&qspi {
+	status = "okay";
+
+	flash: flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "n25q00";
+		reg = <0>;
+		spi-max-frequency = <108000000>;
+		m25p,fast-read;
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+	};
+};
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:03 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:03 +0200
Subject: [PATCH v2 4/8] ARM: socfpga: socdk add qspi flash
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-5-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 arch/arm/dts/socfpga_cyclone5_socdk.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts
index 025d07c18c02..d123bf679ecc 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts
@@ -61,3 +61,24 @@
 	vmmc-supply = <&regulator_3_3v>;
 	vqmmc-supply = <&regulator_3_3v>;
 };
+
+&qspi {
+	status = "okay";
+
+	flash: flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "n25q00";
+		reg = <0>;
+		spi-max-frequency = <108000000>;
+		m25p,fast-read;
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+	};
+};
+
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:04 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:04 +0200
Subject: [PATCH v2 5/8] ARM: socfpga: socrates: add qspi flash
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-6-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 arch/arm/dts/socfpga_cyclone5_socrates.dts | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts
index 7fa5e63076d4..125ad1b8502d 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts
@@ -62,3 +62,23 @@
 &mmc {
 	status = "okay";
 };
+
+&qspi {
+	status = "okay";
+
+	flash: flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "n25q00";
+		reg = <0>;
+		spi-max-frequency = <100000000>;
+		m25p,fast-read;
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+	};
+};
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:06 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:06 +0200
Subject: [PATCH v2 7/8] ARM: socfpga: xload: support qspi bootsource
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-8-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 Documentation/boards/socfpga.rst                  | 56 ++++++++++++++++++++--
 arch/arm/mach-socfpga/include/mach/generic.h      |  5 ++
 arch/arm/mach-socfpga/include/mach/socfpga-regs.h |  2 +
 arch/arm/mach-socfpga/xload.c                     | 58 ++++++++++++++++++++++-
 4 files changed, 115 insertions(+), 6 deletions(-)

diff --git a/Documentation/boards/socfpga.rst b/Documentation/boards/socfpga.rst
index e956bccbe24a..358e5ab91030 100644
--- a/Documentation/boards/socfpga.rst
+++ b/Documentation/boards/socfpga.rst
@@ -11,10 +11,34 @@ build the ``socfpga-xload_defconfig``; for second stage use the normal
 Bootstrapping
 -------------
 
-The supported bootsource is a SD card. The Boot ROM searches for a partition of
-type A2 and loads what it finds there. When barebox is placed in such a partition
-it will then itself try and mount the second partition of the SD card, which must
-be of type FAT32. On this partition barebox searches for a file called barebox.bin.
+The supported bootsources are: SD card and QSPI.
+
+Bootsource selection
+^^^^^^^^^^^^^^^^^^^^
+
++--------------+-----------+-----------+
+| Board        | BSEL[2:0] | CSEL[1:0] |
++==============+===========+===========+
+| Sockit SD    | 0b100     | 0b00      |
++--------------+-----------+-----------+
+| Sockit QSPI  | 0b110     | 0b00      |
++--------------+-----------+-----------+
+| Socrates SD  | 0b101     | 0b11      |
++--------------+-----------+-----------+
+| Socrates QSPI| 0b111     | 0b11      |
++--------------+-----------+-----------+
+| SocDK SD     | 0b100     | 0b00      |
++--------------+-----------+-----------+
+| SocDK QSPI   | 0b110     | 0b00      |
++--------------+-----------+-----------+
+
+SD card
+^^^^^^^
+
+The Boot ROM searches for a partition of type A2 and loads what it finds there.
+When barebox is placed in such a partition it will then itself try and mount the
+second partition of the SD card, which must be of type FAT32. On this partition
+barebox searches for a file called barebox.bin.
 
 To boot barebox on a Terasic SoCkit, the procedure is as follows (sdb1 is the A2 and
 sdb2 the FAT32 partition)::
@@ -34,6 +58,30 @@ proceed with::
 
 For the EBV Socrates use ``images/barebox-socfpga-socrates(-xload).img`` instead.
 
+QSPI
+^^^^
+
+The Boot ROM loads the preloader starting from address 0x0 on the QSPI flash.
+barebox then searches for a barebox image at the 256K offset and loads it.
+
+The default bootsource is SD card, so to change that to QSPI, you have to::
+
+  make socfpga-xload_defconfig
+  make menuconfig
+
+And then select the options `MTD` and `SPI_CADENCE_QUADSPI`. Now::
+
+  make
+  cat images/barebox-socfpga-<board>-xload.img > /dev/mtd0
+
+For barebox itself, the build step is like for SD card. The resulting image has to be
+written to the offset 256K.
+
+Warning! There is a known issue with booting from QSPI and doing Cold/Warm-Resets.
+Please consult `Rocketboards <http://rocketboards.org/foswiki/Documentation/SocBoardQspiBoot#Serial_Flash_Challenges>`_
+to see how to fix this.
+
+
 Updating handoff files
 ----------------------
 
diff --git a/arch/arm/mach-socfpga/include/mach/generic.h b/arch/arm/mach-socfpga/include/mach/generic.h
index 2f5cda0d0263..1f4247f803e3 100644
--- a/arch/arm/mach-socfpga/include/mach/generic.h
+++ b/arch/arm/mach-socfpga/include/mach/generic.h
@@ -15,4 +15,9 @@ static inline void __udelay(unsigned us)
 	for (i = 0; i < us * 3; i++);
 }
 
+struct socfpga_barebox_part {
+	unsigned int nor_offset;
+	unsigned int nor_size;
+};
+
 #endif /* __MACH_SOCFPGA_GENERIC_H */
diff --git a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
index b124ed675cfc..e88daf718917 100644
--- a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
@@ -2,6 +2,8 @@
 #define __MACH_SOCFPGA_REGS_H
 
 #define CYCLONE5_SDMMC_ADDRESS		0xff704000
+#define CYCLONE5_QSPI_CTRL_ADDRESS	0xff705000
+#define CYCLONE5_QSPI_DATA_ADDRESS	0xffa00000
 #define CYCLONE5_FPGAMGRREGS_ADDRESS	0xff706000
 #define CYCLONE5_GPIO0_BASE		0xff708000
 #define CYCLONE5_GPIO1_BASE		0xff709000
diff --git a/arch/arm/mach-socfpga/xload.c b/arch/arm/mach-socfpga/xload.c
index 3380092168ae..272896b6bda0 100644
--- a/arch/arm/mach-socfpga/xload.c
+++ b/arch/arm/mach-socfpga/xload.c
@@ -1,3 +1,4 @@
+#include <platform_data/cadence_qspi.h>
 #include <platform_data/dw_mmc.h>
 #include <bootsource.h>
 #include <bootstrap.h>
@@ -14,11 +15,19 @@
 #include <linux/stat.h>
 #include <linux/clk.h>
 
+#include <mach/generic.h>
 #include <mach/system-manager.h>
 #include <mach/socfpga-regs.h>
 
+struct socfpga_barebox_part *barebox_part;
+
+static struct socfpga_barebox_part default_part = {
+	.nor_offset = SZ_256K,
+	.nor_size = SZ_1M,
+};
+
 enum socfpga_clks {
-	timer, mmc, uart, clk_max
+	timer, mmc, qspi_clk, uart, clk_max
 };
 
 static struct clk *clks[clk_max];
@@ -35,6 +44,43 @@ static void socfpga_mmc_init(void)
 			IORESOURCE_MEM, &mmc_pdata);
 }
 
+#if defined(CONFIG_SPI_CADENCE_QUADSPI)
+static struct cadence_qspi_platform_data qspi_pdata = {
+	.ext_decoder = 0,
+	.fifo_depth = 128,
+};
+
+static __maybe_unused void add_cadence_qspi_device(int id, resource_size_t ctrl,
+				    resource_size_t data, void *pdata)
+{
+	struct resource *res;
+
+	res = xzalloc(sizeof(struct resource) * 2);
+	res[0].start = ctrl;
+	res[0].end = ctrl + 0x100 - 1;
+	res[0].flags = IORESOURCE_MEM;
+	res[1].start = data;
+	res[1].end = data + 0x100 - 1;
+	res[1].flags = IORESOURCE_MEM;
+
+	add_generic_device_res("cadence_qspi", id, res, 2, pdata);
+}
+
+static __maybe_unused void socfpga_qspi_init(void)
+{
+	clks[qspi_clk] = clk_fixed("qspi_clk", 370000000);
+	clkdev_add_physbase(clks[qspi_clk], CYCLONE5_QSPI_CTRL_ADDRESS, NULL);
+	clkdev_add_physbase(clks[qspi_clk], CYCLONE5_QSPI_DATA_ADDRESS, NULL);
+	add_cadence_qspi_device(0, CYCLONE5_QSPI_CTRL_ADDRESS,
+				CYCLONE5_QSPI_DATA_ADDRESS, &qspi_pdata);
+}
+#else
+static void socfpga_qspi_init(void)
+{
+	return;
+}
+#endif
+
 static struct NS16550_plat uart_pdata = {
 	.clock = 100000000,
 	.shift = 2,
@@ -62,10 +108,19 @@ static __noreturn int socfpga_xload(void)
 	enum bootsource bootsource = bootsource_get();
 	void *buf;
 
+	if (!barebox_part)
+		barebox_part = &default_part;
+
 	switch (bootsource) {
 	case BOOTSOURCE_MMC:
+		socfpga_mmc_init();
 		buf = bootstrap_read_disk("disk0.1", "fat");
 		break;
+	case BOOTSOURCE_SPI:
+		socfpga_qspi_init();
+		buf = bootstrap_read_devfs("mtd0", false, barebox_part->nor_offset,
+					barebox_part->nor_size, SZ_1M);
+		break;
 	default:
 		pr_err("unknown bootsource %d\n", bootsource);
 		hang();
@@ -88,7 +143,6 @@ static int socfpga_devices_init(void)
 	barebox_set_model("SoCFPGA");
 	socfpga_timer_init();
 	socfpga_uart_init();
-	socfpga_mmc_init();
 
 	barebox_main = socfpga_xload;
 
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:07 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:07 +0200
Subject: [PATCH v2 8/8] mtd: m25p80: use the SPI nor framework
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-9-git-send-email-s.trumtrar@pengutronix.de>

Use the spi-nor framework for the m25p80 driver to de-duplicate the code base
and follow along with the linux kernel version, so bugfixes or features can be
easier integrated.

Based on the Linux v4.1-rc3 version of m25p80.c.

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 drivers/mtd/devices/Kconfig  |   2 +-
 drivers/mtd/devices/m25p80.c | 998 +++++++------------------------------------
 2 files changed, 166 insertions(+), 834 deletions(-)

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 7f9c30625844..345c348c692b 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -21,7 +21,7 @@ config MTD_DATAFLASH_WRITE_VERIFY
 
 config MTD_M25P80
 	tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
-	depends on SPI
+	depends on MTD_SPI_NOR
 	help
 	  This enables access to most modern SPI flash chips, used for
 	  program and data storage. Series supported include Atmel AT26DF,
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 095a4ca0936c..c941767de94c 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -25,774 +25,202 @@
 #include <errno.h>
 #include <linux/err.h>
 #include <clock.h>
-#include <linux/math64.h>
-#include <linux/mtd/cfi.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/mod_devicetable.h>
 
-/* Flash opcodes. */
-#define	OPCODE_WREN		0x06	/* Write enable */
-#define	OPCODE_RDSR		0x05	/* Read status register */
-#define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
-#define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
-#define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
-#define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
-#define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
-#define	OPCODE_BE_32K		0x52	/* Erase 32KiB block */
-#define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
-#define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
-#define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
-
-/* Used for SST flashes only. */
-#define	OPCODE_BP		0x02	/* Byte program */
-#define	OPCODE_WRDI		0x04	/* Write disable */
-#define	OPCODE_AAI_WP		0xad	/* Auto address increment word program */
-
-/* Used for Macronix flashes only. */
-#define	OPCODE_EN4B		0xb7	/* Enter 4-byte mode */
-#define	OPCODE_EX4B		0xe9	/* Exit 4-byte mode */
-
-/* Used for Spansion flashes only. */
-#define	OPCODE_BRWR		0x17	/* Bank register write */
-
-/* Status Register bits. */
-#define	SR_WIP			1	/* Write in progress */
-#define	SR_WEL			2	/* Write enable latch */
-/* meaning of other SR_* bits may differ between vendors */
-#define	SR_BP0			4	/* Block protect 0 */
-#define	SR_BP1			8	/* Block protect 1 */
-#define	SR_BP2			0x10	/* Block protect 2 */
-#define	SR_SRWD			0x80	/* SR write protect */
-
-/* Define max times to check status register before we give up. */
-#define	MAX_READY_WAIT		40	/* M25P16 specs 40s max chip erase */
 #define MAX_CMD_SIZE		6
 
-#define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
-
-/****************************************************************************/
-
-#define SPI_NAME_SIZE   32
-
 struct m25p {
 	struct spi_device	*spi;
+	struct spi_nor		spi_nor;
 	struct mtd_info		mtd;
-	u16			page_size;
-	unsigned		sector_size;
-	u16			addr_width;
-	u8			erase_opcode;
-	u8			erase_opcode_4k;
-	u8			*command;
+	u8			command[MAX_CMD_SIZE];
 };
 
-static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
-{
-	return container_of(mtd, struct m25p, mtd);
-}
-
-/****************************************************************************/
-
-/*
- * Internal helper functions
- */
-
-/*
- * Read the status register, returning its value in the location
- * Return the status register value.
- * Returns negative if error occurred.
- */
-static int read_sr(struct m25p *flash)
-{
-	ssize_t retval;
-	u8 code = OPCODE_RDSR;
-	u8 val;
-
-	retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
-
-	if (retval < 0) {
-		dev_err(&flash->spi->dev, "error %d reading SR\n",
-				(int) retval);
-		return retval;
-	}
-
-	return val;
-}
-
-/*
- * Write status register 1 byte
- * Returns negative if error occurred.
- */
-static int write_sr(struct m25p *flash, u8 val)
-{
-	flash->command[0] = OPCODE_WRSR;
-	flash->command[1] = val;
-
-	return spi_write(flash->spi, flash->command, 2);
-}
-
-/*
- * Set write enable latch with Write Enable command.
- * Returns negative if error occurred.
- */
-static inline int write_enable(struct m25p *flash)
-{
-	u8	code = OPCODE_WREN;
-
-	return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
-}
-
-/*
- * Send write disble instruction to the chip.
- */
-static inline int write_disable(struct m25p *flash)
-{
-	u8	code = OPCODE_WRDI;
-
-	return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
-}
-
-/*
- * Enable/disable 4-byte addressing mode.
- */
-static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)
-{
-	switch (JEDEC_MFR(jedec_id)) {
-	case CFI_MFR_MACRONIX:
-		flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
-		return spi_write(flash->spi, flash->command, 1);
-	default:
-		/* Spansion style */
-		flash->command[0] = OPCODE_BRWR;
-		flash->command[1] = enable << 7;
-		return spi_write(flash->spi, flash->command, 2);
-	}
-}
-
-/*
- * Service routine to read status register until ready, or timeout occurs.
- * Returns non-zero if error.
- */
-static int wait_till_ready(struct m25p *flash)
+static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
 {
-	int sr;
-	uint64_t timer_start;
+	struct m25p *flash = nor->priv;
+	struct spi_device *spi = flash->spi;
+	int ret;
 
-	timer_start = get_time_ns();
+	ret = spi_write_then_read(spi, &code, 1, val, len);
+	if (ret < 0)
+		dev_err(&spi->dev, "error %d reading %x\n", ret, code);
 
-	do {
-		if ((sr = read_sr(flash)) < 0)
-			break;
-		else if (!(sr & SR_WIP))
-			return 0;
-
-	} while (!(is_timeout(timer_start, MAX_READY_WAIT * SECOND)));
-
-	return -ETIMEDOUT;
-}
-
-/*
- * Erase the whole flash memory
- *
- * Returns 0 if successful, non-zero otherwise.
- */
-static int erase_chip(struct m25p *flash)
-{
-	dev_dbg(&flash->spi->dev, "%s %lldKiB\n",
-		__func__, (long long)(flash->mtd.size >> 10));
-
-	/* Wait until finished previous write command. */
-	if (wait_till_ready(flash))
-		return -ETIMEDOUT;
-
-	/* Send write enable, then erase commands. */
-	write_enable(flash);
-
-	/* Set up command buffer. */
-	flash->command[0] = OPCODE_CHIP_ERASE;
-
-	spi_write(flash->spi, flash->command, 1);
-
-	return 0;
+	return ret;
 }
 
-static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
+static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, u8 *cmd)
 {
 	/* opcode is in cmd[0] */
-	cmd[1] = addr >> (flash->addr_width * 8 -  8);
-	cmd[2] = addr >> (flash->addr_width * 8 - 16);
-	cmd[3] = addr >> (flash->addr_width * 8 - 24);
-	cmd[4] = addr >> (flash->addr_width * 8 - 32);
+	cmd[1] = addr >> (nor->addr_width * 8 -  8);
+	cmd[2] = addr >> (nor->addr_width * 8 - 16);
+	cmd[3] = addr >> (nor->addr_width * 8 - 24);
+	cmd[4] = addr >> (nor->addr_width * 8 - 32);
 }
 
-static int m25p_cmdsz(struct m25p *flash)
+static int m25p_cmdsz(struct spi_nor *nor)
 {
-	return 1 + flash->addr_width;
-}
-
-/*
- * Erase one sector of flash memory at offset ``offset'' which is any
- * address within the sector which should be erased.
- *
- * Returns 0 if successful, non-zero otherwise.
- */
-static int erase_sector(struct m25p *flash, u32 offset, u32 command)
-{
-	dev_dbg(&flash->spi->dev, "%s %dKiB at 0x%08x\n",
-		__func__, flash->mtd.erasesize / 1024, offset);
-
-	/* Wait until finished previous write command. */
-	if (wait_till_ready(flash))
-		return -ETIMEDOUT;
-
-	/* Send write enable, then erase commands. */
-	write_enable(flash);
-
-	/* Set up command buffer. */
-	flash->command[0] = command;
-	m25p_addr2cmd(flash, offset, flash->command);
-
-	spi_write(flash->spi, flash->command, m25p_cmdsz(flash));
-
-	return 0;
+	return 1 + nor->addr_width;
 }
 
-/****************************************************************************/
-
-/*
- * MTD implementation
- */
-
-/*
- * Erase an address range on the flash chip.  The address range may extend
- * one or more erase sectors.  Return an error is there is a problem erasing.
- */
-static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
+			    int wr_en)
 {
-	struct m25p *flash = mtd_to_m25p(mtd);
-	u32 addr;
-	uint32_t rem;
-	uint64_t len;
-
-	dev_dbg(&flash->spi->dev, "%s at 0x%llx, len %lld\n",
-			__func__, (long long)instr->addr,
-			(long long)instr->len);
-
-	div_u64_rem(instr->len, mtd->erasesize, &rem);
-	if (rem)
-		return -EINVAL;
-
-	addr = instr->addr;
-	len = instr->len;
-
-	/* whole-chip erase? */
-	if (len == flash->mtd.size) {
-		if (erase_chip(flash)) {
-			instr->state = MTD_ERASE_FAILED;
-			return -EIO;
-		}
-		return 0;
-	}
-
-	if (flash->erase_opcode_4k) {
-		while (len && (addr & (flash->sector_size - 1))) {
-			if (ctrlc())
-				return -EINTR;
-			if (erase_sector(flash, addr, flash->erase_opcode_4k))
-				return -EIO;
-			addr += mtd->erasesize;
-			len -= mtd->erasesize;
-		}
-
-		while (len >= flash->sector_size) {
-			if (ctrlc())
-				return -EINTR;
-			if (erase_sector(flash, addr, flash->erase_opcode))
-				return -EIO;
-			addr += flash->sector_size;
-			len -= flash->sector_size;
-		}
-
-		while (len) {
-			if (ctrlc())
-				return -EINTR;
-			if (erase_sector(flash, addr, flash->erase_opcode_4k))
-				return -EIO;
-			addr += mtd->erasesize;
-			len -= mtd->erasesize;
-		}
-	} else {
-		while (len) {
-			if (ctrlc())
-				return -EINTR;
-			if (erase_sector(flash, addr, flash->erase_opcode))
-				return -EIO;
-
-			if (len <= mtd->erasesize)
-				break;
-			addr += mtd->erasesize;
-			len -= mtd->erasesize;
-		}
-	}
+	struct m25p *flash = nor->priv;
+	struct spi_device *spi = flash->spi;
 
-	if (wait_till_ready(flash))
-		return -ETIMEDOUT;
+	flash->command[0] = opcode;
+	if (buf)
+		memcpy(&flash->command[1], buf, len);
 
-	instr->state = MTD_ERASE_DONE;
-	mtd_erase_callback(instr);
-
-	return 0;
+	return spi_write(spi, flash->command, len + 1);
 }
 
-/*
- * Read an address range from the flash chip.  The address range
- * may be any size provided it is within the physical boundaries.
- */
-static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
-	size_t *retlen, u_char *buf)
+static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
+			 size_t *retlen, const u_char *buf)
 {
-	struct m25p *flash = mtd_to_m25p(mtd);
-	struct spi_transfer t[2];
+	struct m25p *flash = nor->priv;
+	struct spi_device *spi = flash->spi;
+	struct spi_transfer t[2] = {};
 	struct spi_message m;
-	int fast_read = 0;
-
-	if (flash->spi->max_speed_hz >= 25000000)
-		fast_read = 1;
+	int cmd_sz = m25p_cmdsz(nor);
 
 	spi_message_init(&m);
-	memset(t, 0, (sizeof t));
 
-	/* NOTE:
-	 * OPCODE_FAST_READ (if available) is faster.
-	 * Should add 1 byte DUMMY_BYTE.
-	 */
+	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+		cmd_sz = 1;
+
+	flash->command[0] = nor->program_opcode;
+	m25p_addr2cmd(nor, to, flash->command);
+
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + fast_read;
+	t[0].len = cmd_sz;
 	spi_message_add_tail(&t[0], &m);
 
-	t[1].rx_buf = buf;
+	t[1].tx_buf = buf;
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
 
-	/* Wait till previous write/erase is done. */
-	if (wait_till_ready(flash))
-		return -ETIMEDOUT;
-
-	/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
-	 * clocks; and at this writing, every chip this driver handles
-	 * supports that opcode.
-	 */
+	spi_sync(spi, &m);
 
-	/* Set up the write data buffer. */
-	flash->command[0] = fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ;
-	m25p_addr2cmd(flash, from, flash->command);
-
-	spi_sync(flash->spi, &m);
-
-	*retlen = m.actual_length - m25p_cmdsz(flash) - fast_read;
-
-	return 0;
+	*retlen += m.actual_length - cmd_sz;
 }
 
 /*
- * Write an address range to the flash chip.  Data must be written in
- * FLASH_PAGESIZE chunks.  The address range may be any size provided
- * it is within the physical boundaries.
+ * Read an address range from the nor chip.  The address range
+ * may be any size provided it is within the physical boundaries.
  */
-static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
-	size_t *retlen, const u_char *buf)
+static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
+		       size_t *retlen, u_char *buf)
 {
-	struct m25p *flash = mtd_to_m25p(mtd);
-	u32 page_offset, page_size;
+	struct m25p *flash = nor->priv;
+	struct spi_device *spi = flash->spi;
 	struct spi_transfer t[2];
 	struct spi_message m;
+	unsigned int dummy = nor->read_dummy;
 
-	dev_dbg(&flash->spi->dev, "m25p80_write %ld bytes at 0x%08llx\n",
-			(unsigned long)len, to);
+	/* convert the dummy cycles to the number of bytes */
+	dummy /= 8;
 
 	spi_message_init(&m);
 	memset(t, 0, (sizeof t));
 
+	flash->command[0] = nor->read_opcode;
+	m25p_addr2cmd(nor, from, flash->command);
+
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash);
+	t[0].len = m25p_cmdsz(nor) + dummy;
 	spi_message_add_tail(&t[0], &m);
 
-	t[1].tx_buf = buf;
+	t[1].rx_buf = buf;
+	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
 
-	/* Wait until finished previous write command. */
-	if (wait_till_ready(flash))
-		return -ETIMEDOUT;
-
-	write_enable(flash);
-
-	/* Set up the opcode in the write buffer. */
-	flash->command[0] = OPCODE_PP;
-	m25p_addr2cmd(flash, to, flash->command);
-
-	page_offset = to & (flash->page_size - 1);
-
-	/* do all the bytes fit onto one page? */
-	if (page_offset + len <= flash->page_size) {
-		t[1].len = len;
-
-		spi_sync(flash->spi, &m);
-
-		*retlen = m.actual_length - m25p_cmdsz(flash);
-	} else {
-		u32 i;
-
-		/* the size of data remaining on the first page */
-		page_size = flash->page_size - page_offset;
-
-		t[1].len = page_size;
-		spi_sync(flash->spi, &m);
-
-		*retlen = m.actual_length - m25p_cmdsz(flash);
-
-		/* write everything in flash->page_size chunks */
-		for (i = page_size; i < len; i += page_size) {
-			page_size = len - i;
-			if (page_size > flash->page_size)
-				page_size = flash->page_size;
-
-			/* write the next page to flash */
-			m25p_addr2cmd(flash, to + i, flash->command);
-
-			t[1].tx_buf = buf + i;
-			t[1].len = page_size;
-
-			wait_till_ready(flash);
-
-			write_enable(flash);
-
-			spi_sync(flash->spi, &m);
-
-			*retlen += m.actual_length - m25p_cmdsz(flash);
-		}
-	}
+	spi_sync(spi, &m);
 
+	*retlen = m.actual_length - m25p_cmdsz(nor) - dummy;
 	return 0;
 }
 
-static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
-		size_t *retlen, const u_char *buf)
+static int m25p80_erase(struct spi_nor *nor, loff_t offset)
 {
-	struct m25p *flash = mtd_to_m25p(mtd);
-	struct spi_transfer t[2];
-	struct spi_message m;
-	size_t actual;
-	int cmd_sz, ret;
+	struct m25p *flash = nor->priv;
 
-	dev_dbg(&flash->spi->dev, "%s to 0x%08x, len %zd\n",
-			__func__, (u32)to, len);
+        dev_dbg(nor->dev, "%dKiB at 0x%08x\n",
+                flash->mtd.erasesize / 1024, (u32)offset);
 
-	spi_message_init(&m);
-	memset(t, 0, (sizeof t));
+        /* Set up command buffer. */
+        flash->command[0] = nor->erase_opcode;
+        m25p_addr2cmd(nor, offset, flash->command);
 
-	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash);
-	spi_message_add_tail(&t[0], &m);
+        spi_write(flash->spi, flash->command, m25p_cmdsz(nor));
 
-	t[1].tx_buf = buf;
-	spi_message_add_tail(&t[1], &m);
-
-	/* Wait until finished previous write command. */
-	ret = wait_till_ready(flash);
-	if (ret)
-		goto time_out;
-
-	write_enable(flash);
-
-	actual = to % 2;
-	/* Start write from odd address. */
-	if (actual) {
-		flash->command[0] = OPCODE_BP;
-		m25p_addr2cmd(flash, to, flash->command);
-
-		/* write one byte. */
-		t[1].len = 1;
-		spi_sync(flash->spi, &m);
-		ret = wait_till_ready(flash);
-		if (ret)
-			goto time_out;
-		*retlen += m.actual_length - m25p_cmdsz(flash);
-	}
-	to += actual;
-
-	flash->command[0] = OPCODE_AAI_WP;
-	m25p_addr2cmd(flash, to, flash->command);
-
-	/* Write out most of the data here. */
-	cmd_sz = m25p_cmdsz(flash);
-	for (; actual < len - 1; actual += 2) {
-		t[0].len = cmd_sz;
-		/* write two bytes. */
-		t[1].len = 2;
-		t[1].tx_buf = buf + actual;
-
-		spi_sync(flash->spi, &m);
-		ret = wait_till_ready(flash);
-		if (ret)
-			goto time_out;
-		*retlen += m.actual_length - cmd_sz;
-		cmd_sz = 1;
-		to += 2;
-	}
-	write_disable(flash);
-	ret = wait_till_ready(flash);
-	if (ret)
-		goto time_out;
-
-	/* Write out trailing byte if it exists. */
-	if (actual != len) {
-		write_enable(flash);
-		flash->command[0] = OPCODE_BP;
-		m25p_addr2cmd(flash, to, flash->command);
-		t[0].len = m25p_cmdsz(flash);
-		t[1].len = 1;
-		t[1].tx_buf = buf + actual;
-
-		spi_sync(flash->spi, &m);
-		ret = wait_till_ready(flash);
-		if (ret)
-			goto time_out;
-		*retlen += m.actual_length - m25p_cmdsz(flash);
-		write_disable(flash);
-	}
-
-time_out:
-	return ret;
+	return 0;
 }
 
-/****************************************************************************/
-
 /*
- * SPI device driver setup and teardown
- */
-
-struct flash_info {
-	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
-	 * a high byte of zero plus three data bytes: the manufacturer id,
-	 * then a two byte device id.
-	 */
-	u32		jedec_id;
-	u16             ext_id;
-
-	/* The size listed here is what works with OPCODE_SE, which isn't
-	 * necessarily called a "sector" by the vendor.
-	 */
-	unsigned	sector_size;
-	u16		n_sectors;
-
-	u16		page_size;
-	u16		addr_width;
-
-	u16		flags;
-#define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */
-#define	M25P_NO_ERASE	0x02		/* No erase command needed */
-};
-
-#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-	((unsigned long)&(struct flash_info) {				\
-		.jedec_id = (_jedec_id),				\
-		.ext_id = (_ext_id),					\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = 256,					\
-		.flags = (_flags),					\
-	})
-
-#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width)	\
-	((unsigned long)&(struct flash_info) {				\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = (_page_size),				\
-		.addr_width = (_addr_width),				\
-		.flags = M25P_NO_ERASE,					\
-	})
-
-/* NOTE: double check command sets and memory organization when you add
- * more flash chips.  This current list focusses on newer chips, which
- * have been converging on command sets which including JEDEC ID.
+ * Do NOT add to this array without reading the following:
+ *
+ * Historically, many flash devices are bound to this driver by their name. But
+ * since most of these flash are compatible to some extent, and their
+ * differences can often be differentiated by the JEDEC read-ID command, we
+ * encourage new users to add support to the spi-nor library, and simply bind
+ * against a generic string here (e.g., "nor-jedec").
+ *
+ * Many flash names are kept here in this list (as well as in spi-nor.c) to
+ * keep them available as module aliases for existing platforms.
  */
 static const struct platform_device_id m25p_ids[] = {
-	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
-	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
-	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
-
-	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
-	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
-	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
-
-	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
-	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
-	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
-	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
-
-	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
-
-	/* EON -- en25xxx */
-	{ "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
-	{ "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
-	{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
-	{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
-	{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
-
-	/* Everspin */
-	{ "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2) },
-
-	/* Intel/Numonyx -- xxxs33b */
-	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
-	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
-	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
-	{ "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
-
-	/* Macronix */
-	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
-	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
-	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
-	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
-	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
-	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
-	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
-	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-
-	/* Micron */
-	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
-	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
-	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
-	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
-
-	/* Spansion -- single (large) sector size only, at least
-	 * for the chips listed here (without boot sectors).
-	 */
-	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
-	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
-	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
-	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
-	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
-	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
-	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
-	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
-	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
-	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
-	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
-	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
-	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
-	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
-	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
-	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
-
-	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
-	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K) },
-	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K) },
-	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K) },
-	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K) },
-	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K) },
-	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K) },
-	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K) },
-	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K) },
-
-	/* ST Microelectronics -- newer production may have feature updates */
-	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
-	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
-	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
-	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
-	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
-	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
-	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
-	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
-	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
-	{ "n25q032", INFO(0x20ba16,  0,  64 * 1024,  64, 0) },
-
-	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
-	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
-	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
-	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
-	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
-	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
-	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
-	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
-	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
-
-	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
-	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
-	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
-
-	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
-	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
-	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
-
-	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
-
-	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
-	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
-	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
-	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
-	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
-	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
-	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) },
-	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
-
-	/* Catalyst / On Semiconductor -- non-JEDEC */
-	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
-	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2) },
-	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2) },
-	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2) },
-	{ "cat25128", CAT25_INFO(2048, 8, 64, 2) },
+	{"at25fs010"},  {"at25fs040"},  {"at25df041a"}, {"at25df321a"},
+	{"at25df641"},  {"at26f004"},   {"at26df081a"}, {"at26df161a"},
+	{"at26df321"},  {"at45db081d"},
+	{"en25f32"},    {"en25p32"},    {"en25q32b"},   {"en25p64"},
+	{"en25q64"},    {"en25qh128"},  {"en25qh256"},
+	{"f25l32pa"},
+	{"mr25h256"},   {"mr25h10"},
+	{"gd25q32"},    {"gd25q64"},
+	{"160s33b"},    {"320s33b"},    {"640s33b"},
+	{"mx25l2005a"}, {"mx25l4005a"}, {"mx25l8005"},  {"mx25l1606e"},
+	{"mx25l3205d"}, {"mx25l3255e"}, {"mx25l6405d"}, {"mx25l12805d"},
+	{"mx25l12855e"},{"mx25l25635e"},{"mx25l25655e"},{"mx66l51235l"},
+	{"mx66l1g55g"},
+	{"n25q064"},    {"n25q128a11"}, {"n25q128a13"}, {"n25q256a"},
+	{"n25q512a"},   {"n25q512ax3"}, {"n25q00"},
+	{"pm25lv512"},  {"pm25lv010"},  {"pm25lq032"},
+	{"s25sl032p"},  {"s25sl064p"},  {"s25fl256s0"}, {"s25fl256s1"},
+	{"s25fl512s"},  {"s70fl01gs"},  {"s25sl12800"}, {"s25sl12801"},
+	{"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"},  {"s25sl008a"},
+	{"s25sl016a"},  {"s25sl032a"},  {"s25sl064a"},  {"s25fl008k"},
+	{"s25fl016k"},  {"s25fl064k"},  {"s25fl132k"},
+	{"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"},
+	{"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"},
+	{"sst25wf040"},
+	{"m25p05"},     {"m25p10"},     {"m25p20"},     {"m25p40"},
+	{"m25p80"},     {"m25p16"},     {"m25p32"},     {"m25p64"},
+	{"m25p128"},    {"n25q032"},
+	{"m25p05-nonjedec"},    {"m25p10-nonjedec"},    {"m25p20-nonjedec"},
+	{"m25p40-nonjedec"},    {"m25p80-nonjedec"},    {"m25p16-nonjedec"},
+	{"m25p32-nonjedec"},    {"m25p64-nonjedec"},    {"m25p128-nonjedec"},
+	{"m45pe10"},    {"m45pe80"},    {"m45pe16"},
+	{"m25pe20"},    {"m25pe80"},    {"m25pe16"},
+	{"m25px16"},    {"m25px32"},    {"m25px32-s0"}, {"m25px32-s1"},
+	{"m25px64"},    {"m25px80"},
+	{"w25x10"},     {"w25x20"},     {"w25x40"},     {"w25x80"},
+	{"w25x16"},     {"w25x32"},     {"w25q32"},     {"w25q32dw"},
+	{"w25x64"},     {"w25q64"},     {"w25q80"},     {"w25q80bl"},
+	{"w25q128"},    {"w25q256"},    {"cat25c11"},
+	{"cat25c03"},   {"cat25c09"},   {"cat25c17"},   {"cat25128"},
+
+        /*
+         * Generic support for SPI NOR that can be identified by the JEDEC READ
+         * ID opcode (0x9F). Use this, if possible.
+         */
+        {"nor-jedec"},
 	{ },
 };
 
-static const struct platform_device_id *jedec_probe(struct spi_device *spi)
-{
-	int			tmp;
-	u8			code = OPCODE_RDID;
-	u8			id[5];
-	u32			jedec;
-	u16			ext_jedec;
-	struct flash_info	*info;
-
-	/* JEDEC also defines an optional "extended device information"
-	 * string for after vendor-specific data, after the three bytes
-	 * we use here.  Supporting some chips might require using it.
-	 */
-	tmp = spi_write_then_read(spi, &code, 1, id, 5);
-	if (tmp < 0) {
-		dev_dbg(&spi->dev, "%s: error %d reading JEDEC ID\n",
-				dev_name(&spi->dev), tmp);
-		return ERR_PTR(tmp);
-	}
-	jedec = id[0];
-	jedec = jedec << 8;
-	jedec |= id[1];
-	jedec = jedec << 8;
-	jedec |= id[2];
-
-	ext_jedec = id[3] << 8 | id[4];
-
-	for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
-		info = (void *)m25p_ids[tmp].driver_data;
-		if (info->jedec_id == jedec) {
-			if (info->ext_id != 0 && info->ext_id != ext_jedec)
-				continue;
-			return &m25p_ids[tmp];
-		}
-	}
-	dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
-	return ERR_PTR(-ENODEV);
-}
-
-
 /*
  * board specific setup should have ensured the SPI clock used here
  * matches what the READ command supports, at least until this driver
@@ -801,164 +229,68 @@ static const struct platform_device_id *jedec_probe(struct spi_device *spi)
 static int m25p_probe(struct device_d *dev)
 {
 	struct spi_device *spi = (struct spi_device *)dev->type_data;
-	const struct platform_device_id	*id = NULL;
 	struct flash_platform_data	*data;
 	struct m25p			*flash;
-	struct flash_info		*info = NULL;
-	unsigned			i;
-	unsigned			do_jdec_probe = 1;
-	char				*flashname = NULL;
-	const char			*typename = NULL;
+	struct spi_nor			*nor;
+	enum read_mode mode =		SPI_NOR_NORMAL;
+	char				*flash_name = NULL;
 	int				device_id;
+	int ret;
 
-	/* Platform data helps sort out which chip type we have, as
-	 * well as how this board partitions it.  If we don't have
-	 * a chip ID, try the JEDEC id commands; they'll work for most
-	 * newer chips, even if we don't recognize the particular chip.
-	 */
 	data = dev->platform_data;
-	if (data && data->type)
-		typename = data->type;
-	else if (dev->id_entry)
-		typename = dev->id_entry->name;
-
-	if (typename) {
-		const struct platform_device_id *plat_id;
-
-		for (i = 0; i < ARRAY_SIZE(m25p_ids) - 1; i++) {
-			plat_id = &m25p_ids[i];
-			if (strcmp(typename, plat_id->name))
-				continue;
-			break;
-		}
-
-		if (i < ARRAY_SIZE(m25p_ids) - 1) {
-			id = plat_id;
-			info = (void *)id->driver_data;
-			/* If flash type is provided but the memory is not
-			 * JEDEC compliant, don't try to probe the JEDEC id */
-			if (!info->jedec_id)
-				do_jdec_probe = 0;
-		} else
-			dev_warn(&spi->dev, "unrecognized id %s\n", typename);
-	}
-
-	if (do_jdec_probe) {
-		const struct platform_device_id *jid;
-
-		jid = jedec_probe(spi);
-		if (IS_ERR(jid)) {
-			return PTR_ERR(jid);
-		} else if (jid != id) {
-			/*
-			 * JEDEC knows better, so overwrite platform ID. We
-			 * can't trust partitions any longer, but we'll let
-			 * mtd apply them anyway, since some partitions may be
-			 * marked read-only, and we don't want to lose that
-			 * information, even if it's not 100% accurate.
-			 */
-			if (id)
-				dev_warn(dev, "found %s, expected %s\n",
-					jid->name, id->name);
-
-			id = jid;
-			info = (void *)jid->driver_data;
-		}
-	}
 
 	flash = xzalloc(sizeof *flash);
-	flash->command = xmalloc(MAX_CMD_SIZE);
 
+	nor = &flash->spi_nor;
+
+	/* install the hooks */
+	nor->read = m25p80_read;
+	nor->write = m25p80_write;
+	nor->erase = m25p80_erase;
+	nor->write_reg = m25p80_write_reg;
+	nor->read_reg = m25p80_read_reg;
+
+	nor->dev = dev;
+	nor->mtd = &flash->mtd;
+	nor->priv = flash;
+
+	flash->mtd.priv = nor;
+	flash->mtd.parent = &spi->dev;
 	flash->spi = spi;
+
 	dev->priv = (void *)flash;
-	/*
-	 * Atmel, SST and Intel/Numonyx serial flash tend to power
-	 * up with the software protection bits set
-	 */
-
-	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL ||
-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL ||
-	    JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) {
-		write_enable(flash);
-		write_sr(flash, 0);
-	}
+
+	if (data && data->name)
+		flash->mtd.name = data->name;
+
+	if (data && data->type)
+		flash_name = data->type;
+	else if (data && data->name)
+		flash_name = data->name;
+	else if (dev->id_entry)
+		flash_name = dev->id_entry->name;
+	else
+		flash_name = NULL; /* auto-detect */
+
+	ret = spi_nor_scan(nor, flash_name, mode);
+	if (ret)
+		return ret;
 
 	device_id = DEVICE_ID_SINGLE;
 	if (dev->device_node) {
 		const char *alias = of_alias_get(dev->device_node);
 		if (alias)
-			flashname = xstrdup(alias);
+			flash_name = xstrdup(alias);
 	} else if (data && data->name) {
-		flashname = data->name;
+		flash_name = data->name;
 	}
 
-	if (!flashname) {
+	if (!flash_name) {
 		device_id = DEVICE_ID_DYNAMIC;
-		flashname = "m25p";
-	}
-
-	flash->mtd.type = MTD_NORFLASH;
-	flash->mtd.writesize = 1;
-	flash->mtd.flags = MTD_CAP_NORFLASH;
-	flash->mtd.size = (uint64_t)info->sector_size * info->n_sectors;
-	flash->mtd.erase = m25p80_erase;
-	flash->mtd.read = m25p80_read;
-
-	/* sst flash chips use AAI word program */
-	if (IS_ENABLED(CONFIG_MTD_SST25L) && JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
-		flash->mtd.write = sst_write;
-	else
-		flash->mtd.write = m25p80_write;
-
-	/* prefer "small sector" erase if possible */
-	if (info->flags & SECT_4K) {
-		flash->erase_opcode_4k = OPCODE_BE_4K;
-		flash->erase_opcode = OPCODE_SE;
-		flash->mtd.erasesize = 4096;
-	} else {
-		flash->erase_opcode = OPCODE_SE;
-		flash->mtd.erasesize = info->sector_size;
-	}
-
-	if (info->flags & M25P_NO_ERASE)
-		flash->mtd.flags |= MTD_NO_ERASE;
-
-	flash->mtd.parent = &spi->dev;
-	flash->page_size = info->page_size;
-	flash->sector_size = info->sector_size;
-
-	if (info->addr_width)
-		flash->addr_width = info->addr_width;
-	else {
-		/* enable 4-byte addressing if the device exceeds 16MiB */
-		if (flash->mtd.size > 0x1000000) {
-			flash->addr_width = 4;
-			set_4byte(flash, info->jedec_id, 1);
-		} else
-			flash->addr_width = 3;
+		flash_name = "m25p";
 	}
 
-	dev_info(dev, "%s (%lld Kbytes)\n", id->name,
-			(long long)flash->mtd.size >> 10);
-
-	dev_dbg(dev, "mtd .name = %s, .size = 0x%llx (%lldMiB) "
-			".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
-		flash->mtd.name,
-		(long long)flash->mtd.size, (long long)(flash->mtd.size >> 20),
-		flash->mtd.erasesize, flash->mtd.erasesize / 1024,
-		flash->mtd.numeraseregions);
-
-	if (flash->mtd.numeraseregions)
-		for (i = 0; i < flash->mtd.numeraseregions; i++)
-			dev_dbg(dev, "mtd.eraseregions[%d] = { .offset = 0x%llx, "
-				".erasesize = 0x%.8x (%uKiB), "
-				".numblocks = %d }\n",
-				i, (long long)flash->mtd.eraseregions[i].offset,
-				flash->mtd.eraseregions[i].erasesize,
-				flash->mtd.eraseregions[i].erasesize / 1024,
-				flash->mtd.eraseregions[i].numblocks);
-
-	return add_mtd_device(&flash->mtd, flashname, device_id);
+	return add_mtd_device(&flash->mtd, flash_name, device_id);
 }
 
 static __maybe_unused struct of_device_id m25p80_dt_ids[] = {
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:01 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:01 +0200
Subject: [PATCH v2 2/8] mtd: spi-nor: add cadence quadspi driver
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-3-git-send-email-s.trumtrar@pengutronix.de>

Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 drivers/mtd/spi-nor/Kconfig           |    9 +
 drivers/mtd/spi-nor/Makefile          |    1 +
 drivers/mtd/spi-nor/cadence-quadspi.c | 1211 +++++++++++++++++++++++++++++++++
 include/platform_data/cadence_qspi.h  |    9 +
 4 files changed, 1230 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/cadence-quadspi.c
 create mode 100644 include/platform_data/cadence_qspi.h

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 1568b2fb6d69..a84591fdd139 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -4,3 +4,12 @@ menuconfig MTD_SPI_NOR
 	help
 	  This is the framework for the SPI NOR which can be used by the SPI
 	  device drivers and the SPI-NOR device driver.
+
+if MTD_SPI_NOR
+
+config SPI_CADENCE_QUADSPI
+	tristate "Cadence Quad SPI controller"
+	help
+	  This enables support for the Cadence Quad SPI controller and NOR flash.
+
+endif
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index fe88e3d86ee5..4e00f38a7d86 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MTD_SPI_NOR)		+= spi-nor.o
+obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= cadence-quadspi.o
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
new file mode 100644
index 000000000000..dce29ca0ea02
--- /dev/null
+++ b/drivers/mtd/spi-nor/cadence-quadspi.c
@@ -0,0 +1,1211 @@
+/*
+ * Copyright (C) 2015 Pengutronix, Steffen Trumtrar <s.trumtrar at pengutronix.de>
+ *
+ * derived from Linux kernel driver by
+ *
+ * Driver for Cadence QSPI Controller
+ *
+ * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
+ *
+ * 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 <clock.h>
+#include <common.h>
+#include <driver.h>
+#include <errno.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/spi-nor.h>
+#include <of.h>
+#include <platform_data/cadence_qspi.h>
+#include <spi/spi.h>
+
+#define CQSPI_MAX_CHIPSELECT		16
+
+struct cqspi_flash_pdata {
+	struct mtd_info mtd;
+	struct spi_nor nor;
+	u32 clk_rate;
+	unsigned int block_size;
+	unsigned int read_delay;
+	unsigned int tshsl_ns;
+	unsigned int tsd2d_ns;
+	unsigned int tchsh_ns;
+	unsigned int tslch_ns;
+};
+
+struct cqspi_st {
+	struct device_d	*dev;
+	struct clk	*l4_mp_clk;
+	struct clk	*qspi_clk;
+	unsigned int	sclk;
+
+	void __iomem	*iobase;
+	void __iomem	*ahb_base;
+	unsigned int	irq_mask;
+	int		current_cs;
+	unsigned int	master_ref_clk_hz;
+	unsigned int	ext_decoder;
+	unsigned int	fifo_depth;
+	struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
+	bool no_reconfig;
+};
+
+/* Operation timeout value */
+#define CQSPI_TIMEOUT_MS			800 * MSECOND
+#define CQSPI_READ_TIMEOUT_MS			100 * MSECOND
+#define CQSPI_POLL_IDLE_RETRY			3
+
+#define CQSPI_FIFO_WIDTH			4
+
+#define CQSPI_REG_SRAM_THRESHOLD_BYTES		50
+
+/* Instruction type */
+#define CQSPI_INST_TYPE_SINGLE			0
+#define CQSPI_INST_TYPE_DUAL			1
+#define CQSPI_INST_TYPE_QUAD			2
+
+#define CQSPI_DUMMY_CLKS_PER_BYTE		8
+#define CQSPI_DUMMY_BYTES_MAX			4
+
+#define CQSPI_STIG_DATA_LEN_MAX			8
+
+#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		0xFFFFF
+
+/* Register map */
+#define CQSPI_REG_CONFIG			0x00
+#define CQSPI_REG_CONFIG_ENABLE_MASK		BIT(0)
+#define CQSPI_REG_CONFIG_DECODE_MASK		BIT(9)
+#define CQSPI_REG_CONFIG_CHIPSELECT_LSB		10
+#define CQSPI_REG_CONFIG_DMA_MASK		BIT(15)
+#define CQSPI_REG_CONFIG_BAUD_LSB		19
+#define CQSPI_REG_CONFIG_IDLE_LSB		31
+#define CQSPI_REG_CONFIG_CHIPSELECT_MASK	0xF
+#define CQSPI_REG_CONFIG_BAUD_MASK		0xF
+
+#define CQSPI_REG_RD_INSTR			0x04
+#define CQSPI_REG_RD_INSTR_OPCODE_LSB		0
+#define CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB	8
+#define CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB	12
+#define CQSPI_REG_RD_INSTR_TYPE_DATA_LSB	16
+#define CQSPI_REG_RD_INSTR_MODE_EN_LSB		20
+#define CQSPI_REG_RD_INSTR_DUMMY_LSB		24
+#define CQSPI_REG_RD_INSTR_TYPE_INSTR_MASK	0x3
+#define CQSPI_REG_RD_INSTR_TYPE_ADDR_MASK	0x3
+#define CQSPI_REG_RD_INSTR_TYPE_DATA_MASK	0x3
+#define CQSPI_REG_RD_INSTR_DUMMY_MASK		0x1F
+
+#define CQSPI_REG_WR_INSTR			0x08
+#define CQSPI_REG_WR_INSTR_OPCODE_LSB		0
+#define CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB	12
+#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB	16
+
+#define CQSPI_REG_DELAY				0x0C
+#define CQSPI_REG_DELAY_TSLCH_LSB		0
+#define CQSPI_REG_DELAY_TCHSH_LSB		8
+#define CQSPI_REG_DELAY_TSD2D_LSB		16
+#define CQSPI_REG_DELAY_TSHSL_LSB		24
+#define CQSPI_REG_DELAY_TSLCH_MASK		0xFF
+#define CQSPI_REG_DELAY_TCHSH_MASK		0xFF
+#define CQSPI_REG_DELAY_TSD2D_MASK		0xFF
+#define CQSPI_REG_DELAY_TSHSL_MASK		0xFF
+
+#define CQSPI_REG_READCAPTURE			0x10
+#define CQSPI_REG_READCAPTURE_BYPASS_LSB	0
+#define CQSPI_REG_READCAPTURE_DELAY_LSB		1
+#define CQSPI_REG_READCAPTURE_DELAY_MASK	0xF
+
+#define CQSPI_REG_SIZE				0x14
+#define CQSPI_REG_SIZE_ADDRESS_LSB		0
+#define CQSPI_REG_SIZE_PAGE_LSB			4
+#define CQSPI_REG_SIZE_BLOCK_LSB		16
+#define CQSPI_REG_SIZE_ADDRESS_MASK		0xF
+#define CQSPI_REG_SIZE_PAGE_MASK		0xFFF
+#define CQSPI_REG_SIZE_BLOCK_MASK		0x3F
+
+#define CQSPI_REG_SRAMPARTITION			0x18
+#define CQSPI_REG_INDIRECTTRIGGER		0x1C
+
+#define CQSPI_REG_DMA				0x20
+#define CQSPI_REG_DMA_SINGLE_LSB		0
+#define CQSPI_REG_DMA_BURST_LSB			8
+#define CQSPI_REG_DMA_SINGLE_MASK		0xFF
+#define CQSPI_REG_DMA_BURST_MASK		0xFF
+
+#define CQSPI_REG_REMAP				0x24
+#define CQSPI_REG_MODE_BIT			0x28
+
+#define CQSPI_REG_SRAMLEVEL			0x2C
+#define CQSPI_REG_SRAMLEVEL_RD_LSB		0
+#define CQSPI_REG_SRAMLEVEL_WR_LSB		16
+#define CQSPI_REG_SRAMLEVEL_RD_MASK		0xFFFF
+#define CQSPI_REG_SRAMLEVEL_WR_MASK		0xFFFF
+
+#define CQSPI_REG_IRQSTATUS			0x40
+#define CQSPI_REG_IRQMASK			0x44
+
+#define CQSPI_REG_INDIRECTRD			0x60
+#define CQSPI_REG_INDIRECTRD_START_MASK		BIT(0)
+#define CQSPI_REG_INDIRECTRD_CANCEL_MASK	BIT(1)
+#define CQSPI_REG_INDIRECTRD_DONE_MASK		BIT(5)
+
+#define CQSPI_REG_INDIRECTRDWATERMARK		0x64
+#define CQSPI_REG_INDIRECTRDSTARTADDR		0x68
+#define CQSPI_REG_INDIRECTRDBYTES		0x6C
+
+#define CQSPI_REG_CMDCTRL			0x90
+#define CQSPI_REG_CMDCTRL_EXECUTE_MASK		BIT(0)
+#define CQSPI_REG_CMDCTRL_INPROGRESS_MASK	BIT(1)
+#define CQSPI_REG_CMDCTRL_WR_BYTES_LSB		12
+#define CQSPI_REG_CMDCTRL_WR_EN_LSB		15
+#define CQSPI_REG_CMDCTRL_ADD_BYTES_LSB		16
+#define CQSPI_REG_CMDCTRL_ADDR_EN_LSB		19
+#define CQSPI_REG_CMDCTRL_RD_BYTES_LSB		20
+#define CQSPI_REG_CMDCTRL_RD_EN_LSB		23
+#define CQSPI_REG_CMDCTRL_OPCODE_LSB		24
+#define CQSPI_REG_CMDCTRL_WR_BYTES_MASK		0x7
+#define CQSPI_REG_CMDCTRL_ADD_BYTES_MASK	0x3
+#define CQSPI_REG_CMDCTRL_RD_BYTES_MASK		0x7
+
+#define CQSPI_REG_INDIRECTWR			0x70
+#define CQSPI_REG_INDIRECTWR_START_MASK		BIT(0)
+#define CQSPI_REG_INDIRECTWR_CANCEL_MASK	BIT(1)
+#define CQSPI_REG_INDIRECTWR_DONE_MASK		BIT(5)
+
+#define CQSPI_REG_INDIRECTWRWATERMARK		0x74
+#define CQSPI_REG_INDIRECTWRSTARTADDR		0x78
+#define CQSPI_REG_INDIRECTWRBYTES		0x7C
+
+#define CQSPI_REG_CMDADDRESS			0x94
+#define CQSPI_REG_CMDREADDATALOWER		0xA0
+#define CQSPI_REG_CMDREADDATAUPPER		0xA4
+#define CQSPI_REG_CMDWRITEDATALOWER		0xA8
+#define CQSPI_REG_CMDWRITEDATAUPPER		0xAC
+
+/* Interrupt status bits */
+#define CQSPI_REG_IRQ_MODE_ERR			BIT(0)
+#define CQSPI_REG_IRQ_UNDERFLOW			BIT(1)
+#define CQSPI_REG_IRQ_IND_COMP			BIT(2)
+#define CQSPI_REG_IRQ_IND_RD_REJECT		BIT(3)
+#define CQSPI_REG_IRQ_WR_PROTECTED_ERR		BIT(4)
+#define CQSPI_REG_IRQ_ILLEGAL_AHB_ERR		BIT(5)
+#define CQSPI_REG_IRQ_WATERMARK			BIT(6)
+#define CQSPI_REG_IRQ_IND_RD_OVERFLOW		BIT(12)
+
+#define CQSPI_IRQ_STATUS_ERR		(CQSPI_REG_IRQ_MODE_ERR		| \
+					 CQSPI_REG_IRQ_IND_RD_REJECT	| \
+					 CQSPI_REG_IRQ_WR_PROTECTED_ERR	| \
+					 CQSPI_REG_IRQ_ILLEGAL_AHB_ERR)
+
+#define CQSPI_IRQ_MASK_RD		(CQSPI_REG_IRQ_WATERMARK	| \
+					 CQSPI_REG_IRQ_IND_RD_OVERFLOW	| \
+					 CQSPI_REG_IRQ_IND_COMP)
+
+#define CQSPI_IRQ_MASK_WR		(CQSPI_REG_IRQ_IND_COMP		| \
+					 CQSPI_REG_IRQ_WATERMARK	| \
+					 CQSPI_REG_IRQ_UNDERFLOW)
+
+#define CQSPI_IRQ_STATUS_MASK		0x1FFFE
+
+#define CQSPI_REG_IS_IDLE(base)						\
+		((readl(base + CQSPI_REG_CONFIG) >>			\
+			CQSPI_REG_CONFIG_IDLE_LSB) & 0x1)
+
+#define CQSPI_GET_RD_SRAM_LEVEL(reg_base)				\
+		(((readl(reg_base + CQSPI_REG_SRAMLEVEL)) >>		\
+		CQSPI_REG_SRAMLEVEL_RD_LSB) & CQSPI_REG_SRAMLEVEL_RD_MASK)
+
+static void cqspi_fifo_read(void *dest, const void *src_ahb_addr,
+			    unsigned int bytes)
+{
+	unsigned int temp;
+	int remaining = bytes;
+	unsigned int *dest_ptr = (unsigned int *)dest;
+	unsigned int *src_ptr = (unsigned int *)src_ahb_addr;
+
+	while (remaining > CQSPI_FIFO_WIDTH) {
+		*dest_ptr = readl(src_ptr);
+		dest_ptr++;
+		remaining -= CQSPI_FIFO_WIDTH;
+	}
+	if (remaining > 0) {
+		/* dangling bytes */
+		temp = readl(src_ptr);
+		memcpy(dest_ptr, &temp, remaining);
+	}
+}
+
+static void cqspi_fifo_write(void *dest_ahb_addr,
+			     const void *src, unsigned int bytes)
+{
+	unsigned int temp;
+	int remaining = bytes;
+	unsigned int *dest_ptr = (unsigned int *)dest_ahb_addr;
+	unsigned int *src_ptr = (unsigned int *)src;
+
+	while (remaining > CQSPI_FIFO_WIDTH) {
+		writel(*src_ptr, dest_ptr);
+		src_ptr++;
+		remaining -= CQSPI_FIFO_WIDTH;
+	}
+	if (remaining > 0) {
+		/* dangling bytes */
+		memcpy(&temp, src_ptr, remaining);
+		writel(temp, dest_ptr);
+	}
+}
+
+static int cqspi_find_chipselect(struct spi_nor *nor)
+{
+	int cs = -1;
+	struct cqspi_st *cqspi = nor->priv;
+
+	for (cs = 0; cs < CQSPI_MAX_CHIPSELECT; cs++)
+		if (nor == &cqspi->f_pdata[cs].nor)
+			break;
+	return cs;
+}
+
+static unsigned int cqspi_calc_rdreg(struct spi_nor *nor, u8 opcode)
+{
+	unsigned int rdreg = 0;
+	struct cqspi_st *cqspi = nor->priv;
+	struct cqspi_flash_pdata *f_pdata;
+
+	f_pdata = &cqspi->f_pdata[cqspi->current_cs];
+
+	if (nor->flash_read == SPI_NOR_QUAD)
+		rdreg |= (CQSPI_INST_TYPE_QUAD
+			  << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB);
+	return rdreg;
+}
+
+static unsigned int cqspi_wait_idle(struct cqspi_st *cqspi)
+{
+	void __iomem *reg_base = cqspi->iobase;
+
+	if (wait_on_timeout(CQSPI_TIMEOUT_MS,
+		CQSPI_REG_IS_IDLE(reg_base))) {
+		/* Timeout, in busy mode. */
+		dev_err(cqspi->dev, "QSPI is still busy after %llums timeout.\n",
+			CQSPI_TIMEOUT_MS);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
+{
+	void __iomem *reg_base = cqspi->iobase;
+
+	/* Write the CMDCTRL without start execution. */
+	writel(reg, reg_base + CQSPI_REG_CMDCTRL);
+	/* Start execute */
+	reg |= CQSPI_REG_CMDCTRL_EXECUTE_MASK;
+	writel(reg, reg_base + CQSPI_REG_CMDCTRL);
+
+	if (wait_on_timeout(CQSPI_TIMEOUT_MS,
+		(readl(reg_base + CQSPI_REG_CMDCTRL) &
+			CQSPI_REG_CMDCTRL_INPROGRESS_MASK) == 0)) {
+		dev_err(cqspi->dev, "flash cmd execute time out (0x%08x)\n",
+			readl(reg_base + CQSPI_REG_CMDCTRL));
+		return -EIO;
+	}
+
+	/* Polling QSPI idle status. */
+	return cqspi_wait_idle(cqspi);
+}
+
+static int cqspi_command_read(struct spi_nor *nor,
+			      const u8 *txbuf, unsigned n_tx,
+			      u8 *rxbuf, unsigned n_rx)
+{
+	unsigned int reg;
+	unsigned int read_len;
+	int status;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int rdreg;
+
+	if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || rxbuf == NULL) {
+		dev_err(nor->dev,
+			"Invalid input argument, len %d rxbuf 0x%08x\n", n_rx,
+			(unsigned int)rxbuf);
+		return -EINVAL;
+	}
+
+	reg = txbuf[0] << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+
+	rdreg = cqspi_calc_rdreg(nor, txbuf[0]);
+	writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
+
+	reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
+
+	/* 0 means 1 byte. */
+	reg |= (((n_rx - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK)
+		<< CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
+	status = cqspi_exec_flash_cmd(cqspi, reg);
+	if (status != 0)
+		return status;
+
+	reg = readl(reg_base + CQSPI_REG_CMDREADDATALOWER);
+
+	/* Put the read value into rx_buf */
+	read_len = (n_rx > 4) ? 4 : n_rx;
+	memcpy(rxbuf, &reg, read_len);
+	rxbuf += read_len;
+
+	if (n_rx > 4) {
+		reg = readl(reg_base + CQSPI_REG_CMDREADDATAUPPER);
+
+		read_len = n_rx - read_len;
+		memcpy(rxbuf, &reg, read_len);
+	}
+
+	return 0;
+}
+
+static __maybe_unused int cqspi_command_write(struct spi_nor *nor,
+				u8 opcode, const u8 *txbuf, unsigned n_tx)
+{
+	unsigned int reg;
+	unsigned int data;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+
+	if (n_tx > 4 || (n_tx && txbuf == NULL)) {
+		dev_err(nor->dev,
+			"Invalid input argument, cmdlen %d txbuf 0x%08x\n",
+			n_tx, (unsigned int)txbuf);
+		return -EINVAL;
+	}
+
+	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+	if (n_tx) {
+		reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
+		reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
+		    << CQSPI_REG_CMDCTRL_WR_BYTES_LSB;
+		data = 0;
+		memcpy(&data, txbuf, n_tx);
+		writel(data, reg_base + CQSPI_REG_CMDWRITEDATALOWER);
+	}
+
+	return cqspi_exec_flash_cmd(cqspi, reg);
+}
+
+static int cqspi_command_write_addr(struct spi_nor *nor,
+				    u8 opcode, unsigned int addr)
+{
+	unsigned int reg;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+
+	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+	reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
+	reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
+		<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
+
+	writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
+
+	return cqspi_exec_flash_cmd(cqspi, reg);
+}
+
+static int cqspi_indirect_read_setup(struct spi_nor *nor,
+				     unsigned int from_addr)
+{
+	struct cqspi_st *cqspi = nor->priv;
+	unsigned int ahb_base = (unsigned int) cqspi->ahb_base;
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int dummy_clk = 0;
+	unsigned int dummy_bytes;
+	unsigned int reg = 0;
+
+	writel(ahb_base & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	       reg_base + CQSPI_REG_INDIRECTTRIGGER);
+	writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
+
+	reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
+	reg |= cqspi_calc_rdreg(nor, nor->read_opcode);
+
+	/* Setup dummy clock cycles */
+	dummy_bytes = nor->read_dummy / 8;
+
+	if (dummy_bytes) {
+		struct cqspi_flash_pdata *f_pdata;
+
+		f_pdata = &cqspi->f_pdata[cqspi->current_cs];
+
+		if (dummy_bytes > CQSPI_DUMMY_BYTES_MAX)
+			dummy_bytes = CQSPI_DUMMY_BYTES_MAX;
+
+		reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
+		/* Set mode bits high to ensure chip doesn't enter XIP */
+		writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
+
+		/* Convert to clock cycles. */
+		dummy_clk = dummy_bytes * CQSPI_DUMMY_CLKS_PER_BYTE;
+		/* Need to subtract the mode byte (8 clocks). */
+		dummy_clk -= CQSPI_DUMMY_CLKS_PER_BYTE;
+
+		if (dummy_clk)
+			reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+			    << CQSPI_REG_RD_INSTR_DUMMY_LSB;
+	}
+
+	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+
+	/* Set address width */
+	reg = readl(reg_base + CQSPI_REG_SIZE);
+	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
+	reg |= (nor->addr_width) - 1;
+	writel(reg, reg_base + CQSPI_REG_SIZE);
+	return 0;
+}
+
+static int cqspi_indirect_read_execute(struct spi_nor *nor,
+				       u8 *rxbuf, unsigned n_rx)
+{
+	int ret = 0;
+	unsigned int reg = 0;
+	unsigned int bytes_to_read = 0;
+	unsigned int watermark;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+	void __iomem *ahb_base = cqspi->ahb_base;
+	int remaining = (int)n_rx;
+
+	watermark = cqspi->fifo_depth * CQSPI_FIFO_WIDTH / 2;
+	writel(watermark, reg_base + CQSPI_REG_INDIRECTRDWATERMARK);
+	writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
+
+	/* Clear all interrupts. */
+	writel(CQSPI_IRQ_STATUS_MASK, reg_base + CQSPI_REG_IRQSTATUS);
+
+	cqspi->irq_mask = CQSPI_IRQ_MASK_RD;
+	writel(cqspi->irq_mask, reg_base + CQSPI_REG_IRQMASK);
+
+	writel(CQSPI_REG_INDIRECTRD_START_MASK,
+		reg_base + CQSPI_REG_INDIRECTRD);
+
+	while (remaining > 0) {
+		unsigned int irq_status;
+
+		ret = wait_on_timeout(CQSPI_READ_TIMEOUT_MS,
+			readl(reg_base + CQSPI_REG_IRQSTATUS) & cqspi->irq_mask);
+
+		irq_status = readl(reg_base + CQSPI_REG_IRQSTATUS);
+		bytes_to_read = CQSPI_GET_RD_SRAM_LEVEL(reg_base);
+
+		/* Clear all interrupts. */
+		writel(irq_status, reg_base + CQSPI_REG_IRQSTATUS);
+
+		if (!ret && bytes_to_read == 0) {
+			dev_err(nor->dev, "Indirect read timeout, no bytes\n");
+			ret = -ETIMEDOUT;
+			goto failrd;
+		}
+
+		while (bytes_to_read != 0) {
+			bytes_to_read *= CQSPI_FIFO_WIDTH;
+			bytes_to_read = bytes_to_read > remaining
+					? remaining : bytes_to_read;
+			cqspi_fifo_read(rxbuf, ahb_base, bytes_to_read);
+			rxbuf += bytes_to_read;
+			remaining -= bytes_to_read;
+			bytes_to_read = CQSPI_GET_RD_SRAM_LEVEL(reg_base);
+		}
+	}
+
+	/* Check indirect done status */
+	if (wait_on_timeout(CQSPI_TIMEOUT_MS,
+		readl(reg_base + CQSPI_REG_INDIRECTRD) &
+			CQSPI_REG_INDIRECTRD_DONE_MASK)) {
+		dev_err(nor->dev,
+			"Indirect read completion error 0x%08x\n", reg);
+		ret = -ETIMEDOUT;
+		goto failrd;
+	}
+
+	/* Disable interrupt */
+	writel(0, reg_base + CQSPI_REG_IRQMASK);
+
+	/* Clear indirect completion status */
+	writel(CQSPI_REG_INDIRECTRD_DONE_MASK, reg_base + CQSPI_REG_INDIRECTRD);
+
+	return 0;
+
+ failrd:
+	/* Disable interrupt */
+	writel(0, reg_base + CQSPI_REG_IRQMASK);
+
+	/* Cancel the indirect read */
+	writel(CQSPI_REG_INDIRECTWR_CANCEL_MASK,
+	       reg_base + CQSPI_REG_INDIRECTRD);
+	return ret;
+}
+
+static __maybe_unused int cqspi_indirect_write_setup(struct spi_nor *nor,
+						     unsigned int to_addr)
+{
+	unsigned int reg;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+
+	/* Set opcode. */
+	reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+	writel(reg, reg_base + CQSPI_REG_WR_INSTR);
+	reg = cqspi_calc_rdreg(nor, nor->program_opcode);
+	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
+
+	writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
+
+	reg = readl(reg_base + CQSPI_REG_SIZE);
+	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
+	reg |= (nor->addr_width - 1);
+	writel(reg, reg_base + CQSPI_REG_SIZE);
+	return 0;
+}
+
+static __maybe_unused int cqspi_indirect_write_execute(struct spi_nor *nor,
+						const u8 *txbuf, unsigned n_tx)
+{
+	int ret;
+	unsigned int reg = 0;
+	struct cqspi_st *cqspi = nor->priv;
+	void __iomem *reg_base = cqspi->iobase;
+	void __iomem *ahb_base = cqspi->ahb_base;
+	int remaining = (int)n_tx;
+	unsigned int page_size;
+	unsigned int write_bytes;
+
+	page_size = nor->page_size;
+
+	writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
+
+	writel(CQSPI_REG_SRAM_THRESHOLD_BYTES, reg_base +
+	       CQSPI_REG_INDIRECTWRWATERMARK);
+
+	/* Clear all interrupts. */
+	writel(CQSPI_IRQ_STATUS_MASK, reg_base + CQSPI_REG_IRQSTATUS);
+
+	cqspi->irq_mask = CQSPI_IRQ_MASK_WR;
+	writel(cqspi->irq_mask, reg_base + CQSPI_REG_IRQMASK);
+
+	writel(CQSPI_REG_INDIRECTWR_START_MASK,
+	       reg_base + CQSPI_REG_INDIRECTWR);
+
+	/* Write a page or remaining bytes. */
+	write_bytes = remaining > page_size ? page_size : remaining;
+	/* Fill up the data at the beginning */
+	cqspi_fifo_write(ahb_base, txbuf, write_bytes);
+	txbuf += write_bytes;
+	remaining -= write_bytes;
+
+	while (remaining > 0) {
+		ret = wait_on_timeout(CQSPI_READ_TIMEOUT_MS,
+			readl(reg_base + CQSPI_REG_IRQSTATUS) & cqspi->irq_mask);
+
+		/* Clear all interrupts. */
+		writel(CQSPI_IRQ_STATUS_MASK, reg_base + CQSPI_REG_IRQSTATUS);
+
+		if (ret < 0) {
+			dev_err(nor->dev, "Indirect write timeout\n");
+			ret = -ETIMEDOUT;
+			goto failwr;
+		}
+
+		write_bytes = remaining > page_size ? page_size : remaining;
+		cqspi_fifo_write(ahb_base, txbuf, write_bytes);
+		txbuf += write_bytes;
+		remaining -= write_bytes;
+
+		writel(cqspi->irq_mask, reg_base + CQSPI_REG_IRQMASK);
+	}
+	ret = wait_on_timeout(CQSPI_READ_TIMEOUT_MS,
+			readl(reg_base + CQSPI_REG_IRQSTATUS) & cqspi->irq_mask);
+
+	/* Clear all interrupts. */
+	writel(CQSPI_IRQ_STATUS_MASK, reg_base + CQSPI_REG_IRQSTATUS);
+	if (ret < 0) {
+		dev_err(nor->dev, "Indirect write timeout\n");
+		ret = -ETIMEDOUT;
+		goto failwr;
+	}
+
+	/* Check indirect done status */
+	if (wait_on_timeout(CQSPI_TIMEOUT_MS,
+		readl(reg_base + CQSPI_REG_INDIRECTWR)
+			& CQSPI_REG_INDIRECTWR_DONE_MASK)) {
+		dev_err(nor->dev,
+			"Indirect write completion error 0x%08x\n", reg);
+		ret = -ETIMEDOUT;
+		goto failwr;
+	}
+
+	/* Disable interrupt. */
+	writel(0, reg_base + CQSPI_REG_IRQMASK);
+
+	/* Clear indirect completion status */
+	writel(CQSPI_REG_INDIRECTWR_DONE_MASK, reg_base + CQSPI_REG_INDIRECTWR);
+
+	cqspi_wait_idle(cqspi);
+
+	return 0;
+
+failwr:
+	/* Disable interrupt. */
+	writel(0, reg_base + CQSPI_REG_IRQMASK);
+
+	/* Cancel the indirect write */
+	writel(CQSPI_REG_INDIRECTWR_CANCEL_MASK,
+	       reg_base + CQSPI_REG_INDIRECTWR);
+	return ret;
+}
+
+static void cqspi_write(struct spi_nor *nor, loff_t to,
+			size_t len, size_t *retlen, const u_char *buf)
+{
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return;
+
+	ret = cqspi_indirect_write_setup(nor, to);
+	if (ret == 0) {
+		ret = cqspi_indirect_write_execute(nor, buf, len);
+		if (ret == 0)
+			*retlen += len;
+	}
+}
+
+static int cqspi_read(struct spi_nor *nor, loff_t from,
+		      size_t len, size_t *retlen, u_char *buf)
+{
+	int ret;
+
+	ret = cqspi_indirect_read_setup(nor, from);
+	if (ret == 0) {
+		ret = cqspi_indirect_read_execute(nor, buf, len);
+		if (ret == 0)
+			*retlen += len;
+	}
+	return ret;
+}
+
+static int cqspi_erase(struct spi_nor *nor, loff_t offs)
+{
+	int ret;
+
+	/* Send write enable, then erase commands. */
+	ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
+	if (ret)
+		return ret;
+
+	/* Set up command buffer. */
+	ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static unsigned int calculate_ticks_for_ns(unsigned int ref_clk_hz,
+					   unsigned int ns_val)
+{
+	unsigned int ticks;
+
+	ticks = ref_clk_hz;
+	ticks /= 1000;
+	ticks *= ns_val;
+	ticks += 999999;
+	ticks /= 1000000;
+	return ticks;
+}
+
+static void cqspi_delay(struct cqspi_st *cqspi,
+			unsigned int ref_clk_hz, unsigned int sclk_hz)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	struct cqspi_flash_pdata *f_pdata;
+	unsigned int ref_clk_ns;
+	unsigned int sclk_ns;
+	unsigned int tshsl, tchsh, tslch, tsd2d;
+	unsigned int reg;
+	unsigned int tsclk;
+
+	if (cqspi->no_reconfig)
+		return;
+
+	f_pdata = &cqspi->f_pdata[cqspi->current_cs];
+
+	/* Convert to ns. */
+	ref_clk_ns = NSEC_PER_SEC / ref_clk_hz;
+
+	/* Convert to ns. */
+	sclk_ns = NSEC_PER_SEC / sclk_hz;
+
+	/* calculate the number of ref ticks for one sclk tick */
+	tsclk = (ref_clk_hz + sclk_hz - 1) / sclk_hz;
+
+	tshsl = calculate_ticks_for_ns(ref_clk_hz, f_pdata->tshsl_ns);
+	/* this particular value must be at least one sclk */
+	if (tshsl < tsclk)
+		tshsl = tsclk;
+
+	tchsh = calculate_ticks_for_ns(ref_clk_hz, f_pdata->tchsh_ns);
+	tslch = calculate_ticks_for_ns(ref_clk_hz, f_pdata->tslch_ns);
+	tsd2d = calculate_ticks_for_ns(ref_clk_hz, f_pdata->tsd2d_ns);
+
+	reg = ((tshsl & CQSPI_REG_DELAY_TSHSL_MASK)
+	       << CQSPI_REG_DELAY_TSHSL_LSB);
+	reg |= ((tchsh & CQSPI_REG_DELAY_TCHSH_MASK)
+		<< CQSPI_REG_DELAY_TCHSH_LSB);
+	reg |= ((tslch & CQSPI_REG_DELAY_TSLCH_MASK)
+		<< CQSPI_REG_DELAY_TSLCH_LSB);
+	reg |= ((tsd2d & CQSPI_REG_DELAY_TSD2D_MASK)
+		<< CQSPI_REG_DELAY_TSD2D_LSB);
+	writel(reg, reg_base + CQSPI_REG_DELAY);
+}
+
+static void cqspi_config_baudrate_div(struct cqspi_st *cqspi,
+				      unsigned int ref_clk_hz,
+				      unsigned int sclk_hz)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+	unsigned int div;
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	reg &= ~(CQSPI_REG_CONFIG_BAUD_MASK << CQSPI_REG_CONFIG_BAUD_LSB);
+
+	div = ref_clk_hz / sclk_hz;
+
+	/* Recalculate the baudrate divisor based on QSPI specification. */
+	if (div > 32)
+		div = 32;
+
+	/* Check if even number. */
+	if (div & 1)
+		div = (div / 2);
+	else
+		div = (div / 2) - 1;
+
+	div = (div & CQSPI_REG_CONFIG_BAUD_MASK) << CQSPI_REG_CONFIG_BAUD_LSB;
+	reg |= div;
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+}
+
+static void cqspi_readdata_capture(struct cqspi_st *cqspi,
+				   unsigned int bypass, unsigned int delay)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+
+	if (cqspi->no_reconfig)
+		return;
+
+	reg = readl(reg_base + CQSPI_REG_READCAPTURE);
+
+	if (bypass)
+		reg |= (1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
+	else
+		reg &= ~(1 << CQSPI_REG_READCAPTURE_BYPASS_LSB);
+
+	reg &= ~(CQSPI_REG_READCAPTURE_DELAY_MASK
+		 << CQSPI_REG_READCAPTURE_DELAY_LSB);
+
+	reg |= ((delay & CQSPI_REG_READCAPTURE_DELAY_MASK)
+		<< CQSPI_REG_READCAPTURE_DELAY_LSB);
+
+	writel(reg, reg_base + CQSPI_REG_READCAPTURE);
+}
+
+static void cqspi_chipselect(struct cqspi_st *cqspi,
+			     unsigned int chip_select,
+			     unsigned int decoder_enable)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	if (decoder_enable) {
+		reg |= CQSPI_REG_CONFIG_DECODE_MASK;
+	} else {
+		reg &= ~CQSPI_REG_CONFIG_DECODE_MASK;
+
+		/* Convert CS if without decoder.
+		 * CS0 to 4b'1110
+		 * CS1 to 4b'1101
+		 * CS2 to 4b'1011
+		 * CS3 to 4b'0111
+		 */
+		chip_select = 0xF & ~(1 << chip_select);
+	}
+
+	reg &= ~(CQSPI_REG_CONFIG_CHIPSELECT_MASK
+		 << CQSPI_REG_CONFIG_CHIPSELECT_LSB);
+	reg |= (chip_select & CQSPI_REG_CONFIG_CHIPSELECT_MASK)
+	    << CQSPI_REG_CONFIG_CHIPSELECT_LSB;
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+}
+
+static void cqspi_controller_enable(struct cqspi_st *cqspi)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	reg |= CQSPI_REG_CONFIG_ENABLE_MASK;
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+}
+
+static void cqspi_controller_disable(struct cqspi_st *cqspi)
+{
+	void __iomem *reg_base = cqspi->iobase;
+	unsigned int reg;
+
+	reg = readl(reg_base + CQSPI_REG_CONFIG);
+	reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
+	writel(reg, reg_base + CQSPI_REG_CONFIG);
+}
+
+static void cqspi_switch_cs(struct cqspi_st *cqspi, unsigned int cs)
+{
+	unsigned int reg;
+	struct cqspi_flash_pdata *f_pdata = &cqspi->f_pdata[cs];
+	void __iomem *reg_base = cqspi->iobase;
+	struct spi_nor *nor = &f_pdata->nor;
+
+	cqspi_controller_disable(cqspi);
+
+	/* configure page size and block size. */
+	reg = readl(reg_base + CQSPI_REG_SIZE);
+	reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB);
+	reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB);
+	reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB);
+	reg |= (f_pdata->block_size << CQSPI_REG_SIZE_BLOCK_LSB);
+	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
+	reg |= (nor->addr_width - 1);
+	writel(reg, reg_base + CQSPI_REG_SIZE);
+
+	/* configure the chip select */
+	cqspi_chipselect(cqspi, cs, cqspi->ext_decoder);
+
+	cqspi_controller_enable(cqspi);
+}
+
+static int cqspi_prep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+	struct cqspi_st *cqspi = nor->priv;
+	int cs = cqspi_find_chipselect(nor);
+	struct cqspi_flash_pdata *f_pdata;
+	unsigned int sclk;
+
+	/* Switch chip select. */
+	if (cqspi->current_cs != cs) {
+		cqspi->current_cs = cs;
+		cqspi_switch_cs(cqspi, cs);
+	}
+
+	/* Setup baudrate divisor and delays */
+	f_pdata = &cqspi->f_pdata[cqspi->current_cs];
+	sclk = f_pdata->clk_rate;
+	if (cqspi->sclk != sclk) {
+		cqspi->sclk = sclk;
+		cqspi_controller_disable(cqspi);
+		cqspi_config_baudrate_div(cqspi,
+					  cqspi->master_ref_clk_hz, sclk);
+		cqspi_delay(cqspi, cqspi->master_ref_clk_hz, sclk);
+		cqspi_readdata_capture(cqspi, 1, f_pdata->read_delay);
+		cqspi_controller_enable(cqspi);
+	}
+	return 0;
+}
+
+static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+{
+	int ret;
+
+	cqspi_prep(nor, SPI_NOR_OPS_READ);
+
+	ret = cqspi_command_read(nor, &opcode, 1, buf, len);
+	return ret;
+}
+
+static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
+			   int write_enable)
+{
+	int ret = 0;
+
+	if (!IS_ENABLED(CONFIG_MTD_WRITE))
+		return -ENOTSUPP;
+
+	cqspi_prep(nor, SPI_NOR_OPS_WRITE);
+
+	ret = cqspi_command_write(nor, opcode, buf, len);
+	return ret;
+}
+
+static int cqspi_of_get_flash_pdata(struct device_d *dev,
+				    struct cqspi_flash_pdata *f_pdata,
+				    struct device_node *np)
+{
+	struct cqspi_st *cqspi = dev->priv;
+	void __iomem *reg_base = cqspi->iobase;
+
+	if (!np) {
+		f_pdata->block_size = (readl(reg_base + CQSPI_REG_SIZE) >>
+					CQSPI_REG_SIZE_BLOCK_LSB) &
+					CQSPI_REG_SIZE_BLOCK_MASK;
+
+		cqspi->no_reconfig = true;
+
+		return 0;
+	}
+
+	if (of_property_read_u32(np, "cdns,block-size", &f_pdata->block_size)) {
+		dev_err(dev, "couldn't determine block-size\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "cdns,read-delay", &f_pdata->read_delay)) {
+		dev_err(dev, "couldn't determine read-delay\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "cdns,tshsl-ns", &f_pdata->tshsl_ns)) {
+		dev_err(dev, "couldn't determine tshsl-ns\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "cdns,tsd2d-ns", &f_pdata->tsd2d_ns)) {
+		dev_err(dev, "couldn't determine tsd2d-ns\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "cdns,tchsh-ns", &f_pdata->tchsh_ns)) {
+		dev_err(dev, "couldn't determine tchsh-ns\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "cdns,tslch-ns", &f_pdata->tslch_ns)) {
+		dev_err(dev, "couldn't determine tslch-ns\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "spi-max-frequency", &f_pdata->clk_rate)) {
+		dev_err(dev, "couldn't determine spi-max-frequency\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int cqspi_parse_dt(struct cqspi_st *cqspi)
+{
+	struct device_node *np = cqspi->dev->device_node;
+	struct device_d *dev = cqspi->dev;
+
+	if (of_property_read_u32(np, "ext-decoder", &cqspi->ext_decoder)) {
+		dev_err(dev, "couldn't determine ext-decoder\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "fifo-depth", &cqspi->fifo_depth)) {
+		dev_err(dev, "couldn't determine fifo-depth\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int cqspi_setup_flash(struct device_d *dev,
+			     struct cqspi_flash_pdata *f_pdata,
+			     struct device_node *np)
+{
+	struct cqspi_st *cqspi = dev->priv;
+	struct mtd_info *mtd;
+	struct spi_nor *nor;
+	int ret;
+
+	ret = cqspi_of_get_flash_pdata(dev, f_pdata, np);
+	if (ret)
+		goto probe_failed;
+
+	nor = &f_pdata->nor;
+	mtd = &f_pdata->mtd;
+
+	nor->mtd = mtd;
+
+	if (np) {
+		nor->dev = xzalloc(sizeof(*nor->dev));
+
+		strcpy(nor->dev->name, np->name);
+
+		nor->dev->device_node = np;
+		nor->dev->id = DEVICE_ID_SINGLE;
+		nor->dev->parent = dev;
+		ret = register_device(nor->dev);
+
+		if (ret)
+			return ret;
+
+		mtd->parent = nor->dev;
+	} else {
+		nor->dev = dev;
+	}
+
+	nor->priv = cqspi;
+	mtd->priv = nor;
+
+	nor->read_reg = cqspi_read_reg;
+	nor->write_reg = cqspi_write_reg;
+	nor->read = cqspi_read;
+	nor->write = cqspi_write;
+	nor->erase = cqspi_erase;
+
+	ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
+	if (ret)
+		goto probe_failed;
+
+	ret = add_mtd_device(mtd, NULL, DEVICE_ID_DYNAMIC);
+	if (ret)
+		goto probe_failed;
+
+	return 0;
+
+probe_failed:
+	dev_err(dev, "probing for flashchip failed\n");
+	return ret;
+
+}
+
+static void cqspi_controller_init(struct cqspi_st *cqspi)
+{
+	cqspi_controller_disable(cqspi);
+
+	/* Configure the remap address register, no remap */
+	writel(0, cqspi->iobase + CQSPI_REG_REMAP);
+
+	/* Disable all interrupts */
+	writel(0, cqspi->iobase + CQSPI_REG_IRQMASK);
+
+	cqspi_controller_enable(cqspi);
+}
+
+static int cqspi_probe(struct device_d *dev)
+{
+	struct device_node *np = dev->device_node;
+	struct cqspi_st *cqspi;
+	struct cadence_qspi_platform_data *pdata = dev->platform_data;
+	int ret;
+
+	cqspi = kzalloc(sizeof(*cqspi), GFP_KERNEL);
+	if (!cqspi)
+		return -ENOMEM;
+
+	cqspi->dev = dev;
+	dev->priv = cqspi;
+
+	if (pdata) {
+		cqspi->ext_decoder = pdata->ext_decoder;
+		cqspi->fifo_depth = pdata->fifo_depth;
+	} else {
+		ret = cqspi_parse_dt(cqspi);
+		if (ret) {
+			dev_err(dev, "Get platform data failed.\n");
+			return -ENODEV;
+		}
+	}
+
+	cqspi->qspi_clk = clk_get(dev, "qspi_clk");
+	if (IS_ERR(cqspi->qspi_clk)) {
+		dev_err(dev, "cannot get qspi clk\n");
+		ret = PTR_ERR(cqspi->qspi_clk);
+		goto probe_failed;
+	}
+	cqspi->master_ref_clk_hz = clk_get_rate(cqspi->qspi_clk);
+
+	clk_enable(cqspi->qspi_clk);
+
+	cqspi->iobase = dev_request_mem_region(dev, 0);
+	if (IS_ERR(cqspi->iobase)) {
+		dev_err(dev, "dev_request_mem_region 0 failed\n");
+		ret = PTR_ERR(cqspi->iobase);
+		goto probe_failed;
+	}
+
+	cqspi->ahb_base = dev_request_mem_region(dev, 1);
+	if (IS_ERR(cqspi->ahb_base)) {
+		dev_err(dev, "dev_request_mem_region 0 failed\n");
+		ret = PTR_ERR(cqspi->ahb_base);
+		goto probe_failed;
+	}
+
+	cqspi_wait_idle(cqspi);
+	cqspi_controller_init(cqspi);
+	cqspi->current_cs = -1;
+	cqspi->sclk = 0;
+
+	if (!dev->device_node) {
+		struct cqspi_flash_pdata *f_pdata;
+
+		f_pdata = &cqspi->f_pdata[0];
+
+		ret = cqspi_setup_flash(dev, f_pdata, NULL);
+		if (ret)
+			goto probe_failed;
+	} else {
+		/* Get flash device data */
+		for_each_available_child_of_node(dev->device_node, np) {
+			struct cqspi_flash_pdata *f_pdata;
+			unsigned int cs;
+			if (of_property_read_u32(np, "reg", &cs)) {
+				dev_err(dev, "couldn't determine chip select\n");
+				return -ENXIO;
+			}
+			if (cs > CQSPI_MAX_CHIPSELECT) {
+				dev_err(dev, "chip select %d out of range\n", cs);
+				return -ENXIO;
+			}
+			f_pdata = &cqspi->f_pdata[cs];
+
+			ret = cqspi_setup_flash(dev, f_pdata, np);
+			if (ret)
+				goto probe_failed;
+		}
+	}
+
+	dev_info(dev, "Cadence QSPI NOR flash driver\n");
+	return 0;
+
+probe_failed:
+	dev_err(dev, "Cadence QSPI NOR probe failed\n");
+	return ret;
+}
+
+static __maybe_unused struct of_device_id cqspi_dt_ids[] = {
+	{.compatible = "cdns,qspi-nor",},
+	{ /* end of table */ }
+};
+
+static struct driver_d cqspi_driver = {
+	.name = "cadence_qspi",
+	.probe = cqspi_probe,
+	.of_compatible = DRV_OF_COMPAT(cqspi_dt_ids),
+};
+device_platform_driver(cqspi_driver);
diff --git a/include/platform_data/cadence_qspi.h b/include/platform_data/cadence_qspi.h
new file mode 100644
index 000000000000..4930edce507e
--- /dev/null
+++ b/include/platform_data/cadence_qspi.h
@@ -0,0 +1,9 @@
+#ifndef __INCLUDE_PLATFORM_DATA_CADENCE_QSPI_H
+#define __INCLUDE_PLATFORM_DATA_CADENCE_QSPI_H
+
+struct cadence_qspi_platform_data {
+	unsigned int ext_decoder;
+	unsigned int fifo_depth;
+};
+
+#endif /* __INCLUDE_PLATFORM_DATA_CADENCE_QSPI_H */
-- 
2.1.4



From s.trumtrar at pengutronix.de  Thu May 28 08:56:00 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Thu, 28 May 2015 17:56:00 +0200
Subject: [PATCH v2 1/8] mtd: spi-nor: add SPI-NOR framework
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <1432828567-14037-2-git-send-email-s.trumtrar@pengutronix.de>

Import the SPI-NOR framework from linux kernel v3.19.

Signed-off-by: Enrico Jorns <ejo at pengutronix.de>
Signed-off-by: Steffen Trumtrar <s.trumtrar at pengutronix.de>
---
 drivers/mtd/Kconfig             |    1 +
 drivers/mtd/Makefile            |    1 +
 drivers/mtd/spi-nor/Kconfig     |    6 +
 drivers/mtd/spi-nor/Makefile    |    1 +
 drivers/mtd/spi-nor/spi-nor.c   | 1148 +++++++++++++++++++++++++++++++++++++++
 include/linux/mod_devicetable.h |    7 +
 include/linux/mtd/spi-nor.h     |  204 +++++++
 7 files changed, 1368 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/Kconfig
 create mode 100644 drivers/mtd/spi-nor/Makefile
 create mode 100644 drivers/mtd/spi-nor/spi-nor.c
 create mode 100644 include/linux/mtd/spi-nor.h

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index e94e6b1f63bb..49ea88cac430 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -23,6 +23,7 @@ config MTD_RAW_DEVICE
 source "drivers/mtd/devices/Kconfig"
 source "drivers/mtd/nor/Kconfig"
 source "drivers/mtd/nand/Kconfig"
+source "drivers/mtd/spi-nor/Kconfig"
 source "drivers/mtd/ubi/Kconfig"
 
 endif
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 9c7725742e6f..148ec6ca23b1 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NAND)			+= nand/
 obj-$(CONFIG_DRIVER_CFI)		+= nor/
+obj-$(CONFIG_MTD_SPI_NOR)		+= spi-nor/
 obj-$(CONFIG_MTD_UBI)			+= ubi/
 obj-y					+= devices/
 obj-$(CONFIG_MTD)			+= core.o partition.o
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
new file mode 100644
index 000000000000..1568b2fb6d69
--- /dev/null
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -0,0 +1,6 @@
+menuconfig MTD_SPI_NOR
+	tristate "SPI-NOR device support"
+	depends on MTD
+	help
+	  This is the framework for the SPI NOR which can be used by the SPI
+	  device drivers and the SPI-NOR device driver.
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
new file mode 100644
index 000000000000..fe88e3d86ee5
--- /dev/null
+++ b/drivers/mtd/spi-nor/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MTD_SPI_NOR)		+= spi-nor.o
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
new file mode 100644
index 000000000000..c85ed34e06f9
--- /dev/null
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -0,0 +1,1148 @@
+/*
+ * Based on m25p80.c, by Mike Lavender (mike at steroidmicros.com), with
+ * influence from lart.c (Abraham Van Der Merwe) and mtd_dataflash.c
+ *
+ * Copyright (C) 2005, Intec Automation Inc.
+ * Copyright (C) 2014, Freescale Semiconductor, Inc.
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <clock.h>
+#include <common.h>
+#include <driver.h>
+#include <errno.h>
+#include <linux/err.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/cfi.h>
+#include <linux/mtd/spi-nor.h>
+#include <of.h>
+#include <spi/flash.h>
+
+#define SPI_NOR_MAX_ID_LEN	6
+
+struct flash_info {
+	/*
+	 * This array stores the ID bytes.
+	 * The first three bytes are the JEDIC ID.
+	 * JEDEC ID zero means "no ID" (mostly older chips).
+	 */
+	u8		id[SPI_NOR_MAX_ID_LEN];
+	u8		id_len;
+
+	/* The size listed here is what works with SPINOR_OP_SE, which isn't
+	 * necessarily called a "sector" by the vendor.
+	 */
+	unsigned	sector_size;
+	u16		n_sectors;
+
+	u16		page_size;
+	u16		addr_width;
+
+	u16		flags;
+#define	SECT_4K			0x01	/* SPINOR_OP_BE_4K works uniformly */
+#define	SPI_NOR_NO_ERASE	0x02	/* No erase command needed */
+#define	SST_WRITE		0x04	/* use SST byte programming */
+#define	SPI_NOR_NO_FR		0x08	/* Can't do fastread */
+#define	SECT_4K_PMC		0x10	/* SPINOR_OP_BE_4K_PMC works uniformly */
+#define	SPI_NOR_DUAL_READ	0x20    /* Flash supports Dual Read */
+#define	SPI_NOR_QUAD_READ	0x40    /* Flash supports Quad Read */
+#define	USE_FSR			0x80	/* use flag status register */
+};
+
+#define JEDEC_MFR(info)	((info)->id[0])
+
+static const struct spi_device_id *spi_nor_match_id(const char *name);
+
+/*
+ * Read the status register, returning its value in the location
+ * Return the status register value.
+ * Returns negative if error occurred.
+ */
+static int read_sr(struct spi_nor *nor)
+{
+	int ret;
+	u8 val;
+
+	ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
+	if (ret < 0) {
+		pr_err("error %d reading SR\n", (int) ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
+ * Read the flag status register, returning its value in the location
+ * Return the status register value.
+ * Returns negative if error occurred.
+ */
+static int read_fsr(struct spi_nor *nor)
+{
+	int ret;
+	u8 val;
+
+	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
+	if (ret < 0) {
+		pr_err("error %d reading FSR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
+ * Read configuration register, returning its value in the
+ * location. Return the configuration register value.
+ * Returns negative if error occured.
+ */
+static int read_cr(struct spi_nor *nor)
+{
+	int ret;
+	u8 val;
+
+	ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1);
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
+ * Dummy Cycle calculation for different type of read.
+ * It can be used to support more commands with
+ * different dummy cycle requirements.
+ */
+static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
+{
+	switch (nor->flash_read) {
+	case SPI_NOR_FAST:
+	case SPI_NOR_DUAL:
+	case SPI_NOR_QUAD:
+		return 8;
+	case SPI_NOR_NORMAL:
+		return 0;
+	}
+	return 0;
+}
+
+/*
+ * Write status register 1 byte
+ * Returns negative if error occurred.
+ */
+static inline int write_sr(struct spi_nor *nor, u8 val)
+{
+	nor->cmd_buf[0] = val;
+	return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
+}
+
+/*
+ * Set write enable latch with Write Enable command.
+ * Returns negative if error occurred.
+ */
+static inline int write_enable(struct spi_nor *nor)
+{
+	return nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0, 0);
+}
+
+/*
+ * Send write disble instruction to the chip.
+ */
+static inline int write_disable(struct spi_nor *nor)
+{
+	return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
+}
+
+static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
+{
+	return mtd->priv;
+}
+
+/* Enable/disable 4-byte addressing mode. */
+static inline int set_4byte(struct spi_nor *nor, struct flash_info *info,
+			    int enable)
+{
+	int status;
+	bool need_wren = false;
+	u8 cmd;
+
+	switch (JEDEC_MFR(info)) {
+	case CFI_MFR_ST: /* Micron, actually */
+		/* Some Micron need WREN command; all will accept it */
+		need_wren = true;
+	case CFI_MFR_MACRONIX:
+	case 0xEF /* winbond */:
+		if (need_wren)
+			write_enable(nor);
+
+		cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
+		status = nor->write_reg(nor, cmd, NULL, 0, 0);
+		if (need_wren)
+			write_disable(nor);
+
+		return status;
+	default:
+		/* Spansion style */
+		nor->cmd_buf[0] = enable << 7;
+		return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0);
+	}
+}
+static inline int spi_nor_sr_ready(struct spi_nor *nor)
+{
+	int sr = read_sr(nor);
+	if (sr < 0)
+		return sr;
+	else
+		return !(sr & SR_WIP);
+}
+
+static inline int spi_nor_fsr_ready(struct spi_nor *nor)
+{
+	int fsr = read_fsr(nor);
+	if (fsr < 0)
+		return fsr;
+	else
+		return fsr & FSR_READY;
+}
+
+static int spi_nor_ready(struct spi_nor *nor)
+{
+	int sr, fsr;
+	sr = spi_nor_sr_ready(nor);
+	if (sr < 0)
+		return sr;
+	fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
+	if (fsr < 0)
+		return fsr;
+	return sr && fsr;
+}
+
+/*
+ * Service routine to read status register until ready, or timeout occurs.
+ * Returns non-zero if error.
+ */
+static int spi_nor_wait_till_ready(struct spi_nor *nor)
+{
+	uint64_t start = get_time_ns();
+	int timeout = 0;
+	int ret;
+
+	while (!timeout) {
+		if (is_timeout(start, 40 * SECOND))
+			timeout = 1;
+
+		ret = spi_nor_ready(nor);
+		if (ret < 0)
+			return ret;
+		if (ret)
+			return 0;
+	}
+
+	dev_err(nor->dev, "flash operation timed out\n");
+
+	return -ETIMEDOUT;
+}
+
+/*
+ * Erase the whole flash memory
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_chip(struct spi_nor *nor)
+{
+	dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd->size >> 10));
+
+	return nor->write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0, 0);
+}
+
+static int spi_nor_lock_and_prep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+	int ret = 0;
+
+	mutex_lock(&nor->lock);
+
+	if (nor->prepare) {
+		ret = nor->prepare(nor, ops);
+		if (ret) {
+			dev_err(nor->dev, "failed in the preparation.\n");
+			mutex_unlock(&nor->lock);
+			return ret;
+		}
+	}
+	return ret;
+}
+
+static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops)
+{
+	if (nor->unprepare)
+		nor->unprepare(nor, ops);
+	mutex_unlock(&nor->lock);
+}
+
+/*
+ * Erase an address range on the nor chip.  The address range may extend
+ * one or more erase sectors.  Return an error is there is a problem erasing.
+ */
+static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	u32 addr, len;
+	uint32_t rem;
+	int ret;
+
+	dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
+			(long long)instr->len);
+
+	div_u64_rem(instr->len, mtd->erasesize, &rem);
+	if (rem)
+		return -EINVAL;
+
+	addr = instr->addr;
+	len = instr->len;
+
+	/* Assure previous operations are completed */
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		goto erase_err;
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_ERASE);
+	if (ret)
+		return ret;
+
+	/* whole-chip erase? */
+	if (len == mtd->size) {
+		write_enable(nor);
+
+		if (erase_chip(nor)) {
+			ret = -EIO;
+			goto erase_err;
+		}
+
+		ret = spi_nor_wait_till_ready(nor);
+		if (ret)
+			goto erase_err;
+
+	/* REVISIT in some cases we could speed up erasing large regions
+	 * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
+	 * to use "small sector erase", but that's not always optimal.
+	 */
+
+	/* "sector"-at-a-time erase */
+	} else {
+		while (len) {
+			write_enable(nor);
+
+			if (nor->erase(nor, addr)) {
+				ret = -EIO;
+				goto erase_err;
+			}
+
+			addr += mtd->erasesize;
+			len -= mtd->erasesize;
+
+			ret = spi_nor_wait_till_ready(nor);
+			if (ret)
+				goto erase_err;
+		}
+	}
+
+	write_disable(nor);
+
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
+
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
+
+	return ret;
+
+erase_err:
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
+	instr->state = MTD_ERASE_FAILED;
+	return ret;
+}
+
+static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	uint32_t offset = ofs;
+	uint8_t status_old, status_new;
+	int ret = 0;
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK);
+	if (ret)
+		return ret;
+
+	status_old = read_sr(nor);
+
+	if (offset < mtd->size - (mtd->size / 2))
+		status_new = status_old | SR_BP2 | SR_BP1 | SR_BP0;
+	else if (offset < mtd->size - (mtd->size / 4))
+		status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
+	else if (offset < mtd->size - (mtd->size / 8))
+		status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
+	else if (offset < mtd->size - (mtd->size / 16))
+		status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
+	else if (offset < mtd->size - (mtd->size / 32))
+		status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
+	else if (offset < mtd->size - (mtd->size / 64))
+		status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
+	else
+		status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
+
+	/* Only modify protection if it will not unlock other areas */
+	if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) >
+				(status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
+		write_enable(nor);
+		ret = write_sr(nor, status_new);
+		if (ret)
+			goto err;
+	}
+
+err:
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
+	return ret;
+}
+
+static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	uint32_t offset = ofs;
+	uint8_t status_old, status_new;
+	int ret = 0;
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK);
+	if (ret)
+		return ret;
+
+	status_old = read_sr(nor);
+
+	if (offset+len > mtd->size - (mtd->size / 64))
+		status_new = status_old & ~(SR_BP2 | SR_BP1 | SR_BP0);
+	else if (offset+len > mtd->size - (mtd->size / 32))
+		status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
+	else if (offset+len > mtd->size - (mtd->size / 16))
+		status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
+	else if (offset+len > mtd->size - (mtd->size / 8))
+		status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
+	else if (offset+len > mtd->size - (mtd->size / 4))
+		status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
+	else if (offset+len > mtd->size - (mtd->size / 2))
+		status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
+	else
+		status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
+
+	/* Only modify protection if it will not lock other areas */
+	if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) <
+				(status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
+		write_enable(nor);
+		ret = write_sr(nor, status_new);
+		if (ret)
+			goto err;
+	}
+
+err:
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
+	return ret;
+}
+
+/* Used when the "_ext_id" is two bytes at most */
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
+	((unsigned long)&(struct flash_info) {				\
+		.id = {							\
+			((_jedec_id) >> 16) & 0xff,			\
+			((_jedec_id) >> 8) & 0xff,			\
+			(_jedec_id) & 0xff,				\
+			((_ext_id) >> 8) & 0xff,			\
+			(_ext_id) & 0xff,				\
+			},						\
+		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = 256,					\
+		.flags = (_flags),					\
+	})
+
+#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
+	((unsigned long)&(struct flash_info) {				\
+		.id = {							\
+			((_jedec_id) >> 16) & 0xff,			\
+			((_jedec_id) >> 8) & 0xff,			\
+			(_jedec_id) & 0xff,				\
+			((_ext_id) >> 16) & 0xff,			\
+			((_ext_id) >> 8) & 0xff,			\
+			(_ext_id) & 0xff,				\
+			},						\
+		.id_len = 6,						\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = 256,					\
+		.flags = (_flags),					\
+	})
+
+#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
+	((unsigned long)&(struct flash_info) {				\
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = (_page_size),				\
+		.addr_width = (_addr_width),				\
+		.flags = (_flags),					\
+	})
+
+/* NOTE: double check command sets and memory organization when you add
+ * more nor chips.  This current list focusses on newer chips, which
+ * have been converging on command sets which including JEDEC ID.
+ */
+static const struct spi_device_id spi_nor_ids[] = {
+	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
+	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
+	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
+
+	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
+	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
+	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
+
+	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
+	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
+	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
+	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
+
+	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
+
+	/* EON -- en25xxx */
+	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
+	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
+	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
+	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
+	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
+	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
+	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
+
+	/* ESMT */
+	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
+
+	/* Everspin */
+	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+
+	/* Fujitsu */
+	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
+
+	/* GigaDevice */
+	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
+
+	/* Intel/Numonyx -- xxxs33b */
+	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
+	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
+	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
+
+	/* Macronix */
+	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
+	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
+	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
+	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
+	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
+	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
+	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
+	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
+	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+
+	/* Micron */
+	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, 0) },
+	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
+	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
+	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR | SPI_NOR_QUAD_READ) },
+
+	/* PMC */
+	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
+	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
+	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
+
+	/* Spansion -- single (large) sector size only, at least
+	 * for the chips listed here (without boot sectors).
+	 */
+	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
+	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
+	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
+	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
+	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
+	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
+	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
+	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
+	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
+	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
+	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K) },
+	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
+	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
+	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, 0) },
+
+	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
+	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
+	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
+	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
+	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
+	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
+	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+
+	/* ST Microelectronics -- newer production may have feature updates */
+	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
+	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
+	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
+	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
+	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
+	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
+	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
+	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
+	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
+
+	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
+	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
+	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
+	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
+	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
+	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
+	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
+	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
+	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
+
+	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
+	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
+	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
+
+	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
+	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
+	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
+
+	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SECT_4K) },
+	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
+	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
+
+	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
+	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
+	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
+	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
+	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
+	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
+
+	/* Catalyst / On Semiconductor -- non-JEDEC */
+	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ },
+};
+
+static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
+{
+	int			tmp;
+	u8			id[SPI_NOR_MAX_ID_LEN];
+	struct flash_info	*info;
+
+	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+	if (tmp < 0) {
+		dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
+		return ERR_PTR(tmp);
+	}
+
+	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
+		info = (void *)spi_nor_ids[tmp].driver_data;
+		if (info->id_len) {
+			if (!memcmp(info->id, id, info->id_len))
+				return &spi_nor_ids[tmp];
+		}
+	}
+	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
+		id[0], id[1], id[2]);
+	return ERR_PTR(-ENODEV);
+}
+
+static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, u_char *buf)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	int ret;
+
+	dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_READ);
+	if (ret)
+		return ret;
+
+	ret = nor->read(nor, from, len, retlen, buf);
+
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
+	return ret;
+}
+
+static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u_char *buf)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	size_t actual;
+	int ret;
+
+	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);
+	if (ret)
+		return ret;
+
+	write_enable(nor);
+
+	nor->sst_write_second = false;
+
+	actual = to % 2;
+	/* Start write from odd address. */
+	if (actual) {
+		nor->program_opcode = SPINOR_OP_BP;
+
+		/* write one byte. */
+		nor->write(nor, to, 1, retlen, buf);
+		ret = spi_nor_wait_till_ready(nor);
+		if (ret)
+			goto time_out;
+	}
+	to += actual;
+
+	/* Write out most of the data here. */
+	for (; actual < len - 1; actual += 2) {
+		nor->program_opcode = SPINOR_OP_AAI_WP;
+
+		/* write two bytes. */
+		nor->write(nor, to, 2, retlen, buf + actual);
+		ret = spi_nor_wait_till_ready(nor);
+		if (ret)
+			goto time_out;
+		to += 2;
+		nor->sst_write_second = true;
+	}
+	nor->sst_write_second = false;
+
+	write_disable(nor);
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		goto time_out;
+
+	/* Write out trailing byte if it exists. */
+	if (actual != len) {
+		write_enable(nor);
+
+		nor->program_opcode = SPINOR_OP_BP;
+		nor->write(nor, to, 1, retlen, buf + actual);
+
+		ret = spi_nor_wait_till_ready(nor);
+		if (ret)
+			goto time_out;
+		write_disable(nor);
+	}
+time_out:
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+	return ret;
+}
+
+/*
+ * Write an address range to the nor chip.  Data must be written in
+ * FLASH_PAGESIZE chunks.  The address range may be any size provided
+ * it is within the physical boundaries.
+ */
+static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
+	size_t *retlen, const u_char *buf)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	u32 page_offset, page_size, i;
+	int ret;
+
+	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
+
+	ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE);
+	if (ret)
+		return ret;
+
+	write_enable(nor);
+
+	page_offset = to & (nor->page_size - 1);
+
+	/* do all the bytes fit onto one page? */
+	if (page_offset + len <= nor->page_size) {
+		nor->write(nor, to, len, retlen, buf);
+	} else {
+		/* the size of data remaining on the first page */
+		page_size = nor->page_size - page_offset;
+		nor->write(nor, to, page_size, retlen, buf);
+
+		/* write everything in nor->page_size chunks */
+		for (i = page_size; i < len; i += page_size) {
+			page_size = len - i;
+			if (page_size > nor->page_size)
+				page_size = nor->page_size;
+
+			ret = spi_nor_wait_till_ready(nor);
+			if (ret)
+				goto write_err;
+
+			write_enable(nor);
+
+			nor->write(nor, to + i, page_size, retlen, buf + i);
+		}
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+write_err:
+	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
+	return ret;
+}
+
+static int macronix_quad_enable(struct spi_nor *nor)
+{
+	int ret, val;
+
+	val = read_sr(nor);
+	write_enable(nor);
+
+	nor->cmd_buf[0] = val | SR_QUAD_EN_MX;
+	nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1, 0);
+
+	if (spi_nor_wait_till_ready(nor))
+		return 1;
+
+	ret = read_sr(nor);
+	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+		dev_err(nor->dev, "Macronix Quad bit not set\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct spi_nor *nor, u16 val)
+{
+	nor->cmd_buf[0] = val & 0xff;
+	nor->cmd_buf[1] = (val >> 8);
+
+	return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2, 0);
+}
+
+static int spansion_quad_enable(struct spi_nor *nor)
+{
+	int ret;
+	int quad_en = CR_QUAD_EN_SPAN << 8;
+
+	write_enable(nor);
+
+	ret = write_sr_cr(nor, quad_en);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while writing configuration register\n");
+		return -EINVAL;
+	}
+
+	/* read back and check it */
+	ret = read_cr(nor);
+	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+		dev_err(nor->dev, "Spansion Quad bit not set\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
+{
+	int status;
+
+	switch (JEDEC_MFR(info)) {
+	case CFI_MFR_MACRONIX:
+		status = macronix_quad_enable(nor);
+		if (status) {
+			dev_err(nor->dev, "Macronix quad-read not enabled\n");
+			return -EINVAL;
+		}
+		return status;
+	default:
+		status = spansion_quad_enable(nor);
+		if (status) {
+			dev_err(nor->dev, "Spansion quad-read not enabled\n");
+			return -EINVAL;
+		}
+		return status;
+	}
+}
+
+static int spi_nor_check(struct spi_nor *nor)
+{
+	if (!nor->dev || !nor->read || !nor->write ||
+		!nor->read_reg || !nor->write_reg || !nor->erase) {
+		pr_err("spi-nor: please fill all the necessary fields!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+{
+	const struct spi_device_id	*id = NULL;
+	struct flash_info		*info;
+	struct device_d *dev = nor->dev;
+	struct mtd_info *mtd = nor->mtd;
+	struct device_node *np = dev->device_node;
+	int ret;
+	int i;
+
+	ret = spi_nor_check(nor);
+	if (ret)
+		return ret;
+
+	/* Try to auto-detect if chip name wasn't specified */
+	if (!name)
+		id = spi_nor_read_id(nor);
+	else
+		id = spi_nor_match_id(name);
+	if (IS_ERR_OR_NULL(id))
+		return -ENOENT;
+
+	info = (void *)id->driver_data;
+
+	/*
+	 * If caller has specified name of flash model that can normally be
+	 * detected using JEDEC, let's verify it.
+	 */
+	if (name && info->id_len) {
+		const struct spi_device_id *jid;
+
+		jid = spi_nor_read_id(nor);
+		if (IS_ERR(jid)) {
+			return PTR_ERR(jid);
+		} else if (jid != id) {
+			/*
+			 * JEDEC knows better, so overwrite platform ID. We
+			 * can't trust partitions any longer, but we'll let
+			 * mtd apply them anyway, since some partitions may be
+			 * marked read-only, and we don't want to lose that
+			 * information, even if it's not 100% accurate.
+			 */
+			dev_warn(dev, "found %s, expected %s\n",
+				 jid->name, id->name);
+			id = jid;
+			info = (void *)jid->driver_data;
+		}
+	}
+
+	mutex_init(&nor->lock);
+
+	/*
+	 * Atmel, SST and Intel/Numonyx serial nor tend to power
+	 * up with the software protection bits set
+	 */
+
+	if (JEDEC_MFR(info) == CFI_MFR_ATMEL ||
+	    JEDEC_MFR(info) == CFI_MFR_INTEL ||
+	    JEDEC_MFR(info) == CFI_MFR_SST) {
+		write_enable(nor);
+		write_sr(nor, 0);
+	}
+
+	if (!mtd->name)
+		mtd->name = (char *) dev_name(dev);
+	mtd->type = MTD_NORFLASH;
+	mtd->writesize = 1;
+	mtd->flags = MTD_CAP_NORFLASH;
+	mtd->size = info->sector_size * info->n_sectors;
+	mtd->erase = spi_nor_erase;
+	mtd->read = spi_nor_read;
+
+	/* nor protection support for STmicro chips */
+	if (JEDEC_MFR(info) == CFI_MFR_ST) {
+		mtd->lock = spi_nor_lock;
+		mtd->unlock = spi_nor_unlock;
+	}
+
+	/* sst nor chips use AAI word program */
+	if (info->flags & SST_WRITE)
+		mtd->write = sst_write;
+	else
+		mtd->write = spi_nor_write;
+
+	if (info->flags & USE_FSR)
+		nor->flags |= SNOR_F_USE_FSR;
+
+#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
+	/* prefer "small sector" erase if possible */
+	if (info->flags & SECT_4K) {
+		nor->erase_opcode = SPINOR_OP_BE_4K;
+		mtd->erasesize = 4096;
+	} else if (info->flags & SECT_4K_PMC) {
+		nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
+		mtd->erasesize = 4096;
+	} else
+#endif
+	{
+		nor->erase_opcode = SPINOR_OP_SE;
+		mtd->erasesize = info->sector_size;
+	}
+
+	if (info->flags & SPI_NOR_NO_ERASE)
+		mtd->flags |= MTD_NO_ERASE;
+
+	nor->page_size = info->page_size;
+	mtd->writebufsize = nor->page_size;
+
+	if (np) {
+		/* If we were instantiated by DT, use it */
+		if (of_property_read_bool(np, "m25p,fast-read"))
+			nor->flash_read = SPI_NOR_FAST;
+		else
+			nor->flash_read = SPI_NOR_NORMAL;
+	} else {
+		/* If we weren't instantiated by DT, default to fast-read */
+		nor->flash_read = SPI_NOR_FAST;
+	}
+
+	/* Some devices cannot do fast-read, no matter what DT tells us */
+	if (info->flags & SPI_NOR_NO_FR)
+		nor->flash_read = SPI_NOR_NORMAL;
+
+	/* Quad/Dual-read mode takes precedence over fast/normal */
+	if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
+		ret = set_quad_mode(nor, info);
+		if (ret) {
+			dev_err(dev, "quad mode not supported\n");
+			return ret;
+		}
+		nor->flash_read = SPI_NOR_QUAD;
+	} else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) {
+		nor->flash_read = SPI_NOR_DUAL;
+	}
+
+	/* Default commands */
+	switch (nor->flash_read) {
+	case SPI_NOR_QUAD:
+		nor->read_opcode = SPINOR_OP_READ_1_1_4;
+		break;
+	case SPI_NOR_DUAL:
+		nor->read_opcode = SPINOR_OP_READ_1_1_2;
+		break;
+	case SPI_NOR_FAST:
+		nor->read_opcode = SPINOR_OP_READ_FAST;
+		break;
+	case SPI_NOR_NORMAL:
+		nor->read_opcode = SPINOR_OP_READ;
+		break;
+	default:
+		dev_err(dev, "No Read opcode defined\n");
+		return -EINVAL;
+	}
+
+	nor->program_opcode = SPINOR_OP_PP;
+
+	if (info->addr_width)
+		nor->addr_width = info->addr_width;
+	else if (mtd->size > 0x1000000) {
+		/* enable 4-byte addressing if the device exceeds 16MiB */
+		nor->addr_width = 4;
+		if (JEDEC_MFR(info) == CFI_MFR_AMD) {
+			/* Dedicated 4-byte command set */
+			switch (nor->flash_read) {
+			case SPI_NOR_QUAD:
+				nor->read_opcode = SPINOR_OP_READ4_1_1_4;
+				break;
+			case SPI_NOR_DUAL:
+				nor->read_opcode = SPINOR_OP_READ4_1_1_2;
+				break;
+			case SPI_NOR_FAST:
+				nor->read_opcode = SPINOR_OP_READ4_FAST;
+				break;
+			case SPI_NOR_NORMAL:
+				nor->read_opcode = SPINOR_OP_READ4;
+				break;
+			}
+			nor->program_opcode = SPINOR_OP_PP_4B;
+			/* No small sector erase for 4-byte command set */
+			nor->erase_opcode = SPINOR_OP_SE_4B;
+			mtd->erasesize = info->sector_size;
+		} else
+			set_4byte(nor, info, 1);
+	} else {
+		nor->addr_width = 3;
+	}
+
+	nor->read_dummy = spi_nor_read_dummy_cycles(nor);
+
+	dev_info(dev, "%s (%lld Kbytes)\n", id->name,
+			(long long)mtd->size >> 10);
+
+	dev_dbg(dev,
+		"mtd .name = %s, .size = 0x%llx (%lldMiB), "
+		".erasesize = 0x%.8x (%uKiB) .numeraseregions = %d\n",
+		mtd->name, (long long)mtd->size, (long long)(mtd->size >> 20),
+		mtd->erasesize, mtd->erasesize / 1024, mtd->numeraseregions);
+
+	if (mtd->numeraseregions)
+		for (i = 0; i < mtd->numeraseregions; i++)
+			dev_dbg(dev,
+				"mtd.eraseregions[%d] = { .offset = 0x%llx, "
+				".erasesize = 0x%.8x (%uKiB), "
+				".numblocks = %d }\n",
+				i, (long long)mtd->eraseregions[i].offset,
+				mtd->eraseregions[i].erasesize,
+				mtd->eraseregions[i].erasesize / 1024,
+				mtd->eraseregions[i].numblocks);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(spi_nor_scan);
+
+static const struct spi_device_id *spi_nor_match_id(const char *name)
+{
+	const struct spi_device_id *id = spi_nor_ids;
+
+	while (id->name[0]) {
+		if (!strcmp(name, id->name))
+			return id;
+		id++;
+	}
+	return NULL;
+}
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index c8220756884d..d8125214a04a 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -17,4 +17,11 @@ struct pci_device_id {
 	__u32 class, class_mask;	/* (class,subclass,prog-if) triplet */
 };
 
+#define SPI_NAME_SIZE 32
+
+struct spi_device_id {
+	char name[SPI_NAME_SIZE];
+	unsigned long driver_data;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
new file mode 100644
index 000000000000..f099406c534a
--- /dev/null
+++ b/include/linux/mtd/spi-nor.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef __LINUX_MTD_SPI_NOR_H
+#define __LINUX_MTD_SPI_NOR_H
+
+/*
+ * Note on opcode nomenclature: some opcodes have a format like
+ * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
+ * of I/O lines used for the opcode, address, and data (respectively). The
+ * FUNCTION has an optional suffix of '4', to represent an opcode which
+ * requires a 4-byte (32-bit) address.
+ */
+
+/* Flash opcodes. */
+#define SPINOR_OP_WREN		0x06	/* Write enable */
+#define SPINOR_OP_RDSR		0x05	/* Read status register */
+#define SPINOR_OP_WRSR		0x01	/* Write status register 1 byte */
+#define SPINOR_OP_READ		0x03	/* Read data bytes (low frequency) */
+#define SPINOR_OP_READ_FAST	0x0b	/* Read data bytes (high frequency) */
+#define SPINOR_OP_READ_1_1_2	0x3b	/* Read data bytes (Dual SPI) */
+#define SPINOR_OP_READ_1_1_4	0x6b	/* Read data bytes (Quad SPI) */
+#define SPINOR_OP_PP		0x02	/* Page program (up to 256 bytes) */
+#define SPINOR_OP_BE_4K		0x20	/* Erase 4KiB block */
+#define SPINOR_OP_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
+#define SPINOR_OP_BE_32K	0x52	/* Erase 32KiB block */
+#define SPINOR_OP_CHIP_ERASE	0xc7	/* Erase whole flash chip */
+#define SPINOR_OP_SE		0xd8	/* Sector erase (usually 64KiB) */
+#define SPINOR_OP_RDID		0x9f	/* Read JEDEC ID */
+#define SPINOR_OP_RDCR		0x35	/* Read configuration register */
+#define SPINOR_OP_RDFSR		0x70	/* Read flag status register */
+
+/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
+#define SPINOR_OP_READ4		0x13	/* Read data bytes (low frequency) */
+#define SPINOR_OP_READ4_FAST	0x0c	/* Read data bytes (high frequency) */
+#define SPINOR_OP_READ4_1_1_2	0x3c	/* Read data bytes (Dual SPI) */
+#define SPINOR_OP_READ4_1_1_4	0x6c	/* Read data bytes (Quad SPI) */
+#define SPINOR_OP_PP_4B		0x12	/* Page program (up to 256 bytes) */
+#define SPINOR_OP_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
+
+/* Used for SST flashes only. */
+#define SPINOR_OP_BP		0x02	/* Byte program */
+#define SPINOR_OP_WRDI		0x04	/* Write disable */
+#define SPINOR_OP_AAI_WP	0xad	/* Auto address increment word program */
+
+/* Used for Macronix and Winbond flashes. */
+#define SPINOR_OP_EN4B		0xb7	/* Enter 4-byte mode */
+#define SPINOR_OP_EX4B		0xe9	/* Exit 4-byte mode */
+
+/* Used for Spansion flashes only. */
+#define SPINOR_OP_BRWR		0x17	/* Bank register write */
+
+/* Status Register bits. */
+#define SR_WIP			1	/* Write in progress */
+#define SR_WEL			2	/* Write enable latch */
+/* meaning of other SR_* bits may differ between vendors */
+#define SR_BP0			4	/* Block protect 0 */
+#define SR_BP1			8	/* Block protect 1 */
+#define SR_BP2			0x10	/* Block protect 2 */
+#define SR_SRWD			0x80	/* SR write protect */
+
+#define SR_QUAD_EN_MX		0x40	/* Macronix Quad I/O */
+
+/* Flag Status Register bits */
+#define FSR_READY		0x80
+
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN		0x2	/* Spansion Quad I/O */
+
+enum read_mode {
+	SPI_NOR_NORMAL = 0,
+	SPI_NOR_FAST,
+	SPI_NOR_DUAL,
+	SPI_NOR_QUAD,
+};
+
+/**
+ * struct spi_nor_xfer_cfg - Structure for defining a Serial Flash transfer
+ * @wren:		command for "Write Enable", or 0x00 for not required
+ * @cmd:		command for operation
+ * @cmd_pins:		number of pins to send @cmd (1, 2, 4)
+ * @addr:		address for operation
+ * @addr_pins:		number of pins to send @addr (1, 2, 4)
+ * @addr_width:		number of address bytes
+ *			(3,4, or 0 for address not required)
+ * @mode:		mode data
+ * @mode_pins:		number of pins to send @mode (1, 2, 4)
+ * @mode_cycles:	number of mode cycles (0 for mode not required)
+ * @dummy_cycles:	number of dummy cycles (0 for dummy not required)
+ */
+struct spi_nor_xfer_cfg {
+	u8		wren;
+	u8		cmd;
+	u8		cmd_pins;
+	u32		addr;
+	u8		addr_pins;
+	u8		addr_width;
+	u8		mode;
+	u8		mode_pins;
+	u8		mode_cycles;
+	u8		dummy_cycles;
+};
+
+#define SPI_NOR_MAX_CMD_SIZE	8
+enum spi_nor_ops {
+	SPI_NOR_OPS_READ = 0,
+	SPI_NOR_OPS_WRITE,
+	SPI_NOR_OPS_ERASE,
+	SPI_NOR_OPS_LOCK,
+	SPI_NOR_OPS_UNLOCK,
+};
+
+enum spi_nor_option_flags {
+	SNOR_F_USE_FSR		= BIT(0),
+};
+
+/**
+ * struct spi_nor - Structure for defining a the SPI NOR layer
+ * @mtd:		point to a mtd_info structure
+ * @lock:		the lock for the read/write/erase/lock/unlock operations
+ * @dev:		point to a spi device, or a spi nor controller device.
+ * @page_size:		the page size of the SPI NOR
+ * @addr_width:		number of address bytes
+ * @erase_opcode:	the opcode for erasing a sector
+ * @read_opcode:	the read opcode
+ * @read_dummy:		the dummy needed by the read operation
+ * @program_opcode:	the program opcode
+ * @flash_read:		the mode of the read
+ * @sst_write_second:	used by the SST write operation
+ * @flags:		flag options for the current SPI-NOR (SNOR_F_*)
+ * @cfg:		used by the read_xfer/write_xfer
+ * @cmd_buf:		used by the write_reg
+ * @prepare:		[OPTIONAL] do some preparations for the
+ *			read/write/erase/lock/unlock operations
+ * @unprepare:		[OPTIONAL] do some post work after the
+ *			read/write/erase/lock/unlock operations
+ * @read_xfer:		[OPTIONAL] the read fundamental primitive
+ * @write_xfer:		[OPTIONAL] the writefundamental primitive
+ * @read_reg:		[DRIVER-SPECIFIC] read out the register
+ * @write_reg:		[DRIVER-SPECIFIC] write data to the register
+ * @read:		[DRIVER-SPECIFIC] read data from the SPI NOR
+ * @write:		[DRIVER-SPECIFIC] write data to the SPI NOR
+ * @erase:		[DRIVER-SPECIFIC] erase a sector of the SPI NOR
+ *			at the offset @offs
+ * @priv:		the private data
+ */
+struct spi_nor {
+	struct mtd_info		*mtd;
+	struct mutex		lock;
+	struct device_d		*dev;
+	u32			page_size;
+	u8			addr_width;
+	u8			erase_opcode;
+	u8			read_opcode;
+	u8			read_dummy;
+	u8			program_opcode;
+	enum read_mode		flash_read;
+	bool			sst_write_second;
+	u32			flags;
+	struct spi_nor_xfer_cfg	cfg;
+	u8			cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+
+	int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
+	void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
+	int (*read_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg,
+			 u8 *buf, size_t len);
+	int (*write_xfer)(struct spi_nor *nor, struct spi_nor_xfer_cfg *cfg,
+			  u8 *buf, size_t len);
+	int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
+	int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
+			int write_enable);
+
+	int (*read)(struct spi_nor *nor, loff_t from,
+			size_t len, size_t *retlen, u_char *read_buf);
+	void (*write)(struct spi_nor *nor, loff_t to,
+			size_t len, size_t *retlen, const u_char *write_buf);
+	int (*erase)(struct spi_nor *nor, loff_t offs);
+
+	void *priv;
+};
+
+/**
+ * spi_nor_scan() - scan the SPI NOR
+ * @nor:	the spi_nor structure
+ * @name:	the chip type name
+ * @mode:	the read mode supported by the driver
+ *
+ * The drivers can use this fuction to scan the SPI NOR.
+ * In the scanning, it will try to get all the necessary information to
+ * fill the mtd_info{} and the spi_nor{}.
+ *
+ * The chip type name can be provided through the @name parameter.
+ *
+ * Return: 0 for success, others for failure.
+ */
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+
+#endif
-- 
2.1.4



From s.hauer at pengutronix.de  Fri May 29 00:22:50 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 29 May 2015 09:22:50 +0200
Subject: [PATCH] barebox update: add note after successful update
In-Reply-To: <20150522115515.GB5384@lws-christ>
References: <1432194109-4340-1-git-send-email-s.christ@phytec.de>
 <20150522065037.GT6325@pengutronix.de>
 <20150522115515.GB5384@lws-christ>
Message-ID: <20150529072250.GB6325@pengutronix.de>

On Fri, May 22, 2015 at 01:55:16PM +0200, Stefan Christ wrote:
> On Fri, May 22, 2015 at 08:50:37AM +0200, Sascha Hauer wrote:
> > On Thu, May 21, 2015 at 09:41:49AM +0200, Stefan Christ wrote:
> > > Some users of the barebox_update command forget to erase the external
> > > barebox environment after updating the barebox. Using an old barebox
> > > environment leads to various problems if there were major changes.
> > > 
> > > So add a gentle reminder after the successful update.
> > > 
> > > Signed-off-by: Stefan Christ <s.christ at phytec.de>
> > > ---
> > >  common/bbu.c | 5 ++++-
> > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/common/bbu.c b/common/bbu.c
> > > index 7fb154a..1b125e9 100644
> > > --- a/common/bbu.c
> > > +++ b/common/bbu.c
> > > @@ -113,8 +113,11 @@ int barebox_update(struct bbu_data *data)
> > >  	if (ret == -EINTR)
> > >  		printf("update aborted\n");
> > >  
> > > -	if (!ret)
> > > +	if (!ret) {
> > >  		printf("update succeeded\n");
> > > +		if (IS_ENABLED(CONFIG_ENV_HANDLING))
> > > +			printf("You maybe want to erase the barebox environment.\n");
> > 
> > How about adding a hint ...using saveenv -z?
> 
> Oh, I didn't know that the "-z" argument exits. Nice.
> 
> Ok, but what about the situation when a user boots the barebox from sdcard and
> uses the barebox_update handler to flash a barebox to NAND. In such case
> 'saveenv -z' overwrites the environment on the sdcard.

I still have no good answer to this :/

I may also happen that the updated barebox comes with a different
partition layout so that you can't properly erase the environment from
the currently running barebox. At some point we thought about adding
some version counter to the environment so that the updated barebox
could either issue a warning when an outdated environment is detected
or ignore it completely. This would of course mean we must not forget to
increase the version when we do an incompatible change.

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  Fri May 29 00:23:54 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 29 May 2015 09:23:54 +0200
Subject: Memtest failed. Error: -22
In-Reply-To: <55636025.4050508@ge.com>
References: <55636025.4050508@ge.com>
Message-ID: <20150529072354.GC6325@pengutronix.de>

Hi Renaud,

On Mon, May 25, 2015 at 06:47:17PM +0100, Renaud Barbier wrote:
> I just used memtest on a couple of PPC board (freescale mpc8544 and
> P1014) and it failed with:
> 
> barebox>/ memtest
> Memtest failed. Error: -22
> 
> This error happens when the space between two regions is smaller than a
> page size:
>  0x0bf75000 - 0x0ff74fff (size 0x04000000) malloc space
>  0x0ff756e8 - 0x0ff7d6e7 (size 0x00008000) stack
> 
> 
> In this case, the size - when doing the calculation "size =
> PAGE_ALIGN_DOWN(end - start + 1);" - is zero.
> 
> The function call ret = alloc_memtest_region(list, start, size);
> then fails.
> 
> I will not be able to offer a patch until second week of June as I am away.

Thanks for noting, this is worth fixing. I think though that we can wait
until you are back.

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  Fri May 29 00:25:24 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 29 May 2015 09:25:24 +0200
Subject: [PATCH v2 0/8] Socfpga: QSPI support
In-Reply-To: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
Message-ID: <20150529072524.GD6325@pengutronix.de>

On Thu, May 28, 2015 at 05:55:59PM +0200, Steffen Trumtrar wrote:
> Hi!
> 
> This series adds support for reading,writing and booting from Quad SPI
> flash chips on the SoCFPFGA platform.
> 
> The driver is based on a patch for linux, which is still in development.
> As this driver uses the spi-nor framework, this is imported into barebox, too.
> To deduplicate the code base, the m25p80 is also converted to use the spi-nor
> framework.
> 
> With the QSPI driver in place, support for booting from it is also added.
> As the preloader barebox doesn't have a devicetree to go from, the driver doesn't
> touch the registers that have already been set up successfully by the Boot ROM code.
> If there ever is any other user of the Cadence QSPI core, that does not have a
> devicetree to probe from, platform code might have to be added for this initialization.
> As there isn't at the moment, I chose to not bother with this.
> 
> The cadence-qspi was tested on the Socrates, Sockit and Socdk.
> The m25p80 was tested as "m25p80" on a Phycore AM335x SOM.

Applied, thanks.

Please look out for trailing blank lines next time. There are some of
them in the dts changes I manually fixed up this time.

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  Fri May 29 00:49:43 2015
From: s.trumtrar at pengutronix.de (Steffen Trumtrar)
Date: Fri, 29 May 2015 09:49:43 +0200
Subject: [PATCH v2 0/8] Socfpga: QSPI support
In-Reply-To: <20150529072524.GD6325@pengutronix.de>
References: <1432828567-14037-1-git-send-email-s.trumtrar@pengutronix.de>
 <20150529072524.GD6325@pengutronix.de>
Message-ID: <20150529074943.GC12390@pengutronix.de>

On Fri, May 29, 2015 at 09:25:24AM +0200, Sascha Hauer wrote:
> On Thu, May 28, 2015 at 05:55:59PM +0200, Steffen Trumtrar wrote:
> > Hi!
> > 
> > This series adds support for reading,writing and booting from Quad SPI
> > flash chips on the SoCFPFGA platform.
> > 
> > The driver is based on a patch for linux, which is still in development.
> > As this driver uses the spi-nor framework, this is imported into barebox, too.
> > To deduplicate the code base, the m25p80 is also converted to use the spi-nor
> > framework.
> > 
> > With the QSPI driver in place, support for booting from it is also added.
> > As the preloader barebox doesn't have a devicetree to go from, the driver doesn't
> > touch the registers that have already been set up successfully by the Boot ROM code.
> > If there ever is any other user of the Cadence QSPI core, that does not have a
> > devicetree to probe from, platform code might have to be added for this initialization.
> > As there isn't at the moment, I chose to not bother with this.
> > 
> > The cadence-qspi was tested on the Socrates, Sockit and Socdk.
> > The m25p80 was tested as "m25p80" on a Phycore AM335x SOM.
> 
> Applied, thanks.
> 
> Please look out for trailing blank lines next time. There are some of
> them in the dts changes I manually fixed up this time.
> 

Oh, sorry. I didn't catch them...

Thanks,
Steffen

-- 
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 jluebbe at debian.org  Sat May 30 05:57:49 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 14:57:49 +0200
Subject: [PATCH] gpio-davinci: gpio get should return 0 or 1
Message-ID: <1432990669-20515-1-git-send-email-jluebbe@debian.org>

Returning other values causes problems for client code which wants to
perform calculations with the returned value.

Signed-off-by: Jan Luebbe <jluebbe at debian.org>
---
 drivers/gpio/gpio-davinci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index 2b1d82b..61c6e7e 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -117,7 +117,7 @@ static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
 	struct davinci_gpio_controller *d = chip2controller(chip);
 	struct davinci_gpio_regs __iomem *g = d->regs;
 
-	return (1 << offset) & readl_relaxed(&g->in_data);
+	return ((1 << offset) & readl_relaxed(&g->in_data)) ? 1 : 0;
 }
 
 /*
-- 
2.1.4



From jluebbe at debian.org  Sat May 30 06:03:41 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 15:03:41 +0200
Subject: [PATCH] watchdog: add davinci watchdog driver
Message-ID: <1432991021-20738-1-git-send-email-jluebbe@debian.org>

This driver is based on the Linux driver (v4.0).

Signed-off-by: Jan Luebbe <jluebbe at debian.org>
---
 drivers/watchdog/Kconfig       |   6 ++
 drivers/watchdog/Makefile      |   1 +
 drivers/watchdog/davinci_wdt.c | 172 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/watchdog/davinci_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7f7b02e..582c615 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -10,6 +10,12 @@ menuconfig WATCHDOG
 
 if WATCHDOG
 
+config WATCHDOG_DAVINCI
+	bool "TI Davinci"
+	depends on ARCH_DAVINCI
+	help
+	  Add support for watchdog on the TI Davinci SoC.
+
 config WATCHDOG_MXS28
 	bool "i.MX28"
 	depends on ARCH_IMX28
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 865fc47..1e63c49 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_WATCHDOG) += wd_core.o
+obj-$(CONFIG_WATCHDOG_DAVINCI) += davinci_wdt.o
 obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
 obj-$(CONFIG_WATCHDOG_JZ4740) += jz4740.o
 obj-$(CONFIG_WATCHDOG_IMX_RESET_SOURCE) += imxwd.o
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
new file mode 100644
index 0000000..17bceb8
--- /dev/null
+++ b/drivers/watchdog/davinci_wdt.c
@@ -0,0 +1,172 @@
+/*
+ * drivers/char/watchdog/davinci_wdt.c
+ *
+ * Watchdog driver for DaVinci DM644x/DM646x processors
+ *
+ * Copyright (C) 2006-2013 Texas Instruments.
+ * Copyright (C) 2015 Jan Luebbe <jluebbe at debian.org>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <errno.h>
+#include <malloc.h>
+#include <watchdog.h>
+
+#include <linux/clk.h>
+
+/* Timer register set definition */
+#define PID12	(0x0)
+#define EMUMGT	(0x4)
+#define TIM12	(0x10)
+#define TIM34	(0x14)
+#define PRD12	(0x18)
+#define PRD34	(0x1C)
+#define TCR	(0x20)
+#define TGCR	(0x24)
+#define WDTCR	(0x28)
+
+/* TCR bit definitions */
+#define ENAMODE12_DISABLED	(0 << 6)
+#define ENAMODE12_ONESHOT	(1 << 6)
+#define ENAMODE12_PERIODIC	(2 << 6)
+
+/* TGCR bit definitions */
+#define TIM12RS_UNRESET		(1 << 0)
+#define TIM34RS_UNRESET		(1 << 1)
+#define TIMMODE_64BIT_WDOG      (2 << 2)
+
+/* WDTCR bit definitions */
+#define WDEN			(1 << 14)
+#define WDFLAG			(1 << 15)
+#define WDKEY_SEQ0		(0xa5c6 << 16)
+#define WDKEY_SEQ1		(0xda7e << 16)
+
+/*
+ * struct to hold data for each WDT device
+ * @wd - hold watchdog device as is in WDT core
+ * @base - base io address of WD device
+ * @clk - source clock of WDT
+ * @timeout - previously configured timeout
+ */
+struct davinci_wdt {
+	struct watchdog	wd;
+	void __iomem	*base;
+	struct clk	*clk;
+	unsigned	timeout;
+};
+
+#define to_davinci_wdt(h) container_of(h, struct davinci_wdt, wd)
+
+static int davinci_wdt_start(struct watchdog *wd)
+{
+	u32 tgcr;
+	u32 timer_margin;
+	unsigned long wdt_freq;
+	struct davinci_wdt *davinci_wdt = to_davinci_wdt(wd);
+
+	wdt_freq = clk_get_rate(davinci_wdt->clk);
+
+	/* disable, internal clock source */
+	iowrite32(0, davinci_wdt->base + TCR);
+	/* reset timer, set mode to 64-bit watchdog, and unreset */
+	iowrite32(0, davinci_wdt->base + TGCR);
+	tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
+	iowrite32(tgcr, davinci_wdt->base + TGCR);
+	/* clear counter regs */
+	iowrite32(0, davinci_wdt->base + TIM12);
+	iowrite32(0, davinci_wdt->base + TIM34);
+	/* set timeout period */
+	timer_margin = (((u64)davinci_wdt->timeout * wdt_freq) & 0xffffffff);
+	iowrite32(timer_margin, davinci_wdt->base + PRD12);
+	timer_margin = (((u64)davinci_wdt->timeout * wdt_freq) >> 32);
+	iowrite32(timer_margin, davinci_wdt->base + PRD34);
+	/* enable run continuously */
+	iowrite32(ENAMODE12_PERIODIC, davinci_wdt->base + TCR);
+	/* Once the WDT is in pre-active state write to
+	 * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
+	 * write protected (except for the WDKEY field)
+	 */
+	/* put watchdog in pre-active state */
+	iowrite32(WDKEY_SEQ0 | WDEN, davinci_wdt->base + WDTCR);
+	/* put watchdog in active state */
+	iowrite32(WDKEY_SEQ1 | WDEN, davinci_wdt->base + WDTCR);
+	return 0;
+}
+
+static int davinci_wdt_ping(struct watchdog *wd)
+{
+	struct davinci_wdt *davinci_wdt = to_davinci_wdt(wd);
+
+	/* put watchdog in service state */
+	iowrite32(WDKEY_SEQ0, davinci_wdt->base + WDTCR);
+	/* put watchdog in active state */
+	iowrite32(WDKEY_SEQ1, davinci_wdt->base + WDTCR);
+	return 0;
+}
+
+static int davinci_wdt_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+	struct davinci_wdt *davinci_wdt = to_davinci_wdt(wd);
+
+	if (!davinci_wdt->timeout) {
+		davinci_wdt->timeout = timeout;
+		davinci_wdt_start(wd);
+	} else {
+		davinci_wdt_ping(wd);
+		if (davinci_wdt->timeout != timeout)
+			pr_warn("watchdog timeout can not be changed (currently %d)\n",
+				davinci_wdt->timeout);
+	}
+
+	return 0;
+}
+
+static int davinci_wdt_probe(struct device_d *dev)
+{
+	int ret = 0;
+	struct davinci_wdt *davinci_wdt;
+
+	davinci_wdt = xzalloc(sizeof(*davinci_wdt));
+
+	davinci_wdt->base = dev_request_mem_region(dev, 0);
+	if (!davinci_wdt->base)
+		return -ENODEV;
+
+	davinci_wdt->clk = clk_get(dev, NULL);
+	if (WARN_ON(IS_ERR(davinci_wdt->clk)))
+		return PTR_ERR(davinci_wdt->clk);
+
+	clk_enable(davinci_wdt->clk);
+
+	davinci_wdt->wd.set_timeout = davinci_wdt_set_timeout;
+
+	ret = watchdog_register(&davinci_wdt->wd);
+	if (ret < 0)
+		dev_err(dev, "cannot register watchdog device\n");
+
+	return ret;
+}
+
+static __maybe_unused struct of_device_id davinci_wdt_of_match[] = {
+	{ .compatible = "ti,davinci-wdt", },
+	{},
+};
+
+static struct driver_d platform_wdt_driver = {
+	.name = "davinci-wdt",
+	.of_compatible = DRV_OF_COMPAT(davinci_wdt_of_match),
+	.probe = davinci_wdt_probe,
+};
+device_platform_driver(platform_wdt_driver);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("DaVinci Watchdog Driver");
+MODULE_LICENSE("GPL");
-- 
2.1.4



From jluebbe at debian.org  Sat May 30 06:04:11 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 15:04:11 +0200
Subject: [PATCH] davinci_nand: add support for the NAND controller
Message-ID: <1432991051-20800-1-git-send-email-jluebbe@debian.org>

This driver is based on the Linux driver (v4.0).

Signed-off-by: Jan Luebbe <jluebbe at debian.org>
---
 drivers/mtd/nand/Kconfig        |   7 +
 drivers/mtd/nand/Makefile       |   1 +
 drivers/mtd/nand/davinci_nand.c | 866 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 874 insertions(+)
 create mode 100644 drivers/mtd/nand/davinci_nand.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index a75540b..41a3e31 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -140,4 +140,11 @@ config MTD_NAND_NOMADIK
 	help
 	  Driver for the NAND flash controller on the Nomadik, with ECC.
 
+config MTD_NAND_DAVINCI
+	tristate "Support NAND on DaVinci"
+	depends on ARCH_DAVINCI
+	help
+	  Enable the driver for NAND flash chips on Texas Instruments
+	  DaVinci processors.
+
 endif
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index a0b3198..b8644b2 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_NAND)			+= nand_base.o nand-bb.o
 obj-$(CONFIG_NAND_BBT)			+= nand_bbt.o
 
 obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
+obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
 obj-$(CONFIG_NAND_IMX)			+= nand_imx.o
 obj-$(CONFIG_NAND_IMX_BBM)		+= nand_imx_bbm.o
 obj-$(CONFIG_NAND_OMAP_GPMC)		+= nand_omap_gpmc.o nand_omap_bch_decoder.o
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
new file mode 100644
index 0000000..4b14b6c
--- /dev/null
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -0,0 +1,866 @@
+/*
+ * davinci_nand.c - NAND Flash Driver for DaVinci family chips
+ *
+ * Copyright ? 2006 Texas Instruments.
+ *
+ * Port to 2.6.23 Copyright ? 2008 by:
+ *   Sander Huijsen <Shuijsen at optelecom-nkf.com>
+ *   Troy Kisky <troy.kisky at boundarydevices.com>
+ *   Dirk Behme <Dirk.Behme at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//#define DEBUG
+
+#include <common.h>
+#include <io.h>
+#include <malloc.h>
+#include <driver.h>
+#include <init.h>
+#include <clock.h>
+
+#include <of.h>
+#include <of_mtd.h>
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/mtd/nand.h>
+
+#define NANDFCR_OFFSET		0x60
+#define NANDFSR_OFFSET		0x64
+#define NANDF1ECC_OFFSET	0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET	0xbc
+#define NAND_4BIT_ECC1_OFFSET		0xc0
+#define NAND_4BIT_ECC2_OFFSET		0xc4
+#define NAND_4BIT_ECC3_OFFSET		0xc8
+#define NAND_4BIT_ECC4_OFFSET		0xcc
+#define NAND_ERR_ADD1_OFFSET		0xd0
+#define NAND_ERR_ADD2_OFFSET		0xd4
+#define NAND_ERR_ERRVAL1_OFFSET		0xd8
+#define NAND_ERR_ERRVAL2_OFFSET		0xdc
+
+/* NOTE:  boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define	MASK_ALE		0x08
+#define	MASK_CLE		0x10
+
+struct davinci_nand_pdata {		/* platform_data */
+	uint32_t		chipsel;
+
+	uint32_t		mask_ale;
+	uint32_t		mask_cle;
+
+	/* for packages using two chipselects */
+	uint32_t		mask_chipsel;
+
+	/* board's default static partition info */
+	struct mtd_partition	*parts;
+	unsigned		nr_parts;
+
+	/* none  == NAND_ECC_NONE (strongly *not* advised!!)
+	 * soft  == NAND_ECC_SOFT
+	 * else  == NAND_ECC_HW, according to ecc_bits
+	 *
+	 * All DaVinci-family chips support 1-bit hardware ECC.
+	 * Newer ones also support 4-bit ECC, but are awkward
+	 * using it with large page chips.
+	 */
+	nand_ecc_modes_t	ecc_mode;
+	u8			ecc_bits;
+
+	/* e.g. NAND_BUSWIDTH_16 */
+	unsigned		options;
+	/* e.g. NAND_BBT_USE_FLASH */
+	unsigned		bbt_options;
+
+	/* Main and mirror bbt descriptor overrides */
+	struct nand_bbt_descr	*bbt_td;
+	struct nand_bbt_descr	*bbt_md;
+
+	/* Access timings */
+	//struct davinci_aemif_timing	*timing;
+};
+
+#define NRCSR_OFFSET            0x00                                             
+#define AWCCR_OFFSET            0x04                                             
+#define A1CR_OFFSET             0x10                                             
+                                                                                 
+#define ACR_ASIZE_MASK          0x3                                              
+#define ACR_EW_MASK             BIT(30)                                          
+#define ACR_SS_MASK             BIT(31)                                          
+
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips.  It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
+struct davinci_nand_info {
+	struct mtd_info		mtd;
+	struct nand_chip	chip;
+	struct nand_ecclayout	ecclayout;
+
+	struct device_d		*dev;
+	struct clk		*clk;
+
+	bool			is_readmode;
+
+	void __iomem		*base;
+	void __iomem		*vaddr;
+
+	uint32_t		ioaddr;
+	uint32_t		current_cs;
+
+	uint32_t		mask_chipsel;
+	uint32_t		mask_ale;
+	uint32_t		mask_cle;
+
+	uint32_t		core_chipsel;
+
+	//struct davinci_aemif_timing	*timing;
+};
+
+static bool ecc4_busy;
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
+
+
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+		int offset)
+{
+	return __raw_readl(info->base + offset);
+}
+
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+		int offset, unsigned long value)
+{
+	__raw_writel(value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Access to hardware control lines:  ALE, CLE, secondary chipselect.
+ */
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+				   unsigned int ctrl)
+{
+	struct davinci_nand_info	*info = to_davinci_nand(mtd);
+	uint32_t			addr = info->current_cs;
+	struct nand_chip		*nand = mtd->priv;
+
+	/* Did the control lines change? */
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
+			addr |= info->mask_cle;
+		else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
+			addr |= info->mask_ale;
+
+		nand->IO_ADDR_W = (void __iomem __force *)addr;
+	}
+
+	if (cmd != NAND_CMD_NONE)
+		iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct davinci_nand_info	*info = to_davinci_nand(mtd);
+	uint32_t			addr = info->ioaddr;
+
+	/* maybe kick in a second chipselect */
+	if (chip > 0)
+		addr |= info->mask_chipsel;
+	info->current_cs = addr;
+
+	info->chip.IO_ADDR_W = (void __iomem __force *)addr;
+	info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 1-bit hardware ECC ... context maintained for each core chipselect
+ */
+
+static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	dev_dbg(info->dev, "%s\n", __func__);
+
+	return davinci_nand_readl(info, NANDF1ECC_OFFSET
+			+ 4 * info->core_chipsel);
+}
+
+static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	uint32_t nandcfr;
+
+	dev_dbg(info->dev, "%s\n", __func__);
+
+	/* Reset ECC hardware */
+	nand_davinci_readecc_1bit(mtd);
+
+	/* Restart ECC hardware */
+	nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
+	nandcfr |= BIT(8 + info->core_chipsel);
+	davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
+				      const u_char *dat, u_char *ecc_code)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
+	unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
+	dev_dbg(info->dev, "%s\n", __func__);
+
+	/* invert so that erased block ecc is correct */
+	ecc24 = ~ecc24;
+	ecc_code[0] = (u_char)(ecc24);
+	ecc_code[1] = (u_char)(ecc24 >> 8);
+	ecc_code[2] = (u_char)(ecc24 >> 16);
+
+	return 0;
+}
+
+static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
+				     u_char *read_ecc, u_char *calc_ecc)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	struct nand_chip *chip = mtd->priv;
+	uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
+					  (read_ecc[2] << 16);
+	uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
+					  (calc_ecc[2] << 16);
+	uint32_t diff = eccCalc ^ eccNand;
+
+	dev_dbg(info->dev, "%s nand=0x%x calc=0x%x\n", __func__, eccNand, eccCalc);
+
+	if (diff) {
+		if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+			/* Correctable error */
+			if ((diff >> (12 + 3)) < chip->ecc.size) {
+				dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
+				return 1;
+			} else {
+				return -1;
+			}
+		} else if (!(diff & (diff - 1))) {
+			/* Single bit ECC error in the ECC itself,
+			 * nothing to fix */
+			return 1;
+		} else {
+			/* Uncorrectable error */
+			return -1;
+		}
+
+	}
+	return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 4-bit hardware ECC ... context maintained over entire AEMIF
+ *
+ * This is a syndrome engine, but we avoid NAND_ECC_HW_SYNDROME
+ * since that forces use of a problematic "infix OOB" layout.
+ * Among other things, it trashes manufacturer bad block markers.
+ * Also, and specific to this hardware, it ECC-protects the "prepad"
+ * in the OOB ... while having ECC protection for parts of OOB would
+ * seem useful, the current MTD stack sometimes wants to update the
+ * OOB without recomputing ECC.
+ */
+
+static void nand_davinci_hwctl_4bit(struct mtd_info *mtd, int mode)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	u32 val;
+
+	/* Start 4-bit ECC calculation for read/write */
+	val = davinci_nand_readl(info, NANDFCR_OFFSET);
+	val &= ~(0x03 << 4);
+	val |= (info->core_chipsel << 4) | BIT(12);
+	davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+	info->is_readmode = (mode == NAND_ECC_READ);
+}
+
+/* Read raw ECC code after writing to NAND. */
+static void
+nand_davinci_readecc_4bit(struct davinci_nand_info *info, u32 code[4])
+{
+	const u32 mask = 0x03ff03ff;
+
+	code[0] = davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET) & mask;
+	code[1] = davinci_nand_readl(info, NAND_4BIT_ECC2_OFFSET) & mask;
+	code[2] = davinci_nand_readl(info, NAND_4BIT_ECC3_OFFSET) & mask;
+	code[3] = davinci_nand_readl(info, NAND_4BIT_ECC4_OFFSET) & mask;
+}
+
+/* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
+static int nand_davinci_calculate_4bit(struct mtd_info *mtd,
+		const u_char *dat, u_char *ecc_code)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	u32 raw_ecc[4], *p;
+	unsigned i;
+
+	/* After a read, terminate ECC calculation by a dummy read
+	 * of some 4-bit ECC register.  ECC covers everything that
+	 * was read; correct() just uses the hardware state, so
+	 * ecc_code is not needed.
+	 */
+	if (info->is_readmode) {
+		davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
+		return 0;
+	}
+
+	/* Pack eight raw 10-bit ecc values into ten bytes, making
+	 * two passes which each convert four values (in upper and
+	 * lower halves of two 32-bit words) into five bytes.  The
+	 * ROM boot loader uses this same packing scheme.
+	 */
+	nand_davinci_readecc_4bit(info, raw_ecc);
+	for (i = 0, p = raw_ecc; i < 2; i++, p += 2) {
+		*ecc_code++ =   p[0]        & 0xff;
+		*ecc_code++ = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);
+		*ecc_code++ = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);
+		*ecc_code++ = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);
+		*ecc_code++ =  (p[1] >> 18) & 0xff;
+	}
+
+	return 0;
+}
+
+/* Correct up to 4 bits in data we just read, using state left in the
+ * hardware plus the ecc_code computed when it was first written.
+ */
+static int nand_davinci_correct_4bit(struct mtd_info *mtd,
+		u_char *data, u_char *ecc_code, u_char *null)
+{
+	int i;
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+	unsigned short ecc10[8];
+	unsigned short *ecc16;
+	u32 syndrome[4];
+	unsigned num_errors, corrected;
+
+	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
+	for (i = 0; i < 10; i++) {
+		if (ecc_code[i] != 0xff)
+			goto compare;
+	}
+	return 0;
+
+compare:
+	/* Unpack ten bytes into eight 10 bit values.  We know we're
+	 * little-endian, and use type punning for less shifting/masking.
+	 */
+	if (WARN_ON(0x01 & (unsigned) ecc_code))
+		return -EINVAL;
+	ecc16 = (unsigned short *)ecc_code;
+
+	ecc10[0] =  (ecc16[0] >>  0) & 0x3ff;
+	ecc10[1] = ((ecc16[0] >> 10) & 0x3f) | ((ecc16[1] << 6) & 0x3c0);
+	ecc10[2] =  (ecc16[1] >>  4) & 0x3ff;
+	ecc10[3] = ((ecc16[1] >> 14) & 0x3)  | ((ecc16[2] << 2) & 0x3fc);
+	ecc10[4] =  (ecc16[2] >>  8)         | ((ecc16[3] << 8) & 0x300);
+	ecc10[5] =  (ecc16[3] >>  2) & 0x3ff;
+	ecc10[6] = ((ecc16[3] >> 12) & 0xf)  | ((ecc16[4] << 4) & 0x3f0);
+	ecc10[7] =  (ecc16[4] >>  6) & 0x3ff;
+
+	/* Tell ECC controller about the expected ECC codes. */
+	for (i = 7; i >= 0; i--)
+		davinci_nand_writel(info, NAND_4BIT_ECC_LOAD_OFFSET, ecc10[i]);
+
+	/* Allow time for syndrome calculation ... then read it.
+	 * A syndrome of all zeroes 0 means no detected errors.
+	 */
+	davinci_nand_readl(info, NANDFSR_OFFSET);
+	nand_davinci_readecc_4bit(info, syndrome);
+	if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3]))
+		return 0;
+
+	/*
+	 * Clear any previous address calculation by doing a dummy read of an
+	 * error address register.
+	 */
+	davinci_nand_readl(info, NAND_ERR_ADD1_OFFSET);
+
+	/* Start address calculation, and wait for it to complete.
+	 * We _could_ start reading more data while this is working,
+	 * to speed up the overall page read.
+	 */
+	davinci_nand_writel(info, NANDFCR_OFFSET,
+			davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
+
+	/*
+	 * ECC_STATE field reads 0x3 (Error correction complete) immediately
+	 * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
+	 * begin trying to poll for the state, you may fall right out of your
+	 * loop without any of the correction calculations having taken place.
+	 * The recommendation from the hardware team is to initially delay as
+	 * long as ECC_STATE reads less than 4. After that, ECC HW has entered
+	 * correction state.
+	 */
+	wait_on_timeout(100 * USECOND,
+			((davinci_nand_readl(info, NANDFSR_OFFSET) >> 8) & 0x0f)
+			< 4);
+
+	for (;;) {
+		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
+
+		switch ((fsr >> 8) & 0x0f) {
+		case 0:		/* no error, should not happen */
+			davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
+			return 0;
+		case 1:		/* five or more errors detected */
+			davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
+			return -EIO;
+		case 2:		/* error addresses computed */
+		case 3:
+			num_errors = 1 + ((fsr >> 16) & 0x03);
+			goto correct;
+		default:	/* still working on it */
+			//cpu_relax();
+			continue;
+		}
+	}
+
+correct:
+	/* correct each error */
+	for (i = 0, corrected = 0; i < num_errors; i++) {
+		int error_address, error_value;
+
+		if (i > 1) {
+			error_address = davinci_nand_readl(info,
+						NAND_ERR_ADD2_OFFSET);
+			error_value = davinci_nand_readl(info,
+						NAND_ERR_ERRVAL2_OFFSET);
+		} else {
+			error_address = davinci_nand_readl(info,
+						NAND_ERR_ADD1_OFFSET);
+			error_value = davinci_nand_readl(info,
+						NAND_ERR_ERRVAL1_OFFSET);
+		}
+
+		if (i & 1) {
+			error_address >>= 16;
+			error_value >>= 16;
+		}
+		error_address &= 0x3ff;
+		error_address = (512 + 7) - error_address;
+
+		if (error_address < 512) {
+			data[error_address] ^= error_value;
+			corrected++;
+		}
+	}
+
+	return corrected;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE:  NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
+ * how these chips are normally wired.  This translates to both 8 and 16
+ * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+ *
+ * For now we assume that configuration, or any other one which ignores
+ * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
+ * and have that transparently morphed into multiple NAND operations.
+ */
+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	dev_dbg(info->dev, "%s\n", __func__);
+
+
+	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+		readsl(chip->IO_ADDR_R, buf, len >> 2);
+	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+		readsw(chip->IO_ADDR_R, buf, len >> 1);
+	else
+		readsb(chip->IO_ADDR_R, buf, len);
+}
+
+static void nand_davinci_write_buf(struct mtd_info *mtd,
+		const uint8_t *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	dev_dbg(info->dev, "%s\n", __func__);
+
+
+	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+		writesl(chip->IO_ADDR_R, buf, len >> 2);
+	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+		writesw(chip->IO_ADDR_R, buf, len >> 1);
+	else
+		writesb(chip->IO_ADDR_R, buf, len);
+}
+
+/*
+ * Check hardware register for wait status. Returns 1 if device is ready,
+ * 0 if it is still busy.
+ */
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+	struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+	return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* An ECC layout for using 4-bit ECC with small-page flash, storing
+ * ten ECC bytes plus the manufacturer's bad block marker byte, and
+ * and not overlapping the default BBT markers.
+ */
+static struct nand_ecclayout hwecc4_small = {
+	.eccbytes = 10,
+	.eccpos = { 0, 1, 2, 3, 4,
+		/* offset 5 holds the badblock marker */
+		6, 7,
+		13, 14, 15, },
+	.oobfree = {
+		{.offset = 8, .length = 5, },
+		{.offset = 16, },
+	},
+};
+
+/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash,
+ * storing ten ECC bytes plus the manufacturer's bad block marker byte,
+ * and not overlapping the default BBT markers.
+ */
+static struct nand_ecclayout hwecc4_2048 = {
+	.eccbytes = 40,
+	.eccpos = {
+		/* at the end of spare sector */
+		24, 25, 26, 27, 28, 29,	30, 31, 32, 33,
+		34, 35, 36, 37, 38, 39,	40, 41, 42, 43,
+		44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+		54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+		},
+	.oobfree = {
+		/* 2 bytes at offset 0 hold manufacturer badblock markers */
+		{.offset = 2, .length = 22, },
+		/* 5 bytes at offset 8 hold BBT markers */
+		/* 8 bytes at offset 16 hold JFFS2 clean markers */
+	},
+};
+
+static struct of_device_id davinci_nand_of_match[] = {
+	{.compatible = "ti,davinci-nand", },
+	{.compatible = "ti,keystone-nand", },
+	{},
+};
+
+static struct davinci_nand_pdata
+	*nand_davinci_get_pdata(struct device_d *dev)
+{
+	struct davinci_nand_pdata *pdata;
+	const char *mode;
+	u32 prop;
+
+	pdata = kzalloc(sizeof(struct davinci_nand_pdata),
+			GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+	if (!of_property_read_u32(dev->device_node,
+		"ti,davinci-chipselect", &prop))
+		pdata->chipsel = prop;
+	else
+		return ERR_PTR(-EINVAL);
+
+	if (!of_property_read_u32(dev->device_node,
+		"ti,davinci-mask-ale", &prop))
+		pdata->mask_ale = prop;
+	if (!of_property_read_u32(dev->device_node,
+		"ti,davinci-mask-cle", &prop))
+		pdata->mask_cle = prop;
+	if (!of_property_read_u32(dev->device_node,
+		"ti,davinci-mask-chipsel", &prop))
+		pdata->mask_chipsel = prop;
+	if (!of_property_read_string(dev->device_node,
+		"nand-ecc-mode", &mode) ||
+	    !of_property_read_string(dev->device_node,
+		"ti,davinci-ecc-mode", &mode)) {
+		if (!strncmp("none", mode, 4))
+			pdata->ecc_mode = NAND_ECC_NONE;
+		if (!strncmp("soft", mode, 4))
+			pdata->ecc_mode = NAND_ECC_SOFT;
+		if (!strncmp("hw", mode, 2))
+			pdata->ecc_mode = NAND_ECC_HW;
+	}
+	if (!of_property_read_u32(dev->device_node,
+		"ti,davinci-ecc-bits", &prop))
+		pdata->ecc_bits = prop;
+
+	prop = of_get_nand_bus_width(dev->device_node);
+	if (0 < prop || !of_property_read_u32(dev->device_node,
+		"ti,davinci-nand-buswidth", &prop))
+		if (prop == 16)
+			pdata->options |= NAND_BUSWIDTH_16;
+	if (of_property_read_bool(dev->device_node,
+		"nand-on-flash-bbt") ||
+	    of_property_read_bool(dev->device_node,
+		"ti,davinci-nand-use-bbt"))
+		pdata->bbt_options = NAND_BBT_USE_FLASH;
+
+	if (of_device_is_compatible(dev->device_node,
+				    "ti,keystone-nand")) {
+		pdata->options |= NAND_NO_SUBPAGE_WRITE;
+	}
+	return pdata;
+}
+
+static int nand_davinci_probe(struct device_d *dev)
+{
+	struct davinci_nand_pdata	*pdata;
+	struct davinci_nand_info	*info;
+	int				ret;
+	uint32_t			val;
+	nand_ecc_modes_t		ecc_mode;
+
+	pdata = nand_davinci_get_pdata(dev);
+
+	/* insist on board-specific configuration */
+	if (!pdata)
+		return -ENODEV;
+
+	/* which external chipselect will we be managing? */
+	if (pdata->chipsel < 0 || pdata->chipsel > 3)
+		return -ENODEV;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	//platform_set_drvdata(pdev, info);
+
+	info->dev		= dev;
+	info->base		= dev_request_mem_region(dev, 1);
+	info->vaddr		= dev_request_mem_region(dev, 0);
+
+	val = davinci_nand_readl(info, NRCSR_OFFSET);
+	dev_info(dev, "controller rev. %d.%d\n",
+	       (val >> 8) & 0xff, val & 0xff);
+
+	info->mtd.priv		= &info->chip;
+	info->mtd.name		= dev_name(dev);
+	info->mtd.parent	= dev;
+
+	info->chip.IO_ADDR_R	= info->vaddr;
+	info->chip.IO_ADDR_W	= info->vaddr;
+	info->chip.chip_delay	= 0;
+	info->chip.select_chip	= nand_davinci_select_chip;
+
+	/* options such as NAND_BBT_USE_FLASH */
+	info->chip.bbt_options	= pdata->bbt_options;
+	/* options such as 16-bit widths */
+	info->chip.options	= pdata->options;
+	info->chip.bbt_td	= pdata->bbt_td;
+	info->chip.bbt_md	= pdata->bbt_md;
+	//info->timing		= pdata->timing;
+
+	info->ioaddr		= (uint32_t __force) info->vaddr;
+
+	info->current_cs	= info->ioaddr;
+	info->core_chipsel	= pdata->chipsel;
+	info->mask_chipsel	= pdata->mask_chipsel;
+
+	/* use nandboot-capable ALE/CLE masks by default */
+	info->mask_ale		= pdata->mask_ale ? : MASK_ALE;
+	info->mask_cle		= pdata->mask_cle ? : MASK_CLE;
+
+	/* Set address of hardware control function */
+	info->chip.cmd_ctrl	= nand_davinci_hwcontrol;
+	info->chip.dev_ready	= nand_davinci_dev_ready;
+
+	/* Speed up buffer I/O */
+	info->chip.read_buf     = nand_davinci_read_buf;
+	info->chip.write_buf    = nand_davinci_write_buf;
+
+	/* Use board-specific ECC config */
+	ecc_mode		= pdata->ecc_mode;
+
+	ret = -EINVAL;
+	switch (ecc_mode) {
+	case NAND_ECC_NONE:
+	case NAND_ECC_SOFT:
+		pdata->ecc_bits = 0;
+		break;
+	case NAND_ECC_HW:
+		if (pdata->ecc_bits == 4) {
+			/* No sanity checks:  CPUs must support this,
+			 * and the chips may not use NAND_BUSWIDTH_16.
+			 */
+
+			/* No sharing 4-bit hardware between chipselects yet */
+			if (ecc4_busy)
+				ret = -EBUSY;
+			else
+				ecc4_busy = true;
+
+			if (ret == -EBUSY)
+				return ret;
+
+			info->chip.ecc.calculate = nand_davinci_calculate_4bit;
+			info->chip.ecc.correct = nand_davinci_correct_4bit;
+			info->chip.ecc.hwctl = nand_davinci_hwctl_4bit;
+			info->chip.ecc.bytes = 10;
+		} else {
+			info->chip.ecc.calculate = nand_davinci_calculate_1bit;
+			info->chip.ecc.correct = nand_davinci_correct_1bit;
+			info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
+			info->chip.ecc.bytes = 3;
+		}
+		info->chip.ecc.size = 512;
+		info->chip.ecc.strength = pdata->ecc_bits;
+		break;
+	default:
+		return -EINVAL;
+	}
+	info->chip.ecc.mode = ecc_mode;
+
+	info->clk = clk_get(dev, "aemif");
+	if (IS_ERR(info->clk)) {
+		ret = PTR_ERR(info->clk);
+		dev_dbg(dev, "unable to get AEMIF clock, err %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_enable(info->clk);
+	if (ret < 0) {
+		dev_dbg(dev, "unable to enable AEMIF clock, err %d\n",
+			ret);
+		goto err_clk_enable;
+	}
+
+	/* put CSxNAND into NAND mode */
+	val = davinci_nand_readl(info, NANDFCR_OFFSET);
+	val |= BIT(info->core_chipsel);
+	davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+	/* Scan to find existence of the device(s) */
+	ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL);
+	if (ret < 0) {
+		dev_dbg(dev, "no NAND chip(s) found\n");
+		goto err;
+	}
+
+	/* Update ECC layout if needed ... for 1-bit HW ECC, the default
+	 * is OK, but it allocates 6 bytes when only 3 are needed (for
+	 * each 512 bytes).  For the 4-bit HW ECC, that default is not
+	 * usable:  10 bytes are needed, not 6.
+	 */
+	if (pdata->ecc_bits == 4) {
+		int	chunks = info->mtd.writesize / 512;
+
+		if (!chunks || info->mtd.oobsize < 16) {
+			dev_dbg(dev, "too small\n");
+			ret = -EINVAL;
+			goto err;
+		}
+
+		/* For small page chips, preserve the manufacturer's
+		 * badblock marking data ... and make sure a flash BBT
+		 * table marker fits in the free bytes.
+		 */
+		if (chunks == 1) {
+			info->ecclayout = hwecc4_small;
+			info->ecclayout.oobfree[1].length =
+				info->mtd.oobsize - 16;
+			goto syndrome_done;
+		}
+		if (chunks == 4) {
+			info->ecclayout = hwecc4_2048;
+			info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
+			goto syndrome_done;
+		}
+
+		/* 4KiB page chips are not yet supported. The eccpos from
+		 * nand_ecclayout cannot hold 80 bytes and change to eccpos[]
+		 * breaks userspace ioctl interface with mtd-utils. Once we
+		 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
+		 * for the 4KiB page chips.
+		 *
+		 * TODO: Note that nand_ecclayout has now been expanded and can
+		 *  hold plenty of OOB entries.
+		 */
+		dev_warn(dev, "no 4-bit ECC support yet "
+				"for 4KiB-page NAND\n");
+		ret = -EIO;
+		goto err;
+
+syndrome_done:
+		info->chip.ecc.layout = &info->ecclayout;
+	}
+
+	ret = nand_scan_tail(&info->mtd);
+	if (ret < 0)
+		goto err;
+
+	add_mtd_nand_device(&info->mtd, "nand");
+
+	return 0;
+
+err:
+	clk_disable(info->clk);
+
+err_clk_enable:
+	if (ecc_mode == NAND_ECC_HW_SYNDROME)
+		ecc4_busy = false;
+	return ret;
+}
+
+static struct driver_d nand_davinci_driver = {
+	.name	= "davinci_nand",
+	.probe	= nand_davinci_probe,
+	.of_compatible = DRV_OF_COMPAT(davinci_nand_of_match),
+};
+device_platform_driver(nand_davinci_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("Davinci NAND flash driver");
+
-- 
2.1.4



From jluebbe at debian.org  Sat May 30 06:11:43 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 15:11:43 +0200
Subject: state support updates
Message-ID: <1432991505-21204-1-git-send-email-jluebbe@debian.org>

Hi,

these patches apply to for-next/state. The first improves the error reporting
and the second makes it easier to use the state framework with small EEPROMs.

Regards,
Jan



From jluebbe at debian.org  Sat May 30 06:11:45 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 15:11:45 +0200
Subject: [PATCH 2/2] state: add support for uint8 variables
In-Reply-To: <1432991505-21204-1-git-send-email-jluebbe@debian.org>
References: <1432991505-21204-1-git-send-email-jluebbe@debian.org>
Message-ID: <1432991505-21204-3-git-send-email-jluebbe@debian.org>

Signed-off-by: Jan Luebbe <jluebbe at debian.org>
---
 common/state.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/common/state.c b/common/state.c
index 0be0efe..7076f57 100644
--- a/common/state.c
+++ b/common/state.c
@@ -61,6 +61,7 @@ struct state_backend {
 enum state_variable_type {
 	STATE_TYPE_INVALID = 0,
 	STATE_TYPE_ENUM,
+	STATE_TYPE_U8,
 	STATE_TYPE_U32,
 	STATE_TYPE_MAC,
 };
@@ -162,6 +163,32 @@ static int state_uint32_import(struct state_variable *sv,
 	return 0;
 }
 
+static struct state_variable *state_uint8_create(struct state *state,
+		const char *name, struct device_node *node)
+{
+	struct state_uint32 *su32;
+	struct param_d *param;
+
+	su32 = xzalloc(sizeof(*su32));
+
+	param = dev_add_param_int(&state->dev, name, state_set_dirty,
+				  NULL, &su32->value, "%d", state);
+	if (IS_ERR(param)) {
+		free(su32);
+		return ERR_CAST(param);
+	}
+
+	su32->param = param;
+	su32->var.size = sizeof(uint8_t);
+#ifdef __LITTLE_ENDIAN
+	su32->var.raw = &su32->value;
+#else
+	su32->var.raw = &su32->value + 3;
+#endif
+
+	return &su32->var;
+}
+
 static struct state_variable *state_uint32_create(struct state *state,
 		const char *name, struct device_node *node)
 {
@@ -372,6 +399,12 @@ out:
 
 static struct variable_type types[] =  {
 	{
+		.type = STATE_TYPE_U8,
+		.type_name = "uint8",
+		.export = state_uint32_export,
+		.import = state_uint32_import,
+		.create = state_uint8_create,
+	}, {
 		.type = STATE_TYPE_U32,
 		.type_name = "uint32",
 		.export = state_uint32_export,
-- 
2.1.4



From jluebbe at debian.org  Sat May 30 06:11:44 2015
From: jluebbe at debian.org (Jan Luebbe)
Date: Sat, 30 May 2015 15:11:44 +0200
Subject: [PATCH 1/2] state: add some more error messages
In-Reply-To: <1432991505-21204-1-git-send-email-jluebbe@debian.org>
References: <1432991505-21204-1-git-send-email-jluebbe@debian.org>
Message-ID: <1432991505-21204-2-git-send-email-jluebbe@debian.org>

This helps with finding out why the state cannot be loaded correctly.

Signed-off-by: Jan Luebbe <jluebbe at debian.org>
---
 common/state.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/common/state.c b/common/state.c
index d243de8..0be0efe 100644
--- a/common/state.c
+++ b/common/state.c
@@ -848,10 +848,13 @@ int state_load(struct state *state)
 		return -ENOSYS;
 
 	ret = state->backend->load(state->backend, state);
-	if (ret)
+	if (ret) {
+		dev_warn(&state->dev, "load failed\n");
 		state->dirty = 1;
-	else
+	} else {
+		dev_info(&state->dev, "load successful\n");
 		state->dirty = 0;
+	}
 
 	return ret;
 }
@@ -1065,8 +1068,11 @@ static int backend_raw_load_one(struct state_backend_raw *backend_raw,
 
 	ret = read_full(fd, &header, sizeof(header));
 	max_len -= sizeof(header);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_err(&state->dev,
+			"cannot read header from backend device");
 		return ret;
+	}
 
 	crc = crc32(0, &header, sizeof(header) - sizeof(uint32_t));
 	if (crc != header.header_crc) {
@@ -1127,8 +1133,10 @@ static int state_backend_raw_load(struct state_backend *backend,
 	int ret = 0, fd, i;
 
 	fd = open(backend->path, O_RDONLY);
-	if (fd < 0)
+	if (fd < 0) {
+		dev_err(&state->dev, "cannot open %s\n", backend->path);
 		return fd;
+	}
 
 	for (i = 0; i < RAW_BACKEND_COPIES; i++) {
 		off_t offset = backend_raw->offset + i * backend_raw->stride;
@@ -1352,7 +1360,8 @@ int state_backend_raw_file(struct state *state, const char *of_path,
 	}
 
 	if (backend_raw->size / backend_raw->stride < RAW_BACKEND_COPIES) {
-		dev_err(&state->dev, "not enough space for two copies\n");
+		dev_err(&state->dev, "not enough space for two copies (%lu each)\n",
+			backend_raw->stride);
 		ret = -ENOSPC;
 		goto err;
 	}
-- 
2.1.4



From antonynpavlov at gmail.com  Sun May 31 06:58:01 2015
From: antonynpavlov at gmail.com (Antony Pavlov)
Date: Sun, 31 May 2015 16:58:01 +0300
Subject: [PATCH] davinci_nand: add support for the NAND controller
In-Reply-To: <1432991051-20800-1-git-send-email-jluebbe@debian.org>
References: <1432991051-20800-1-git-send-email-jluebbe@debian.org>
Message-ID: <20150531165801.1239a325f2bcba1c1bafc874@gmail.com>

On Sat, 30 May 2015 15:04:11 +0200
Jan Luebbe <jluebbe at debian.org> wrote:

> This driver is based on the Linux driver (v4.0).

checkpatch.pl output:

  total: 15 errors, 9 warnings, 884 lines checked

  NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or
        scripts/cleanfile

Please fix the patch!

> Signed-off-by: Jan Luebbe <jluebbe at debian.org>
> ---
>  drivers/mtd/nand/Kconfig        |   7 +
>  drivers/mtd/nand/Makefile       |   1 +
>  drivers/mtd/nand/davinci_nand.c | 866 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 874 insertions(+)
>  create mode 100644 drivers/mtd/nand/davinci_nand.c
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index a75540b..41a3e31 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -140,4 +140,11 @@ config MTD_NAND_NOMADIK
>  	help
>  	  Driver for the NAND flash controller on the Nomadik, with ECC.
>  
> +config MTD_NAND_DAVINCI
> +	tristate "Support NAND on DaVinci"
> +	depends on ARCH_DAVINCI
> +	help
> +	  Enable the driver for NAND flash chips on Texas Instruments
> +	  DaVinci processors.
> +
>  endif
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index a0b3198..b8644b2 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -7,6 +7,7 @@ obj-$(CONFIG_NAND)			+= nand_base.o nand-bb.o
>  obj-$(CONFIG_NAND_BBT)			+= nand_bbt.o
>  
>  obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
> +obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
>  obj-$(CONFIG_NAND_IMX)			+= nand_imx.o
>  obj-$(CONFIG_NAND_IMX_BBM)		+= nand_imx_bbm.o
>  obj-$(CONFIG_NAND_OMAP_GPMC)		+= nand_omap_gpmc.o nand_omap_bch_decoder.o
> diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
> new file mode 100644
> index 0000000..4b14b6c
> --- /dev/null
> +++ b/drivers/mtd/nand/davinci_nand.c
> @@ -0,0 +1,866 @@
> +/*
> + * davinci_nand.c - NAND Flash Driver for DaVinci family chips
> + *
> + * Copyright ? 2006 Texas Instruments.
> + *
> + * Port to 2.6.23 Copyright ? 2008 by:
> + *   Sander Huijsen <Shuijsen at optelecom-nkf.com>
> + *   Troy Kisky <troy.kisky at boundarydevices.com>
> + *   Dirk Behme <Dirk.Behme at gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +//#define DEBUG
> +
> +#include <common.h>
> +#include <io.h>
> +#include <malloc.h>
> +#include <driver.h>
> +#include <init.h>
> +#include <clock.h>
> +
> +#include <of.h>
> +#include <of_mtd.h>
> +
> +#include <linux/kernel.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/mtd/nand.h>
> +
> +#define NANDFCR_OFFSET		0x60
> +#define NANDFSR_OFFSET		0x64
> +#define NANDF1ECC_OFFSET	0x70
> +
> +/* 4-bit ECC syndrome registers */
> +#define NAND_4BIT_ECC_LOAD_OFFSET	0xbc
> +#define NAND_4BIT_ECC1_OFFSET		0xc0
> +#define NAND_4BIT_ECC2_OFFSET		0xc4
> +#define NAND_4BIT_ECC3_OFFSET		0xc8
> +#define NAND_4BIT_ECC4_OFFSET		0xcc
> +#define NAND_ERR_ADD1_OFFSET		0xd0
> +#define NAND_ERR_ADD2_OFFSET		0xd4
> +#define NAND_ERR_ERRVAL1_OFFSET		0xd8
> +#define NAND_ERR_ERRVAL2_OFFSET		0xdc
> +
> +/* NOTE:  boards don't need to use these address bits
> + * for ALE/CLE unless they support booting from NAND.
> + * They're used unless platform data overrides them.
> + */
> +#define	MASK_ALE		0x08
> +#define	MASK_CLE		0x10
> +
> +struct davinci_nand_pdata {		/* platform_data */
> +	uint32_t		chipsel;
> +
> +	uint32_t		mask_ale;
> +	uint32_t		mask_cle;
> +
> +	/* for packages using two chipselects */
> +	uint32_t		mask_chipsel;
> +
> +	/* board's default static partition info */
> +	struct mtd_partition	*parts;
> +	unsigned		nr_parts;
> +
> +	/* none  == NAND_ECC_NONE (strongly *not* advised!!)
> +	 * soft  == NAND_ECC_SOFT
> +	 * else  == NAND_ECC_HW, according to ecc_bits
> +	 *
> +	 * All DaVinci-family chips support 1-bit hardware ECC.
> +	 * Newer ones also support 4-bit ECC, but are awkward
> +	 * using it with large page chips.
> +	 */
> +	nand_ecc_modes_t	ecc_mode;
> +	u8			ecc_bits;
> +
> +	/* e.g. NAND_BUSWIDTH_16 */
> +	unsigned		options;
> +	/* e.g. NAND_BBT_USE_FLASH */
> +	unsigned		bbt_options;
> +
> +	/* Main and mirror bbt descriptor overrides */
> +	struct nand_bbt_descr	*bbt_td;
> +	struct nand_bbt_descr	*bbt_md;
> +
> +	/* Access timings */
> +	//struct davinci_aemif_timing	*timing;
> +};
> +
> +#define NRCSR_OFFSET            0x00                                             
> +#define AWCCR_OFFSET            0x04                                             
> +#define A1CR_OFFSET             0x10                                             
> +                                                                                 
> +#define ACR_ASIZE_MASK          0x3                                              
> +#define ACR_EW_MASK             BIT(30)                                          
> +#define ACR_SS_MASK             BIT(31)                                          
> +
> +/*
> + * This is a device driver for the NAND flash controller found on the
> + * various DaVinci family chips.  It handles up to four SoC chipselects,
> + * and some flavors of secondary chipselect (e.g. based on A12) as used
> + * with multichip packages.
> + *
> + * The 1-bit ECC hardware is supported, as well as the newer 4-bit ECC
> + * available on chips like the DM355 and OMAP-L137 and needed with the
> + * more error-prone MLC NAND chips.
> + *
> + * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
> + * outputs in a "wire-AND" configuration, with no per-chip signals.
> + */
> +struct davinci_nand_info {
> +	struct mtd_info		mtd;
> +	struct nand_chip	chip;
> +	struct nand_ecclayout	ecclayout;
> +
> +	struct device_d		*dev;
> +	struct clk		*clk;
> +
> +	bool			is_readmode;
> +
> +	void __iomem		*base;
> +	void __iomem		*vaddr;
> +
> +	uint32_t		ioaddr;
> +	uint32_t		current_cs;
> +
> +	uint32_t		mask_chipsel;
> +	uint32_t		mask_ale;
> +	uint32_t		mask_cle;
> +
> +	uint32_t		core_chipsel;
> +
> +	//struct davinci_aemif_timing	*timing;
> +};
> +
> +static bool ecc4_busy;
> +
> +#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
> +
> +
> +static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
> +		int offset)
> +{
> +	return __raw_readl(info->base + offset);
> +}
> +
> +static inline void davinci_nand_writel(struct davinci_nand_info *info,
> +		int offset, unsigned long value)
> +{
> +	__raw_writel(value, info->base + offset);
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +/*
> + * Access to hardware control lines:  ALE, CLE, secondary chipselect.
> + */
> +
> +static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
> +				   unsigned int ctrl)
> +{
> +	struct davinci_nand_info	*info = to_davinci_nand(mtd);
> +	uint32_t			addr = info->current_cs;
> +	struct nand_chip		*nand = mtd->priv;
> +
> +	/* Did the control lines change? */
> +	if (ctrl & NAND_CTRL_CHANGE) {
> +		if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
> +			addr |= info->mask_cle;
> +		else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
> +			addr |= info->mask_ale;
> +
> +		nand->IO_ADDR_W = (void __iomem __force *)addr;
> +	}
> +
> +	if (cmd != NAND_CMD_NONE)
> +		iowrite8(cmd, nand->IO_ADDR_W);
> +}
> +
> +static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
> +{
> +	struct davinci_nand_info	*info = to_davinci_nand(mtd);
> +	uint32_t			addr = info->ioaddr;
> +
> +	/* maybe kick in a second chipselect */
> +	if (chip > 0)
> +		addr |= info->mask_chipsel;
> +	info->current_cs = addr;
> +
> +	info->chip.IO_ADDR_W = (void __iomem __force *)addr;
> +	info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +/*
> + * 1-bit hardware ECC ... context maintained for each core chipselect
> + */
> +
> +static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +
> +	dev_dbg(info->dev, "%s\n", __func__);
> +
> +	return davinci_nand_readl(info, NANDF1ECC_OFFSET
> +			+ 4 * info->core_chipsel);
> +}
> +
> +static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	uint32_t nandcfr;
> +
> +	dev_dbg(info->dev, "%s\n", __func__);
> +
> +	/* Reset ECC hardware */
> +	nand_davinci_readecc_1bit(mtd);
> +
> +	/* Restart ECC hardware */
> +	nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
> +	nandcfr |= BIT(8 + info->core_chipsel);
> +	davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
> +}
> +
> +/*
> + * Read hardware ECC value and pack into three bytes
> + */
> +static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
> +				      const u_char *dat, u_char *ecc_code)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
> +	unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
> +
> +	dev_dbg(info->dev, "%s\n", __func__);
> +
> +	/* invert so that erased block ecc is correct */
> +	ecc24 = ~ecc24;
> +	ecc_code[0] = (u_char)(ecc24);
> +	ecc_code[1] = (u_char)(ecc24 >> 8);
> +	ecc_code[2] = (u_char)(ecc24 >> 16);
> +
> +	return 0;
> +}
> +
> +static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
> +				     u_char *read_ecc, u_char *calc_ecc)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	struct nand_chip *chip = mtd->priv;
> +	uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
> +					  (read_ecc[2] << 16);
> +	uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
> +					  (calc_ecc[2] << 16);
> +	uint32_t diff = eccCalc ^ eccNand;
> +
> +	dev_dbg(info->dev, "%s nand=0x%x calc=0x%x\n", __func__, eccNand, eccCalc);
> +
> +	if (diff) {
> +		if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
> +			/* Correctable error */
> +			if ((diff >> (12 + 3)) < chip->ecc.size) {
> +				dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
> +				return 1;
> +			} else {
> +				return -1;
> +			}
> +		} else if (!(diff & (diff - 1))) {
> +			/* Single bit ECC error in the ECC itself,
> +			 * nothing to fix */
> +			return 1;
> +		} else {
> +			/* Uncorrectable error */
> +			return -1;
> +		}
> +
> +	}
> +	return 0;
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +/*
> + * 4-bit hardware ECC ... context maintained over entire AEMIF
> + *
> + * This is a syndrome engine, but we avoid NAND_ECC_HW_SYNDROME
> + * since that forces use of a problematic "infix OOB" layout.
> + * Among other things, it trashes manufacturer bad block markers.
> + * Also, and specific to this hardware, it ECC-protects the "prepad"
> + * in the OOB ... while having ECC protection for parts of OOB would
> + * seem useful, the current MTD stack sometimes wants to update the
> + * OOB without recomputing ECC.
> + */
> +
> +static void nand_davinci_hwctl_4bit(struct mtd_info *mtd, int mode)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	u32 val;
> +
> +	/* Start 4-bit ECC calculation for read/write */
> +	val = davinci_nand_readl(info, NANDFCR_OFFSET);
> +	val &= ~(0x03 << 4);
> +	val |= (info->core_chipsel << 4) | BIT(12);
> +	davinci_nand_writel(info, NANDFCR_OFFSET, val);
> +
> +	info->is_readmode = (mode == NAND_ECC_READ);
> +}
> +
> +/* Read raw ECC code after writing to NAND. */
> +static void
> +nand_davinci_readecc_4bit(struct davinci_nand_info *info, u32 code[4])
> +{
> +	const u32 mask = 0x03ff03ff;
> +
> +	code[0] = davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET) & mask;
> +	code[1] = davinci_nand_readl(info, NAND_4BIT_ECC2_OFFSET) & mask;
> +	code[2] = davinci_nand_readl(info, NAND_4BIT_ECC3_OFFSET) & mask;
> +	code[3] = davinci_nand_readl(info, NAND_4BIT_ECC4_OFFSET) & mask;
> +}
> +
> +/* Terminate read ECC; or return ECC (as bytes) of data written to NAND. */
> +static int nand_davinci_calculate_4bit(struct mtd_info *mtd,
> +		const u_char *dat, u_char *ecc_code)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	u32 raw_ecc[4], *p;
> +	unsigned i;
> +
> +	/* After a read, terminate ECC calculation by a dummy read
> +	 * of some 4-bit ECC register.  ECC covers everything that
> +	 * was read; correct() just uses the hardware state, so
> +	 * ecc_code is not needed.
> +	 */
> +	if (info->is_readmode) {
> +		davinci_nand_readl(info, NAND_4BIT_ECC1_OFFSET);
> +		return 0;
> +	}
> +
> +	/* Pack eight raw 10-bit ecc values into ten bytes, making
> +	 * two passes which each convert four values (in upper and
> +	 * lower halves of two 32-bit words) into five bytes.  The
> +	 * ROM boot loader uses this same packing scheme.
> +	 */
> +	nand_davinci_readecc_4bit(info, raw_ecc);
> +	for (i = 0, p = raw_ecc; i < 2; i++, p += 2) {
> +		*ecc_code++ =   p[0]        & 0xff;
> +		*ecc_code++ = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);
> +		*ecc_code++ = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);
> +		*ecc_code++ = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);
> +		*ecc_code++ =  (p[1] >> 18) & 0xff;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Correct up to 4 bits in data we just read, using state left in the
> + * hardware plus the ecc_code computed when it was first written.
> + */
> +static int nand_davinci_correct_4bit(struct mtd_info *mtd,
> +		u_char *data, u_char *ecc_code, u_char *null)
> +{
> +	int i;
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +	unsigned short ecc10[8];
> +	unsigned short *ecc16;
> +	u32 syndrome[4];
> +	unsigned num_errors, corrected;
> +
> +	/* All bytes 0xff?  It's an erased page; ignore its ECC. */
> +	for (i = 0; i < 10; i++) {
> +		if (ecc_code[i] != 0xff)
> +			goto compare;
> +	}
> +	return 0;
> +
> +compare:
> +	/* Unpack ten bytes into eight 10 bit values.  We know we're
> +	 * little-endian, and use type punning for less shifting/masking.
> +	 */
> +	if (WARN_ON(0x01 & (unsigned) ecc_code))
> +		return -EINVAL;
> +	ecc16 = (unsigned short *)ecc_code;
> +
> +	ecc10[0] =  (ecc16[0] >>  0) & 0x3ff;
> +	ecc10[1] = ((ecc16[0] >> 10) & 0x3f) | ((ecc16[1] << 6) & 0x3c0);
> +	ecc10[2] =  (ecc16[1] >>  4) & 0x3ff;
> +	ecc10[3] = ((ecc16[1] >> 14) & 0x3)  | ((ecc16[2] << 2) & 0x3fc);
> +	ecc10[4] =  (ecc16[2] >>  8)         | ((ecc16[3] << 8) & 0x300);
> +	ecc10[5] =  (ecc16[3] >>  2) & 0x3ff;
> +	ecc10[6] = ((ecc16[3] >> 12) & 0xf)  | ((ecc16[4] << 4) & 0x3f0);
> +	ecc10[7] =  (ecc16[4] >>  6) & 0x3ff;
> +
> +	/* Tell ECC controller about the expected ECC codes. */
> +	for (i = 7; i >= 0; i--)
> +		davinci_nand_writel(info, NAND_4BIT_ECC_LOAD_OFFSET, ecc10[i]);
> +
> +	/* Allow time for syndrome calculation ... then read it.
> +	 * A syndrome of all zeroes 0 means no detected errors.
> +	 */
> +	davinci_nand_readl(info, NANDFSR_OFFSET);
> +	nand_davinci_readecc_4bit(info, syndrome);
> +	if (!(syndrome[0] | syndrome[1] | syndrome[2] | syndrome[3]))
> +		return 0;
> +
> +	/*
> +	 * Clear any previous address calculation by doing a dummy read of an
> +	 * error address register.
> +	 */
> +	davinci_nand_readl(info, NAND_ERR_ADD1_OFFSET);
> +
> +	/* Start address calculation, and wait for it to complete.
> +	 * We _could_ start reading more data while this is working,
> +	 * to speed up the overall page read.
> +	 */
> +	davinci_nand_writel(info, NANDFCR_OFFSET,
> +			davinci_nand_readl(info, NANDFCR_OFFSET) | BIT(13));
> +
> +	/*
> +	 * ECC_STATE field reads 0x3 (Error correction complete) immediately
> +	 * after setting the 4BITECC_ADD_CALC_START bit. So if you immediately
> +	 * begin trying to poll for the state, you may fall right out of your
> +	 * loop without any of the correction calculations having taken place.
> +	 * The recommendation from the hardware team is to initially delay as
> +	 * long as ECC_STATE reads less than 4. After that, ECC HW has entered
> +	 * correction state.
> +	 */
> +	wait_on_timeout(100 * USECOND,
> +			((davinci_nand_readl(info, NANDFSR_OFFSET) >> 8) & 0x0f)
> +			< 4);
> +
> +	for (;;) {
> +		u32	fsr = davinci_nand_readl(info, NANDFSR_OFFSET);
> +
> +		switch ((fsr >> 8) & 0x0f) {
> +		case 0:		/* no error, should not happen */
> +			davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
> +			return 0;
> +		case 1:		/* five or more errors detected */
> +			davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET);
> +			return -EIO;
> +		case 2:		/* error addresses computed */
> +		case 3:
> +			num_errors = 1 + ((fsr >> 16) & 0x03);
> +			goto correct;
> +		default:	/* still working on it */
> +			//cpu_relax();
> +			continue;
> +		}
> +	}
> +
> +correct:
> +	/* correct each error */
> +	for (i = 0, corrected = 0; i < num_errors; i++) {
> +		int error_address, error_value;
> +
> +		if (i > 1) {
> +			error_address = davinci_nand_readl(info,
> +						NAND_ERR_ADD2_OFFSET);
> +			error_value = davinci_nand_readl(info,
> +						NAND_ERR_ERRVAL2_OFFSET);
> +		} else {
> +			error_address = davinci_nand_readl(info,
> +						NAND_ERR_ADD1_OFFSET);
> +			error_value = davinci_nand_readl(info,
> +						NAND_ERR_ERRVAL1_OFFSET);
> +		}
> +
> +		if (i & 1) {
> +			error_address >>= 16;
> +			error_value >>= 16;
> +		}
> +		error_address &= 0x3ff;
> +		error_address = (512 + 7) - error_address;
> +
> +		if (error_address < 512) {
> +			data[error_address] ^= error_value;
> +			corrected++;
> +		}
> +	}
> +
> +	return corrected;
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +/*
> + * NOTE:  NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
> + * how these chips are normally wired.  This translates to both 8 and 16
> + * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
> + *
> + * For now we assume that configuration, or any other one which ignores
> + * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
> + * and have that transparently morphed into multiple NAND operations.
> + */
> +static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd->priv;
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +
> +	dev_dbg(info->dev, "%s\n", __func__);
> +
> +
> +	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
> +		readsl(chip->IO_ADDR_R, buf, len >> 2);
> +	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
> +		readsw(chip->IO_ADDR_R, buf, len >> 1);
> +	else
> +		readsb(chip->IO_ADDR_R, buf, len);
> +}
> +
> +static void nand_davinci_write_buf(struct mtd_info *mtd,
> +		const uint8_t *buf, int len)
> +{
> +	struct nand_chip *chip = mtd->priv;
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +
> +	dev_dbg(info->dev, "%s\n", __func__);
> +
> +
> +	if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
> +		writesl(chip->IO_ADDR_R, buf, len >> 2);
> +	else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
> +		writesw(chip->IO_ADDR_R, buf, len >> 1);
> +	else
> +		writesb(chip->IO_ADDR_R, buf, len);
> +}
> +
> +/*
> + * Check hardware register for wait status. Returns 1 if device is ready,
> + * 0 if it is still busy.
> + */
> +static int nand_davinci_dev_ready(struct mtd_info *mtd)
> +{
> +	struct davinci_nand_info *info = to_davinci_nand(mtd);
> +
> +	return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +/* An ECC layout for using 4-bit ECC with small-page flash, storing
> + * ten ECC bytes plus the manufacturer's bad block marker byte, and
> + * and not overlapping the default BBT markers.
> + */
> +static struct nand_ecclayout hwecc4_small = {
> +	.eccbytes = 10,
> +	.eccpos = { 0, 1, 2, 3, 4,
> +		/* offset 5 holds the badblock marker */
> +		6, 7,
> +		13, 14, 15, },
> +	.oobfree = {
> +		{.offset = 8, .length = 5, },
> +		{.offset = 16, },
> +	},
> +};
> +
> +/* An ECC layout for using 4-bit ECC with large-page (2048bytes) flash,
> + * storing ten ECC bytes plus the manufacturer's bad block marker byte,
> + * and not overlapping the default BBT markers.
> + */
> +static struct nand_ecclayout hwecc4_2048 = {
> +	.eccbytes = 40,
> +	.eccpos = {
> +		/* at the end of spare sector */
> +		24, 25, 26, 27, 28, 29,	30, 31, 32, 33,
> +		34, 35, 36, 37, 38, 39,	40, 41, 42, 43,
> +		44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
> +		54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
> +		},
> +	.oobfree = {
> +		/* 2 bytes at offset 0 hold manufacturer badblock markers */
> +		{.offset = 2, .length = 22, },
> +		/* 5 bytes at offset 8 hold BBT markers */
> +		/* 8 bytes at offset 16 hold JFFS2 clean markers */
> +	},
> +};
> +
> +static struct of_device_id davinci_nand_of_match[] = {
> +	{.compatible = "ti,davinci-nand", },
> +	{.compatible = "ti,keystone-nand", },
> +	{},
> +};
> +
> +static struct davinci_nand_pdata
> +	*nand_davinci_get_pdata(struct device_d *dev)
> +{
> +	struct davinci_nand_pdata *pdata;
> +	const char *mode;
> +	u32 prop;
> +
> +	pdata = kzalloc(sizeof(struct davinci_nand_pdata),
> +			GFP_KERNEL);
> +	if (!pdata)
> +		return ERR_PTR(-ENOMEM);
> +	if (!of_property_read_u32(dev->device_node,
> +		"ti,davinci-chipselect", &prop))
> +		pdata->chipsel = prop;
> +	else
> +		return ERR_PTR(-EINVAL);
> +
> +	if (!of_property_read_u32(dev->device_node,
> +		"ti,davinci-mask-ale", &prop))
> +		pdata->mask_ale = prop;
> +	if (!of_property_read_u32(dev->device_node,
> +		"ti,davinci-mask-cle", &prop))
> +		pdata->mask_cle = prop;
> +	if (!of_property_read_u32(dev->device_node,
> +		"ti,davinci-mask-chipsel", &prop))
> +		pdata->mask_chipsel = prop;
> +	if (!of_property_read_string(dev->device_node,
> +		"nand-ecc-mode", &mode) ||
> +	    !of_property_read_string(dev->device_node,
> +		"ti,davinci-ecc-mode", &mode)) {
> +		if (!strncmp("none", mode, 4))
> +			pdata->ecc_mode = NAND_ECC_NONE;
> +		if (!strncmp("soft", mode, 4))
> +			pdata->ecc_mode = NAND_ECC_SOFT;
> +		if (!strncmp("hw", mode, 2))
> +			pdata->ecc_mode = NAND_ECC_HW;
> +	}
> +	if (!of_property_read_u32(dev->device_node,
> +		"ti,davinci-ecc-bits", &prop))
> +		pdata->ecc_bits = prop;
> +
> +	prop = of_get_nand_bus_width(dev->device_node);
> +	if (0 < prop || !of_property_read_u32(dev->device_node,
> +		"ti,davinci-nand-buswidth", &prop))
> +		if (prop == 16)
> +			pdata->options |= NAND_BUSWIDTH_16;
> +	if (of_property_read_bool(dev->device_node,
> +		"nand-on-flash-bbt") ||
> +	    of_property_read_bool(dev->device_node,
> +		"ti,davinci-nand-use-bbt"))
> +		pdata->bbt_options = NAND_BBT_USE_FLASH;
> +
> +	if (of_device_is_compatible(dev->device_node,
> +				    "ti,keystone-nand")) {
> +		pdata->options |= NAND_NO_SUBPAGE_WRITE;
> +	}
> +	return pdata;
> +}
> +
> +static int nand_davinci_probe(struct device_d *dev)
> +{
> +	struct davinci_nand_pdata	*pdata;
> +	struct davinci_nand_info	*info;
> +	int				ret;
> +	uint32_t			val;
> +	nand_ecc_modes_t		ecc_mode;
> +
> +	pdata = nand_davinci_get_pdata(dev);
> +
> +	/* insist on board-specific configuration */
> +	if (!pdata)
> +		return -ENODEV;
> +
> +	/* which external chipselect will we be managing? */
> +	if (pdata->chipsel < 0 || pdata->chipsel > 3)
> +		return -ENODEV;
> +
> +	info = kzalloc(sizeof(*info), GFP_KERNEL);
> +	if (!info)
> +		return -ENOMEM;
> +
> +	//platform_set_drvdata(pdev, info);
> +
> +	info->dev		= dev;
> +	info->base		= dev_request_mem_region(dev, 1);
> +	info->vaddr		= dev_request_mem_region(dev, 0);
> +
> +	val = davinci_nand_readl(info, NRCSR_OFFSET);
> +	dev_info(dev, "controller rev. %d.%d\n",
> +	       (val >> 8) & 0xff, val & 0xff);
> +
> +	info->mtd.priv		= &info->chip;
> +	info->mtd.name		= dev_name(dev);
> +	info->mtd.parent	= dev;
> +
> +	info->chip.IO_ADDR_R	= info->vaddr;
> +	info->chip.IO_ADDR_W	= info->vaddr;
> +	info->chip.chip_delay	= 0;
> +	info->chip.select_chip	= nand_davinci_select_chip;
> +
> +	/* options such as NAND_BBT_USE_FLASH */
> +	info->chip.bbt_options	= pdata->bbt_options;
> +	/* options such as 16-bit widths */
> +	info->chip.options	= pdata->options;
> +	info->chip.bbt_td	= pdata->bbt_td;
> +	info->chip.bbt_md	= pdata->bbt_md;
> +	//info->timing		= pdata->timing;
> +
> +	info->ioaddr		= (uint32_t __force) info->vaddr;
> +
> +	info->current_cs	= info->ioaddr;
> +	info->core_chipsel	= pdata->chipsel;
> +	info->mask_chipsel	= pdata->mask_chipsel;
> +
> +	/* use nandboot-capable ALE/CLE masks by default */
> +	info->mask_ale		= pdata->mask_ale ? : MASK_ALE;
> +	info->mask_cle		= pdata->mask_cle ? : MASK_CLE;
> +
> +	/* Set address of hardware control function */
> +	info->chip.cmd_ctrl	= nand_davinci_hwcontrol;
> +	info->chip.dev_ready	= nand_davinci_dev_ready;
> +
> +	/* Speed up buffer I/O */
> +	info->chip.read_buf     = nand_davinci_read_buf;
> +	info->chip.write_buf    = nand_davinci_write_buf;
> +
> +	/* Use board-specific ECC config */
> +	ecc_mode		= pdata->ecc_mode;
> +
> +	ret = -EINVAL;
> +	switch (ecc_mode) {
> +	case NAND_ECC_NONE:
> +	case NAND_ECC_SOFT:
> +		pdata->ecc_bits = 0;
> +		break;
> +	case NAND_ECC_HW:
> +		if (pdata->ecc_bits == 4) {
> +			/* No sanity checks:  CPUs must support this,
> +			 * and the chips may not use NAND_BUSWIDTH_16.
> +			 */
> +
> +			/* No sharing 4-bit hardware between chipselects yet */
> +			if (ecc4_busy)
> +				ret = -EBUSY;
> +			else
> +				ecc4_busy = true;
> +
> +			if (ret == -EBUSY)
> +				return ret;
> +
> +			info->chip.ecc.calculate = nand_davinci_calculate_4bit;
> +			info->chip.ecc.correct = nand_davinci_correct_4bit;
> +			info->chip.ecc.hwctl = nand_davinci_hwctl_4bit;
> +			info->chip.ecc.bytes = 10;
> +		} else {
> +			info->chip.ecc.calculate = nand_davinci_calculate_1bit;
> +			info->chip.ecc.correct = nand_davinci_correct_1bit;
> +			info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
> +			info->chip.ecc.bytes = 3;
> +		}
> +		info->chip.ecc.size = 512;
> +		info->chip.ecc.strength = pdata->ecc_bits;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	info->chip.ecc.mode = ecc_mode;
> +
> +	info->clk = clk_get(dev, "aemif");
> +	if (IS_ERR(info->clk)) {
> +		ret = PTR_ERR(info->clk);
> +		dev_dbg(dev, "unable to get AEMIF clock, err %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_enable(info->clk);
> +	if (ret < 0) {
> +		dev_dbg(dev, "unable to enable AEMIF clock, err %d\n",
> +			ret);
> +		goto err_clk_enable;
> +	}
> +
> +	/* put CSxNAND into NAND mode */
> +	val = davinci_nand_readl(info, NANDFCR_OFFSET);
> +	val |= BIT(info->core_chipsel);
> +	davinci_nand_writel(info, NANDFCR_OFFSET, val);
> +
> +	/* Scan to find existence of the device(s) */
> +	ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL);
> +	if (ret < 0) {
> +		dev_dbg(dev, "no NAND chip(s) found\n");
> +		goto err;
> +	}
> +
> +	/* Update ECC layout if needed ... for 1-bit HW ECC, the default
> +	 * is OK, but it allocates 6 bytes when only 3 are needed (for
> +	 * each 512 bytes).  For the 4-bit HW ECC, that default is not
> +	 * usable:  10 bytes are needed, not 6.
> +	 */
> +	if (pdata->ecc_bits == 4) {
> +		int	chunks = info->mtd.writesize / 512;
> +
> +		if (!chunks || info->mtd.oobsize < 16) {
> +			dev_dbg(dev, "too small\n");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +
> +		/* For small page chips, preserve the manufacturer's
> +		 * badblock marking data ... and make sure a flash BBT
> +		 * table marker fits in the free bytes.
> +		 */
> +		if (chunks == 1) {
> +			info->ecclayout = hwecc4_small;
> +			info->ecclayout.oobfree[1].length =
> +				info->mtd.oobsize - 16;
> +			goto syndrome_done;
> +		}
> +		if (chunks == 4) {
> +			info->ecclayout = hwecc4_2048;
> +			info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
> +			goto syndrome_done;
> +		}
> +
> +		/* 4KiB page chips are not yet supported. The eccpos from
> +		 * nand_ecclayout cannot hold 80 bytes and change to eccpos[]
> +		 * breaks userspace ioctl interface with mtd-utils. Once we
> +		 * resolve this issue, NAND_ECC_HW_OOB_FIRST mode can be used
> +		 * for the 4KiB page chips.
> +		 *
> +		 * TODO: Note that nand_ecclayout has now been expanded and can
> +		 *  hold plenty of OOB entries.
> +		 */
> +		dev_warn(dev, "no 4-bit ECC support yet "
> +				"for 4KiB-page NAND\n");
> +		ret = -EIO;
> +		goto err;
> +
> +syndrome_done:
> +		info->chip.ecc.layout = &info->ecclayout;
> +	}
> +
> +	ret = nand_scan_tail(&info->mtd);
> +	if (ret < 0)
> +		goto err;
> +
> +	add_mtd_nand_device(&info->mtd, "nand");
> +
> +	return 0;
> +
> +err:
> +	clk_disable(info->clk);
> +
> +err_clk_enable:
> +	if (ecc_mode == NAND_ECC_HW_SYNDROME)
> +		ecc4_busy = false;
> +	return ret;
> +}
> +
> +static struct driver_d nand_davinci_driver = {
> +	.name	= "davinci_nand",
> +	.probe	= nand_davinci_probe,
> +	.of_compatible = DRV_OF_COMPAT(davinci_nand_of_match),
> +};
> +device_platform_driver(nand_davinci_driver);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Texas Instruments");
> +MODULE_DESCRIPTION("Davinci NAND flash driver");
> +
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
--?
Best regards,
? Antony Pavlov


