diff --git a/target/linux/mvebu/patches-3.10/0128-mtd-nand-pxa3xx_nand-Remove-redundant-of_match_ptr.patch b/target/linux/mvebu/patches-3.10/0128-mtd-nand-pxa3xx_nand-Remove-redundant-of_match_ptr.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a0c4e6995f77417dfc674f2b391a8893c08e4a45
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0128-mtd-nand-pxa3xx_nand-Remove-redundant-of_match_ptr.patch
@@ -0,0 +1,25 @@
+From 38a6d3f3330da6586695746a0a85a96143171211 Mon Sep 17 00:00:00 2001
+From: Sachin Kamat <sachin.kamat@linaro.org>
+Date: Mon, 30 Sep 2013 15:10:24 +0530
+Subject: [PATCH 128/203] mtd: nand: pxa3xx_nand: Remove redundant of_match_ptr
+
+The data structure of_match_ptr() protects is always compiled in.
+Hence of_match_ptr() is not needed.
+
+Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1412,7 +1412,7 @@ static int pxa3xx_nand_resume(struct pla
+ static struct platform_driver pxa3xx_nand_driver = {
+ 	.driver = {
+ 		.name	= "pxa3xx-nand",
+-		.of_match_table = of_match_ptr(pxa3xx_nand_dt_ids),
++		.of_match_table = pxa3xx_nand_dt_ids,
+ 	},
+ 	.probe		= pxa3xx_nand_probe,
+ 	.remove		= pxa3xx_nand_remove,
diff --git a/target/linux/mvebu/patches-3.10/0129-mtd-nand-pxa3xx-Move-DMA-I-O-enabling.patch b/target/linux/mvebu/patches-3.10/0129-mtd-nand-pxa3xx-Move-DMA-I-O-enabling.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0c95a61b97257abf6426e784003fbcfd2fdbe42a
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0129-mtd-nand-pxa3xx-Move-DMA-I-O-enabling.patch
@@ -0,0 +1,40 @@
+From 18166290599760e8ff1b6c0389834beafd09a517 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 4 Oct 2013 15:30:37 -0300
+Subject: [PATCH 129/203] mtd: nand: pxa3xx: Move DMA I/O enabling
+
+Instead of setting info->dma each time a command is prepared,
+we can move it after the DMA buffers are allocated.
+
+This is more clear and it's the proper place to enable this, given
+DMA cannot be turned on and off during runtime.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -540,7 +540,6 @@ static int prepare_command_pool(struct p
+ 	info->oob_size		= 0;
+ 	info->use_ecc		= 0;
+ 	info->use_spare		= 1;
+-	info->use_dma		= (use_dma) ? 1 : 0;
+ 	info->is_ready		= 0;
+ 	info->retcode		= ERR_NONE;
+ 	if (info->cs != 0)
+@@ -950,6 +949,11 @@ static int pxa3xx_nand_init_buff(struct
+ 		return info->data_dma_ch;
+ 	}
+ 
++	/*
++	 * Now that DMA buffers are allocated we turn on
++	 * DMA proper for I/O operations.
++	 */
++	info->use_dma = 1;
+ 	return 0;
+ }
+ 
diff --git a/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch b/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch
new file mode 100644
index 0000000000000000000000000000000000000000..09f022b967b691e8ed925759f93b3908434df111
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0130-mtd-nand-pxa3xx-Allocate-data-buffer-on-detected-fla.patch
@@ -0,0 +1,143 @@
+From 71d6267980d7590e38059a784785ca158e361f87 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 4 Oct 2013 15:30:38 -0300
+Subject: [PATCH 130/203] mtd: nand: pxa3xx: Allocate data buffer on detected
+ flash size
+
+This commit replaces the currently hardcoded buffer size, by a
+dynamic detection scheme. First a small 256 bytes buffer is allocated
+so the device can be detected (using READID and friends commands).
+
+After detection, this buffer is released and a new buffer is allocated
+to acommodate the page size plus out-of-band size.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 45 ++++++++++++++++++++++++++++--------------
+ 1 file changed, 30 insertions(+), 15 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -39,6 +39,13 @@
+ #define NAND_STOP_DELAY		(2 * HZ/50)
+ #define PAGE_CHUNK_SIZE		(2048)
+ 
++/*
++ * Define a buffer size for the initial command that detects the flash device:
++ * STATUS, READID and PARAM. The largest of these is the PARAM command,
++ * needing 256 bytes.
++ */
++#define INIT_BUFFER_SIZE	256
++
+ /* registers and bit definitions */
+ #define NDCR		(0x00) /* Control register */
+ #define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
+@@ -164,6 +171,7 @@ struct pxa3xx_nand_info {
+ 
+ 	unsigned int 		buf_start;
+ 	unsigned int		buf_count;
++	unsigned int		buf_size;
+ 
+ 	/* DMA information */
+ 	int			drcmr_dat;
+@@ -911,26 +919,20 @@ static int pxa3xx_nand_detect_config(str
+ 	return 0;
+ }
+ 
+-/* the maximum possible buffer size for large page with OOB data
+- * is: 2048 + 64 = 2112 bytes, allocate a page here for both the
+- * data buffer and the DMA descriptor
+- */
+-#define MAX_BUFF_SIZE	PAGE_SIZE
+-
+ #ifdef ARCH_HAS_DMA
+ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
+ {
+ 	struct platform_device *pdev = info->pdev;
+-	int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc);
++	int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc);
+ 
+ 	if (use_dma == 0) {
+-		info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
++		info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
+ 		if (info->data_buff == NULL)
+ 			return -ENOMEM;
+ 		return 0;
+ 	}
+ 
+-	info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE,
++	info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size,
+ 				&info->data_buff_phys, GFP_KERNEL);
+ 	if (info->data_buff == NULL) {
+ 		dev_err(&pdev->dev, "failed to allocate dma buffer\n");
+@@ -944,7 +946,7 @@ static int pxa3xx_nand_init_buff(struct
+ 				pxa3xx_nand_data_dma_irq, info);
+ 	if (info->data_dma_ch < 0) {
+ 		dev_err(&pdev->dev, "failed to request data dma\n");
+-		dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
++		dma_free_coherent(&pdev->dev, info->buf_size,
+ 				info->data_buff, info->data_buff_phys);
+ 		return info->data_dma_ch;
+ 	}
+@@ -962,7 +964,7 @@ static void pxa3xx_nand_free_buff(struct
+ 	struct platform_device *pdev = info->pdev;
+ 	if (use_dma) {
+ 		pxa_free_dma(info->data_dma_ch);
+-		dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
++		dma_free_coherent(&pdev->dev, info->buf_size,
+ 				  info->data_buff, info->data_buff_phys);
+ 	} else {
+ 		kfree(info->data_buff);
+@@ -971,7 +973,7 @@ static void pxa3xx_nand_free_buff(struct
+ #else
+ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
+ {
+-	info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
++	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
+ 	if (info->data_buff == NULL)
+ 		return -ENOMEM;
+ 	return 0;
+@@ -1085,7 +1087,16 @@ KEEP_CONFIG:
+ 	else
+ 		host->col_addr_cycles = 1;
+ 
++	/* release the initial buffer */
++	kfree(info->data_buff);
++
++	/* allocate the real data + oob buffer */
++	info->buf_size = mtd->writesize + mtd->oobsize;
++	ret = pxa3xx_nand_init_buff(info);
++	if (ret)
++		return ret;
+ 	info->oob_buff = info->data_buff + mtd->writesize;
++
+ 	if ((mtd->size >> chip->page_shift) > 65536)
+ 		host->row_addr_cycles = 3;
+ 	else
+@@ -1191,9 +1202,13 @@ static int alloc_nand_resource(struct pl
+ 	}
+ 	info->mmio_phys = r->start;
+ 
+-	ret = pxa3xx_nand_init_buff(info);
+-	if (ret)
++	/* Allocate a buffer to allow flash detection */
++	info->buf_size = INIT_BUFFER_SIZE;
++	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
++	if (info->data_buff == NULL) {
++		ret = -ENOMEM;
+ 		goto fail_disable_clk;
++	}
+ 
+ 	/* initialize all interrupts to be disabled */
+ 	disable_int(info, NDSR_MASK);
+@@ -1211,7 +1226,7 @@ static int alloc_nand_resource(struct pl
+ 
+ fail_free_buf:
+ 	free_irq(irq, info);
+-	pxa3xx_nand_free_buff(info);
++	kfree(info->data_buff);
+ fail_disable_clk:
+ 	clk_disable_unprepare(info->clk);
+ 	return ret;
diff --git a/target/linux/mvebu/patches-3.10/0131-mtd-nand-remove-deprecated-IRQF_DISABLED.patch b/target/linux/mvebu/patches-3.10/0131-mtd-nand-remove-deprecated-IRQF_DISABLED.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6cecbf2c88a4c61e1b91f7b43ec71bf4edc8fbae
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0131-mtd-nand-remove-deprecated-IRQF_DISABLED.patch
@@ -0,0 +1,27 @@
+From e3779fc4a84e1c51c061e3e13b1abf1c9a56a2cd Mon Sep 17 00:00:00 2001
+From: Michael Opdenacker <michael.opdenacker@free-electrons.com>
+Date: Sun, 13 Oct 2013 08:21:32 +0200
+Subject: [PATCH 131/203] mtd: nand: remove deprecated IRQF_DISABLED
+
+This patch proposes to remove the use of the IRQF_DISABLED flag
+
+It's a NOOP since 2.6.35 and it will be removed one day.
+
+Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1213,8 +1213,7 @@ static int alloc_nand_resource(struct pl
+ 	/* initialize all interrupts to be disabled */
+ 	disable_int(info, NDSR_MASK);
+ 
+-	ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED,
+-			  pdev->name, info);
++	ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
+ 	if (ret < 0) {
+ 		dev_err(&pdev->dev, "failed to request IRQ\n");
+ 		goto fail_free_buf;
diff --git a/target/linux/mvebu/patches-3.10/0132-mtd-nand-pxa3xx-Add-documentation-about-the-controll.patch b/target/linux/mvebu/patches-3.10/0132-mtd-nand-pxa3xx-Add-documentation-about-the-controll.patch
new file mode 100644
index 0000000000000000000000000000000000000000..561c7d7d741daed762c5d674158c50936886e872
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0132-mtd-nand-pxa3xx-Add-documentation-about-the-controll.patch
@@ -0,0 +1,28 @@
+From 54c1163b143e4ed911b8dddc0829c87f93b3debd Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:10 -0300
+Subject: [PATCH 132/203] mtd: nand: pxa3xx: Add documentation about the
+ controller
+
+Given there's no public specification to this date, and in order
+to capture some important details and singularities about the
+controller let's document them once and for good.
+
+Cc: linux-doc@vger.kernel.org
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -7,6 +7,8 @@
+  * 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.
++ *
++ * See Documentation/mtd/nand/pxa3xx-nand.txt for more details.
+  */
+ 
+ #include <linux/kernel.h>
diff --git a/target/linux/mvebu/patches-3.10/0133-mtd-nand-pxa3xx-Prevent-sub-page-writes.patch b/target/linux/mvebu/patches-3.10/0133-mtd-nand-pxa3xx-Prevent-sub-page-writes.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1af6da297fec3bf1409636275cdd7117aa3ec679
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0133-mtd-nand-pxa3xx-Prevent-sub-page-writes.patch
@@ -0,0 +1,25 @@
+From ec1977c2873dc7f0e6cec3edb8c30d92882f65d1 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:12 -0300
+Subject: [PATCH 133/203] mtd: nand: pxa3xx: Prevent sub-page writes
+
+The current driver doesn't support sub-page writing, so report
+that to the NAND core.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1145,6 +1145,7 @@ static int alloc_nand_resource(struct pl
+ 		chip->read_byte		= pxa3xx_nand_read_byte;
+ 		chip->read_buf		= pxa3xx_nand_read_buf;
+ 		chip->write_buf		= pxa3xx_nand_write_buf;
++		chip->options		|= NAND_NO_SUBPAGE_WRITE;
+ 	}
+ 
+ 	spin_lock_init(&chip->controller->lock);
diff --git a/target/linux/mvebu/patches-3.10/0134-mtd-nand-pxa3xx-read_page-returns-max_bitflips.patch b/target/linux/mvebu/patches-3.10/0134-mtd-nand-pxa3xx-read_page-returns-max_bitflips.patch
new file mode 100644
index 0000000000000000000000000000000000000000..afb81720c084c1ad2d0b91816b1c50041c5f4910
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0134-mtd-nand-pxa3xx-read_page-returns-max_bitflips.patch
@@ -0,0 +1,42 @@
+From 97598678602aaea473303523ce37a45d258206ca Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:13 -0300
+Subject: [PATCH 134/203] mtd: nand: pxa3xx: read_page() returns max_bitflips
+
+As per the ecc.read_page() prototype, we must return the maximum number
+of bitflips that were corrected on any one region covering an ecc step.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -751,6 +751,7 @@ static int pxa3xx_nand_read_page_hwecc(s
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+ 	struct pxa3xx_nand_info *info = host->info_data;
++	int max_bitflips = 0;
+ 
+ 	chip->read_buf(mtd, buf, mtd->writesize);
+ 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+@@ -758,6 +759,7 @@ static int pxa3xx_nand_read_page_hwecc(s
+ 	if (info->retcode == ERR_SBERR) {
+ 		switch (info->use_ecc) {
+ 		case 1:
++			max_bitflips = 1;
+ 			mtd->ecc_stats.corrected++;
+ 			break;
+ 		case 0:
+@@ -776,7 +778,7 @@ static int pxa3xx_nand_read_page_hwecc(s
+ 			mtd->ecc_stats.failed++;
+ 	}
+ 
+-	return 0;
++	return max_bitflips;
+ }
+ 
+ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
diff --git a/target/linux/mvebu/patches-3.10/0135-mtd-nand-pxa3xx-Early-variant-detection.patch b/target/linux/mvebu/patches-3.10/0135-mtd-nand-pxa3xx-Early-variant-detection.patch
new file mode 100644
index 0000000000000000000000000000000000000000..328a2ab900848c139360dfd3bdc7e02063f3bcbb
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0135-mtd-nand-pxa3xx-Early-variant-detection.patch
@@ -0,0 +1,97 @@
+From dc333ddda677d416a6726509e144c6dfb93e7e89 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:14 -0300
+Subject: [PATCH 135/203] mtd: nand: pxa3xx: Early variant detection
+
+In order to customize early settings depending on the detected SoC variant,
+move the detection to be before the nand_chip struct filling.
+
+In a follow-up patch, this change is needed to detect the variant *before*
+the call to alloc_nand_resource(), which allows to set a different cmdfunc()
+for each variant.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 48 +++++++++++++++++++++---------------------
+ 1 file changed, 24 insertions(+), 24 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -258,6 +258,29 @@ static struct pxa3xx_nand_flash builtin_
+ /* convert nano-seconds to nand flash controller clock cycles */
+ #define ns2cycle(ns, clk)	(int)((ns) * (clk / 1000000) / 1000)
+ 
++static struct of_device_id pxa3xx_nand_dt_ids[] = {
++	{
++		.compatible = "marvell,pxa3xx-nand",
++		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
++	},
++	{
++		.compatible = "marvell,armada370-nand",
++		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
++	},
++	{}
++};
++MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
++
++static enum pxa3xx_nand_variant
++pxa3xx_nand_get_variant(struct platform_device *pdev)
++{
++	const struct of_device_id *of_id =
++			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
++	if (!of_id)
++		return PXA3XX_NAND_VARIANT_PXA;
++	return (enum pxa3xx_nand_variant)of_id->data;
++}
++
+ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
+ 				   const struct pxa3xx_nand_timing *t)
+ {
+@@ -1125,6 +1148,7 @@ static int alloc_nand_resource(struct pl
+ 		return -ENOMEM;
+ 
+ 	info->pdev = pdev;
++	info->variant = pxa3xx_nand_get_variant(pdev);
+ 	for (cs = 0; cs < pdata->num_cs; cs++) {
+ 		mtd = (struct mtd_info *)((unsigned int)&info[1] +
+ 		      (sizeof(*mtd) + sizeof(*host)) * cs);
+@@ -1259,29 +1283,6 @@ static int pxa3xx_nand_remove(struct pla
+ 	return 0;
+ }
+ 
+-static struct of_device_id pxa3xx_nand_dt_ids[] = {
+-	{
+-		.compatible = "marvell,pxa3xx-nand",
+-		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
+-	},
+-	{
+-		.compatible = "marvell,armada370-nand",
+-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
+-	},
+-	{}
+-};
+-MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
+-
+-static enum pxa3xx_nand_variant
+-pxa3xx_nand_get_variant(struct platform_device *pdev)
+-{
+-	const struct of_device_id *of_id =
+-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
+-	if (!of_id)
+-		return PXA3XX_NAND_VARIANT_PXA;
+-	return (enum pxa3xx_nand_variant)of_id->data;
+-}
+-
+ static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
+ {
+ 	struct pxa3xx_nand_platform_data *pdata;
+@@ -1338,7 +1339,6 @@ static int pxa3xx_nand_probe(struct plat
+ 	}
+ 
+ 	info = platform_get_drvdata(pdev);
+-	info->variant = pxa3xx_nand_get_variant(pdev);
+ 	probe_success = 0;
+ 	for (cs = 0; cs < pdata->num_cs; cs++) {
+ 		struct mtd_info *mtd = info->host[cs]->mtd;
diff --git a/target/linux/mvebu/patches-3.10/0136-mtd-nand-pxa3xx-Use-chip-cmdfunc-instead-of-the-inte.patch b/target/linux/mvebu/patches-3.10/0136-mtd-nand-pxa3xx-Use-chip-cmdfunc-instead-of-the-inte.patch
new file mode 100644
index 0000000000000000000000000000000000000000..de79b8d28d8965f88c7550ec48a45451c1ce8a9c
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0136-mtd-nand-pxa3xx-Use-chip-cmdfunc-instead-of-the-inte.patch
@@ -0,0 +1,41 @@
+From 67ab922e1e292494732a10f367d3de47338639ac Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:15 -0300
+Subject: [PATCH 136/203] mtd: nand: pxa3xx: Use chip->cmdfunc instead of the
+ internal
+
+Whenever possible, it's always better to use the generic chip->cmdfunc
+instead of the internal pxa3xx_nand_cmdfunc().
+In this particular case, this will allow to have multiple cmdfunc()
+implementations for different SoC variants.
+
+Reviewed-by: Huang Shijie <shijie8@gmail.com>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1015,14 +1015,18 @@ static void pxa3xx_nand_free_buff(struct
+ static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
+ {
+ 	struct mtd_info *mtd;
++	struct nand_chip *chip;
+ 	int ret;
++
+ 	mtd = info->host[info->cs]->mtd;
++	chip = mtd->priv;
++
+ 	/* use the common timing to make a try */
+ 	ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
+ 	if (ret)
+ 		return ret;
+ 
+-	pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
++	chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+ 	if (info->is_ready)
+ 		return 0;
+ 
diff --git a/target/linux/mvebu/patches-3.10/0137-mtd-nand-pxa3xx-Split-FIFO-size-from-to-be-read-FIFO.patch b/target/linux/mvebu/patches-3.10/0137-mtd-nand-pxa3xx-Split-FIFO-size-from-to-be-read-FIFO.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e00921d40fd9de90471a61625744ce57db33e013
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0137-mtd-nand-pxa3xx-Split-FIFO-size-from-to-be-read-FIFO.patch
@@ -0,0 +1,74 @@
+From 496f307424d3958ef43ad06ae6a0be98ede2a92c Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:16 -0300
+Subject: [PATCH 137/203] mtd: nand: pxa3xx: Split FIFO size from to-be-read
+ FIFO count
+
+Introduce a fifo_size field to represent the size of the controller's
+FIFO buffer, and use it to distinguish that size from the amount
+of data bytes to be read from the FIFO.
+
+This is important to support devices with pages larger than the
+controller's internal FIFO, that need to read the pages in FIFO-sized
+chunks.
+
+In particular, the current code is at least confusing, for it mixes
+all the different sizes involved: FIFO size, page size and data size.
+
+This commit starts the cleaning by removing the info->page_size field
+that is not currently used. The host->page_size field should also
+be removed and use always mtd->writesize instead. Follow up commits
+will clean this up.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -201,8 +201,8 @@ struct pxa3xx_nand_info {
+ 	int			use_spare;	/* use spare ? */
+ 	int			is_ready;
+ 
+-	unsigned int		page_size;	/* page size of attached chip */
+-	unsigned int		data_size;	/* data size in FIFO */
++	unsigned int		fifo_size;	/* max. data size in the FIFO */
++	unsigned int		data_size;	/* data to be read from FIFO */
+ 	unsigned int		oob_size;
+ 	int 			retcode;
+ 
+@@ -307,16 +307,15 @@ static void pxa3xx_nand_set_timing(struc
+ 
+ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
+ {
+-	struct pxa3xx_nand_host *host = info->host[info->cs];
+ 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
+ 
+-	info->data_size = host->page_size;
++	info->data_size = info->fifo_size;
+ 	if (!oob_enable) {
+ 		info->oob_size = 0;
+ 		return;
+ 	}
+ 
+-	switch (host->page_size) {
++	switch (info->fifo_size) {
+ 	case 2048:
+ 		info->oob_size = (info->use_ecc) ? 40 : 64;
+ 		break;
+@@ -933,9 +932,12 @@ static int pxa3xx_nand_detect_config(str
+ 	uint32_t ndcr = nand_readl(info, NDCR);
+ 
+ 	if (ndcr & NDCR_PAGE_SZ) {
++		/* Controller's FIFO size */
++		info->fifo_size = 2048;
+ 		host->page_size = 2048;
+ 		host->read_id_bytes = 4;
+ 	} else {
++		info->fifo_size = 512;
+ 		host->page_size = 512;
+ 		host->read_id_bytes = 2;
+ 	}
diff --git a/target/linux/mvebu/patches-3.10/0138-mtd-nand-pxa3xx-Replace-host-page_size-by-mtd-writes.patch b/target/linux/mvebu/patches-3.10/0138-mtd-nand-pxa3xx-Replace-host-page_size-by-mtd-writes.patch
new file mode 100644
index 0000000000000000000000000000000000000000..259f6a0a399e763e2cefefec849c25a717de5446
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0138-mtd-nand-pxa3xx-Replace-host-page_size-by-mtd-writes.patch
@@ -0,0 +1,72 @@
+From ad40a597cbfeb2374c799ba6dad3a69f131511c8 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:17 -0300
+Subject: [PATCH 138/203] mtd: nand: pxa3xx: Replace host->page_size by
+ mtd->writesize
+
+There's no need to privately store the device page size as it's
+available in mtd structure field mtd->writesize.
+Also, this removes the hardcoded page size value, leaving the
+auto-detected value only.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -151,7 +151,6 @@ struct pxa3xx_nand_host {
+ 	void			*info_data;
+ 
+ 	/* page size of attached chip */
+-	unsigned int		page_size;
+ 	int			use_ecc;
+ 	int			cs;
+ 
+@@ -614,12 +613,12 @@ static int prepare_command_pool(struct p
+ 			info->buf_start += mtd->writesize;
+ 
+ 		/* Second command setting for large pages */
+-		if (host->page_size >= PAGE_CHUNK_SIZE)
++		if (mtd->writesize >= PAGE_CHUNK_SIZE)
+ 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+ 
+ 	case NAND_CMD_SEQIN:
+ 		/* small page addr setting */
+-		if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) {
++		if (unlikely(mtd->writesize < PAGE_CHUNK_SIZE)) {
+ 			info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
+ 					| (column & 0xFF);
+ 
+@@ -895,7 +894,6 @@ static int pxa3xx_nand_config_flash(stru
+ 	}
+ 
+ 	/* calculate flash information */
+-	host->page_size = f->page_size;
+ 	host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+ 
+ 	/* calculate addressing information */
+@@ -934,11 +932,9 @@ static int pxa3xx_nand_detect_config(str
+ 	if (ndcr & NDCR_PAGE_SZ) {
+ 		/* Controller's FIFO size */
+ 		info->fifo_size = 2048;
+-		host->page_size = 2048;
+ 		host->read_id_bytes = 4;
+ 	} else {
+ 		info->fifo_size = 512;
+-		host->page_size = 512;
+ 		host->read_id_bytes = 2;
+ 	}
+ 
+@@ -1106,7 +1102,7 @@ static int pxa3xx_nand_scan(struct mtd_i
+ 	def = pxa3xx_flash_ids;
+ KEEP_CONFIG:
+ 	chip->ecc.mode = NAND_ECC_HW;
+-	chip->ecc.size = host->page_size;
++	chip->ecc.size = info->fifo_size;
+ 	chip->ecc.strength = 1;
+ 
+ 	if (info->reg_ndcr & NDCR_DWIDTH_M)
diff --git a/target/linux/mvebu/patches-3.10/0139-mtd-nand-pxa3xx-Add-a-nice-comment-to-pxa3xx_set_dat.patch b/target/linux/mvebu/patches-3.10/0139-mtd-nand-pxa3xx-Add-a-nice-comment-to-pxa3xx_set_dat.patch
new file mode 100644
index 0000000000000000000000000000000000000000..aeecae6218d3ac1dbeddff88400729172a4456fa
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0139-mtd-nand-pxa3xx-Add-a-nice-comment-to-pxa3xx_set_dat.patch
@@ -0,0 +1,30 @@
+From 8bce53e42f78e009fbfbd4a98ea98f66e6cd5b4c Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:18 -0300
+Subject: [PATCH 139/203] mtd: nand: pxa3xx: Add a nice comment to
+ pxa3xx_set_datasize()
+
+Add a comment clarifying the use of pxa3xx_set_datasize() which is only
+applicable on data read/write commands (i.e. commands with a data cycle,
+such as READID, READ0, STATUS, etc.)
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -304,6 +304,11 @@ static void pxa3xx_nand_set_timing(struc
+ 	nand_writel(info, NDTR1CS0, ndtr1);
+ }
+ 
++/*
++ * Set the data and OOB size, depending on the selected
++ * spare and ECC configuration.
++ * Only applicable to READ0, READOOB and PAGEPROG commands.
++ */
+ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
+ {
+ 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
diff --git a/target/linux/mvebu/patches-3.10/0140-mtd-nand-pxa3xx-Use-a-completion-to-signal-device-re.patch b/target/linux/mvebu/patches-3.10/0140-mtd-nand-pxa3xx-Use-a-completion-to-signal-device-re.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7f5108fd2f41cf75f33dedb743c0b54e6adfbdfb
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0140-mtd-nand-pxa3xx-Use-a-completion-to-signal-device-re.patch
@@ -0,0 +1,138 @@
+From b5289e9cb18e6c254e13826e6bcfbfe95b819d77 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:26 -0300
+Subject: [PATCH 140/203] mtd: nand: pxa3xx: Use a completion to signal device
+ ready
+
+The expected behavior of the waitfunc() NAND chip call is to wait
+for the device to be READY (this is a standard chip line).
+However, the current implementation does almost nothing, which opens
+the possibility of issuing a command to a non-ready device.
+
+Fix this by adding a new completion to wait for the ready event to arrive.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 38 ++++++++++++++++++++++++--------------
+ 1 file changed, 24 insertions(+), 14 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -37,6 +37,7 @@
+ 
+ #include <linux/platform_data/mtd-nand-pxa3xx.h>
+ 
++#define NAND_DEV_READY_TIMEOUT  50
+ #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
+ #define NAND_STOP_DELAY		(2 * HZ/50)
+ #define PAGE_CHUNK_SIZE		(2048)
+@@ -168,7 +169,7 @@ struct pxa3xx_nand_info {
+ 	struct clk		*clk;
+ 	void __iomem		*mmio_base;
+ 	unsigned long		mmio_phys;
+-	struct completion	cmd_complete;
++	struct completion	cmd_complete, dev_ready;
+ 
+ 	unsigned int 		buf_start;
+ 	unsigned int		buf_count;
+@@ -198,7 +199,7 @@ struct pxa3xx_nand_info {
+ 	int			use_ecc;	/* use HW ECC ? */
+ 	int			use_dma;	/* use DMA ? */
+ 	int			use_spare;	/* use spare ? */
+-	int			is_ready;
++	int			need_wait;
+ 
+ 	unsigned int		fifo_size;	/* max. data size in the FIFO */
+ 	unsigned int		data_size;	/* data to be read from FIFO */
+@@ -480,7 +481,7 @@ static void start_data_dma(struct pxa3xx
+ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
+ {
+ 	struct pxa3xx_nand_info *info = devid;
+-	unsigned int status, is_completed = 0;
++	unsigned int status, is_completed = 0, is_ready = 0;
+ 	unsigned int ready, cmd_done;
+ 
+ 	if (info->cs == 0) {
+@@ -516,8 +517,8 @@ static irqreturn_t pxa3xx_nand_irq(int i
+ 		is_completed = 1;
+ 	}
+ 	if (status & ready) {
+-		info->is_ready = 1;
+ 		info->state = STATE_READY;
++		is_ready = 1;
+ 	}
+ 
+ 	if (status & NDSR_WRCMDREQ) {
+@@ -546,6 +547,8 @@ static irqreturn_t pxa3xx_nand_irq(int i
+ 	nand_writel(info, NDSR, status);
+ 	if (is_completed)
+ 		complete(&info->cmd_complete);
++	if (is_ready)
++		complete(&info->dev_ready);
+ NORMAL_IRQ_EXIT:
+ 	return IRQ_HANDLED;
+ }
+@@ -576,7 +579,6 @@ static int prepare_command_pool(struct p
+ 	info->oob_size		= 0;
+ 	info->use_ecc		= 0;
+ 	info->use_spare		= 1;
+-	info->is_ready		= 0;
+ 	info->retcode		= ERR_NONE;
+ 	if (info->cs != 0)
+ 		info->ndcb0 = NDCB0_CSEL;
+@@ -749,6 +751,8 @@ static void pxa3xx_nand_cmdfunc(struct m
+ 	exec_cmd = prepare_command_pool(info, command, column, page_addr);
+ 	if (exec_cmd) {
+ 		init_completion(&info->cmd_complete);
++		init_completion(&info->dev_ready);
++		info->need_wait = 1;
+ 		pxa3xx_nand_start(info);
+ 
+ 		ret = wait_for_completion_timeout(&info->cmd_complete,
+@@ -863,21 +867,27 @@ static int pxa3xx_nand_waitfunc(struct m
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+ 	struct pxa3xx_nand_info *info = host->info_data;
++	int ret;
++
++	if (info->need_wait) {
++		ret = wait_for_completion_timeout(&info->dev_ready,
++				CHIP_DELAY_TIMEOUT);
++		info->need_wait = 0;
++		if (!ret) {
++			dev_err(&info->pdev->dev, "Ready time out!!!\n");
++			return NAND_STATUS_FAIL;
++		}
++	}
+ 
+ 	/* pxa3xx_nand_send_command has waited for command complete */
+ 	if (this->state == FL_WRITING || this->state == FL_ERASING) {
+ 		if (info->retcode == ERR_NONE)
+ 			return 0;
+-		else {
+-			/*
+-			 * any error make it return 0x01 which will tell
+-			 * the caller the erase and write fail
+-			 */
+-			return 0x01;
+-		}
++		else
++			return NAND_STATUS_FAIL;
+ 	}
+ 
+-	return 0;
++	return NAND_STATUS_READY;
+ }
+ 
+ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
+@@ -1030,7 +1040,7 @@ static int pxa3xx_nand_sensing(struct px
+ 		return ret;
+ 
+ 	chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+-	if (info->is_ready)
++	if (!info->need_wait)
+ 		return 0;
+ 
+ 	return -ENODEV;
diff --git a/target/linux/mvebu/patches-3.10/0141-mtd-nand-pxa3xx-Use-waitfunc-to-wait-for-the-device-.patch b/target/linux/mvebu/patches-3.10/0141-mtd-nand-pxa3xx-Use-waitfunc-to-wait-for-the-device-.patch
new file mode 100644
index 0000000000000000000000000000000000000000..13fdffe532970790bc69c5c3bad2338b836a3ffb
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0141-mtd-nand-pxa3xx-Use-waitfunc-to-wait-for-the-device-.patch
@@ -0,0 +1,34 @@
+From 2a1254f505ca4d376eae81768e4d5d890b578d13 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:27 -0300
+Subject: [PATCH 141/203] mtd: nand: pxa3xx: Use waitfunc() to wait for the
+ device to be ready
+
+In pxa3xx_nand_sensing() instead of simply using info->is_ready
+after issuing a command, the correct way of checking is to wait
+for the device to be ready through the chip's waitfunc().
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1040,10 +1040,11 @@ static int pxa3xx_nand_sensing(struct px
+ 		return ret;
+ 
+ 	chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+-	if (!info->need_wait)
+-		return 0;
++	ret = chip->waitfunc(mtd, chip);
++	if (ret & NAND_STATUS_FAIL)
++		return -ENODEV;
+ 
+-	return -ENODEV;
++	return 0;
+ }
+ 
+ static int pxa3xx_nand_scan(struct mtd_info *mtd)
diff --git a/target/linux/mvebu/patches-3.10/0142-mtd-nand-pxa3xx-Add-bad-block-handling.patch b/target/linux/mvebu/patches-3.10/0142-mtd-nand-pxa3xx-Add-bad-block-handling.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0d04bf4d8269d26f7b6982b97c11eb19f6d37d52
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0142-mtd-nand-pxa3xx-Add-bad-block-handling.patch
@@ -0,0 +1,108 @@
+From bd428b9b18c2dffb8c9d737e99adfd145822e502 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:28 -0300
+Subject: [PATCH 142/203] mtd: nand: pxa3xx: Add bad block handling
+
+Add support for flash-based bad block table using Marvell's
+custom in-flash bad block table layout. The support is enabled
+a 'flash_bbt' platform data or device tree parameter.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ .../devicetree/bindings/mtd/pxa3xx-nand.txt        |  2 ++
+ drivers/mtd/nand/pxa3xx_nand.c                     | 37 ++++++++++++++++++++++
+ include/linux/platform_data/mtd-nand-pxa3xx.h      |  3 ++
+ 3 files changed, 42 insertions(+)
+
+--- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
++++ b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
+@@ -13,6 +13,8 @@ Optional properties:
+  - marvell,nand-keep-config:	Set to keep the NAND controller config as set
+ 				by the bootloader
+  - num-cs:			Number of chipselect lines to usw
++ - nand-on-flash-bbt: 		boolean to enable on flash bbt option if
++				not present false
+ 
+ Example:
+ 
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -26,6 +26,7 @@
+ #include <linux/slab.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/of_mtd.h>
+ 
+ #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
+ #define ARCH_HAS_DMA
+@@ -241,6 +242,29 @@ static struct pxa3xx_nand_flash builtin_
+ { "256MiB 16-bit", 0xba20,  64, 2048, 16, 16, 2048, &timing[3] },
+ };
+ 
++static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
++static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
++
++static struct nand_bbt_descr bbt_main_descr = {
++	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
++		| NAND_BBT_2BIT | NAND_BBT_VERSION,
++	.offs =	8,
++	.len = 6,
++	.veroffs = 14,
++	.maxblocks = 8,		/* Last 8 blocks in each chip */
++	.pattern = bbt_pattern
++};
++
++static struct nand_bbt_descr bbt_mirror_descr = {
++	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
++		| NAND_BBT_2BIT | NAND_BBT_VERSION,
++	.offs =	8,
++	.len = 6,
++	.veroffs = 14,
++	.maxblocks = 8,		/* Last 8 blocks in each chip */
++	.pattern = bbt_mirror_pattern
++};
++
+ /* Define a default flash type setting serve as flash detecting only */
+ #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
+ 
+@@ -1126,6 +1150,18 @@ KEEP_CONFIG:
+ 
+ 	if (nand_scan_ident(mtd, 1, def))
+ 		return -ENODEV;
++
++	if (pdata->flash_bbt) {
++		/*
++		 * We'll use a bad block table stored in-flash and don't
++		 * allow writing the bad block marker to the flash.
++		 */
++		chip->bbt_options |= NAND_BBT_USE_FLASH |
++				     NAND_BBT_NO_OOB_BBM;
++		chip->bbt_td = &bbt_main_descr;
++		chip->bbt_md = &bbt_mirror_descr;
++	}
++
+ 	/* calculate addressing information */
+ 	if (mtd->writesize >= 2048)
+ 		host->col_addr_cycles = 2;
+@@ -1320,6 +1356,7 @@ static int pxa3xx_nand_probe_dt(struct p
+ 	if (of_get_property(np, "marvell,nand-keep-config", NULL))
+ 		pdata->keep_config = 1;
+ 	of_property_read_u32(np, "num-cs", &pdata->num_cs);
++	pdata->flash_bbt = of_get_nand_on_flash_bbt(np);
+ 
+ 	pdev->dev.platform_data = pdata;
+ 
+--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
++++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
+@@ -55,6 +55,9 @@ struct pxa3xx_nand_platform_data {
+ 	/* indicate how many chip selects will be used */
+ 	int	num_cs;
+ 
++	/* use an flash-based bad block table */
++	bool	flash_bbt;
++
+ 	const struct mtd_partition		*parts[NUM_CHIP_SELECT];
+ 	unsigned int				nr_parts[NUM_CHIP_SELECT];
+ 
diff --git a/target/linux/mvebu/patches-3.10/0143-mtd-nand-pxa3xx-Add-driver-specific-ECC-BCH-support.patch b/target/linux/mvebu/patches-3.10/0143-mtd-nand-pxa3xx-Add-driver-specific-ECC-BCH-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c310effadf40742bbc7053dc7ecaadb6841cd9d8
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0143-mtd-nand-pxa3xx-Add-driver-specific-ECC-BCH-support.patch
@@ -0,0 +1,172 @@
+From 3677d22ed7e3a631f35e2addc4e2181f6215e4b0 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:29 -0300
+Subject: [PATCH 143/203] mtd: nand: pxa3xx: Add driver-specific ECC BCH
+ support
+
+This commit adds the BCH ECC support available in NFCv2 controller.
+Depending on the detected required strength the respective ECC layout
+is selected.
+
+This commit adds an empty ECC layout, since support to access large
+pages is first required. Once that support is added, a proper ECC
+layout will be added as well.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 86 +++++++++++++++++++++++++++++++++---------
+ 1 file changed, 69 insertions(+), 17 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -58,6 +58,7 @@
+ #define NDPCR		(0x18) /* Page Count Register */
+ #define NDBDR0		(0x1C) /* Bad Block Register 0 */
+ #define NDBDR1		(0x20) /* Bad Block Register 1 */
++#define NDECCCTRL	(0x28) /* ECC control */
+ #define NDDB		(0x40) /* Data Buffer */
+ #define NDCB0		(0x48) /* Command Buffer0 */
+ #define NDCB1		(0x4C) /* Command Buffer1 */
+@@ -198,6 +199,7 @@ struct pxa3xx_nand_info {
+ 
+ 	int			cs;
+ 	int			use_ecc;	/* use HW ECC ? */
++	int			ecc_bch;	/* using BCH ECC? */
+ 	int			use_dma;	/* use DMA ? */
+ 	int			use_spare;	/* use spare ? */
+ 	int			need_wait;
+@@ -205,6 +207,8 @@ struct pxa3xx_nand_info {
+ 	unsigned int		fifo_size;	/* max. data size in the FIFO */
+ 	unsigned int		data_size;	/* data to be read from FIFO */
+ 	unsigned int		oob_size;
++	unsigned int		spare_size;
++	unsigned int		ecc_size;
+ 	int 			retcode;
+ 
+ 	/* cached register value */
+@@ -339,19 +343,12 @@ static void pxa3xx_set_datasize(struct p
+ 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
+ 
+ 	info->data_size = info->fifo_size;
+-	if (!oob_enable) {
+-		info->oob_size = 0;
++	if (!oob_enable)
+ 		return;
+-	}
+ 
+-	switch (info->fifo_size) {
+-	case 2048:
+-		info->oob_size = (info->use_ecc) ? 40 : 64;
+-		break;
+-	case 512:
+-		info->oob_size = (info->use_ecc) ? 8 : 16;
+-		break;
+-	}
++	info->oob_size = info->spare_size;
++	if (!info->use_ecc)
++		info->oob_size += info->ecc_size;
+ }
+ 
+ /**
+@@ -366,10 +363,15 @@ static void pxa3xx_nand_start(struct pxa
+ 
+ 	ndcr = info->reg_ndcr;
+ 
+-	if (info->use_ecc)
++	if (info->use_ecc) {
+ 		ndcr |= NDCR_ECC_EN;
+-	else
++		if (info->ecc_bch)
++			nand_writel(info, NDECCCTRL, 0x1);
++	} else {
+ 		ndcr &= ~NDCR_ECC_EN;
++		if (info->ecc_bch)
++			nand_writel(info, NDECCCTRL, 0x0);
++	}
+ 
+ 	if (info->use_dma)
+ 		ndcr |= NDCR_DMA_EN;
+@@ -1071,6 +1073,41 @@ static int pxa3xx_nand_sensing(struct px
+ 	return 0;
+ }
+ 
++static int pxa_ecc_init(struct pxa3xx_nand_info *info,
++			struct nand_ecc_ctrl *ecc,
++			int strength, int page_size)
++{
++	/*
++	 * We don't use strength here as the PXA variant
++	 * is used with non-ONFI compliant devices.
++	 */
++	if (page_size == 2048) {
++		info->spare_size = 40;
++		info->ecc_size = 24;
++		ecc->mode = NAND_ECC_HW;
++		ecc->size = 512;
++		ecc->strength = 1;
++		return 1;
++
++	} else if (page_size == 512) {
++		info->spare_size = 8;
++		info->ecc_size = 8;
++		ecc->mode = NAND_ECC_HW;
++		ecc->size = 512;
++		ecc->strength = 1;
++		return 1;
++	}
++	return 0;
++}
++
++static int armada370_ecc_init(struct pxa3xx_nand_info *info,
++			      struct nand_ecc_ctrl *ecc,
++			      int strength, int page_size)
++{
++	/* Unimplemented yet */
++	return 0;
++}
++
+ static int pxa3xx_nand_scan(struct mtd_info *mtd)
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+@@ -1141,13 +1178,13 @@ static int pxa3xx_nand_scan(struct mtd_i
+ 	pxa3xx_flash_ids[1].name = NULL;
+ 	def = pxa3xx_flash_ids;
+ KEEP_CONFIG:
+-	chip->ecc.mode = NAND_ECC_HW;
+-	chip->ecc.size = info->fifo_size;
+-	chip->ecc.strength = 1;
+-
+ 	if (info->reg_ndcr & NDCR_DWIDTH_M)
+ 		chip->options |= NAND_BUSWIDTH_16;
+ 
++	/* Device detection must be done with ECC disabled */
++	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
++		nand_writel(info, NDECCCTRL, 0x0);
++
+ 	if (nand_scan_ident(mtd, 1, def))
+ 		return -ENODEV;
+ 
+@@ -1162,6 +1199,21 @@ KEEP_CONFIG:
+ 		chip->bbt_md = &bbt_mirror_descr;
+ 	}
+ 
++	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
++		ret = armada370_ecc_init(info, &chip->ecc,
++				   chip->ecc_strength_ds,
++				   mtd->writesize);
++	else
++		ret = pxa_ecc_init(info, &chip->ecc,
++				   chip->ecc_strength_ds,
++				   mtd->writesize);
++	if (!ret) {
++		dev_err(&info->pdev->dev,
++			"ECC strength %d at page size %d is not supported\n",
++			chip->ecc_strength_ds, mtd->writesize);
++		return -ENODEV;
++	}
++
+ 	/* calculate addressing information */
+ 	if (mtd->writesize >= 2048)
+ 		host->col_addr_cycles = 2;
diff --git a/target/linux/mvebu/patches-3.10/0144-mtd-nand-pxa3xx-Clear-cmd-buffer-3-NDCB3-on-command-.patch b/target/linux/mvebu/patches-3.10/0144-mtd-nand-pxa3xx-Clear-cmd-buffer-3-NDCB3-on-command-.patch
new file mode 100644
index 0000000000000000000000000000000000000000..567cc8e1b1750cb0418368129305c3bb91eaf01c
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0144-mtd-nand-pxa3xx-Clear-cmd-buffer-3-NDCB3-on-command-.patch
@@ -0,0 +1,34 @@
+From cb574fecefd9552e5c6c5105adab7b37b0feb712 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:30 -0300
+Subject: [PATCH 144/203] mtd: nand: pxa3xx: Clear cmd buffer #3 (NDCB3) on
+ command start
+
+Command buffer #3 is not properly cleared and it keeps the last
+set value. Fix this by clearing when a command is setup.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -606,6 +606,7 @@ static int prepare_command_pool(struct p
+ 	info->use_ecc		= 0;
+ 	info->use_spare		= 1;
+ 	info->retcode		= ERR_NONE;
++	info->ndcb3		= 0;
+ 	if (info->cs != 0)
+ 		info->ndcb0 = NDCB0_CSEL;
+ 	else
+@@ -627,7 +628,6 @@ static int prepare_command_pool(struct p
+ 	default:
+ 		info->ndcb1 = 0;
+ 		info->ndcb2 = 0;
+-		info->ndcb3 = 0;
+ 		break;
+ 	}
+ 
diff --git a/target/linux/mvebu/patches-3.10/0145-mtd-nand-pxa3xx-Add-helper-function-to-set-page-addr.patch b/target/linux/mvebu/patches-3.10/0145-mtd-nand-pxa3xx-Add-helper-function-to-set-page-addr.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a0a909e09d411e8d4e820be24fea3ab7e297e362
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0145-mtd-nand-pxa3xx-Add-helper-function-to-set-page-addr.patch
@@ -0,0 +1,70 @@
+From 09a84f8e89c3715160423701b0606ef99e2a05bf Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:31 -0300
+Subject: [PATCH 145/203] mtd: nand: pxa3xx: Add helper function to set page
+ address
+
+Let's simplify the code by first introducing a helper function
+to set the page address, as done by the READ0, READOOB and SEQIN
+commands.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 36 +++++++++++++++++++++---------------
+ 1 file changed, 21 insertions(+), 15 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -587,6 +587,26 @@ static inline int is_buf_blank(uint8_t *
+ 	return 1;
+ }
+ 
++static void set_command_address(struct pxa3xx_nand_info *info,
++		unsigned int page_size, uint16_t column, int page_addr)
++{
++	/* small page addr setting */
++	if (page_size < PAGE_CHUNK_SIZE) {
++		info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
++				| (column & 0xFF);
++
++		info->ndcb2 = 0;
++	} else {
++		info->ndcb1 = ((page_addr & 0xFFFF) << 16)
++				| (column & 0xFFFF);
++
++		if (page_addr & 0xFF0000)
++			info->ndcb2 = (page_addr & 0xFF0000) >> 16;
++		else
++			info->ndcb2 = 0;
++	}
++}
++
+ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
+ 		uint16_t column, int page_addr)
+ {
+@@ -650,22 +670,8 @@ static int prepare_command_pool(struct p
+ 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+ 
+ 	case NAND_CMD_SEQIN:
+-		/* small page addr setting */
+-		if (unlikely(mtd->writesize < PAGE_CHUNK_SIZE)) {
+-			info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
+-					| (column & 0xFF);
+-
+-			info->ndcb2 = 0;
+-		} else {
+-			info->ndcb1 = ((page_addr & 0xFFFF) << 16)
+-					| (column & 0xFFFF);
+-
+-			if (page_addr & 0xFF0000)
+-				info->ndcb2 = (page_addr & 0xFF0000) >> 16;
+-			else
+-				info->ndcb2 = 0;
+-		}
+ 
++		set_command_address(info, mtd->writesize, column, page_addr);
+ 		info->buf_count = mtd->writesize + mtd->oobsize;
+ 		memset(info->data_buff, 0xFF, info->buf_count);
+ 
diff --git a/target/linux/mvebu/patches-3.10/0146-mtd-nand-pxa3xx-Remove-READ0-switch-case-falltrough.patch b/target/linux/mvebu/patches-3.10/0146-mtd-nand-pxa3xx-Remove-READ0-switch-case-falltrough.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0631b926b17df2709b751063674c7172b57236d3
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0146-mtd-nand-pxa3xx-Remove-READ0-switch-case-falltrough.patch
@@ -0,0 +1,32 @@
+From 11532c10a29e4faef29b5f3b354391d1e2f90213 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:32 -0300
+Subject: [PATCH 146/203] mtd: nand: pxa3xx: Remove READ0 switch/case
+ falltrough
+
+READ0 and READOOB command preparation has a falltrough to SEQIN
+case, where the command address is specified.
+This is certainly confusing and makes the code less readable with
+no added value. Let's remove it.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -669,6 +669,11 @@ static int prepare_command_pool(struct p
+ 		if (mtd->writesize >= PAGE_CHUNK_SIZE)
+ 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+ 
++		set_command_address(info, mtd->writesize, column, page_addr);
++		info->buf_count = mtd->writesize + mtd->oobsize;
++		memset(info->data_buff, 0xFF, info->buf_count);
++		break;
++
+ 	case NAND_CMD_SEQIN:
+ 
+ 		set_command_address(info, mtd->writesize, column, page_addr);
diff --git a/target/linux/mvebu/patches-3.10/0147-mtd-nand-pxa3xx-Split-prepare_command_pool-in-two-st.patch b/target/linux/mvebu/patches-3.10/0147-mtd-nand-pxa3xx-Split-prepare_command_pool-in-two-st.patch
new file mode 100644
index 0000000000000000000000000000000000000000..aa25c07bb46588f41958da1df5bc9ef9a98e696c
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0147-mtd-nand-pxa3xx-Split-prepare_command_pool-in-two-st.patch
@@ -0,0 +1,101 @@
+From 78c8c8dc7e27c4502504cb4daa07bc9762f54de9 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:33 -0300
+Subject: [PATCH 147/203] mtd: nand: pxa3xx: Split prepare_command_pool() in
+ two stages
+
+This commit splits the prepare_command_pool() function into two
+stages: prepare_start_command() / prepare_set_command().
+
+This is a preparation patch without any functionality changes,
+and is meant to allow support for multiple page reading/writing
+operations.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 44 ++++++++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 19 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -607,18 +607,8 @@ static void set_command_address(struct p
+ 	}
+ }
+ 
+-static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
+-		uint16_t column, int page_addr)
++static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
+ {
+-	int addr_cycle, exec_cmd;
+-	struct pxa3xx_nand_host *host;
+-	struct mtd_info *mtd;
+-
+-	host = info->host[info->cs];
+-	mtd = host->mtd;
+-	addr_cycle = 0;
+-	exec_cmd = 1;
+-
+ 	/* reset data and oob column point to handle data */
+ 	info->buf_start		= 0;
+ 	info->buf_count		= 0;
+@@ -627,10 +617,6 @@ static int prepare_command_pool(struct p
+ 	info->use_spare		= 1;
+ 	info->retcode		= ERR_NONE;
+ 	info->ndcb3		= 0;
+-	if (info->cs != 0)
+-		info->ndcb0 = NDCB0_CSEL;
+-	else
+-		info->ndcb0 = 0;
+ 
+ 	switch (command) {
+ 	case NAND_CMD_READ0:
+@@ -642,14 +628,32 @@ static int prepare_command_pool(struct p
+ 	case NAND_CMD_PARAM:
+ 		info->use_spare = 0;
+ 		break;
+-	case NAND_CMD_SEQIN:
+-		exec_cmd = 0;
+-		break;
+ 	default:
+ 		info->ndcb1 = 0;
+ 		info->ndcb2 = 0;
+ 		break;
+ 	}
++}
++
++static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
++		uint16_t column, int page_addr)
++{
++	int addr_cycle, exec_cmd;
++	struct pxa3xx_nand_host *host;
++	struct mtd_info *mtd;
++
++	host = info->host[info->cs];
++	mtd = host->mtd;
++	addr_cycle = 0;
++	exec_cmd = 1;
++
++	if (info->cs != 0)
++		info->ndcb0 = NDCB0_CSEL;
++	else
++		info->ndcb0 = 0;
++
++	if (command == NAND_CMD_SEQIN)
++		exec_cmd = 0;
+ 
+ 	addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
+ 				    + host->col_addr_cycles);
+@@ -784,8 +788,10 @@ static void pxa3xx_nand_cmdfunc(struct m
+ 		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
+ 	}
+ 
++	prepare_start_command(info, command);
++
+ 	info->state = STATE_PREPARED;
+-	exec_cmd = prepare_command_pool(info, command, column, page_addr);
++	exec_cmd = prepare_set_command(info, command, column, page_addr);
+ 	if (exec_cmd) {
+ 		init_completion(&info->cmd_complete);
+ 		init_completion(&info->dev_ready);
diff --git a/target/linux/mvebu/patches-3.10/0148-mtd-nand-pxa3xx-Move-the-data-buffer-clean-to-prepar.patch b/target/linux/mvebu/patches-3.10/0148-mtd-nand-pxa3xx-Move-the-data-buffer-clean-to-prepar.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3d74844f5ca3fc171b41f88fae6cd73fa558a90a
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0148-mtd-nand-pxa3xx-Move-the-data-buffer-clean-to-prepar.patch
@@ -0,0 +1,69 @@
+From 1c0aed9b4cfb7bb891aab07a429436d017ac4d7c Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:34 -0300
+Subject: [PATCH 148/203] mtd: nand: pxa3xx: Move the data buffer clean to
+ prepare_start_command()
+
+To allow future support of multiple page reading/writing, move the data
+buffer clean out of prepare_set_command().
+
+This is done to prevent the data buffer from being cleaned on every command
+preparation, when a multiple command sequence is implemented to read/write
+pages larger than the FIFO size (2 KiB).
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -609,6 +609,9 @@ static void set_command_address(struct p
+ 
+ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
+ {
++	struct pxa3xx_nand_host *host = info->host[info->cs];
++	struct mtd_info *mtd = host->mtd;
++
+ 	/* reset data and oob column point to handle data */
+ 	info->buf_start		= 0;
+ 	info->buf_count		= 0;
+@@ -633,6 +636,19 @@ static void prepare_start_command(struct
+ 		info->ndcb2 = 0;
+ 		break;
+ 	}
++
++	/*
++	 * If we are about to issue a read command, or about to set
++	 * the write address, then clean the data buffer.
++	 */
++	if (command == NAND_CMD_READ0 ||
++	    command == NAND_CMD_READOOB ||
++	    command == NAND_CMD_SEQIN) {
++
++		info->buf_count = mtd->writesize + mtd->oobsize;
++		memset(info->data_buff, 0xFF, info->buf_count);
++	}
++
+ }
+ 
+ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
+@@ -674,16 +690,11 @@ static int prepare_set_command(struct px
+ 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+ 
+ 		set_command_address(info, mtd->writesize, column, page_addr);
+-		info->buf_count = mtd->writesize + mtd->oobsize;
+-		memset(info->data_buff, 0xFF, info->buf_count);
+ 		break;
+ 
+ 	case NAND_CMD_SEQIN:
+ 
+ 		set_command_address(info, mtd->writesize, column, page_addr);
+-		info->buf_count = mtd->writesize + mtd->oobsize;
+-		memset(info->data_buff, 0xFF, info->buf_count);
+-
+ 		break;
+ 
+ 	case NAND_CMD_PAGEPROG:
diff --git a/target/linux/mvebu/patches-3.10/0149-mtd-nand-pxa3xx-Fix-SEQIN-column-address-set.patch b/target/linux/mvebu/patches-3.10/0149-mtd-nand-pxa3xx-Fix-SEQIN-column-address-set.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cb59ccbd1ce850b50afb6d541e8bb8ff4adef44b
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0149-mtd-nand-pxa3xx-Fix-SEQIN-column-address-set.patch
@@ -0,0 +1,32 @@
+From d5c9b013c71a570737353270f94b9a52639fcea1 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:35 -0300
+Subject: [PATCH 149/203] mtd: nand: pxa3xx: Fix SEQIN column address set
+
+This commit adds support page programming with a non-zero "column"
+address setting. This is important to support OOB writing, through
+command sequences such as:
+
+  cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, ofs);
+  write_buf(mtd, oob_buf, 6);
+  cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -694,7 +694,8 @@ static int prepare_set_command(struct px
+ 
+ 	case NAND_CMD_SEQIN:
+ 
+-		set_command_address(info, mtd->writesize, column, page_addr);
++		info->buf_start = column;
++		set_command_address(info, mtd->writesize, 0, page_addr);
+ 		break;
+ 
+ 	case NAND_CMD_PAGEPROG:
diff --git a/target/linux/mvebu/patches-3.10/0150-mtd-nand-pxa3xx-Add-a-read-write-buffers-markers.patch b/target/linux/mvebu/patches-3.10/0150-mtd-nand-pxa3xx-Add-a-read-write-buffers-markers.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1251f6022af0ffa4065a1b6461dc71bc9bafcec7
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0150-mtd-nand-pxa3xx-Add-a-read-write-buffers-markers.patch
@@ -0,0 +1,111 @@
+From 6e3022aeb5d221af838ad43a2163374aecacf929 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:36 -0300
+Subject: [PATCH 150/203] mtd: nand: pxa3xx: Add a read/write buffers markers
+
+In preparation to support multiple (aka chunked, aka splitted)
+page I/O, this commit adds 'data_buff_pos' and 'oob_buff_pos' fields
+to keep track of where the next read (or write) should be done.
+
+This will allow multiple calls to handle_data_pio() to continue
+the read (or write) operation.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 40 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 29 insertions(+), 11 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -176,6 +176,8 @@ struct pxa3xx_nand_info {
+ 	unsigned int 		buf_start;
+ 	unsigned int		buf_count;
+ 	unsigned int		buf_size;
++	unsigned int		data_buff_pos;
++	unsigned int		oob_buff_pos;
+ 
+ 	/* DMA information */
+ 	int			drcmr_dat;
+@@ -338,11 +340,12 @@ static void pxa3xx_nand_set_timing(struc
+  * spare and ECC configuration.
+  * Only applicable to READ0, READOOB and PAGEPROG commands.
+  */
+-static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
++static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info,
++				struct mtd_info *mtd)
+ {
+ 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
+ 
+-	info->data_size = info->fifo_size;
++	info->data_size = mtd->writesize;
+ 	if (!oob_enable)
+ 		return;
+ 
+@@ -430,26 +433,39 @@ static void disable_int(struct pxa3xx_na
+ 
+ static void handle_data_pio(struct pxa3xx_nand_info *info)
+ {
++	unsigned int do_bytes = min(info->data_size, info->fifo_size);
++
+ 	switch (info->state) {
+ 	case STATE_PIO_WRITING:
+-		__raw_writesl(info->mmio_base + NDDB, info->data_buff,
+-				DIV_ROUND_UP(info->data_size, 4));
++		__raw_writesl(info->mmio_base + NDDB,
++			      info->data_buff + info->data_buff_pos,
++			      DIV_ROUND_UP(do_bytes, 4));
++
+ 		if (info->oob_size > 0)
+-			__raw_writesl(info->mmio_base + NDDB, info->oob_buff,
+-					DIV_ROUND_UP(info->oob_size, 4));
++			__raw_writesl(info->mmio_base + NDDB,
++				      info->oob_buff + info->oob_buff_pos,
++				      DIV_ROUND_UP(info->oob_size, 4));
+ 		break;
+ 	case STATE_PIO_READING:
+-		__raw_readsl(info->mmio_base + NDDB, info->data_buff,
+-				DIV_ROUND_UP(info->data_size, 4));
++		__raw_readsl(info->mmio_base + NDDB,
++			     info->data_buff + info->data_buff_pos,
++			     DIV_ROUND_UP(do_bytes, 4));
++
+ 		if (info->oob_size > 0)
+-			__raw_readsl(info->mmio_base + NDDB, info->oob_buff,
+-					DIV_ROUND_UP(info->oob_size, 4));
++			__raw_readsl(info->mmio_base + NDDB,
++				     info->oob_buff + info->oob_buff_pos,
++				     DIV_ROUND_UP(info->oob_size, 4));
+ 		break;
+ 	default:
+ 		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
+ 				info->state);
+ 		BUG();
+ 	}
++
++	/* Update buffer pointers for multi-page read/write */
++	info->data_buff_pos += do_bytes;
++	info->oob_buff_pos += info->oob_size;
++	info->data_size -= do_bytes;
+ }
+ 
+ #ifdef ARCH_HAS_DMA
+@@ -616,6 +632,8 @@ static void prepare_start_command(struct
+ 	info->buf_start		= 0;
+ 	info->buf_count		= 0;
+ 	info->oob_size		= 0;
++	info->data_buff_pos	= 0;
++	info->oob_buff_pos	= 0;
+ 	info->use_ecc		= 0;
+ 	info->use_spare		= 1;
+ 	info->retcode		= ERR_NONE;
+@@ -626,7 +644,7 @@ static void prepare_start_command(struct
+ 	case NAND_CMD_PAGEPROG:
+ 		info->use_ecc = 1;
+ 	case NAND_CMD_READOOB:
+-		pxa3xx_set_datasize(info);
++		pxa3xx_set_datasize(info, mtd);
+ 		break;
+ 	case NAND_CMD_PARAM:
+ 		info->use_spare = 0;
diff --git a/target/linux/mvebu/patches-3.10/0151-mtd-nand-pxa3xx-Introduce-multiple-page-I-O-support.patch b/target/linux/mvebu/patches-3.10/0151-mtd-nand-pxa3xx-Introduce-multiple-page-I-O-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f8e3c8796d3a2fd7de0f48c0b1786be634f4d612
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0151-mtd-nand-pxa3xx-Introduce-multiple-page-I-O-support.patch
@@ -0,0 +1,325 @@
+From cfd1799f9ec5c9820f371e1fcf2f3c458bd24ebb Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:37 -0300
+Subject: [PATCH 151/203] mtd: nand: pxa3xx: Introduce multiple page I/O
+ support
+
+As preparation work to fully support large pages, this commit adds
+the initial infrastructure to support splitted (aka chunked) I/O
+operation. This commit adds support for read, and follow-up patches
+will add write support.
+
+When a read (aka READ0) command is issued, the driver loops issuing
+the same command until all the requested data is transfered, changing
+the 'extended' command field as needed.
+
+For instance, if the driver is required to read a 4 KiB page, using a
+chunk size of 2 KiB, the transaction is splitted in:
+1. Monolithic read, first 2 KiB page chunk is read
+2. Last naked read, second and last 2KiB page chunk is read
+
+If ECC is enabled it is calculated on each chunk transfered and added
+at a controller-fixed location after the data chunk that must be
+spare area.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 182 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 172 insertions(+), 10 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -103,6 +103,8 @@
+ #define NDCB0_ST_ROW_EN         (0x1 << 26)
+ #define NDCB0_AUTO_RS		(0x1 << 25)
+ #define NDCB0_CSEL		(0x1 << 24)
++#define NDCB0_EXT_CMD_TYPE_MASK	(0x7 << 29)
++#define NDCB0_EXT_CMD_TYPE(x)	(((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
+ #define NDCB0_CMD_TYPE_MASK	(0x7 << 21)
+ #define NDCB0_CMD_TYPE(x)	(((x) << 21) & NDCB0_CMD_TYPE_MASK)
+ #define NDCB0_NC		(0x1 << 20)
+@@ -113,6 +115,14 @@
+ #define NDCB0_CMD1_MASK		(0xff)
+ #define NDCB0_ADDR_CYC_SHIFT	(16)
+ 
++#define EXT_CMD_TYPE_DISPATCH	6 /* Command dispatch */
++#define EXT_CMD_TYPE_NAKED_RW	5 /* Naked read or Naked write */
++#define EXT_CMD_TYPE_READ	4 /* Read */
++#define EXT_CMD_TYPE_DISP_WR	4 /* Command dispatch with write */
++#define EXT_CMD_TYPE_FINAL	3 /* Final command */
++#define EXT_CMD_TYPE_LAST_RW	1 /* Last naked read/write */
++#define EXT_CMD_TYPE_MONO	0 /* Monolithic read/write */
++
+ /* macros for registers read/write */
+ #define nand_writel(info, off, val)	\
+ 	__raw_writel((val), (info)->mmio_base + (off))
+@@ -206,8 +216,8 @@ struct pxa3xx_nand_info {
+ 	int			use_spare;	/* use spare ? */
+ 	int			need_wait;
+ 
+-	unsigned int		fifo_size;	/* max. data size in the FIFO */
+ 	unsigned int		data_size;	/* data to be read from FIFO */
++	unsigned int		chunk_size;	/* split commands chunk size */
+ 	unsigned int		oob_size;
+ 	unsigned int		spare_size;
+ 	unsigned int		ecc_size;
+@@ -271,6 +281,31 @@ static struct nand_bbt_descr bbt_mirror_
+ 	.pattern = bbt_mirror_pattern
+ };
+ 
++static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
++	.eccbytes = 64,
++	.eccpos = {
++		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,
++		96,  97,  98,  99,  100, 101, 102, 103,
++		104, 105, 106, 107, 108, 109, 110, 111,
++		112, 113, 114, 115, 116, 117, 118, 119,
++		120, 121, 122, 123, 124, 125, 126, 127},
++	/* Bootrom looks in bytes 0 & 5 for bad blocks */
++	.oobfree = { {6, 26}, { 64, 32} }
++};
++
++static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
++	.eccbytes = 128,
++	.eccpos = {
++		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 = { }
++};
++
+ /* Define a default flash type setting serve as flash detecting only */
+ #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
+ 
+@@ -433,7 +468,7 @@ static void disable_int(struct pxa3xx_na
+ 
+ static void handle_data_pio(struct pxa3xx_nand_info *info)
+ {
+-	unsigned int do_bytes = min(info->data_size, info->fifo_size);
++	unsigned int do_bytes = min(info->data_size, info->chunk_size);
+ 
+ 	switch (info->state) {
+ 	case STATE_PIO_WRITING:
+@@ -670,7 +705,7 @@ static void prepare_start_command(struct
+ }
+ 
+ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
+-		uint16_t column, int page_addr)
++		int ext_cmd_type, uint16_t column, int page_addr)
+ {
+ 	int addr_cycle, exec_cmd;
+ 	struct pxa3xx_nand_host *host;
+@@ -703,9 +738,20 @@ static int prepare_set_command(struct px
+ 		if (command == NAND_CMD_READOOB)
+ 			info->buf_start += mtd->writesize;
+ 
+-		/* Second command setting for large pages */
+-		if (mtd->writesize >= PAGE_CHUNK_SIZE)
++		/*
++		 * Multiple page read needs an 'extended command type' field,
++		 * which is either naked-read or last-read according to the
++		 * state.
++		 */
++		if (mtd->writesize == PAGE_CHUNK_SIZE) {
+ 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
++		} else if (mtd->writesize > PAGE_CHUNK_SIZE) {
++			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
++					| NDCB0_LEN_OVRD
++					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
++			info->ndcb3 = info->chunk_size +
++				      info->oob_size;
++		}
+ 
+ 		set_command_address(info, mtd->writesize, column, page_addr);
+ 		break;
+@@ -821,7 +867,8 @@ static void pxa3xx_nand_cmdfunc(struct m
+ 	prepare_start_command(info, command);
+ 
+ 	info->state = STATE_PREPARED;
+-	exec_cmd = prepare_set_command(info, command, column, page_addr);
++	exec_cmd = prepare_set_command(info, command, 0, column, page_addr);
++
+ 	if (exec_cmd) {
+ 		init_completion(&info->cmd_complete);
+ 		init_completion(&info->dev_ready);
+@@ -839,6 +886,93 @@ static void pxa3xx_nand_cmdfunc(struct m
+ 	info->state = STATE_IDLE;
+ }
+ 
++static void armada370_nand_cmdfunc(struct mtd_info *mtd,
++				   const unsigned command,
++				   int column, int page_addr)
++{
++	struct pxa3xx_nand_host *host = mtd->priv;
++	struct pxa3xx_nand_info *info = host->info_data;
++	int ret, exec_cmd, ext_cmd_type;
++
++	/*
++	 * if this is a x16 device then convert the input
++	 * "byte" address into a "word" address appropriate
++	 * for indexing a word-oriented device
++	 */
++	if (info->reg_ndcr & NDCR_DWIDTH_M)
++		column /= 2;
++
++	/*
++	 * There may be different NAND chip hooked to
++	 * different chip select, so check whether
++	 * chip select has been changed, if yes, reset the timing
++	 */
++	if (info->cs != host->cs) {
++		info->cs = host->cs;
++		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
++		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
++	}
++
++	/* Select the extended command for the first command */
++	switch (command) {
++	case NAND_CMD_READ0:
++	case NAND_CMD_READOOB:
++		ext_cmd_type = EXT_CMD_TYPE_MONO;
++		break;
++	default:
++		ext_cmd_type = 0;
++	}
++
++	prepare_start_command(info, command);
++
++	/*
++	 * Prepare the "is ready" completion before starting a command
++	 * transaction sequence. If the command is not executed the
++	 * completion will be completed, see below.
++	 *
++	 * We can do that inside the loop because the command variable
++	 * is invariant and thus so is the exec_cmd.
++	 */
++	info->need_wait = 1;
++	init_completion(&info->dev_ready);
++	do {
++		info->state = STATE_PREPARED;
++		exec_cmd = prepare_set_command(info, command, ext_cmd_type,
++					       column, page_addr);
++		if (!exec_cmd) {
++			info->need_wait = 0;
++			complete(&info->dev_ready);
++			break;
++		}
++
++		init_completion(&info->cmd_complete);
++		pxa3xx_nand_start(info);
++
++		ret = wait_for_completion_timeout(&info->cmd_complete,
++				CHIP_DELAY_TIMEOUT);
++		if (!ret) {
++			dev_err(&info->pdev->dev, "Wait time out!!!\n");
++			/* Stop State Machine for next command cycle */
++			pxa3xx_nand_stop(info);
++			break;
++		}
++
++		/* Check if the sequence is complete */
++		if (info->data_size == 0)
++			break;
++
++		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
++			/* Last read: issue a 'last naked read' */
++			if (info->data_size == info->chunk_size)
++				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
++			else
++				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
++		}
++	} while (1);
++
++	info->state = STATE_IDLE;
++}
++
+ static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
+ 		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+ {
+@@ -1019,13 +1153,14 @@ static int pxa3xx_nand_detect_config(str
+ 
+ 	if (ndcr & NDCR_PAGE_SZ) {
+ 		/* Controller's FIFO size */
+-		info->fifo_size = 2048;
++		info->chunk_size = 2048;
+ 		host->read_id_bytes = 4;
+ 	} else {
+-		info->fifo_size = 512;
++		info->chunk_size = 512;
+ 		host->read_id_bytes = 2;
+ 	}
+ 
++	/* Set an initial chunk size */
+ 	info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
+ 	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
+ 	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
+@@ -1129,6 +1264,7 @@ static int pxa_ecc_init(struct pxa3xx_na
+ 	 * is used with non-ONFI compliant devices.
+ 	 */
+ 	if (page_size == 2048) {
++		info->chunk_size = 2048;
+ 		info->spare_size = 40;
+ 		info->ecc_size = 24;
+ 		ecc->mode = NAND_ECC_HW;
+@@ -1137,6 +1273,7 @@ static int pxa_ecc_init(struct pxa3xx_na
+ 		return 1;
+ 
+ 	} else if (page_size == 512) {
++		info->chunk_size = 512;
+ 		info->spare_size = 8;
+ 		info->ecc_size = 8;
+ 		ecc->mode = NAND_ECC_HW;
+@@ -1151,7 +1288,28 @@ static int armada370_ecc_init(struct pxa
+ 			      struct nand_ecc_ctrl *ecc,
+ 			      int strength, int page_size)
+ {
+-	/* Unimplemented yet */
++	if (strength == 4 && page_size == 4096) {
++		info->ecc_bch = 1;
++		info->chunk_size = 2048;
++		info->spare_size = 32;
++		info->ecc_size = 32;
++		ecc->mode = NAND_ECC_HW;
++		ecc->size = info->chunk_size;
++		ecc->layout = &ecc_layout_4KB_bch4bit;
++		ecc->strength = 16;
++		return 1;
++
++	} else if (strength == 8 && page_size == 4096) {
++		info->ecc_bch = 1;
++		info->chunk_size = 1024;
++		info->spare_size = 0;
++		info->ecc_size = 32;
++		ecc->mode = NAND_ECC_HW;
++		ecc->size = info->chunk_size;
++		ecc->layout = &ecc_layout_4KB_bch8bit;
++		ecc->strength = 16;
++		return 1;
++	}
+ 	return 0;
+ }
+ 
+@@ -1319,12 +1477,16 @@ static int alloc_nand_resource(struct pl
+ 		chip->controller        = &info->controller;
+ 		chip->waitfunc		= pxa3xx_nand_waitfunc;
+ 		chip->select_chip	= pxa3xx_nand_select_chip;
+-		chip->cmdfunc		= pxa3xx_nand_cmdfunc;
+ 		chip->read_word		= pxa3xx_nand_read_word;
+ 		chip->read_byte		= pxa3xx_nand_read_byte;
+ 		chip->read_buf		= pxa3xx_nand_read_buf;
+ 		chip->write_buf		= pxa3xx_nand_write_buf;
+ 		chip->options		|= NAND_NO_SUBPAGE_WRITE;
++
++		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
++			chip->cmdfunc = armada370_nand_cmdfunc;
++		else
++			chip->cmdfunc = pxa3xx_nand_cmdfunc;
+ 	}
+ 
+ 	spin_lock_init(&chip->controller->lock);
diff --git a/target/linux/mvebu/patches-3.10/0152-mtd-nand-pxa3xx-Add-multiple-chunk-write-support.patch b/target/linux/mvebu/patches-3.10/0152-mtd-nand-pxa3xx-Add-multiple-chunk-write-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..058dc0bc3c4a2c498f61314d3b3dacd01278ae80
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0152-mtd-nand-pxa3xx-Add-multiple-chunk-write-support.patch
@@ -0,0 +1,146 @@
+From db95c66cebb6297595a5a32b369d1033b08775ce Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:38 -0300
+Subject: [PATCH 152/203] mtd: nand: pxa3xx: Add multiple chunk write support
+
+This commit adds write support for large pages (4 KiB, 8 KiB).
+Such support is implemented by issuing a multiple command sequence,
+transfering a set of 2 KiB chunks per transaction.
+
+The splitted command sequence requires to send the SEQIN command
+independently of the PAGEPROG command and therefore it's set as
+an execution command.
+
+Since PAGEPROG enables ECC, each 2 KiB chunk of data is written
+together with ECC code at a controller-fixed location within
+the flash page.
+
+Currently, only devices with a 4 KiB page size has been tested.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 81 +++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 73 insertions(+), 8 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -760,6 +760,20 @@ static int prepare_set_command(struct px
+ 
+ 		info->buf_start = column;
+ 		set_command_address(info, mtd->writesize, 0, page_addr);
++
++		/*
++		 * Multiple page programming needs to execute the initial
++		 * SEQIN command that sets the page address.
++		 */
++		if (mtd->writesize > PAGE_CHUNK_SIZE) {
++			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
++				| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
++				| addr_cycle
++				| command;
++			/* No data transfer in this case */
++			info->data_size = 0;
++			exec_cmd = 1;
++		}
+ 		break;
+ 
+ 	case NAND_CMD_PAGEPROG:
+@@ -769,13 +783,40 @@ static int prepare_set_command(struct px
+ 			break;
+ 		}
+ 
+-		info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+-				| NDCB0_AUTO_RS
+-				| NDCB0_ST_ROW_EN
+-				| NDCB0_DBC
+-				| (NAND_CMD_PAGEPROG << 8)
+-				| NAND_CMD_SEQIN
+-				| addr_cycle;
++		/* Second command setting for large pages */
++		if (mtd->writesize > PAGE_CHUNK_SIZE) {
++			/*
++			 * Multiple page write uses the 'extended command'
++			 * field. This can be used to issue a command dispatch
++			 * or a naked-write depending on the current stage.
++			 */
++			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
++					| NDCB0_LEN_OVRD
++					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
++			info->ndcb3 = info->chunk_size +
++				      info->oob_size;
++
++			/*
++			 * This is the command dispatch that completes a chunked
++			 * page program operation.
++			 */
++			if (info->data_size == 0) {
++				info->ndcb0 = NDCB0_CMD_TYPE(0x1)
++					| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
++					| command;
++				info->ndcb1 = 0;
++				info->ndcb2 = 0;
++				info->ndcb3 = 0;
++			}
++		} else {
++			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
++					| NDCB0_AUTO_RS
++					| NDCB0_ST_ROW_EN
++					| NDCB0_DBC
++					| (NAND_CMD_PAGEPROG << 8)
++					| NAND_CMD_SEQIN
++					| addr_cycle;
++		}
+ 		break;
+ 
+ 	case NAND_CMD_PARAM:
+@@ -919,8 +960,15 @@ static void armada370_nand_cmdfunc(struc
+ 	case NAND_CMD_READOOB:
+ 		ext_cmd_type = EXT_CMD_TYPE_MONO;
+ 		break;
++	case NAND_CMD_SEQIN:
++		ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
++		break;
++	case NAND_CMD_PAGEPROG:
++		ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
++		break;
+ 	default:
+ 		ext_cmd_type = 0;
++		break;
+ 	}
+ 
+ 	prepare_start_command(info, command);
+@@ -958,7 +1006,16 @@ static void armada370_nand_cmdfunc(struc
+ 		}
+ 
+ 		/* Check if the sequence is complete */
+-		if (info->data_size == 0)
++		if (info->data_size == 0 && command != NAND_CMD_PAGEPROG)
++			break;
++
++		/*
++		 * After a splitted program command sequence has issued
++		 * the command dispatch, the command sequence is complete.
++		 */
++		if (info->data_size == 0 &&
++		    command == NAND_CMD_PAGEPROG &&
++		    ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
+ 			break;
+ 
+ 		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
+@@ -967,6 +1024,14 @@ static void armada370_nand_cmdfunc(struc
+ 				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
+ 			else
+ 				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
++
++		/*
++		 * If a splitted program command has no more data to transfer,
++		 * the command dispatch must be issued to complete.
++		 */
++		} else if (command == NAND_CMD_PAGEPROG &&
++			   info->data_size == 0) {
++				ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
+ 		}
+ 	} while (1);
+ 
diff --git a/target/linux/mvebu/patches-3.10/0153-mtd-nand-pxa3xx-Add-ECC-BCH-correctable-errors-detec.patch b/target/linux/mvebu/patches-3.10/0153-mtd-nand-pxa3xx-Add-ECC-BCH-correctable-errors-detec.patch
new file mode 100644
index 0000000000000000000000000000000000000000..fa68e5b033c0e56e42907f4011f42cf0aba651ee
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0153-mtd-nand-pxa3xx-Add-ECC-BCH-correctable-errors-detec.patch
@@ -0,0 +1,144 @@
+From 26d82e0081aa6f0c7db5e4bb5b154b7c528cb8d6 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 14 Nov 2013 18:25:39 -0300
+Subject: [PATCH 153/203] mtd: nand: pxa3xx: Add ECC BCH correctable errors
+ detection
+
+This commit extends the ECC correctable error detection to include
+ECC BCH errors. The number of BCH correctable errors can be any up to 16,
+and the actual value is exposed in the NDSR register.
+
+Therefore, we change some symbol names to refer to correctable or
+uncorrectable (instead of single-bit or double-bit as it was in the
+Hamming case) and while at it, cleanup the detection code slightly.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 57 ++++++++++++++++++++++++++----------------
+ 1 file changed, 35 insertions(+), 22 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -85,6 +85,9 @@
+ #define NDCR_INT_MASK           (0xFFF)
+ 
+ #define NDSR_MASK		(0xfff)
++#define NDSR_ERR_CNT_OFF	(16)
++#define NDSR_ERR_CNT_MASK       (0x1f)
++#define NDSR_ERR_CNT(sr)	((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
+ #define NDSR_RDY                (0x1 << 12)
+ #define NDSR_FLASH_RDY          (0x1 << 11)
+ #define NDSR_CS0_PAGED		(0x1 << 10)
+@@ -93,8 +96,8 @@
+ #define NDSR_CS1_CMDD		(0x1 << 7)
+ #define NDSR_CS0_BBD		(0x1 << 6)
+ #define NDSR_CS1_BBD		(0x1 << 5)
+-#define NDSR_DBERR		(0x1 << 4)
+-#define NDSR_SBERR		(0x1 << 3)
++#define NDSR_UNCORERR		(0x1 << 4)
++#define NDSR_CORERR		(0x1 << 3)
+ #define NDSR_WRDREQ		(0x1 << 2)
+ #define NDSR_RDDREQ		(0x1 << 1)
+ #define NDSR_WRCMDREQ		(0x1)
+@@ -135,9 +138,9 @@ enum {
+ 	ERR_NONE	= 0,
+ 	ERR_DMABUSERR	= -1,
+ 	ERR_SENDCMD	= -2,
+-	ERR_DBERR	= -3,
++	ERR_UNCORERR	= -3,
+ 	ERR_BBERR	= -4,
+-	ERR_SBERR	= -5,
++	ERR_CORERR	= -5,
+ };
+ 
+ enum {
+@@ -221,6 +224,8 @@ struct pxa3xx_nand_info {
+ 	unsigned int		oob_size;
+ 	unsigned int		spare_size;
+ 	unsigned int		ecc_size;
++	unsigned int		ecc_err_cnt;
++	unsigned int		max_bitflips;
+ 	int 			retcode;
+ 
+ 	/* cached register value */
+@@ -571,10 +576,25 @@ static irqreturn_t pxa3xx_nand_irq(int i
+ 
+ 	status = nand_readl(info, NDSR);
+ 
+-	if (status & NDSR_DBERR)
+-		info->retcode = ERR_DBERR;
+-	if (status & NDSR_SBERR)
+-		info->retcode = ERR_SBERR;
++	if (status & NDSR_UNCORERR)
++		info->retcode = ERR_UNCORERR;
++	if (status & NDSR_CORERR) {
++		info->retcode = ERR_CORERR;
++		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
++		    info->ecc_bch)
++			info->ecc_err_cnt = NDSR_ERR_CNT(status);
++		else
++			info->ecc_err_cnt = 1;
++
++		/*
++		 * Each chunk composing a page is corrected independently,
++		 * and we need to store maximum number of corrected bitflips
++		 * to return it to the MTD layer in ecc.read_page().
++		 */
++		info->max_bitflips = max_t(unsigned int,
++					   info->max_bitflips,
++					   info->ecc_err_cnt);
++	}
+ 	if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
+ 		/* whether use dma to transfer data */
+ 		if (info->use_dma) {
+@@ -672,6 +692,7 @@ static void prepare_start_command(struct
+ 	info->use_ecc		= 0;
+ 	info->use_spare		= 1;
+ 	info->retcode		= ERR_NONE;
++	info->ecc_err_cnt	= 0;
+ 	info->ndcb3		= 0;
+ 
+ 	switch (command) {
+@@ -1053,26 +1074,18 @@ static int pxa3xx_nand_read_page_hwecc(s
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+ 	struct pxa3xx_nand_info *info = host->info_data;
+-	int max_bitflips = 0;
+ 
+ 	chip->read_buf(mtd, buf, mtd->writesize);
+ 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+ 
+-	if (info->retcode == ERR_SBERR) {
+-		switch (info->use_ecc) {
+-		case 1:
+-			max_bitflips = 1;
+-			mtd->ecc_stats.corrected++;
+-			break;
+-		case 0:
+-		default:
+-			break;
+-		}
+-	} else if (info->retcode == ERR_DBERR) {
++	if (info->retcode == ERR_CORERR && info->use_ecc) {
++		mtd->ecc_stats.corrected += info->ecc_err_cnt;
++
++	} else if (info->retcode == ERR_UNCORERR) {
+ 		/*
+ 		 * for blank page (all 0xff), HW will calculate its ECC as
+ 		 * 0, which is different from the ECC information within
+-		 * OOB, ignore such double bit errors
++		 * OOB, ignore such uncorrectable errors
+ 		 */
+ 		if (is_buf_blank(buf, mtd->writesize))
+ 			info->retcode = ERR_NONE;
+@@ -1080,7 +1093,7 @@ static int pxa3xx_nand_read_page_hwecc(s
+ 			mtd->ecc_stats.failed++;
+ 	}
+ 
+-	return max_bitflips;
++	return info->max_bitflips;
+ }
+ 
+ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd)
diff --git a/target/linux/mvebu/patches-3.10/0154-mtd-nand-pxa3xx-make-ECC-configuration-checks-more-e.patch b/target/linux/mvebu/patches-3.10/0154-mtd-nand-pxa3xx-make-ECC-configuration-checks-more-e.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8d9d21ac0a4b0c2b603ab1dc69d67eea1198fe16
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0154-mtd-nand-pxa3xx-make-ECC-configuration-checks-more-e.patch
@@ -0,0 +1,67 @@
+From c312e183e96bed3b727888673d4b6b54b8e6283e Mon Sep 17 00:00:00 2001
+From: Brian Norris <computersforpeace@gmail.com>
+Date: Thu, 14 Nov 2013 14:41:32 -0800
+Subject: [PATCH 154/203] mtd: nand: pxa3xx: make ECC configuration checks more
+ explicit
+
+The Armada BCH configuration in this driver uses one of the two
+following ECC schemes:
+
+ 16-bit correction per 2048 bytes
+ 16-bit correction per 1024 bytes
+
+These are sufficient for mapping to the 4-bit per 512-bytes and 8-bit
+per 512-bytes (respectively) minimum correctability requirements of many
+common NAND.
+
+The current code only checks for the required strength (4-bit or 8-bit)
+without checking the ECC step size that is associated with that strength
+(and simply assumes it is 512). While that is often a safe assumption to
+make, let's make it explicit, since we have that information.
+
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Acked-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1364,9 +1364,13 @@ static int pxa_ecc_init(struct pxa3xx_na
+ 
+ static int armada370_ecc_init(struct pxa3xx_nand_info *info,
+ 			      struct nand_ecc_ctrl *ecc,
+-			      int strength, int page_size)
++			      int strength, int ecc_stepsize, int page_size)
+ {
+-	if (strength == 4 && page_size == 4096) {
++	/*
++	 * Required ECC: 4-bit correction per 512 bytes
++	 * Select: 16-bit correction per 2048 bytes
++	 */
++	if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
+ 		info->ecc_bch = 1;
+ 		info->chunk_size = 2048;
+ 		info->spare_size = 32;
+@@ -1377,7 +1381,11 @@ static int armada370_ecc_init(struct pxa
+ 		ecc->strength = 16;
+ 		return 1;
+ 
+-	} else if (strength == 8 && page_size == 4096) {
++	/*
++	 * Required ECC: 8-bit correction per 512 bytes
++	 * Select: 16-bit correction per 1024 bytes
++	 */
++	} else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
+ 		info->ecc_bch = 1;
+ 		info->chunk_size = 1024;
+ 		info->spare_size = 0;
+@@ -1485,6 +1493,7 @@ KEEP_CONFIG:
+ 	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+ 		ret = armada370_ecc_init(info, &chip->ecc,
+ 				   chip->ecc_strength_ds,
++				   chip->ecc_step_ds,
+ 				   mtd->writesize);
+ 	else
+ 		ret = pxa_ecc_init(info, &chip->ecc,
diff --git a/target/linux/mvebu/patches-3.10/0155-mtd-nand-pxa3xx-Use-info-use_dma-to-release-DMA-reso.patch b/target/linux/mvebu/patches-3.10/0155-mtd-nand-pxa3xx-Use-info-use_dma-to-release-DMA-reso.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d86cc9bf85afd0be90a8fac74e6da0895565ec7a
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0155-mtd-nand-pxa3xx-Use-info-use_dma-to-release-DMA-reso.patch
@@ -0,0 +1,29 @@
+From 4c6bade4cf80d77decc5ea89fbaadff8b008f5e9 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Mon, 25 Nov 2013 12:35:28 -0300
+Subject: [PATCH 155/203] mtd: nand: pxa3xx: Use info->use_dma to release DMA
+ resources
+
+After the driver allocates all DMA resources, it sets "info->use_dma".
+Therefore, we need to check that variable to decide which resources
+needs to be freed, instead of the global use_dma variable.
+
+Without this change, when the device probe fails, the driver will try
+to release unallocated DMA resources, with nasty results.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1288,7 +1288,7 @@ static int pxa3xx_nand_init_buff(struct
+ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
+ {
+ 	struct platform_device *pdev = info->pdev;
+-	if (use_dma) {
++	if (info->use_dma) {
+ 		pxa_free_dma(info->data_dma_ch);
+ 		dma_free_coherent(&pdev->dev, info->buf_size,
+ 				  info->data_buff, info->data_buff_phys);
diff --git a/target/linux/mvebu/patches-3.10/0156-mtd-nand-pxa3xx-Use-extended-cmdfunc-only-if-needed.patch b/target/linux/mvebu/patches-3.10/0156-mtd-nand-pxa3xx-Use-extended-cmdfunc-only-if-needed.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7b14da8cea91b6ba30145a9e847139820426308b
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0156-mtd-nand-pxa3xx-Use-extended-cmdfunc-only-if-needed.patch
@@ -0,0 +1,89 @@
+From a701d8e1c4c1e31a208dae616ed9067ba4e90191 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Mon, 25 Nov 2013 11:02:51 -0300
+Subject: [PATCH 156/203] mtd: nand: pxa3xx: Use extended cmdfunc() only if
+ needed
+
+Currently, we have two different cmdfunc's implementations:
+one for PXA3xx SoC variant and one for Armada 370/XP SoC variant.
+
+The former is the legacy one, typically constrained to devices
+with page sizes smaller or equal to the controller's FIFO buffer.
+On the other side, the latter _only_ supports the so-called extended
+command semantics, which allow to handle devices with larger
+page sizes (4 KiB, 8 KiB, ...).
+
+This means we currently don't support devices with smaller pages on the
+A370/XP SoC. Fix it by first renaming the cmdfuncs variants, and then
+make the choice based on device page size (and SoC variant), rather than
+SoC variant alone.
+
+While at it, add a check for page size, to make sure we don't allow larger
+pages sizes on the PXA3xx variant.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 31 +++++++++++++++++++++----------
+ 1 file changed, 21 insertions(+), 10 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -900,8 +900,8 @@ static int prepare_set_command(struct px
+ 	return exec_cmd;
+ }
+ 
+-static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
+-				int column, int page_addr)
++static void nand_cmdfunc(struct mtd_info *mtd, unsigned command,
++			 int column, int page_addr)
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+ 	struct pxa3xx_nand_info *info = host->info_data;
+@@ -948,9 +948,9 @@ static void pxa3xx_nand_cmdfunc(struct m
+ 	info->state = STATE_IDLE;
+ }
+ 
+-static void armada370_nand_cmdfunc(struct mtd_info *mtd,
+-				   const unsigned command,
+-				   int column, int page_addr)
++static void nand_cmdfunc_extended(struct mtd_info *mtd,
++				  const unsigned command,
++				  int column, int page_addr)
+ {
+ 	struct pxa3xx_nand_host *host = mtd->priv;
+ 	struct pxa3xx_nand_info *info = host->info_data;
+@@ -1490,6 +1490,21 @@ KEEP_CONFIG:
+ 		chip->bbt_md = &bbt_mirror_descr;
+ 	}
+ 
++	/*
++	 * If the page size is bigger than the FIFO size, let's check
++	 * we are given the right variant and then switch to the extended
++	 * (aka splitted) command handling,
++	 */
++	if (mtd->writesize > PAGE_CHUNK_SIZE) {
++		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) {
++			chip->cmdfunc = nand_cmdfunc_extended;
++		} else {
++			dev_err(&info->pdev->dev,
++				"unsupported page size on this variant\n");
++			return -ENODEV;
++		}
++	}
++
+ 	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+ 		ret = armada370_ecc_init(info, &chip->ecc,
+ 				   chip->ecc_strength_ds,
+@@ -1569,11 +1584,7 @@ static int alloc_nand_resource(struct pl
+ 		chip->read_buf		= pxa3xx_nand_read_buf;
+ 		chip->write_buf		= pxa3xx_nand_write_buf;
+ 		chip->options		|= NAND_NO_SUBPAGE_WRITE;
+-
+-		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+-			chip->cmdfunc = armada370_nand_cmdfunc;
+-		else
+-			chip->cmdfunc = pxa3xx_nand_cmdfunc;
++		chip->cmdfunc		= nand_cmdfunc;
+ 	}
+ 
+ 	spin_lock_init(&chip->controller->lock);
diff --git a/target/linux/mvebu/patches-3.10/0157-mtd-nand-pxa3xx-Consolidate-ECC-initialization.patch b/target/linux/mvebu/patches-3.10/0157-mtd-nand-pxa3xx-Consolidate-ECC-initialization.patch
new file mode 100644
index 0000000000000000000000000000000000000000..28ec7d8897fa17b46a097248fee46fb85284d750
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0157-mtd-nand-pxa3xx-Consolidate-ECC-initialization.patch
@@ -0,0 +1,100 @@
+From 70c36de37f357f38b5a56292534133d75e7d8870 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Mon, 25 Nov 2013 12:36:18 -0300
+Subject: [PATCH 157/203] mtd: nand: pxa3xx: Consolidate ECC initialization
+
+In order to avoid code duplication, let's consolidate the ECC setting
+for all SoC variants. Such decision is based on page size and ECC
+strength requirements.
+
+Also, provide a default value for the case where such ECC information
+is not provided (non-ONFI devices).
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 40 ++++++++++++++++------------------------
+ 1 file changed, 16 insertions(+), 24 deletions(-)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -1335,13 +1335,9 @@ static int pxa3xx_nand_sensing(struct px
+ 
+ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
+ 			struct nand_ecc_ctrl *ecc,
+-			int strength, int page_size)
++			int strength, int ecc_stepsize, int page_size)
+ {
+-	/*
+-	 * We don't use strength here as the PXA variant
+-	 * is used with non-ONFI compliant devices.
+-	 */
+-	if (page_size == 2048) {
++	if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
+ 		info->chunk_size = 2048;
+ 		info->spare_size = 40;
+ 		info->ecc_size = 24;
+@@ -1350,7 +1346,7 @@ static int pxa_ecc_init(struct pxa3xx_na
+ 		ecc->strength = 1;
+ 		return 1;
+ 
+-	} else if (page_size == 512) {
++	} else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
+ 		info->chunk_size = 512;
+ 		info->spare_size = 8;
+ 		info->ecc_size = 8;
+@@ -1358,19 +1354,12 @@ static int pxa_ecc_init(struct pxa3xx_na
+ 		ecc->size = 512;
+ 		ecc->strength = 1;
+ 		return 1;
+-	}
+-	return 0;
+-}
+ 
+-static int armada370_ecc_init(struct pxa3xx_nand_info *info,
+-			      struct nand_ecc_ctrl *ecc,
+-			      int strength, int ecc_stepsize, int page_size)
+-{
+ 	/*
+ 	 * Required ECC: 4-bit correction per 512 bytes
+ 	 * Select: 16-bit correction per 2048 bytes
+ 	 */
+-	if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
++	} else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
+ 		info->ecc_bch = 1;
+ 		info->chunk_size = 2048;
+ 		info->spare_size = 32;
+@@ -1411,6 +1400,7 @@ static int pxa3xx_nand_scan(struct mtd_i
+ 	uint32_t id = -1;
+ 	uint64_t chipsize;
+ 	int i, ret, num;
++	uint16_t ecc_strength, ecc_step;
+ 
+ 	if (pdata->keep_config && !pxa3xx_nand_detect_config(info))
+ 		goto KEEP_CONFIG;
+@@ -1505,15 +1495,17 @@ KEEP_CONFIG:
+ 		}
+ 	}
+ 
+-	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+-		ret = armada370_ecc_init(info, &chip->ecc,
+-				   chip->ecc_strength_ds,
+-				   chip->ecc_step_ds,
+-				   mtd->writesize);
+-	else
+-		ret = pxa_ecc_init(info, &chip->ecc,
+-				   chip->ecc_strength_ds,
+-				   mtd->writesize);
++	ecc_strength = chip->ecc_strength_ds;
++	ecc_step = chip->ecc_step_ds;
++
++	/* Set default ECC strength requirements on non-ONFI devices */
++	if (ecc_strength < 1 && ecc_step < 1) {
++		ecc_strength = 1;
++		ecc_step = 512;
++	}
++
++	ret = pxa_ecc_init(info, &chip->ecc, ecc_strength,
++			   ecc_step, mtd->writesize);
+ 	if (!ret) {
+ 		dev_err(&info->pdev->dev,
+ 			"ECC strength %d at page size %d is not supported\n",
diff --git a/target/linux/mvebu/patches-3.10/0158-mtd-nand-Allow-to-build-pxa3xx_nand-on-Orion-platfor.patch b/target/linux/mvebu/patches-3.10/0158-mtd-nand-Allow-to-build-pxa3xx_nand-on-Orion-platfor.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6ac5a67ffe2127cbb8b6ecf4330a8ba8b2a7b6ec
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0158-mtd-nand-Allow-to-build-pxa3xx_nand-on-Orion-platfor.patch
@@ -0,0 +1,29 @@
+From 933f5de151614aee0f7b1f664f86b04f3773a075 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Mon, 12 Aug 2013 14:14:59 -0300
+Subject: [PATCH 158/203] mtd: nand: Allow to build pxa3xx_nand on Orion
+ platforms
+
+The Armada 370 and Armada XP SoC families, selected by PLAT_ORION,
+have a Nand Flash Controller (NFC) IP very similar to the one present
+in PXA platforms. Therefore, we want to build this driver on PLAT_ORION.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Tested-by: Daniel Mack <zonque@gmail.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/nand/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -354,7 +354,7 @@ config MTD_NAND_ATMEL
+ 
+ config MTD_NAND_PXA3xx
+ 	tristate "Support for NAND flash devices on PXA3xx"
+-	depends on PXA3xx || ARCH_MMP
++	depends on PXA3xx || ARCH_MMP || PLAT_ORION
+ 	help
+ 	  This enables the driver for the NAND flash device found on
+ 	  PXA3xx processors
diff --git a/target/linux/mvebu/patches-3.10/0159-mtd-nand-pxa3xx-Make-config-menu-show-supported-plat.patch b/target/linux/mvebu/patches-3.10/0159-mtd-nand-pxa3xx-Make-config-menu-show-supported-plat.patch
new file mode 100644
index 0000000000000000000000000000000000000000..001a9ee5a51110cd7adde40382dc1625f77da773
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0159-mtd-nand-pxa3xx-Make-config-menu-show-supported-plat.patch
@@ -0,0 +1,31 @@
+From b1abf1e5c6a7531a1a93a0ab6c75607dcb0e9947 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 7 Nov 2013 12:17:11 -0300
+Subject: [PATCH 159/203] mtd: nand: pxa3xx: Make config menu show supported
+ platforms
+
+Since we have now support for the NFCv2 controller found on
+Armada 370/XP platforms.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/nand/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -353,11 +353,11 @@ config MTD_NAND_ATMEL
+ 	  on Atmel AT91 and AVR32 processors.
+ 
+ config MTD_NAND_PXA3xx
+-	tristate "Support for NAND flash devices on PXA3xx"
++	tristate "NAND support on PXA3xx and Armada 370/XP"
+ 	depends on PXA3xx || ARCH_MMP || PLAT_ORION
+ 	help
+ 	  This enables the driver for the NAND flash device found on
+-	  PXA3xx processors
++	  PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
+ 
+ config MTD_NAND_SLC_LPC32XX
+ 	tristate "NXP LPC32xx SLC Controller"
diff --git a/target/linux/mvebu/patches-3.10/0160-ARM-mvebu-config-Add-NAND-support.patch b/target/linux/mvebu/patches-3.10/0160-ARM-mvebu-config-Add-NAND-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4edcaf2d96b1f3f67efbee99c74eb434cf050d8f
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0160-ARM-mvebu-config-Add-NAND-support.patch
@@ -0,0 +1,24 @@
+From a18945a7fd26b83c765b60bcffe306421f7efe80 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Mon, 2 Dec 2013 18:44:40 -0300
+Subject: [PATCH 160/203] ARM: mvebu: config: Add NAND support
+
+Enable the pxa3xx-nand driver, which now supports the NAND controller
+in Armada 370/XP SoC.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/configs/mvebu_defconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm/configs/mvebu_defconfig
++++ b/arch/arm/configs/mvebu_defconfig
+@@ -53,6 +53,8 @@ CONFIG_MTD_CFI_INTELEXT=y
+ CONFIG_MTD_CFI_AMDSTD=y
+ CONFIG_MTD_CFI_STAA=y
+ CONFIG_MTD_PHYSMAP_OF=y
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_PXA3xx=y
+ CONFIG_SERIAL_8250_DW=y
+ CONFIG_GPIOLIB=y
+ CONFIG_GPIO_SYSFS=y
diff --git a/target/linux/mvebu/patches-3.10/0161-net-mvneta-Fix-incorrect-DMA-unmapping-size.patch b/target/linux/mvebu/patches-3.10/0161-net-mvneta-Fix-incorrect-DMA-unmapping-size.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f5d600f86a99e71f1c67579c6d05f482b2fa5bde
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0161-net-mvneta-Fix-incorrect-DMA-unmapping-size.patch
@@ -0,0 +1,69 @@
+From f834da3962eaee5d72f152e9a066c06ec0d9c2c4 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 5 Dec 2013 13:35:37 -0300
+Subject: [PATCH 161/203] net: mvneta: Fix incorrect DMA unmapping size
+
+The current code unmaps the DMA mapping created for rx skb_buff's by
+using the data_size as the the mapping size. This is wrong since the
+correct size to specify should match the size used to create the mapping.
+
+This commit removes the following DMA_API_DEBUG warning:
+
+------------[ cut here ]------------
+WARNING: at lib/dma-debug.c:887 check_unmap+0x3a8/0x860()
+mvneta d0070000.ethernet: DMA-API: device driver frees DMA memory with different size [device address=0x000000002eb80000] [map size=1600 bytes] [unmap size=66 bytes]
+CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.10.21-01444-ga88ae13-dirty #92
+[<c0013600>] (unwind_backtrace+0x0/0xf8) from [<c0010fb8>] (show_stack+0x10/0x14)
+[<c0010fb8>] (show_stack+0x10/0x14) from [<c001afa0>] (warn_slowpath_common+0x48/0x68)
+[<c001afa0>] (warn_slowpath_common+0x48/0x68) from [<c001b01c>] (warn_slowpath_fmt+0x30/0x40)
+[<c001b01c>] (warn_slowpath_fmt+0x30/0x40) from [<c018d0fc>] (check_unmap+0x3a8/0x860)
+[<c018d0fc>] (check_unmap+0x3a8/0x860) from [<c018d734>] (debug_dma_unmap_page+0x64/0x70)
+[<c018d734>] (debug_dma_unmap_page+0x64/0x70) from [<c0233f78>] (mvneta_rx+0xec/0x468)
+[<c0233f78>] (mvneta_rx+0xec/0x468) from [<c023436c>] (mvneta_poll+0x78/0x16c)
+[<c023436c>] (mvneta_poll+0x78/0x16c) from [<c02db468>] (net_rx_action+0x94/0x160)
+[<c02db468>] (net_rx_action+0x94/0x160) from [<c0021e68>] (__do_softirq+0xe8/0x1d0)
+[<c0021e68>] (__do_softirq+0xe8/0x1d0) from [<c0021ff8>] (do_softirq+0x4c/0x58)
+[<c0021ff8>] (do_softirq+0x4c/0x58) from [<c0022228>] (irq_exit+0x58/0x90)
+[<c0022228>] (irq_exit+0x58/0x90) from [<c000e7c8>] (handle_IRQ+0x3c/0x94)
+[<c000e7c8>] (handle_IRQ+0x3c/0x94) from [<c0008548>] (armada_370_xp_handle_irq+0x4c/0xb4)
+[<c0008548>] (armada_370_xp_handle_irq+0x4c/0xb4) from [<c000dc20>] (__irq_svc+0x40/0x50)
+Exception stack(0xc04f1f70 to 0xc04f1fb8)
+1f60:                                     c1fe46f8 00000000 00001d92 00001d92
+1f80: c04f0000 c04f0000 c04f84a4 c03e081c c05220e7 00000001 c05220e7 c04f0000
+1fa0: 00000000 c04f1fb8 c000eaf8 c004c048 60000113 ffffffff
+[<c000dc20>] (__irq_svc+0x40/0x50) from [<c004c048>] (cpu_startup_entry+0x54/0x128)
+[<c004c048>] (cpu_startup_entry+0x54/0x128) from [<c04c1a14>] (start_kernel+0x29c/0x2f0)
+[<c04c1a14>] (start_kernel+0x29c/0x2f0) from [<00008074>] (0x8074)
+---[ end trace d4955f6acd178110 ]---
+Mapped at:
+ [<c018d600>] debug_dma_map_page+0x4c/0x11c
+ [<c0235d6c>] mvneta_setup_rxqs+0x398/0x598
+ [<c0236084>] mvneta_open+0x40/0x17c
+ [<c02dbbd4>] __dev_open+0x9c/0x100
+ [<c02dbe58>] __dev_change_flags+0x7c/0x134
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -1341,7 +1341,7 @@ static void mvneta_rxq_drop_pkts(struct
+ 
+ 		dev_kfree_skb_any(skb);
+ 		dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
+-				 rx_desc->data_size, DMA_FROM_DEVICE);
++				 MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
+ 	}
+ 
+ 	if (rx_done)
+@@ -1387,7 +1387,7 @@ static int mvneta_rx(struct mvneta_port
+ 		}
+ 
+ 		dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
+-				 rx_desc->data_size, DMA_FROM_DEVICE);
++				 MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
+ 
+ 		rx_bytes = rx_desc->data_size -
+ 			(ETH_FCS_LEN + MVNETA_MH_SIZE);
diff --git a/target/linux/mvebu/patches-3.10/0162-mtd-nand-pxa3xx-Clear-need_wait-flag-when-starting-a.patch b/target/linux/mvebu/patches-3.10/0162-mtd-nand-pxa3xx-Clear-need_wait-flag-when-starting-a.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5665ca13e61ab91d36154811c0c127e98d9261ca
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0162-mtd-nand-pxa3xx-Clear-need_wait-flag-when-starting-a.patch
@@ -0,0 +1,50 @@
+From 7efaa8677ffd07d54d0122b5e92f29b74a36ad39 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 19 Dec 2013 06:08:03 -0300
+Subject: [PATCH 162/203] mtd: nand: pxa3xx: Clear need_wait flag when starting
+ a command
+
+Currently the driver assumes all commands will eventually trigger a RnB
+transition, and thus a "device is ready" IRQ.
+
+This assumption means that on every issued command, the dev_ready completion
+handler is init'ed and the need_wait flag is set.
+
+However this is incorrect: some commands (such as NAND_CMD_STATUS) don't
+make the device 'busy' and thus a RnB transition never occurs.
+Given, the NAND core never calls waitfunc() after such commands, this
+is not a problem.
+
+Therefore, it's possible to only clear the need_wait flag on every command
+that is started.
+
+This fixes a current bug that can be reproduced on PXA boards by writing
+blank (all 0xff'ed) to a page:
+
+  1. The kernel issues NAND_CMD_STATUS and sets need_wait=1. The flag
+     won't be cleared for this command since no RnB transition is
+     involved.
+
+  2. NAND_CMD_PAGEPROG is issued but since the data is blank, the driver
+     decides not to execute the command (and no IRQ activity is
+     involved).
+
+  3. The NAND core calls waitfunc() and waits for the dev_ready
+     completion, which will never end since the device _is_ already ready.
+
+Tested-by: Arnaud Ebalard <arno@natisbad.org>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/mtd/nand/pxa3xx_nand.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mtd/nand/pxa3xx_nand.c
++++ b/drivers/mtd/nand/pxa3xx_nand.c
+@@ -694,6 +694,7 @@ static void prepare_start_command(struct
+ 	info->retcode		= ERR_NONE;
+ 	info->ecc_err_cnt	= 0;
+ 	info->ndcb3		= 0;
++	info->need_wait		= 0;
+ 
+ 	switch (command) {
+ 	case NAND_CMD_READ0:
diff --git a/target/linux/mvebu/patches-3.10/0163-ARM-mvebu-move-ARMADA_XP_MAX_CPUS-to-armada-370-xp.h.patch b/target/linux/mvebu/patches-3.10/0163-ARM-mvebu-move-ARMADA_XP_MAX_CPUS-to-armada-370-xp.h.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5f46bc1493ffdfbf2b856fd43b898ad9f8f11ddc
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0163-ARM-mvebu-move-ARMADA_XP_MAX_CPUS-to-armada-370-xp.h.patch
@@ -0,0 +1,39 @@
+From b340059540cbc90412f3e7159dc57a178e0effd6 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 4 Dec 2013 14:28:59 +0100
+Subject: [PATCH 163/203] ARM: mvebu: move ARMADA_XP_MAX_CPUS to
+ armada-370-xp.h
+
+The ARMADA_XP_MAX_CPUS definition was in common.h, which as its name
+says, is common to all mvebu SoCs. It is more logical to have this XP
+specific definition in the already existing armada-370-xp.h header
+file.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ arch/arm/mach-mvebu/armada-370-xp.h | 2 ++
+ arch/arm/mach-mvebu/common.h        | 2 --
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/mach-mvebu/armada-370-xp.h
++++ b/arch/arm/mach-mvebu/armada-370-xp.h
+@@ -18,6 +18,8 @@
+ #ifdef CONFIG_SMP
+ #include <linux/cpumask.h>
+ 
++#define ARMADA_XP_MAX_CPUS 4
++
+ void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
+ void armada_xp_mpic_smp_cpu_init(void);
+ #endif
+--- a/arch/arm/mach-mvebu/common.h
++++ b/arch/arm/mach-mvebu/common.h
+@@ -15,8 +15,6 @@
+ #ifndef __ARCH_MVEBU_COMMON_H
+ #define __ARCH_MVEBU_COMMON_H
+ 
+-#define ARMADA_XP_MAX_CPUS 4
+-
+ void mvebu_restart(char mode, const char *cmd);
+ 
+ void armada_370_xp_init_irq(void);
diff --git a/target/linux/mvebu/patches-3.10/0164-ARM-mvebu-fix-register-length-for-Armada-XP-PMSU.patch b/target/linux/mvebu/patches-3.10/0164-ARM-mvebu-fix-register-length-for-Armada-XP-PMSU.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7b58f61a7723bc547039aa652c1f7fccd4bab19c
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0164-ARM-mvebu-fix-register-length-for-Armada-XP-PMSU.patch
@@ -0,0 +1,34 @@
+From 10208caf7f0ebfb3d6b546aa2ae66e42462551e0 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 4 Dec 2013 14:37:52 +0100
+Subject: [PATCH 164/203] ARM: mvebu: fix register length for Armada XP PMSU
+
+The per-CPU PMSU registers documented in the datasheet start at
+0x22100 and the last register for CPU3 is at 0x22428. However, the DT
+informations use <0x22100 0x430>, which makes the region end at
+0x22530 and not 0x22430.
+
+Moreover, looking at the datasheet, we can see that the registers for
+CPU0 start at 0x22100, for CPU1 at 0x22200, for CPU2 at 0x22300 and
+for CPU3 at 0x22400. It seems clear that 0x100 bytes of registers have
+been used per CPU.
+
+Therefore, this commit reduces the length of the PMSU per-CPU register
+area from the incorrect 0x430 bytes to a more logical 0x400 bytes.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ arch/arm/boot/dts/armada-xp.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/armada-xp.dtsi
++++ b/arch/arm/boot/dts/armada-xp.dtsi
+@@ -48,7 +48,7 @@
+ 
+ 			armada-370-xp-pmsu@22000 {
+ 				compatible = "marvell,armada-370-xp-pmsu";
+-				reg = <0x22100 0x430>, <0x20800 0x20>;
++				reg = <0x22100 0x400>, <0x20800 0x20>;
+ 			};
+ 
+ 			serial@12200 {
diff --git a/target/linux/mvebu/patches-3.10/0165-ARM-mvebu-make-armada_370_xp_pmsu_init-static.patch b/target/linux/mvebu/patches-3.10/0165-ARM-mvebu-make-armada_370_xp_pmsu_init-static.patch
new file mode 100644
index 0000000000000000000000000000000000000000..72465a19eba96444932999447d877a5e73a2fd47
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0165-ARM-mvebu-make-armada_370_xp_pmsu_init-static.patch
@@ -0,0 +1,36 @@
+From 167c442fb9adf4c2e02663a0291c6cfae31bad72 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Thu, 5 Dec 2013 10:02:25 +0100
+Subject: [PATCH 165/203] ARM: mvebu: make armada_370_xp_pmsu_init() static
+
+The armada_370_xp_pmsu_init() function is called as an
+early_initcall(). Therefore, there is no need to export this function,
+and we can make it static.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+---
+ arch/arm/mach-mvebu/common.h | 1 -
+ arch/arm/mach-mvebu/pmsu.c   | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/mach-mvebu/common.h
++++ b/arch/arm/mach-mvebu/common.h
+@@ -22,7 +22,6 @@ void armada_370_xp_handle_irq(struct pt_
+ 
+ void armada_xp_cpu_die(unsigned int cpu);
+ int armada_370_xp_coherency_init(void);
+-int armada_370_xp_pmsu_init(void);
+ void armada_xp_secondary_startup(void);
+ extern struct smp_operations armada_xp_smp_ops;
+ #endif
+--- a/arch/arm/mach-mvebu/pmsu.c
++++ b/arch/arm/mach-mvebu/pmsu.c
+@@ -58,7 +58,7 @@ int armada_xp_boot_cpu(unsigned int cpu_
+ }
+ #endif
+ 
+-int __init armada_370_xp_pmsu_init(void)
++static int __init armada_370_xp_pmsu_init(void)
+ {
+ 	struct device_node *np;
+ 
diff --git a/target/linux/mvebu/patches-3.10/0166-clocksource-armada-370-xp-Use-BIT.patch b/target/linux/mvebu/patches-3.10/0166-clocksource-armada-370-xp-Use-BIT.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8f07046a1784d3ebb0655f59d8e0821cd0844935
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0166-clocksource-armada-370-xp-Use-BIT.patch
@@ -0,0 +1,37 @@
+From ea331be867c791bca8200e6d707499845d8dfa87 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 13 Aug 2013 11:43:10 -0300
+Subject: [PATCH 166/203] clocksource: armada-370-xp: Use BIT()
+
+This is a purely cosmetic commit: we replace hardcoded values that
+representing bits by BIT(), which is slightly more readable.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+---
+ drivers/clocksource/time-armada-370-xp.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -35,13 +35,13 @@
+  * Timer block registers.
+  */
+ #define TIMER_CTRL_OFF		0x0000
+-#define  TIMER0_EN		 0x0001
+-#define  TIMER0_RELOAD_EN	 0x0002
+-#define  TIMER0_25MHZ            0x0800
++#define  TIMER0_EN		 BIT(0)
++#define  TIMER0_RELOAD_EN	 BIT(1)
++#define  TIMER0_25MHZ            BIT(11)
+ #define  TIMER0_DIV(div)         ((div) << 19)
+-#define  TIMER1_EN		 0x0004
+-#define  TIMER1_RELOAD_EN	 0x0008
+-#define  TIMER1_25MHZ            0x1000
++#define  TIMER1_EN		 BIT(2)
++#define  TIMER1_RELOAD_EN	 BIT(3)
++#define  TIMER1_25MHZ            BIT(12)
+ #define  TIMER1_DIV(div)         ((div) << 22)
+ #define TIMER_EVENTS_STATUS	0x0004
+ #define  TIMER0_CLR_MASK         (~0x1)
diff --git a/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch b/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch
new file mode 100644
index 0000000000000000000000000000000000000000..109d52d7c266021a11902f12fe6961154c545c6e
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch
@@ -0,0 +1,174 @@
+From 7a5e03909417ccecc85819837d10cbb6ffe1d759 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 13 Aug 2013 11:43:11 -0300
+Subject: [PATCH 167/203] clocksource: armada-370-xp: Simplify TIMER_CTRL
+ register access
+
+This commit creates two functions to access the TIMER_CTRL register:
+one for global one for the per-cpu. This makes the code much more
+readable. In addition, since the TIMER_CTRL register is also used for
+watchdog, this is preparation work for future thread-safe improvements.
+
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/clocksource/time-armada-370-xp.c | 69 ++++++++++++++------------------
+ 1 file changed, 30 insertions(+), 39 deletions(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -71,6 +71,18 @@ static u32 ticks_per_jiffy;
+ 
+ static struct clock_event_device __percpu **percpu_armada_370_xp_evt;
+ 
++static void timer_ctrl_clrset(u32 clr, u32 set)
++{
++	writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set,
++		timer_base + TIMER_CTRL_OFF);
++}
++
++static void local_timer_ctrl_clrset(u32 clr, u32 set)
++{
++	writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
++		local_base + TIMER_CTRL_OFF);
++}
++
+ static u32 notrace armada_370_xp_read_sched_clock(void)
+ {
+ 	return ~readl(timer_base + TIMER0_VAL_OFF);
+@@ -83,7 +95,6 @@ static int
+ armada_370_xp_clkevt_next_event(unsigned long delta,
+ 				struct clock_event_device *dev)
+ {
+-	u32 u;
+ 	/*
+ 	 * Clear clockevent timer interrupt.
+ 	 */
+@@ -97,11 +108,8 @@ armada_370_xp_clkevt_next_event(unsigned
+ 	/*
+ 	 * Enable the timer.
+ 	 */
+-	u = readl(local_base + TIMER_CTRL_OFF);
+-	u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN |
+-	     TIMER0_DIV(TIMER_DIVIDER_SHIFT));
+-	writel(u, local_base + TIMER_CTRL_OFF);
+-
++	local_timer_ctrl_clrset(TIMER0_RELOAD_EN,
++				TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT));
+ 	return 0;
+ }
+ 
+@@ -109,8 +117,6 @@ static void
+ armada_370_xp_clkevt_mode(enum clock_event_mode mode,
+ 			  struct clock_event_device *dev)
+ {
+-	u32 u;
+-
+ 	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+ 
+ 		/*
+@@ -122,18 +128,14 @@ armada_370_xp_clkevt_mode(enum clock_eve
+ 		/*
+ 		 * Enable timer.
+ 		 */
+-
+-		u = readl(local_base + TIMER_CTRL_OFF);
+-
+-		writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
+-			TIMER0_DIV(TIMER_DIVIDER_SHIFT)),
+-			local_base + TIMER_CTRL_OFF);
++		local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN |
++					   TIMER0_EN |
++					   TIMER0_DIV(TIMER_DIVIDER_SHIFT));
+ 	} else {
+ 		/*
+ 		 * Disable timer.
+ 		 */
+-		u = readl(local_base + TIMER_CTRL_OFF);
+-		writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF);
++		local_timer_ctrl_clrset(TIMER0_EN, 0);
+ 
+ 		/*
+ 		 * ACK pending timer interrupt.
+@@ -169,18 +171,18 @@ static irqreturn_t armada_370_xp_timer_i
+  */
+ static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt)
+ {
+-	u32 u;
++	u32 clr = 0, set = 0;
+ 	int cpu = smp_processor_id();
+ 
+ 	/* Use existing clock_event for cpu 0 */
+ 	if (!smp_processor_id())
+ 		return 0;
+ 
+-	u = readl(local_base + TIMER_CTRL_OFF);
+ 	if (timer25Mhz)
+-		writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
++		set = TIMER0_25MHZ;
+ 	else
+-		writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
++		clr = TIMER0_25MHZ;
++	local_timer_ctrl_clrset(clr, set);
+ 
+ 	evt->name		= armada_370_xp_clkevt.name;
+ 	evt->irq		= armada_370_xp_clkevt.irq;
+@@ -212,7 +214,7 @@ static struct local_timer_ops armada_370
+ 
+ static void __init armada_370_xp_timer_init(struct device_node *np)
+ {
+-	u32 u;
++	u32 clr = 0, set = 0;
+ 	int res;
+ 
+ 	timer_base = of_iomap(np, 0);
+@@ -221,29 +223,20 @@ static void __init armada_370_xp_timer_i
+ 
+ 	if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
+ 		/* The fixed 25MHz timer is available so let's use it */
+-		u = readl(local_base + TIMER_CTRL_OFF);
+-		writel(u | TIMER0_25MHZ,
+-		       local_base + TIMER_CTRL_OFF);
+-		u = readl(timer_base + TIMER_CTRL_OFF);
+-		writel(u | TIMER0_25MHZ,
+-		       timer_base + TIMER_CTRL_OFF);
++		set = TIMER0_25MHZ;
+ 		timer_clk = 25000000;
+ 	} else {
+ 		unsigned long rate = 0;
+ 		struct clk *clk = of_clk_get(np, 0);
+ 		WARN_ON(IS_ERR(clk));
+ 		rate =  clk_get_rate(clk);
+-		u = readl(local_base + TIMER_CTRL_OFF);
+-		writel(u & ~(TIMER0_25MHZ),
+-		       local_base + TIMER_CTRL_OFF);
+-
+-		u = readl(timer_base + TIMER_CTRL_OFF);
+-		writel(u & ~(TIMER0_25MHZ),
+-		       timer_base + TIMER_CTRL_OFF);
+-
+ 		timer_clk = rate / TIMER_DIVIDER;
++
++		clr = TIMER0_25MHZ;
+ 		timer25Mhz = false;
+ 	}
++	timer_ctrl_clrset(clr, set);
++	local_timer_ctrl_clrset(clr, set);
+ 
+ 	/*
+ 	 * We use timer 0 as clocksource, and private(local) timer 0
+@@ -265,10 +258,8 @@ static void __init armada_370_xp_timer_i
+ 	writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
+ 	writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
+ 
+-	u = readl(timer_base + TIMER_CTRL_OFF);
+-
+-	writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
+-		TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF);
++	timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN |
++			     TIMER0_DIV(TIMER_DIVIDER_SHIFT));
+ 
+ 	clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
+ 			      "armada_370_xp_clocksource",
diff --git a/target/linux/mvebu/patches-3.10/0168-clocksource-armada-370-xp-Introduce-new-compatibles.patch b/target/linux/mvebu/patches-3.10/0168-clocksource-armada-370-xp-Introduce-new-compatibles.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f028dfabc024cff38d133b856722601668ca0f34
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0168-clocksource-armada-370-xp-Introduce-new-compatibles.patch
@@ -0,0 +1,101 @@
+From 9cb47bf175645d15f97e6d964dd4a4f089275ef5 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 13 Aug 2013 11:43:13 -0300
+Subject: [PATCH 168/203] clocksource: armada-370-xp: Introduce new compatibles
+
+The Armada XP SoC clocksource driver cannot work without the 25 MHz
+fixed timer. Therefore it's appropriate to introduce a new compatible
+string and use it to set the 25 MHz fixed timer.
+
+The 'marvell,timer-25MHz' property will be marked as deprecated.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+---
+ drivers/clocksource/time-armada-370-xp.c | 54 +++++++++++++++++++++++---------
+ 1 file changed, 39 insertions(+), 15 deletions(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -13,6 +13,19 @@
+  *
+  * Timer 0 is used as free-running clocksource, while timer 1 is
+  * used as clock_event_device.
++ *
++ * ---
++ * Clocksource driver for Armada 370 and Armada XP SoC.
++ * This driver implements one compatible string for each SoC, given
++ * each has its own characteristics:
++ *
++ *   * Armada 370 has no 25 MHz fixed timer.
++ *
++ *   * Armada XP cannot work properly without such 25 MHz fixed timer as
++ *     doing otherwise leads to using a clocksource whose frequency varies
++ *     when doing cpufreq frequency changes.
++ *
++ * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
+  */
+ 
+ #include <linux/init.h>
+@@ -212,7 +225,7 @@ static struct local_timer_ops armada_370
+ 	.stop	=  armada_370_xp_timer_stop,
+ };
+ 
+-static void __init armada_370_xp_timer_init(struct device_node *np)
++static void __init armada_370_xp_timer_common_init(struct device_node *np)
+ {
+ 	u32 clr = 0, set = 0;
+ 	int res;
+@@ -221,20 +234,10 @@ static void __init armada_370_xp_timer_i
+ 	WARN_ON(!timer_base);
+ 	local_base = of_iomap(np, 1);
+ 
+-	if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
+-		/* The fixed 25MHz timer is available so let's use it */
++	if (timer25Mhz)
+ 		set = TIMER0_25MHZ;
+-		timer_clk = 25000000;
+-	} else {
+-		unsigned long rate = 0;
+-		struct clk *clk = of_clk_get(np, 0);
+-		WARN_ON(IS_ERR(clk));
+-		rate =  clk_get_rate(clk);
+-		timer_clk = rate / TIMER_DIVIDER;
+-
++	else
+ 		clr = TIMER0_25MHZ;
+-		timer25Mhz = false;
+-	}
+ 	timer_ctrl_clrset(clr, set);
+ 	local_timer_ctrl_clrset(clr, set);
+ 
+@@ -288,5 +291,26 @@ static void __init armada_370_xp_timer_i
+ #endif
+ 	}
+ }
+-CLOCKSOURCE_OF_DECLARE(armada_370_xp, "marvell,armada-370-xp-timer",
+-		       armada_370_xp_timer_init);
++
++static void __init armada_xp_timer_init(struct device_node *np)
++{
++	/* The fixed 25MHz timer is required, timer25Mhz is true by default */
++	timer_clk = 25000000;
++
++	armada_370_xp_timer_common_init(np);
++}
++CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
++		       armada_xp_timer_init);
++
++static void __init armada_370_timer_init(struct device_node *np)
++{
++	struct clk *clk = of_clk_get(np, 0);
++
++	WARN_ON(IS_ERR(clk));
++	timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
++	timer25Mhz = false;
++
++	armada_370_xp_timer_common_init(np);
++}
++CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer",
++		       armada_370_timer_init);
diff --git a/target/linux/mvebu/patches-3.10/0169-clocksource-armada-370-xp-Replace-WARN_ON-with-BUG_O.patch b/target/linux/mvebu/patches-3.10/0169-clocksource-armada-370-xp-Replace-WARN_ON-with-BUG_O.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e1707603030854b49762b60d0a230ae4dc5af723
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0169-clocksource-armada-370-xp-Replace-WARN_ON-with-BUG_O.patch
@@ -0,0 +1,29 @@
+From bcaac3d9265d751f7d20df6ed0ac24241308dff7 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 20 Aug 2013 12:45:52 -0300
+Subject: [PATCH 169/203] clocksource: armada-370-xp: Replace WARN_ON with
+ BUG_ON
+
+If the clock fails to be obtained and the timer fails to be properly
+registered, the kernel will freeze real soon. Instead, let's BUG()
+where the actual problem is located.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ drivers/clocksource/time-armada-370-xp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -306,7 +306,7 @@ static void __init armada_370_timer_init
+ {
+ 	struct clk *clk = of_clk_get(np, 0);
+ 
+-	WARN_ON(IS_ERR(clk));
++	BUG_ON(IS_ERR(clk));
+ 	timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
+ 	timer25Mhz = false;
+ 
diff --git a/target/linux/mvebu/patches-3.10/0170-clocksource-armada-370-xp-Get-reference-fixed-clock-.patch b/target/linux/mvebu/patches-3.10/0170-clocksource-armada-370-xp-Get-reference-fixed-clock-.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e87f7fc7c5f3e7e2fce54565d08cc22266eec713
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0170-clocksource-armada-370-xp-Get-reference-fixed-clock-.patch
@@ -0,0 +1,36 @@
+From 7d7214129f7bde5bb55c0691968407b48f08efb5 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 20 Aug 2013 12:45:53 -0300
+Subject: [PATCH 170/203] clocksource: armada-370-xp: Get reference fixed-clock
+ by name
+
+The Armada XP timer has two mandatory clock inputs: nbclk and refclk,
+as specified by the device-tree binding.
+
+This commit fixes the clock selection. Instead of hard-coding the clock
+rate for the 25 MHz reference fixed-clock, obtain the clock by its name.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ drivers/clocksource/time-armada-370-xp.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -294,8 +294,11 @@ static void __init armada_370_xp_timer_c
+ 
+ static void __init armada_xp_timer_init(struct device_node *np)
+ {
+-	/* The fixed 25MHz timer is required, timer25Mhz is true by default */
+-	timer_clk = 25000000;
++	struct clk *clk = of_clk_get_by_name(np, "fixed");
++
++	/* The 25Mhz fixed clock is mandatory, and must always be available */
++	BUG_ON(IS_ERR(clk));
++	timer_clk = clk_get_rate(clk);
+ 
+ 	armada_370_xp_timer_common_init(np);
+ }
diff --git a/target/linux/mvebu/patches-3.10/0171-clocksource-armada-370-xp-Register-sched_clock-after.patch b/target/linux/mvebu/patches-3.10/0171-clocksource-armada-370-xp-Register-sched_clock-after.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c5b4dcef77f7208b2164c4ff4578a9a9497b8562
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0171-clocksource-armada-370-xp-Register-sched_clock-after.patch
@@ -0,0 +1,65 @@
+From 3d7976bb4a0f34203456cc0e9054b4a6401c9fdb Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 26 Nov 2013 18:20:14 -0300
+Subject: [PATCH 171/203] clocksource: armada-370-xp: Register sched_clock
+ after the counter reset
+
+This commit registers the sched_clock _after_ the counter reset
+(instead of before). This removes the timestamp 'jump' in kernel
+log messages.
+
+Before this change:
+
+[    0.000000] sched_clock: 32 bits at 25MHz, resolution 40ns, wraps every 171798691800ns
+[    0.000000] Initializing Coherency fabric
+[    0.000000] Aurora cache controller enabled
+[    0.000000] l2x0: 16 ways, CACHE_ID 0x00000100, AUX_CTRL 0x1a696b12, Cache size: 1024 kB
+[  163.507447] Calibrating delay loop... 1325.05 BogoMIPS (lpj=662528)
+[  163.521419] pid_max: default: 32768 minimum: 301
+[  163.526185] Mount-cache hash table entries: 512
+[  163.531095] CPU: Testing write buffer coherency: ok
+
+After this change:
+
+[    0.000000] sched_clock: 32 bits at 25MHz, resolution 40ns, wraps every 171798691800ns
+[    0.000000] Initializing Coherency fabric
+[    0.000000] Aurora cache controller enabled
+[    0.000000] l2x0: 16 ways, CACHE_ID 0x00000100, AUX_CTRL 0x1a696b12, Cache size: 1024 kB
+[    0.016849] Calibrating delay loop... 1325.05 BogoMIPS (lpj=662528)
+[    0.030820] pid_max: default: 32768 minimum: 301
+[    0.035588] Mount-cache hash table entries: 512
+[    0.040500] CPU: Testing write buffer coherency: ok
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+---
+ drivers/clocksource/time-armada-370-xp.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/clocksource/time-armada-370-xp.c
++++ b/drivers/clocksource/time-armada-370-xp.c
+@@ -250,11 +250,6 @@ static void __init armada_370_xp_timer_c
+ 	ticks_per_jiffy = (timer_clk + HZ / 2) / HZ;
+ 
+ 	/*
+-	 * Set scale and timer for sched_clock.
+-	 */
+-	setup_sched_clock(armada_370_xp_read_sched_clock, 32, timer_clk);
+-
+-	/*
+ 	 * Setup free-running clocksource timer (interrupts
+ 	 * disabled).
+ 	 */
+@@ -264,6 +259,11 @@ static void __init armada_370_xp_timer_c
+ 	timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN |
+ 			     TIMER0_DIV(TIMER_DIVIDER_SHIFT));
+ 
++	/*
++	 * Set scale and timer for sched_clock.
++	 */
++	setup_sched_clock(armada_370_xp_read_sched_clock, 32, timer_clk);
++
+ 	clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
+ 			      "armada_370_xp_clocksource",
+ 			      timer_clk, 300, 32, clocksource_mmio_readl_down);
diff --git a/target/linux/mvebu/patches-3.10/0172-ARM-mvebu-Fix-the-Armada-370-XP-timer-compatible-str.patch b/target/linux/mvebu/patches-3.10/0172-ARM-mvebu-Fix-the-Armada-370-XP-timer-compatible-str.patch
new file mode 100644
index 0000000000000000000000000000000000000000..de409aa5b79151ed19a0d6f0bf8b7e9778f7adf7
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0172-ARM-mvebu-Fix-the-Armada-370-XP-timer-compatible-str.patch
@@ -0,0 +1,62 @@
+From e33103d8d4cfc513467eb30bc4faee5c91c8e6c2 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 13 Aug 2013 11:43:15 -0300
+Subject: [PATCH 172/203] ARM: mvebu: Fix the Armada 370/XP timer compatible
+ strings
+
+The "marvell,armada-370-xp-timer" compatible string, together with
+the "marvell,timer-25Mhz" property are deprecated and should be
+removed from current DT.
+
+Instead, the timer DT nodes are now required to have an appropriate
+compatible string, which should be either "marvell,armada-370-timer"
+or "marvell,armada-xp-timer", depending on SoC.
+
+The clock property is now required only for Armada 370 so move it accordingly.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-370-xp.dtsi | 2 --
+ arch/arm/boot/dts/armada-370.dtsi    | 5 +++++
+ arch/arm/boot/dts/armada-xp.dtsi     | 2 +-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-370-xp.dtsi
++++ b/arch/arm/boot/dts/armada-370-xp.dtsi
+@@ -143,10 +143,8 @@
+ 			};
+ 
+ 			timer@20300 {
+-				compatible = "marvell,armada-370-xp-timer";
+ 				reg = <0x20300 0x30>, <0x21040 0x30>;
+ 				interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
+-				clocks = <&coreclk 2>;
+ 			};
+ 
+ 			sata@a0000 {
+--- a/arch/arm/boot/dts/armada-370.dtsi
++++ b/arch/arm/boot/dts/armada-370.dtsi
+@@ -163,6 +163,11 @@
+ 				interrupts = <91>;
+ 			};
+ 
++			timer@20300 {
++				compatible = "marvell,armada-370-timer";
++				clocks = <&coreclk 2>;
++			};
++
+ 			coreclk: mvebu-sar@18230 {
+ 				compatible = "marvell,armada-370-core-clock";
+ 				reg = <0x18230 0x08>;
+--- a/arch/arm/boot/dts/armada-xp.dtsi
++++ b/arch/arm/boot/dts/armada-xp.dtsi
+@@ -69,7 +69,7 @@
+ 			};
+ 
+ 			timer@20300 {
+-				marvell,timer-25Mhz;
++				compatible = "marvell,armada-xp-timer";
+ 			};
+ 
+ 			coreclk: mvebu-sar@18230 {
diff --git a/target/linux/mvebu/patches-3.10/0173-ARM-mvebu-Add-the-reference-25-MHz-fixed-clock-to-Ar.patch b/target/linux/mvebu/patches-3.10/0173-ARM-mvebu-Add-the-reference-25-MHz-fixed-clock-to-Ar.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4f7dd76cda0f93c86eb792c0420b7fdc0d92b40e
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0173-ARM-mvebu-Add-the-reference-25-MHz-fixed-clock-to-Ar.patch
@@ -0,0 +1,34 @@
+From e4011be91332bacc5cf166e1ce92c3678fc7c646 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 20 Aug 2013 12:45:50 -0300
+Subject: [PATCH 173/203] ARM: mvebu: Add the reference 25 MHz fixed-clock to
+ Armada XP
+
+The Armada XP SoC has a reference 25 MHz fixed-clock that is used in
+some controllers such as the timer and the watchdog. This commit adds
+a DT representation of this clock through a fixed-clock compatible node.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Mike Turquette <mturquette@linaro.org>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-xp.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-xp.dtsi
++++ b/arch/arm/boot/dts/armada-xp.dtsi
+@@ -169,4 +169,13 @@
+ 			};
+ 		};
+ 	};
++
++	clocks {
++		/* 25 MHz reference crystal */
++		refclk: oscillator {
++			compatible = "fixed-clock";
++			#clock-cells = <0>;
++			clock-frequency = <25000000>;
++		};
++	};
+ };
diff --git a/target/linux/mvebu/patches-3.10/0174-ARM-mvebu-Add-clock-properties-to-Armada-XP-timer-no.patch b/target/linux/mvebu/patches-3.10/0174-ARM-mvebu-Add-clock-properties-to-Armada-XP-timer-no.patch
new file mode 100644
index 0000000000000000000000000000000000000000..51796bf241988e88d18ac12d96be51e011c0edc0
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0174-ARM-mvebu-Add-clock-properties-to-Armada-XP-timer-no.patch
@@ -0,0 +1,30 @@
+From 200b303fc6c2709340996b02ae0c9a7130de7ec3 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 20 Aug 2013 12:45:51 -0300
+Subject: [PATCH 174/203] ARM: mvebu: Add clock properties to Armada XP timer
+ node
+
+With the addition of the Armada XP reference clock, we can now model
+accurately the available clock inputs for the timer: namely, nbclk
+and refclk. For each of this clock inputs we assign a name, for the
+driver to select as appropriate.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Mike Turquette <mturquette@linaro.org>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-xp.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm/boot/dts/armada-xp.dtsi
++++ b/arch/arm/boot/dts/armada-xp.dtsi
+@@ -70,6 +70,8 @@
+ 
+ 			timer@20300 {
+ 				compatible = "marvell,armada-xp-timer";
++				clocks = <&coreclk 2>, <&refclk>;
++				clock-names = "nbclk", "fixed";
+ 			};
+ 
+ 			coreclk: mvebu-sar@18230 {
diff --git a/target/linux/mvebu/patches-3.10/0175-ARM-mvebu-Relocate-PCIe-node-in-Armada-370-RD-board.patch b/target/linux/mvebu/patches-3.10/0175-ARM-mvebu-Relocate-PCIe-node-in-Armada-370-RD-board.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3b37ab93e6555bf60b76d915f113da13ff021c76
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0175-ARM-mvebu-Relocate-PCIe-node-in-Armada-370-RD-board.patch
@@ -0,0 +1,62 @@
+From 079d1ecae4bd4166a0f89bcb8e0c96bec1b39622 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Thu, 8 Aug 2013 18:03:09 -0300
+Subject: [PATCH 175/203] ARM: mvebu: Relocate PCIe node in Armada 370 RD board
+
+The pcie-controller node needs to be relocated according the MBus
+DT binding, since it's now a child of the mbus-compatible node.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-370-rd.dts | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-370-rd.dts
++++ b/arch/arm/boot/dts/armada-370-rd.dts
+@@ -31,6 +31,22 @@
+ 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ 			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+ 
++		pcie-controller {
++			status = "okay";
++
++			/* Internal mini-PCIe connector */
++			pcie@1,0 {
++				/* Port 0, Lane 0 */
++				status = "okay";
++			};
++
++			/* Internal mini-PCIe connector */
++			pcie@2,0 {
++				/* Port 1, Lane 0 */
++				status = "okay";
++			};
++		};
++
+ 		internal-regs {
+ 			serial@12000 {
+ 				clock-frequency = <200000000>;
+@@ -88,22 +104,6 @@
+ 					gpios = <&gpio0 6 1>;
+ 				};
+ 			};
+-
+-			pcie-controller {
+-				status = "okay";
+-
+-				/* Internal mini-PCIe connector */
+-				pcie@1,0 {
+-					/* Port 0, Lane 0 */
+-					status = "okay";
+-				};
+-
+-				/* Internal mini-PCIe connector */
+-				pcie@2,0 {
+-					/* Port 1, Lane 0 */
+-					status = "okay";
+-				};
+-			};
+ 		};
+ 	};
+  };
diff --git a/target/linux/mvebu/patches-3.10/0176-of-irq-create-interrupts-extended-property.patch b/target/linux/mvebu/patches-3.10/0176-of-irq-create-interrupts-extended-property.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a31d2d02962de143ab8d0e5950f52b6743015d72
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0176-of-irq-create-interrupts-extended-property.patch
@@ -0,0 +1,104 @@
+From 6dc29d94d92ccc558b946bd57cd8d7cb19d8def1 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:47 -0300
+Subject: [PATCH 176/203] of/irq: create interrupts-extended property
+
+The standard interrupts property in device tree can only handle
+interrupts coming from a single interrupt parent. If a device is wired
+to multiple interrupt controllers, then it needs to be attached to a
+node with an interrupt-map property to demux the interrupt specifiers
+which is confusing. It would be a lot easier if there was a form of the
+interrupts property that allows for a separate interrupt phandle for
+each interrupt specifier.
+
+This patch does exactly that by creating a new interrupts-extended
+property which reuses the phandle+arguments pattern used by GPIOs and
+other core bindings.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Kumar Gala <galak@codeaurora.org>
+[grant.likely: removed versatile platform hunks into separate patch]
+Cc: Rob Herring <rob.herring@calxeda.com>
+
+Conflicts:
+	arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+	drivers/of/selftest.c
+---
+ .../bindings/interrupt-controller/interrupts.txt   | 29 +++++++++++++++++-----
+ drivers/of/irq.c                                   | 16 ++++++++----
+ 2 files changed, 34 insertions(+), 11 deletions(-)
+
+--- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
++++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+@@ -4,16 +4,33 @@ Specifying interrupt information for dev
+ 1) Interrupt client nodes
+ -------------------------
+ 
+-Nodes that describe devices which generate interrupts must contain an
+-"interrupts" property. This property must contain a list of interrupt
+-specifiers, one per output interrupt. The format of the interrupt specifier is
+-determined by the interrupt controller to which the interrupts are routed; see
+-section 2 below for details.
++Nodes that describe devices which generate interrupts must contain an either an
++"interrupts" property or an "interrupts-extended" property. These properties
++contain a list of interrupt specifiers, one per output interrupt. The format of
++the interrupt specifier is determined by the interrupt controller to which the
++interrupts are routed; see section 2 below for details.
++
++  Example:
++	interrupt-parent = <&intc1>;
++	interrupts = <5 0>, <6 0>;
+ 
+ The "interrupt-parent" property is used to specify the controller to which
+ interrupts are routed and contains a single phandle referring to the interrupt
+ controller node. This property is inherited, so it may be specified in an
+-interrupt client node or in any of its parent nodes.
++interrupt client node or in any of its parent nodes. Interrupts listed in the
++"interrupts" property are always in reference to the node's interrupt parent.
++
++The "interrupts-extended" property is a special form for use when a node needs
++to reference multiple interrupt parents. Each entry in this property contains
++both the parent phandle and the interrupt specifier. "interrupts-extended"
++should only be used when a device has multiple interrupt parents.
++
++  Example:
++	interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;
++
++A device node may contain either "interrupts" or "interrupts-extended", but not
++both. If both properties are present, then the operating system should log an
++error and use only the data in "interrupts".
+ 
+ 2) Interrupt controller nodes
+ -----------------------------
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -293,17 +293,23 @@ int of_irq_map_one(struct device_node *d
+ 	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
+ 		return of_irq_map_oldworld(device, index, out_irq);
+ 
++	/* Get the reg property (if any) */
++	addr = of_get_property(device, "reg", NULL);
++
+ 	/* Get the interrupts property */
+ 	intspec = of_get_property(device, "interrupts", &intlen);
+-	if (intspec == NULL)
+-		return -EINVAL;
++	if (intspec == NULL) {
++		/* Try the new-style interrupts-extended */
++		res = of_parse_phandle_with_args(device, "interrupts-extended",
++						"#interrupt-cells", index, out_irq);
++		if (res)
++			return -EINVAL;
++		return of_irq_parse_raw(addr, out_irq);
++	}
+ 	intlen /= sizeof(*intspec);
+ 
+ 	pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
+ 
+-	/* Get the reg property (if any) */
+-	addr = of_get_property(device, "reg", NULL);
+-
+ 	/* Look for the interrupt parent. */
+ 	p = of_irq_find_parent(device);
+ 	if (p == NULL)
diff --git a/target/linux/mvebu/patches-3.10/0177-of-irq-Avoid-calling-list_first_entry-for-empty-list.patch b/target/linux/mvebu/patches-3.10/0177-of-irq-Avoid-calling-list_first_entry-for-empty-list.patch
new file mode 100644
index 0000000000000000000000000000000000000000..14b3d13b03d2cb68a9083fed9d45830d3239e45f
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0177-of-irq-Avoid-calling-list_first_entry-for-empty-list.patch
@@ -0,0 +1,30 @@
+From f159ea8ab3bce09a098d0d56c9e8909f385b87aa Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Thu, 19 Dec 2013 09:30:48 -0300
+Subject: [PATCH 177/203] of/irq: Avoid calling list_first_entry() for empty
+ list
+
+list_first_entry() expects the list is not empty, we need to check if list is
+empty before calling list_first_entry(). Thus use list_first_entry_or_null()
+instead of list_first_entry().
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/irq.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -488,8 +488,9 @@ void __init of_irq_init(const struct of_
+ 		}
+ 
+ 		/* Get the next pending parent that might have children */
+-		desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
+-		if (list_empty(&intc_parent_list) || !desc) {
++		desc = list_first_entry_or_null(&intc_parent_list,
++						typeof(*desc), list);
++		if (!desc) {
+ 			pr_err("of_irq_init: children remain, but no parents\n");
+ 			break;
+ 		}
diff --git a/target/linux/mvebu/patches-3.10/0178-of-clean-up-ifdefs-in-of_irq.h.patch b/target/linux/mvebu/patches-3.10/0178-of-clean-up-ifdefs-in-of_irq.h.patch
new file mode 100644
index 0000000000000000000000000000000000000000..57ea57455718ff5d8e7fd82845e1961abd467b11
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0178-of-clean-up-ifdefs-in-of_irq.h.patch
@@ -0,0 +1,68 @@
+From 704f3796c741df558d624078c5094439c0b65d09 Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Thu, 19 Dec 2013 09:30:49 -0300
+Subject: [PATCH 178/203] of: clean-up ifdefs in of_irq.h
+
+Much of of_irq.h is needlessly ifdef'ed. Clean this up and minimize the
+amount ifdef'ed code. This fixes some  build warnings when CONFIG_OF
+is not enabled (seen on i386 and x86_64):
+
+include/linux/of_irq.h:82:7: warning: 'struct device_node' declared inside parameter list [enabled by default]
+include/linux/of_irq.h:82:7: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
+include/linux/of_irq.h:87:47: warning: 'struct device_node' declared inside parameter list [enabled by default]
+
+Compile tested on i386, sparc and arm.
+
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Grant Likely <grant.likely@linaro.org>
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+---
+ include/linux/of_irq.h | 20 ++++++++------------
+ 1 file changed, 8 insertions(+), 12 deletions(-)
+
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -1,8 +1,6 @@
+ #ifndef __OF_IRQ_H
+ #define __OF_IRQ_H
+ 
+-#if defined(CONFIG_OF)
+-struct of_irq;
+ #include <linux/types.h>
+ #include <linux/errno.h>
+ #include <linux/irq.h>
+@@ -10,14 +8,6 @@ struct of_irq;
+ #include <linux/ioport.h>
+ #include <linux/of.h>
+ 
+-/*
+- * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC
+- * implements it differently.  However, the prototype is the same for all,
+- * so declare it here regardless of the CONFIG_OF_IRQ setting.
+- */
+-extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
+-
+-#if defined(CONFIG_OF_IRQ)
+ /**
+  * of_irq - container for device_node/irq_specifier pair for an irq controller
+  * @controller: pointer to interrupt controller device tree node
+@@ -71,11 +61,17 @@ extern int of_irq_to_resource(struct dev
+ extern int of_irq_count(struct device_node *dev);
+ extern int of_irq_to_resource_table(struct device_node *dev,
+ 		struct resource *res, int nr_irqs);
+-extern struct device_node *of_irq_find_parent(struct device_node *child);
+ 
+ extern void of_irq_init(const struct of_device_id *matches);
+ 
+-#endif /* CONFIG_OF_IRQ */
++#if defined(CONFIG_OF)
++/*
++ * irq_of_parse_and_map() is used by all OF enabled platforms; but SPARC
++ * implements it differently.  However, the prototype is the same for all,
++ * so declare it here regardless of the CONFIG_OF_IRQ setting.
++ */
++extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
++extern struct device_node *of_irq_find_parent(struct device_node *child);
+ 
+ #else /* !CONFIG_OF */
+ static inline unsigned int irq_of_parse_and_map(struct device_node *dev,
diff --git a/target/linux/mvebu/patches-3.10/0179-of-irq-init-struct-resource-to-0-in-of_irq_to_resour.patch b/target/linux/mvebu/patches-3.10/0179-of-irq-init-struct-resource-to-0-in-of_irq_to_resour.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1e14dbf453d66543c6273104adce7629632ae0c4
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0179-of-irq-init-struct-resource-to-0-in-of_irq_to_resour.patch
@@ -0,0 +1,27 @@
+From 15a2884ede54118137708ccc72f246fe986f8a57 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Thu, 19 Dec 2013 09:30:50 -0300
+Subject: [PATCH 179/203] of/irq: init struct resource to 0 in
+ of_irq_to_resource()
+
+It almost does not matter because most users use only the ->start member
+of the struct. However if this struct is passed to a platform device
+which is then added via platform_device_add() then the ->parent member is
+also used.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/irq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -351,6 +351,7 @@ int of_irq_to_resource(struct device_nod
+ 	if (r && irq) {
+ 		const char *name = NULL;
+ 
++		memset(r, 0, sizeof(*r));
+ 		/*
+ 		 * Get optional "interrupts-names" property to add a name
+ 		 * to the resource.
diff --git a/target/linux/mvebu/patches-3.10/0180-irq-of-Fix-comment-typo-for-irq_of_parse_and_map.patch b/target/linux/mvebu/patches-3.10/0180-irq-of-Fix-comment-typo-for-irq_of_parse_and_map.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b66a59f6cbdd409209523b4a1278e6e42d8c3751
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0180-irq-of-Fix-comment-typo-for-irq_of_parse_and_map.patch
@@ -0,0 +1,24 @@
+From 3d73f7a8db8a7506630174d0e8609138d97c8326 Mon Sep 17 00:00:00 2001
+From: Yijing Wang <wangyijing@huawei.com>
+Date: Thu, 19 Dec 2013 09:30:51 -0300
+Subject: [PATCH 180/203] irq/of: Fix comment typo for irq_of_parse_and_map
+
+Fix trivial comment typo for irq_of_parse_and_map().
+
+Signed-off-by: Yijing Wang <wangyijing@huawei.com>
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -28,7 +28,7 @@
+ 
+ /**
+  * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
+- * @device: Device node of the device whose interrupt is to be mapped
++ * @dev: Device node of the device whose interrupt is to be mapped
+  * @index: Index of the interrupt to map
+  *
+  * This function is a wrapper that chains of_irq_map_one() and
diff --git a/target/linux/mvebu/patches-3.10/0181-of-Fix-dereferencing-node-name-in-debug-output-to-be.patch b/target/linux/mvebu/patches-3.10/0181-of-Fix-dereferencing-node-name-in-debug-output-to-be.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ce62d531c2e1b693e5dfc5aee3c48557ec8f60d9
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0181-of-Fix-dereferencing-node-name-in-debug-output-to-be.patch
@@ -0,0 +1,82 @@
+From 02abb20a226a5a1e5c6dfaaf765dd71a90200cf9 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:52 -0300
+Subject: [PATCH 181/203] of: Fix dereferencing node name in debug output to be
+ safe
+
+Several locations in the of_address and of_irq code dereference the
+full_name parameter from a device_node pointer without checking if the
+pointer is valid.  This patch switches to use of_node_full_name() which
+always checks the pointer.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/address.c | 6 +++---
+ drivers/of/irq.c     | 8 ++++----
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -481,7 +481,7 @@ static u64 __of_translate_address(struct
+ 	int na, ns, pna, pns;
+ 	u64 result = OF_BAD_ADDR;
+ 
+-	pr_debug("OF: ** translation for device %s **\n", dev->full_name);
++	pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev));
+ 
+ 	/* Increase refcount at current level */
+ 	of_node_get(dev);
+@@ -496,13 +496,13 @@ static u64 __of_translate_address(struct
+ 	bus->count_cells(dev, &na, &ns);
+ 	if (!OF_CHECK_COUNTS(na, ns)) {
+ 		printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+-		       dev->full_name);
++		       of_node_full_name(dev));
+ 		goto bail;
+ 	}
+ 	memcpy(addr, in_addr, na * 4);
+ 
+ 	pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
+-	    bus->name, na, ns, parent->full_name);
++	    bus->name, na, ns, of_node_full_name(parent));
+ 	of_dump_addr("OF: translating address:", addr, na);
+ 
+ 	/* Translate */
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -102,7 +102,7 @@ int of_irq_map_raw(struct device_node *p
+ 	int imaplen, match, i;
+ 
+ 	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+-		 parent->full_name, be32_to_cpup(intspec),
++		 of_node_full_name(parent), be32_to_cpup(intspec),
+ 		 be32_to_cpup(intspec + 1), ointsize);
+ 
+ 	ipar = of_node_get(parent);
+@@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *p
+ 		goto fail;
+ 	}
+ 
+-	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
++	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
+ 
+ 	if (ointsize != intsize)
+ 		return -EINVAL;
+@@ -287,7 +287,7 @@ int of_irq_map_one(struct device_node *d
+ 	u32 intsize, intlen;
+ 	int res = -EINVAL;
+ 
+-	pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
++	pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index);
+ 
+ 	/* OldWorld mac stuff is "special", handle out of line */
+ 	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
+@@ -361,7 +361,7 @@ int of_irq_to_resource(struct device_nod
+ 
+ 		r->start = r->end = irq;
+ 		r->flags = IORESOURCE_IRQ;
+-		r->name = name ? name : dev->full_name;
++		r->name = name ? name : of_node_full_name(dev);
+ 	}
+ 
+ 	return irq;
diff --git a/target/linux/mvebu/patches-3.10/0182-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch b/target/linux/mvebu/patches-3.10/0182-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5363b2e008f3ce2aeee6fd2e53ad9f8e3fc6492b
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0182-of-irq-Pass-trigger-type-in-IRQ-resource-flags.patch
@@ -0,0 +1,34 @@
+From 4bd60065fb935a5d390c9a442be3a18d2ea18eee Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <tomasz.figa@gmail.com>
+Date: Thu, 19 Dec 2013 09:30:53 -0300
+Subject: [PATCH 182/203] of/irq: Pass trigger type in IRQ resource flags
+
+Some drivers might rely on availability of trigger flags in IRQ
+resource, for example to configure the hardware for particular interrupt
+type. However current code creating IRQ resources from data in device
+tree does not configure trigger flags in resulting resources.
+
+This patch tries to solve the problem, based on the fact that
+irq_of_parse_and_map() configures the trigger based on DT interrupt
+specifier and IRQD_TRIGGER_* flags are consistent with IORESOURCE_IRQ_*,
+and we can get correct trigger flags by calling irqd_get_trigger_type()
+after mapping the interrupt.
+
+Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
+[grant.likely: Merged the two assignments to r->flags]
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -360,7 +360,7 @@ int of_irq_to_resource(struct device_nod
+ 					      &name);
+ 
+ 		r->start = r->end = irq;
+-		r->flags = IORESOURCE_IRQ;
++		r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq));
+ 		r->name = name ? name : of_node_full_name(dev);
+ 	}
+ 
diff --git a/target/linux/mvebu/patches-3.10/0183-of-irq-Rename-of_irq_map_-functions-to-of_irq_parse_.patch b/target/linux/mvebu/patches-3.10/0183-of-irq-Rename-of_irq_map_-functions-to-of_irq_parse_.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5007d9164d1efa26a0d14ad53323fb1663196ee1
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0183-of-irq-Rename-of_irq_map_-functions-to-of_irq_parse_.patch
@@ -0,0 +1,682 @@
+From fd33285b3dab183df0cea06de9f618886dc0f1c0 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:54 -0300
+Subject: [PATCH 183/203] of/irq: Rename of_irq_map_* functions to
+ of_irq_parse_*
+
+The OF irq handling code has been overloading the term 'map' to refer to
+both parsing the data in the device tree and mapping it to the internal
+linux irq system. This is probably because the device tree does have the
+concept of an 'interrupt-map' function for translating interrupt
+references from one node to another, but 'map' is still confusing when
+the primary purpose of some of the functions are to parse the DT data.
+
+This patch renames all the of_irq_map_* functions to of_irq_parse_*
+which makes it clear that there is a difference between the parsing
+phase and the mapping phase. Kernel code can make use of just the
+parsing or just the mapping support as needed by the subsystem.
+
+The patch was generated mechanically with a handful of sed commands.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Michal Simek <monstr@monstr.eu>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+Conflicts:
+	arch/arm/mach-integrator/pci_v3.c
+	arch/mips/pci/pci-rt3883.c
+---
+ arch/arm/mach-integrator/pci_v3.c              | 279 +++++++++++++++++++++++++
+ arch/microblaze/pci/pci-common.c               |   2 +-
+ arch/mips/pci/fixup-lantiq.c                   |   2 +-
+ arch/powerpc/kernel/pci-common.c               |   2 +-
+ arch/powerpc/platforms/cell/celleb_scc_pciex.c |   2 +-
+ arch/powerpc/platforms/cell/celleb_scc_sio.c   |   2 +-
+ arch/powerpc/platforms/cell/spider-pic.c       |   2 +-
+ arch/powerpc/platforms/cell/spu_manage.c       |   2 +-
+ arch/powerpc/platforms/fsl_uli1575.c           |   2 +-
+ arch/powerpc/platforms/powermac/pic.c          |   2 +-
+ arch/powerpc/platforms/pseries/event_sources.c |   2 +-
+ arch/powerpc/sysdev/mpic_msi.c                 |   2 +-
+ arch/x86/kernel/devicetree.c                   |   2 +-
+ drivers/of/address.c                           |   4 +-
+ drivers/of/irq.c                               |  28 +--
+ drivers/of/of_pci_irq.c                        |  10 +-
+ drivers/pci/host/pci-mvebu.c                   |   2 +-
+ include/linux/of_irq.h                         |   8 +-
+ include/linux/of_pci.h                         |   2 +-
+ 19 files changed, 318 insertions(+), 39 deletions(-)
+
+--- a/arch/arm/mach-integrator/pci_v3.c
++++ b/arch/arm/mach-integrator/pci_v3.c
+@@ -610,3 +610,282 @@ void __init pci_v3_postinit(void)
+ 
+ 	register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
+ }
++
++/*
++ * A small note about bridges and interrupts.  The DECchip 21050 (and
++ * later) adheres to the PCI-PCI bridge specification.  This says that
++ * the interrupts on the other side of a bridge are swizzled in the
++ * following manner:
++ *
++ * Dev    Interrupt   Interrupt
++ *        Pin on      Pin on
++ *        Device      Connector
++ *
++ *   4    A           A
++ *        B           B
++ *        C           C
++ *        D           D
++ *
++ *   5    A           B
++ *        B           C
++ *        C           D
++ *        D           A
++ *
++ *   6    A           C
++ *        B           D
++ *        C           A
++ *        D           B
++ *
++ *   7    A           D
++ *        B           A
++ *        C           B
++ *        D           C
++ *
++ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
++ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
++ */
++
++/*
++ * This routine handles multiple bridges.
++ */
++static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
++{
++	if (*pinp == 0)
++		*pinp = 1;
++
++	return pci_common_swizzle(dev, pinp);
++}
++
++static int irq_tab[4] __initdata = {
++	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
++};
++
++/*
++ * map the specified device/slot/pin to an IRQ.  This works out such
++ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
++ */
++static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++	int intnr = ((slot - 9) + (pin - 1)) & 3;
++
++	return irq_tab[intnr];
++}
++
++static struct hw_pci pci_v3 __initdata = {
++	.swizzle		= pci_v3_swizzle,
++	.setup			= pci_v3_setup,
++	.nr_controllers		= 1,
++	.ops			= &pci_v3_ops,
++	.preinit		= pci_v3_preinit,
++	.postinit		= pci_v3_postinit,
++};
++
++#ifdef CONFIG_OF
++
++static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++	struct of_irq oirq;
++	int ret;
++
++	ret = of_irq_parse_pci(dev, &oirq);
++	if (ret) {
++		dev_err(&dev->dev, "of_irq_parse_pci() %d\n", ret);
++		/* Proper return code 0 == NO_IRQ */
++		return 0;
++	}
++
++	return irq_create_of_mapping(oirq.controller, oirq.specifier,
++				     oirq.size);
++}
++
++static int __init pci_v3_dtprobe(struct platform_device *pdev,
++				struct device_node *np)
++{
++	struct of_pci_range_parser parser;
++	struct of_pci_range range;
++	struct resource *res;
++	int irq, ret;
++
++	if (of_pci_range_parser_init(&parser, np))
++		return -EINVAL;
++
++	/* Get base for bridge registers */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "unable to obtain PCIv3 base\n");
++		return -ENODEV;
++	}
++	pci_v3_base = devm_ioremap(&pdev->dev, res->start,
++				   resource_size(res));
++	if (!pci_v3_base) {
++		dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
++		return -ENODEV;
++	}
++
++	/* Get and request error IRQ resource */
++	irq = platform_get_irq(pdev, 0);
++	if (irq <= 0) {
++		dev_err(&pdev->dev, "unable to obtain PCIv3 error IRQ\n");
++		return -ENODEV;
++	}
++	ret = devm_request_irq(&pdev->dev, irq, v3_irq, 0,
++			"PCIv3 error", NULL);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "unable to request PCIv3 error IRQ %d (%d)\n", irq, ret);
++		return ret;
++	}
++
++	for_each_of_pci_range(&parser, &range) {
++		if (!range.flags) {
++			of_pci_range_to_resource(&range, np, &conf_mem);
++			conf_mem.name = "PCIv3 config";
++		}
++		if (range.flags & IORESOURCE_IO) {
++			of_pci_range_to_resource(&range, np, &io_mem);
++			io_mem.name = "PCIv3 I/O";
++		}
++		if ((range.flags & IORESOURCE_MEM) &&
++			!(range.flags & IORESOURCE_PREFETCH)) {
++			non_mem_pci = range.pci_addr;
++			non_mem_pci_sz = range.size;
++			of_pci_range_to_resource(&range, np, &non_mem);
++			non_mem.name = "PCIv3 non-prefetched mem";
++		}
++		if ((range.flags & IORESOURCE_MEM) &&
++			(range.flags & IORESOURCE_PREFETCH)) {
++			pre_mem_pci = range.pci_addr;
++			pre_mem_pci_sz = range.size;
++			of_pci_range_to_resource(&range, np, &pre_mem);
++			pre_mem.name = "PCIv3 prefetched mem";
++		}
++	}
++
++	if (!conf_mem.start || !io_mem.start ||
++	    !non_mem.start || !pre_mem.start) {
++		dev_err(&pdev->dev, "missing ranges in device node\n");
++		return -EINVAL;
++	}
++
++	pci_v3.map_irq = pci_v3_map_irq_dt;
++	pci_common_init_dev(&pdev->dev, &pci_v3);
++
++	return 0;
++}
++
++#else
++
++static inline int pci_v3_dtprobe(struct platform_device *pdev,
++				  struct device_node *np)
++{
++	return -EINVAL;
++}
++
++#endif
++
++static int __init pci_v3_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	int ret;
++
++	/* Remap the Integrator system controller */
++	ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
++	if (!ap_syscon_base) {
++		dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
++		return -ENODEV;
++	}
++
++	/* Device tree probe path */
++	if (np)
++		return pci_v3_dtprobe(pdev, np);
++
++	pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K);
++	if (!pci_v3_base) {
++		dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
++		return -ENODEV;
++	}
++
++	ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
++	if (ret) {
++		dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n",
++			ret);
++		return -ENODEV;
++	}
++
++	conf_mem.name = "PCIv3 config";
++	conf_mem.start = PHYS_PCI_CONFIG_BASE;
++	conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1;
++	conf_mem.flags = IORESOURCE_MEM;
++
++	io_mem.name = "PCIv3 I/O";
++	io_mem.start = PHYS_PCI_IO_BASE;
++	io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1;
++	io_mem.flags = IORESOURCE_MEM;
++
++	non_mem_pci = 0x00000000;
++	non_mem_pci_sz = SZ_256M;
++	non_mem.name = "PCIv3 non-prefetched mem";
++	non_mem.start = PHYS_PCI_MEM_BASE;
++	non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1;
++	non_mem.flags = IORESOURCE_MEM;
++
++	pre_mem_pci = 0x10000000;
++	pre_mem_pci_sz = SZ_256M;
++	pre_mem.name = "PCIv3 prefetched mem";
++	pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M;
++	pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1;
++	pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
++
++	pci_v3.map_irq = pci_v3_map_irq;
++
++	pci_common_init_dev(&pdev->dev, &pci_v3);
++
++	return 0;
++}
++
++static const struct of_device_id pci_ids[] = {
++	{ .compatible = "v3,v360epc-pci", },
++	{},
++};
++
++static struct platform_driver pci_v3_driver = {
++	.driver = {
++		.name = "pci-v3",
++		.of_match_table = pci_ids,
++	},
++};
++
++static int __init pci_v3_init(void)
++{
++	return platform_driver_probe(&pci_v3_driver, pci_v3_probe);
++}
++
++subsys_initcall(pci_v3_init);
++
++/*
++ * Static mappings for the PCIv3 bridge
++ *
++ * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
++ * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
++ * fee00000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
++ */
++static struct map_desc pci_v3_io_desc[] __initdata __maybe_unused = {
++	{
++		.virtual	= (unsigned long)PCI_MEMORY_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_MEM_BASE),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}, {
++		.virtual	= (unsigned long)PCI_CONFIG_VADDR,
++		.pfn		= __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
++		.length		= SZ_16M,
++		.type		= MT_DEVICE
++	}
++};
++
++int __init pci_v3_early_init(void)
++{
++	iotable_init(pci_v3_io_desc, ARRAY_SIZE(pci_v3_io_desc));
++	vga_base = (unsigned long)PCI_MEMORY_VADDR;
++	pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
++	return 0;
++}
+--- a/arch/microblaze/pci/pci-common.c
++++ b/arch/microblaze/pci/pci-common.c
+@@ -217,7 +217,7 @@ int pci_read_irq_line(struct pci_dev *pc
+ 	memset(&oirq, 0xff, sizeof(oirq));
+ #endif
+ 	/* Try to get a mapping from the device-tree */
+-	if (of_irq_map_pci(pci_dev, &oirq)) {
++	if (of_irq_parse_pci(pci_dev, &oirq)) {
+ 		u8 line, pin;
+ 
+ 		/* If that fails, lets fallback to what is in the config
+--- a/arch/mips/pci/fixup-lantiq.c
++++ b/arch/mips/pci/fixup-lantiq.c
+@@ -28,7 +28,7 @@ int __init pcibios_map_irq(const struct
+ 	struct of_irq dev_irq;
+ 	int irq;
+ 
+-	if (of_irq_map_pci(dev, &dev_irq)) {
++	if (of_irq_parse_pci(dev, &dev_irq)) {
+ 		dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n",
+ 			slot, pin);
+ 		return 0;
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -237,7 +237,7 @@ static int pci_read_irq_line(struct pci_
+ 	memset(&oirq, 0xff, sizeof(oirq));
+ #endif
+ 	/* Try to get a mapping from the device-tree */
+-	if (of_irq_map_pci(pci_dev, &oirq)) {
++	if (of_irq_parse_pci(pci_dev, &oirq)) {
+ 		u8 line, pin;
+ 
+ 		/* If that fails, lets fallback to what is in the config
+--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+@@ -507,7 +507,7 @@ static __init int celleb_setup_pciex(str
+ 	phb->ops = &scc_pciex_pci_ops;
+ 
+ 	/* internal interrupt handler */
+-	if (of_irq_map_one(node, 1, &oirq)) {
++	if (of_irq_parse_one(node, 1, &oirq)) {
+ 		pr_err("PCIEXC:Failed to map irq\n");
+ 		goto error;
+ 	}
+--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
+@@ -53,7 +53,7 @@ static int __init txx9_serial_init(void)
+ 			if (!(txx9_serial_bitmap & (1<<i)))
+ 				continue;
+ 
+-			if (of_irq_map_one(node, i, &irq))
++			if (of_irq_parse_one(node, i, &irq))
+ 				continue;
+ 			if (of_address_to_resource(node,
+ 				txx9_scc_tab[i].index, &res))
+--- a/arch/powerpc/platforms/cell/spider-pic.c
++++ b/arch/powerpc/platforms/cell/spider-pic.c
+@@ -236,7 +236,7 @@ static unsigned int __init spider_find_c
+ 	 * tree in case the device-tree is ever fixed
+ 	 */
+ 	struct of_irq oirq;
+-	if (of_irq_map_one(pic->host->of_node, 0, &oirq) == 0) {
++	if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
+ 		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ 					     oirq.size);
+ 		return virq;
+--- a/arch/powerpc/platforms/cell/spu_manage.c
++++ b/arch/powerpc/platforms/cell/spu_manage.c
+@@ -182,7 +182,7 @@ static int __init spu_map_interrupts(str
+ 	int i;
+ 
+ 	for (i=0; i < 3; i++) {
+-		ret = of_irq_map_one(np, i, &oirq);
++		ret = of_irq_parse_one(np, i, &oirq);
+ 		if (ret) {
+ 			pr_debug("spu_new: failed to get irq %d\n", i);
+ 			goto err;
+--- a/arch/powerpc/platforms/fsl_uli1575.c
++++ b/arch/powerpc/platforms/fsl_uli1575.c
+@@ -333,7 +333,7 @@ static void hpcd_final_uli5288(struct pc
+ 
+ 	laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
+ 	laddr[1] = laddr[2] = 0;
+-	of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
++	of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq);
+ 	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ 				     oirq.size);
+ 	dev->irq = virq;
+--- a/arch/powerpc/platforms/powermac/pic.c
++++ b/arch/powerpc/platforms/powermac/pic.c
+@@ -393,7 +393,7 @@ static void __init pmac_pic_probe_oldsty
+ #endif
+ }
+ 
+-int of_irq_map_oldworld(struct device_node *device, int index,
++int of_irq_parse_oldworld(struct device_node *device, int index,
+ 			struct of_irq *out_irq)
+ {
+ 	const u32 *ints = NULL;
+--- a/arch/powerpc/platforms/pseries/event_sources.c
++++ b/arch/powerpc/platforms/pseries/event_sources.c
+@@ -55,7 +55,7 @@ void request_event_sources_irqs(struct d
+ 	/* Else use normal interrupt tree parsing */
+ 	else {
+ 		/* First try to do a proper OF tree parsing */
+-		for (index = 0; of_irq_map_one(np, index, &oirq) == 0;
++		for (index = 0; of_irq_parse_one(np, index, &oirq) == 0;
+ 		     index++) {
+ 			if (count > 15)
+ 				break;
+--- a/arch/powerpc/sysdev/mpic_msi.c
++++ b/arch/powerpc/sysdev/mpic_msi.c
+@@ -63,7 +63,7 @@ static int mpic_msi_reserve_u3_hwirqs(st
+ 		pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
+ 
+ 		index = 0;
+-		while (of_irq_map_one(np, index++, &oirq) == 0) {
++		while (of_irq_parse_one(np, index++, &oirq) == 0) {
+ 			ops->xlate(mpic->irqhost, NULL, oirq.specifier,
+ 						oirq.size, &hwirq, &flags);
+ 			msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
+--- a/arch/x86/kernel/devicetree.c
++++ b/arch/x86/kernel/devicetree.c
+@@ -117,7 +117,7 @@ static int x86_of_pci_irq_enable(struct
+ 	if (!pin)
+ 		return 0;
+ 
+-	ret = of_irq_map_pci(dev, &oirq);
++	ret = of_irq_parse_pci(dev, &oirq);
+ 	if (ret)
+ 		return ret;
+ 
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -524,12 +524,12 @@ static u64 __of_translate_address(struct
+ 		pbus->count_cells(dev, &pna, &pns);
+ 		if (!OF_CHECK_COUNTS(pna, pns)) {
+ 			printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+-			       dev->full_name);
++			       of_node_full_name(dev));
+ 			break;
+ 		}
+ 
+ 		pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+-		    pbus->name, pna, pns, parent->full_name);
++		    pbus->name, pna, pns, of_node_full_name(parent));
+ 
+ 		/* Apply bus translation */
+ 		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -31,14 +31,14 @@
+  * @dev: Device node of the device whose interrupt is to be mapped
+  * @index: Index of the interrupt to map
+  *
+- * This function is a wrapper that chains of_irq_map_one() and
++ * This function is a wrapper that chains of_irq_parse_one() and
+  * irq_create_of_mapping() to make things easier to callers
+  */
+ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+ {
+ 	struct of_irq oirq;
+ 
+-	if (of_irq_map_one(dev, index, &oirq))
++	if (of_irq_parse_one(dev, index, &oirq))
+ 		return 0;
+ 
+ 	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+@@ -79,7 +79,7 @@ struct device_node *of_irq_find_parent(s
+ }
+ 
+ /**
+- * of_irq_map_raw - Low level interrupt tree parsing
++ * of_irq_parse_raw - Low level interrupt tree parsing
+  * @parent:	the device interrupt parent
+  * @intspec:	interrupt specifier ("interrupts" property of the device)
+  * @ointsize:   size of the passed in interrupt specifier
+@@ -93,7 +93,7 @@ struct device_node *of_irq_find_parent(s
+  * properties, for example when resolving PCI interrupts when no device
+  * node exist for the parent.
+  */
+-int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
++int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+ 		   u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
+ {
+ 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+@@ -101,7 +101,7 @@ int of_irq_map_raw(struct device_node *p
+ 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ 	int imaplen, match, i;
+ 
+-	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
++	pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+ 		 of_node_full_name(parent), be32_to_cpup(intspec),
+ 		 be32_to_cpup(intspec + 1), ointsize);
+ 
+@@ -126,7 +126,7 @@ int of_irq_map_raw(struct device_node *p
+ 		goto fail;
+ 	}
+ 
+-	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
++	pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
+ 
+ 	if (ointsize != intsize)
+ 		return -EINVAL;
+@@ -269,29 +269,29 @@ int of_irq_map_raw(struct device_node *p
+ 
+ 	return -EINVAL;
+ }
+-EXPORT_SYMBOL_GPL(of_irq_map_raw);
++EXPORT_SYMBOL_GPL(of_irq_parse_raw);
+ 
+ /**
+- * of_irq_map_one - Resolve an interrupt for a device
++ * of_irq_parse_one - Resolve an interrupt for a device
+  * @device: the device whose interrupt is to be resolved
+  * @index: index of the interrupt to resolve
+  * @out_irq: structure of_irq filled by this function
+  *
+  * This function resolves an interrupt, walking the tree, for a given
+- * device-tree node. It's the high level pendant to of_irq_map_raw().
++ * device-tree node. It's the high level pendant to of_irq_parse_raw().
+  */
+-int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
++int of_irq_parse_one(struct device_node *device, int index, struct of_irq *out_irq)
+ {
+ 	struct device_node *p;
+ 	const __be32 *intspec, *tmp, *addr;
+ 	u32 intsize, intlen;
+ 	int res = -EINVAL;
+ 
+-	pr_debug("of_irq_map_one: dev=%s, index=%d\n", of_node_full_name(device), index);
++	pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);
+ 
+ 	/* OldWorld mac stuff is "special", handle out of line */
+ 	if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
+-		return of_irq_map_oldworld(device, index, out_irq);
++		return of_irq_parse_oldworld(device, index, out_irq);
+ 
+ 	/* Get the reg property (if any) */
+ 	addr = of_get_property(device, "reg", NULL);
+@@ -328,13 +328,13 @@ int of_irq_map_one(struct device_node *d
+ 		goto out;
+ 
+ 	/* Get new specifier and map it */
+-	res = of_irq_map_raw(p, intspec + index * intsize, intsize,
++	res = of_irq_parse_raw(p, intspec + index * intsize, intsize,
+ 			     addr, out_irq);
+  out:
+ 	of_node_put(p);
+ 	return res;
+ }
+-EXPORT_SYMBOL_GPL(of_irq_map_one);
++EXPORT_SYMBOL_GPL(of_irq_parse_one);
+ 
+ /**
+  * of_irq_to_resource - Decode a node's IRQ and return it as a resource
+--- a/drivers/of/of_pci_irq.c
++++ b/drivers/of/of_pci_irq.c
+@@ -5,7 +5,7 @@
+ #include <asm/prom.h>
+ 
+ /**
+- * of_irq_map_pci - Resolve the interrupt for a PCI device
++ * of_irq_parse_pci - Resolve the interrupt for a PCI device
+  * @pdev:       the device whose interrupt is to be resolved
+  * @out_irq:    structure of_irq filled by this function
+  *
+@@ -15,7 +15,7 @@
+  * PCI tree until an device-node is found, at which point it will finish
+  * resolving using the OF tree walking.
+  */
+-int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
++int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
+ {
+ 	struct device_node *dn, *ppnode;
+ 	struct pci_dev *ppdev;
+@@ -30,7 +30,7 @@ int of_irq_map_pci(const struct pci_dev
+ 	 */
+ 	dn = pci_device_to_OF_node(pdev);
+ 	if (dn) {
+-		rc = of_irq_map_one(dn, 0, out_irq);
++		rc = of_irq_parse_one(dn, 0, out_irq);
+ 		if (!rc)
+ 			return rc;
+ 	}
+@@ -88,6 +88,6 @@ int of_irq_map_pci(const struct pci_dev
+ 	lspec_be = cpu_to_be32(lspec);
+ 	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+ 	laddr[1]  = laddr[2] = cpu_to_be32(0);
+-	return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq);
++	return of_irq_parse_raw(ppnode, &lspec_be, 1, laddr, out_irq);
+ }
+-EXPORT_SYMBOL_GPL(of_irq_map_pci);
++EXPORT_SYMBOL_GPL(of_irq_parse_pci);
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -652,7 +652,7 @@ static int __init mvebu_pcie_map_irq(con
+ 	struct of_irq oirq;
+ 	int ret;
+ 
+-	ret = of_irq_map_pci(dev, &oirq);
++	ret = of_irq_parse_pci(dev, &oirq);
+ 	if (ret)
+ 		return ret;
+ 
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -35,12 +35,12 @@ typedef int (*of_irq_init_cb_t)(struct d
+ #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
+ extern unsigned int of_irq_workarounds;
+ extern struct device_node *of_irq_dflt_pic;
+-extern int of_irq_map_oldworld(struct device_node *device, int index,
++extern int of_irq_parse_oldworld(struct device_node *device, int index,
+ 			       struct of_irq *out_irq);
+ #else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+ #define of_irq_workarounds (0)
+ #define of_irq_dflt_pic (NULL)
+-static inline int of_irq_map_oldworld(struct device_node *device, int index,
++static inline int of_irq_parse_oldworld(struct device_node *device, int index,
+ 				      struct of_irq *out_irq)
+ {
+ 	return -EINVAL;
+@@ -48,10 +48,10 @@ static inline int of_irq_map_oldworld(st
+ #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+ 
+ 
+-extern int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
++extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+ 			  u32 ointsize, const __be32 *addr,
+ 			  struct of_irq *out_irq);
+-extern int of_irq_map_one(struct device_node *device, int index,
++extern int of_irq_parse_one(struct device_node *device, int index,
+ 			  struct of_irq *out_irq);
+ extern unsigned int irq_create_of_mapping(struct device_node *controller,
+ 					  const u32 *intspec,
+--- a/include/linux/of_pci.h
++++ b/include/linux/of_pci.h
+@@ -6,7 +6,7 @@
+ 
+ struct pci_dev;
+ struct of_irq;
+-int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
++int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
+ 
+ struct device_node;
+ struct device_node *of_pci_find_child_device(struct device_node *parent,
diff --git a/target/linux/mvebu/patches-3.10/0184-of-irq-Replace-of_irq-with-of_phandle_args.patch b/target/linux/mvebu/patches-3.10/0184-of-irq-Replace-of_irq-with-of_phandle_args.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f22da5fa90e08fc403eda37fd8cdbe420d2e3f5a
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0184-of-irq-Replace-of_irq-with-of_phandle_args.patch
@@ -0,0 +1,486 @@
+From 1baf727ee1d863a0eacd249cff6afc99022593c2 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:55 -0300
+Subject: [PATCH 184/203] of/irq: Replace of_irq with of_phandle_args
+
+struct of_irq and struct of_phandle_args are exactly the same structure.
+This patch makes the kernel use of_phandle_args everywhere. This in
+itself isn't a big deal, but it makes some follow-on patches simpler.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Michal Simek <monstr@monstr.eu>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Cc: Russell King <linux@arm.linux.org.uk>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+Conflicts:
+	arch/mips/pci/pci-rt3883.c
+---
+ arch/arm/mach-integrator/pci_v3.c              |  5 ++---
+ arch/microblaze/pci/pci-common.c               |  9 ++++-----
+ arch/mips/pci/fixup-lantiq.c                   |  5 ++---
+ arch/powerpc/kernel/pci-common.c               |  9 ++++-----
+ arch/powerpc/platforms/cell/celleb_scc_pciex.c |  5 ++---
+ arch/powerpc/platforms/cell/celleb_scc_sio.c   |  5 ++---
+ arch/powerpc/platforms/cell/spider-pic.c       |  6 +++---
+ arch/powerpc/platforms/cell/spu_manage.c       | 12 ++++++------
+ arch/powerpc/platforms/fsl_uli1575.c           |  8 +++-----
+ arch/powerpc/platforms/powermac/pic.c          |  8 ++++----
+ arch/powerpc/platforms/pseries/event_sources.c |  7 +++----
+ arch/powerpc/sysdev/mpic_msi.c                 |  6 +++---
+ arch/x86/kernel/devicetree.c                   |  5 ++---
+ drivers/of/irq.c                               | 15 +++++++--------
+ drivers/of/of_pci_irq.c                        |  2 +-
+ drivers/pci/host/pci-mvebu.c                   |  5 ++---
+ include/linux/of_irq.h                         | 24 ++++--------------------
+ include/linux/of_pci.h                         |  4 ++--
+ 18 files changed, 56 insertions(+), 84 deletions(-)
+
+--- a/arch/arm/mach-integrator/pci_v3.c
++++ b/arch/arm/mach-integrator/pci_v3.c
+@@ -684,7 +684,7 @@ static struct hw_pci pci_v3 __initdata =
+ 
+ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	int ret;
+ 
+ 	ret = of_irq_parse_pci(dev, &oirq);
+@@ -694,8 +694,7 @@ static int __init pci_v3_map_irq_dt(cons
+ 		return 0;
+ 	}
+ 
+-	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+-				     oirq.size);
++	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ }
+ 
+ static int __init pci_v3_dtprobe(struct platform_device *pdev,
+--- a/arch/microblaze/pci/pci-common.c
++++ b/arch/microblaze/pci/pci-common.c
+@@ -199,7 +199,7 @@ void pcibios_set_master(struct pci_dev *
+  */
+ int pci_read_irq_line(struct pci_dev *pci_dev)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	unsigned int virq;
+ 
+ 	/* The current device-tree that iSeries generates from the HV
+@@ -243,11 +243,10 @@ int pci_read_irq_line(struct pci_dev *pc
+ 			irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ 	} else {
+ 		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+-			 oirq.size, oirq.specifier[0], oirq.specifier[1],
+-			 of_node_full_name(oirq.controller));
++			 oirq.args_count, oirq.args[0], oirq.args[1],
++			 of_node_full_name(oirq.np));
+ 
+-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-					     oirq.size);
++		virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ 	}
+ 	if (!virq) {
+ 		pr_debug(" Failed to map !\n");
+--- a/arch/mips/pci/fixup-lantiq.c
++++ b/arch/mips/pci/fixup-lantiq.c
+@@ -25,7 +25,7 @@ int pcibios_plat_dev_init(struct pci_dev
+ 
+ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+-	struct of_irq dev_irq;
++	struct of_phandle_args dev_irq;
+ 	int irq;
+ 
+ 	if (of_irq_parse_pci(dev, &dev_irq)) {
+@@ -33,8 +33,7 @@ int __init pcibios_map_irq(const struct
+ 			slot, pin);
+ 		return 0;
+ 	}
+-	irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier,
+-					dev_irq.size);
++	irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);
+ 	dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
+ 	return irq;
+ }
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -228,7 +228,7 @@ int pcibios_add_platform_entries(struct
+  */
+ static int pci_read_irq_line(struct pci_dev *pci_dev)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	unsigned int virq;
+ 
+ 	pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
+@@ -263,11 +263,10 @@ static int pci_read_irq_line(struct pci_
+ 			irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ 	} else {
+ 		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+-			 oirq.size, oirq.specifier[0], oirq.specifier[1],
+-			 of_node_full_name(oirq.controller));
++			 oirq.args_count, oirq.args[0], oirq.args[1],
++			 of_node_full_name(oirq.np));
+ 
+-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-					     oirq.size);
++		virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ 	}
+ 	if(virq == NO_IRQ) {
+ 		pr_debug(" Failed to map !\n");
+--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+@@ -486,7 +486,7 @@ static __init int celleb_setup_pciex(str
+ 				     struct pci_controller *phb)
+ {
+ 	struct resource	r;
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	int virq;
+ 
+ 	/* SMMIO registers; used inside this file */
+@@ -511,8 +511,7 @@ static __init int celleb_setup_pciex(str
+ 		pr_err("PCIEXC:Failed to map irq\n");
+ 		goto error;
+ 	}
+-	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-				     oirq.size);
++	virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ 	if (request_irq(virq, pciex_handle_internal_irq,
+ 			0, "pciex", (void *)phb)) {
+ 		pr_err("PCIEXC:Failed to request irq\n");
+--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
+@@ -45,7 +45,7 @@ static int __init txx9_serial_init(void)
+ 	struct device_node *node;
+ 	int i;
+ 	struct uart_port req;
+-	struct of_irq irq;
++	struct of_phandle_args irq;
+ 	struct resource res;
+ 
+ 	for_each_compatible_node(node, "serial", "toshiba,sio-scc") {
+@@ -66,8 +66,7 @@ static int __init txx9_serial_init(void)
+ #ifdef CONFIG_SERIAL_TXX9_CONSOLE
+ 			req.membase = ioremap(req.mapbase, 0x24);
+ #endif
+-			req.irq = irq_create_of_mapping(irq.controller,
+-				irq.specifier, irq.size);
++			req.irq = irq_create_of_mapping(irq.np, irq.args, irq.args_count);
+ 			req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
+ 				/*HAVE_CTS_LINE*/;
+ 			req.uartclk = 83300000;
+--- a/arch/powerpc/platforms/cell/spider-pic.c
++++ b/arch/powerpc/platforms/cell/spider-pic.c
+@@ -235,10 +235,10 @@ static unsigned int __init spider_find_c
+ 	/* First, we check whether we have a real "interrupts" in the device
+ 	 * tree in case the device-tree is ever fixed
+ 	 */
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
+-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-					     oirq.size);
++		virq = irq_create_of_mapping(oirq.np, oirq.args,
++					     oirq.args_count);
+ 		return virq;
+ 	}
+ 
+--- a/arch/powerpc/platforms/cell/spu_manage.c
++++ b/arch/powerpc/platforms/cell/spu_manage.c
+@@ -177,7 +177,7 @@ out:
+ 
+ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	int ret;
+ 	int i;
+ 
+@@ -188,10 +188,10 @@ static int __init spu_map_interrupts(str
+ 			goto err;
+ 		}
+ 		ret = -EINVAL;
+-		pr_debug("  irq %d no 0x%x on %s\n", i, oirq.specifier[0],
+-			 oirq.controller->full_name);
+-		spu->irqs[i] = irq_create_of_mapping(oirq.controller,
+-					oirq.specifier, oirq.size);
++		pr_debug("  irq %d no 0x%x on %s\n", i, oirq.args[0],
++			 oirq.np->full_name);
++		spu->irqs[i] = irq_create_of_mapping(oirq.np,
++					oirq.args, oirq.args_count);
+ 		if (spu->irqs[i] == NO_IRQ) {
+ 			pr_debug("spu_new: failed to map it !\n");
+ 			goto err;
+@@ -200,7 +200,7 @@ static int __init spu_map_interrupts(str
+ 	return 0;
+ 
+ err:
+-	pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier,
++	pr_debug("failed to map irq %x for spu %s\n", *oirq.args,
+ 		spu->name);
+ 	for (; i >= 0; i--) {
+ 		if (spu->irqs[i] != NO_IRQ)
+--- a/arch/powerpc/platforms/fsl_uli1575.c
++++ b/arch/powerpc/platforms/fsl_uli1575.c
+@@ -321,8 +321,8 @@ static void hpcd_final_uli5288(struct pc
+ {
+ 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ 	struct device_node *hosenode = hose ? hose->dn : NULL;
+-	struct of_irq oirq;
+-	int virq, pin = 2;
++	struct of_phandle_args oirq;
++	int pin = 2;
+ 	u32 laddr[3];
+ 
+ 	if (!machine_is(mpc86xx_hpcd))
+@@ -334,9 +334,7 @@ static void hpcd_final_uli5288(struct pc
+ 	laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
+ 	laddr[1] = laddr[2] = 0;
+ 	of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq);
+-	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-				     oirq.size);
+-	dev->irq = virq;
++	dev->irq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ }
+ 
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575);
+--- a/arch/powerpc/platforms/powermac/pic.c
++++ b/arch/powerpc/platforms/powermac/pic.c
+@@ -394,7 +394,7 @@ static void __init pmac_pic_probe_oldsty
+ }
+ 
+ int of_irq_parse_oldworld(struct device_node *device, int index,
+-			struct of_irq *out_irq)
++			struct of_phandle_args *out_irq)
+ {
+ 	const u32 *ints = NULL;
+ 	int intlen;
+@@ -422,9 +422,9 @@ int of_irq_parse_oldworld(struct device_
+ 	if (index >= intlen)
+ 		return -EINVAL;
+ 
+-	out_irq->controller = NULL;
+-	out_irq->specifier[0] = ints[index];
+-	out_irq->size = 1;
++	out_irq->np = NULL;
++	out_irq->args[0] = ints[index];
++	out_irq->args_count = 1;
+ 
+ 	return 0;
+ }
+--- a/arch/powerpc/platforms/pseries/event_sources.c
++++ b/arch/powerpc/platforms/pseries/event_sources.c
+@@ -25,7 +25,7 @@ void request_event_sources_irqs(struct d
+ 				const char *name)
+ {
+ 	int i, index, count = 0;
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	const u32 *opicprop;
+ 	unsigned int opicplen;
+ 	unsigned int virqs[16];
+@@ -59,9 +59,8 @@ void request_event_sources_irqs(struct d
+ 		     index++) {
+ 			if (count > 15)
+ 				break;
+-			virqs[count] = irq_create_of_mapping(oirq.controller,
+-							    oirq.specifier,
+-							    oirq.size);
++			virqs[count] = irq_create_of_mapping(oirq.np, oirq.args,
++							    oirq.args_count);
+ 			if (virqs[count] == NO_IRQ) {
+ 				pr_err("event-sources: Unable to allocate "
+ 				       "interrupt number for %s\n",
+--- a/arch/powerpc/sysdev/mpic_msi.c
++++ b/arch/powerpc/sysdev/mpic_msi.c
+@@ -35,7 +35,7 @@ static int mpic_msi_reserve_u3_hwirqs(st
+ 	const struct irq_domain_ops *ops = mpic->irqhost->ops;
+ 	struct device_node *np;
+ 	int flags, index, i;
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 
+ 	pr_debug("mpic: found U3, guessing msi allocator setup\n");
+ 
+@@ -64,8 +64,8 @@ static int mpic_msi_reserve_u3_hwirqs(st
+ 
+ 		index = 0;
+ 		while (of_irq_parse_one(np, index++, &oirq) == 0) {
+-			ops->xlate(mpic->irqhost, NULL, oirq.specifier,
+-						oirq.size, &hwirq, &flags);
++			ops->xlate(mpic->irqhost, NULL, oirq.args,
++						oirq.args_count, &hwirq, &flags);
+ 			msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
+ 		}
+ 	}
+--- a/arch/x86/kernel/devicetree.c
++++ b/arch/x86/kernel/devicetree.c
+@@ -106,7 +106,7 @@ struct device_node *pcibios_get_phb_of_n
+ 
+ static int x86_of_pci_irq_enable(struct pci_dev *dev)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	u32 virq;
+ 	int ret;
+ 	u8 pin;
+@@ -121,8 +121,7 @@ static int x86_of_pci_irq_enable(struct
+ 	if (ret)
+ 		return ret;
+ 
+-	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+-			oirq.size);
++	virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ 	if (virq == 0)
+ 		return -EINVAL;
+ 	dev->irq = virq;
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -36,13 +36,12 @@
+  */
+ unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 
+ 	if (of_irq_parse_one(dev, index, &oirq))
+ 		return 0;
+ 
+-	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+-				     oirq.size);
++	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ }
+ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+ 
+@@ -94,7 +93,7 @@ struct device_node *of_irq_find_parent(s
+  * node exist for the parent.
+  */
+ int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+-		   u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
++		   u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+ 	const __be32 *tmp, *imap, *imask;
+@@ -156,10 +155,10 @@ int of_irq_parse_raw(struct device_node
+ 				NULL) {
+ 			pr_debug(" -> got it !\n");
+ 			for (i = 0; i < intsize; i++)
+-				out_irq->specifier[i] =
++				out_irq->args[i] =
+ 						of_read_number(intspec +i, 1);
+-			out_irq->size = intsize;
+-			out_irq->controller = ipar;
++			out_irq->args_count = intsize;
++			out_irq->np = ipar;
+ 			of_node_put(old);
+ 			return 0;
+ 		}
+@@ -280,7 +279,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw);
+  * This function resolves an interrupt, walking the tree, for a given
+  * device-tree node. It's the high level pendant to of_irq_parse_raw().
+  */
+-int of_irq_parse_one(struct device_node *device, int index, struct of_irq *out_irq)
++int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *p;
+ 	const __be32 *intspec, *tmp, *addr;
+--- a/drivers/of/of_pci_irq.c
++++ b/drivers/of/of_pci_irq.c
+@@ -15,7 +15,7 @@
+  * PCI tree until an device-node is found, at which point it will finish
+  * resolving using the OF tree walking.
+  */
+-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq)
++int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *dn, *ppnode;
+ 	struct pci_dev *ppdev;
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -649,15 +649,14 @@ static int __init mvebu_pcie_setup(int n
+ 
+ static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+-	struct of_irq oirq;
++	struct of_phandle_args oirq;
+ 	int ret;
+ 
+ 	ret = of_irq_parse_pci(dev, &oirq);
+ 	if (ret)
+ 		return ret;
+ 
+-	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+-				     oirq.size);
++	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
+ }
+ 
+ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -8,22 +8,6 @@
+ #include <linux/ioport.h>
+ #include <linux/of.h>
+ 
+-/**
+- * of_irq - container for device_node/irq_specifier pair for an irq controller
+- * @controller: pointer to interrupt controller device tree node
+- * @size: size of interrupt specifier
+- * @specifier: array of cells @size long specifing the specific interrupt
+- *
+- * This structure is returned when an interrupt is mapped. The controller
+- * field needs to be put() after use
+- */
+-#define OF_MAX_IRQ_SPEC		4 /* We handle specifiers of at most 4 cells */
+-struct of_irq {
+-	struct device_node *controller; /* Interrupt controller node */
+-	u32 size; /* Specifier size */
+-	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
+-};
+-
+ typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+ 
+ /*
+@@ -36,12 +20,12 @@ typedef int (*of_irq_init_cb_t)(struct d
+ extern unsigned int of_irq_workarounds;
+ extern struct device_node *of_irq_dflt_pic;
+ extern int of_irq_parse_oldworld(struct device_node *device, int index,
+-			       struct of_irq *out_irq);
++			       struct of_phandle_args *out_irq);
+ #else /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+ #define of_irq_workarounds (0)
+ #define of_irq_dflt_pic (NULL)
+ static inline int of_irq_parse_oldworld(struct device_node *device, int index,
+-				      struct of_irq *out_irq)
++				      struct of_phandle_args *out_irq)
+ {
+ 	return -EINVAL;
+ }
+@@ -50,9 +34,9 @@ static inline int of_irq_parse_oldworld(
+ 
+ extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+ 			  u32 ointsize, const __be32 *addr,
+-			  struct of_irq *out_irq);
++			  struct of_phandle_args *out_irq);
+ extern int of_irq_parse_one(struct device_node *device, int index,
+-			  struct of_irq *out_irq);
++			  struct of_phandle_args *out_irq);
+ extern unsigned int irq_create_of_mapping(struct device_node *controller,
+ 					  const u32 *intspec,
+ 					  unsigned int intsize);
+--- a/include/linux/of_pci.h
++++ b/include/linux/of_pci.h
+@@ -5,8 +5,8 @@
+ #include <linux/msi.h>
+ 
+ struct pci_dev;
+-struct of_irq;
+-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
++struct of_phandle_args;
++int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);
+ 
+ struct device_node;
+ struct device_node *of_pci_find_child_device(struct device_node *parent,
diff --git a/target/linux/mvebu/patches-3.10/0185-of-irq-simplify-args-to-irq_create_of_mapping.patch b/target/linux/mvebu/patches-3.10/0185-of-irq-simplify-args-to-irq_create_of_mapping.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2de7e7b6742f4257078241ae226a02243e2ce19f
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0185-of-irq-simplify-args-to-irq_create_of_mapping.patch
@@ -0,0 +1,245 @@
+From 5e69ff59f7e51ddfde0b31587beb9e40ea1c85bc Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:56 -0300
+Subject: [PATCH 185/203] of/irq: simplify args to irq_create_of_mapping
+
+All the callers of irq_create_of_mapping() pass the contents of a struct
+of_phandle_args structure to the function. Since all the callers already
+have an of_phandle_args pointer, why not pass it directly to
+irq_create_of_mapping()?
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Michal Simek <monstr@monstr.eu>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Russell King <linux@arm.linux.org.uk>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+Conflicts:
+	arch/mips/pci/pci-rt3883.c
+	kernel/irq/irqdomain.c
+---
+ arch/arm/mach-integrator/pci_v3.c              |  2 +-
+ arch/microblaze/pci/pci-common.c               |  2 +-
+ arch/mips/pci/fixup-lantiq.c                   |  2 +-
+ arch/powerpc/kernel/pci-common.c               |  2 +-
+ arch/powerpc/platforms/cell/celleb_scc_pciex.c |  2 +-
+ arch/powerpc/platforms/cell/celleb_scc_sio.c   |  2 +-
+ arch/powerpc/platforms/cell/spider-pic.c       |  7 ++-----
+ arch/powerpc/platforms/cell/spu_manage.c       |  3 +--
+ arch/powerpc/platforms/fsl_uli1575.c           |  2 +-
+ arch/powerpc/platforms/pseries/event_sources.c |  3 +--
+ arch/x86/kernel/devicetree.c                   |  2 +-
+ drivers/of/irq.c                               |  2 +-
+ drivers/pci/host/pci-mvebu.c                   |  2 +-
+ include/linux/of_irq.h                         |  4 +---
+ kernel/irq/irqdomain.c                         | 15 +++++++--------
+ 15 files changed, 22 insertions(+), 30 deletions(-)
+
+--- a/arch/arm/mach-integrator/pci_v3.c
++++ b/arch/arm/mach-integrator/pci_v3.c
+@@ -694,7 +694,7 @@ static int __init pci_v3_map_irq_dt(cons
+ 		return 0;
+ 	}
+ 
+-	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	return irq_create_of_mapping(&oirq);
+ }
+ 
+ static int __init pci_v3_dtprobe(struct platform_device *pdev,
+--- a/arch/microblaze/pci/pci-common.c
++++ b/arch/microblaze/pci/pci-common.c
+@@ -246,7 +246,7 @@ int pci_read_irq_line(struct pci_dev *pc
+ 			 oirq.args_count, oirq.args[0], oirq.args[1],
+ 			 of_node_full_name(oirq.np));
+ 
+-		virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++		virq = irq_create_of_mapping(&oirq);
+ 	}
+ 	if (!virq) {
+ 		pr_debug(" Failed to map !\n");
+--- a/arch/mips/pci/fixup-lantiq.c
++++ b/arch/mips/pci/fixup-lantiq.c
+@@ -33,7 +33,7 @@ int __init pcibios_map_irq(const struct
+ 			slot, pin);
+ 		return 0;
+ 	}
+-	irq = irq_create_of_mapping(dev_irq.np, dev_irq.args, dev_irq.args_count);
++	irq = irq_create_of_mapping(&dev_irq);
+ 	dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
+ 	return irq;
+ }
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -266,7 +266,7 @@ static int pci_read_irq_line(struct pci_
+ 			 oirq.args_count, oirq.args[0], oirq.args[1],
+ 			 of_node_full_name(oirq.np));
+ 
+-		virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++		virq = irq_create_of_mapping(&oirq);
+ 	}
+ 	if(virq == NO_IRQ) {
+ 		pr_debug(" Failed to map !\n");
+--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+@@ -511,7 +511,7 @@ static __init int celleb_setup_pciex(str
+ 		pr_err("PCIEXC:Failed to map irq\n");
+ 		goto error;
+ 	}
+-	virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	virq = irq_create_of_mapping(&oirq);
+ 	if (request_irq(virq, pciex_handle_internal_irq,
+ 			0, "pciex", (void *)phb)) {
+ 		pr_err("PCIEXC:Failed to request irq\n");
+--- a/arch/powerpc/platforms/cell/celleb_scc_sio.c
++++ b/arch/powerpc/platforms/cell/celleb_scc_sio.c
+@@ -66,7 +66,7 @@ static int __init txx9_serial_init(void)
+ #ifdef CONFIG_SERIAL_TXX9_CONSOLE
+ 			req.membase = ioremap(req.mapbase, 0x24);
+ #endif
+-			req.irq = irq_create_of_mapping(irq.np, irq.args, irq.args_count);
++			req.irq = irq_create_of_mapping(&irq);
+ 			req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
+ 				/*HAVE_CTS_LINE*/;
+ 			req.uartclk = 83300000;
+--- a/arch/powerpc/platforms/cell/spider-pic.c
++++ b/arch/powerpc/platforms/cell/spider-pic.c
+@@ -236,11 +236,8 @@ static unsigned int __init spider_find_c
+ 	 * tree in case the device-tree is ever fixed
+ 	 */
+ 	struct of_phandle_args oirq;
+-	if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0) {
+-		virq = irq_create_of_mapping(oirq.np, oirq.args,
+-					     oirq.args_count);
+-		return virq;
+-	}
++	if (of_irq_parse_one(pic->host->of_node, 0, &oirq) == 0)
++		return irq_create_of_mapping(&oirq);
+ 
+ 	/* Now do the horrible hacks */
+ 	tmp = of_get_property(pic->host->of_node, "#interrupt-cells", NULL);
+--- a/arch/powerpc/platforms/cell/spu_manage.c
++++ b/arch/powerpc/platforms/cell/spu_manage.c
+@@ -190,8 +190,7 @@ static int __init spu_map_interrupts(str
+ 		ret = -EINVAL;
+ 		pr_debug("  irq %d no 0x%x on %s\n", i, oirq.args[0],
+ 			 oirq.np->full_name);
+-		spu->irqs[i] = irq_create_of_mapping(oirq.np,
+-					oirq.args, oirq.args_count);
++		spu->irqs[i] = irq_create_of_mapping(&oirq);
+ 		if (spu->irqs[i] == NO_IRQ) {
+ 			pr_debug("spu_new: failed to map it !\n");
+ 			goto err;
+--- a/arch/powerpc/platforms/fsl_uli1575.c
++++ b/arch/powerpc/platforms/fsl_uli1575.c
+@@ -334,7 +334,7 @@ static void hpcd_final_uli5288(struct pc
+ 	laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
+ 	laddr[1] = laddr[2] = 0;
+ 	of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq);
+-	dev->irq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	dev->irq = irq_create_of_mapping(&oirq);
+ }
+ 
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575);
+--- a/arch/powerpc/platforms/pseries/event_sources.c
++++ b/arch/powerpc/platforms/pseries/event_sources.c
+@@ -59,8 +59,7 @@ void request_event_sources_irqs(struct d
+ 		     index++) {
+ 			if (count > 15)
+ 				break;
+-			virqs[count] = irq_create_of_mapping(oirq.np, oirq.args,
+-							    oirq.args_count);
++			virqs[count] = irq_create_of_mapping(&oirq);
+ 			if (virqs[count] == NO_IRQ) {
+ 				pr_err("event-sources: Unable to allocate "
+ 				       "interrupt number for %s\n",
+--- a/arch/x86/kernel/devicetree.c
++++ b/arch/x86/kernel/devicetree.c
+@@ -121,7 +121,7 @@ static int x86_of_pci_irq_enable(struct
+ 	if (ret)
+ 		return ret;
+ 
+-	virq = irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	virq = irq_create_of_mapping(&oirq);
+ 	if (virq == 0)
+ 		return -EINVAL;
+ 	dev->irq = virq;
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -41,7 +41,7 @@ unsigned int irq_of_parse_and_map(struct
+ 	if (of_irq_parse_one(dev, index, &oirq))
+ 		return 0;
+ 
+-	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	return irq_create_of_mapping(&oirq);
+ }
+ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
+ 
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -656,7 +656,7 @@ static int __init mvebu_pcie_map_irq(con
+ 	if (ret)
+ 		return ret;
+ 
+-	return irq_create_of_mapping(oirq.np, oirq.args, oirq.args_count);
++	return irq_create_of_mapping(&oirq);
+ }
+ 
+ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -37,9 +37,7 @@ extern int of_irq_parse_raw(struct devic
+ 			  struct of_phandle_args *out_irq);
+ extern int of_irq_parse_one(struct device_node *device, int index,
+ 			  struct of_phandle_args *out_irq);
+-extern unsigned int irq_create_of_mapping(struct device_node *controller,
+-					  const u32 *intspec,
+-					  unsigned int intsize);
++extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
+ extern int of_irq_to_resource(struct device_node *dev, int index,
+ 			      struct resource *r);
+ extern int of_irq_count(struct device_node *dev);
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -655,15 +655,14 @@ int irq_create_strict_mappings(struct ir
+ }
+ EXPORT_SYMBOL_GPL(irq_create_strict_mappings);
+ 
+-unsigned int irq_create_of_mapping(struct device_node *controller,
+-				   const u32 *intspec, unsigned int intsize)
++unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data)
+ {
+ 	struct irq_domain *domain;
+ 	irq_hw_number_t hwirq;
+ 	unsigned int type = IRQ_TYPE_NONE;
+ 	unsigned int virq;
+ 
+-	domain = controller ? irq_find_host(controller) : irq_default_domain;
++	domain = irq_data->np ? irq_find_host(irq_data->np) : irq_default_domain;
+ 	if (!domain) {
+ #ifdef CONFIG_MIPS
+ 		/*
+@@ -677,17 +676,17 @@ unsigned int irq_create_of_mapping(struc
+ 		if (intsize > 0)
+ 			return intspec[0];
+ #endif
+-		pr_warning("no irq domain found for %s !\n",
+-			   of_node_full_name(controller));
++		pr_warn("no irq domain found for %s !\n",
++			of_node_full_name(irq_data->np));
+ 		return 0;
+ 	}
+ 
+ 	/* If domain has no translation, then we assume interrupt line */
+ 	if (domain->ops->xlate == NULL)
+-		hwirq = intspec[0];
++		hwirq = irq_data->args[0];
+ 	else {
+-		if (domain->ops->xlate(domain, controller, intspec, intsize,
+-				     &hwirq, &type))
++		if (domain->ops->xlate(domain, irq_data->np, irq_data->args,
++					irq_data->args_count, &hwirq, &type))
+ 			return 0;
+ 	}
+ 
diff --git a/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch b/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7f17bb737b4b64131185ccbb5d1676b0e8192cfa
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0186-of-irq-Refactor-interrupt-map-parsing.patch
@@ -0,0 +1,287 @@
+From 44ad702902e9e274f57edce8944e46540b978f9a Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:57 -0300
+Subject: [PATCH 186/203] of/irq: Refactor interrupt-map parsing
+
+All the users of of_irq_parse_raw pass in a raw interrupt specifier from
+the device tree and expect it to be returned (possibly modified) in an
+of_phandle_args structure. However, the primary function of
+of_irq_parse_raw() is to check for translations due to the presence of
+one or more interrupt-map properties. The actual placing of the data
+into an of_phandle_args structure is trivial. If it is refactored to
+accept an of_phandle_args structure directly, then it becomes possible
+to consume of_phandle_args from other sources. This is important for an
+upcoming patch that allows a device to be connected to more than one
+interrupt parent. It also simplifies the code a bit.
+
+The biggest complication with this patch is that the old version works
+on the interrupt specifiers in __be32 form, but the of_phandle_args
+structure is intended to carry it in the cpu-native version. A bit of
+churn was required to make this work. In the end it results in tighter
+code, so the churn is worth it.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+---
+ arch/powerpc/platforms/fsl_uli1575.c |   6 +-
+ drivers/of/irq.c                     | 108 ++++++++++++++++++-----------------
+ drivers/of/of_pci_irq.c              |   7 ++-
+ include/linux/of_irq.h               |   5 +-
+ 4 files changed, 67 insertions(+), 59 deletions(-)
+
+--- a/arch/powerpc/platforms/fsl_uli1575.c
++++ b/arch/powerpc/platforms/fsl_uli1575.c
+@@ -322,7 +322,6 @@ static void hpcd_final_uli5288(struct pc
+ 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+ 	struct device_node *hosenode = hose ? hose->dn : NULL;
+ 	struct of_phandle_args oirq;
+-	int pin = 2;
+ 	u32 laddr[3];
+ 
+ 	if (!machine_is(mpc86xx_hpcd))
+@@ -331,9 +330,12 @@ static void hpcd_final_uli5288(struct pc
+ 	if (!hosenode)
+ 		return;
+ 
++	oirq.np = hosenode;
++	oirq.args[0] = 2;
++	oirq.args_count = 1;
+ 	laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
+ 	laddr[1] = laddr[2] = 0;
+-	of_irq_parse_raw(hosenode, &pin, 1, laddr, &oirq);
++	of_irq_parse_raw(laddr, &oirq);
+ 	dev->irq = irq_create_of_mapping(&oirq);
+ }
+ 
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -80,31 +80,32 @@ struct device_node *of_irq_find_parent(s
+ /**
+  * of_irq_parse_raw - Low level interrupt tree parsing
+  * @parent:	the device interrupt parent
+- * @intspec:	interrupt specifier ("interrupts" property of the device)
+- * @ointsize:   size of the passed in interrupt specifier
+- * @addr:	address specifier (start of "reg" property of the device)
+- * @out_irq:	structure of_irq filled by this function
++ * @addr:	address specifier (start of "reg" property of the device) in be32 format
++ * @out_irq:	structure of_irq updated by this function
+  *
+  * Returns 0 on success and a negative number on error
+  *
+  * This function is a low-level interrupt tree walking function. It
+  * can be used to do a partial walk with synthetized reg and interrupts
+  * properties, for example when resolving PCI interrupts when no device
+- * node exist for the parent.
++ * node exist for the parent. It takes an interrupt specifier structure as
++ * input, walks the tree looking for any interrupt-map properties, translates
++ * the specifier for each map, and then returns the translated map.
+  */
+-int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+-		   u32 ointsize, const __be32 *addr, struct of_phandle_args *out_irq)
++int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+-	const __be32 *tmp, *imap, *imask;
++	__be32 initial_match_array[8];
++	const __be32 *match_array = initial_match_array;
++	const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 };
+ 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ 	int imaplen, match, i;
+ 
+ 	pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+-		 of_node_full_name(parent), be32_to_cpup(intspec),
+-		 be32_to_cpup(intspec + 1), ointsize);
++		 of_node_full_name(out_irq->np), out_irq->args[0], out_irq->args[1],
++		 out_irq->args_count);
+ 
+-	ipar = of_node_get(parent);
++	ipar = of_node_get(out_irq->np);
+ 
+ 	/* First get the #interrupt-cells property of the current cursor
+ 	 * that tells us how to interpret the passed-in intspec. If there
+@@ -127,7 +128,7 @@ int of_irq_parse_raw(struct device_node
+ 
+ 	pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
+ 
+-	if (ointsize != intsize)
++	if (out_irq->args_count != intsize)
+ 		return -EINVAL;
+ 
+ 	/* Look for this #address-cells. We have to implement the old linux
+@@ -146,6 +147,21 @@ int of_irq_parse_raw(struct device_node
+ 
+ 	pr_debug(" -> addrsize=%d\n", addrsize);
+ 
++	/* If we were passed no "reg" property and we attempt to parse
++	 * an interrupt-map, then #address-cells must be 0.
++	 * Fail if it's not.
++	 */
++	if (addr == NULL && addrsize != 0) {
++		pr_debug(" -> no reg passed in when needed !\n");
++		return -EINVAL;
++	}
++
++	/* Precalculate the match array - this simplifies match loop */
++	for (i = 0; i < addrsize; i++)
++		initial_match_array[i] = addr[i];
++	for (i = 0; i < intsize; i++)
++		initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
++
+ 	/* Now start the actual "proper" walk of the interrupt tree */
+ 	while (ipar != NULL) {
+ 		/* Now check if cursor is an interrupt-controller and if it is
+@@ -154,11 +170,6 @@ int of_irq_parse_raw(struct device_node
+ 		if (of_get_property(ipar, "interrupt-controller", NULL) !=
+ 				NULL) {
+ 			pr_debug(" -> got it !\n");
+-			for (i = 0; i < intsize; i++)
+-				out_irq->args[i] =
+-						of_read_number(intspec +i, 1);
+-			out_irq->args_count = intsize;
+-			out_irq->np = ipar;
+ 			of_node_put(old);
+ 			return 0;
+ 		}
+@@ -175,34 +186,16 @@ int of_irq_parse_raw(struct device_node
+ 
+ 		/* Look for a mask */
+ 		imask = of_get_property(ipar, "interrupt-map-mask", NULL);
+-
+-		/* If we were passed no "reg" property and we attempt to parse
+-		 * an interrupt-map, then #address-cells must be 0.
+-		 * Fail if it's not.
+-		 */
+-		if (addr == NULL && addrsize != 0) {
+-			pr_debug(" -> no reg passed in when needed !\n");
+-			goto fail;
+-		}
++		if (!imask)
++			imask = dummy_imask;
+ 
+ 		/* Parse interrupt-map */
+ 		match = 0;
+ 		while (imaplen > (addrsize + intsize + 1) && !match) {
+ 			/* Compare specifiers */
+ 			match = 1;
+-			for (i = 0; i < addrsize && match; ++i) {
+-				__be32 mask = imask ? imask[i]
+-						    : cpu_to_be32(0xffffffffu);
+-				match = ((addr[i] ^ imap[i]) & mask) == 0;
+-			}
+-			for (; i < (addrsize + intsize) && match; ++i) {
+-				__be32 mask = imask ? imask[i]
+-						    : cpu_to_be32(0xffffffffu);
+-				match =
+-				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
+-			}
+-			imap += addrsize + intsize;
+-			imaplen -= addrsize + intsize;
++			for (i = 0; i < (addrsize + intsize); i++, imaplen--)
++				match = !((match_array[i] ^ *imap++) & imask[i]);
+ 
+ 			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+ 
+@@ -247,12 +240,18 @@ int of_irq_parse_raw(struct device_node
+ 		if (!match)
+ 			goto fail;
+ 
+-		of_node_put(old);
+-		old = of_node_get(newpar);
++		/*
++		 * Successfully parsed an interrrupt-map translation; copy new
++		 * interrupt specifier into the out_irq structure
++		 */
++		of_node_put(out_irq->np);
++		out_irq->np = of_node_get(newpar);
++
++		match_array = imap - newaddrsize - newintsize;
++		for (i = 0; i < newintsize; i++)
++			out_irq->args[i] = be32_to_cpup(imap - newintsize + i);
++		out_irq->args_count = intsize = newintsize;
+ 		addrsize = newaddrsize;
+-		intsize = newintsize;
+-		intspec = imap - intsize;
+-		addr = intspec - addrsize;
+ 
+ 	skiplevel:
+ 		/* Iterate again with new parent */
+@@ -263,7 +262,7 @@ int of_irq_parse_raw(struct device_node
+ 	}
+  fail:
+ 	of_node_put(ipar);
+-	of_node_put(old);
++	of_node_put(out_irq->np);
+ 	of_node_put(newpar);
+ 
+ 	return -EINVAL;
+@@ -276,15 +275,16 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw);
+  * @index: index of the interrupt to resolve
+  * @out_irq: structure of_irq filled by this function
+  *
+- * This function resolves an interrupt, walking the tree, for a given
+- * device-tree node. It's the high level pendant to of_irq_parse_raw().
++ * This function resolves an interrupt for a node by walking the interrupt tree,
++ * finding which interrupt controller node it is attached to, and returning the
++ * interrupt specifier that can be used to retrieve a Linux IRQ number.
+  */
+ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *p;
+ 	const __be32 *intspec, *tmp, *addr;
+ 	u32 intsize, intlen;
+-	int res = -EINVAL;
++	int i, res = -EINVAL;
+ 
+ 	pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);
+ 
+@@ -326,9 +326,15 @@ int of_irq_parse_one(struct device_node
+ 	if ((index + 1) * intsize > intlen)
+ 		goto out;
+ 
+-	/* Get new specifier and map it */
+-	res = of_irq_parse_raw(p, intspec + index * intsize, intsize,
+-			     addr, out_irq);
++	/* Copy intspec into irq structure */
++	intspec += index * intsize;
++	out_irq->np = p;
++	out_irq->args_count = intsize;
++	for (i = 0; i < intsize; i++)
++		out_irq->args[i] = be32_to_cpup(intspec++);
++
++	/* Check if there are any interrupt-map translations to process */
++	res = of_irq_parse_raw(addr, out_irq);
+  out:
+ 	of_node_put(p);
+ 	return res;
+--- a/drivers/of/of_pci_irq.c
++++ b/drivers/of/of_pci_irq.c
+@@ -85,9 +85,12 @@ int of_irq_parse_pci(const struct pci_de
+ 		pdev = ppdev;
+ 	}
+ 
++	out_irq->np = ppnode;
++	out_irq->args_count = 1;
++	out_irq->args[0] = lspec;
+ 	lspec_be = cpu_to_be32(lspec);
+ 	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+-	laddr[1]  = laddr[2] = cpu_to_be32(0);
+-	return of_irq_parse_raw(ppnode, &lspec_be, 1, laddr, out_irq);
++	laddr[1] = laddr[2] = cpu_to_be32(0);
++	return of_irq_parse_raw(laddr, out_irq);
+ }
+ EXPORT_SYMBOL_GPL(of_irq_parse_pci);
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -31,10 +31,7 @@ static inline int of_irq_parse_oldworld(
+ }
+ #endif /* CONFIG_PPC32 && CONFIG_PPC_PMAC */
+ 
+-
+-extern int of_irq_parse_raw(struct device_node *parent, const __be32 *intspec,
+-			  u32 ointsize, const __be32 *addr,
+-			  struct of_phandle_args *out_irq);
++extern int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq);
+ extern int of_irq_parse_one(struct device_node *device, int index,
+ 			  struct of_phandle_args *out_irq);
+ extern unsigned int irq_create_of_mapping(struct of_phandle_args *irq_data);
diff --git a/target/linux/mvebu/patches-3.10/0187-of-Add-helper-for-printing-an-of_phandle_args-struct.patch b/target/linux/mvebu/patches-3.10/0187-of-Add-helper-for-printing-an-of_phandle_args-struct.patch
new file mode 100644
index 0000000000000000000000000000000000000000..064e9a2b16bcef253f82d27742ee40639c26d459
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0187-of-Add-helper-for-printing-an-of_phandle_args-struct.patch
@@ -0,0 +1,62 @@
+From 061855025b6842debdf6ea2e8bfd86f50700e263 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:30:58 -0300
+Subject: [PATCH 187/203] of: Add helper for printing an of_phandle_args
+ structure
+
+It is sometimes useful for debug to get the contents of an
+of_phandle_args structure out into the kernel log.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+
+Conflicts:
+	drivers/of/base.c
+---
+ drivers/of/base.c  | 9 +++++++++
+ drivers/of/irq.c   | 6 +++---
+ include/linux/of.h | 1 +
+ 3 files changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -1136,6 +1136,15 @@ EXPORT_SYMBOL(of_parse_phandle);
+  * To get a device_node of the `node2' node you may call this:
+  * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
+  */
++void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
++{
++	int i;
++	printk("%s %s", msg, of_node_full_name(args->np));
++	for (i = 0; i < args->args_count; i++)
++		printk(i ? ",%08x" : ":%08x", args->args[i]);
++	printk("\n");
++}
++
+ static int __of_parse_phandle_with_args(const struct device_node *np,
+ 					const char *list_name,
+ 					const char *cells_name, int index,
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -101,9 +101,9 @@ int of_irq_parse_raw(const __be32 *addr,
+ 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ 	int imaplen, match, i;
+ 
+-	pr_debug("of_irq_parse_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
+-		 of_node_full_name(out_irq->np), out_irq->args[0], out_irq->args[1],
+-		 out_irq->args_count);
++#ifdef DEBUG
++	of_print_phandle_args("of_irq_parse_raw: ", out_irq);
++#endif
+ 
+ 	ipar = of_node_get(out_irq->np);
+ 
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -274,6 +274,7 @@ extern int of_n_size_cells(struct device
+ extern const struct of_device_id *of_match_node(
+ 	const struct of_device_id *matches, const struct device_node *node);
+ extern int of_modalias_node(struct device_node *node, char *modalias, int len);
++extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args);
+ extern struct device_node *of_parse_phandle(const struct device_node *np,
+ 					    const char *phandle_name,
+ 					    int index);
diff --git a/target/linux/mvebu/patches-3.10/0188-of-irq-Rework-of_irq_count.patch b/target/linux/mvebu/patches-3.10/0188-of-irq-Rework-of_irq_count.patch
new file mode 100644
index 0000000000000000000000000000000000000000..39fc79488b0d987eb6588782f7b635f24a5551d9
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0188-of-irq-Rework-of_irq_count.patch
@@ -0,0 +1,36 @@
+From 3665853921092bb68aa0929efb3a94ecdfc96782 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <thierry.reding@gmail.com>
+Date: Thu, 19 Dec 2013 09:30:59 -0300
+Subject: [PATCH 188/203] of/irq: Rework of_irq_count()
+
+The of_irq_to_resource() helper that is used to implement of_irq_count()
+tries to resolve interrupts and in fact creates a mapping for resolved
+interrupts. That's pretty heavy lifting for something that claims to
+just return the number of interrupts requested by a given device node.
+
+Instead, use the more lightweight of_irq_map_one(), which, despite the
+name, doesn't create an actual mapping. Perhaps a better name would be
+of_irq_translate_one().
+
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Acked-by: Rob Herring <rob.herring@calxeda.com>
+[grant.likely: fixup s/of_irq_map_one/of_irq_parse_one/]
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+---
+ drivers/of/irq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -379,9 +379,10 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
+  */
+ int of_irq_count(struct device_node *dev)
+ {
++	struct of_phandle_args irq;
+ 	int nr = 0;
+ 
+-	while (of_irq_to_resource(dev, nr, NULL))
++	while (of_irq_parse_one(dev, nr, &irq) == 0)
+ 		nr++;
+ 
+ 	return nr;
diff --git a/target/linux/mvebu/patches-3.10/0189-of-irq-create-interrupts-extended-property.patch b/target/linux/mvebu/patches-3.10/0189-of-irq-create-interrupts-extended-property.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7e2e2baa336943d9a042d4eb5f6ab28425cc0d9b
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0189-of-irq-create-interrupts-extended-property.patch
@@ -0,0 +1,192 @@
+From efd4032754a57bc258eafe30fde684ec47dc36e1 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:31:00 -0300
+Subject: [PATCH 189/203] of/irq: create interrupts-extended property
+
+The standard interrupts property in device tree can only handle
+interrupts coming from a single interrupt parent. If a device is wired
+to multiple interrupt controllers, then it needs to be attached to a
+node with an interrupt-map property to demux the interrupt specifiers
+which is confusing. It would be a lot easier if there was a form of the
+interrupts property that allows for a separate interrupt phandle for
+each interrupt specifier.
+
+This patch does exactly that by creating a new interrupts-extended
+property which reuses the phandle+arguments pattern used by GPIOs and
+other core bindings.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Kumar Gala <galak@codeaurora.org>
+[grant.likely: removed versatile platform hunks into separate patch]
+Cc: Rob Herring <rob.herring@calxeda.com>
+
+Conflicts:
+	arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+	drivers/of/selftest.c
+---
+ drivers/of/selftest.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 145 insertions(+), 1 deletion(-)
+
+--- a/drivers/of/selftest.c
++++ b/drivers/of/selftest.c
+@@ -154,6 +154,147 @@ static void __init of_selftest_property_
+ 	selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
+ }
+ 
++static void __init of_selftest_parse_interrupts(void)
++{
++	struct device_node *np;
++	struct of_phandle_args args;
++	int i, rc;
++
++	np = of_find_node_by_path("/testcase-data/interrupts/interrupts0");
++	if (!np) {
++		pr_err("missing testcase data\n");
++		return;
++	}
++
++	for (i = 0; i < 4; i++) {
++		bool passed = true;
++		args.args_count = 0;
++		rc = of_irq_parse_one(np, i, &args);
++
++		passed &= !rc;
++		passed &= (args.args_count == 1);
++		passed &= (args.args[0] == (i + 1));
++
++		selftest(passed, "index %i - data error on node %s rc=%i\n",
++			 i, args.np->full_name, rc);
++	}
++	of_node_put(np);
++
++	np = of_find_node_by_path("/testcase-data/interrupts/interrupts1");
++	if (!np) {
++		pr_err("missing testcase data\n");
++		return;
++	}
++
++	for (i = 0; i < 4; i++) {
++		bool passed = true;
++		args.args_count = 0;
++		rc = of_irq_parse_one(np, i, &args);
++
++		/* Test the values from tests-phandle.dtsi */
++		switch (i) {
++		case 0:
++			passed &= !rc;
++			passed &= (args.args_count == 1);
++			passed &= (args.args[0] == 9);
++			break;
++		case 1:
++			passed &= !rc;
++			passed &= (args.args_count == 3);
++			passed &= (args.args[0] == 10);
++			passed &= (args.args[1] == 11);
++			passed &= (args.args[2] == 12);
++			break;
++		case 2:
++			passed &= !rc;
++			passed &= (args.args_count == 2);
++			passed &= (args.args[0] == 13);
++			passed &= (args.args[1] == 14);
++			break;
++		case 3:
++			passed &= !rc;
++			passed &= (args.args_count == 2);
++			passed &= (args.args[0] == 15);
++			passed &= (args.args[1] == 16);
++			break;
++		default:
++			passed = false;
++		}
++		selftest(passed, "index %i - data error on node %s rc=%i\n",
++			 i, args.np->full_name, rc);
++	}
++	of_node_put(np);
++}
++
++static void __init of_selftest_parse_interrupts_extended(void)
++{
++	struct device_node *np;
++	struct of_phandle_args args;
++	int i, rc;
++
++	np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0");
++	if (!np) {
++		pr_err("missing testcase data\n");
++		return;
++	}
++
++	for (i = 0; i < 7; i++) {
++		bool passed = true;
++		rc = of_irq_parse_one(np, i, &args);
++
++		/* Test the values from tests-phandle.dtsi */
++		switch (i) {
++		case 0:
++			passed &= !rc;
++			passed &= (args.args_count == 1);
++			passed &= (args.args[0] == 1);
++			break;
++		case 1:
++			passed &= !rc;
++			passed &= (args.args_count == 3);
++			passed &= (args.args[0] == 2);
++			passed &= (args.args[1] == 3);
++			passed &= (args.args[2] == 4);
++			break;
++		case 2:
++			passed &= !rc;
++			passed &= (args.args_count == 2);
++			passed &= (args.args[0] == 5);
++			passed &= (args.args[1] == 6);
++			break;
++		case 3:
++			passed &= !rc;
++			passed &= (args.args_count == 1);
++			passed &= (args.args[0] == 9);
++			break;
++		case 4:
++			passed &= !rc;
++			passed &= (args.args_count == 3);
++			passed &= (args.args[0] == 10);
++			passed &= (args.args[1] == 11);
++			passed &= (args.args[2] == 12);
++			break;
++		case 5:
++			passed &= !rc;
++			passed &= (args.args_count == 2);
++			passed &= (args.args[0] == 13);
++			passed &= (args.args[1] == 14);
++			break;
++		case 6:
++			passed &= !rc;
++			passed &= (args.args_count == 1);
++			passed &= (args.args[0] == 15);
++			break;
++		default:
++			passed = false;
++		}
++
++		selftest(passed, "index %i - data error on node %s rc=%i\n",
++			 i, args.np->full_name, rc);
++	}
++	of_node_put(np);
++}
++
+ static int __init of_selftest(void)
+ {
+ 	struct device_node *np;
+@@ -168,7 +309,10 @@ static int __init of_selftest(void)
+ 	pr_info("start of selftest - you will see error messages\n");
+ 	of_selftest_parse_phandle_with_args();
+ 	of_selftest_property_match_string();
+-	pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
++	of_selftest_parse_interrupts();
++	of_selftest_parse_interrupts_extended();
++	pr_info("end of selftest - %i passed, %i failed\n",
++		selftest_results.passed, selftest_results.failed);
+ 	return 0;
+ }
+ late_initcall(of_selftest);
diff --git a/target/linux/mvebu/patches-3.10/0190-of-irq-Fix-bug-in-interrupt-parsing-refactor.patch b/target/linux/mvebu/patches-3.10/0190-of-irq-Fix-bug-in-interrupt-parsing-refactor.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5e1e6053b88cbcd3800fe130beb19b4a2dcfb02a
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0190-of-irq-Fix-bug-in-interrupt-parsing-refactor.patch
@@ -0,0 +1,60 @@
+From 1c67d6e7cc30a856e79664e0be3a1f705bad56e4 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:31:01 -0300
+Subject: [PATCH 190/203] of/irq: Fix bug in interrupt parsing refactor.
+
+Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced
+a bug. The irq parsing will fail for some nodes that don't have a reg
+property. It is fixed by deferring the check for reg until it is
+actually needed. Also adjust the testcase data to catch the bug.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Tested-by: Stephen Warren <swarren@nvidia.com>
+Tested-by: Ming Lei <tom.leiming@gmail.com>
+Tested-by: Stephen Warren <swarren@nvidia.com>
+Cc: Rob Herring <rob.herring@calxeda.com>
+
+Conflicts:
+	arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+---
+ drivers/of/irq.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -147,18 +147,9 @@ int of_irq_parse_raw(const __be32 *addr,
+ 
+ 	pr_debug(" -> addrsize=%d\n", addrsize);
+ 
+-	/* If we were passed no "reg" property and we attempt to parse
+-	 * an interrupt-map, then #address-cells must be 0.
+-	 * Fail if it's not.
+-	 */
+-	if (addr == NULL && addrsize != 0) {
+-		pr_debug(" -> no reg passed in when needed !\n");
+-		return -EINVAL;
+-	}
+-
+ 	/* Precalculate the match array - this simplifies match loop */
+ 	for (i = 0; i < addrsize; i++)
+-		initial_match_array[i] = addr[i];
++		initial_match_array[i] = addr ? addr[i] : 0;
+ 	for (i = 0; i < intsize; i++)
+ 		initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]);
+ 
+@@ -174,6 +165,15 @@ int of_irq_parse_raw(const __be32 *addr,
+ 			return 0;
+ 		}
+ 
++		/*
++		 * interrupt-map parsing does not work without a reg
++		 * property when #address-cells != 0
++		 */
++		if (addrsize && !addr) {
++			pr_debug(" -> no reg passed in when needed !\n");
++			goto fail;
++		}
++
+ 		/* Now look for an interrupt-map */
+ 		imap = of_get_property(ipar, "interrupt-map", &imaplen);
+ 		/* No interrupt map, check for an interrupt parent */
diff --git a/target/linux/mvebu/patches-3.10/0191-of-irq-Fix-potential-buffer-overflow.patch b/target/linux/mvebu/patches-3.10/0191-of-irq-Fix-potential-buffer-overflow.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9c7908d7b930bc157f70d9be1c98252ba4580428
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0191-of-irq-Fix-potential-buffer-overflow.patch
@@ -0,0 +1,52 @@
+From 5a1bd82f089e19ba049a871a0d5538ed9eb5e5cd Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Thu, 19 Dec 2013 09:31:02 -0300
+Subject: [PATCH 191/203] of/irq: Fix potential buffer overflow
+
+Commit 2361613206e6, "of/irq: Refactor interrupt-map parsing" introduced
+a potential buffer overflow bug because it doesn't do sufficient range
+checking on the input data. This patch adds the appropriate checking and
+buffer size adjustments. If the bounds are out of range then warn
+loudly. MAX_PHANDLE_ARGS should be sufficient. If it is not then the
+value can be increased.
+
+Signed-off-by: Grant Likely <grant.likely@linaro.org>
+Cc: Rob Herring <rob.herring@calxeda.com>
+---
+ drivers/of/irq.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -95,9 +95,9 @@ struct device_node *of_irq_find_parent(s
+ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
+ {
+ 	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
+-	__be32 initial_match_array[8];
++	__be32 initial_match_array[MAX_PHANDLE_ARGS];
+ 	const __be32 *match_array = initial_match_array;
+-	const __be32 *tmp, *imap, *imask, dummy_imask[] = { ~0, ~0, ~0, ~0, ~0 };
++	const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 };
+ 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
+ 	int imaplen, match, i;
+ 
+@@ -147,6 +147,10 @@ int of_irq_parse_raw(const __be32 *addr,
+ 
+ 	pr_debug(" -> addrsize=%d\n", addrsize);
+ 
++	/* Range check so that the temporary buffer doesn't overflow */
++	if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS))
++		goto fail;
++
+ 	/* Precalculate the match array - this simplifies match loop */
+ 	for (i = 0; i < addrsize; i++)
+ 		initial_match_array[i] = addr ? addr[i] : 0;
+@@ -229,6 +233,8 @@ int of_irq_parse_raw(const __be32 *addr,
+ 			    newintsize, newaddrsize);
+ 
+ 			/* Check for malformed properties */
++			if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS))
++				goto fail;
+ 			if (imaplen < (newaddrsize + newintsize))
+ 				goto fail;
+ 
diff --git a/target/linux/mvebu/patches-3.10/0192-of-irq-Fix-interrupt-map-entry-matching.patch b/target/linux/mvebu/patches-3.10/0192-of-irq-Fix-interrupt-map-entry-matching.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3de0b146dd6dc5f31694e064ce9d3971677a8e3d
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0192-of-irq-Fix-interrupt-map-entry-matching.patch
@@ -0,0 +1,26 @@
+From 8413f9010508998c62969827850a7434a1d5716c Mon Sep 17 00:00:00 2001
+From: Tomasz Figa <t.figa@samsung.com>
+Date: Thu, 19 Dec 2013 09:31:03 -0300
+Subject: [PATCH 192/203] of: irq: Fix interrupt-map entry matching
+
+This patch fixes interrupt-map entry matching code to properly match all
+specifier cells with interrupt map entries.
+
+Signed-off-by: Tomasz Figa <t.figa@samsung.com>
+Tested-by: Sachin Kamat <sachin.kamat@linaro.org>
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+---
+ drivers/of/irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -199,7 +199,7 @@ int of_irq_parse_raw(const __be32 *addr,
+ 			/* Compare specifiers */
+ 			match = 1;
+ 			for (i = 0; i < (addrsize + intsize); i++, imaplen--)
+-				match = !((match_array[i] ^ *imap++) & imask[i]);
++				match &= !((match_array[i] ^ *imap++) & imask[i]);
+ 
+ 			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
+ 
diff --git a/target/linux/mvebu/patches-3.10/0193-clocksource-armada-370-xp-Fix-device-tree-binding.patch b/target/linux/mvebu/patches-3.10/0193-clocksource-armada-370-xp-Fix-device-tree-binding.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4ee7f3f56303b07463c5bcdb345ce499ff6732c0
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0193-clocksource-armada-370-xp-Fix-device-tree-binding.patch
@@ -0,0 +1,70 @@
+From ba47ab198541f6ed822b3c9691b392d83edba8b4 Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 13 Aug 2013 11:43:14 -0300
+Subject: [PATCH 193/203] clocksource: armada-370-xp: Fix device-tree binding
+
+This commit fixes the DT binding for the Armada 370/XP SoC timer.
+The previous "marvell,armada-370-xp-timer" compatible is removed and
+two new compatible strings are introduced: "marvell,armada-xp-timer"
+and "marvell,armada-370-timer".
+
+The rationale behind this change is that the Armada 370 SoC and the
+Armada XP SoC timers are not really compatible:
+
+  * Armada 370 has no 25 MHz fixed timer.
+
+  * Armada XP cannot work properly without such 25 MHz fixed timer
+    as doing otherwise leads to using a clocksource whose frequency
+    varies when doing cpufreq frequency changes.
+
+This commit also removes the "marvell,timer-25Mhz" property, given
+it's now meaningless.
+
+Cc: devicetree@vger.kernel.org
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ .../bindings/timer/marvell,armada-370-xp-timer.txt | 27 ++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 5 deletions(-)
+
+--- a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
++++ b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
+@@ -2,14 +2,31 @@ Marvell Armada 370 and Armada XP Timers
+ ---------------------------------------
+ 
+ Required properties:
+-- compatible: Should be "marvell,armada-370-xp-timer"
++- compatible: Should be either "marvell,armada-370-timer" or
++  "marvell,armada-xp-timer" as appropriate.
+ - interrupts: Should contain the list of Global Timer interrupts and
+   then local timer interrupts
+ - reg: Should contain location and length for timers register. First
+   pair for the Global Timer registers, second pair for the
+   local/private timers.
+-- clocks: clock driving the timer hardware
++- clocks: clock driving the timer hardware, only required for
++  "marvell,armada-370-timer";
+ 
+-Optional properties:
+-- marvell,timer-25Mhz: Tells whether the Global timer supports the 25
+-  Mhz fixed mode (available on Armada XP and not on Armada 370)
++Examples:
++
++- Armada 370:
++
++	timer {
++		compatible = "marvell,armada-370-timer";
++		reg = <0x20300 0x30>, <0x21040 0x30>;
++		interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
++		clocks = <&coreclk 2>;
++	};
++
++- Armada XP:
++
++	timer {
++		compatible = "marvell,armada-xp-timer";
++		reg = <0x20300 0x30>, <0x21040 0x30>;
++		interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
++	};
diff --git a/target/linux/mvebu/patches-3.10/0194-clocksource-armada-370-xp-Add-detailed-clock-require.patch b/target/linux/mvebu/patches-3.10/0194-clocksource-armada-370-xp-Add-detailed-clock-require.patch
new file mode 100644
index 0000000000000000000000000000000000000000..333f7b6a9d10551033e17650759e4a47b65f99f8
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0194-clocksource-armada-370-xp-Add-detailed-clock-require.patch
@@ -0,0 +1,47 @@
+From d569707433b26bb70f6b595a480bcfb3043a614c Mon Sep 17 00:00:00 2001
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 20 Aug 2013 12:45:54 -0300
+Subject: [PATCH 194/203] clocksource: armada-370-xp: Add detailed clock
+ requirements in devicetree binding
+
+Specifies the required clock inputs for each supported compatible.
+Armada 370 requires a single clock phandle, and Armada XP requires
+two clock phandles with clock-names "nbclk" and "fixed".
+
+Cc: devicetree@vger.kernel.org
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Jason Cooper <jason@lakedaemon.net>
+Acked-by: Stephen Warren <swarren@nvidia.com>
+Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+---
+ .../bindings/timer/marvell,armada-370-xp-timer.txt          | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
++++ b/Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
+@@ -9,8 +9,15 @@ Required properties:
+ - reg: Should contain location and length for timers register. First
+   pair for the Global Timer registers, second pair for the
+   local/private timers.
+-- clocks: clock driving the timer hardware, only required for
+-  "marvell,armada-370-timer";
++
++Clocks required for compatible = "marvell,armada-370-timer":
++- clocks : Must contain a single entry describing the clock input
++
++Clocks required for compatible = "marvell,armada-xp-timer":
++- clocks : Must contain an entry for each entry in clock-names.
++- clock-names : Must include the following entries:
++  "nbclk" (L2/coherency fabric clock),
++  "fixed" (Reference 25 MHz fixed-clock).
+ 
+ Examples:
+ 
+@@ -29,4 +36,6 @@ Examples:
+ 		compatible = "marvell,armada-xp-timer";
+ 		reg = <0x20300 0x30>, <0x21040 0x30>;
+ 		interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
++		clocks = <&coreclk 2>, <&refclk>;
++		clock-names = "nbclk", "fixed";
+ 	};
diff --git a/target/linux/mvebu/patches-3.10/0195-usb-Add-Device-Tree-support-to-XHCI-Platform-driver.patch b/target/linux/mvebu/patches-3.10/0195-usb-Add-Device-Tree-support-to-XHCI-Platform-driver.patch
new file mode 100644
index 0000000000000000000000000000000000000000..091c3a10a0f602d6c39239b16ff4da10c1dac9a2
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0195-usb-Add-Device-Tree-support-to-XHCI-Platform-driver.patch
@@ -0,0 +1,68 @@
+From 956b857c1fc80164859adbe1147704b1f352e153 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx@gmail.com>
+Date: Fri, 6 Dec 2013 00:18:25 +0100
+Subject: [PATCH 195/203] usb: Add Device Tree support to XHCI Platform driver
+
+Add Device Tree match table to xhci-plat.c. Add DT bindings document.
+
+Signed-off-by: Al Cooper <alcooperx@gmail.com>
+Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Cc: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+Conflicts:
+	drivers/usb/host/xhci-plat.c
+---
+ Documentation/devicetree/bindings/usb/usb-xhci.txt | 14 ++++++++++++++
+ drivers/usb/host/xhci-plat.c                       | 10 ++++++++++
+ 2 files changed, 24 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/usb/usb-xhci.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/usb/usb-xhci.txt
+@@ -0,0 +1,14 @@
++USB xHCI controllers
++
++Required properties:
++  - compatible: should be "xhci-platform".
++  - reg: should contain address and length of the standard XHCI
++    register set for the device.
++  - interrupts: one XHCI interrupt should be described here.
++
++Example:
++	usb@f0931000 {
++		compatible = "xhci-platform";
++		reg = <0xf0931000 0x8c8>;
++		interrupts = <0x0 0x4e 0x0>;
++	};
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -14,6 +14,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/of.h>
+ 
+ #include "xhci.h"
+ 
+@@ -186,11 +187,20 @@ static int xhci_plat_remove(struct platf
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_OF
++static const struct of_device_id usb_xhci_of_match[] = {
++	{ .compatible = "xhci-platform" },
++	{ },
++};
++MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
++#endif
++
+ static struct platform_driver usb_xhci_driver = {
+ 	.probe	= xhci_plat_probe,
+ 	.remove	= xhci_plat_remove,
+ 	.driver	= {
+ 		.name = "xhci-hcd",
++		.of_match_table = of_match_ptr(usb_xhci_of_match),
+ 	},
+ };
+ MODULE_ALIAS("platform:xhci-hcd");
diff --git a/target/linux/mvebu/patches-3.10/0196-ata-sata_mv-setting-PHY-speed-according-to-SControl-.patch b/target/linux/mvebu/patches-3.10/0196-ata-sata_mv-setting-PHY-speed-according-to-SControl-.patch
new file mode 100644
index 0000000000000000000000000000000000000000..8a3162ce966186caa027359dc687d612d1fcafcd
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0196-ata-sata_mv-setting-PHY-speed-according-to-SControl-.patch
@@ -0,0 +1,58 @@
+From d587c866f34aa8e59ddc3628969113e725e36eab Mon Sep 17 00:00:00 2001
+From: Lior Amsalem <alior@marvell.com>
+Date: Mon, 23 Dec 2013 13:07:35 +0100
+Subject: [PATCH 196/203] ata: sata_mv: setting PHY speed according to SControl
+ speed
+
+This patch fixes a SATA hotplug issue on the Armada 370 and Armada XP
+SoCs. Without it, if a disk is unplugged from a SATA port, then further
+hotplug notification are now longer received on this port.
+
+This should be applied to every -stable kernel supporting Armada SoCs.
+
+Signed-off-by: Lior Amsalem <alior@marvell.com>
+Signed-off-by: Nadav Haklai <nadavh@marvell.com>
+Signed-off-by: Simon Guinot <simon.guinot@sequanux.org>
+Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Cc: Jason Cooper <jason@lakedaemon.net>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Gregory Clement <gregory.clement@free-electrons.com>
+Cc: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Cc: stable@vger.kernel.org
+---
+ drivers/ata/sata_mv.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/ata/sata_mv.c
++++ b/drivers/ata/sata_mv.c
+@@ -304,6 +304,7 @@ enum {
+ 	MV5_LTMODE		= 0x30,
+ 	MV5_PHY_CTL		= 0x0C,
+ 	SATA_IFCFG		= 0x050,
++	LP_PHY_CTL		= 0x058,
+ 
+ 	MV_M2_PREAMP_MASK	= 0x7e0,
+ 
+@@ -1353,6 +1354,7 @@ static int mv_scr_write(struct ata_link
+ 
+ 	if (ofs != 0xffffffffU) {
+ 		void __iomem *addr = mv_ap_base(link->ap) + ofs;
++		void __iomem *lp_phy_addr = mv_ap_base(link->ap) + LP_PHY_CTL;
+ 		if (sc_reg_in == SCR_CONTROL) {
+ 			/*
+ 			 * Workaround for 88SX60x1 FEr SATA#26:
+@@ -1369,6 +1371,14 @@ static int mv_scr_write(struct ata_link
+ 			 */
+ 			if ((val & 0xf) == 1 || (readl(addr) & 0xf) == 1)
+ 				val |= 0xf000;
++
++			/*
++			 * Setting PHY speed according to SControl speed
++			 */
++			if ((val & 0xf0) == 0x10)
++				writelfl(0x7, lp_phy_addr);
++			else
++				writelfl(0x227, lp_phy_addr);
+ 		}
+ 		writelfl(val, addr);
+ 		return 0;
diff --git a/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch b/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch
new file mode 100644
index 0000000000000000000000000000000000000000..84fcbafb5b9cd03f634377120a87a8224d766686
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0197-xhci-fix-dma-mask-setup-in-xhci.c.patch
@@ -0,0 +1,124 @@
+From 5cb802766e9cdc9a56e8ce8e4686692ebbcfb5cc Mon Sep 17 00:00:00 2001
+From: Xenia Ragiadakou <burzalodowa@gmail.com>
+Date: Mon, 23 Dec 2013 16:59:02 +0100
+Subject: [PATCH 197/203] xhci: fix dma mask setup in xhci.c
+
+The function dma_set_mask() tests internally whether the dma_mask pointer
+for the device is initialized and fails if the dma_mask pointer is NULL.
+On pci platforms, the device dma_mask pointer is initialized, when pci
+devices are enumerated, to point to the pci_dev->dma_mask which is 0xffffffff.
+However, for non-pci platforms, the dma_mask pointer may not be initialized
+and in that case dma_set_mask() will fail.
+
+This patch initializes the dma_mask and the coherent_dma_mask to 32bits
+in xhci_plat_probe(), before the call to usb_create_hcd() that sets the
+"uses_dma" flag for the usb bus and the call to usb_add_hcd() that creates
+coherent dma pools for the usb hcd.
+
+Moreover, a call to dma_set_mask() does not set the device coherent_dma_mask.
+Since the xhci-hcd driver calls dma_alloc_coherent() and dma_pool_alloc()
+to allocate consistent DMA memory blocks, the coherent DMA address mask
+has to be set explicitly.
+
+This patch sets the coherent_dma_mask to 64bits in xhci_gen_setup() when
+the xHC is capable for 64-bit DMA addressing.
+
+If dma_set_mask() succeeds, for a given bitmask, it is guaranteed that
+the given bitmask is also supported for consistent DMA mappings.
+
+Other changes introduced in this patch are:
+
+- The return value of dma_set_mask() is checked to ensure that the required
+  dma bitmask conforms with the host system's addressing capabilities.
+
+- The dma_mask setup code for the non-primary hcd was removed since both
+  primary and non-primary hcd refer to the same generic device whose
+  dma_mask and coherent_dma_mask are already set during the setup of
+  the primary hcd.
+
+- The code for reading the HCCPARAMS register to find out the addressing
+  capabilities of xHC was removed since its value is already cached in
+  xhci->hccparams.
+
+- hcd->self.controller was replaced with the dev variable since it is
+  already available.
+
+Signed-off-by: Xenia Ragiadakou <burzalodowa@gmail.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+Conflicts:
+	drivers/usb/host/xhci-plat.c
+---
+ drivers/usb/host/xhci-plat.c | 10 ++++++++++
+ drivers/usb/host/xhci.c      | 19 +++++--------------
+ 2 files changed, 15 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/of.h>
++#include <linux/dma-mapping.h>
+ 
+ #include "xhci.h"
+ 
+@@ -105,6 +106,15 @@ static int xhci_plat_probe(struct platfo
+ 	if (!res)
+ 		return -ENODEV;
+ 
++	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
++	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
++	if (ret)
++		return ret;
++	if (!pdev->dev.dma_mask)
++		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++	else
++		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
++
+ 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+ 	if (!hcd)
+ 		return -ENOMEM;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4654,7 +4654,6 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ 	struct xhci_hcd		*xhci;
+ 	struct device		*dev = hcd->self.controller;
+ 	int			retval;
+-	u32			temp;
+ 
+ 	/* Accept arbitrarily long scatter-gather lists */
+ 	hcd->self.sg_tablesize = ~0;
+@@ -4682,14 +4681,6 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ 		/* xHCI private pointer was set in xhci_pci_probe for the second
+ 		 * registered roothub.
+ 		 */
+-		xhci = hcd_to_xhci(hcd);
+-		temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+-		if (HCC_64BIT_ADDR(temp)) {
+-			xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+-		} else {
+-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
+-		}
+ 		return 0;
+ 	}
+ 
+@@ -4728,12 +4719,12 @@ int xhci_gen_setup(struct usb_hcd *hcd,
+ 		goto error;
+ 	xhci_dbg(xhci, "Reset complete\n");
+ 
+-	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
+-	if (HCC_64BIT_ADDR(temp)) {
++	/* Set dma_mask and coherent_dma_mask to 64-bits,
++	 * if xHC supports 64-bit addressing */
++	if (HCC_64BIT_ADDR(xhci->hcc_params) &&
++			!dma_set_mask(dev, DMA_BIT_MASK(64))) {
+ 		xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
+-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
+-	} else {
+-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
++		dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+ 	}
+ 
+ 	xhci_dbg(xhci, "Calling HCD init\n");
diff --git a/target/linux/mvebu/patches-3.10/0198-of-Add-testcases-for-interrupt-parsing.patch b/target/linux/mvebu/patches-3.10/0198-of-Add-testcases-for-interrupt-parsing.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cbb9252f366f16af188344084c2ded68726558f5
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0198-of-Add-testcases-for-interrupt-parsing.patch
@@ -0,0 +1,104 @@
+From 39623dc5cb8814223e9580e22e78dfab10d91783 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@linaro.org>
+Date: Tue, 24 Dec 2013 11:36:02 +0100
+Subject: [PATCH 198/203] of: Add testcases for interrupt parsing
+
+This patch extends the DT selftest code with some test cases for the
+interrupt parsing functions.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+---
+ arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 41 +++++++++++++++++++++++
+ arch/arm/boot/dts/testcases/tests.dtsi            |  1 +
+ drivers/of/selftest.c                             | 15 ++++++---
+ 3 files changed, 52 insertions(+), 5 deletions(-)
+ create mode 100644 arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+
+--- /dev/null
++++ b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+@@ -0,0 +1,41 @@
++
++/ {
++	testcase-data {
++		interrupts {
++			#address-cells = <0>;
++			test_intc0: intc0 {
++				interrupt-controller;
++				#interrupt-cells = <1>;
++			};
++
++			test_intc1: intc1 {
++				interrupt-controller;
++				#interrupt-cells = <3>;
++			};
++
++			test_intc2: intc2 {
++				interrupt-controller;
++				#interrupt-cells = <2>;
++			};
++
++			test_intmap0: intmap0 {
++				#interrupt-cells = <1>;
++				#address-cells = <0>;
++				interrupt-map = <1 &test_intc0 9>,
++						<2 &test_intc1 10 11 12>,
++						<3 &test_intc2 13 14>,
++						<4 &test_intc2 15 16>;
++			};
++
++			interrupts0 {
++				interrupt-parent = <&test_intc0>;
++				interrupts = <1>, <2>, <3>, <4>;
++			};
++
++			interrupts1 {
++				interrupt-parent = <&test_intmap0>;
++				interrupts = <1>, <2>, <3>, <4>;
++			};
++		};
++	};
++};
+--- a/arch/arm/boot/dts/testcases/tests.dtsi
++++ b/arch/arm/boot/dts/testcases/tests.dtsi
+@@ -1 +1,2 @@
+ /include/ "tests-phandle.dtsi"
++/include/ "tests-interrupts.dtsi"
+--- a/drivers/of/selftest.c
++++ b/drivers/of/selftest.c
+@@ -9,18 +9,24 @@
+ #include <linux/errno.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/list.h>
+ #include <linux/mutex.h>
+ #include <linux/slab.h>
+ #include <linux/device.h>
+ 
+-static bool selftest_passed = true;
++static struct selftest_results {
++	int passed;
++	int failed;
++} selftest_results;
++
+ #define selftest(result, fmt, ...) { \
+ 	if (!(result)) { \
+-		pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
+-		selftest_passed = false; \
++		selftest_results.failed++; \
++		pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
+ 	} else { \
+-		pr_info("pass %s:%i\n", __FILE__, __LINE__); \
++		selftest_results.passed++; \
++		pr_debug("pass %s():%i\n", __func__, __LINE__); \
+ 	} \
+ }
+ 
+@@ -131,7 +137,6 @@ static void __init of_selftest_property_
+ 	struct device_node *np;
+ 	int rc;
+ 
+-	pr_info("start\n");
+ 	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
+ 	if (!np) {
+ 		pr_err("No testcase data in device tree\n");
diff --git a/target/linux/mvebu/patches-3.10/0199-PCI-mvebu-Convert-to-use-devm_ioremap_resource.patch b/target/linux/mvebu/patches-3.10/0199-PCI-mvebu-Convert-to-use-devm_ioremap_resource.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7f1bdb24d684dface6ad15e3e5e7df404b6b9165
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0199-PCI-mvebu-Convert-to-use-devm_ioremap_resource.patch
@@ -0,0 +1,44 @@
+From 508e3a33ebe14ae4444a45b3f65dff5d5e6a4c73 Mon Sep 17 00:00:00 2001
+From: Tushar Behera <tushar.behera@linaro.org>
+Date: Mon, 17 Jun 2013 14:46:13 +0530
+Subject: [PATCH 199/203] PCI: mvebu: Convert to use devm_ioremap_resource
+
+Commit 75096579c3ac ("lib: devres: Introduce devm_ioremap_resource()")
+introduced devm_ioremap_resource() and deprecated the use of
+devm_request_and_ioremap().
+
+While at it, modify mvebu_pcie_map_registers() to propagate error code.
+
+Signed-off-by: Tushar Behera <tushar.behera@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ drivers/pci/host/pci-mvebu.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -736,9 +736,9 @@ mvebu_pcie_map_registers(struct platform
+ 
+ 	ret = of_address_to_resource(np, 0, &regs);
+ 	if (ret)
+-		return NULL;
++		return ERR_PTR(ret);
+ 
+-	return devm_request_and_ioremap(&pdev->dev, &regs);
++	return devm_ioremap_resource(&pdev->dev, &regs);
+ }
+ 
+ static void __init mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
+@@ -897,9 +897,10 @@ static int __init mvebu_pcie_probe(struc
+ 		}
+ 
+ 		port->base = mvebu_pcie_map_registers(pdev, child, port);
+-		if (!port->base) {
++		if (IS_ERR(port->base)) {
+ 			dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
+ 				port->port, port->lane);
++			port->base = NULL;
+ 			continue;
+ 		}
+ 
diff --git a/target/linux/mvebu/patches-3.10/0200-PCI-mvebu-move-clock-enable-before-register-access.patch b/target/linux/mvebu/patches-3.10/0200-PCI-mvebu-move-clock-enable-before-register-access.patch
new file mode 100644
index 0000000000000000000000000000000000000000..33fba3db7d0311a007f106a124b7db801194f246
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0200-PCI-mvebu-move-clock-enable-before-register-access.patch
@@ -0,0 +1,65 @@
+From c524c5790d413b37702013e7e83a845fd3f007ac Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Tue, 13 Aug 2013 14:25:20 +0200
+Subject: [PATCH 200/203] PCI: mvebu: move clock enable before register access
+
+The clock passed to PCI controller found on MVEBU SoCs may come from a
+clock gate. This requires the clock to be enabled before any registers
+are accessed. Therefore, move the clock enable before register iomap to
+ensure it is enabled.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ drivers/pci/host/pci-mvebu.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -896,11 +896,23 @@ static int __init mvebu_pcie_probe(struc
+ 			continue;
+ 		}
+ 
++		port->clk = of_clk_get_by_name(child, NULL);
++		if (IS_ERR(port->clk)) {
++			dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
++			       port->port, port->lane);
++			continue;
++		}
++
++		ret = clk_prepare_enable(port->clk);
++		if (ret)
++			continue;
++
+ 		port->base = mvebu_pcie_map_registers(pdev, child, port);
+ 		if (IS_ERR(port->base)) {
+ 			dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
+ 				port->port, port->lane);
+ 			port->base = NULL;
++			clk_disable_unprepare(port->clk);
+ 			continue;
+ 		}
+ 
+@@ -916,22 +928,9 @@ static int __init mvebu_pcie_probe(struc
+ 				 port->port, port->lane);
+ 		}
+ 
+-		port->clk = of_clk_get_by_name(child, NULL);
+-		if (!port->clk) {
+-			dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
+-			       port->port, port->lane);
+-			iounmap(port->base);
+-			port->haslink = 0;
+-			continue;
+-		}
+-
+ 		port->dn = child;
+-
+-		clk_prepare_enable(port->clk);
+ 		spin_lock_init(&port->conf_lock);
+-
+ 		mvebu_sw_pci_bridge_init(port);
+-
+ 		i++;
+ 	}
+ 
diff --git a/target/linux/mvebu/patches-3.10/0201-PCI-mvebu-increment-nports-only-for-registered-ports.patch b/target/linux/mvebu/patches-3.10/0201-PCI-mvebu-increment-nports-only-for-registered-ports.patch
new file mode 100644
index 0000000000000000000000000000000000000000..810fbe19e72256e956e9e87214f676847141215c
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0201-PCI-mvebu-increment-nports-only-for-registered-ports.patch
@@ -0,0 +1,47 @@
+From e619fe9eb65d8064739f16eca2015145ac920f13 Mon Sep 17 00:00:00 2001
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Tue, 13 Aug 2013 14:25:21 +0200
+Subject: [PATCH 201/203] PCI: mvebu: increment nports only for registered
+ ports
+
+The number of ports is probed by counting the number of available child nodes.
+Later on, the registration of a port can fail and cause a mismatch between
+the ->nports counter and registered ports. This patch modifies the counting
+strategy, to make ->nports represent the number of registered ports instead
+of the number of available childs.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ drivers/pci/host/pci-mvebu.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/host/pci-mvebu.c
++++ b/drivers/pci/host/pci-mvebu.c
+@@ -841,13 +841,14 @@ static int __init mvebu_pcie_probe(struc
+ 		return ret;
+ 	}
+ 
++	i = 0;
+ 	for_each_child_of_node(pdev->dev.of_node, child) {
+ 		if (!of_device_is_available(child))
+ 			continue;
+-		pcie->nports++;
++		i++;
+ 	}
+ 
+-	pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports *
++	pcie->ports = devm_kzalloc(&pdev->dev, i *
+ 				   sizeof(struct mvebu_pcie_port),
+ 				   GFP_KERNEL);
+ 	if (!pcie->ports)
+@@ -934,8 +935,8 @@ static int __init mvebu_pcie_probe(struc
+ 		i++;
+ 	}
+ 
++	pcie->nports = i;
+ 	mvebu_pcie_msi_enable(pcie);
+-
+ 	mvebu_pcie_enable(pcie);
+ 
+ 	return 0;
diff --git a/target/linux/mvebu/patches-3.10/0202-ARM-mvebu-second-PCIe-unit-of-Armada-XP-mv78230-is-o.patch b/target/linux/mvebu/patches-3.10/0202-ARM-mvebu-second-PCIe-unit-of-Armada-XP-mv78230-is-o.patch
new file mode 100644
index 0000000000000000000000000000000000000000..af2a59a6719411a205aaad66787018e7daeea1bc
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0202-ARM-mvebu-second-PCIe-unit-of-Armada-XP-mv78230-is-o.patch
@@ -0,0 +1,85 @@
+From b2ea44bd7bca49fe5696857327a1d1514edd1196 Mon Sep 17 00:00:00 2001
+From: Arnaud Ebalard <arno@natisbad.org>
+Date: Tue, 5 Nov 2013 21:45:48 +0100
+Subject: [PATCH 202/203] ARM: mvebu: second PCIe unit of Armada XP mv78230 is
+ only x1 capable
+
+Various Marvell datasheets advertise second PCIe unit of mv78230
+flavour of Armada XP as x4/quad x1 capable. This second unit is in
+fact only x1 capable. This patch fixes current mv78230 .dtsi to
+reflect that, i.e. makes 1.0 the second interface (instead of 2.0
+at the moment). This was successfully tested on a mv78230-based
+ReadyNAS 2120 platform with a x1 device (FL1009 XHCI controller)
+connected to this second interface.
+
+Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
+Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Cc: <stable@vger.kernel.org> # v3.10.x
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-xp-mv78230.dtsi | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+@@ -47,7 +47,7 @@
+ 		/*
+ 		 * MV78230 has 2 PCIe units Gen2.0: One unit can be
+ 		 * configured as x4 or quad x1 lanes. One unit is
+-		 * x4/x1.
++		 * x1 only.
+ 		 */
+ 		pcie-controller {
+ 			compatible = "marvell,armada-xp-pcie";
+@@ -62,10 +62,10 @@
+ 
+ 			ranges =
+ 			       <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000   /* Port 0.0 registers */
+-				0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000   /* Port 2.0 registers */
+ 				0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000   /* Port 0.1 registers */
+ 				0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000   /* Port 0.2 registers */
+ 				0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000   /* Port 0.3 registers */
++				0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000   /* Port 1.0 registers */
+ 				0x82000000 0x1 0       MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 				0x81000000 0x1 0       MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO  */
+ 				0x82000000 0x2 0       MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
+@@ -74,8 +74,8 @@
+ 				0x81000000 0x3 0       MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO  */
+ 				0x82000000 0x4 0       MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
+ 				0x81000000 0x4 0       MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO  */
+-				0x82000000 0x9 0       MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
+-				0x81000000 0x9 0       MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO  */>;
++				0x82000000 0x5 0       MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
++				0x81000000 0x5 0       MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */>;
+ 
+ 			pcie@1,0 {
+ 				device_type = "pci";
+@@ -145,20 +145,20 @@
+ 				status = "disabled";
+ 			};
+ 
+-			pcie@9,0 {
++			pcie@5,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+-				reg = <0x4800 0 0 0 0>;
++				assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++				reg = <0x2800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+ 				#interrupt-cells = <1>;
+-				ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+-					  0x81000000 0 0 0x81000000 0x9 0 1 0>;
++				ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
++					  0x81000000 0 0 0x81000000 0x5 0 1 0>;
+ 				interrupt-map-mask = <0 0 0 0>;
+-				interrupt-map = <0 0 0 0 &mpic 99>;
+-				marvell,pcie-port = <2>;
++				interrupt-map = <0 0 0 0 &mpic 62>;
++				marvell,pcie-port = <1>;
+ 				marvell,pcie-lane = <0>;
+-				clocks = <&gateclk 26>;
++				clocks = <&gateclk 9>;
+ 				status = "disabled";
+ 			};
+ 		};
diff --git a/target/linux/mvebu/patches-3.10/0203-ARM-mvebu-fix-second-and-third-PCIe-unit-of-Armada-X.patch b/target/linux/mvebu/patches-3.10/0203-ARM-mvebu-fix-second-and-third-PCIe-unit-of-Armada-X.patch
new file mode 100644
index 0000000000000000000000000000000000000000..70953bfe55575287f254eecf6c5097fa9db9f935
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0203-ARM-mvebu-fix-second-and-third-PCIe-unit-of-Armada-X.patch
@@ -0,0 +1,180 @@
+From 9c2caf4d2d60780182d7754896c41496192b99c2 Mon Sep 17 00:00:00 2001
+From: Arnaud Ebalard <arno@natisbad.org>
+Date: Tue, 5 Nov 2013 21:46:02 +0100
+Subject: [PATCH 203/203] ARM: mvebu: fix second and third PCIe unit of Armada
+ XP mv78260
+
+mv78260 flavour of Marvell Armada XP SoC has 3 PCIe units. The
+two first units are both x4 and quad x1 capable. The third unit
+is only x4 capable. This patch fixes mv78260 .dtsi to reflect
+those capabilities.
+
+Signed-off-by: Arnaud Ebalard <arno@natisbad.org>
+Acked-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Cc: <stable@vger.kernel.org> # v3.10.x
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+---
+ arch/arm/boot/dts/armada-xp-mv78260.dtsi | 109 ++++++++++++++++++++++++-------
+ 1 file changed, 85 insertions(+), 24 deletions(-)
+
+--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+@@ -48,7 +48,7 @@
+ 		/*
+ 		 * MV78260 has 3 PCIe units Gen2.0: Two units can be
+ 		 * configured as x4 or quad x1 lanes. One unit is
+-		 * x4/x1.
++		 * x4 only.
+ 		 */
+ 		pcie-controller {
+ 			compatible = "marvell,armada-xp-pcie";
+@@ -68,7 +68,9 @@
+ 				0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000   /* Port 0.2 registers */
+ 				0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000   /* Port 0.3 registers */
+ 				0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000   /* Port 1.0 registers */
+-				0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000   /* Port 3.0 registers */
++				0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000   /* Port 1.1 registers */
++				0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000   /* Port 1.2 registers */
++				0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000   /* Port 1.3 registers */
+ 				0x82000000 0x1 0     MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
+ 				0x81000000 0x1 0     MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO  */
+ 				0x82000000 0x2 0     MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
+@@ -77,10 +79,18 @@
+ 				0x81000000 0x3 0     MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO  */
+ 				0x82000000 0x4 0     MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
+ 				0x81000000 0x4 0     MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO  */
+-				0x82000000 0x9 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
+-				0x81000000 0x9 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */
+-				0x82000000 0xa 0     MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
+-				0x81000000 0xa 0     MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO  */>;
++
++				0x82000000 0x5 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
++				0x81000000 0x5 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO  */
++				0x82000000 0x6 0     MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
++				0x81000000 0x6 0     MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO  */
++				0x82000000 0x7 0     MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
++				0x81000000 0x7 0     MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO  */
++				0x82000000 0x8 0     MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
++				0x81000000 0x8 0     MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO  */
++
++				0x82000000 0x9 0     MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
++				0x81000000 0x9 0     MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO  */>;
+ 
+ 			pcie@1,0 {
+ 				device_type = "pci";
+@@ -106,8 +116,8 @@
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+ 				#interrupt-cells = <1>;
+-                                ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
+-                                          0x81000000 0 0 0x81000000 0x2 0 1 0>;
++				ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
++					  0x81000000 0 0 0x81000000 0x2 0 1 0>;
+ 				interrupt-map-mask = <0 0 0 0>;
+ 				interrupt-map = <0 0 0 0 &mpic 59>;
+ 				marvell,pcie-port = <0>;
+@@ -150,37 +160,88 @@
+ 				status = "disabled";
+ 			};
+ 
+-			pcie@9,0 {
++			pcie@5,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
+-				reg = <0x4800 0 0 0 0>;
++				assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++				reg = <0x2800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+ 				#interrupt-cells = <1>;
+-				ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
+-					  0x81000000 0 0 0x81000000 0x9 0 1 0>;
++				ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
++					  0x81000000 0 0 0x81000000 0x5 0 1 0>;
+ 				interrupt-map-mask = <0 0 0 0>;
+-				interrupt-map = <0 0 0 0 &mpic 99>;
+-				marvell,pcie-port = <2>;
++				interrupt-map = <0 0 0 0 &mpic 62>;
++				marvell,pcie-port = <1>;
+ 				marvell,pcie-lane = <0>;
+-				clocks = <&gateclk 26>;
++				clocks = <&gateclk 9>;
+ 				status = "disabled";
+ 			};
+ 
+-			pcie@10,0 {
++			pcie@6,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
+-				reg = <0x5000 0 0 0 0>;
++				assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
++				reg = <0x3000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+ 				#interrupt-cells = <1>;
+-				ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
+-					  0x81000000 0 0 0x81000000 0xa 0 1 0>;
++				ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
++					  0x81000000 0 0 0x81000000 0x6 0 1 0>;
+ 				interrupt-map-mask = <0 0 0 0>;
+-				interrupt-map = <0 0 0 0 &mpic 103>;
+-				marvell,pcie-port = <3>;
++				interrupt-map = <0 0 0 0 &mpic 63>;
++				marvell,pcie-port = <1>;
++				marvell,pcie-lane = <1>;
++				clocks = <&gateclk 10>;
++				status = "disabled";
++			};
++
++			pcie@7,0 {
++				device_type = "pci";
++				assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
++				reg = <0x3800 0 0 0 0>;
++				#address-cells = <3>;
++				#size-cells = <2>;
++				#interrupt-cells = <1>;
++				ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
++					  0x81000000 0 0 0x81000000 0x7 0 1 0>;
++				interrupt-map-mask = <0 0 0 0>;
++				interrupt-map = <0 0 0 0 &mpic 64>;
++				marvell,pcie-port = <1>;
++				marvell,pcie-lane = <2>;
++				clocks = <&gateclk 11>;
++				status = "disabled";
++			};
++
++			pcie@8,0 {
++				device_type = "pci";
++				assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
++				reg = <0x4000 0 0 0 0>;
++				#address-cells = <3>;
++				#size-cells = <2>;
++				#interrupt-cells = <1>;
++				ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
++					  0x81000000 0 0 0x81000000 0x8 0 1 0>;
++				interrupt-map-mask = <0 0 0 0>;
++				interrupt-map = <0 0 0 0 &mpic 65>;
++				marvell,pcie-port = <1>;
++				marvell,pcie-lane = <3>;
++				clocks = <&gateclk 12>;
++				status = "disabled";
++			};
++
++			pcie@9,0 {
++				device_type = "pci";
++				assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
++				reg = <0x4800 0 0 0 0>;
++				#address-cells = <3>;
++				#size-cells = <2>;
++				#interrupt-cells = <1>;
++				ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
++					  0x81000000 0 0 0x81000000 0x9 0 1 0>;
++				interrupt-map-mask = <0 0 0 0>;
++				interrupt-map = <0 0 0 0 &mpic 99>;
++				marvell,pcie-port = <2>;
+ 				marvell,pcie-lane = <0>;
+-				clocks = <&gateclk 27>;
++				clocks = <&gateclk 26>;
+ 				status = "disabled";
+ 			};
+ 		};