mvebu: backport mainline patches from kernel 3.12

This is a backport of the patches accepted to the Linux mainline related to
mvebu SoC (Armada XP and Armada 370) between Linux v3.11, and Linux v3.12.
This work mainly covers:

* Ground work for sharing the pxa nand driver(drivers/mtd/nand/pxa3xx_nand.c)
  between the PXA family,and the Armada family.
* Further updates to the mvebu MBus.
* Work and ground work for enabling MSI on the Armada family.
* some phy / mdio bus initialization related work.
* Device tree binding documentation update.

Signed-off-by: Seif Mazareeb <seif.mazareeb@gmail.com>
CC: Luka Perkov <luka@openwrt.org>

SVN-Revision: 39565
This commit is contained in:
Luka Perkov 2014-02-11 02:07:41 +00:00
parent 69d323f231
commit 3af779eb17
74 changed files with 8337 additions and 0 deletions

View file

@ -0,0 +1,67 @@
From 23a9b291a7b9ba28b31da56e6ced7a8168baa3de Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 21 May 2013 11:01:33 -0300
Subject: [PATCH 053/203] ARM: mvebu: Remove the harcoded BootROM window
allocation
The address decoding window to access the BootROM should not be
allocated programatically, but instead declared in the device tree.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/mach-mvebu/platsmp.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -21,6 +21,7 @@
#include <linux/smp.h>
#include <linux/clk.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/mbus.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
@@ -29,6 +30,9 @@
#include "pmsu.h"
#include "coherency.h"
+#define AXP_BOOTROM_BASE 0xfff00000
+#define AXP_BOOTROM_SIZE 0x100000
+
void __init set_secondary_cpus_clock(void)
{
int thiscpu;
@@ -115,10 +119,29 @@ static void __init armada_xp_smp_init_cp
void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
{
+ struct device_node *node;
+ struct resource res;
+ int err;
+
set_secondary_cpus_clock();
flush_cache_all();
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
- mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M);
+
+ /*
+ * In order to boot the secondary CPUs we need to ensure
+ * the bootROM is mapped at the correct address.
+ */
+ node = of_find_compatible_node(NULL, NULL, "marvell,bootrom");
+ if (!node)
+ panic("Cannot find 'marvell,bootrom' compatible node");
+
+ err = of_address_to_resource(node, 0, &res);
+ if (err < 0)
+ panic("Cannot get 'bootrom' node address");
+
+ if (res.start != AXP_BOOTROM_BASE ||
+ resource_size(&res) != AXP_BOOTROM_SIZE)
+ panic("The address for the BootROM is incorrect");
}
struct smp_operations armada_xp_smp_ops __initdata = {

View file

@ -0,0 +1,67 @@
From 08fe0e166c06fd86d6c8eed145d6508c3e5efaac Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 21 May 2013 11:12:00 -0300
Subject: [PATCH 054/203] ARM: mvebu: Initialize MBus using the DT binding
Now that the mbus device tree binding has been introduced, we can
switch over to it.
Also, and since the initialization of the mbus driver is quite
fundamental for the system to work properly, this patch adds a BUG()
in case mbus fails to initialize.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/mach-mvebu/armada-370-xp.c | 34 +---------------------------------
1 file changed, 1 insertion(+), 33 deletions(-)
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -35,44 +35,12 @@ static void __init armada_370_xp_map_io(
debug_ll_io_init();
}
-/*
- * This initialization will be replaced by a DT-based
- * initialization once the mvebu-mbus driver gains DT support.
- */
-
-#define ARMADA_370_XP_MBUS_WINS_OFFS 0x20000
-#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100
-#define ARMADA_370_XP_SDRAM_WINS_OFFS 0x20180
-#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20
-
-static void __init armada_370_xp_mbus_init(void)
-{
- char *mbus_soc_name;
- struct device_node *dn;
- const __be32 mbus_wins_offs = cpu_to_be32(ARMADA_370_XP_MBUS_WINS_OFFS);
- const __be32 sdram_wins_offs = cpu_to_be32(ARMADA_370_XP_SDRAM_WINS_OFFS);
-
- if (of_machine_is_compatible("marvell,armada370"))
- mbus_soc_name = "marvell,armada370-mbus";
- else
- mbus_soc_name = "marvell,armadaxp-mbus";
-
- dn = of_find_node_by_name(NULL, "internal-regs");
- BUG_ON(!dn);
-
- mvebu_mbus_init(mbus_soc_name,
- of_translate_address(dn, &mbus_wins_offs),
- ARMADA_370_XP_MBUS_WINS_SIZE,
- of_translate_address(dn, &sdram_wins_offs),
- ARMADA_370_XP_SDRAM_WINS_SIZE);
-}
-
static void __init armada_370_xp_timer_and_clk_init(void)
{
mvebu_clocks_init();
armada_370_xp_timer_init();
coherency_init();
- armada_370_xp_mbus_init();
+ BUG_ON(mvebu_mbus_dt_init());
#ifdef CONFIG_CACHE_L2X0
l2x0_of_init(0, ~0UL);
#endif

View file

@ -0,0 +1,132 @@
From 09aa74a11d05763043b1925628f65a5ac0d42237 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 12 Jun 2013 15:42:00 -0300
Subject: [PATCH 055/203] ARM: mvebu: Use the preprocessor on Armada 370/XP
device tree files
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/armada-370-db.dts | 2 +-
arch/arm/boot/dts/armada-370-mirabox.dts | 2 +-
arch/arm/boot/dts/armada-370-rd.dts | 2 +-
arch/arm/boot/dts/armada-370.dtsi | 2 +-
arch/arm/boot/dts/armada-xp-db.dts | 2 +-
arch/arm/boot/dts/armada-xp-gp.dts | 2 +-
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 2 +-
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 2 +-
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 2 +-
arch/arm/boot/dts/armada-xp.dtsi | 2 +-
10 files changed, 10 insertions(+), 10 deletions(-)
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -14,7 +14,7 @@
*/
/dts-v1/;
-/include/ "armada-370.dtsi"
+#include "armada-370.dtsi"
/ {
model = "Marvell Armada 370 Evaluation Board";
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -9,7 +9,7 @@
*/
/dts-v1/;
-/include/ "armada-370.dtsi"
+#include "armada-370.dtsi"
/ {
model = "Globalscale Mirabox";
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -12,7 +12,7 @@
*/
/dts-v1/;
-/include/ "armada-370.dtsi"
+#include "armada-370.dtsi"
/ {
model = "Marvell Armada 370 Reference Design";
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -15,7 +15,7 @@
* common to all Armada SoCs.
*/
-/include/ "armada-370-xp.dtsi"
+#include "armada-370-xp.dtsi"
/include/ "skeleton.dtsi"
/ {
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -14,7 +14,7 @@
*/
/dts-v1/;
-/include/ "armada-xp-mv78460.dtsi"
+#include "armada-xp-mv78460.dtsi"
/ {
model = "Marvell Armada XP Evaluation Board";
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -14,7 +14,7 @@
*/
/dts-v1/;
-/include/ "armada-xp-mv78460.dtsi"
+#include "armada-xp-mv78460.dtsi"
/ {
model = "Marvell Armada XP Development Board DB-MV784MP-GP";
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -13,7 +13,7 @@
* common to all Armada XP SoCs.
*/
-/include/ "armada-xp.dtsi"
+#include "armada-xp.dtsi"
/ {
model = "Marvell Armada XP MV78260 SoC";
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -13,7 +13,7 @@
* common to all Armada XP SoCs.
*/
-/include/ "armada-xp.dtsi"
+#include "armada-xp.dtsi"
/ {
model = "Marvell Armada XP MV78460 SoC";
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -11,7 +11,7 @@
*/
/dts-v1/;
-/include/ "armada-xp-mv78260.dtsi"
+#include "armada-xp-mv78260.dtsi"
/ {
model = "PlatHome OpenBlocks AX3-4 board";
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -16,7 +16,7 @@
* common to all Armada SoCs.
*/
-/include/ "armada-370-xp.dtsi"
+#include "armada-370-xp.dtsi"
/ {
model = "Marvell Armada XP family SoC";

View file

@ -0,0 +1,167 @@
From 8298866bfa7fe9c1e33055322c415f612c16a477 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 28 May 2013 08:56:04 -0300
Subject: [PATCH 056/203] ARM: mvebu: Add MBus to Armada 370/XP device tree
The Armada 370/XP SoC family has a completely configurable address
space handled by the MBus controller.
This patch introduces the device tree layout of MBus, making the
'soc' node as mbus-compatible.
Since every peripheral/controller is a child of this 'soc' node,
this makes all of them sit behind the mbus, thus describing the
hardware accurately.
A translation entry has been added for the internal-regs mapping.
This can't be done in the common armada-370-xp.dtsi because A370
and AXP have different addressing width.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/armada-370-db.dts | 2 ++
arch/arm/boot/dts/armada-370-mirabox.dts | 2 ++
arch/arm/boot/dts/armada-370-rd.dts | 2 ++
arch/arm/boot/dts/armada-370-xp.dtsi | 15 ++++++++++-----
arch/arm/boot/dts/armada-370.dtsi | 4 ++--
arch/arm/boot/dts/armada-xp-db.dts | 4 +---
arch/arm/boot/dts/armada-xp-gp.dts | 4 +---
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 4 +---
arch/arm/boot/dts/armada-xp.dtsi | 2 ++
9 files changed, 23 insertions(+), 16 deletions(-)
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -30,6 +30,8 @@
};
soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -25,6 +25,8 @@
};
soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -28,6 +28,8 @@
};
soc {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+
internal-regs {
serial@12000 {
clock-frequency = <200000000>;
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -18,6 +18,8 @@
/include/ "skeleton64.dtsi"
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
/ {
model = "Marvell Armada 370 and XP SoC";
compatible = "marvell,armada-370-xp";
@@ -29,18 +31,21 @@
};
soc {
- #address-cells = <1>;
+ #address-cells = <2>;
#size-cells = <1>;
- compatible = "simple-bus";
+ controller = <&mbusc>;
interrupt-parent = <&mpic>;
- ranges = <0 0 0xd0000000 0x0100000 /* internal registers */
- 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */>;
internal-regs {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
- ranges;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
mpic: interrupt-controller@20000 {
compatible = "marvell,mpic";
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -29,8 +29,8 @@
};
soc {
- ranges = <0 0xd0000000 0x0100000 /* internal registers */
- 0xe0000000 0xe0000000 0x8100000 /* PCIe */>;
+ compatible = "marvell,armada370-mbus", "simple-bus";
+
internal-regs {
system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -30,9 +30,7 @@
};
soc {
- ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
- 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
- 0xf0000000 0 0xf0000000 0x1000000>; /* Device Bus, NOR 16MiB */
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -39,9 +39,7 @@
};
soc {
- ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
- 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
- 0xf0000000 0 0xf0000000 0x1000000 /* Device Bus, NOR 16MiB */>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -27,9 +27,7 @@
};
soc {
- ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
- 0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
- 0xf0000000 0 0xf0000000 0x8000000 /* Device Bus, NOR 128MiB */>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -23,6 +23,8 @@
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
soc {
+ compatible = "marvell,armadaxp-mbus", "simple-bus";
+
internal-regs {
L2: l2-cache {
compatible = "marvell,aurora-system-cache";

View file

@ -0,0 +1,123 @@
From 1028055490cf9d6e146f57d920e8cfff4eda37e2 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Fri, 14 Jun 2013 10:34:45 -0300
Subject: [PATCH 057/203] ARM: mvebu: Add BootROM to Armada 370/XP device tree
In order to access the SoC BootROM, we need to declare a mapping
(through a ranges property). The mbus driver will use this property
to allocate a suitable address decoding window.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/armada-370-db.dts | 3 ++-
arch/arm/boot/dts/armada-370-mirabox.dts | 3 ++-
arch/arm/boot/dts/armada-370-rd.dts | 3 ++-
arch/arm/boot/dts/armada-370.dtsi | 5 +++++
arch/arm/boot/dts/armada-xp-db.dts | 3 ++-
arch/arm/boot/dts/armada-xp-gp.dts | 3 ++-
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 3 ++-
arch/arm/boot/dts/armada-xp.dtsi | 5 +++++
8 files changed, 22 insertions(+), 6 deletions(-)
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -30,7 +30,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -25,7 +25,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -28,7 +28,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -31,6 +31,11 @@
soc {
compatible = "marvell,armada370-mbus", "simple-bus";
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0xe0) 0 0x100000>;
+ };
+
internal-regs {
system-controller@18200 {
compatible = "marvell,armada-370-xp-system-controller";
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -30,7 +30,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -39,7 +39,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -27,7 +27,8 @@
};
soc {
- ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000>;
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
internal-regs {
serial@12000 {
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -25,6 +25,11 @@
soc {
compatible = "marvell,armadaxp-mbus", "simple-bus";
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+ };
+
internal-regs {
L2: l2-cache {
compatible = "marvell,aurora-system-cache";

View file

@ -0,0 +1,357 @@
From bcb0e54d62804f1f986ad478a11235dadb1b61bb Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Fri, 14 Jun 2013 10:44:57 -0300
Subject: [PATCH 058/203] ARM: mvebu: Relocate Armada 370/XP DeviceBus device
tree nodes
Now that mbus has been added to the device tree, it's possible to
move the DeviceBus out of internal registers, placing it directly
below the mbus. This is a more accurate representation of the hardware.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 94 +++++++++++++-----------
arch/arm/boot/dts/armada-xp-db.dts | 59 +++++++--------
arch/arm/boot/dts/armada-xp-gp.dts | 60 +++++++--------
arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 60 +++++++--------
4 files changed, 140 insertions(+), 133 deletions(-)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -36,6 +36,56 @@
controller = <&mbusc>;
interrupt-parent = <&mpic>;
+ devbus-bootcs {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10400 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs0 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10408 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3e) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs1 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10410 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3d) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs2 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10418 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x3b) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
+ devbus-cs3 {
+ compatible = "marvell,mvebu-devbus";
+ reg = <MBUS_ID(0xf0, 0x01) 0x10420 0x8>;
+ ranges = <0 MBUS_ID(0x01, 0x37) 0 0xffffffff>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&coreclk 0>;
+ status = "disabled";
+ };
+
internal-regs {
compatible = "simple-bus";
#address-cells = <1>;
@@ -191,50 +241,6 @@
status = "disabled";
};
- devbus-bootcs@10400 {
- compatible = "marvell,mvebu-devbus";
- reg = <0x10400 0x8>;
- #address-cells = <1>;
- #size-cells = <1>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- devbus-cs0@10408 {
- compatible = "marvell,mvebu-devbus";
- reg = <0x10408 0x8>;
- #address-cells = <1>;
- #size-cells = <1>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- devbus-cs1@10410 {
- compatible = "marvell,mvebu-devbus";
- reg = <0x10410 0x8>;
- #address-cells = <1>;
- #size-cells = <1>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- devbus-cs2@10418 {
- compatible = "marvell,mvebu-devbus";
- reg = <0x10418 0x8>;
- #address-cells = <1>;
- #size-cells = <1>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
-
- devbus-cs3@10420 {
- compatible = "marvell,mvebu-devbus";
- reg = <0x10420 0x8>;
- #address-cells = <1>;
- #size-cells = <1>;
- clocks = <&coreclk 0>;
- status = "disabled";
- };
};
};
};
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -31,7 +31,36 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 16 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <2>;
+ };
+ };
internal-regs {
serial@12000 {
@@ -160,34 +189,6 @@
};
};
- devbus-bootcs@10400 {
- status = "okay";
- ranges = <0 0xf0000000 0x1000000>;
-
- /* Device Bus parameters are required */
-
- /* Read parameters */
- devbus,bus-width = <8>;
- devbus,turn-off-ps = <60000>;
- devbus,badr-skew-ps = <0>;
- devbus,acc-first-ps = <124000>;
- devbus,acc-next-ps = <248000>;
- devbus,rd-setup-ps = <0>;
- devbus,rd-hold-ps = <0>;
-
- /* Write parameters */
- devbus,sync-enable = <0>;
- devbus,wr-high-ps = <60000>;
- devbus,wr-low-ps = <60000>;
- devbus,ale-wr-ps = <60000>;
-
- /* NOR 16 MiB */
- nor@0 {
- compatible = "cfi-flash";
- reg = <0 0x1000000>;
- bank-width = <2>;
- };
- };
};
};
};
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -40,7 +40,36 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 16 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x1000000>;
+ bank-width = <2>;
+ };
+ };
internal-regs {
serial@12000 {
@@ -126,35 +155,6 @@
};
};
- devbus-bootcs@10400 {
- status = "okay";
- ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf000000, size 0x1000000 */
-
- /* Device Bus parameters are required */
-
- /* Read parameters */
- devbus,bus-width = <8>;
- devbus,turn-off-ps = <60000>;
- devbus,badr-skew-ps = <0>;
- devbus,acc-first-ps = <124000>;
- devbus,acc-next-ps = <248000>;
- devbus,rd-setup-ps = <0>;
- devbus,rd-hold-ps = <0>;
-
- /* Write parameters */
- devbus,sync-enable = <0>;
- devbus,wr-high-ps = <60000>;
- devbus,wr-low-ps = <60000>;
- devbus,ale-wr-ps = <60000>;
-
- /* NOR 16 MiB */
- nor@0 {
- compatible = "cfi-flash";
- reg = <0 0x1000000>;
- bank-width = <2>;
- };
- };
-
pcie-controller {
status = "okay";
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -28,7 +28,36 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
- MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000>;
+
+ devbus-bootcs {
+ status = "okay";
+
+ /* Device Bus parameters are required */
+
+ /* Read parameters */
+ devbus,bus-width = <8>;
+ devbus,turn-off-ps = <60000>;
+ devbus,badr-skew-ps = <0>;
+ devbus,acc-first-ps = <124000>;
+ devbus,acc-next-ps = <248000>;
+ devbus,rd-setup-ps = <0>;
+ devbus,rd-hold-ps = <0>;
+
+ /* Write parameters */
+ devbus,sync-enable = <0>;
+ devbus,wr-high-ps = <60000>;
+ devbus,wr-low-ps = <60000>;
+ devbus,ale-wr-ps = <60000>;
+
+ /* NOR 128 MiB */
+ nor@0 {
+ compatible = "cfi-flash";
+ reg = <0 0x8000000>;
+ bank-width = <2>;
+ };
+ };
internal-regs {
serial@12000 {
@@ -144,35 +173,6 @@
status = "okay";
};
- devbus-bootcs@10400 {
- status = "okay";
- ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */
-
- /* Device Bus parameters are required */
-
- /* Read parameters */
- devbus,bus-width = <8>;
- devbus,turn-off-ps = <60000>;
- devbus,badr-skew-ps = <0>;
- devbus,acc-first-ps = <124000>;
- devbus,acc-next-ps = <248000>;
- devbus,rd-setup-ps = <0>;
- devbus,rd-hold-ps = <0>;
-
- /* Write parameters */
- devbus,sync-enable = <0>;
- devbus,wr-high-ps = <60000>;
- devbus,wr-low-ps = <60000>;
- devbus,ale-wr-ps = <60000>;
-
- /* NOR 128 MiB */
- nor@0 {
- compatible = "cfi-flash";
- reg = <0 0x8000000>;
- bank-width = <2>;
- };
- };
-
pcie-controller {
status = "okay";
/* Internal mini-PCIe connector */

View file

@ -0,0 +1,52 @@
From d1989c73eb770891635cc644f091d7524bbfd696 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 23 Jul 2013 07:42:09 -0300
Subject: [PATCH 060/203] ARM: kirkwood: Split DT and legacy MBus
initialization
This commit replaces the legacy MBus initialization with the new
DT-based in Kirkwood. For boards that are not yet converted to DT,
we keep the legacy initialization.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/mach-kirkwood/board-dt.c | 1 +
arch/arm/mach-kirkwood/common.c | 8 ++++----
2 files changed, 5 insertions(+), 4 deletions(-)
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -93,6 +93,7 @@ static void __init kirkwood_dt_init(void
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+ BUG_ON(mvebu_mbus_dt_init());
kirkwood_setup_wins();
kirkwood_l2_init();
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -527,10 +527,6 @@ void __init kirkwood_cpuidle_init(void)
void __init kirkwood_init_early(void)
{
orion_time_set_base(TIMER_VIRT_BASE);
-
- mvebu_mbus_init("marvell,kirkwood-mbus",
- BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
- DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ);
}
int kirkwood_tclk;
@@ -703,6 +699,10 @@ void __init kirkwood_init(void)
*/
writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+ BUG_ON(mvebu_mbus_init("marvell,kirkwood-mbus",
+ BRIDGE_WINS_BASE, BRIDGE_WINS_SZ,
+ DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ));
+
kirkwood_setup_wins();
kirkwood_l2_init();

View file

@ -0,0 +1,485 @@
From 67bbed6edc12a5f239435c182d9c56ce2c930d87 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 23 Jul 2013 07:45:49 -0300
Subject: [PATCH 061/203] ARM: kirkwood: Use the preprocessor on device tree
files
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/kirkwood-cloudbox.dts | 4 +--
arch/arm/boot/dts/kirkwood-dns320.dts | 2 +-
arch/arm/boot/dts/kirkwood-dns325.dts | 2 +-
arch/arm/boot/dts/kirkwood-dnskw.dtsi | 4 +--
arch/arm/boot/dts/kirkwood-dockstar.dts | 4 +--
arch/arm/boot/dts/kirkwood-dreamplug.dts | 4 +--
arch/arm/boot/dts/kirkwood-goflexnet.dts | 4 +--
.../arm/boot/dts/kirkwood-guruplug-server-plus.dts | 4 +--
arch/arm/boot/dts/kirkwood-ib62x0.dts | 4 +--
arch/arm/boot/dts/kirkwood-iconnect.dts | 4 +--
arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts | 4 +--
arch/arm/boot/dts/kirkwood-is2.dts | 2 +-
arch/arm/boot/dts/kirkwood-km_kirkwood.dts | 4 +--
arch/arm/boot/dts/kirkwood-lschlv2.dts | 2 +-
arch/arm/boot/dts/kirkwood-lsxhl.dts | 2 +-
arch/arm/boot/dts/kirkwood-lsxl.dtsi | 4 +--
arch/arm/boot/dts/kirkwood-mplcec4.dts | 4 +--
.../boot/dts/kirkwood-netgear_readynas_duo_v2.dts | 4 +--
arch/arm/boot/dts/kirkwood-ns2-common.dtsi | 4 +--
arch/arm/boot/dts/kirkwood-ns2.dts | 2 +-
arch/arm/boot/dts/kirkwood-ns2lite.dts | 2 +-
arch/arm/boot/dts/kirkwood-ns2max.dts | 2 +-
arch/arm/boot/dts/kirkwood-ns2mini.dts | 2 +-
arch/arm/boot/dts/kirkwood-nsa310.dts | 40 +++++++++++++---------
arch/arm/boot/dts/kirkwood-openblocks_a6.dts | 4 +--
arch/arm/boot/dts/kirkwood-topkick.dts | 4 +--
arch/arm/boot/dts/kirkwood-ts219-6281.dts | 13 +++----
arch/arm/boot/dts/kirkwood-ts219-6282.dts | 21 ++++++++----
28 files changed, 86 insertions(+), 70 deletions(-)
--- a/arch/arm/boot/dts/kirkwood-cloudbox.dts
+++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "LaCie CloudBox";
--- a/arch/arm/boot/dts/kirkwood-dns320.dts
+++ b/arch/arm/boot/dts/kirkwood-dns320.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-dnskw.dtsi"
+#include "kirkwood-dnskw.dtsi"
/ {
model = "D-Link DNS-320 NAS (Rev A1)";
--- a/arch/arm/boot/dts/kirkwood-dns325.dts
+++ b/arch/arm/boot/dts/kirkwood-dns325.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-dnskw.dtsi"
+#include "kirkwood-dnskw.dtsi"
/ {
model = "D-Link DNS-325 NAS (Rev A1)";
--- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -1,5 +1,5 @@
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "D-Link DNS NASes (kirkwood-based)";
--- a/arch/arm/boot/dts/kirkwood-dockstar.dts
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Seagate FreeAgent Dockstar";
--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Globalscale Technologies Dreamplug";
--- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Seagate GoFlex Net";
--- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
+++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Globalscale Technologies Guruplug Server Plus";
--- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Iomega Iconnect";
--- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "Iomega StorCenter ix2-200";
--- a/arch/arm/boot/dts/kirkwood-is2.dts
+++ b/arch/arm/boot/dts/kirkwood-is2.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-ns2-common.dtsi"
+#include "kirkwood-ns2-common.dtsi"
/ {
model = "LaCie Internet Space v2";
--- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
+++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-98dx4122.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-98dx4122.dtsi"
/ {
model = "Keymile Kirkwood Reference Design";
--- a/arch/arm/boot/dts/kirkwood-lschlv2.dts
+++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-lsxl.dtsi"
+#include "kirkwood-lsxl.dtsi"
/ {
model = "Buffalo Linkstation LS-CHLv2";
--- a/arch/arm/boot/dts/kirkwood-lsxhl.dts
+++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-lsxl.dtsi"
+#include "kirkwood-lsxl.dtsi"
/ {
model = "Buffalo Linkstation LS-XHL";
--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
@@ -1,5 +1,5 @@
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
chosen {
--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "MPL CEC4";
--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6282.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
/ {
model = "NETGEAR ReadyNAS Duo v2";
--- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
@@ -1,5 +1,5 @@
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
chosen {
--- a/arch/arm/boot/dts/kirkwood-ns2.dts
+++ b/arch/arm/boot/dts/kirkwood-ns2.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-ns2-common.dtsi"
+#include "kirkwood-ns2-common.dtsi"
/ {
model = "LaCie Network Space v2";
--- a/arch/arm/boot/dts/kirkwood-ns2lite.dts
+++ b/arch/arm/boot/dts/kirkwood-ns2lite.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-ns2-common.dtsi"
+#include "kirkwood-ns2-common.dtsi"
/ {
model = "LaCie Network Space Lite v2";
--- a/arch/arm/boot/dts/kirkwood-ns2max.dts
+++ b/arch/arm/boot/dts/kirkwood-ns2max.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-ns2-common.dtsi"
+#include "kirkwood-ns2-common.dtsi"
/ {
model = "LaCie Network Space Max v2";
--- a/arch/arm/boot/dts/kirkwood-ns2mini.dts
+++ b/arch/arm/boot/dts/kirkwood-ns2mini.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-/include/ "kirkwood-ns2-common.dtsi"
+#include "kirkwood-ns2-common.dtsi"
/ {
/* This machine is embedded in the first LaCie CloudBox product. */
--- a/arch/arm/boot/dts/kirkwood-nsa310.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
@@ -1,6 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
/ {
model = "ZyXEL NSA310";
@@ -17,22 +18,7 @@
ocp@f1000000 {
pinctrl: pinctrl@10000 {
- pinctrl-0 = < &pmx_led_esata_green
- &pmx_led_esata_red
- &pmx_led_usb_green
- &pmx_led_usb_red
- &pmx_usb_power_off
- &pmx_led_sys_green
- &pmx_led_sys_red
- &pmx_btn_reset
- &pmx_btn_copy
- &pmx_led_copy_green
- &pmx_led_copy_red
- &pmx_led_hdd_green
- &pmx_led_hdd_red
- &pmx_unknown
- &pmx_btn_power
- &pmx_pwr_off >;
+ pinctrl-0 = <&pmx_unknown>;
pinctrl-names = "default";
pmx_led_esata_green: pmx-led-esata-green {
@@ -176,12 +162,22 @@
reg = <0x5040000 0x2fc0000>;
};
};
+
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
+ pinctrl-0 = <&pmx_btn_reset &pmx_btn_copy &pmx_btn_power>;
+ pinctrl-names = "default";
button@1 {
label = "Power Button";
@@ -202,6 +198,12 @@
gpio-leds {
compatible = "gpio-leds";
+ pinctrl-0 = <&pmx_led_esata_green &pmx_led_esata_red
+ &pmx_led_usb_green &pmx_led_usb_red
+ &pmx_led_sys_green &pmx_led_sys_red
+ &pmx_led_copy_green &pmx_led_copy_red
+ &pmx_led_hdd_green &pmx_led_hdd_red>;
+ pinctrl-names = "default";
green-sys {
label = "nsa310:green:sys";
@@ -247,6 +249,8 @@
gpio_poweroff {
compatible = "gpio-poweroff";
+ pinctrl-0 = <&pmx_pwr_off>;
+ pinctrl-names = "default";
gpios = <&gpio1 16 0>;
};
@@ -254,6 +258,8 @@
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
+ pinctrl-0 = <&pmx_usb_power_off>;
+ pinctrl-names = "default";
usb0_power_off: regulator@1 {
compatible = "regulator-fixed";
--- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6282.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
/ {
model = "Plat'Home OpenBlocksA6";
--- a/arch/arm/boot/dts/kirkwood-topkick.dts
+++ b/arch/arm/boot/dts/kirkwood-topkick.dts
@@ -1,7 +1,7 @@
/dts-v1/;
-/include/ "kirkwood.dtsi"
-/include/ "kirkwood-6282.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
/ {
model = "Univeral Scientific Industrial Co. Topkick-1281P2";
--- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
@@ -1,16 +1,14 @@
/dts-v1/;
-/include/ "kirkwood-ts219.dtsi"
-/include/ "kirkwood-6281.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6281.dtsi"
+#include "kirkwood-ts219.dtsi"
/ {
ocp@f1000000 {
pinctrl: pinctrl@10000 {
- pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
- &pmx_twsi0 &pmx_sata0 &pmx_sata1
- &pmx_ram_size &pmx_reset_button
- &pmx_USB_copy_button &pmx_board_id>;
+ pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
pinctrl-names = "default";
pmx_ram_size: pmx-ram-size {
@@ -38,6 +36,9 @@
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
+ pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+ pinctrl-names = "default";
+
button@1 {
label = "USB Copy";
linux,code = <133>;
--- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
@@ -1,16 +1,14 @@
/dts-v1/;
-/include/ "kirkwood-ts219.dtsi"
-/include/ "kirkwood-6282.dtsi"
+#include "kirkwood.dtsi"
+#include "kirkwood-6282.dtsi"
+#include "kirkwood-ts219.dtsi"
/ {
ocp@f1000000 {
pinctrl: pinctrl@10000 {
- pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
- &pmx_twsi0 &pmx_sata0 &pmx_sata1
- &pmx_ram_size &pmx_reset_button
- &pmx_USB_copy_button &pmx_board_id>;
+ pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
pinctrl-names = "default";
pmx_ram_size: pmx-ram-size {
@@ -32,12 +30,23 @@
marvell,function = "gpio";
};
};
+ pcie-controller {
+ status = "okay";
+
+ pcie@2,0 {
+ status = "okay";
+ };
+ };
+
};
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
+ pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+ pinctrl-names = "default";
+
button@1 {
label = "USB Copy";
linux,code = <133>;

View file

@ -0,0 +1,41 @@
From 9d4a304873c9f6a8bbf78cba329985768a1c6c93 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 23 Jul 2013 07:48:04 -0300
Subject: [PATCH 062/203] ARM: kirkwood: Introduce MBus DT node
Add a minimal MBus node, just to allow the MBus driver to probe.
Follow-up patches will migrate the rest of the nodes appropriately.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/kirkwood.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -16,6 +16,11 @@
<0xf1020214 0x04>;
};
+ mbus {
+ compatible = "marvell,kirkwood-mbus", "simple-bus";
+ controller = <&mbusc>;
+ };
+
ocp@f1000000 {
compatible = "simple-bus";
ranges = <0x00000000 0xf1000000 0x4000000
@@ -23,6 +28,11 @@
#address-cells = <1>;
#size-cells = <1>;
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x80>, <0x1500 0x20>;
+ };
+
core_clk: core-clocks@10030 {
compatible = "marvell,kirkwood-core-clock";
reg = <0x10030 0x4>;

View file

@ -0,0 +1,25 @@
From 32016796bb28ebf748851c166b03159600aa9a00 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 23 Jul 2013 08:33:39 -0300
Subject: [PATCH 063/203] ARM: kirkwood: Introduce MBUS_ID
This macro is used to define window's target ID and attribute cells
for the MBus ranges entries.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/kirkwood.dtsi | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -1,5 +1,7 @@
/include/ "skeleton.dtsi"
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
/ {
compatible = "marvell,kirkwood";
interrupt-parent = <&intc>;

View file

@ -0,0 +1,301 @@
From ae23894bcb163d1f91483b9566dc077f1e863af6 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 23 Jul 2013 08:44:00 -0300
Subject: [PATCH 064/203] ARM: kirkwood: Relocate PCIe device tree nodes
Now that mbus has been added to the device tree, it's possible to
move the PCIe nodes out of the ocp node, placing it directly
below the mbus. This is a more accurate representation of the hardware.
Moving the PCIe nodes, we now need to introduce an extra cell to
encode the window target ID and attribute. Since this depends on
the PCIe port, we split the ranges translation entries, to
correspond to each MBus window.
In addition, we encode the PCIe memory and I/O apertures in the MBus
node, according to the MBus DT binding specification. The choice made
is 0xe0000000-0xf0000000 for memory space, and 0xf200000-0xf2100000 for
I/O space. These apertures can be changed in each per-board DT file.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
arch/arm/boot/dts/kirkwood-6281.dtsi | 35 ++++++++++++++
arch/arm/boot/dts/kirkwood-6282.dtsi | 55 ++++++++++++++++++++++
arch/arm/boot/dts/kirkwood-iconnect.dts | 11 +++++
arch/arm/boot/dts/kirkwood-mplcec4.dts | 11 +++++
.../boot/dts/kirkwood-netgear_readynas_duo_v2.dts | 11 +++++
arch/arm/boot/dts/kirkwood-nsa310.dts | 19 ++++----
arch/arm/boot/dts/kirkwood-ts219-6282.dts | 19 ++++----
arch/arm/boot/dts/kirkwood-ts219.dtsi | 10 ++++
arch/arm/boot/dts/kirkwood.dtsi | 4 ++
9 files changed, 159 insertions(+), 16 deletions(-)
--- a/arch/arm/boot/dts/kirkwood-6281.dtsi
+++ b/arch/arm/boot/dts/kirkwood-6281.dtsi
@@ -1,4 +1,39 @@
/ {
+ mbus {
+ pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 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 */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
compatible = "marvell,88f6281-pinctrl";
--- a/arch/arm/boot/dts/kirkwood-6282.dtsi
+++ b/arch/arm/boot/dts/kirkwood-6282.dtsi
@@ -1,4 +1,59 @@
/ {
+ mbus {
+ pcie-controller {
+ compatible = "marvell,kirkwood-pcie";
+ status = "disabled";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ bus-range = <0x00 0xff>;
+
+ ranges =
+ <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
+ 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
+ 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
+ 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 1.0 MEM */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1.0 IO */>;
+
+ pcie@1,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 9>;
+ marvell,pcie-port = <0>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 2>;
+ status = "disabled";
+ };
+
+ pcie@2,0 {
+ device_type = "pci";
+ assigned-addresses = <0x82001000 0 0x00044000 0 0x2000>;
+ reg = <0x1000 0 0 0 0>;
+ #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>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &intc 10>;
+ marvell,pcie-port = <1>;
+ marvell,pcie-lane = <0>;
+ clocks = <&gate_clk 18>;
+ status = "disabled";
+ };
+ };
+ };
ocp@f1000000 {
pinctrl: pinctrl@10000 {
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -18,6 +18,17 @@
linux,initrd-end = <0x4800000>;
};
+ mbus {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
@@ -16,6 +16,17 @@
bootargs = "console=ttyS0,115200n8 earlyprintk";
};
+ mbus {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
@@ -16,6 +16,17 @@
bootargs = "console=ttyS0,115200n8 earlyprintk";
};
+ mbus {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
--- a/arch/arm/boot/dts/kirkwood-nsa310.dts
+++ b/arch/arm/boot/dts/kirkwood-nsa310.dts
@@ -16,6 +16,17 @@
bootargs = "console=ttyS0,115200";
};
+ mbus {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
pinctrl-0 = <&pmx_unknown>;
@@ -162,14 +173,6 @@
reg = <0x5040000 0x2fc0000>;
};
};
-
- pcie-controller {
- status = "okay";
-
- pcie@1,0 {
- status = "okay";
- };
- };
};
gpio_keys {
--- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
@@ -5,6 +5,17 @@
#include "kirkwood-ts219.dtsi"
/ {
+ mbus {
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>;
+ pcie-controller {
+ status = "okay";
+
+ pcie@2,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
pinctrl: pinctrl@10000 {
@@ -30,14 +41,6 @@
marvell,function = "gpio";
};
};
- pcie-controller {
- status = "okay";
-
- pcie@2,0 {
- status = "okay";
- };
- };
-
};
gpio_keys {
--- a/arch/arm/boot/dts/kirkwood-ts219.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi
@@ -13,6 +13,16 @@
bootargs = "console=ttyS0,115200n8";
};
+ mbus {
+ pcie-controller {
+ status = "okay";
+
+ pcie@1,0 {
+ status = "okay";
+ };
+ };
+ };
+
ocp@f1000000 {
i2c@11000 {
status = "okay";
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -20,7 +20,11 @@
mbus {
compatible = "marvell,kirkwood-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
controller = <&mbusc>;
+ pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256 MiB memory space */
+ pcie-io-aperture = <0xf2000000 0x100000>; /* 1 MiB I/O space */
};
ocp@f1000000 {

View file

@ -0,0 +1,303 @@
From 442681ff6aca5e839fe41378ff919df1c340dc62 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 28 May 2013 07:58:31 -0300
Subject: [PATCH 065/203] bus: mvebu-mbus: Add devicetree binding
Introduce the devicetree binding for the mvebu MBus driver
avaiable in the mvebu SoCs (Armada 370/XP, Kirkwood, Dove, ...).
This binding provides an accurate model of the SoC address space,
and allows to declare the address and size of the decoding windows the MBus
needs to access the peripherals, together with the target ID and attribute
for those windows.
The binding is composed of two required nodes: one for the MBus bus
and one for the MBus controller.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
.../devicetree/bindings/bus/mvebu-mbus.txt | 276 +++++++++++++++++++++
1 file changed, 276 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/mvebu-mbus.txt
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt
@@ -0,0 +1,276 @@
+
+* Marvell MBus
+
+Required properties:
+
+- compatible: Should be set to one of the following:
+ marvell,armada370-mbus
+ marvell,armadaxp-mbus
+ marvell,armada370-mbus
+ marvell,armadaxp-mbus
+ marvell,kirkwood-mbus
+ marvell,dove-mbus
+ marvell,orion5x-88f5281-mbus
+ marvell,orion5x-88f5182-mbus
+ marvell,orion5x-88f5181-mbus
+ marvell,orion5x-88f6183-mbus
+ marvell,mv78xx0-mbus
+
+- address-cells: Must be '2'. The first cell for the MBus ID encoding,
+ the second cell for the address offset within the window.
+
+- size-cells: Must be '1'.
+
+- ranges: Must be set up to provide a proper translation for each child.
+ See the examples below.
+
+- controller: Contains a single phandle referring to the MBus controller
+ node. This allows to specify the node that contains the
+ registers that control the MBus, which is typically contained
+ within the internal register window (see below).
+
+Optional properties:
+
+- pcie-mem-aperture: This optional property contains the aperture for
+ the memory region of the PCIe driver.
+ If it's defined, it must encode the base address and
+ size for the address decoding windows allocated for
+ the PCIe memory region.
+
+- pcie-io-aperture: Just as explained for the above property, this
+ optional property contains the aperture for the
+ I/O region of the PCIe driver.
+
+* Marvell MBus controller
+
+Required properties:
+
+- compatible: Should be set to "marvell,mbus-controller".
+
+- reg: Device's register space.
+ Two entries are expected (see the examples below):
+ the first one controls the devices decoding window and
+ the second one controls the SDRAM decoding window.
+
+Example:
+
+ soc {
+ compatible = "marvell,armada370-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+ pcie-mem-aperture = <0xe0000000 0x8000000>;
+ pcie-io-aperture = <0xe8000000 0x100000>;
+
+ internal-regs {
+ compatible = "simple-bus";
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ /* more children ...*/
+ };
+ };
+
+** MBus address decoding window specification
+
+The MBus children address space is comprised of two cells: the first one for
+the window ID and the second one for the offset within the window.
+In order to allow to describe valid and non-valid window entries, the
+following encoding is used:
+
+ 0xSIAA0000 0x00oooooo
+
+Where:
+
+ S = 0x0 for a MBus valid window
+ S = 0xf for a non-valid window (see below)
+
+If S = 0x0, then:
+
+ I = 4-bit window target ID
+ AA = windpw attribute
+
+If S = 0xf, then:
+
+ I = don't care
+ AA = 1 for internal register
+
+Following the above encoding, for each ranges entry for a MBus valid window
+(S = 0x0), an address decoding window is allocated. On the other side,
+entries for translation that do not correspond to valid windows (S = 0xf)
+are skipped.
+
+ soc {
+ compatible = "marvell,armada370-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+
+ ranges = <0xf0010000 0 0 0xd0000000 0x100000
+ 0x01e00000 0 0 0xfff00000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <0x01e00000 0 0x100000>;
+ };
+
+ /* other children */
+ ...
+
+ internal-regs {
+ compatible = "simple-bus";
+ ranges = <0 0xf0010000 0 0x100000>;
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ /* more children ...*/
+ };
+ };
+
+In the shown example, the translation entry in the 'ranges' property is what
+makes the MBus driver create a static decoding window for the corresponding
+given child device. Note that the binding does not require child nodes to be
+present. Of course, child nodes are needed to probe the devices.
+
+Since each window is identified by its target ID and attribute ID there's
+a special macro that can be use to simplify the translation entries:
+
+#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16))
+
+Using this macro, the above example would be:
+
+ soc {
+ compatible = "marvell,armada370-mbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ controller = <&mbusc>;
+
+ ranges = < MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
+ MBUS_ID(0x01, 0xe0) 0 0 0xfff00000 0x100000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0xe0) 0 0x100000>;
+ };
+
+ /* other children */
+ ...
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ mbusc: mbus-controller@20000 {
+ compatible = "marvell,mbus-controller";
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ /* other children */
+ ...
+ };
+ };
+
+
+** About the window base address
+
+Remember the MBus controller allows a great deal of flexibility for choosing
+the decoding window base address. When planning the device tree layout it's
+possible to choose any address as the base address, provided of course there's
+a region large enough available, and with the required alignment.
+
+Yet in other words: there's nothing preventing us from setting a base address
+of 0xf0000000, or 0xd0000000 for the NOR device shown above, if such region is
+unused.
+
+** Window allocation policy
+
+The mbus-node ranges property defines a set of mbus windows that are expected
+to be set by the operating system and that are guaranteed to be free of overlaps
+with one another or with the system memory ranges.
+
+Each entry in the property refers to exactly one window. If the operating system
+choses to use a different set of mbus windows, it must ensure that any address
+translations performed from downstream devices are adapted accordingly.
+
+The operating system may insert additional mbus windows that do not conflict
+with the ones listed in the ranges, e.g. for mapping PCIe devices.
+As a special case, the internal register window must be set up by the boot
+loader at the address listed in the ranges property, since access to that region
+is needed to set up the other windows.
+
+** Example
+
+See the example below, where a more complete device tree is shown:
+
+ soc {
+ compatible = "marvell,armadaxp-mbus", "simple-bus";
+ controller = <&mbusc>;
+
+ ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000 /* internal-regs */
+ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+ MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000>;
+
+ bootrom {
+ compatible = "marvell,bootrom";
+ reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>;
+ };
+
+ devbus-bootcs {
+ status = "okay";
+ ranges = <0 MBUS_ID(0x01, 0x2f) 0 0x8000000>;
+
+ /* NOR */
+ nor {
+ compatible = "cfi-flash";
+ reg = <0 0x8000000>;
+ bank-width = <2>;
+ };
+ };
+
+ pcie-controller {
+ compatible = "marvell,armada-xp-pcie";
+ status = "okay";
+ device_type = "pci";
+
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ 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 */
+ 0x82000800 0 0xe0000000 MBUS_ID(0x04, 0xe8) 0xe0000000 0 0x08000000 /* Port 0.0 MEM */
+ 0x81000800 0 0 MBUS_ID(0x04, 0xe0) 0xe8000000 0 0x00100000 /* Port 0.0 IO */>;
+
+
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ };
+
+ internal-regs {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>;
+
+ mbusc: mbus-controller@20000 {
+ reg = <0x20000 0x100>, <0x20180 0x20>;
+ };
+
+ interrupt-controller@20000 {
+ reg = <0x20a00 0x2d0>, <0x21070 0x58>;
+ };
+ };
+ };

View file

@ -0,0 +1,304 @@
From 60538f9841697cd4539d353afd8a7f51cd17e4af Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Fri, 5 Jul 2013 14:54:17 +0200
Subject: [PATCH 066/203] PCI: mvebu: Adapt to the new device tree layout
The new device tree layout encodes the window's target ID and attribute
in the PCIe controller node's ranges property. This allows to parse
such entries to obtain such information and use the recently introduced
MBus API to create the windows, instead of using the current name based
scheme.
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
.../devicetree/bindings/pci/mvebu-pci.txt | 145 ++++++++++++++++-----
1 file changed, 109 insertions(+), 36 deletions(-)
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -1,6 +1,7 @@
* Marvell EBU PCIe interfaces
Mandatory properties:
+
- compatible: one of the following values:
marvell,armada-370-pcie
marvell,armada-xp-pcie
@@ -9,11 +10,49 @@ Mandatory properties:
- #interrupt-cells, set to <1>
- bus-range: PCI bus numbers covered
- device_type, set to "pci"
-- ranges: ranges for the PCI memory and I/O regions, as well as the
- MMIO registers to control the PCIe interfaces.
+- ranges: ranges describing the MMIO registers to control the PCIe
+ interfaces, and ranges describing the MBus windows needed to access
+ the memory and I/O regions of each PCIe interface.
+
+The ranges describing the MMIO registers have the following layout:
+
+ 0x82000000 0 r MBUS_ID(0xf0, 0x01) r 0 s
+
+where:
+
+ * r is a 32-bits value that gives the offset of the MMIO
+ registers of this PCIe interface, from the base of the internal
+ registers.
+
+ * s is a 32-bits value that give the size of this MMIO
+ registers area. This range entry translates the '0x82000000 0 r' PCI
+ address into the 'MBUS_ID(0xf0, 0x01) r' CPU address, which is part
+ of the internal register window (as identified by MBUS_ID(0xf0,
+ 0x01)).
+
+The ranges describing the MBus windows have the following layout:
+
+ 0x8t000000 s 0 MBUS_ID(w, a) 0 1 0
+
+where:
-In addition, the Device Tree node must have sub-nodes describing each
+ * t is the type of the MBus window (as defined by the standard PCI DT
+ bindings), 1 for I/O and 2 for memory.
+
+ * s is the PCI slot that corresponds to this PCIe interface
+
+ * w is the 'target ID' value for the MBus window
+
+ * a the 'attribute' value for the MBus window.
+
+Since the location and size of the different MBus windows is not fixed in
+hardware, and only determined in runtime, those ranges cover the full first
+4 GB of the physical address space, and do not translate into a valid CPU
+address.
+
+In addition, the device tree node must have sub-nodes describing each
PCIe interface, having the following mandatory properties:
+
- reg: used only for interrupt mapping, so only the first four bytes
are used to refer to the correct bus number and device number.
- assigned-addresses: reference to the MMIO registers used to control
@@ -25,7 +64,8 @@ PCIe interface, having the following man
- #address-cells, set to <3>
- #size-cells, set to <2>
- #interrupt-cells, set to <1>
-- ranges, empty property.
+- ranges, translating the MBus windows ranges of the parent node into
+ standard PCI addresses.
- interrupt-map-mask and interrupt-map, standard PCI properties to
define the mapping of the PCIe interface to interrupt numbers.
@@ -46,27 +86,50 @@ pcie-controller {
bus-range = <0x00 0xff>;
- ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000 /* Port 0.0 registers */
- 0x82000000 0 0xd0042000 0xd0042000 0 0x00002000 /* Port 2.0 registers */
- 0x82000000 0 0xd0044000 0xd0044000 0 0x00002000 /* Port 0.1 registers */
- 0x82000000 0 0xd0048000 0xd0048000 0 0x00002000 /* Port 0.2 registers */
- 0x82000000 0 0xd004c000 0xd004c000 0 0x00002000 /* Port 0.3 registers */
- 0x82000000 0 0xd0080000 0xd0080000 0 0x00002000 /* Port 1.0 registers */
- 0x82000000 0 0xd0082000 0xd0082000 0 0x00002000 /* Port 3.0 registers */
- 0x82000000 0 0xd0084000 0xd0084000 0 0x00002000 /* Port 1.1 registers */
- 0x82000000 0 0xd0088000 0xd0088000 0 0x00002000 /* Port 1.2 registers */
- 0x82000000 0 0xd008c000 0xd008c000 0 0x00002000 /* Port 1.3 registers */
- 0x82000000 0 0xe0000000 0xe0000000 0 0x08000000 /* non-prefetchable memory */
- 0x81000000 0 0 0xe8000000 0 0x00100000>; /* downstream I/O */
+ 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 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 */
+ 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 0.1 IO */
+ 0x82000000 0x3 0 MBUS_ID(0x04, 0xb8) 0 1 0 /* Port 0.2 MEM */
+ 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 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 */
+
+ 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 */>;
pcie@1,0 {
device_type = "pci";
- assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+ assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
reg = <0x0800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
+ 0x81000000 0 0 0x81000000 0x1 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 58>;
marvell,pcie-port = <0>;
@@ -77,12 +140,13 @@ pcie-controller {
pcie@2,0 {
device_type = "pci";
- assigned-addresses = <0x82001000 0 0xd0044000 0 0x2000>;
+ assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
reg = <0x1000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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>;
@@ -93,12 +157,13 @@ pcie-controller {
pcie@3,0 {
device_type = "pci";
- assigned-addresses = <0x82001800 0 0xd0048000 0 0x2000>;
+ assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
reg = <0x1800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
+ 0x81000000 0 0 0x81000000 0x3 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 60>;
marvell,pcie-port = <0>;
@@ -109,12 +174,13 @@ pcie-controller {
pcie@4,0 {
device_type = "pci";
- assigned-addresses = <0x82002000 0 0xd004c000 0 0x2000>;
+ assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
reg = <0x2000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
+ 0x81000000 0 0 0x81000000 0x4 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 61>;
marvell,pcie-port = <0>;
@@ -125,12 +191,13 @@ pcie-controller {
pcie@5,0 {
device_type = "pci";
- assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>;
+ assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
reg = <0x2800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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 62>;
marvell,pcie-port = <1>;
@@ -141,12 +208,13 @@ pcie-controller {
pcie@6,0 {
device_type = "pci";
- assigned-addresses = <0x82003000 0 0xd0084000 0 0x2000>;
+ assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
reg = <0x3000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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 63>;
marvell,pcie-port = <1>;
@@ -157,12 +225,13 @@ pcie-controller {
pcie@7,0 {
device_type = "pci";
- assigned-addresses = <0x82003800 0 0xd0088000 0 0x2000>;
+ assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
reg = <0x3800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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>;
@@ -173,12 +242,13 @@ pcie-controller {
pcie@8,0 {
device_type = "pci";
- assigned-addresses = <0x82004000 0 0xd008c000 0 0x2000>;
+ assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
reg = <0x4000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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>;
@@ -186,14 +256,16 @@ pcie-controller {
clocks = <&gateclk 12>;
status = "disabled";
};
+
pcie@9,0 {
device_type = "pci";
- assigned-addresses = <0x82004800 0 0xd0042000 0 0x2000>;
+ assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
reg = <0x4800 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ 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>;
@@ -204,12 +276,13 @@ pcie-controller {
pcie@10,0 {
device_type = "pci";
- assigned-addresses = <0x82005000 0 0xd0082000 0 0x2000>;
+ assigned-addresses = <0x82005000 0 0x82000 0 0x2000>;
reg = <0x5000 0 0 0 0>;
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
- ranges;
+ ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
+ 0x81000000 0 0 0x81000000 0xa 0 1 0>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &mpic 103>;
marvell,pcie-port = <3>;

View file

@ -0,0 +1,90 @@
From cc4fb487fbf95c97b40e1e8e5b8b2ddabc8d124d Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Mon, 3 Jun 2013 18:47:36 +0200
Subject: [PATCH 067/203] ARM: mvebu: set aliases for ethernet controllers
These aliases are used when feeding the DT from ATAGS to set the
devices MAC addresses.
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 9 +++++++--
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 3 ++-
arch/arm/boot/dts/armada-xp.dtsi | 6 +++++-
3 files changed, 14 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -24,6 +24,11 @@
model = "Marvell Armada 370 and XP SoC";
compatible = "marvell,armada-370-xp";
+ aliases {
+ eth0 = &eth0;
+ eth1 = &eth1;
+ };
+
cpus {
cpu@0 {
compatible = "marvell,sheeva-v7";
@@ -151,7 +156,7 @@
reg = <0x72004 0x4>;
};
- ethernet@70000 {
+ eth0: ethernet@70000 {
compatible = "marvell,armada-370-neta";
reg = <0x70000 0x4000>;
interrupts = <8>;
@@ -159,7 +164,7 @@
status = "disabled";
};
- ethernet@74000 {
+ eth1: ethernet@74000 {
compatible = "marvell,armada-370-neta";
reg = <0x74000 0x4000>;
interrupts = <10>;
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -23,6 +23,7 @@
gpio0 = &gpio0;
gpio1 = &gpio1;
gpio2 = &gpio2;
+ eth3 = &eth3;
};
@@ -326,7 +327,7 @@
interrupts = <91>;
};
- ethernet@34000 {
+ eth3: ethernet@34000 {
compatible = "marvell,armada-370-neta";
reg = <0x34000 0x4000>;
interrupts = <14>;
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -22,6 +22,10 @@
model = "Marvell Armada XP family SoC";
compatible = "marvell,armadaxp", "marvell,armada-370-xp";
+ aliases {
+ eth2 = &eth2;
+ };
+
soc {
compatible = "marvell,armadaxp-mbus", "simple-bus";
@@ -93,7 +97,7 @@
reg = <0x18200 0x500>;
};
- ethernet@30000 {
+ eth2: ethernet@30000 {
compatible = "marvell,armada-370-neta";
reg = <0x30000 0x4000>;
interrupts = <12>;

View file

@ -0,0 +1,127 @@
From d967b31469239f610ea84b0a54ce296c15d860e9 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Tue, 30 Jul 2013 16:59:02 +0200
Subject: [PATCH 068/203] ARM: mvebu: use correct #interrupt-cells instead of
#interrupts-cells
The Device Tree information for the GPIO banks of the Armada 370 and
Armada XP SOCs was incorrectly using #interrupts-cells instead of
controller when using GPIO interrupts, since the GPIO bank DT node
wasn't recognized as a valid interrupt controller by the OF code.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/boot/dts/armada-370.dtsi | 6 +++---
arch/arm/boot/dts/armada-xp-mv78230.dtsi | 4 ++--
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 6 +++---
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 6 +++---
4 files changed, 11 insertions(+), 11 deletions(-)
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -136,7 +136,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
};
@@ -147,7 +147,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <87>, <88>, <89>, <90>;
};
@@ -158,7 +158,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <91>;
};
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -181,7 +181,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
};
@@ -192,7 +192,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <87>, <88>, <89>;
};
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -203,7 +203,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
};
@@ -214,7 +214,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <87>, <88>, <89>, <90>;
};
@@ -225,7 +225,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <91>;
};
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -301,7 +301,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <82>, <83>, <84>, <85>;
};
@@ -312,7 +312,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <87>, <88>, <89>, <90>;
};
@@ -323,7 +323,7 @@
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
- #interrupts-cells = <2>;
+ #interrupt-cells = <2>;
interrupts = <91>;
};

View file

@ -0,0 +1,21 @@
From 3953e4230483d6ce51b9f7e3b20db30e5ca6f4da Mon Sep 17 00:00:00 2001
From: Jason Cooper <jason@lakedaemon.net>
Date: Wed, 7 Aug 2013 20:04:21 +0000
Subject: [PATCH 069/203] ARM: mvebu: use dts pre-processor for mv78230
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/boot/dts/armada-xp-mv78230.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -13,7 +13,7 @@
* common to all Armada XP SoCs.
*/
-/include/ "armada-xp.dtsi"
+#include "armada-xp.dtsi"
/ {
model = "Marvell Armada XP MV78230 SoC";

View file

@ -0,0 +1,291 @@
From 4fb403ed86e78027a5b85333fa1491d5a0e68ae9 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Wed, 19 Jun 2013 09:42:32 +0200
Subject: [PATCH 070/203] PCI: use weak functions for MSI arch-specific
functions
Until now, the MSI architecture-specific functions could be overloaded
using a fairly complex set of #define and compile-time
conditionals. In order to prepare for the introduction of the msi_chip
infrastructure, it is desirable to switch all those functions to use
the 'weak' mechanism. This commit converts all the architectures that
were overidding those MSI functions to use the new strategy.
Note that we keep two separate, non-weak, functions
default_teardown_msi_irqs() and default_restore_msi_irqs() for the
default behavior of the arch_teardown_msi_irqs() and
arch_restore_msi_irqs(), as the default behavior is needed by x86 PCI
code.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Tested-by: Daniel Price <daniel.price@gmail.com>
Tested-by: Thierry Reding <thierry.reding@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Cc: David S. Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Chris Metcalf <cmetcalf@tilera.com>
---
arch/mips/include/asm/pci.h | 5 -----
arch/powerpc/include/asm/pci.h | 5 -----
arch/s390/include/asm/pci.h | 4 ----
arch/x86/include/asm/pci.h | 30 --------------------------
arch/x86/kernel/x86_init.c | 24 +++++++++++++++++++++
drivers/pci/msi.c | 48 +++++++++++++++++++++---------------------
include/linux/msi.h | 8 ++++++-
7 files changed, 55 insertions(+), 69 deletions(-)
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -137,11 +137,6 @@ static inline int pci_get_legacy_ide_irq
return channel ? 15 : 14;
}
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-/* MSI arch hook for OCTEON */
-#define arch_setup_msi_irqs arch_setup_msi_irqs
-#endif
-
extern char * (*pcibios_plat_setup)(char *str);
#ifdef CONFIG_OF
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -113,11 +113,6 @@ extern int pci_domain_nr(struct pci_bus
/* Decide whether to display the domain number in /proc */
extern int pci_proc_domain(struct pci_bus *bus);
-/* MSI arch hooks */
-#define arch_setup_msi_irqs arch_setup_msi_irqs
-#define arch_teardown_msi_irqs arch_teardown_msi_irqs
-#define arch_msi_check_device arch_msi_check_device
-
struct vm_area_struct;
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -21,10 +21,6 @@ void pci_iounmap(struct pci_dev *, void
int pci_domain_nr(struct pci_bus *);
int pci_proc_domain(struct pci_bus *);
-/* MSI arch hooks */
-#define arch_setup_msi_irqs arch_setup_msi_irqs
-#define arch_teardown_msi_irqs arch_teardown_msi_irqs
-
#define ZPCI_BUS_NR 0 /* default bus number */
#define ZPCI_DEVFN 0 /* default device number */
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -100,29 +100,6 @@ static inline void early_quirks(void) {
extern void pci_iommu_alloc(void);
#ifdef CONFIG_PCI_MSI
-/* MSI arch specific hooks */
-static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
- return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-static inline void x86_teardown_msi_irqs(struct pci_dev *dev)
-{
- x86_msi.teardown_msi_irqs(dev);
-}
-
-static inline void x86_teardown_msi_irq(unsigned int irq)
-{
- x86_msi.teardown_msi_irq(irq);
-}
-static inline void x86_restore_msi_irqs(struct pci_dev *dev, int irq)
-{
- x86_msi.restore_msi_irqs(dev, irq);
-}
-#define arch_setup_msi_irqs x86_setup_msi_irqs
-#define arch_teardown_msi_irqs x86_teardown_msi_irqs
-#define arch_teardown_msi_irq x86_teardown_msi_irq
-#define arch_restore_msi_irqs x86_restore_msi_irqs
/* implemented in arch/x86/kernel/apic/io_apic. */
struct msi_desc;
int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
@@ -130,16 +107,9 @@ void native_teardown_msi_irq(unsigned in
void native_restore_msi_irqs(struct pci_dev *dev, int irq);
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
unsigned int irq_base, unsigned int irq_offset);
-/* default to the implementation in drivers/lib/msi.c */
-#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
-#define HAVE_DEFAULT_MSI_RESTORE_IRQS
-void default_teardown_msi_irqs(struct pci_dev *dev);
-void default_restore_msi_irqs(struct pci_dev *dev, int irq);
#else
#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
-#define default_teardown_msi_irqs NULL
-#define default_restore_msi_irqs NULL
#endif
#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -107,6 +107,8 @@ struct x86_platform_ops x86_platform = {
};
EXPORT_SYMBOL_GPL(x86_platform);
+
+#if defined(CONFIG_PCI_MSI)
struct x86_msi_ops x86_msi = {
.setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg = native_compose_msi_msg,
@@ -116,6 +118,28 @@ struct x86_msi_ops x86_msi = {
.setup_hpet_msi = default_setup_hpet_msi,
};
+/* MSI arch specific hooks */
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ return x86_msi.setup_msi_irqs(dev, nvec, type);
+}
+
+void arch_teardown_msi_irqs(struct pci_dev *dev)
+{
+ x86_msi.teardown_msi_irqs(dev);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ x86_msi.teardown_msi_irq(irq);
+}
+
+void arch_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+ x86_msi.restore_msi_irqs(dev, irq);
+}
+#endif
+
struct x86_io_apic_ops x86_io_apic_ops = {
.init = native_io_apic_init_mappings,
.read = native_io_apic_read,
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -30,20 +30,21 @@ static int pci_msi_enable = 1;
/* Arch hooks */
-#ifndef arch_msi_check_device
-int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+ return -EINVAL;
+}
+
+void __weak arch_teardown_msi_irq(unsigned int irq)
{
- return 0;
}
-#endif
-#ifndef arch_setup_msi_irqs
-# define arch_setup_msi_irqs default_setup_msi_irqs
-# define HAVE_DEFAULT_MSI_SETUP_IRQS
-#endif
+int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+{
+ return 0;
+}
-#ifdef HAVE_DEFAULT_MSI_SETUP_IRQS
-int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
@@ -65,14 +66,11 @@ int default_setup_msi_irqs(struct pci_de
return 0;
}
-#endif
-#ifndef arch_teardown_msi_irqs
-# define arch_teardown_msi_irqs default_teardown_msi_irqs
-# define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
-#endif
-
-#ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS
+/*
+ * We have a default implementation available as a separate non-weak
+ * function, as it is used by the Xen x86 PCI code
+ */
void default_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
@@ -86,14 +84,12 @@ void default_teardown_msi_irqs(struct pc
arch_teardown_msi_irq(entry->irq + i);
}
}
-#endif
-#ifndef arch_restore_msi_irqs
-# define arch_restore_msi_irqs default_restore_msi_irqs
-# define HAVE_DEFAULT_MSI_RESTORE_IRQS
-#endif
+void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
+{
+ return default_teardown_msi_irqs(dev);
+}
-#ifdef HAVE_DEFAULT_MSI_RESTORE_IRQS
void default_restore_msi_irqs(struct pci_dev *dev, int irq)
{
struct msi_desc *entry;
@@ -111,7 +107,11 @@ void default_restore_msi_irqs(struct pci
if (entry)
write_msi_msg(irq, &entry->msg);
}
-#endif
+
+void __weak arch_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+ return default_restore_msi_irqs(dev, irq);
+}
static void msi_set_enable(struct pci_dev *dev, int enable)
{
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -50,12 +50,18 @@ struct msi_desc {
};
/*
- * The arch hook for setup up msi irqs
+ * The arch hooks to setup up msi irqs. Those functions are
+ * implemented as weak symbols so that they /can/ be overriden by
+ * architecture specific code if needed.
*/
int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
void arch_teardown_msi_irq(unsigned int irq);
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
void arch_teardown_msi_irqs(struct pci_dev *dev);
int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
+void arch_restore_msi_irqs(struct pci_dev *dev, int irq);
+
+void default_teardown_msi_irqs(struct pci_dev *dev);
+void default_restore_msi_irqs(struct pci_dev *dev, int irq);
#endif /* LINUX_MSI_H */

View file

@ -0,0 +1,152 @@
From c819a1b0907257d73de96af33d557668a5c0c895 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Mon, 1 Jul 2013 14:26:57 +0200
Subject: [PATCH 071/203] PCI: remove ARCH_SUPPORTS_MSI kconfig option
Now that we have weak versions for each of the PCI MSI architecture
functions, we can actually build the MSI support for all platforms,
regardless of whether they provide or not architecture-specific
versions of those functions. For this reason, the ARCH_SUPPORTS_MSI
hidden kconfig boolean becomes useless, and this patch gets rid of it.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Tested-by: Daniel Price <daniel.price@gmail.com>
Tested-by: Thierry Reding <thierry.reding@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Cc: David S. Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Chris Metcalf <cmetcalf@tilera.com>
---
arch/arm/Kconfig | 1 -
arch/ia64/Kconfig | 1 -
arch/mips/Kconfig | 2 --
arch/powerpc/Kconfig | 1 -
arch/s390/Kconfig | 1 -
arch/sparc/Kconfig | 1 -
arch/tile/Kconfig | 1 -
arch/x86/Kconfig | 1 -
drivers/pci/Kconfig | 4 ----
9 files changed, 13 deletions(-)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -435,7 +435,6 @@ config ARCH_NETX
config ARCH_IOP13XX
bool "IOP13xx-based"
depends on MMU
- select ARCH_SUPPORTS_MSI
select CPU_XSC3
select NEED_MACH_MEMORY_H
select NEED_RET_TO_USER
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -9,7 +9,6 @@ config IA64
select PCI if (!IA64_HP_SIM)
select ACPI if (!IA64_HP_SIM)
select PM if (!IA64_HP_SIM)
- select ARCH_SUPPORTS_MSI
select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_IDE
select HAVE_OPROFILE
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -764,7 +764,6 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select SYS_HAS_CPU_CAVIUM_OCTEON
select SWAP_IO_SPACE
select HW_HAS_PCI
- select ARCH_SUPPORTS_MSI
select ZONE_DMA32
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
@@ -800,7 +799,6 @@ config NLM_XLR_BOARD
select CEVT_R4K
select CSRC_R4K
select IRQ_CPU
- select ARCH_SUPPORTS_MSI
select ZONE_DMA32 if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -734,7 +734,6 @@ config PCI
default y if !40x && !CPM2 && !8xx && !PPC_83xx \
&& !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON
default PCI_QSPAN if !4xx && !CPM2 && 8xx
- select ARCH_SUPPORTS_MSI
select GENERIC_PCI_IOMAP
help
Find out whether your system includes a PCI bus. PCI is the name of
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -430,7 +430,6 @@ menuconfig PCI
bool "PCI support"
default n
depends on 64BIT
- select ARCH_SUPPORTS_MSI
select PCI_MSI
help
Enable PCI support.
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -52,7 +52,6 @@ config SPARC32
config SPARC64
def_bool 64BIT
- select ARCH_SUPPORTS_MSI
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_FP_TEST
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -379,7 +379,6 @@ config PCI
select PCI_DOMAINS
select GENERIC_PCI_IOMAP
select TILE_GXIO_TRIO if TILEGX
- select ARCH_SUPPORTS_MSI if TILEGX
select PCI_MSI if TILEGX
---help---
Enable PCI root complex support, so PCIe endpoint devices can
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1999,7 +1999,6 @@ menu "Bus options (PCI etc.)"
config PCI
bool "PCI support"
default y
- select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC)
---help---
Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -1,13 +1,9 @@
#
# PCI configuration
#
-config ARCH_SUPPORTS_MSI
- bool
-
config PCI_MSI
bool "Message Signaled Interrupts (MSI and MSI-X)"
depends on PCI
- depends on ARCH_SUPPORTS_MSI
help
This allows device drivers to enable MSI (Message Signaled
Interrupts). Message Signaled Interrupts enable a device to

View file

@ -0,0 +1,108 @@
From 9c6ddccbbfaf789beccc6a1d87abe9bc60dc570f Mon Sep 17 00:00:00 2001
From: Thierry Reding <thierry.reding@avionic-design.de>
Date: Thu, 6 Jun 2013 18:20:29 +0200
Subject: [PATCH 072/203] PCI: Introduce new MSI chip infrastructure
The new struct msi_chip is used to associated an MSI controller with a
PCI bus. It is automatically handed down from the root to its children
during bus enumeration.
This patch provides default (weak) implementations for the architecture-
specific MSI functions (arch_setup_msi_irq(), arch_teardown_msi_irq()
and arch_msi_check_device()) which check if a PCI device's bus has an
attached MSI chip and forward the call appropriately.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Daniel Price <daniel.price@gmail.com>
Tested-by: Thierry Reding <thierry.reding@gmail.com>
---
drivers/pci/msi.c | 27 +++++++++++++++++++++++++--
drivers/pci/probe.c | 1 +
include/linux/msi.h | 11 +++++++++++
include/linux/pci.h | 1 +
4 files changed, 38 insertions(+), 2 deletions(-)
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -32,16 +32,39 @@ static int pci_msi_enable = 1;
int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- return -EINVAL;
+ struct msi_chip *chip = dev->bus->msi;
+ int err;
+
+ if (!chip || !chip->setup_irq)
+ return -EINVAL;
+
+ err = chip->setup_irq(chip, dev, desc);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_data(desc->irq, chip);
+
+ return 0;
}
void __weak arch_teardown_msi_irq(unsigned int irq)
{
+ struct msi_chip *chip = irq_get_chip_data(irq);
+
+ if (!chip || !chip->teardown_irq)
+ return;
+
+ chip->teardown_irq(chip, irq);
}
int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
{
- return 0;
+ struct msi_chip *chip = dev->bus->msi;
+
+ if (!chip || !chip->check_device)
+ return 0;
+
+ return chip->check_device(chip, dev, nvec, type);
}
int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -634,6 +634,7 @@ static struct pci_bus *pci_alloc_child_b
child->parent = parent;
child->ops = parent->ops;
+ child->msi = parent->msi;
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -64,4 +64,15 @@ void arch_restore_msi_irqs(struct pci_de
void default_teardown_msi_irqs(struct pci_dev *dev);
void default_restore_msi_irqs(struct pci_dev *dev, int irq);
+struct msi_chip {
+ struct module *owner;
+ struct device *dev;
+
+ int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
+ struct msi_desc *desc);
+ void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
+ int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
+ int nvec, int type);
+};
+
#endif /* LINUX_MSI_H */
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -432,6 +432,7 @@ struct pci_bus {
struct resource busn_res; /* bus numbers routed to this bus */
struct pci_ops *ops; /* configuration access functions */
+ struct msi_chip *msi; /* MSI controller */
void *sysdata; /* hook for sys-specific extension */
struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */

View file

@ -0,0 +1,106 @@
From a05852e828063b6731fcac543b87367c137c16f8 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:21:18 +0200
Subject: [PATCH 073/203] of: pci: add registry of MSI chips
This commit adds a very basic registry of msi_chip structures, so that
an IRQ controller driver can register an msi_chip, and a PCIe host
controller can find it, based on a 'struct device_node'.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Rob Herring <rob.herring@calxeda.com>
---
drivers/of/of_pci.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/msi.h | 2 ++
include/linux/of_pci.h | 12 ++++++++++++
3 files changed, 59 insertions(+)
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -89,3 +89,48 @@ int of_pci_parse_bus_range(struct device
return 0;
}
EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
+
+#ifdef CONFIG_PCI_MSI
+
+static LIST_HEAD(of_pci_msi_chip_list);
+static DEFINE_MUTEX(of_pci_msi_chip_mutex);
+
+int of_pci_msi_chip_add(struct msi_chip *chip)
+{
+ if (!of_property_read_bool(chip->of_node, "msi-controller"))
+ return -EINVAL;
+
+ mutex_lock(&of_pci_msi_chip_mutex);
+ list_add(&chip->list, &of_pci_msi_chip_list);
+ mutex_unlock(&of_pci_msi_chip_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_msi_chip_add);
+
+void of_pci_msi_chip_remove(struct msi_chip *chip)
+{
+ mutex_lock(&of_pci_msi_chip_mutex);
+ list_del(&chip->list);
+ mutex_unlock(&of_pci_msi_chip_mutex);
+}
+EXPORT_SYMBOL_GPL(of_pci_msi_chip_remove);
+
+struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node)
+{
+ struct msi_chip *c;
+
+ mutex_lock(&of_pci_msi_chip_mutex);
+ list_for_each_entry(c, &of_pci_msi_chip_list, list) {
+ if (c->of_node == of_node) {
+ mutex_unlock(&of_pci_msi_chip_mutex);
+ return c;
+ }
+ }
+ mutex_unlock(&of_pci_msi_chip_mutex);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_pci_find_msi_chip_by_node);
+
+#endif /* CONFIG_PCI_MSI */
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -67,6 +67,8 @@ void default_restore_msi_irqs(struct pci
struct msi_chip {
struct module *owner;
struct device *dev;
+ struct device_node *of_node;
+ struct list_head list;
int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
struct msi_desc *desc);
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -2,6 +2,7 @@
#define __OF_PCI_H
#include <linux/pci.h>
+#include <linux/msi.h>
struct pci_dev;
struct of_irq;
@@ -13,4 +14,15 @@ struct device_node *of_pci_find_child_de
int of_pci_get_devfn(struct device_node *np);
int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
+#if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI)
+int of_pci_msi_chip_add(struct msi_chip *chip);
+void of_pci_msi_chip_remove(struct msi_chip *chip);
+struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node);
+#else
+static inline int of_pci_msi_chip_add(struct msi_chip *chip) { return -EINVAL; }
+static inline void of_pci_msi_chip_remove(struct msi_chip *chip) { }
+static inline struct msi_chip *
+of_pci_find_msi_chip_by_node(struct device_node *of_node) { return NULL; }
+#endif
+
#endif

View file

@ -0,0 +1,64 @@
From c8efa45217cbd780dafe12d87b61554c2e19a010 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:22:51 +0200
Subject: [PATCH 074/203] irqchip: armada-370-xp: properly request resources
Instead of using of_iomap(), we now use of_address_to_resource(),
request_mem_region() and ioremap(). This allows the corresponding I/O
regions to be properly requested and visible in /proc/iomem.
The main motivation for this change is that the introduction of the
MSI support requires us to get the physical address of the main
interrupt controller registers, so we will need the corresponding
'struct resource' anyway.
We also take this opportunity to change a panic() to BUG_ON(), in
order to be consistent with the rest of the driver.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Daniel Price <daniel.price@gmail.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/irqchip/irq-armada-370-xp.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -248,12 +248,25 @@ armada_370_xp_handle_irq(struct pt_regs
static int __init armada_370_xp_mpic_of_init(struct device_node *node,
struct device_node *parent)
{
+ struct resource main_int_res, per_cpu_int_res;
u32 control;
- main_int_base = of_iomap(node, 0);
- per_cpu_int_base = of_iomap(node, 1);
+ BUG_ON(of_address_to_resource(node, 0, &main_int_res));
+ BUG_ON(of_address_to_resource(node, 1, &per_cpu_int_res));
+ BUG_ON(!request_mem_region(main_int_res.start,
+ resource_size(&main_int_res),
+ node->full_name));
+ BUG_ON(!request_mem_region(per_cpu_int_res.start,
+ resource_size(&per_cpu_int_res),
+ node->full_name));
+
+ main_int_base = ioremap(main_int_res.start,
+ resource_size(&main_int_res));
BUG_ON(!main_int_base);
+
+ per_cpu_int_base = ioremap(per_cpu_int_res.start,
+ resource_size(&per_cpu_int_res));
BUG_ON(!per_cpu_int_base);
control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
@@ -262,8 +275,7 @@ static int __init armada_370_xp_mpic_of_
irq_domain_add_linear(node, (control >> 2) & 0x3ff,
&armada_370_xp_mpic_irq_ops, NULL);
- if (!armada_370_xp_mpic_domain)
- panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
+ BUG_ON(!armada_370_xp_mpic_domain);
irq_set_default_host(armada_370_xp_mpic_domain);

View file

@ -0,0 +1,270 @@
From eaa70d53f6b827f147d775a3de7ff3ef27d0fae6 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:25:16 +0200
Subject: [PATCH 075/203] irqchip: armada-370-xp: implement MSI support
This commit introduces the support for the MSI interrupts in the
armada-370-xp interrupt controller driver. It registers an MSI chip to
the MSI chip registry, which will be used by the Marvell PCIe host
controller driver.
The MSI interrupts use the 16 high doorbells, and are therefore
notified using IRQ1 of the main interrupt controller.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/arm/armada-370-xp-mpic.txt | 3 +
drivers/irqchip/irq-armada-370-xp.c | 182 ++++++++++++++++++++-
2 files changed, 184 insertions(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
+++ b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
@@ -4,6 +4,8 @@ Marvell Armada 370 and Armada XP Interru
Required properties:
- compatible: Should be "marvell,mpic"
- interrupt-controller: Identifies the node as an interrupt controller.
+- msi-controller: Identifies the node as an PCI Message Signaled
+ Interrupt controller.
- #interrupt-cells: The number of cells to define the interrupts. Should be 1.
The cell is the IRQ number
@@ -24,6 +26,7 @@ Example:
#address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
+ msi-controller;
reg = <0xd0020a00 0x1d0>,
<0xd0021070 0x58>;
};
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -21,7 +21,10 @@
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/of_pci.h>
#include <linux/irqdomain.h>
+#include <linux/slab.h>
+#include <linux/msi.h>
#include <asm/mach/arch.h>
#include <asm/exception.h>
#include <asm/smp_plat.h>
@@ -51,12 +54,22 @@
#define IPI_DOORBELL_START (0)
#define IPI_DOORBELL_END (8)
#define IPI_DOORBELL_MASK 0xFF
+#define PCI_MSI_DOORBELL_START (16)
+#define PCI_MSI_DOORBELL_NR (16)
+#define PCI_MSI_DOORBELL_END (32)
+#define PCI_MSI_DOORBELL_MASK 0xFFFF0000
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
static void __iomem *per_cpu_int_base;
static void __iomem *main_int_base;
static struct irq_domain *armada_370_xp_mpic_domain;
+#ifdef CONFIG_PCI_MSI
+static struct irq_domain *armada_370_xp_msi_domain;
+static DECLARE_BITMAP(msi_used, PCI_MSI_DOORBELL_NR);
+static DEFINE_MUTEX(msi_used_lock);
+static phys_addr_t msi_doorbell_addr;
+#endif
/*
* In SMP mode:
@@ -87,6 +100,144 @@ static void armada_370_xp_irq_unmask(str
ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
}
+#ifdef CONFIG_PCI_MSI
+
+static int armada_370_xp_alloc_msi(void)
+{
+ int hwirq;
+
+ mutex_lock(&msi_used_lock);
+ hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR);
+ if (hwirq >= PCI_MSI_DOORBELL_NR)
+ hwirq = -ENOSPC;
+ else
+ set_bit(hwirq, msi_used);
+ mutex_unlock(&msi_used_lock);
+
+ return hwirq;
+}
+
+static void armada_370_xp_free_msi(int hwirq)
+{
+ mutex_lock(&msi_used_lock);
+ if (!test_bit(hwirq, msi_used))
+ pr_err("trying to free unused MSI#%d\n", hwirq);
+ else
+ clear_bit(hwirq, msi_used);
+ mutex_unlock(&msi_used_lock);
+}
+
+static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
+ struct pci_dev *pdev,
+ struct msi_desc *desc)
+{
+ struct msi_msg msg;
+ irq_hw_number_t hwirq;
+ int virq;
+
+ hwirq = armada_370_xp_alloc_msi();
+ if (hwirq < 0)
+ return hwirq;
+
+ virq = irq_create_mapping(armada_370_xp_msi_domain, hwirq);
+ if (!virq) {
+ armada_370_xp_free_msi(hwirq);
+ return -EINVAL;
+ }
+
+ irq_set_msi_desc(virq, desc);
+
+ msg.address_lo = msi_doorbell_addr;
+ msg.address_hi = 0;
+ msg.data = 0xf00 | (hwirq + 16);
+
+ write_msi_msg(virq, &msg);
+ return 0;
+}
+
+static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
+ unsigned int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+ irq_dispose_mapping(irq);
+ armada_370_xp_free_msi(d->hwirq);
+}
+
+static struct irq_chip armada_370_xp_msi_irq_chip = {
+ .name = "armada_370_xp_msi_irq",
+ .irq_enable = unmask_msi_irq,
+ .irq_disable = mask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+};
+
+static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
+ handle_simple_irq);
+ set_irq_flags(virq, IRQF_VALID);
+
+ return 0;
+}
+
+static const struct irq_domain_ops armada_370_xp_msi_irq_ops = {
+ .map = armada_370_xp_msi_map,
+};
+
+static int armada_370_xp_msi_init(struct device_node *node,
+ phys_addr_t main_int_phys_base)
+{
+ struct msi_chip *msi_chip;
+ u32 reg;
+ int ret;
+
+ msi_doorbell_addr = main_int_phys_base +
+ ARMADA_370_XP_SW_TRIG_INT_OFFS;
+
+ msi_chip = kzalloc(sizeof(*msi_chip), GFP_KERNEL);
+ if (!msi_chip)
+ return -ENOMEM;
+
+ msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
+ msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
+ msi_chip->of_node = node;
+
+ armada_370_xp_msi_domain =
+ irq_domain_add_linear(NULL, PCI_MSI_DOORBELL_NR,
+ &armada_370_xp_msi_irq_ops,
+ NULL);
+ if (!armada_370_xp_msi_domain) {
+ kfree(msi_chip);
+ return -ENOMEM;
+ }
+
+ ret = of_pci_msi_chip_add(msi_chip);
+ if (ret < 0) {
+ irq_domain_remove(armada_370_xp_msi_domain);
+ kfree(msi_chip);
+ return ret;
+ }
+
+ reg = readl(per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_MSK_OFFS)
+ | PCI_MSI_DOORBELL_MASK;
+
+ writel(reg, per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
+
+ /* Unmask IPI interrupt */
+ writel(1, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
+
+ return 0;
+}
+#else
+static inline int armada_370_xp_msi_init(struct device_node *node,
+ phys_addr_t main_int_phys_base)
+{
+ return 0;
+}
+#endif
+
#ifdef CONFIG_SMP
static int armada_xp_set_affinity(struct irq_data *d,
const struct cpumask *mask_val, bool force)
@@ -214,12 +365,39 @@ armada_370_xp_handle_irq(struct pt_regs
if (irqnr > 1022)
break;
- if (irqnr > 0) {
+ if (irqnr > 1) {
irqnr = irq_find_mapping(armada_370_xp_mpic_domain,
irqnr);
handle_IRQ(irqnr, regs);
continue;
}
+
+#ifdef CONFIG_PCI_MSI
+ /* MSI handling */
+ if (irqnr == 1) {
+ u32 msimask, msinr;
+
+ msimask = readl_relaxed(per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
+ & PCI_MSI_DOORBELL_MASK;
+
+ writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
+
+ for (msinr = PCI_MSI_DOORBELL_START;
+ msinr < PCI_MSI_DOORBELL_END; msinr++) {
+ int irq;
+
+ if (!(msimask & BIT(msinr)))
+ continue;
+
+ irq = irq_find_mapping(armada_370_xp_msi_domain,
+ msinr - 16);
+ handle_IRQ(irq, regs);
+ }
+ }
+#endif
+
#ifdef CONFIG_SMP
/* IPI Handling */
if (irqnr == 0) {
@@ -292,6 +470,8 @@ static int __init armada_370_xp_mpic_of_
#endif
+ armada_370_xp_msi_init(node, main_int_res.start);
+
set_handle_irq(armada_370_xp_handle_irq);
return 0;

View file

@ -0,0 +1,80 @@
From ea6a42a34462ea382209ff4f083b8b17260eb409 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Wed, 19 Jun 2013 18:27:20 +0200
Subject: [PATCH 076/203] ARM: pci: add ->add_bus() and ->remove_bus() hooks to
hw_pci
Some PCI drivers may need to adjust the pci_bus structure after it has
been allocated by the Linux PCI core. The PCI core allows
architectures to implement the pcibios_add_bus() and
pcibios_remove_bus() for this purpose. This commit therefore extends
the hw_pci and pci_sys_data structures of the ARM PCI core to allow
PCI drivers to register ->add_bus() and ->remove_bus() in hw_pci,
which will get called when a bus is added or removed from the system.
This will be used for example by the Marvell PCIe driver to connect a
particular PCI bus with its corresponding MSI chip to handle Message
Signaled Interrupts.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Daniel Price <daniel.price@gmail.com>
Tested-by: Thierry Reding <thierry.reding@gmail.com>
---
arch/arm/include/asm/mach/pci.h | 4 ++++
arch/arm/kernel/bios32.c | 16 ++++++++++++++++
2 files changed, 20 insertions(+)
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -35,6 +35,8 @@ struct hw_pci {
resource_size_t start,
resource_size_t size,
resource_size_t align);
+ void (*add_bus)(struct pci_bus *bus);
+ void (*remove_bus)(struct pci_bus *bus);
};
/*
@@ -62,6 +64,8 @@ struct pci_sys_data {
resource_size_t start,
resource_size_t size,
resource_size_t align);
+ void (*add_bus)(struct pci_bus *bus);
+ void (*remove_bus)(struct pci_bus *bus);
void *private_data; /* platform controller private data */
};
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -363,6 +363,20 @@ void pcibios_fixup_bus(struct pci_bus *b
}
EXPORT_SYMBOL(pcibios_fixup_bus);
+void pcibios_add_bus(struct pci_bus *bus)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ if (sys->add_bus)
+ sys->add_bus(bus);
+}
+
+void pcibios_remove_bus(struct pci_bus *bus)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ if (sys->remove_bus)
+ sys->remove_bus(bus);
+}
+
/*
* Swizzle the device pin each time we cross a bridge. If a platform does
* not provide a swizzle function, we perform the standard PCI swizzling.
@@ -463,6 +477,8 @@ static void pcibios_init_hw(struct hw_pc
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
sys->align_resource = hw->align_resource;
+ sys->add_bus = hw->add_bus;
+ sys->remove_bus = hw->remove_bus;
INIT_LIST_HEAD(&sys->resources);
if (hw->private_data)

View file

@ -0,0 +1,28 @@
From 2ae5acab1c267ef1c5e61e5086b93fba8eb9752e Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:26:29 +0200
Subject: [PATCH 077/203] ARM: mvebu: the MPIC now provides MSI controller
features
Adds the 'msi-controller' property to the main interrupt controller
Device Tree node, to indicate that it can now behave as a MSI
controller.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Thierry Reding <thierry.reding@gmail.com>
Tested-by: Daniel Price <daniel.price@gmail.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -109,6 +109,7 @@
#interrupt-cells = <1>;
#size-cells = <1>;
interrupt-controller;
+ msi-controller;
};
coherency-fabric@20200 {

View file

@ -0,0 +1,109 @@
From be448338edda73460dc3e8c005b17edddf1c1b4f Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:27:16 +0200
Subject: [PATCH 078/203] PCI: mvebu: add support for MSI
This commit adds support for Message Signaled Interrupts in the
Marvell PCIe host controller. The work is very simple: it simply gets
a reference to the msi_chip associated to the PCIe controller thanks
to the msi-parent DT property, and stores this reference in the
pci_bus structure. This is enough to let the Linux PCI core use the
functions of msi_chip to setup and teardown MSIs.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
.../devicetree/bindings/pci/mvebu-pci.txt | 3 +++
drivers/pci/host/pci-mvebu.c | 26 ++++++++++++++++++++++
2 files changed, 29 insertions(+)
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -14,6 +14,8 @@ Mandatory properties:
interfaces, and ranges describing the MBus windows needed to access
the memory and I/O regions of each PCIe interface.
+- msi-parent: Link to the hardware entity that serves as the Message
+ Signaled Interrupt controller for this PCI controller.
The ranges describing the MMIO registers have the following layout:
0x82000000 0 r MBUS_ID(0xf0, 0x01) r 0 s
@@ -85,6 +87,7 @@ pcie-controller {
#size-cells = <2>;
bus-range = <0x00 0xff>;
+ msi-parent = <&mpic>;
ranges =
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -11,6 +11,7 @@
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/mbus.h>
+#include <linux/msi.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/of_address.h>
@@ -103,6 +104,7 @@ struct mvebu_pcie_port;
struct mvebu_pcie {
struct platform_device *pdev;
struct mvebu_pcie_port *ports;
+ struct msi_chip *msi;
struct resource io;
struct resource realio;
struct resource mem;
@@ -673,6 +675,12 @@ static struct pci_bus *mvebu_pcie_scan_b
return bus;
}
+void mvebu_pcie_add_bus(struct pci_bus *bus)
+{
+ struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+ bus->msi = pcie->msi;
+}
+
resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
@@ -709,6 +717,7 @@ static void __init mvebu_pcie_enable(str
hw.map_irq = mvebu_pcie_map_irq;
hw.ops = &mvebu_pcie_ops;
hw.align_resource = mvebu_pcie_align_resource;
+ hw.add_bus = mvebu_pcie_add_bus;
pci_common_init(&hw);
}
@@ -733,6 +742,21 @@ mvebu_pcie_map_registers(struct platform
return devm_request_and_ioremap(&pdev->dev, &regs);
}
+static void __init mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
+{
+ struct device_node *msi_node;
+
+ msi_node = of_parse_phandle(pcie->pdev->dev.of_node,
+ "msi-parent", 0);
+ if (!msi_node)
+ return;
+
+ pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
+
+ if (pcie->msi)
+ pcie->msi->dev = &pcie->pdev->dev;
+}
+
#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
#define DT_TYPE_IO 0x1
#define DT_TYPE_MEM32 0x2
@@ -911,6 +935,8 @@ static int __init mvebu_pcie_probe(struc
i++;
}
+ mvebu_pcie_msi_enable(pcie);
+
mvebu_pcie_enable(pcie);
return 0;

View file

@ -0,0 +1,60 @@
From 7171305e9caebac8cd12ef5a5ef3823f0fbe4a1c Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Thu, 6 Jun 2013 18:30:19 +0200
Subject: [PATCH 079/203] ARM: mvebu: link PCIe controllers to the MSI
controller
This commit adjusts the Armada 370 and Armada XP PCIe controllers
Device Tree informations to reference their MSI controller. In the
case of this platform, the MSI controller is implemented by the MPIC.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Tested-by: Daniel Price <daniel.price@gmail.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-370.dtsi | 1 +
arch/arm/boot/dts/armada-xp-mv78230.dtsi | 1 +
arch/arm/boot/dts/armada-xp-mv78260.dtsi | 1 +
arch/arm/boot/dts/armada-xp-mv78460.dtsi | 1 +
4 files changed, 4 insertions(+)
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -44,6 +44,7 @@
#address-cells = <3>;
#size-cells = <2>;
+ msi-parent = <&mpic>;
bus-range = <0x00 0xff>;
ranges =
--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
@@ -57,6 +57,7 @@
#address-cells = <3>;
#size-cells = <2>;
+ msi-parent = <&mpic>;
bus-range = <0x00 0xff>;
ranges =
--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
@@ -58,6 +58,7 @@
#address-cells = <3>;
#size-cells = <2>;
+ msi-parent = <&mpic>;
bus-range = <0x00 0xff>;
ranges =
--- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi
+++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi
@@ -74,6 +74,7 @@
#address-cells = <3>;
#size-cells = <2>;
+ msi-parent = <&mpic>;
bus-range = <0x00 0xff>;
ranges =

View file

@ -0,0 +1,132 @@
From 5378928ebac13756fc13d0b2de8dd45ace8026aa Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Mon, 15 Jul 2013 17:34:08 +0200
Subject: [PATCH 080/203] of: provide a binding for the 'fixed-link' property
Some Ethernet MACs have a "fixed link", and are not connected to a
normal MDIO-managed PHY device. For those situations, a Device Tree
binding allows to describe a "fixed link", as a "fixed-link" property
of the Ethernet device Device Tree node.
This patch adds:
* A documentation for the Device Tree property "fixed-link".
* A of_phy_register_fixed_link() OF helper, which provided an OF node
that contains a "fixed-link" property, registers the corresponding
fixed PHY.
* Removes the warning on the of_phy_connect_fixed_link() that says
new drivers should not use it, since Grant Likely indicated that
this "fixed-link" property is indeed the way to go.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
.../devicetree/bindings/net/fixed-link.txt | 26 ++++++++++++++++
drivers/of/of_mdio.c | 36 +++++++++++++++++++---
include/linux/of_mdio.h | 10 ++++++
3 files changed, 68 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/fixed-link.txt
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/fixed-link.txt
@@ -0,0 +1,26 @@
+Fixed link Device Tree binding
+------------------------------
+
+Some Ethernet MACs have a "fixed link", and are not connected to a
+normal MDIO-managed PHY device. For those situations, a Device Tree
+binding allows to describe a "fixed link".
+
+Such a fixed link situation is described within an Ethernet device
+Device Tree node using a 'fixed-link' property, composed of 5
+elements:
+
+ 1. A fake PHY ID, which must be unique accross all fixed-link PHYs in
+ the system.
+ 2. The duplex (1 for full-duplex, 0 for half-duplex)
+ 3. The speed (10, 100, 1000)
+ 4. The pause setting (1 for enabled, 0 for disabled)
+ 5. The asym pause setting (1 for enabled, 0 for disabled)
+
+Example:
+
+ethernet@0 {
+ ...
+ fixed-link = <1 1 1000 0 0>;
+ ...
+};
+
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -14,6 +14,7 @@
#include <linux/netdevice.h>
#include <linux/err.h>
#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
@@ -215,10 +216,6 @@ EXPORT_SYMBOL(of_phy_connect);
* @dev: pointer to net_device claiming the phy
* @hndlr: Link state callback for the network device
* @iface: PHY data interface type
- *
- * This function is a temporary stop-gap and will be removed soon. It is
- * only to support the fs_enet, ucc_geth and gianfar Ethernet drivers. Do
- * not call this function from new drivers.
*/
struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
void (*hndlr)(struct net_device *),
@@ -247,3 +244,34 @@ struct phy_device *of_phy_connect_fixed_
return IS_ERR(phy) ? NULL : phy;
}
EXPORT_SYMBOL(of_phy_connect_fixed_link);
+
+#if defined(CONFIG_FIXED_PHY)
+/**
+ * of_phy_register_fixed_link - Parse fixed-link property and register a dummy phy
+ * @np: pointer to the OF device node that contains the "fixed-link"
+ * property for which a dummy phy should be registered.
+ */
+#define FIXED_LINK_PROPERTIES_COUNT 5
+int of_phy_register_fixed_link(struct device_node *np)
+{
+ struct fixed_phy_status status = {};
+ u32 fixed_link_props[FIXED_LINK_PROPERTIES_COUNT];
+ int ret;
+
+ ret = of_property_read_u32_array(np, "fixed-link",
+ fixed_link_props,
+ FIXED_LINK_PROPERTIES_COUNT);
+ if (ret < 0)
+ return ret;
+
+ status.link = 1;
+ status.duplex = fixed_link_props[1];
+ status.speed = fixed_link_props[2];
+ status.pause = fixed_link_props[3];
+ status.asym_pause = fixed_link_props[4];
+
+ return fixed_phy_add(PHY_POLL, fixed_link_props[0],
+ &status);
+}
+EXPORT_SYMBOL(of_phy_register_fixed_link);
+#endif
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -57,4 +57,14 @@ static inline struct mii_bus *of_mdio_fi
}
#endif /* CONFIG_OF */
+#if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY)
+extern int of_phy_register_fixed_link(struct device_node *np);
+#else
+static inline int of_phy_register_fixed_link(struct device_node *np)
+{
+ return -ENOSYS;
+}
+#endif
+
+
#endif /* __LINUX_OF_MDIO_H */

View file

@ -0,0 +1,42 @@
From dce33dc5a6ba5f7fcbab4d7e92cc68c756a1f714 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Mon, 15 Jul 2013 17:34:09 +0200
Subject: [PATCH 081/203] net: phy: call mdiobus_scan() after adding a fixed
PHY
The fixed_phy_add() function allows to register a fixed PHY. However,
when this function gets called *after* fixed_mdio_bus_init() (which
gets called at the module_init stage), then the fixed PHY is not
registered into the phylib.
In order to address this, we add a call to mdiobus_scan() in
fixed_phy_add() to ensure that the PHY indeed gets registered into the
phylib, even if the fixed_phy_add() is called after
fixed_mdio_bus_init().
This is needed because until now, the only code that was calling the
fixed_add_phy() function was PowerPC-specific platform code, which
could ensure that such fixed PHYs get registered before
fixed_mdio_bus_init() is called.
However, with the new of_phy_register_fixed_link() function, device
drivers can parse their 'fixed-link' property and register a fixed PHY
at ->probe() time, which may happen after fixed_mdio_bus_init() is
called.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/net/phy/fixed.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -195,6 +195,8 @@ int fixed_phy_add(unsigned int irq, int
list_add_tail(&fp->node, &fmb->phys);
+ mdiobus_scan(fmb->mii_bus, phy_id);
+
return 0;
err_regs:

View file

@ -0,0 +1,90 @@
From 350a4e8e9d517d2d7c48bc915da5b1e30163add3 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Mon, 15 Jul 2013 17:34:10 +0200
Subject: [PATCH 082/203] net: mvneta: add support for fixed links
Following the introduction of of_phy_register_fixed_link(), this patch
introduces fixed link support in the mvneta driver, for Marvell Armada
370/XP SOCs.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
.../bindings/net/marvell-armada-370-neta.txt | 24 +++++++++++++++++++---
drivers/net/ethernet/marvell/mvneta.c | 18 +++++++++++-----
2 files changed, 34 insertions(+), 8 deletions(-)
--- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
+++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
@@ -4,13 +4,21 @@ Required properties:
- compatible: should be "marvell,armada-370-neta".
- reg: address and length of the register set for the device.
- interrupts: interrupt for the device
-- phy: A phandle to a phy node defining the PHY address (as the reg
- property, a single integer).
- phy-mode: The interface between the SoC and the PHY (a string that
of_get_phy_mode() can understand)
- clocks: a pointer to the reference clock for this device.
-Example:
+Optional properties:
+
+- phy: A phandle to a phy node defining the PHY address (as the reg
+ property, a single integer). Note: if this property isn't present,
+ then fixed link is assumed, and the 'fixed-link' property is
+ mandatory.
+- fixed-link: A 5 elements array that describe a fixed link, see
+ fixed-link.txt for details. Note: if a 'phy' property is present,
+ this 'fixed-link' property is ignored.
+
+Examples:
ethernet@d0070000 {
compatible = "marvell,armada-370-neta";
@@ -21,3 +29,13 @@ ethernet@d0070000 {
phy = <&phy0>;
phy-mode = "rgmii-id";
};
+
+ethernet@d0070000 {
+ compatible = "marvell,armada-370-neta";
+ reg = <0xd0070000 0x2500>;
+ interrupts = <8>;
+ clocks = <&gate_clk 4>;
+ status = "okay";
+ fixed-link = <1 1 1000 0 0>;
+ phy-mode = "rgmii-id";
+};
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2360,8 +2360,12 @@ static int mvneta_mdio_probe(struct mvne
{
struct phy_device *phy_dev;
- phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
- pp->phy_interface);
+ if (pp->phy_node)
+ phy_dev = of_phy_connect(pp->dev, pp->phy_node, mvneta_adjust_link, 0,
+ pp->phy_interface);
+ else
+ phy_dev = of_phy_connect_fixed_link(pp->dev, mvneta_adjust_link,
+ pp->phy_interface);
if (!phy_dev) {
netdev_err(pp->dev, "could not find the PHY\n");
return -ENODEV;
@@ -2719,9 +2723,13 @@ static int mvneta_probe(struct platform_
phy_node = of_parse_phandle(dn, "phy", 0);
if (!phy_node) {
- dev_err(&pdev->dev, "no associated PHY\n");
- err = -ENODEV;
- goto err_free_irq;
+ /* No 'phy' found, see if we have a 'fixed-link'
+ * property */
+ err = of_phy_register_fixed_link(dn);
+ if (err < 0) {
+ dev_err(&pdev->dev, "no 'phy' or 'fixed-link' properties\n");
+ goto err_free_irq;
+ }
}
phy_mode = of_get_phy_mode(dn);

View file

@ -0,0 +1,84 @@
From 409885c9ec1b0dba5c8f393af6d481c69bfa9b0a Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 13 Aug 2013 11:43:12 -0300
Subject: [PATCH 083/203] clocksource: armada-370-xp: Use
CLOCKSOURCE_OF_DECLARE
This is almost cosmetic: we achieve a bit of consistency with
other clocksource drivers by using the CLOCKSOURCE_OF_DECLARE
macro for the boilerplate code.
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>
---
arch/arm/mach-mvebu/armada-370-xp.c | 4 ++--
drivers/clocksource/time-armada-370-xp.c | 6 +++---
include/linux/time-armada-370-xp.h | 18 ------------------
3 files changed, 5 insertions(+), 23 deletions(-)
delete mode 100644 include/linux/time-armada-370-xp.h
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -17,7 +17,7 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/io.h>
-#include <linux/time-armada-370-xp.h>
+#include <linux/clocksource.h>
#include <linux/clk/mvebu.h>
#include <linux/dma-mapping.h>
#include <linux/mbus.h>
@@ -38,7 +38,7 @@ static void __init armada_370_xp_map_io(
static void __init armada_370_xp_timer_and_clk_init(void)
{
mvebu_clocks_init();
- armada_370_xp_timer_init();
+ clocksource_of_init();
coherency_init();
BUG_ON(mvebu_mbus_dt_init());
#ifdef CONFIG_CACHE_L2X0
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -210,13 +210,11 @@ static struct local_timer_ops armada_370
.stop = armada_370_xp_timer_stop,
};
-void __init armada_370_xp_timer_init(void)
+static void __init armada_370_xp_timer_init(struct device_node *np)
{
u32 u;
- struct device_node *np;
int res;
- np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
timer_base = of_iomap(np, 0);
WARN_ON(!timer_base);
local_base = of_iomap(np, 1);
@@ -299,3 +297,5 @@ void __init armada_370_xp_timer_init(voi
#endif
}
}
+CLOCKSOURCE_OF_DECLARE(armada_370_xp, "marvell,armada-370-xp-timer",
+ armada_370_xp_timer_init);
--- a/include/linux/time-armada-370-xp.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Marvell Armada 370/XP SoC timer handling.
- *
- * Copyright (C) 2012 Marvell
- *
- * Lior Amsalem <alior@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- */
-#ifndef __TIME_ARMADA_370_XPPRCMU_H
-#define __TIME_ARMADA_370_XPPRCMU_H
-
-#include <linux/init.h>
-
-void __init armada_370_xp_timer_init(void);
-
-#endif

View file

@ -0,0 +1,33 @@
From 02b0213923da41034a766942508d882f9be51efd Mon Sep 17 00:00:00 2001
From: Jean Pihet <jean.pihet@linaro.org>
Date: Wed, 18 Sep 2013 20:55:09 +0200
Subject: [PATCH 084/203] arm: clocksource: mvebu: Use the main timer as clock
source from DT
This commit:
573145f08c2b92c45498468afbbba909f6ce6135
clocksource: armada-370-xp: Use CLOCKSOURCE_OF_DECLARE
replaced a call to the driver's timer initialization by a call to
clocksource_of_init(). However, it failed to select CONFIG_CLKSRC_OF.
Fix this by selecting CONFIG_CLKSRC_OF for Armada370/XP machines.
Without this change the kernel is stuck at: 'Calibrating delay loop...'.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Acked-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
drivers/clocksource/Kconfig | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -24,6 +24,7 @@ config DW_APB_TIMER_OF
config ARMADA_370_XP_TIMER
bool
+ select CLKSRC_OF
config SUN4I_TIMER
bool

View file

@ -0,0 +1,46 @@
From 60b78d28057f9f1ecce39955755d26e4cd3130de Mon Sep 17 00:00:00 2001
From: Lior Amsalem <alior@marvell.com>
Date: Mon, 25 Nov 2013 17:26:44 +0100
Subject: [PATCH 085/203] irqchip: armada-370-xp: fix IPI race condition
In the Armada 370/XP driver, when we receive an IRQ 0, we read the
list of doorbells that caused the interrupt from register
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of IPIs that
were generated. However, instead of acknowledging only the IPIs that
were generated, we acknowledge *all* the IPIs, by writing
~IPI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register.
This creates a race condition: if a new IPI that isn't part of the
ones read into the temporary "ipimask" variable is fired before we
acknowledge all IPIs, then we will simply loose it. This is causing
scheduling hangs on SMP intensive workloads.
It is important to mention that this ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS
register has the following behavior: "A CPU write of 0 clears the bits
in this field. A CPU write of 1 has no effect". This is what allows us
to simply write ~ipimask to acknoledge the handled IPIs.
Notice that the same problem is present in the MSI implementation, but
it will be fixed as a separate patch, so that this IPI fix can be
pushed to older stable versions as appropriate (all the way to 3.8),
while the MSI code only appeared in 3.13.
Signed-off-by: Lior Amsalem <alior@marvell.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: stable@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-armada-370-xp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -407,7 +407,7 @@ armada_370_xp_handle_irq(struct pt_regs
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
& IPI_DOORBELL_MASK;
- writel(~IPI_DOORBELL_MASK, per_cpu_int_base +
+ writel(~ipimask, per_cpu_int_base +
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
/* Handle all pending doorbells */

View file

@ -0,0 +1,44 @@
From ddda6fa410b6e50ee67d4a628187e76b4a6c9b28 Mon Sep 17 00:00:00 2001
From: Lior Amsalem <alior@marvell.com>
Date: Mon, 25 Nov 2013 17:26:45 +0100
Subject: [PATCH 086/203] irqchip: armada-370-xp: fix MSI race condition
In the Armada 370/XP driver, when we receive an IRQ 1, we read the
list of doorbells that caused the interrupt from register
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of MSIs that
were generated. However, instead of acknowledging only the MSIs that
were generated, we acknowledge *all* the MSIs, by writing
~MSI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register.
This creates a race condition: if a new MSI that isn't part of the
ones read into the temporary "msimask" variable is fired before we
acknowledge all MSIs, then we will simply loose it.
It is important to mention that this ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS
register has the following behavior: "A CPU write of 0 clears the bits
in this field. A CPU write of 1 has no effect". This is what allows us
to simply write ~msimask to acknoledge the handled MSIs.
Notice that the same problem is present in the IPI implementation, but
it is fixed as a separate patch, so that this IPI fix can be pushed to
older stable versions as appropriate (all the way to 3.8), while the
MSI code only appeared in 3.13.
Signed-off-by: Lior Amsalem <alior@marvell.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-armada-370-xp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -381,7 +381,7 @@ armada_370_xp_handle_irq(struct pt_regs
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
& PCI_MSI_DOORBELL_MASK;
- writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base +
+ writel(~msimask, per_cpu_int_base +
ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
for (msinr = PCI_MSI_DOORBELL_START;

View file

@ -0,0 +1,60 @@
From 98e6b600e81f71f8621e316f5d46cf261a9f1da4 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Mon, 25 Nov 2013 17:26:47 +0100
Subject: [PATCH 088/203] ARM: mvebu: re-enable PCIe on Armada 370 DB
Commit 14fd8ed0a7fd19913 ("ARM: mvebu: Relocate Armada 370/XP PCIe
device tree nodes") relocated the PCIe controller DT nodes one level
up in the Device Tree, to reflect a more correct representation of the
hardware introduced by the mvebu-mbus Device Tree binding.
However, while most of the boards were properly adjusted accordingly,
the Armada 370 DB board was left unchanged, and therefore, PCIe is
seen as not enabled on this board. This patch fixes that by moving the
PCIe controller node one level-up in armada-370-db.dts.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: stable@vger.kernel.org
---
arch/arm/boot/dts/armada-370-db.dts | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -99,22 +99,22 @@
spi-max-frequency = <50000000>;
};
};
+ };
- pcie-controller {
+ pcie-controller {
+ status = "okay";
+ /*
+ * The two PCIe units are accessible through
+ * both standard PCIe slots and mini-PCIe
+ * slots on the board.
+ */
+ pcie@1,0 {
+ /* Port 0, Lane 0 */
+ status = "okay";
+ };
+ pcie@2,0 {
+ /* Port 1, Lane 0 */
status = "okay";
- /*
- * The two PCIe units are accessible through
- * both standard PCIe slots and mini-PCIe
- * slots on the board.
- */
- pcie@1,0 {
- /* Port 0, Lane 0 */
- status = "okay";
- };
- pcie@2,0 {
- /* Port 1, Lane 0 */
- status = "okay";
- };
};
};
};

View file

@ -0,0 +1,43 @@
From 67f66e13d8a6da710d6df965021d92261083b584 Mon Sep 17 00:00:00 2001
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Date: Wed, 25 Sep 2013 13:24:18 +0200
Subject: [PATCH 089/203] ARM: mvebu: fix gated clock documentation
The gated clock documentation referred only to the Orion SoC whereas
it also applied for the Armada 370/XP SoC. This commit updates the
introduction text and also the list of the compatible strings.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
.../devicetree/bindings/clock/mvebu-gated-clock.txt | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
+++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
@@ -1,10 +1,10 @@
-* Gated Clock bindings for Marvell Orion SoCs
+* Gated Clock bindings for Marvell EBU SoCs
-Marvell Dove and Kirkwood allow some peripheral clocks to be gated to save
-some power. The clock consumer should specify the desired clock by having
-the clock ID in its "clocks" phandle cell. The clock ID is directly mapped to
-the corresponding clock gating control bit in HW to ease manual clock lookup
-in datasheet.
+Marvell Armada 370/XP, Dove and Kirkwood allow some peripheral clocks to be
+gated to save some power. The clock consumer should specify the desired clock
+by having the clock ID in its "clocks" phandle cell. The clock ID is directly
+mapped to the corresponding clock gating control bit in HW to ease manual clock
+lookup in datasheet.
The following is a list of provided IDs for Armada 370:
ID Clock Peripheral
@@ -94,6 +94,8 @@ ID Clock Peripheral
Required properties:
- compatible : shall be one of the following:
+ "marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating
+ "marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating
"marvell,dove-gating-clock" - for Dove SoC clock gating
"marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating
- reg : shall be the register address of the Clock Gating Control register

View file

@ -0,0 +1,64 @@
From 4aa571afd29f88898ef2fb954effcf53fec3264e Mon Sep 17 00:00:00 2001
From: Huang Shijie <b32955@freescale.com>
Date: Fri, 17 May 2013 11:17:25 +0800
Subject: [PATCH 090/203] mtd: add datasheet's ECC information to nand_chip{}
1.) Why add the ECC information to the nand_chip{} ?
Each nand chip has its requirement for the ECC correctability, such as
"4bit ECC for each 512Byte" or "40bit ECC for each 1024Byte".
This ECC info is very important to the nand controller, such as gpmi.
Take the Micron MT29F64G08CBABA for example, its geometry is
8KiB page size, 744 bytes oob size and it requires 40bit ECC per 1KiB.
If we do not provide the ECC info to the gpmi nand driver, it has to
calculate the ECC correctability itself. The gpmi driver will gets the 56bit
ECC for per 1KiB which is beyond its BCH's 40bit ecc capibility.
The gpmi will quits in this case. But in actually, the gpmi can supports
this nand chip if it can get the right ECC info.
2.) about the new fields.
The @ecc_strength_ds stands for the ecc bits needed within the @ecc_step_ds.
The two fields should be set from the nand chip's datasheets.
For example:
"4bit ECC for each 512Byte" could be:
@ecc_strength_ds = 4, @ecc_step_ds = 512.
"40bit ECC for each 1024Byte" could be:
@ecc_strength_ds = 40, @ecc_step_ds = 1024.
3.) Why do not re-use the @strength and @size in the nand_ecc_ctrl{}?
The @strength and @size in nand_ecc_ctrl{} is used by the nand controller
driver, while the @ecc_strength_ds and @ecc_step_ds are get from the datasheet.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Reviewed-and-tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
include/linux/mtd/nand.h | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -434,6 +434,12 @@ struct nand_buffers {
* bad block marker position; i.e., BBM == 11110111b is
* not bad when badblockbits == 7
* @cellinfo: [INTERN] MLC/multichip data from chip ident
+ * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet.
+ * Minimum amount of bit errors per @ecc_step_ds guaranteed
+ * to be correctable. If unknown, set to zero.
+ * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds,
+ * also from the datasheet. It is the recommended ECC step
+ * size, if known; if unknown, set to zero.
* @numchips: [INTERN] number of physical chips
* @chipsize: [INTERN] the size of one chip for multichip arrays
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
@@ -510,6 +516,8 @@ struct nand_chip {
unsigned int pagebuf_bitflips;
int subpagesize;
uint8_t cellinfo;
+ uint16_t ecc_strength_ds;
+ uint16_t ecc_step_ds;
int badblockpos;
int badblockbits;

View file

@ -0,0 +1,85 @@
From 50a7db84f71e7c4779596fb5f8efb579a5d29f97 Mon Sep 17 00:00:00 2001
From: Huang Shijie <b32955@freescale.com>
Date: Fri, 17 May 2013 11:17:27 +0800
Subject: [PATCH 091/203] mtd: add data structures for Extended Parameter Page
Since the ONFI 2.1, the onfi spec adds the Extended Parameter Page
to store the ECC info.
The onfi spec tells us that if the nand chip's recommended ECC codeword
size is not 512 bytes, then the @ecc_bits is 0xff. The host _SHOULD_ then
read the Extended ECC information that is part of the extended parameter
page to retrieve the ECC requirements for this device.
This patch adds
[1] the neccessary fields for nand_onfi_params{},
[2] and adds the onfi_ext_ecc_info{} for Extended ECC information,
[3] adds onfi_ext_section{} for extended sections,
[4] and adds onfi_ext_param_page{} for the Extended Parameter Page.
Acked-by: Pekon Gupta <pekon@ti.com>
Signed-off-by: Huang Shijie <b32955@freescale.com>
Reviewed-and-tested-by: Brian Norris <computersforpeace@gmail.com>
[Brian: amended for checkpatch.pl]
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
include/linux/mtd/nand.h | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -224,7 +224,10 @@ struct nand_onfi_params {
__le16 revision;
__le16 features;
__le16 opt_cmd;
- u8 reserved[22];
+ u8 reserved0[2];
+ __le16 ext_param_page_length; /* since ONFI 2.1 */
+ u8 num_of_param_pages; /* since ONFI 2.1 */
+ u8 reserved1[17];
/* manufacturer information block */
char manufacturer[12];
@@ -281,6 +284,40 @@ struct nand_onfi_params {
#define ONFI_CRC_BASE 0x4F4E
+/* Extended ECC information Block Definition (since ONFI 2.1) */
+struct onfi_ext_ecc_info {
+ u8 ecc_bits;
+ u8 codeword_size;
+ __le16 bb_per_lun;
+ __le16 block_endurance;
+ u8 reserved[2];
+} __packed;
+
+#define ONFI_SECTION_TYPE_0 0 /* Unused section. */
+#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */
+#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */
+struct onfi_ext_section {
+ u8 type;
+ u8 length;
+} __packed;
+
+#define ONFI_EXT_SECTION_MAX 8
+
+/* Extended Parameter Page Definition (since ONFI 2.1) */
+struct onfi_ext_param_page {
+ __le16 crc;
+ u8 sig[4]; /* 'E' 'P' 'P' 'S' */
+ u8 reserved0[10];
+ struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX];
+
+ /*
+ * The actual size of the Extended Parameter Page is in
+ * @ext_param_page_length of nand_onfi_params{}.
+ * The following are the variable length sections.
+ * So we do not add any fields below. Please see the ONFI spec.
+ */
+} __packed;
+
/**
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
* @lock: protection lock

View file

@ -0,0 +1,43 @@
From aeeb6ea6eb18c46f5776dd068989686686cda359 Mon Sep 17 00:00:00 2001
From: Huang Shijie <shijie8@gmail.com>
Date: Fri, 17 May 2013 11:17:28 +0800
Subject: [PATCH 092/203] mtd: add a helper to get the supported features for
ONFI nand
add a helper to get the supported features for ONFI nand.
Also add the neccessary macros.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Reviewed-and-tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
include/linux/mtd/nand.h | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -202,6 +202,10 @@ typedef enum {
/* Keep gcc happy */
struct nand_chip;
+/* ONFI features */
+#define ONFI_FEATURE_16_BIT_BUS (1 << 0)
+#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7)
+
/* ONFI timing mode, used in both asynchronous and synchronous mode */
#define ONFI_TIMING_MODE_0 (1 << 0)
#define ONFI_TIMING_MODE_1 (1 << 1)
@@ -754,6 +758,12 @@ struct platform_nand_chip *get_platform_
return chip->priv;
}
+/* return the supported features. */
+static inline int onfi_feature(struct nand_chip *chip)
+{
+ return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0;
+}
+
/* return the supported asynchronous timing mode. */
static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
{

View file

@ -0,0 +1,31 @@
From ceef2075f3aa430da137e3629b0280a46d420ccd Mon Sep 17 00:00:00 2001
From: Huang Shijie <b32955@freescale.com>
Date: Fri, 17 May 2013 11:17:26 +0800
Subject: [PATCH 093/203] mtd: get the ECC info from the parameter page for
ONFI nand
From the ONFI spec, we can just get the ECC info from the @ecc_bits field of
the parameter page.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Reviewed-and-tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/nand_base.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2924,6 +2924,11 @@ static int nand_flash_detect_onfi(struct
if (le16_to_cpu(p->features) & 1)
*busw = NAND_BUSWIDTH_16;
+ if (p->ecc_bits != 0xff) {
+ chip->ecc_strength_ds = p->ecc_bits;
+ chip->ecc_step_ds = 512;
+ }
+
pr_info("ONFI flash detected\n");
return 1;
}

View file

@ -0,0 +1,131 @@
From f617846b1e20a2ba59cdd9435715339eaed1e251 Mon Sep 17 00:00:00 2001
From: Huang Shijie <b32955@freescale.com>
Date: Wed, 22 May 2013 10:28:27 +0800
Subject: [PATCH 094/203] mtd: get the ECC info from the Extended Parameter
Page
Since the ONFI 2.1, the onfi spec adds the Extended Parameter Page
to store the ECC info.
The onfi spec tells us that if the nand chip's recommended ECC codeword
size is not 512 bytes, then the @ecc_bits is 0xff. The host _SHOULD_ then
read the Extended ECC information that is part of the extended parameter
page to retrieve the ECC requirements for this device.
This patch implement the reading of the Extended Parameter Page, and parses
the sections for ECC type, and get the ECC info from the ECC section.
Tested this patch with Micron MT29F64G08CBABAWP.
Acked-by: Pekon Gupta <pekon@ti.com>
Signed-off-by: Huang Shijie <b32955@freescale.com>
Reviewed-and-tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/nand_base.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2848,6 +2848,78 @@ static u16 onfi_crc16(u16 crc, u8 const
return crc;
}
+/* Parse the Extended Parameter Page. */
+static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
+ struct nand_chip *chip, struct nand_onfi_params *p)
+{
+ struct onfi_ext_param_page *ep;
+ struct onfi_ext_section *s;
+ struct onfi_ext_ecc_info *ecc;
+ uint8_t *cursor;
+ int ret = -EINVAL;
+ int len;
+ int i;
+
+ len = le16_to_cpu(p->ext_param_page_length) * 16;
+ ep = kmalloc(len, GFP_KERNEL);
+ if (!ep) {
+ ret = -ENOMEM;
+ goto ext_out;
+ }
+
+ /* Send our own NAND_CMD_PARAM. */
+ chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
+
+ /* Use the Change Read Column command to skip the ONFI param pages. */
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
+ sizeof(*p) * p->num_of_param_pages , -1);
+
+ /* Read out the Extended Parameter Page. */
+ chip->read_buf(mtd, (uint8_t *)ep, len);
+ if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2)
+ != le16_to_cpu(ep->crc))) {
+ pr_debug("fail in the CRC.\n");
+ goto ext_out;
+ }
+
+ /*
+ * Check the signature.
+ * Do not strictly follow the ONFI spec, maybe changed in future.
+ */
+ if (strncmp(ep->sig, "EPPS", 4)) {
+ pr_debug("The signature is invalid.\n");
+ goto ext_out;
+ }
+
+ /* find the ECC section. */
+ cursor = (uint8_t *)(ep + 1);
+ for (i = 0; i < ONFI_EXT_SECTION_MAX; i++) {
+ s = ep->sections + i;
+ if (s->type == ONFI_SECTION_TYPE_2)
+ break;
+ cursor += s->length * 16;
+ }
+ if (i == ONFI_EXT_SECTION_MAX) {
+ pr_debug("We can not find the ECC section.\n");
+ goto ext_out;
+ }
+
+ /* get the info we want. */
+ ecc = (struct onfi_ext_ecc_info *)cursor;
+
+ if (ecc->codeword_size) {
+ chip->ecc_strength_ds = ecc->ecc_bits;
+ chip->ecc_step_ds = 1 << ecc->codeword_size;
+ }
+
+ pr_info("ONFI extended param page detected.\n");
+ return 0;
+
+ext_out:
+ kfree(ep);
+ return ret;
+}
+
/*
* Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise.
*/
@@ -2927,6 +2999,21 @@ static int nand_flash_detect_onfi(struct
if (p->ecc_bits != 0xff) {
chip->ecc_strength_ds = p->ecc_bits;
chip->ecc_step_ds = 512;
+ } else if (chip->onfi_version >= 21 &&
+ (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
+
+ /*
+ * The nand_flash_detect_ext_param_page() uses the
+ * Change Read Column command which maybe not supported
+ * by the chip->cmdfunc. So try to update the chip->cmdfunc
+ * now. We do not replace user supplied command function.
+ */
+ if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
+ chip->cmdfunc = nand_command_lp;
+
+ /* The Extended Parameter Page is supported since ONFI 2.1. */
+ if (nand_flash_detect_ext_param_page(mtd, chip, p))
+ pr_info("Failed to detect the extended param page.\n");
}
pr_info("ONFI flash detected\n");

View file

@ -0,0 +1,51 @@
From 5d15281ca712cb873835e301937f3a8342e88d4b Mon Sep 17 00:00:00 2001
From: Brian Norris <computersforpeace@gmail.com>
Date: Mon, 16 Sep 2013 17:59:20 -0700
Subject: [PATCH 095/203] mtd: nand: fix memory leak in ONFI extended parameter
page
This fixes a memory leak in the ONFI support code for detecting the
required ECC levels from this commit:
commit 6dcbe0cdd83fb5f77be4f44c9e06c535281c375a
Author: Huang Shijie <b32955@freescale.com>
Date: Wed May 22 10:28:27 2013 +0800
mtd: get the ECC info from the Extended Parameter Page
In the success case, we never freed the 'ep' buffer.
Also, this fixes an oversight in the same commit where we (harmlessly)
freed the NULL pointer.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Acked-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/nand_base.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2862,10 +2862,8 @@ static int nand_flash_detect_ext_param_p
len = le16_to_cpu(p->ext_param_page_length) * 16;
ep = kmalloc(len, GFP_KERNEL);
- if (!ep) {
- ret = -ENOMEM;
- goto ext_out;
- }
+ if (!ep)
+ return -ENOMEM;
/* Send our own NAND_CMD_PARAM. */
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
@@ -2913,7 +2911,7 @@ static int nand_flash_detect_ext_param_p
}
pr_info("ONFI extended param page detected.\n");
- return 0;
+ ret = 0;
ext_out:
kfree(ep);

View file

@ -0,0 +1,273 @@
From ac8294dfb4085f3193bec27673062e5ad63d770a Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Thu, 26 Sep 2013 16:35:27 -0300
Subject: [PATCH 096/203] clk: mvebu: Add Core Divider clock
This commit introduces a new group of clocks present in Armada 370/XP
SoCs (called "Core Divider" clocks) and add a provider for them.
The only clock supported for now is the NAND clock (ndclk), but the
infrastructure to add the rest is already set.
Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
---
arch/arm/mach-mvebu/Kconfig | 1 +
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/clk-corediv.c | 223 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 228 insertions(+)
create mode 100644 drivers/clk/mvebu/clk-corediv.c
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -13,6 +13,7 @@ config ARCH_MVEBU
select MVEBU_CLK_CORE
select MVEBU_CLK_CPU
select MVEBU_CLK_GATING
+ select MVEBU_CLK_COREDIV
select MVEBU_MBUS
select ZONE_DMA if ARM_LPAE
select ARCH_REQUIRE_GPIOLIB
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -6,3 +6,6 @@ config MVEBU_CLK_CPU
config MVEBU_CLK_GATING
bool
+
+config MVEBU_CLK_COREDIV
+ bool
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_MVEBU_CLK_CORE) += clk.o clk-core.o
obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
obj-$(CONFIG_MVEBU_CLK_GATING) += clk-gating-ctrl.o
+obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o
--- /dev/null
+++ b/drivers/clk/mvebu/clk-corediv.c
@@ -0,0 +1,223 @@
+/*
+ * MVEBU Core divider clock
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define CORE_CLK_DIV_RATIO_MASK 0xff
+#define CORE_CLK_DIV_RATIO_RELOAD BIT(8)
+#define CORE_CLK_DIV_ENABLE_OFFSET 24
+#define CORE_CLK_DIV_RATIO_OFFSET 0x8
+
+struct clk_corediv_desc {
+ unsigned int mask;
+ unsigned int offset;
+ unsigned int fieldbit;
+};
+
+struct clk_corediv {
+ struct clk_hw hw;
+ void __iomem *reg;
+ struct clk_corediv_desc desc;
+ spinlock_t lock;
+};
+
+static struct clk_onecell_data clk_data;
+
+static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
+ { .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
+};
+
+#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
+
+static int clk_corediv_is_enabled(struct clk_hw *hwclk)
+{
+ struct clk_corediv *corediv = to_corediv_clk(hwclk);
+ struct clk_corediv_desc *desc = &corediv->desc;
+ u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
+
+ return !!(readl(corediv->reg) & enable_mask);
+}
+
+static int clk_corediv_enable(struct clk_hw *hwclk)
+{
+ struct clk_corediv *corediv = to_corediv_clk(hwclk);
+ struct clk_corediv_desc *desc = &corediv->desc;
+ unsigned long flags = 0;
+ u32 reg;
+
+ spin_lock_irqsave(&corediv->lock, flags);
+
+ reg = readl(corediv->reg);
+ reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+ writel(reg, corediv->reg);
+
+ spin_unlock_irqrestore(&corediv->lock, flags);
+
+ return 0;
+}
+
+static void clk_corediv_disable(struct clk_hw *hwclk)
+{
+ struct clk_corediv *corediv = to_corediv_clk(hwclk);
+ struct clk_corediv_desc *desc = &corediv->desc;
+ unsigned long flags = 0;
+ u32 reg;
+
+ spin_lock_irqsave(&corediv->lock, flags);
+
+ reg = readl(corediv->reg);
+ reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+ writel(reg, corediv->reg);
+
+ spin_unlock_irqrestore(&corediv->lock, flags);
+}
+
+static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct clk_corediv *corediv = to_corediv_clk(hwclk);
+ struct clk_corediv_desc *desc = &corediv->desc;
+ u32 reg, div;
+
+ reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+ div = (reg >> desc->offset) & desc->mask;
+ return parent_rate / div;
+}
+
+static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
+ u32 div;
+
+ div = *parent_rate / rate;
+ if (div < 4)
+ div = 4;
+ else if (div > 6)
+ div = 8;
+
+ return *parent_rate / div;
+}
+
+static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_corediv *corediv = to_corediv_clk(hwclk);
+ struct clk_corediv_desc *desc = &corediv->desc;
+ unsigned long flags = 0;
+ u32 reg, div;
+
+ div = parent_rate / rate;
+
+ spin_lock_irqsave(&corediv->lock, flags);
+
+ /* Write new divider to the divider ratio register */
+ reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+ reg &= ~(desc->mask << desc->offset);
+ reg |= (div & desc->mask) << desc->offset;
+ writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+
+ /* Set reload-force for this clock */
+ reg = readl(corediv->reg) | BIT(desc->fieldbit);
+ writel(reg, corediv->reg);
+
+ /* Now trigger the clock update */
+ reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
+ writel(reg, corediv->reg);
+
+ /*
+ * Wait for clocks to settle down, and then clear all the
+ * ratios request and the reload request.
+ */
+ udelay(1000);
+ reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
+ writel(reg, corediv->reg);
+ udelay(1000);
+
+ spin_unlock_irqrestore(&corediv->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops corediv_ops = {
+ .enable = clk_corediv_enable,
+ .disable = clk_corediv_disable,
+ .is_enabled = clk_corediv_is_enabled,
+ .recalc_rate = clk_corediv_recalc_rate,
+ .round_rate = clk_corediv_round_rate,
+ .set_rate = clk_corediv_set_rate,
+};
+
+static void __init mvebu_corediv_clk_init(struct device_node *node)
+{
+ struct clk_init_data init;
+ struct clk_corediv *corediv;
+ struct clk **clks;
+ void __iomem *base;
+ const char *parent_name;
+ const char *clk_name;
+ int i;
+
+ base = of_iomap(node, 0);
+ if (WARN_ON(!base))
+ return;
+
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
+
+ /* clks holds the clock array */
+ clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
+ GFP_KERNEL);
+ if (WARN_ON(!clks))
+ goto err_unmap;
+ /* corediv holds the clock specific array */
+ corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
+ GFP_KERNEL);
+ if (WARN_ON(!corediv))
+ goto err_free_clks;
+
+ spin_lock_init(&corediv->lock);
+
+ for (i = 0; i < clk_data.clk_num; i++) {
+ of_property_read_string_index(node, "clock-output-names",
+ i, &clk_name);
+ init.num_parents = 1;
+ init.parent_names = &parent_name;
+ init.name = clk_name;
+ init.ops = &corediv_ops;
+ init.flags = 0;
+
+ corediv[i].desc = mvebu_corediv_desc[i];
+ corediv[i].reg = base;
+ corediv[i].hw.init = &init;
+
+ clks[i] = clk_register(NULL, &corediv[i].hw);
+ WARN_ON(IS_ERR(clks[i]));
+ }
+
+ clk_data.clks = clks;
+ of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+ return;
+
+err_free_clks:
+ kfree(clks);
+err_unmap:
+ iounmap(base);
+}
+CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
+ mvebu_corediv_clk_init);

View file

@ -0,0 +1,32 @@
From 455ad812cb2ec97339f780e2a79169620f1e7485 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Fri, 18 Oct 2013 20:02:30 -0300
Subject: [PATCH 097/203] ARM: mvebu: Add a 2 GHz fixed-clock Armada 370/XP
Armada 370/XP SoCs have a 2 GHz fixed PLL that is used to feed
other clocks. This commit adds a DT representation of this clock
through a fixed-clock compatible node.
Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
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 | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -251,4 +251,13 @@
};
};
+
+ clocks {
+ /* 2 GHz fixed main PLL */
+ mainpll: mainpll {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <2000000000>;
+ };
+ };
};

View file

@ -0,0 +1,33 @@
From 408b807592d9cdbc1a69b119f4a862b2ab1e4d87 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Fri, 18 Oct 2013 20:02:31 -0300
Subject: [PATCH 098/203] ARM: mvebu: Add the core-divider clock to Armada
370/XP
The Armada 370/XP SoC has a clock provider called "Core Divider",
that is derived from a fixed 2 GHz PLL clock.
Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
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 | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -134,6 +134,14 @@
status = "disabled";
};
+ coredivclk: corediv-clock@18740 {
+ compatible = "marvell,armada-370-corediv-clock";
+ reg = <0x18740 0xc>;
+ #clock-cells = <1>;
+ clocks = <&mainpll>;
+ clock-output-names = "nand";
+ };
+
timer@20300 {
compatible = "marvell,armada-370-xp-timer";
reg = <0x20300 0x30>, <0x21040 0x30>;

View file

@ -0,0 +1,34 @@
From 64356fe97302ad842d9871a5a4411d8b41127f59 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Thu, 7 Nov 2013 12:17:33 -0300
Subject: [PATCH 099/203] ARM: mvebu: Add support for NAND controller in Armada
370/XP
The Armada 370 and Armada XP SoC have a NAND controller (aka NFCv2).
This commit adds support for it in Armada 370 and Armada XP SoC
common devicetree.
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 | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -257,6 +257,15 @@
status = "disabled";
};
+ nand@d0000 {
+ compatible = "marvell,armada370-nand";
+ reg = <0xd0000 0x54>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupts = <113>;
+ clocks = <&coredivclk 0>;
+ status = "disabled";
+ };
};
};

View file

@ -0,0 +1,36 @@
From 9226a0bb330bb83df9a465ba418efd3277cd00d3 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Thu, 7 Nov 2013 12:17:34 -0300
Subject: [PATCH 100/203] ARM: mvebu: Enable NAND controller in Armada XP GP
board
The Armada XP GP board has a NAND flash, so enable it in the devicetree.
In order to skip the driver's custom device detection and use only ONFI
detection, the "marvell,keep-config" parameter is used.
This is needed because we haven't support for setting the timings
parameters yet and must rely in bootloader's.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
arch/arm/boot/dts/armada-xp-gp.dts | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -175,6 +175,14 @@
spi-max-frequency = <108000000>;
};
};
+
+ nand@d0000 {
+ status = "okay";
+ num-cs = <1>;
+ marvell,nand-keep-config;
+ marvell,nand-enable-arbiter;
+ nand-on-flash-bbt;
+ };
};
};
};

View file

@ -0,0 +1,60 @@
From 271ef48cf11b86ab666582051fed3bdb13681e64 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:09 -0300
Subject: [PATCH 101/203] mtd: nand: pxa3xx: Use devm_kzalloc
Replace regular kzalloc with managed devm_kzalloc
which simplifies the error path.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1035,12 +1035,10 @@ static int alloc_nand_resource(struct pl
int ret, irq, cs;
pdata = pdev->dev.platform_data;
- info = kzalloc(sizeof(*info) + (sizeof(*mtd) +
- sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
+ sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
+ if (!info)
return -ENOMEM;
- }
info->pdev = pdev;
for (cs = 0; cs < pdata->num_cs; cs++) {
@@ -1072,8 +1070,7 @@ static int alloc_nand_resource(struct pl
info->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed to get nand clock\n");
- ret = PTR_ERR(info->clk);
- goto fail_free_mtd;
+ return PTR_ERR(info->clk);
}
clk_enable(info->clk);
@@ -1165,8 +1162,6 @@ fail_free_res:
fail_put_clk:
clk_disable(info->clk);
clk_put(info->clk);
-fail_free_mtd:
- kfree(info);
return ret;
}
@@ -1202,7 +1197,6 @@ static int pxa3xx_nand_remove(struct pla
for (cs = 0; cs < pdata->num_cs; cs++)
nand_release(info->host[cs]->mtd);
- kfree(info);
return 0;
}

View file

@ -0,0 +1,82 @@
From 5c461327aca8975276d2480ddf02b6c7f0a29548 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:10 -0300
Subject: [PATCH 102/203] mtd: nand: pxa3xx: Use devm_ioremap_resource
Using the new devm_ioremap_resource() we can greatly
simplify resource handling.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 31 ++++---------------------------
1 file changed, 4 insertions(+), 27 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1108,30 +1108,16 @@ static int alloc_nand_resource(struct pl
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no IO memory resource defined\n");
- ret = -ENODEV;
+ info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(info->mmio_base)) {
+ ret = PTR_ERR(info->mmio_base);
goto fail_put_clk;
}
-
- r = request_mem_region(r->start, resource_size(r), pdev->name);
- if (r == NULL) {
- dev_err(&pdev->dev, "failed to request memory resource\n");
- ret = -EBUSY;
- goto fail_put_clk;
- }
-
- info->mmio_base = ioremap(r->start, resource_size(r));
- if (info->mmio_base == NULL) {
- dev_err(&pdev->dev, "ioremap() failed\n");
- ret = -ENODEV;
- goto fail_free_res;
- }
info->mmio_phys = r->start;
ret = pxa3xx_nand_init_buff(info);
if (ret)
- goto fail_free_io;
+ goto fail_put_clk;
/* initialize all interrupts to be disabled */
disable_int(info, NDSR_MASK);
@@ -1155,10 +1141,6 @@ fail_free_buf:
info->data_buff, info->data_buff_phys);
} else
kfree(info->data_buff);
-fail_free_io:
- iounmap(info->mmio_base);
-fail_free_res:
- release_mem_region(r->start, resource_size(r));
fail_put_clk:
clk_disable(info->clk);
clk_put(info->clk);
@@ -1169,7 +1151,6 @@ static int pxa3xx_nand_remove(struct pla
{
struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
struct pxa3xx_nand_platform_data *pdata;
- struct resource *r;
int irq, cs;
if (!info)
@@ -1188,10 +1169,6 @@ static int pxa3xx_nand_remove(struct pla
} else
kfree(info->data_buff);
- iounmap(info->mmio_base);
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, resource_size(r));
-
clk_disable(info->clk);
clk_put(info->clk);

View file

@ -0,0 +1,87 @@
From 4ff9eea8b6841bb8be7becba9713a0ce7c82da9d Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:11 -0300
Subject: [PATCH 103/203] mtd: nand: pxa3xx: Use devm_clk_get
Replacing clk_get by managed devm_clk_get, the error path
can be greatly simplified.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1067,7 +1067,7 @@ static int alloc_nand_resource(struct pl
spin_lock_init(&chip->controller->lock);
init_waitqueue_head(&chip->controller->wq);
- info->clk = clk_get(&pdev->dev, NULL);
+ info->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
dev_err(&pdev->dev, "failed to get nand clock\n");
return PTR_ERR(info->clk);
@@ -1087,7 +1087,7 @@ static int alloc_nand_resource(struct pl
if (r == NULL) {
dev_err(&pdev->dev, "no resource defined for data DMA\n");
ret = -ENXIO;
- goto fail_put_clk;
+ goto fail_disable_clk;
}
info->drcmr_dat = r->start;
@@ -1095,7 +1095,7 @@ static int alloc_nand_resource(struct pl
if (r == NULL) {
dev_err(&pdev->dev, "no resource defined for command DMA\n");
ret = -ENXIO;
- goto fail_put_clk;
+ goto fail_disable_clk;
}
info->drcmr_cmd = r->start;
}
@@ -1104,20 +1104,20 @@ static int alloc_nand_resource(struct pl
if (irq < 0) {
dev_err(&pdev->dev, "no IRQ resource defined\n");
ret = -ENXIO;
- goto fail_put_clk;
+ goto fail_disable_clk;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->mmio_base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(info->mmio_base)) {
ret = PTR_ERR(info->mmio_base);
- goto fail_put_clk;
+ goto fail_disable_clk;
}
info->mmio_phys = r->start;
ret = pxa3xx_nand_init_buff(info);
if (ret)
- goto fail_put_clk;
+ goto fail_disable_clk;
/* initialize all interrupts to be disabled */
disable_int(info, NDSR_MASK);
@@ -1141,9 +1141,8 @@ fail_free_buf:
info->data_buff, info->data_buff_phys);
} else
kfree(info->data_buff);
-fail_put_clk:
+fail_disable_clk:
clk_disable(info->clk);
- clk_put(info->clk);
return ret;
}
@@ -1170,7 +1169,6 @@ static int pxa3xx_nand_remove(struct pla
kfree(info->data_buff);
clk_disable(info->clk);
- clk_put(info->clk);
for (cs = 0; cs < pdata->num_cs; cs++)
nand_release(info->host[cs]->mtd);

View file

@ -0,0 +1,45 @@
From e9274ba8dd0c93f12c0fd5896e11f754aa700baf Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:12 -0300
Subject: [PATCH 104/203] mtd: nand: pxa3xx: Use clk_prepare_enable and
clk_disable_unprepare
This patch converts the module to use clk_prepare_enable and
clk_disable_unprepare variants as required by common clock framework.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1072,7 +1072,7 @@ static int alloc_nand_resource(struct pl
dev_err(&pdev->dev, "failed to get nand clock\n");
return PTR_ERR(info->clk);
}
- clk_enable(info->clk);
+ clk_prepare_enable(info->clk);
/*
* This is a dirty hack to make this driver work from devicetree
@@ -1142,7 +1142,7 @@ fail_free_buf:
} else
kfree(info->data_buff);
fail_disable_clk:
- clk_disable(info->clk);
+ clk_disable_unprepare(info->clk);
return ret;
}
@@ -1168,7 +1168,7 @@ static int pxa3xx_nand_remove(struct pla
} else
kfree(info->data_buff);
- clk_disable(info->clk);
+ clk_disable_unprepare(info->clk);
for (cs = 0; cs < pdata->num_cs; cs++)
nand_release(info->host[cs]->mtd);

View file

@ -0,0 +1,29 @@
From 7e8fbc673938278ec7165b99b76227d7cc2ab012 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:13 -0300
Subject: [PATCH 105/203] mtd: nand: pxa3xx: Check for clk_prepare_enable()
return value
clk_prepare_enable() can fail due to unknown reason.
Add a check for this and return the error code if it fails.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.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
@@ -1072,7 +1072,9 @@ static int alloc_nand_resource(struct pl
dev_err(&pdev->dev, "failed to get nand clock\n");
return PTR_ERR(info->clk);
}
- clk_prepare_enable(info->clk);
+ ret = clk_prepare_enable(info->clk);
+ if (ret < 0)
+ return ret;
/*
* This is a dirty hack to make this driver work from devicetree

View file

@ -0,0 +1,66 @@
From 49ff5bd7d4d51a8eb05796f130e9a1a96d18f522 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Wed, 17 Apr 2013 13:38:14 -0300
Subject: [PATCH 106/203] mtd: nand: pxa3xx: Move buffer release code to its
own function
Create a function to release the buffer and the dma channel, thus undoing
what pxa3xx_nand_init_buff() did. This commit makes the code more readable
and will allow to handle non-DMA capable platforms easier.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -912,6 +912,18 @@ static int pxa3xx_nand_init_buff(struct
return 0;
}
+static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
+{
+ struct platform_device *pdev = info->pdev;
+ if (use_dma) {
+ pxa_free_dma(info->data_dma_ch);
+ dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
+ info->data_buff, info->data_buff_phys);
+ } else {
+ kfree(info->data_buff);
+ }
+}
+
static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
{
struct mtd_info *mtd;
@@ -1137,12 +1149,7 @@ static int alloc_nand_resource(struct pl
fail_free_buf:
free_irq(irq, info);
- if (use_dma) {
- pxa_free_dma(info->data_dma_ch);
- dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
- info->data_buff, info->data_buff_phys);
- } else
- kfree(info->data_buff);
+ pxa3xx_nand_free_buff(info);
fail_disable_clk:
clk_disable_unprepare(info->clk);
return ret;
@@ -1163,12 +1170,7 @@ static int pxa3xx_nand_remove(struct pla
irq = platform_get_irq(pdev, 0);
if (irq >= 0)
free_irq(irq, info);
- if (use_dma) {
- pxa_free_dma(info->data_dma_ch);
- dma_free_writecombine(&pdev->dev, MAX_BUFF_SIZE,
- info->data_buff, info->data_buff_phys);
- } else
- kfree(info->data_buff);
+ pxa3xx_nand_free_buff(info);
clk_disable_unprepare(info->clk);

View file

@ -0,0 +1,46 @@
From c16f0b44984bc623621d26df22823b50f13f65d8 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 14 May 2013 08:15:21 -0300
Subject: [PATCH 107/203] mtd: nand: pxa3xx: Set info->use_dma properly
Currently, the variable info->use_dma is never set and always
zero-valued which means the driver never does DMA transfers.
We fix this by simply setting info->use_dma to the module parameter,
also named 'use_dma'. Note that the module parameter has the same name,
but different semantics.
This fixes a regression introduced by the below commit
which removed the info->use_dma variable set.
commit 4eb2da8994042d68e84e31138788429a102da2ea
Author: Lei Wen <leiwen@marvell.com>
Date: Mon Feb 28 10:32:13 2011 +0800
mtd: pxa3xx_nand: unify prepare command
Before the above commit, the driver had use_dma=1 on all NAND commands
except on CMD_STATUS. This behavior is long lost and we are not
recovering in this patch, either.
This was spotted and verified by human inspection.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.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
@@ -506,6 +506,7 @@ static int prepare_command_pool(struct p
info->buf_count = 0;
info->oob_size = 0;
info->use_ecc = 0;
+ info->use_dma = (use_dma) ? 1 : 0;
info->is_ready = 0;
info->retcode = ERR_NONE;
if (info->cs != 0)

View file

@ -0,0 +1,29 @@
From baef6bdc8a3e9cb30ab254fd23eb655d592a19df Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 14 May 2013 08:15:22 -0300
Subject: [PATCH 108/203] mtd: nand: pxa3xx: Use of_machine_is_compatible()
This patch replaces cpu_is_pxa3xx() with of_machine_is_compatible()
which allows to build this driver for other platforms than ARCH_PXA.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.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
@@ -1094,7 +1094,7 @@ static int alloc_nand_resource(struct pl
* bindings. It can be removed once we have a prober DMA controller
* framework for DT.
*/
- if (pdev->dev.of_node && cpu_is_pxa3xx()) {
+ if (pdev->dev.of_node && of_machine_is_compatible("marvell,pxa3xx")) {
info->drcmr_dat = 97;
info->drcmr_cmd = 99;
} else {

View file

@ -0,0 +1,30 @@
From 3bda9dc1472596d094f020ab7231466d54b6fe00 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 14 May 2013 08:15:23 -0300
Subject: [PATCH 109/203] mtd: nand: pxa3xx: Fix MODULE_DEVICE_TABLE
declaration
This module's device table is incorrectly declared using
i2c_pxa_dt_ids, instead of pxa3xx_nand_dt_ids.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.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
@@ -1185,7 +1185,7 @@ static struct of_device_id pxa3xx_nand_d
{ .compatible = "marvell,pxa3xx-nand" },
{}
};
-MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
+MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
{

View file

@ -0,0 +1,31 @@
From 82dad325809637899313315c3103985df94c90a5 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 14 May 2013 08:15:24 -0300
Subject: [PATCH 110/203] mtd: nand: pxa3xx: Add address support for READID
command
This allows to support READID ONFI command which sends 0x20
as address together with the 0x90 READID command.
This is required to detect ONFI compliant devices.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.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
@@ -596,6 +596,7 @@ static int prepare_command_pool(struct p
info->ndcb0 |= NDCB0_CMD_TYPE(3)
| NDCB0_ADDR_CYC(1)
| cmd;
+ info->ndcb1 = (column & 0xFF);
info->data_size = 8;
break;

View file

@ -0,0 +1,37 @@
From 9d6e063c1fb2cb10e6e0c3883ca3d1944dadcfc4 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Tue, 14 May 2013 08:15:25 -0300
Subject: [PATCH 111/203] mtd: nand: pxa3xx: Add support for Read parameter
page command
This command is required to identify ONFI-compliant devices.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Reviewed-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -590,6 +590,16 @@ static int prepare_command_pool(struct p
| addr_cycle;
break;
+ case NAND_CMD_PARAM:
+ cmd = NAND_CMD_PARAM;
+ info->buf_count = 256;
+ info->ndcb0 |= NDCB0_CMD_TYPE(0)
+ | NDCB0_ADDR_CYC(1)
+ | cmd;
+ info->ndcb1 = (column & 0xFF);
+ info->data_size = 256;
+ break;
+
case NAND_CMD_READID:
cmd = host->cmdset->read_id;
info->buf_count = host->read_id_bytes;

View file

@ -0,0 +1,28 @@
From 03ab29791d222be44a7e2f5716f8a1cdbcf76ceb Mon Sep 17 00:00:00 2001
From: Jingoo Han <jg1.han@samsung.com>
Date: Tue, 7 May 2013 15:44:14 +0900
Subject: [PATCH 112/203] mtd: nand: pxa3xx_nand: remove unnecessary
platform_set_drvdata()
The driver core clears the driver data to NULL after device_release
or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d
(device-core: Ensure drvdata = NULL when no driver is bound).
Thus, it is not needed to manually clear the device driver data to NULL.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1177,7 +1177,6 @@ static int pxa3xx_nand_remove(struct pla
return 0;
pdata = pdev->dev.platform_data;
- platform_set_drvdata(pdev, NULL);
irq = platform_get_irq(pdev, 0);
if (irq >= 0)

View file

@ -0,0 +1,80 @@
From f37031e030eb05ba579c82b9e0424d2608c1ad67 Mon Sep 17 00:00:00 2001
From: Jingoo Han <jg1.han@samsung.com>
Date: Tue, 30 Jul 2013 17:18:33 +0900
Subject: [PATCH 113/203] mtd: nand: use dev_get_platdata()
Use the wrapper function for retrieving the platform data instead of
accessing dev->platform_data directly.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -815,7 +815,7 @@ static int pxa3xx_nand_config_flash(stru
const struct pxa3xx_nand_flash *f)
{
struct platform_device *pdev = info->pdev;
- struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
+ struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct pxa3xx_nand_host *host = info->host[info->cs];
uint32_t ndcr = 0x0; /* enable all interrupts */
@@ -958,7 +958,7 @@ static int pxa3xx_nand_scan(struct mtd_i
struct pxa3xx_nand_host *host = mtd->priv;
struct pxa3xx_nand_info *info = host->info_data;
struct platform_device *pdev = info->pdev;
- struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
+ struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL;
const struct pxa3xx_nand_flash *f = NULL;
struct nand_chip *chip = mtd->priv;
@@ -1058,7 +1058,7 @@ static int alloc_nand_resource(struct pl
struct resource *r;
int ret, irq, cs;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) +
sizeof(*host)) * pdata->num_cs, GFP_KERNEL);
if (!info)
@@ -1176,7 +1176,7 @@ static int pxa3xx_nand_remove(struct pla
if (!info)
return 0;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
irq = platform_get_irq(pdev, 0);
if (irq >= 0)
@@ -1239,7 +1239,7 @@ static int pxa3xx_nand_probe(struct plat
if (ret)
return ret;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "no platform data defined\n");
return -ENODEV;
@@ -1286,7 +1286,7 @@ static int pxa3xx_nand_suspend(struct pl
struct mtd_info *mtd;
int cs;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
if (info->state) {
dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
return -EAGAIN;
@@ -1307,7 +1307,7 @@ static int pxa3xx_nand_resume(struct pla
struct mtd_info *mtd;
int cs;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
/* We don't want to handle interrupt without calling mtd routine */
disable_int(info, NDCR_INT_MASK);

View file

@ -0,0 +1,88 @@
From 259e46e4327a9937761fd3f7bc07e208b1fa50e6 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Sat, 10 Aug 2013 16:34:52 -0300
Subject: [PATCH 114/203] mtd: nand: pxa3xx: Introduce 'marvell,armada370-nand'
compatible string
This driver supports NFCv1 (as found in PXA SoC) and NFCv2 (as found in
Armada 370/XP SoC). As both controller has a few differences, a way of
distinguishing between the two is needed.
This commit introduces a new compatible string 'marvell,armada370-nand'
and assigns a compatible data of type enum pxa3xx_nand_variant to allow
such distinction.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Tested-by: Daniel Mack <zonque@gmail.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -123,6 +123,11 @@ enum {
STATE_READY,
};
+enum pxa3xx_nand_variant {
+ PXA3XX_NAND_VARIANT_PXA,
+ PXA3XX_NAND_VARIANT_ARMADA370,
+};
+
struct pxa3xx_nand_host {
struct nand_chip chip;
struct pxa3xx_nand_cmdset *cmdset;
@@ -171,6 +176,12 @@ struct pxa3xx_nand_info {
struct pxa3xx_nand_host *host[NUM_CHIP_SELECT];
unsigned int state;
+ /*
+ * This driver supports NFCv1 (as found in PXA SoC)
+ * and NFCv2 (as found in Armada 370/XP SoC).
+ */
+ enum pxa3xx_nand_variant variant;
+
int cs;
int use_ecc; /* use HW ECC ? */
int use_dma; /* use DMA ? */
@@ -1192,11 +1203,28 @@ static int pxa3xx_nand_remove(struct pla
#ifdef CONFIG_OF
static struct of_device_id pxa3xx_nand_dt_ids[] = {
- { .compatible = "marvell,pxa3xx-nand" },
+ {
+ .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;
@@ -1252,6 +1280,7 @@ 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++) {
info->cs = cs;

View file

@ -0,0 +1,39 @@
From d6af8f27223a244d74ab44842bdec707c97cfe55 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:48 -0300
Subject: [PATCH 115/203] mtd: nand: pxa3xx: Handle ECC and DMA enable/disable
properly
When ECC is not selected, the ECC enable bit must be cleared
in the NAND control register. Same applies to DMA.
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/pxa3xx_nand.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -314,8 +314,17 @@ static void pxa3xx_nand_start(struct pxa
uint32_t ndcr;
ndcr = host->reg_ndcr;
- ndcr |= info->use_ecc ? NDCR_ECC_EN : 0;
- ndcr |= info->use_dma ? NDCR_DMA_EN : 0;
+
+ if (info->use_ecc)
+ ndcr |= NDCR_ECC_EN;
+ else
+ ndcr &= ~NDCR_ECC_EN;
+
+ if (info->use_dma)
+ ndcr |= NDCR_DMA_EN;
+ else
+ ndcr &= ~NDCR_DMA_EN;
+
ndcr |= NDCR_ND_RUN;
/* clear status bits and run */

View file

@ -0,0 +1,49 @@
From be5f1d59341e48dbe0730253417c52bf79c6c3a7 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:49 -0300
Subject: [PATCH 116/203] mtd: nand: pxa3xx: Allow to set/clear the 'spare
enable' field
Some commands (such as the ONFI parameter page read) need to
clear the 'spare enable' bit. This commit allows to set/clear
depending on the prepared command, instead of having it always
set.
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/pxa3xx_nand.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -185,6 +185,7 @@ struct pxa3xx_nand_info {
int cs;
int use_ecc; /* use HW ECC ? */
int use_dma; /* use DMA ? */
+ int use_spare; /* use spare ? */
int is_ready;
unsigned int page_size; /* page size of attached chip */
@@ -325,6 +326,11 @@ static void pxa3xx_nand_start(struct pxa
else
ndcr &= ~NDCR_DMA_EN;
+ if (info->use_spare)
+ ndcr |= NDCR_SPARE_EN;
+ else
+ ndcr &= ~NDCR_SPARE_EN;
+
ndcr |= NDCR_ND_RUN;
/* clear status bits and run */
@@ -526,6 +532,7 @@ static int prepare_command_pool(struct p
info->buf_count = 0;
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;

View file

@ -0,0 +1,59 @@
From 6bbda039fe5e9d1b3c04f4f0dd8479a2c102d28e Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:50 -0300
Subject: [PATCH 117/203] mtd: nand: pxa3xx: Support command buffer #3
Some newer controllers support a fourth command buffer. This additional
command buffer allows to set an arbitrary length count, using the
NDCB3.NDLENCNT field, to perform non-standard length operations
such as the ONFI parameter page read.
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/pxa3xx_nand.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -197,6 +197,7 @@ struct pxa3xx_nand_info {
uint32_t ndcb0;
uint32_t ndcb1;
uint32_t ndcb2;
+ uint32_t ndcb3;
};
static bool use_dma = 1;
@@ -493,9 +494,22 @@ static irqreturn_t pxa3xx_nand_irq(int i
nand_writel(info, NDSR, NDSR_WRCMDREQ);
status &= ~NDSR_WRCMDREQ;
info->state = STATE_CMD_HANDLE;
+
+ /*
+ * Command buffer registers NDCB{0-2} (and optionally NDCB3)
+ * must be loaded by writing directly either 12 or 16
+ * bytes directly to NDCB0, four bytes at a time.
+ *
+ * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored
+ * but each NDCBx register can be read.
+ */
nand_writel(info, NDCB0, info->ndcb0);
nand_writel(info, NDCB0, info->ndcb1);
nand_writel(info, NDCB0, info->ndcb2);
+
+ /* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
+ if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+ nand_writel(info, NDCB0, info->ndcb3);
}
/* clear NDSR to let the controller exit the IRQ */
@@ -554,6 +568,7 @@ static int prepare_command_pool(struct p
default:
info->ndcb1 = 0;
info->ndcb2 = 0;
+ info->ndcb3 = 0;
break;
}

View file

@ -0,0 +1,52 @@
From adbba4cf6ea15c2acb53e3fd9fc03c6b37f1f1fc Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:51 -0300
Subject: [PATCH 118/203] mtd: nand: pxa3xx: Use 'length override' in ONFI
paramater page read
The ONFI command 'parameter page read' needs a non-standard length.
Therefore, we enable the 'length override' field in NDCB0 and set
a non-zero 'length count' in NDCB3.
Additionally, the 'spare enable' bit must be disabled for any command
that sets a non-zero 'length count' in NDCB3.
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/pxa3xx_nand.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -80,6 +80,7 @@
#define NDSR_RDDREQ (0x1 << 1)
#define NDSR_WRCMDREQ (0x1)
+#define NDCB0_LEN_OVRD (0x1 << 28)
#define NDCB0_ST_ROW_EN (0x1 << 26)
#define NDCB0_AUTO_RS (0x1 << 25)
#define NDCB0_CSEL (0x1 << 24)
@@ -562,6 +563,9 @@ static int prepare_command_pool(struct p
case NAND_CMD_READOOB:
pxa3xx_set_datasize(info);
break;
+ case NAND_CMD_PARAM:
+ info->use_spare = 0;
+ break;
case NAND_CMD_SEQIN:
exec_cmd = 0;
break;
@@ -637,8 +641,10 @@ static int prepare_command_pool(struct p
info->buf_count = 256;
info->ndcb0 |= NDCB0_CMD_TYPE(0)
| NDCB0_ADDR_CYC(1)
+ | NDCB0_LEN_OVRD
| cmd;
info->ndcb1 = (column & 0xFF);
+ info->ndcb3 = 256;
info->data_size = 256;
break;

View file

@ -0,0 +1,37 @@
From 9f27a3899318ef0c4c147ed2d84cfbfb339d9bb6 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:52 -0300
Subject: [PATCH 119/203] mtd: nand: pxa3xx: Add a local loop variable
This is just a cosmetic change, to make the code more readable.
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/pxa3xx_nand.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1320,8 +1320,9 @@ static int pxa3xx_nand_probe(struct plat
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;
info->cs = cs;
- ret = pxa3xx_nand_scan(info->host[cs]->mtd);
+ ret = pxa3xx_nand_scan(mtd);
if (ret) {
dev_warn(&pdev->dev, "failed to scan nand at cs %d\n",
cs);
@@ -1329,7 +1330,7 @@ static int pxa3xx_nand_probe(struct plat
}
ppdata.of_node = pdev->dev.of_node;
- ret = mtd_device_parse_register(info->host[cs]->mtd, NULL,
+ ret = mtd_device_parse_register(mtd, NULL,
&ppdata, pdata->parts[cs],
pdata->nr_parts[cs]);
if (!ret)

View file

@ -0,0 +1,45 @@
From 96d8ffc47c7ee9689b8b48ac9588e0b00fa9bd44 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:53 -0300
Subject: [PATCH 120/203] mtd: nand: pxa3xx: Remove hardcoded mtd name
There's no advantage in using a hardcoded name for the mtd device.
Instead use the provided by the platform_device.
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/pxa3xx_nand.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -244,8 +244,6 @@ static struct pxa3xx_nand_flash builtin_
/* Define a default flash type setting serve as flash detecting only */
#define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
-const char *mtd_names[] = {"pxa3xx_nand-0", "pxa3xx_nand-1", NULL};
-
#define NDTR0_tCH(c) (min((c), 7) << 19)
#define NDTR0_tCS(c) (min((c), 7) << 16)
#define NDTR0_tWH(c) (min((c), 7) << 11)
@@ -1091,8 +1089,6 @@ KEEP_CONFIG:
host->row_addr_cycles = 3;
else
host->row_addr_cycles = 2;
-
- mtd->name = mtd_names[0];
return nand_scan_tail(mtd);
}
@@ -1321,6 +1317,8 @@ static int pxa3xx_nand_probe(struct plat
probe_success = 0;
for (cs = 0; cs < pdata->num_cs; cs++) {
struct mtd_info *mtd = info->host[cs]->mtd;
+
+ mtd->name = pdev->name;
info->cs = cs;
ret = pxa3xx_nand_scan(mtd);
if (ret) {

View file

@ -0,0 +1,200 @@
From 45d36da3f284cd424b0ac2060cfccc17f9979552 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:54 -0300
Subject: [PATCH 121/203] mtd: nand: pxa3xx: Remove unneeded internal cmdset
Use the defined macros for NAND command instead of using a constant
internal structure. This commit is only a cleanup, there's no
functionality modification.
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/pxa3xx_nand.c | 63 ++++++++-------------------
include/linux/platform_data/mtd-nand-pxa3xx.h | 13 ------
2 files changed, 17 insertions(+), 59 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -131,7 +131,6 @@ enum pxa3xx_nand_variant {
struct pxa3xx_nand_host {
struct nand_chip chip;
- struct pxa3xx_nand_cmdset *cmdset;
struct mtd_info *mtd;
void *info_data;
@@ -205,23 +204,6 @@ static bool use_dma = 1;
module_param(use_dma, bool, 0444);
MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW");
-/*
- * Default NAND flash controller configuration setup by the
- * bootloader. This configuration is used only when pdata->keep_config is set
- */
-static struct pxa3xx_nand_cmdset default_cmdset = {
- .read1 = 0x3000,
- .read2 = 0x0050,
- .program = 0x1080,
- .read_status = 0x0070,
- .read_id = 0x0090,
- .erase = 0xD060,
- .reset = 0x00FF,
- .lock = 0x002A,
- .unlock = 0x2423,
- .lock_status = 0x007A,
-};
-
static struct pxa3xx_nand_timing timing[] = {
{ 40, 80, 60, 100, 80, 100, 90000, 400, 40, },
{ 10, 0, 20, 40, 30, 40, 11123, 110, 10, },
@@ -530,7 +512,6 @@ static inline int is_buf_blank(uint8_t *
static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
uint16_t column, int page_addr)
{
- uint16_t cmd;
int addr_cycle, exec_cmd;
struct pxa3xx_nand_host *host;
struct mtd_info *mtd;
@@ -580,21 +561,17 @@ static int prepare_command_pool(struct p
switch (command) {
case NAND_CMD_READOOB:
case NAND_CMD_READ0:
- cmd = host->cmdset->read1;
+ info->buf_start = column;
+ info->ndcb0 |= NDCB0_CMD_TYPE(0)
+ | addr_cycle
+ | NAND_CMD_READ0;
+
if (command == NAND_CMD_READOOB)
- info->buf_start = mtd->writesize + column;
- else
- info->buf_start = column;
+ info->buf_start += mtd->writesize;
- if (unlikely(host->page_size < PAGE_CHUNK_SIZE))
- info->ndcb0 |= NDCB0_CMD_TYPE(0)
- | addr_cycle
- | (cmd & NDCB0_CMD1_MASK);
- else
- info->ndcb0 |= NDCB0_CMD_TYPE(0)
- | NDCB0_DBC
- | addr_cycle
- | cmd;
+ /* Second command setting for large pages */
+ if (host->page_size >= PAGE_CHUNK_SIZE)
+ info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
case NAND_CMD_SEQIN:
/* small page addr setting */
@@ -625,62 +602,58 @@ static int prepare_command_pool(struct p
break;
}
- cmd = host->cmdset->program;
info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
| NDCB0_AUTO_RS
| NDCB0_ST_ROW_EN
| NDCB0_DBC
- | cmd
+ | (NAND_CMD_PAGEPROG << 8)
+ | NAND_CMD_SEQIN
| addr_cycle;
break;
case NAND_CMD_PARAM:
- cmd = NAND_CMD_PARAM;
info->buf_count = 256;
info->ndcb0 |= NDCB0_CMD_TYPE(0)
| NDCB0_ADDR_CYC(1)
| NDCB0_LEN_OVRD
- | cmd;
+ | command;
info->ndcb1 = (column & 0xFF);
info->ndcb3 = 256;
info->data_size = 256;
break;
case NAND_CMD_READID:
- cmd = host->cmdset->read_id;
info->buf_count = host->read_id_bytes;
info->ndcb0 |= NDCB0_CMD_TYPE(3)
| NDCB0_ADDR_CYC(1)
- | cmd;
+ | command;
info->ndcb1 = (column & 0xFF);
info->data_size = 8;
break;
case NAND_CMD_STATUS:
- cmd = host->cmdset->read_status;
info->buf_count = 1;
info->ndcb0 |= NDCB0_CMD_TYPE(4)
| NDCB0_ADDR_CYC(1)
- | cmd;
+ | command;
info->data_size = 8;
break;
case NAND_CMD_ERASE1:
- cmd = host->cmdset->erase;
info->ndcb0 |= NDCB0_CMD_TYPE(2)
| NDCB0_AUTO_RS
| NDCB0_ADDR_CYC(3)
| NDCB0_DBC
- | cmd;
+ | (NAND_CMD_ERASE2 << 8)
+ | NAND_CMD_ERASE1;
info->ndcb1 = page_addr;
info->ndcb2 = 0;
break;
case NAND_CMD_RESET:
- cmd = host->cmdset->reset;
info->ndcb0 |= NDCB0_CMD_TYPE(5)
- | cmd;
+ | command;
break;
@@ -876,7 +849,6 @@ static int pxa3xx_nand_config_flash(stru
}
/* calculate flash information */
- host->cmdset = &default_cmdset;
host->page_size = f->page_size;
host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
@@ -922,7 +894,6 @@ static int pxa3xx_nand_detect_config(str
}
host->reg_ndcr = ndcr & ~NDCR_INT_MASK;
- host->cmdset = &default_cmdset;
host->ndtr0cs0 = nand_readl(info, NDTR0CS0);
host->ndtr1cs0 = nand_readl(info, NDTR1CS0);
--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
+++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
@@ -16,19 +16,6 @@ struct pxa3xx_nand_timing {
unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
};
-struct pxa3xx_nand_cmdset {
- uint16_t read1;
- uint16_t read2;
- uint16_t program;
- uint16_t read_status;
- uint16_t read_id;
- uint16_t erase;
- uint16_t reset;
- uint16_t lock;
- uint16_t unlock;
- uint16_t lock_status;
-};
-
struct pxa3xx_nand_flash {
char *name;
uint32_t chip_id;

View file

@ -0,0 +1,127 @@
From 5c5367d7f9ad835b3b8a2dddfbe90e4c6e669084 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:55 -0300
Subject: [PATCH 122/203] mtd: nand: pxa3xx: Move cached registers to info
structure
This registers are not per-chip (aka host) but controller-wide,
so it's better to store them in the global 'info' structure.
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/pxa3xx_nand.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -144,10 +144,6 @@ struct pxa3xx_nand_host {
unsigned int row_addr_cycles;
size_t read_id_bytes;
- /* cached register value */
- uint32_t reg_ndcr;
- uint32_t ndtr0cs0;
- uint32_t ndtr1cs0;
};
struct pxa3xx_nand_info {
@@ -193,6 +189,11 @@ struct pxa3xx_nand_info {
unsigned int oob_size;
int retcode;
+ /* cached register value */
+ uint32_t reg_ndcr;
+ uint32_t ndtr0cs0;
+ uint32_t ndtr1cs0;
+
/* generated NDCBx register values */
uint32_t ndcb0;
uint32_t ndcb1;
@@ -258,8 +259,8 @@ static void pxa3xx_nand_set_timing(struc
NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) |
NDTR1_tAR(ns2cycle(t->tAR, nand_clk));
- host->ndtr0cs0 = ndtr0;
- host->ndtr1cs0 = ndtr1;
+ info->ndtr0cs0 = ndtr0;
+ info->ndtr1cs0 = ndtr1;
nand_writel(info, NDTR0CS0, ndtr0);
nand_writel(info, NDTR1CS0, ndtr1);
}
@@ -267,7 +268,7 @@ 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 = host->reg_ndcr & NDCR_SPARE_EN;
+ int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
info->data_size = host->page_size;
if (!oob_enable) {
@@ -293,10 +294,9 @@ static void pxa3xx_set_datasize(struct p
*/
static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
{
- struct pxa3xx_nand_host *host = info->host[info->cs];
uint32_t ndcr;
- ndcr = host->reg_ndcr;
+ ndcr = info->reg_ndcr;
if (info->use_ecc)
ndcr |= NDCR_ECC_EN;
@@ -683,7 +683,7 @@ static void pxa3xx_nand_cmdfunc(struct m
* "byte" address into a "word" address appropriate
* for indexing a word-oriented device
*/
- if (host->reg_ndcr & NDCR_DWIDTH_M)
+ if (info->reg_ndcr & NDCR_DWIDTH_M)
column /= 2;
/*
@@ -693,8 +693,8 @@ static void pxa3xx_nand_cmdfunc(struct m
*/
if (info->cs != host->cs) {
info->cs = host->cs;
- nand_writel(info, NDTR0CS0, host->ndtr0cs0);
- nand_writel(info, NDTR1CS0, host->ndtr1cs0);
+ nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+ nand_writel(info, NDTR1CS0, info->ndtr1cs0);
}
info->state = STATE_PREPARED;
@@ -870,7 +870,7 @@ static int pxa3xx_nand_config_flash(stru
ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
ndcr |= NDCR_SPARE_EN; /* enable spare by default */
- host->reg_ndcr = ndcr;
+ info->reg_ndcr = ndcr;
pxa3xx_nand_set_timing(host, f->timing);
return 0;
@@ -893,11 +893,9 @@ static int pxa3xx_nand_detect_config(str
host->read_id_bytes = 2;
}
- host->reg_ndcr = ndcr & ~NDCR_INT_MASK;
-
- host->ndtr0cs0 = nand_readl(info, NDTR0CS0);
- host->ndtr1cs0 = nand_readl(info, NDTR1CS0);
-
+ info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
+ info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
+ info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
return 0;
}
@@ -1044,7 +1042,7 @@ KEEP_CONFIG:
chip->ecc.size = host->page_size;
chip->ecc.strength = 1;
- if (host->reg_ndcr & NDCR_DWIDTH_M)
+ if (info->reg_ndcr & NDCR_DWIDTH_M)
chip->options |= NAND_BUSWIDTH_16;
if (nand_scan_ident(mtd, 1, def))

View file

@ -0,0 +1,106 @@
From 085ced2b9e159dbeae029e338958b8c8ae9073b9 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:56 -0300
Subject: [PATCH 123/203] mtd: nand: pxa3xx: Make dma code dependent on dma
capable platforms
This patch adds a macro ARCH_HAS_DMA to compile-out arch specific
dma code, namely pxa_request_dma() and pxa_free_dma(). These symbols
are available only in pxa, which makes impossible to build the driver in
other platforms than ARCH_PXA.
In order to handle non-dma capable platforms, we implement a fallbacks that
allocate buffers as if 'use_dma=false', putting the dma related code
under the ARCH_HAS_DMA conditional.
Please note that the correct way to handle this is to migrate the
dma code to use of the mmp_pdma dmaengine driver. However, currently
this is not possible because the two dmaengine drivers can't work together.
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/pxa3xx_nand.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -25,7 +25,14 @@
#include <linux/of.h>
#include <linux/of_device.h>
+#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
+#define ARCH_HAS_DMA
+#endif
+
+#ifdef ARCH_HAS_DMA
#include <mach/dma.h>
+#endif
+
#include <linux/platform_data/mtd-nand-pxa3xx.h>
#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
@@ -381,6 +388,7 @@ static void handle_data_pio(struct pxa3x
}
}
+#ifdef ARCH_HAS_DMA
static void start_data_dma(struct pxa3xx_nand_info *info)
{
struct pxa_dma_desc *desc = info->data_desc;
@@ -427,6 +435,10 @@ static void pxa3xx_nand_data_dma_irq(int
enable_int(info, NDCR_INT_MASK);
nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
}
+#else
+static void start_data_dma(struct pxa3xx_nand_info *info)
+{}
+#endif
static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
{
@@ -905,6 +917,7 @@ static int pxa3xx_nand_detect_config(str
*/
#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;
@@ -950,6 +963,20 @@ static void pxa3xx_nand_free_buff(struct
kfree(info->data_buff);
}
}
+#else
+static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
+{
+ info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
+ if (info->data_buff == NULL)
+ return -ENOMEM;
+ return 0;
+}
+
+static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
+{
+ kfree(info->data_buff);
+}
+#endif
static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
{
@@ -1265,6 +1292,13 @@ static int pxa3xx_nand_probe(struct plat
struct pxa3xx_nand_info *info;
int ret, cs, probe_success;
+#ifndef ARCH_HAS_DMA
+ if (use_dma) {
+ use_dma = 0;
+ dev_warn(&pdev->dev,
+ "This platform can't do DMA on this device\n");
+ }
+#endif
ret = pxa3xx_nand_probe_dt(pdev);
if (ret)
return ret;

View file

@ -0,0 +1,33 @@
From d6d4e28e52f3cd70f60d03405181994a2763532b Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:57 -0300
Subject: [PATCH 124/203] mtd: nand: pxa3xx: Add __maybe_unused keyword to
enable_int()
Now that we have added ARCH_HAS_DMA conditional the function
enable_int() may be unused. Declare it as __maybe_unused,
in order to remove the following warning, when the function is not used:
drivers/mtd/nand//pxa3xx_nand.c:343:24: warning: 'enable_int' defined
but not used [-Wunused-function]
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/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
@@ -348,7 +348,8 @@ static void pxa3xx_nand_stop(struct pxa3
nand_writel(info, NDSR, NDSR_MASK);
}
-static void enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
+static void __maybe_unused
+enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
{
uint32_t ndcr;

View file

@ -0,0 +1,78 @@
From c26369f5b9929e1187ccf716d6d1678196ec0b4f Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:58 -0300
Subject: [PATCH 125/203] mtd: nand: pxa3xx: Allow devices with no dma
resources
When use_dma=0 there's no point in requesting resources for dma,
since they won't be used anyway. Therefore we remove that requirement,
therefore allowing devices without dma to pass the driver probe.
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/pxa3xx_nand.c | 51 +++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 23 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1141,30 +1141,35 @@ static int alloc_nand_resource(struct pl
if (ret < 0)
return ret;
- /*
- * This is a dirty hack to make this driver work from devicetree
- * bindings. It can be removed once we have a prober DMA controller
- * framework for DT.
- */
- if (pdev->dev.of_node && of_machine_is_compatible("marvell,pxa3xx")) {
- info->drcmr_dat = 97;
- info->drcmr_cmd = 99;
- } else {
- r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no resource defined for data DMA\n");
- ret = -ENXIO;
- goto fail_disable_clk;
- }
- info->drcmr_dat = r->start;
+ if (use_dma) {
+ /*
+ * This is a dirty hack to make this driver work from
+ * devicetree bindings. It can be removed once we have
+ * a prober DMA controller framework for DT.
+ */
+ if (pdev->dev.of_node &&
+ of_machine_is_compatible("marvell,pxa3xx")) {
+ info->drcmr_dat = 97;
+ info->drcmr_cmd = 99;
+ } else {
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev,
+ "no resource defined for data DMA\n");
+ ret = -ENXIO;
+ goto fail_disable_clk;
+ }
+ info->drcmr_dat = r->start;
- r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
- if (r == NULL) {
- dev_err(&pdev->dev, "no resource defined for command DMA\n");
- ret = -ENXIO;
- goto fail_disable_clk;
+ r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (r == NULL) {
+ dev_err(&pdev->dev,
+ "no resource defined for cmd DMA\n");
+ ret = -ENXIO;
+ goto fail_disable_clk;
+ }
+ info->drcmr_cmd = r->start;
}
- info->drcmr_cmd = r->start;
}
irq = platform_get_irq(pdev, 0);

View file

@ -0,0 +1,39 @@
From 1fea4cca22fcb1045a0c1ad42df793e3ea29b5bf Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon, 12 Aug 2013 14:14:46 -0300
Subject: [PATCH 126/203] mtd: nand: pxa3xx: Remove unneeded ifdef CONFIG_OF
There's no need to enclose this code within idef CONFIG_OF,
because the OF framework provides no-op stubs if CONFIG_OF=n.
Cc: devicetree@vger.kernel.org
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
---
drivers/mtd/nand/pxa3xx_nand.c | 7 -------
1 file changed, 7 deletions(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1236,7 +1236,6 @@ static int pxa3xx_nand_remove(struct pla
return 0;
}
-#ifdef CONFIG_OF
static struct of_device_id pxa3xx_nand_dt_ids[] = {
{
.compatible = "marvell,pxa3xx-nand",
@@ -1284,12 +1283,6 @@ static int pxa3xx_nand_probe_dt(struct p
return 0;
}
-#else
-static inline int pxa3xx_nand_probe_dt(struct platform_device *pdev)
-{
- return 0;
-}
-#endif
static int pxa3xx_nand_probe(struct platform_device *pdev)
{

View file

@ -0,0 +1,48 @@
From fe013a7a5667763bde164dd5c9341ee5361a9c23 Mon Sep 17 00:00:00 2001
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Sat, 19 Oct 2013 18:19:25 -0300
Subject: [PATCH 127/203] mtd: nand: pxa3xx: Fix registered MTD name
In a recent commit:
commit f455578dd961087a5cf94730d9f6489bb1d355f0
Author: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Date: Mon Aug 12 14:14:53 2013 -0300
mtd: nand: pxa3xx: Remove hardcoded mtd name
There's no advantage in using a hardcoded name for the mtd device.
Instead use the provided by the platform_device.
The MTD name was changed to use the one provided by the platform_device.
However, this can be problematic as some users want to set partitions
using the kernel parameter 'mtdparts', where the name is needed.
Therefore, to avoid regressions in users relying in 'mtdparts' we revert
the change and use the previous one 'pxa3xx_nand-0'.
While at it, let's put a big comment and prevent this change from happening
ever again.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1320,7 +1320,12 @@ static int pxa3xx_nand_probe(struct plat
for (cs = 0; cs < pdata->num_cs; cs++) {
struct mtd_info *mtd = info->host[cs]->mtd;
- mtd->name = pdev->name;
+ /*
+ * The mtd name matches the one used in 'mtdparts' kernel
+ * parameter. This name cannot be changed or otherwise
+ * user's mtd partitions configuration would get broken.
+ */
+ mtd->name = "pxa3xx_nand-0";
info->cs = cs;
ret = pxa3xx_nand_scan(mtd);
if (ret) {