SoCFPGA patches added

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/patches.socfpga/0001-ARM-dts-socfpga-enable-arm-shared-override-in-the-pl.patch b/patches.socfpga/0001-ARM-dts-socfpga-enable-arm-shared-override-in-the-pl.patch
new file mode 100644
index 0000000..8304e41
--- /dev/null
+++ b/patches.socfpga/0001-ARM-dts-socfpga-enable-arm-shared-override-in-the-pl.patch
@@ -0,0 +1,37 @@
+From 2e23d6de091f3e5e913086e223ac30eb4aa1f2a2 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Mon, 26 Sep 2016 14:29:30 -0500
+Subject: [PATCH 001/103] ARM: dts: socfpga: enable arm,shared-override in the
+ pl310
+
+Enable the bit(22) shared-override bit for the SoCFPGA family. While at it,
+enable the prefetch-data and prefetch-instr settings for the Arria10.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga.dtsi         |    1 +
+ arch/arm/boot/dts/socfpga_arria10.dtsi |    3 +++
+ 2 files changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga.dtsi
++++ b/arch/arm/boot/dts/socfpga.dtsi
+@@ -686,6 +686,7 @@
+ 			arm,data-latency = <2 1 1>;
+ 			prefetch-data = <1>;
+ 			prefetch-instr = <1>;
++			arm,shared-override;
+ 		};
+ 
+ 		mmc: dwmmc0@ff704000 {
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -573,6 +573,9 @@
+ 			interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
+ 			cache-unified;
+ 			cache-level = <2>;
++			prefetch-data = <1>;
++			prefetch-instr = <1>;
++			arm,shared-override;
+ 		};
+ 
+ 		mmc: dwmmc0@ff808000 {
diff --git a/patches.socfpga/0002-ARM-socfpga_defconfig-Enable-HIGHMEM.patch b/patches.socfpga/0002-ARM-socfpga_defconfig-Enable-HIGHMEM.patch
new file mode 100644
index 0000000..214247e
--- /dev/null
+++ b/patches.socfpga/0002-ARM-socfpga_defconfig-Enable-HIGHMEM.patch
@@ -0,0 +1,26 @@
+From c9d8a75227efb5a538da3f00cc675f20d9191602 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Tue, 25 Oct 2016 10:55:40 -0500
+Subject: [PATCH 002/103] ARM: socfpga_defconfig: Enable HIGHMEM
+
+All of the SoCFPGA boards have at least 1GB of RAM, so enabling HIGHMEM
+is necessary to avoid the following warning:
+
+[    0.000000] Truncating RAM at 0x00000000-0x40000000 to -0x30000000
+[    0.000000] Consider using a HIGHMEM enabled kernel.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/configs/socfpga_defconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -25,6 +25,7 @@ CONFIG_PCIE_ALTERA_MSI=y
+ CONFIG_SMP=y
+ CONFIG_NR_CPUS=2
+ CONFIG_AEABI=y
++CONFIG_HIGHMEM=y
+ CONFIG_ZBOOT_ROM_TEXT=0x0
+ CONFIG_ZBOOT_ROM_BSS=0x0
+ CONFIG_VFP=y
diff --git a/patches.socfpga/0003-ARM-dts-socfpga-enable-qspi-on-the-Cyclone5-devkit.patch b/patches.socfpga/0003-ARM-dts-socfpga-enable-qspi-on-the-Cyclone5-devkit.patch
new file mode 100644
index 0000000..52ced0c
--- /dev/null
+++ b/patches.socfpga/0003-ARM-dts-socfpga-enable-qspi-on-the-Cyclone5-devkit.patch
@@ -0,0 +1,54 @@
+From 60dab8bcc4915614d4853861f6a6ff35c2799d57 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Tue, 18 Oct 2016 22:51:42 -0500
+Subject: [PATCH 003/103] ARM: dts: socfpga: enable qspi on the Cyclone5 devkit
+
+Enable the qspi controller on the devkit and add the flash chip.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts |   33 +++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -87,6 +87,39 @@
+ 	status = "okay";
+ };
+ 
++&qspi {
++	status = "okay";
++
++	flash0: n25q00@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "n25q00";
++		reg = <0>;	/* chip select */
++		spi-max-frequency = <100000000>;
++
++		m25p,fast-read;
++		cdns,page-size = <256>;
++		cdns,block-size = <16>;
++		cdns,read-delay = <4>;
++		cdns,tshsl-ns = <50>;
++		cdns,tsd2d-ns = <50>;
++		cdns,tchsh-ns = <4>;
++		cdns,tslch-ns = <4>;
++
++		partition@qspi-boot {
++			/* 8MB for raw data. */
++			label = "Flash 0 Raw Data";
++			reg = <0x0 0x800000>;
++		};
++
++		partition@qspi-rootfs {
++			/* 120MB for jffs2 data. */
++			label = "Flash 0 jffs2 Filesystem";
++			reg = <0x800000 0x7800000>;
++		};
++	};
++};
++
+ &usb1 {
+ 	status = "okay";
+ };
diff --git a/patches.socfpga/0004-ARM-dts-socfpga-Add-QSPI-node-for-the-Arria10.patch b/patches.socfpga/0004-ARM-dts-socfpga-Add-QSPI-node-for-the-Arria10.patch
new file mode 100644
index 0000000..7fc973c
--- /dev/null
+++ b/patches.socfpga/0004-ARM-dts-socfpga-Add-QSPI-node-for-the-Arria10.patch
@@ -0,0 +1,35 @@
+From ab6809e7a5eb396b38f0cee59b1cda615de6cd69 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Wed, 19 Oct 2016 10:56:33 -0500
+Subject: [PATCH 004/103] ARM: dts: socfpga: Add QSPI node for the Arria10
+
+Add the QSPI device node for Arria10 SOC.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria10.dtsi |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -660,6 +660,20 @@
+ 			};
+ 		};
+ 
++		qspi: spi@ff809000 {
++			compatible = "cdns,qspi-nor";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xff809000 0x100>,
++			      <0xffa00000 0x100000>;
++			interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
++			cdns,fifo-depth = <128>;
++			cdns,fifo-width = <4>;
++			cdns,trigger-address = <0x00000000>;
++			clocks = <&qspi_clk>;
++			status = "disabled";
++		};
++
+ 		rst: rstmgr@ffd05000 {
+ 			#reset-cells = <1>;
+ 			compatible = "altr,rst-mgr";
diff --git a/patches.socfpga/0005-ARM-dts-socfpga-Enable-QSPI-in-Arria10-devkit.patch b/patches.socfpga/0005-ARM-dts-socfpga-Enable-QSPI-in-Arria10-devkit.patch
new file mode 100644
index 0000000..d13b676
--- /dev/null
+++ b/patches.socfpga/0005-ARM-dts-socfpga-Enable-QSPI-in-Arria10-devkit.patch
@@ -0,0 +1,76 @@
+From 9004406f4a7df7be3ba20eb5299db80ae89a4de8 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Wed, 19 Oct 2016 10:07:48 -0500
+Subject: [PATCH 005/103] ARM: dts: socfpga: Enable QSPI in Arria10 devkit
+
+Enable the QSPI node and add the flash chip.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/Makefile                       |    1 
+ arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts |   49 +++++++++++++++++++++++
+ 2 files changed, 50 insertions(+)
+ create mode 100644 arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -693,6 +693,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
+ 	sh73a0-kzm9g.dtb
+ dtb-$(CONFIG_ARCH_SOCFPGA) += \
+ 	socfpga_arria5_socdk.dtb \
++	socfpga_arria10_socdk_qspi.dtb \
+ 	socfpga_arria10_socdk_sdmmc.dtb \
+ 	socfpga_cyclone5_mcvevk.dtb \
+ 	socfpga_cyclone5_socdk.dtb \
+--- /dev/null
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2016 Intel. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/dts-v1/;
++#include "socfpga_arria10_socdk.dtsi"
++
++&qspi {
++	status = "okay";
++
++	flash0: n25q00@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "n25q00aa";
++		reg = <0>;
++		spi-max-frequency = <100000000>;
++
++		m25p,fast-read;
++		cdns,page-size = <256>;
++		cdns,block-size = <16>;
++		cdns,read-delay = <4>;
++		cdns,tshsl-ns = <50>;
++		cdns,tsd2d-ns = <50>;
++		cdns,tchsh-ns = <4>;
++		cdns,tslch-ns = <4>;
++
++		partition@qspi-boot {
++			label = "Boot and fpga data";
++			reg = <0x0 0x2720000>;
++		};
++
++		partition@qspi-rootfs {
++			label = "Root Filesystem - JFFS2";
++			reg = <0x2720000 0x58E0000>;
++		};
++	};
++};
diff --git a/patches.socfpga/0006-ARM-dts-socfpga-Enable-QSPI-on-the-Cyclone5-sockit.patch b/patches.socfpga/0006-ARM-dts-socfpga-Enable-QSPI-on-the-Cyclone5-sockit.patch
new file mode 100644
index 0000000..f6d1e75
--- /dev/null
+++ b/patches.socfpga/0006-ARM-dts-socfpga-Enable-QSPI-on-the-Cyclone5-sockit.patch
@@ -0,0 +1,46 @@
+From 72315cbb4c67745c94487884687e469cff71fa88 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Wed, 19 Oct 2016 14:55:54 -0500
+Subject: [PATCH 006/103] ARM: dts: socfpga: Enable QSPI on the Cyclone5 sockit
+
+Enable the QSPI node and add the flash chip.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+v3: Use n25q00 for the compatible entry for the flash part and
+    tested on SoCKit
+v2: Remove partition entries for the SoCKIT
+---
+ arch/arm/boot/dts/socfpga_cyclone5_sockit.dts |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+@@ -175,6 +175,27 @@
+ 	status = "okay";
+ };
+ 
++&qspi {
++	status = "okay";
++
++	flash: flash@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "n25q00";
++		reg = <0>;
++		spi-max-frequency = <100000000>;
++
++		m25p,fast-read;
++		cdns,page-size = <256>;
++		cdns,block-size = <16>;
++		cdns,read-delay = <4>;
++		cdns,tshsl-ns = <50>;
++		cdns,tsd2d-ns = <50>;
++		cdns,tchsh-ns = <4>;
++		cdns,tslch-ns = <4>;
++	};
++};
++
+ &usb1 {
+ 	status = "okay";
+ };
diff --git a/patches.socfpga/0007-ARM-dts-socfpga-Enable-QSPI-on-the-Arria5-devkit.patch b/patches.socfpga/0007-ARM-dts-socfpga-Enable-QSPI-on-the-Arria5-devkit.patch
new file mode 100644
index 0000000..4b18dbd
--- /dev/null
+++ b/patches.socfpga/0007-ARM-dts-socfpga-Enable-QSPI-on-the-Arria5-devkit.patch
@@ -0,0 +1,54 @@
+From b6010bd7a8f9436f60f0b07ea629b5607251f0b2 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@opensource.altera.com>
+Date: Wed, 19 Oct 2016 15:48:07 -0500
+Subject: [PATCH 007/103] ARM: dts: socfpga: Enable QSPI on the Arria5 devkit
+
+Enable the QSPI node and add the flash chip.
+
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria5_socdk.dts |   33 +++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+@@ -82,6 +82,39 @@
+ 	status = "okay";
+ };
+ 
++&qspi {
++	status = "okay";
++
++	flash: flash@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "n25q256a";
++		reg = <0>;
++		spi-max-frequency = <100000000>;
++
++		m25p,fast-read;
++		cdns,page-size = <256>;
++		cdns,block-size = <16>;
++		cdns,read-delay = <4>;
++		cdns,tshsl-ns = <50>;
++		cdns,tsd2d-ns = <50>;
++		cdns,tchsh-ns = <4>;
++		cdns,tslch-ns = <4>;
++
++		partition@qspi-boot {
++			/* 8MB for raw data. */
++			label = "Flash 0 Raw Data";
++			reg = <0x0 0x800000>;
++		};
++
++		partition@qspi-rootfs {
++			/* 120MB for jffs2 data. */
++			label = "Flash 0 jffs2 Filesystem";
++			reg = <0x800000 0x7800000>;
++		};
++	};
++};
++
+ &usb1 {
+ 	status = "okay";
+ };
diff --git a/patches.socfpga/0008-ARM-socfpga_defconfig-enable-FS-configs-to-support-A.patch b/patches.socfpga/0008-ARM-socfpga_defconfig-enable-FS-configs-to-support-A.patch
new file mode 100644
index 0000000..aa320e3
--- /dev/null
+++ b/patches.socfpga/0008-ARM-socfpga_defconfig-enable-FS-configs-to-support-A.patch
@@ -0,0 +1,40 @@
+From 81e36c3e01bbc9cbee6a3882b18d836667758d25 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 8 Nov 2016 15:01:22 -0600
+Subject: [PATCH 008/103] ARM: socfpga_defconfig: enable FS configs to support
+ Angstrom filesystem
+
+systemd on the Angstrom root file system expects AUTOFS to be configured
+as a module and NFSD to be statically linked into the kernel. This patch
+adds the necessary configuration to get rid two "FAILED" error messages
+during systemd startup.
+
+Signed-off-by: Matthew Gerlach <mgerlach@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+v2: provide a more descriptive changelog
+---
+ arch/arm/configs/socfpga_defconfig |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -107,13 +107,18 @@ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
+ CONFIG_EXT3_FS=y
++CONFIG_AUTOFS4_FS=y
+ CONFIG_VFAT_FS=y
+ CONFIG_NTFS_FS=y
+ CONFIG_NTFS_RW=y
+ CONFIG_TMPFS=y
+ CONFIG_CONFIGFS_FS=y
+ CONFIG_NFS_FS=y
++CONFIG_NFS_V3_ACL=y
+ CONFIG_ROOT_NFS=y
++CONFIG_NFSD=y
++CONFIG_NFSD_V3_ACL=y
++CONFIG_NFSD_V4=y
+ CONFIG_NLS_CODEPAGE_437=y
+ CONFIG_NLS_ISO8859_1=y
+ CONFIG_PRINTK_TIME=y
diff --git a/patches.socfpga/0009-dt-bindings-Add-Macnica-Americas-vendor-prefix.patch b/patches.socfpga/0009-dt-bindings-Add-Macnica-Americas-vendor-prefix.patch
new file mode 100644
index 0000000..1487c49
--- /dev/null
+++ b/patches.socfpga/0009-dt-bindings-Add-Macnica-Americas-vendor-prefix.patch
@@ -0,0 +1,24 @@
+From fdcef7128b2fcfa244e5b2ae5e2e323a819a2158 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 1 Nov 2016 10:36:30 -0500
+Subject: [PATCH 009/103] dt-bindings: Add Macnica Americas vendor prefix
+
+Add a vendor prefix for the Macnica company.
+http://http://www.macnica.com
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.txt |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
++++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
+@@ -158,6 +158,7 @@ lg	LG Corporation
+ linux	Linux-specific binding
+ lltc	Linear Technology Corporation
+ lsi	LSI Corp. (LSI Logic)
++macnica	Macnica Americas
+ marvell	Marvell Technology Group Ltd.
+ maxim	Maxim Integrated Products
+ meas	Measurement Specialties
diff --git a/patches.socfpga/0010-dt-bindings-Add-vendor-prefix-for-Terasic-Inc.patch b/patches.socfpga/0010-dt-bindings-Add-vendor-prefix-for-Terasic-Inc.patch
new file mode 100644
index 0000000..7a2ff47
--- /dev/null
+++ b/patches.socfpga/0010-dt-bindings-Add-vendor-prefix-for-Terasic-Inc.patch
@@ -0,0 +1,25 @@
+From 5ae491dadecfd37b8f00965ada793be6c230dddc Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 1 Nov 2016 10:36:31 -0500
+Subject: [PATCH 010/103] dt-bindings: Add vendor prefix for Terasic Inc.
+
+Add a vendor prefix for Terasic.
+
+http://www.terasic.com
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.txt |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
++++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
+@@ -276,6 +276,7 @@ tcg	Trusted Computing Group
+ tcl	Toby Churchill Ltd.
+ technexion	TechNexion
+ technologic	Technologic Systems
++terasic	Terasic Inc.
+ thine	THine Electronics, Inc.
+ ti	Texas Instruments
+ tlm	Trusted Logic Mobility
diff --git a/patches.socfpga/0011-dt-bindings-Add-vendor-prefix-for-Samtec.patch b/patches.socfpga/0011-dt-bindings-Add-vendor-prefix-for-Samtec.patch
new file mode 100644
index 0000000..d0eb1bf
--- /dev/null
+++ b/patches.socfpga/0011-dt-bindings-Add-vendor-prefix-for-Samtec.patch
@@ -0,0 +1,26 @@
+From 886e6363f55f9996be2c7f6e122fbd90fc01c85c Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 1 Nov 2016 10:36:32 -0500
+Subject: [PATCH 011/103] dt-bindings: Add vendor prefix for Samtec
+
+Add a vendor prefix for Samtec, a Softing company.
+
+http://www.samtec.de
+http://www.samtec.org
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/vendor-prefixes.txt |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
++++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
+@@ -232,6 +232,7 @@ richtek	Richtek Technology Corporation
+ ricoh	Ricoh Co. Ltd.
+ rockchip	Fuzhou Rockchip Electronics Co., Ltd
+ samsung	Samsung Semiconductor
++samtec	Samtec/Softing company
+ sandisk	Sandisk Corporation
+ sbs	Smart Battery System
+ schindler	Schindler
diff --git a/patches.socfpga/0012-ARM-dts-socfpga-enable-GPIO-and-LEDs-for-Cyclone5-an.patch b/patches.socfpga/0012-ARM-dts-socfpga-enable-GPIO-and-LEDs-for-Cyclone5-an.patch
new file mode 100644
index 0000000..861b736
--- /dev/null
+++ b/patches.socfpga/0012-ARM-dts-socfpga-enable-GPIO-and-LEDs-for-Cyclone5-an.patch
@@ -0,0 +1,117 @@
+From 68ba0c63510af673e2400895aaaa5a6c7c9ec622 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Mon, 12 Dec 2016 22:02:44 -0600
+Subject: [PATCH 012/103] ARM: dts: socfpga: enable GPIO and LEDs for Cyclone5
+ and Arria5 devkits
+
+Enable all the GPIO ports and define the GPIO-based leds on the Cyclone5 and
+Arria5 devkits.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria5_socdk.dts   |   35 +++++++++++++++++++++++++++
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts |   31 +++++++++++++++++++++++
+ 2 files changed, 66 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+@@ -39,6 +39,29 @@
+ 		ethernet0 = &gmac1;
+ 	};
+ 
++	leds {
++		compatible = "gpio-leds";
++		hps0 {
++			label = "hps_led0";
++			gpios = <&porta 0 1>;
++		};
++
++		hps1 {
++			label = "hps_led1";
++			gpios = <&portb 11 1>;
++		};
++
++		hps2 {
++			label = "hps_led2";
++			gpios = <&porta 17 1>;
++		};
++
++		hps3 {
++			label = "hps_led3";
++			gpios = <&porta 18 1>;
++		};
++	};
++
+ 	regulator_3_3v: 3-3-v-regulator {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "3.3V";
+@@ -61,6 +84,18 @@
+ 	rxc-skew-ps = <2000>;
+ };
+ 
++&gpio0 {
++	status = "okay";
++};
++
++&gpio1 {
++	status = "okay";
++};
++
++&gpio2 {
++	status = "okay";
++};
++
+ &i2c0 {
+ 	status = "okay";
+ 
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -39,6 +39,29 @@
+ 		ethernet0 = &gmac1;
+ 	};
+ 
++	leds {
++		compatible = "gpio-leds";
++		hps0 {
++			label = "hps_led0";
++			gpios = <&portb 15 1>;
++		};
++
++		hps1 {
++			label = "hps_led1";
++			gpios = <&portb 14 1>;
++		};
++
++		hps2 {
++			label = "hps_led2";
++			gpios = <&portb 13 1>;
++		};
++
++		hps3 {
++			label = "hps_led3";
++			gpios = <&portb 12 1>;
++		};
++	};
++
+ 	regulator_3_3v: 3-3-v-regulator {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "3.3V";
+@@ -61,10 +84,18 @@
+ 	rxc-skew-ps = <2000>;
+ };
+ 
++&gpio0 {
++	status = "okay";
++};
++
+ &gpio1 {
+ 	status = "okay";
+ };
+ 
++&gpio2 {
++	status = "okay";
++};
++
+ &i2c0 {
+ 	status = "okay";
+ 
diff --git a/patches.socfpga/0013-ARM-dts-socfpga-set-desired-i2c-clock-on-Cyclone5-an.patch b/patches.socfpga/0013-ARM-dts-socfpga-set-desired-i2c-clock-on-Cyclone5-an.patch
new file mode 100644
index 0000000..ebcff24
--- /dev/null
+++ b/patches.socfpga/0013-ARM-dts-socfpga-set-desired-i2c-clock-on-Cyclone5-an.patch
@@ -0,0 +1,50 @@
+From bae526e301c40e073379cbcf7d8239905ffcaf7f Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 13 Dec 2016 16:52:11 -0600
+Subject: [PATCH 013/103] ARM: dts: socfpga: set desired i2c clock on Cyclone5
+ and Arria5 devkits
+
+The I2C LCD display on the Cyclone5 and Arria5 devkits is only capable of
+the standard 100 kHz clock. Set the "clock-frequency" of the I2C node
+to be 100000.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria5_socdk.dts   |    8 ++++++++
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts |    8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+@@ -98,6 +98,14 @@
+ 
+ &i2c0 {
+ 	status = "okay";
++	clock-frequency = <100000>;
++
++	/*
++	 * adjust the falling times to decrease the i2c frequency to 50Khz
++	 * because the LCD module does not work at the standard 100Khz
++	 */
++	i2c-sda-falling-time-ns = <5000>;
++	i2c-scl-falling-time-ns = <5000>;
+ 
+ 	eeprom@51 {
+ 		compatible = "atmel,24c32";
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -98,6 +98,14 @@
+ 
+ &i2c0 {
+ 	status = "okay";
++	clock-frequency = <100000>;
++
++	/*
++	 * adjust the falling times to decrease the i2c frequency to 50Khz
++	 * because the LCD module does not work at the standard 100Khz
++	 */
++	i2c-sda-falling-time-ns = <5000>;
++	i2c-scl-falling-time-ns = <5000>;
+ 
+ 	eeprom@51 {
+ 		compatible = "atmel,24c32";
diff --git a/patches.socfpga/0014-ARM-dts-socfpga-Add-Rohm-DH2228FV-DAC.patch b/patches.socfpga/0014-ARM-dts-socfpga-Add-Rohm-DH2228FV-DAC.patch
new file mode 100644
index 0000000..4f3e40f
--- /dev/null
+++ b/patches.socfpga/0014-ARM-dts-socfpga-Add-Rohm-DH2228FV-DAC.patch
@@ -0,0 +1,31 @@
+From 3f5e1bdb1957578c511107b2e4bef7c5d287b1bc Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Thu, 15 Dec 2016 23:30:03 -0600
+Subject: [PATCH 014/103] ARM: dts: socfpga: Add Rohm DH2228FV DAC
+
+Enable the SPI node and add the Rohm DH2228FV DAC.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -159,6 +159,16 @@
+ 	};
+ };
+ 
++&spi0 {
++	status = "okay";
++
++	spidev@0 {
++		compatible = "rohm,dh2228fv";
++		reg = <0>;
++		spi-max-frequency = <1000000>;
++	};
++};
++
+ &usb1 {
+ 	status = "okay";
+ };
diff --git a/patches.socfpga/0015-ARM-dts-socfpga-enable-CAN-on-Cyclone5-devkit.patch b/patches.socfpga/0015-ARM-dts-socfpga-enable-CAN-on-Cyclone5-devkit.patch
new file mode 100644
index 0000000..38c7c17
--- /dev/null
+++ b/patches.socfpga/0015-ARM-dts-socfpga-enable-CAN-on-Cyclone5-devkit.patch
@@ -0,0 +1,25 @@
+From 70fa6f9a9bf3bbdcb24f77876dd3787986c4623a Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Fri, 16 Dec 2016 16:55:44 -0600
+Subject: [PATCH 015/103] ARM: dts: socfpga: enable CAN on Cyclone5 devkit
+
+Enable the CAN node on the Cyclone5 devkit.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -70,6 +70,10 @@
+ 	};
+ };
+ 
++&can0 {
++	status = "okay";
++};
++
+ &gmac1 {
+ 	status = "okay";
+ 	phy-mode = "rgmii";
diff --git a/patches.socfpga/0016-ARM-dts-socfpga-enable-watchdog-timer-on-Arria5-and-.patch b/patches.socfpga/0016-ARM-dts-socfpga-enable-watchdog-timer-on-Arria5-and-.patch
new file mode 100644
index 0000000..136e3cf
--- /dev/null
+++ b/patches.socfpga/0016-ARM-dts-socfpga-enable-watchdog-timer-on-Arria5-and-.patch
@@ -0,0 +1,34 @@
+From 6442fc6873b15415fce505c7dbc3a8e824bb8163 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Fri, 16 Dec 2016 17:15:00 -0600
+Subject: [PATCH 016/103] ARM: dts: socfpga: enable watchdog timer on Arria5
+ and Arria10
+
+Enable the watchdog for Arria5 and Arria10.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |    4 ++++
+ arch/arm/boot/dts/socfpga_arria5.dtsi        |    4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -105,3 +105,7 @@
+ &usb0 {
+ 	status = "okay";
+ };
++
++&watchdog0 {
++	status = "okay";
++};
+--- a/arch/arm/boot/dts/socfpga_arria5.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria5.dtsi
+@@ -42,3 +42,7 @@
+ 		};
+ 	};
+ };
++
++&watchdog0 {
++	status = "okay";
++};
diff --git a/patches.socfpga/0017-ARM-dts-socfpga-add-the-LTC2977-power-monitor-on-Arr.patch b/patches.socfpga/0017-ARM-dts-socfpga-add-the-LTC2977-power-monitor-on-Arr.patch
new file mode 100644
index 0000000..656fbdc
--- /dev/null
+++ b/patches.socfpga/0017-ARM-dts-socfpga-add-the-LTC2977-power-monitor-on-Arr.patch
@@ -0,0 +1,27 @@
+From b8ccfd2af325b1bb2cc3fa70cd688850a32e6a54 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Sat, 17 Dec 2016 21:42:32 -0600
+Subject: [PATCH 017/103] ARM: dts: socfpga: add the LTC2977 power monitor on
+ Arria10 devkit
+
+Add the I2C LTC 2977 power monitor that is on the Arria10 devkit.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -96,6 +96,11 @@
+ 		compatible = "dallas,ds1339";
+ 		reg = <0x68>;
+ 	};
++
++	ltc@5c {
++		compatible = "ltc2977";
++		reg = <0x5c>;
++	};
+ };
+ 
+ &uart1 {
diff --git a/patches.socfpga/0018-ARM-dts-socfpga-add-fpga-manager-node-for-Arria10.patch b/patches.socfpga/0018-ARM-dts-socfpga-add-fpga-manager-node-for-Arria10.patch
new file mode 100644
index 0000000..252f94d
--- /dev/null
+++ b/patches.socfpga/0018-ARM-dts-socfpga-add-fpga-manager-node-for-Arria10.patch
@@ -0,0 +1,30 @@
+From f968f1aa6c67873082498738e7756e2311eac0af Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Sat, 17 Dec 2016 22:45:03 -0600
+Subject: [PATCH 018/103] ARM: dts: socfpga: add fpga-manager node for Arria10
+
+Add the FPGA manger DTS entry for Arria10.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10.dtsi |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -512,6 +512,15 @@
+ 			};
+ 		};
+ 
++		fpga_mgr: fpga-mgr@ffd03000 {
++			compatible = "altr,socfpga-a10-fpga-mgr";
++			reg = <0xffd03000 0x100
++			       0xffcfe400 0x20>;
++			clocks = <&l4_mp_clk>;
++			resets = <&rst FPGAMGR_RESET>;
++			reset-names = "fpgamgr";
++		};
++
+ 		i2c0: i2c@ffc02200 {
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
diff --git a/patches.socfpga/0019-ARM-dts-socfpga-fpga-manager-data-is-32-bits.patch b/patches.socfpga/0019-ARM-dts-socfpga-fpga-manager-data-is-32-bits.patch
new file mode 100644
index 0000000..0be678f
--- /dev/null
+++ b/patches.socfpga/0019-ARM-dts-socfpga-fpga-manager-data-is-32-bits.patch
@@ -0,0 +1,26 @@
+From 5a87081d681bad5b577d1fe2a2a83021cfca989f Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Mon, 19 Dec 2016 22:34:00 -0600
+Subject: [PATCH 019/103] ARM: dts: socfpga: fpga manager data is 32 bits
+
+Adjust regs property for the FPGA manager data register to
+properly reflect that it is a single 32 bit register.
+
+Signed-off-by: Dalon Westergreen <dwesterg@altera.com>
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga.dtsi |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/socfpga.dtsi
++++ b/arch/arm/boot/dts/socfpga.dtsi
+@@ -516,7 +516,7 @@
+ 		fpgamgr0: fpgamgr@ff706000 {
+ 			compatible = "altr,socfpga-fpga-mgr";
+ 			reg = <0xff706000 0x1000
+-			       0xffb90000 0x1000>;
++			       0xffb90000 0x4>;
+ 			interrupts = <0 175 4>;
+ 		};
+ 
diff --git a/patches.socfpga/0020-ARM-dts-socfpga-add-fpga-region-support-on-Arria10.patch b/patches.socfpga/0020-ARM-dts-socfpga-add-fpga-region-support-on-Arria10.patch
new file mode 100644
index 0000000..273ebb6
--- /dev/null
+++ b/patches.socfpga/0020-ARM-dts-socfpga-add-fpga-region-support-on-Arria10.patch
@@ -0,0 +1,31 @@
+From f534c9a2d107eb6255532f19decc1dde219a25e7 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Mon, 19 Dec 2016 23:21:27 -0600
+Subject: [PATCH 020/103] ARM: dts: socfpga: add fpga region support on Arria10
+
+Add the base FPGA region for DT overlay support in FPGA programming.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Matthew Gerlach <mgerlach@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10.dtsi |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -83,6 +83,14 @@
+ 			};
+ 		};
+ 
++		base_fpga_region {
++			#address-cells = <0x1>;
++			#size-cells = <0x1>;
++
++			compatible = "fpga-region";
++			fpga-mgr = <&fpga_mgr>;
++		};
++
+ 		clkmgr@ffd04000 {
+ 				compatible = "altr,clk-mgr";
+ 				reg = <0xffd04000 0x1000>;
diff --git a/patches.socfpga/0021-ARM-dts-socfpga-add-missing-compatible-string-for-SD.patch b/patches.socfpga/0021-ARM-dts-socfpga-add-missing-compatible-string-for-SD.patch
new file mode 100644
index 0000000..ce6c180
--- /dev/null
+++ b/patches.socfpga/0021-ARM-dts-socfpga-add-missing-compatible-string-for-SD.patch
@@ -0,0 +1,36 @@
+From 36760f8265fe47bc7176a58aa85ca6c3ec59f812 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 20 Dec 2016 00:01:48 -0600
+Subject: [PATCH 021/103] ARM: dts: socfpga: add missing compatible string for
+ SDRAM controller
+
+Add "altr,sdr-ctl" to the SDRAM controller node.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga.dtsi         |    2 +-
+ arch/arm/boot/dts/socfpga_arria10.dtsi |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/socfpga.dtsi
++++ b/arch/arm/boot/dts/socfpga.dtsi
+@@ -719,7 +719,7 @@
+ 		};
+ 
+ 		sdr: sdr@ffc25000 {
+-			compatible = "syscon";
++			compatible = "altr,sdr-ctl", "syscon";
+ 			reg = <0xffc25000 0x1000>;
+ 		};
+ 
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -580,7 +580,7 @@
+ 		};
+ 
+ 		sdr: sdr@ffc25000 {
+-			compatible = "syscon";
++			compatible = "altr,sdr-ctl", "syscon";
+ 			reg = <0xffcfb100 0x80>;
+ 		};
+ 
diff --git a/patches.socfpga/0022-ARM-dts-watchdog0-cannot-reliably-trigger-reset.patch b/patches.socfpga/0022-ARM-dts-watchdog0-cannot-reliably-trigger-reset.patch
new file mode 100644
index 0000000..38c6f1e
--- /dev/null
+++ b/patches.socfpga/0022-ARM-dts-watchdog0-cannot-reliably-trigger-reset.patch
@@ -0,0 +1,28 @@
+From 22f774c2c8c6b463883e3cbada27b5b74155b121 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Wed, 25 Jan 2017 10:01:28 -0600
+Subject: [PATCH 022/103] ARM: dts: watchdog0 cannot reliably trigger reset
+
+On the Arria10, because of hardware bug, watchdog0 cannot reliably trigger
+a reset to the CPU. The workaround would be to use watchdog1 instead.
+
+Also for watchdog1, there is a dependency on the bootloader to enable the
+boot_clk source to be from the cb_intosc_hs_clk/2, versus from EOSC1. This
+corresponds to the (SWCTRLBTCLKEN & SWCTRLBTCLKSEL) bits enabled in the
+control register in the clock manager module of Arria10.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -111,6 +111,6 @@
+ 	status = "okay";
+ };
+ 
+-&watchdog0 {
++&watchdog1 {
+ 	status = "okay";
+ };
diff --git a/patches.socfpga/0023-MAINTAINERS-socfpga-update-email-for-Dinh-Nguyen.patch b/patches.socfpga/0023-MAINTAINERS-socfpga-update-email-for-Dinh-Nguyen.patch
new file mode 100644
index 0000000..0aa0b17
--- /dev/null
+++ b/patches.socfpga/0023-MAINTAINERS-socfpga-update-email-for-Dinh-Nguyen.patch
@@ -0,0 +1,33 @@
+From bd1f3567243bb08db75c610e7475968b2dec1373 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Fri, 3 Feb 2017 09:29:07 -0600
+Subject: [PATCH 023/103] MAINTAINERS: socfpga: update email for Dinh Nguyen
+
+My opensource.altera.com email will be going away soon.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ MAINTAINERS |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1751,7 +1751,7 @@ F:	drivers/soc/renesas/
+ F:	include/linux/soc/renesas/
+ 
+ ARM/SOCFPGA ARCHITECTURE
+-M:	Dinh Nguyen <dinguyen@opensource.altera.com>
++M:	Dinh Nguyen <dinguyen@kernel.org>
+ S:	Maintained
+ F:	arch/arm/mach-socfpga/
+ F:	arch/arm/boot/dts/socfpga*
+@@ -1761,7 +1761,7 @@ W:	http://www.rocketboards.org
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
+ 
+ ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT
+-M:	Dinh Nguyen <dinguyen@opensource.altera.com>
++M:	Dinh Nguyen <dinguyen@kernel.org>
+ S:	Maintained
+ F:	drivers/clk/socfpga/
+ 
diff --git a/patches.socfpga/0024-of-overlay-add-of-overlay-notifications.patch b/patches.socfpga/0024-of-overlay-add-of-overlay-notifications.patch
new file mode 100644
index 0000000..bc47fd3
--- /dev/null
+++ b/patches.socfpga/0024-of-overlay-add-of-overlay-notifications.patch
@@ -0,0 +1,175 @@
+From 34c5493a5611f3c1481d98767657ead412c55c18 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:22 -0500
+Subject: [PATCH 024/103] of/overlay: add of overlay notifications
+
+This patch add of overlay notifications.
+
+When DT overlays are being added, some drivers/subsystems
+need to see device tree overlays before the changes go into
+the live tree.
+
+This is distinct from reconfig notifiers that are
+post-apply or post-remove and which issue very granular
+notifications without providing access to the context
+of a whole overlay.
+
+The following 4 notificatons are issued:
+  OF_OVERLAY_PRE_APPLY
+  OF_OVERLAY_POST_APPLY
+  OF_OVERLAY_PRE_REMOVE
+  OF_OVERLAY_POST_REMOVE
+
+In the case of pre-apply notification, if the notifier
+returns error, the overlay will be rejected.
+
+This patch exports two functions for registering/unregistering
+notifications:
+  of_overlay_notifier_register(struct notifier_block *nb)
+  of_overlay_notifier_unregister(struct notifier_block *nb)
+
+The of_mutex is held during these notifications. The
+notification data includes pointers to the overlay target
+and the overlay:
+
+struct of_overlay_notify_data {
+       struct device_node *overlay;
+       struct device_node *target;
+};
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/of/overlay.c |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/of.h   |   25 +++++++++++++++++++++++++
+ 2 files changed, 71 insertions(+), 1 deletion(-)
+
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -58,6 +58,41 @@ struct of_overlay {
+ static int of_overlay_apply_one(struct of_overlay *ov,
+ 		struct device_node *target, const struct device_node *overlay);
+ 
++static BLOCKING_NOTIFIER_HEAD(of_overlay_chain);
++
++int of_overlay_notifier_register(struct notifier_block *nb)
++{
++	return blocking_notifier_chain_register(&of_overlay_chain, nb);
++}
++EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
++
++int of_overlay_notifier_unregister(struct notifier_block *nb)
++{
++	return blocking_notifier_chain_unregister(&of_overlay_chain, nb);
++}
++EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister);
++
++static int of_overlay_notify(struct of_overlay *ov,
++			     enum of_overlay_notify_action action)
++{
++	struct of_overlay_notify_data nd;
++	int i, ret;
++
++	for (i = 0; i < ov->count; i++) {
++		struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i];
++
++		nd.target = ovinfo->target;
++		nd.overlay = ovinfo->overlay;
++
++		ret = blocking_notifier_call_chain(&of_overlay_chain,
++						   action, &nd);
++		if (ret)
++			return notifier_to_errno(ret);
++	}
++
++	return 0;
++}
++
+ static int of_overlay_apply_single_property(struct of_overlay *ov,
+ 		struct device_node *target, struct property *prop)
+ {
+@@ -368,6 +403,13 @@ int of_overlay_create(struct device_node
+ 		goto err_free_idr;
+ 	}
+ 
++	err = of_overlay_notify(ov, OF_OVERLAY_PRE_APPLY);
++	if (err < 0) {
++		pr_err("%s: Pre-apply notifier failed (err=%d)\n",
++		       __func__, err);
++		goto err_free_idr;
++	}
++
+ 	/* apply the overlay */
+ 	err = of_overlay_apply(ov);
+ 	if (err)
+@@ -382,6 +424,8 @@ int of_overlay_create(struct device_node
+ 	/* add to the tail of the overlay list */
+ 	list_add_tail(&ov->node, &ov_list);
+ 
++	of_overlay_notify(ov, OF_OVERLAY_POST_APPLY);
++
+ 	mutex_unlock(&of_mutex);
+ 
+ 	return id;
+@@ -498,9 +542,10 @@ int of_overlay_destroy(int id)
+ 		goto out;
+ 	}
+ 
+-
++	of_overlay_notify(ov, OF_OVERLAY_PRE_REMOVE);
+ 	list_del(&ov->node);
+ 	__of_changeset_revert(&ov->cset);
++	of_overlay_notify(ov, OF_OVERLAY_POST_REMOVE);
+ 	of_free_overlay_info(ov);
+ 	idr_remove(&ov_idr, id);
+ 	of_changeset_destroy(&ov->cset);
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -1266,6 +1266,18 @@ static inline bool of_device_is_system_p
+  * Overlay support
+  */
+ 
++enum of_overlay_notify_action {
++	OF_OVERLAY_PRE_APPLY,
++	OF_OVERLAY_POST_APPLY,
++	OF_OVERLAY_PRE_REMOVE,
++	OF_OVERLAY_POST_REMOVE,
++};
++
++struct of_overlay_notify_data {
++	struct device_node *overlay;
++	struct device_node *target;
++};
++
+ #ifdef CONFIG_OF_OVERLAY
+ 
+ /* ID based overlays; the API for external users */
+@@ -1273,6 +1285,9 @@ int of_overlay_create(struct device_node
+ int of_overlay_destroy(int id);
+ int of_overlay_destroy_all(void);
+ 
++int of_overlay_notifier_register(struct notifier_block *nb);
++int of_overlay_notifier_unregister(struct notifier_block *nb);
++
+ #else
+ 
+ static inline int of_overlay_create(struct device_node *tree)
+@@ -1290,6 +1305,16 @@ static inline int of_overlay_destroy_all
+ 	return -ENOTSUPP;
+ }
+ 
++static inline int of_overlay_notifier_register(struct notifier_block *nb)
++{
++	return 0;
++}
++
++static inline int of_overlay_notifier_unregister(struct notifier_block *nb)
++{
++	return 0;
++}
++
+ #endif
+ 
+ #endif /* _LINUX_OF_H */
diff --git a/patches.socfpga/0025-fpga-add-method-to-get-fpga-manager-from-device.patch b/patches.socfpga/0025-fpga-add-method-to-get-fpga-manager-from-device.patch
new file mode 100644
index 0000000..a671185
--- /dev/null
+++ b/patches.socfpga/0025-fpga-add-method-to-get-fpga-manager-from-device.patch
@@ -0,0 +1,159 @@
+From 6cc9e7b146fc8e24e1ca6b7ae0b0e27ca6cc3fae Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:23 -0500
+Subject: [PATCH 025/103] fpga: add method to get fpga manager from device
+
+The intent is to provide a non-DT method of getting
+ahold of a FPGA manager to do some FPGA programming.
+
+This patch refactors of_fpga_mgr_get() to reuse most of it
+while adding a new method fpga_mgr_get() for getting a
+pointer to a fpga manager struct, given the device.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/fpga/fpga-mgr.txt |    6 ++-
+ drivers/fpga/fpga-mgr.c         |   76 ++++++++++++++++++++++++++++------------
+ include/linux/fpga/fpga-mgr.h   |    2 +
+ 3 files changed, 60 insertions(+), 24 deletions(-)
+
+--- a/Documentation/fpga/fpga-mgr.txt
++++ b/Documentation/fpga/fpga-mgr.txt
+@@ -38,11 +38,13 @@ To get/put a reference to a FPGA manager
+ -----------------------------------------
+ 
+ 	struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
++	struct fpga_manager *fpga_mgr_get(struct device *dev);
++
++Given a DT node or device, get an exclusive reference to a FPGA manager.
+ 
+ 	void fpga_mgr_put(struct fpga_manager *mgr);
+ 
+-Given a DT node, get an exclusive reference to a FPGA manager or release
+-the reference.
++Release the reference.
+ 
+ 
+ To register or unregister the low level FPGA-specific driver:
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -39,7 +39,8 @@ static struct class *fpga_mgr_class;
+  * Step the low level fpga manager through the device-specific steps of getting
+  * an FPGA ready to be configured, writing the image to it, then doing whatever
+  * post-configuration steps necessary.  This code assumes the caller got the
+- * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.
++ * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is
++ * not an error code.
+  *
+  * Return: 0 on success, negative error code otherwise.
+  */
+@@ -99,7 +100,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
+  * Request an FPGA image using the firmware class, then write out to the FPGA.
+  * Update the state before each step to provide info on what step failed if
+  * there is a failure.  This code assumes the caller got the mgr pointer
+- * from of_fpga_mgr_get() and checked that it is not an error code.
++ * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error
++ * code.
+  *
+  * Return: 0 on success, negative error code otherwise.
+  */
+@@ -181,30 +183,11 @@ static struct attribute *fpga_mgr_attrs[
+ };
+ ATTRIBUTE_GROUPS(fpga_mgr);
+ 
+-static int fpga_mgr_of_node_match(struct device *dev, const void *data)
+-{
+-	return dev->of_node == data;
+-}
+-
+-/**
+- * of_fpga_mgr_get - get an exclusive reference to a fpga mgr
+- * @node:	device node
+- *
+- * Given a device node, get an exclusive reference to a fpga mgr.
+- *
+- * Return: fpga manager struct or IS_ERR() condition containing error code.
+- */
+-struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
++struct fpga_manager *__fpga_mgr_get(struct device *dev)
+ {
+ 	struct fpga_manager *mgr;
+-	struct device *dev;
+ 	int ret = -ENODEV;
+ 
+-	dev = class_find_device(fpga_mgr_class, NULL, node,
+-				fpga_mgr_of_node_match);
+-	if (!dev)
+-		return ERR_PTR(-ENODEV);
+-
+ 	mgr = to_fpga_manager(dev);
+ 	if (!mgr)
+ 		goto err_dev;
+@@ -226,6 +209,55 @@ err_dev:
+ 	put_device(dev);
+ 	return ERR_PTR(ret);
+ }
++
++static int fpga_mgr_dev_match(struct device *dev, const void *data)
++{
++	return dev->parent == data;
++}
++
++/**
++ * fpga_mgr_get - get an exclusive reference to a fpga mgr
++ * @dev:	parent device that fpga mgr was registered with
++ *
++ * Given a device, get an exclusive reference to a fpga mgr.
++ *
++ * Return: fpga manager struct or IS_ERR() condition containing error code.
++ */
++struct fpga_manager *fpga_mgr_get(struct device *dev)
++{
++	struct device *mgr_dev = class_find_device(fpga_mgr_class, NULL, dev,
++						   fpga_mgr_dev_match);
++	if (!mgr_dev)
++		return ERR_PTR(-ENODEV);
++
++	return __fpga_mgr_get(mgr_dev);
++}
++EXPORT_SYMBOL_GPL(fpga_mgr_get);
++
++static int fpga_mgr_of_node_match(struct device *dev, const void *data)
++{
++	return dev->of_node == data;
++}
++
++/**
++ * of_fpga_mgr_get - get an exclusive reference to a fpga mgr
++ * @node:	device node
++ *
++ * Given a device node, get an exclusive reference to a fpga mgr.
++ *
++ * Return: fpga manager struct or IS_ERR() condition containing error code.
++ */
++struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
++{
++	struct device *dev;
++
++	dev = class_find_device(fpga_mgr_class, NULL, node,
++				fpga_mgr_of_node_match);
++	if (!dev)
++		return ERR_PTR(-ENODEV);
++
++	return __fpga_mgr_get(dev);
++}
+ EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
+ 
+ /**
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -117,6 +117,8 @@ int fpga_mgr_firmware_load(struct fpga_m
+ 
+ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
+ 
++struct fpga_manager *fpga_mgr_get(struct device *dev);
++
+ void fpga_mgr_put(struct fpga_manager *mgr);
+ 
+ int fpga_mgr_register(struct device *dev, const char *name,
diff --git a/patches.socfpga/0026-doc-fpga-mgr-add-fpga-image-info-to-api.patch b/patches.socfpga/0026-doc-fpga-mgr-add-fpga-image-info-to-api.patch
new file mode 100644
index 0000000..f7b3d35
--- /dev/null
+++ b/patches.socfpga/0026-doc-fpga-mgr-add-fpga-image-info-to-api.patch
@@ -0,0 +1,110 @@
+From d4a7acc57d114fb9b54dd9dd9a21465393bb90e8 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:24 -0500
+Subject: [PATCH 026/103] doc: fpga-mgr: add fpga image info to api
+
+This patch adds a minor change in the FPGA Manager API
+to hold information that is specific to an FPGA image
+file.  This change is expected to bring little, if any,
+pain.
+
+An FPGA image file will have particulars that affect how the
+image is programmed to the FPGA.  One example is that
+current 'flags' currently has one bit which shows whether the
+FPGA image was built for full reconfiguration or partial
+reconfiguration.  Another example is timeout values for
+enabling or disabling the bridges in the FPGA.  As the
+complexity of the FPGA design increases, the bridges in the
+FPGA may take longer times to enable or disable.
+
+This patch documents the change in the FPGA Manager API
+functions, replacing the 'u32 flag' parameter with a pointer
+to struct fpga_image_info.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/fpga/fpga-mgr.txt |   34 ++++++++++++++++++++++------------
+ 1 file changed, 22 insertions(+), 12 deletions(-)
+
+--- a/Documentation/fpga/fpga-mgr.txt
++++ b/Documentation/fpga/fpga-mgr.txt
+@@ -18,21 +18,25 @@ API Functions:
+ To program the FPGA from a file or from a buffer:
+ -------------------------------------------------
+ 
+-	int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags,
++	int fpga_mgr_buf_load(struct fpga_manager *mgr,
++			      struct fpga_image_info *info,
+ 		              const char *buf, size_t count);
+ 
+ Load the FPGA from an image which exists as a buffer in memory.
+ 
+-	int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
++	int fpga_mgr_firmware_load(struct fpga_manager *mgr,
++				   struct fpga_image_info *info,
+ 		                   const char *image_name);
+ 
+ Load the FPGA from an image which exists as a file.  The image file must be on
+-the firmware search path (see the firmware class documentation).
+-
+-For both these functions, flags == 0 for normal full reconfiguration or
+-FPGA_MGR_PARTIAL_RECONFIG for partial reconfiguration.  If successful, the FPGA
+-ends up in operating mode.  Return 0 on success or a negative error code.
+-
++the firmware search path (see the firmware class documentation).  If successful,
++the FPGA ends up in operating mode.  Return 0 on success or a negative error
++code.
++
++A FPGA design contained in a FPGA image file will likely have particulars that
++affect how the image is programmed to the FPGA.  These are contained in struct
++fpga_image_info.  Currently the only such particular is a single flag bit
++indicating whether the image is for full or partial reconfiguration.
+ 
+ To get/put a reference to a FPGA manager:
+ -----------------------------------------
+@@ -72,8 +76,11 @@ struct device_node *mgr_node = ...
+ char *buf = ...
+ int count = ...
+ 
++/* struct with information about the FPGA image to program. */
++struct fpga_image_info info;
++
+ /* flags indicates whether to do full or partial reconfiguration */
+-int flags = 0;
++info.flags = 0;
+ 
+ int ret;
+ 
+@@ -81,7 +88,7 @@ int ret;
+ struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
+ 
+ /* Load the buffer to the FPGA */
+-ret = fpga_mgr_buf_load(mgr, flags, buf, count);
++ret = fpga_mgr_buf_load(mgr, &info, buf, count);
+ 
+ /* Release the FPGA manager */
+ fpga_mgr_put(mgr);
+@@ -98,8 +105,11 @@ struct device_node *mgr_node = ...
+ /* FPGA image is in this file which is in the firmware search path */
+ const char *path = "fpga-image-9.rbf"
+ 
++/* struct with information about the FPGA image to program. */
++struct fpga_image_info info;
++
+ /* flags indicates whether to do full or partial reconfiguration */
+-int flags = 0;
++info.flags = 0;
+ 
+ int ret;
+ 
+@@ -107,7 +117,7 @@ int ret;
+ struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
+ 
+ /* Get the firmware image (path) and load it to the FPGA */
+-ret = fpga_mgr_firmware_load(mgr, flags, path);
++ret = fpga_mgr_firmware_load(mgr, &info, path);
+ 
+ /* Release the FPGA manager */
+ fpga_mgr_put(mgr);
diff --git a/patches.socfpga/0027-fpga-add-bindings-document-for-fpga-region.patch b/patches.socfpga/0027-fpga-add-bindings-document-for-fpga-region.patch
new file mode 100644
index 0000000..78d970c
--- /dev/null
+++ b/patches.socfpga/0027-fpga-add-bindings-document-for-fpga-region.patch
@@ -0,0 +1,514 @@
+From a3f533d02f5643af9679ef50d4a2ea24d4766924 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:25 -0500
+Subject: [PATCH 027/103] fpga: add bindings document for fpga region
+
+New bindings document for FPGA Region to support programming
+FPGA's under Device Tree control
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/fpga/fpga-region.txt |  494 +++++++++++++++++
+ 1 file changed, 494 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/fpga-region.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt
+@@ -0,0 +1,494 @@
++FPGA Region Device Tree Binding
++
++Alan Tull 2016
++
++ CONTENTS
++ - Introduction
++ - Terminology
++ - Sequence
++ - FPGA Region
++ - Supported Use Models
++ - Device Tree Examples
++ - Constraints
++
++
++Introduction
++============
++
++FPGA Regions represent FPGA's and partial reconfiguration regions of FPGA's in
++the Device Tree.  FPGA Regions provide a way to program FPGAs under device tree
++control.
++
++This device tree binding document hits some of the high points of FPGA usage and
++attempts to include terminology used by both major FPGA manufacturers.  This
++document isn't a replacement for any manufacturers specifications for FPGA
++usage.
++
++
++Terminology
++===========
++
++Full Reconfiguration
++ * The entire FPGA is programmed.
++
++Partial Reconfiguration (PR)
++ * A section of an FPGA is reprogrammed while the rest of the FPGA is not
++   affected.
++ * Not all FPGA's support PR.
++
++Partial Reconfiguration Region (PRR)
++ * Also called a "reconfigurable partition"
++ * A PRR is a specific section of a FPGA reserved for reconfiguration.
++ * A base (or static) FPGA image may create a set of PRR's that later may
++   be independently reprogrammed many times.
++ * The size and specific location of each PRR is fixed.
++ * The connections at the edge of each PRR are fixed.  The image that is loaded
++   into a PRR must fit and must use a subset of the region's connections.
++ * The busses within the FPGA are split such that each region gets its own
++   branch that may be gated independently.
++
++Persona
++ * Also called a "partial bit stream"
++ * An FPGA image that is designed to be loaded into a PRR.  There may be
++   any number of personas designed to fit into a PRR, but only one at at time
++   may be loaded.
++ * A persona may create more regions.
++
++FPGA Bridge
++ * FPGA Bridges gate bus signals between a host and FPGA.
++ * FPGA Bridges should be disabled while the FPGA is being programmed to
++   prevent spurious signals on the cpu bus and to the soft logic.
++ * FPGA bridges may be actual hardware or soft logic on an FPGA.
++ * During Full Reconfiguration, hardware bridges between the host and FPGA
++   will be disabled.
++ * During Partial Reconfiguration of a specific region, that region's bridge
++   will be used to gate the busses.  Traffic to other regions is not affected.
++ * In some implementations, the FPGA Manager transparantly handles gating the
++   buses, eliminating the need to show the hardware FPGA bridges in the
++   device tree.
++ * An FPGA image may create a set of reprogrammable regions, each having its
++   own bridge and its own split of the busses in the FPGA.
++
++FPGA Manager
++ * An FPGA Manager is a hardware block that programs an FPGA under the control
++   of a host processor.
++
++Base Image
++ * Also called the "static image"
++ * An FPGA image that is designed to do full reconfiguration of the FPGA.
++ * A base image may set up a set of partial reconfiguration regions that may
++   later be reprogrammed.
++
++    ----------------       ----------------------------------
++    |  Host CPU    |       |             FPGA               |
++    |              |       |                                |
++    |          ----|       |       -----------    --------  |
++    |          | H |       |   |==>| Bridge0 |<==>| PRR0 |  |
++    |          | W |       |   |   -----------    --------  |
++    |          |   |       |   |                            |
++    |          | B |<=====>|<==|   -----------    --------  |
++    |          | R |       |   |==>| Bridge1 |<==>| PRR1 |  |
++    |          | I |       |   |   -----------    --------  |
++    |          | D |       |   |                            |
++    |          | G |       |   |   -----------    --------  |
++    |          | E |       |   |==>| Bridge2 |<==>| PRR2 |  |
++    |          ----|       |       -----------    --------  |
++    |              |       |                                |
++    ----------------       ----------------------------------
++
++Figure 1: An FPGA set up with a base image that created three regions.  Each
++region (PRR0-2) gets its own split of the busses that is independently gated by
++a soft logic bridge (Bridge0-2) in the FPGA.  The contents of each PRR can be
++reprogrammed independently while the rest of the system continues to function.
++
++
++Sequence
++========
++
++When a DT overlay that targets a FPGA Region is applied, the FPGA Region will
++do the following:
++
++ 1. Disable appropriate FPGA bridges.
++ 2. Program the FPGA using the FPGA manager.
++ 3. Enable the FPGA bridges.
++ 4. The Device Tree overlay is accepted into the live tree.
++ 5. Child devices are populated.
++
++When the overlay is removed, the child nodes will be removed and the FPGA Region
++will disable the bridges.
++
++
++FPGA Region
++===========
++
++FPGA Regions represent FPGA's and FPGA PR regions in the device tree.  An FPGA
++Region brings together the elements needed to program on a running system and
++add the child devices:
++
++ * FPGA Manager
++ * FPGA Bridges
++ * image-specific information needed to to the programming.
++ * child nodes
++
++The intended use is that a Device Tree overlay (DTO) can be used to reprogram an
++FPGA while an operating system is running.
++
++An FPGA Region that exists in the live Device Tree reflects the current state.
++If the live tree shows a "firmware-name" property or child nodes under a FPGA
++Region, the FPGA already has been programmed.  A DTO that targets a FPGA Region
++and adds the "firmware-name" property is taken as a request to reprogram the
++FPGA.  After reprogramming is successful, the overlay is accepted into the live
++tree.
++
++The base FPGA Region in the device tree represents the FPGA and supports full
++reconfiguration.  It must include a phandle to an FPGA Manager.  The base
++FPGA region will be the child of one of the hardware bridges (the bridge that
++allows register access) between the cpu and the FPGA.  If there are more than
++one bridge to control during FPGA programming, the region will also contain a
++list of phandles to the additional hardware FPGA Bridges.
++
++For partial reconfiguration (PR), each PR region will have an FPGA Region.
++These FPGA regions are children of FPGA bridges which are then children of the
++base FPGA region.  The "Full Reconfiguration to add PRR's" example below shows
++this.
++
++If an FPGA Region does not specify a FPGA Manager, it will inherit the FPGA
++Manager specified by its ancestor FPGA Region.  This supports both the case
++where the same FPGA Manager is used for all of a FPGA as well the case where
++a different FPGA Manager is used for each region.
++
++FPGA Regions do not inherit their ancestor FPGA regions' bridges.  This prevents
++shutting down bridges that are upstream from the other active regions while one
++region is getting reconfigured (see Figure 1 above).  During PR, the FPGA's
++hardware bridges remain enabled.  The PR regions' bridges will be FPGA bridges
++within the static image of the FPGA.
++
++Required properties:
++- compatible : should contain "fpga-region"
++- fpga-mgr : should contain a phandle to an FPGA Manager.  Child FPGA Regions
++	inherit this property from their ancestor regions.  A fpga-mgr property
++	in a region will override any inherited FPGA manager.
++- #address-cells, #size-cells, ranges : must be present to handle address space
++	mapping for child nodes.
++
++Optional properties:
++- firmware-name : should contain the name of an FPGA image file located on the
++	firmware search path.  If this property shows up in a live device tree
++	it indicates that the FPGA has already been programmed with this image.
++	If this property is in an overlay targeting a FPGA region, it is a
++	request to program the FPGA with that image.
++- fpga-bridges : should contain a list of phandles to FPGA Bridges that must be
++	controlled during FPGA programming along with the parent FPGA bridge.
++	This property is optional if the FPGA Manager handles the bridges.
++        If the fpga-region is  the child of a fpga-bridge, the list should not
++        contain the parent bridge.
++- partial-fpga-config : boolean, set if partial reconfiguration is to be done,
++	otherwise full reconfiguration is done.
++- external-fpga-config : boolean, set if the FPGA has already been configured
++	prior to OS boot up.
++- region-unfreeze-timeout-us : The maximum time in microseconds to wait for
++	bridges to successfully become enabled after the region has been
++	programmed.
++- region-freeze-timeout-us : The maximum time in microseconds to wait for
++	bridges to successfully become disabled before the region has been
++	programmed.
++- child nodes : devices in the FPGA after programming.
++
++In the example below, when an overlay is applied targeting fpga-region0,
++fpga_mgr is used to program the FPGA.  Two bridges are controlled during
++programming: the parent fpga_bridge0 and fpga_bridge1.  Because the region is
++the child of fpga_bridge0, only fpga_bridge1 needs to be specified in the
++fpga-bridges property.  During programming, these bridges are disabled, the
++firmware specified in the overlay is loaded to the FPGA using the FPGA manager
++specified in the region.  If FPGA programming succeeds, the bridges are
++reenabled and the overlay makes it into the live device tree.  The child devices
++are then populated.  If FPGA programming fails, the bridges are left disabled
++and the overlay is rejected.  The overlay's ranges property maps the lwhps
++bridge's region (0xff200000) and the hps bridge's region (0xc0000000) for use by
++the two child devices.
++
++Example:
++Base tree contains:
++
++	fpga_mgr: fpga-mgr@ff706000 {
++		compatible = "altr,socfpga-fpga-mgr";
++		reg = <0xff706000 0x1000
++		       0xffb90000 0x20>;
++		interrupts = <0 175 4>;
++	};
++
++	fpga_bridge0: fpga-bridge@ff400000 {
++		compatible = "altr,socfpga-lwhps2fpga-bridge";
++		reg = <0xff400000 0x100000>;
++		resets = <&rst LWHPS2FPGA_RESET>;
++		clocks = <&l4_main_clk>;
++
++		#address-cells = <1>;
++		#size-cells = <1>;
++		ranges;
++
++		fpga_region0: fpga-region0 {
++			compatible = "fpga-region";
++			fpga-mgr = <&fpga_mgr>;
++		};
++	};
++
++	fpga_bridge1: fpga-bridge@ff500000 {
++		compatible = "altr,socfpga-hps2fpga-bridge";
++		reg = <0xff500000 0x10000>;
++		resets = <&rst HPS2FPGA_RESET>;
++		clocks = <&l4_main_clk>;
++	};
++
++Overlay contains:
++
++/dts-v1/ /plugin/;
++/ {
++	fragment@0 {
++		target = <&fpga_region0>;
++		#address-cells = <1>;
++		#size-cells = <1>;
++		__overlay__ {
++			#address-cells = <1>;
++			#size-cells = <1>;
++
++			firmware-name = "soc_system.rbf";
++			fpga-bridges = <&fpga_bridge1>;
++			ranges = <0x20000 0xff200000 0x100000>,
++				 <0x0 0xc0000000 0x20000000>;
++
++			gpio@10040 {
++				compatible = "altr,pio-1.0";
++				reg = <0x10040 0x20>;
++				altr,gpio-bank-width = <4>;
++				#gpio-cells = <2>;
++				clocks = <2>;
++				gpio-controller;
++			};
++
++			onchip-memory {
++				device_type = "memory";
++				compatible = "altr,onchipmem-15.1";
++				reg = <0x0 0x10000>;
++			};
++		};
++	};
++};
++
++
++Supported Use Models
++====================
++
++In all cases the live DT must have the FPGA Manager, FPGA Bridges (if any), and
++a FPGA Region.  The target of the Device Tree Overlay is the FPGA Region.  Some
++uses are specific to a FPGA device.
++
++ * No FPGA Bridges
++   In this case, the FPGA Manager which programs the FPGA also handles the
++   bridges behind the scenes.  No FPGA Bridge devices are needed for full
++   reconfiguration.
++
++ * Full reconfiguration with hardware bridges
++   In this case, there are hardware bridges between the processor and FPGA that
++   need to be controlled during full reconfiguration.  Before the overlay is
++   applied, the live DT must include the FPGA Manager, FPGA Bridges, and a
++   FPGA Region.  The FPGA Region is the child of the bridge that allows
++   register access to the FPGA.  Additional bridges may be listed in a
++   fpga-bridges property in the FPGA region or in the device tree overlay.
++
++ * Partial reconfiguration with bridges in the FPGA
++   In this case, the FPGA will have one or more PRR's that may be programmed
++   separately while the rest of the FPGA can remain active.  To manage this,
++   bridges need to exist in the FPGA that can gate the buses going to each FPGA
++   region while the buses are enabled for other sections.  Before any partial
++   reconfiguration can be done, a base FPGA image must be loaded which includes
++   PRR's with FPGA bridges.  The device tree should have a FPGA region for each
++   PRR.
++
++Device Tree Examples
++====================
++
++The intention of this section is to give some simple examples, focusing on
++the placement of the elements detailed above, especially:
++ * FPGA Manager
++ * FPGA Bridges
++ * FPGA Region
++ * ranges
++ * target-path or target
++
++For the purposes of this section, I'm dividing the Device Tree into two parts,
++each with its own requirements.  The two parts are:
++ * The live DT prior to the overlay being added
++ * The DT overlay
++
++The live Device Tree must contain an FPGA Region, an FPGA Manager, and any FPGA
++Bridges.  The FPGA Region's "fpga-mgr" property specifies the manager by phandle
++to handle programming the FPGA.  If the FPGA Region is the child of another FPGA
++Region, the parent's FPGA Manager is used.  If FPGA Bridges need to be involved,
++they are specified in the FPGA Region by the "fpga-bridges" property.  During
++FPGA programming, the FPGA Region will disable the bridges that are in its
++"fpga-bridges" list and will re-enable them after FPGA programming has
++succeeded.
++
++The Device Tree Overlay will contain:
++ * "target-path" or "target"
++   The insertion point where the the contents of the overlay will go into the
++   live tree.  target-path is a full path, while target is a phandle.
++ * "ranges"
++    The address space mapping from processor to FPGA bus(ses).
++ * "firmware-name"
++   Specifies the name of the FPGA image file on the firmware search
++   path.  The search path is described in the firmware class documentation.
++ * "partial-fpga-config"
++   This binding is a boolean and should be present if partial reconfiguration
++   is to be done.
++ * child nodes corresponding to hardware that will be loaded in this region of
++   the FPGA.
++
++Device Tree Example: Full Reconfiguration without Bridges
++=========================================================
++
++Live Device Tree contains:
++	fpga_mgr0: fpga-mgr@f8007000 {
++		compatible = "xlnx,zynq-devcfg-1.0";
++		reg = <0xf8007000 0x100>;
++		interrupt-parent = <&intc>;
++		interrupts = <0 8 4>;
++		clocks = <&clkc 12>;
++		clock-names = "ref_clk";
++		syscon = <&slcr>;
++	};
++
++	fpga_region0: fpga-region0 {
++		compatible = "fpga-region";
++		fpga-mgr = <&fpga_mgr0>;
++		#address-cells = <0x1>;
++		#size-cells = <0x1>;
++		ranges;
++	};
++
++DT Overlay contains:
++/dts-v1/ /plugin/;
++/ {
++fragment@0 {
++	target = <&fpga_region0>;
++	#address-cells = <1>;
++	#size-cells = <1>;
++	__overlay__ {
++		#address-cells = <1>;
++		#size-cells = <1>;
++
++		firmware-name = "zynq-gpio.bin";
++
++		gpio1: gpio@40000000 {
++			compatible = "xlnx,xps-gpio-1.00.a";
++			reg = <0x40000000 0x10000>;
++			gpio-controller;
++			#gpio-cells = <0x2>;
++			xlnx,gpio-width= <0x6>;
++		};
++	};
++};
++
++Device Tree Example: Full Reconfiguration to add PRR's
++======================================================
++
++The base FPGA Region is specified similar to the first example above.
++
++This example programs the FPGA to have two regions that can later be partially
++configured.  Each region has its own bridge in the FPGA fabric.
++
++DT Overlay contains:
++/dts-v1/ /plugin/;
++/ {
++	fragment@0 {
++		target = <&fpga_region0>;
++		#address-cells = <1>;
++		#size-cells = <1>;
++		__overlay__ {
++			#address-cells = <1>;
++			#size-cells = <1>;
++
++			firmware-name = "base.rbf";
++
++			fpga-bridge@4400 {
++				compatible = "altr,freeze-bridge";
++				reg = <0x4400 0x10>;
++
++				fpga_region1: fpga-region1 {
++					compatible = "fpga-region";
++					#address-cells = <0x1>;
++					#size-cells = <0x1>;
++					ranges;
++				};
++			};
++
++			fpga-bridge@4420 {
++				compatible = "altr,freeze-bridge";
++				reg = <0x4420 0x10>;
++
++				fpga_region2: fpga-region2 {
++					compatible = "fpga-region";
++					#address-cells = <0x1>;
++					#size-cells = <0x1>;
++					ranges;
++				};
++			};
++		};
++	};
++};
++
++Device Tree Example: Partial Reconfiguration
++============================================
++
++This example reprograms one of the PRR's set up in the previous example.
++
++The sequence that occurs when this overlay is similar to the above, the only
++differences are that the FPGA is partially reconfigured due to the
++"partial-fpga-config" boolean and the only bridge that is controlled during
++programming is the FPGA based bridge of fpga_region1.
++
++/dts-v1/ /plugin/;
++/ {
++	fragment@0 {
++		target = <&fpga_region1>;
++		#address-cells = <1>;
++		#size-cells = <1>;
++		__overlay__ {
++			#address-cells = <1>;
++			#size-cells = <1>;
++
++			firmware-name = "soc_image2.rbf";
++			partial-fpga-config;
++
++			gpio@10040 {
++				compatible = "altr,pio-1.0";
++				reg = <0x10040 0x20>;
++				clocks = <0x2>;
++				altr,gpio-bank-width = <0x4>;
++				resetvalue = <0x0>;
++				#gpio-cells = <0x2>;
++				gpio-controller;
++			};
++		};
++	};
++};
++
++Constraints
++===========
++
++It is beyond the scope of this document to fully describe all the FPGA design
++constraints required to make partial reconfiguration work[1] [2] [3], but a few
++deserve quick mention.
++
++A persona must have boundary connections that line up with those of the partion
++or region it is designed to go into.
++
++During programming, transactions through those connections must be stopped and
++the connections must be held at a fixed logic level.  This can be achieved by
++FPGA Bridges that exist on the FPGA fabric prior to the partial reconfiguration.
++
++--
++[1] www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_partrecon.pdf
++[2] tspace.library.utoronto.ca/bitstream/1807/67932/1/Byma_Stuart_A_201411_MAS_thesis.pdf
++[3] http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_1/ug702.pdf
diff --git a/patches.socfpga/0028-fpga-mgr-add-fpga-image-information-struct.patch b/patches.socfpga/0028-fpga-mgr-add-fpga-image-information-struct.patch
new file mode 100644
index 0000000..c0283f5
--- /dev/null
+++ b/patches.socfpga/0028-fpga-mgr-add-fpga-image-information-struct.patch
@@ -0,0 +1,224 @@
+From dcc67124b4337a29ce04452a177953b3ff14b87a Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:26 -0500
+Subject: [PATCH 028/103] fpga-mgr: add fpga image information struct
+
+This patch adds a minor change in the FPGA Manager API
+to hold information that is specific to an FPGA image
+file.  This change is expected to bring little, if any,
+pain.  The socfpga and zynq drivers are fixed up in
+this patch.
+
+An FPGA image file will have particulars that affect how the
+image is programmed to the FPGA.  One example is that
+current 'flags' currently has one bit which shows whether the
+FPGA image was built for full reconfiguration or partial
+reconfiguration.  Another example is timeout values for
+enabling or disabling the bridges in the FPGA.  As the
+complexity of the FPGA design increases, the bridges in the
+FPGA may take longer times to enable or disable.
+
+This patch adds a new 'struct fpga_image_info', moves the
+current 'u32 flags' to it.  Two other image-specific u32's
+are added for the bridge enable/disable timeouts.  The FPGA
+Manager API functions are changed, replacing the 'u32 flag'
+parameter with a pointer to struct fpga_image_info.
+Subsequent patches fix the existing low level FPGA manager
+drivers.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/fpga-mgr.c       |   17 +++++++++--------
+ drivers/fpga/socfpga.c        |    7 ++++---
+ drivers/fpga/zynq-fpga.c      |   10 ++++++----
+ include/linux/fpga/fpga-mgr.h |   23 +++++++++++++++++++----
+ 4 files changed, 38 insertions(+), 19 deletions(-)
+
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -32,7 +32,7 @@ static struct class *fpga_mgr_class;
+ /**
+  * fpga_mgr_buf_load - load fpga from image in buffer
+  * @mgr:	fpga manager
+- * @flags:	flags setting fpga confuration modes
++ * @info:	fpga image specific information
+  * @buf:	buffer contain fpga image
+  * @count:	byte count of buf
+  *
+@@ -44,8 +44,8 @@ static struct class *fpga_mgr_class;
+  *
+  * Return: 0 on success, negative error code otherwise.
+  */
+-int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf,
+-		      size_t count)
++int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
++		      const char *buf, size_t count)
+ {
+ 	struct device *dev = &mgr->dev;
+ 	int ret;
+@@ -56,7 +56,7 @@ int fpga_mgr_buf_load(struct fpga_manage
+ 	 * ready to receive an FPGA image.
+ 	 */
+ 	mgr->state = FPGA_MGR_STATE_WRITE_INIT;
+-	ret = mgr->mops->write_init(mgr, flags, buf, count);
++	ret = mgr->mops->write_init(mgr, info, buf, count);
+ 	if (ret) {
+ 		dev_err(dev, "Error preparing FPGA for writing\n");
+ 		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
+@@ -79,7 +79,7 @@ int fpga_mgr_buf_load(struct fpga_manage
+ 	 * steps to finish and set the FPGA into operating mode.
+ 	 */
+ 	mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
+-	ret = mgr->mops->write_complete(mgr, flags);
++	ret = mgr->mops->write_complete(mgr, info);
+ 	if (ret) {
+ 		dev_err(dev, "Error after writing image data to FPGA\n");
+ 		mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
+@@ -94,7 +94,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
+ /**
+  * fpga_mgr_firmware_load - request firmware and load to fpga
+  * @mgr:	fpga manager
+- * @flags:	flags setting fpga confuration modes
++ * @info:	fpga image specific information
+  * @image_name:	name of image file on the firmware search path
+  *
+  * Request an FPGA image using the firmware class, then write out to the FPGA.
+@@ -105,7 +105,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
+  *
+  * Return: 0 on success, negative error code otherwise.
+  */
+-int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
++int fpga_mgr_firmware_load(struct fpga_manager *mgr,
++			   struct fpga_image_info *info,
+ 			   const char *image_name)
+ {
+ 	struct device *dev = &mgr->dev;
+@@ -123,7 +124,7 @@ int fpga_mgr_firmware_load(struct fpga_m
+ 		return ret;
+ 	}
+ 
+-	ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size);
++	ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size);
+ 
+ 	release_firmware(fw);
+ 
+--- a/drivers/fpga/socfpga.c
++++ b/drivers/fpga/socfpga.c
+@@ -407,13 +407,14 @@ static int socfpga_fpga_reset(struct fpg
+ /*
+  * Prepare the FPGA to receive the configuration data.
+  */
+-static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr, u32 flags,
++static int socfpga_fpga_ops_configure_init(struct fpga_manager *mgr,
++					   struct fpga_image_info *info,
+ 					   const char *buf, size_t count)
+ {
+ 	struct socfpga_fpga_priv *priv = mgr->priv;
+ 	int ret;
+ 
+-	if (flags & FPGA_MGR_PARTIAL_RECONFIG) {
++	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
+ 		dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
+ 		return -EINVAL;
+ 	}
+@@ -478,7 +479,7 @@ static int socfpga_fpga_ops_configure_wr
+ }
+ 
+ static int socfpga_fpga_ops_configure_complete(struct fpga_manager *mgr,
+-					       u32 flags)
++					       struct fpga_image_info *info)
+ {
+ 	struct socfpga_fpga_priv *priv = mgr->priv;
+ 	u32 status;
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -175,7 +175,8 @@ static irqreturn_t zynq_fpga_isr(int irq
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
++static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
++				    struct fpga_image_info *info,
+ 				    const char *buf, size_t count)
+ {
+ 	struct zynq_fpga_priv *priv;
+@@ -189,7 +190,7 @@ static int zynq_fpga_ops_write_init(stru
+ 		return err;
+ 
+ 	/* don't globally reset PL if we're doing partial reconfig */
+-	if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) {
++	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ 		/* assert AXI interface resets */
+ 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
+ 			     FPGA_RST_ALL_MASK);
+@@ -343,7 +344,8 @@ out_free:
+ 	return err;
+ }
+ 
+-static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr, u32 flags)
++static int zynq_fpga_ops_write_complete(struct fpga_manager *mgr,
++					struct fpga_image_info *info)
+ {
+ 	struct zynq_fpga_priv *priv = mgr->priv;
+ 	int err;
+@@ -364,7 +366,7 @@ static int zynq_fpga_ops_write_complete(
+ 		return err;
+ 
+ 	/* for the partial reconfig case we didn't touch the level shifters */
+-	if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) {
++	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ 		/* enable level shifters from PL to PS */
+ 		regmap_write(priv->slcr, SLCR_LVL_SHFTR_EN_OFFSET,
+ 			     LVL_SHFTR_ENABLE_PL_TO_PS);
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -69,6 +69,18 @@ enum fpga_mgr_states {
+ #define FPGA_MGR_PARTIAL_RECONFIG	BIT(0)
+ 
+ /**
++ * struct fpga_image_info - information specific to a FPGA image
++ * @flags: boolean flags as defined above
++ * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
++ * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
++ */
++struct fpga_image_info {
++	u32 flags;
++	u32 enable_timeout_us;
++	u32 disable_timeout_us;
++};
++
++/**
+  * struct fpga_manager_ops - ops for low level fpga manager drivers
+  * @state: returns an enum value of the FPGA's state
+  * @write_init: prepare the FPGA to receive confuration data
+@@ -82,10 +94,12 @@ enum fpga_mgr_states {
+  */
+ struct fpga_manager_ops {
+ 	enum fpga_mgr_states (*state)(struct fpga_manager *mgr);
+-	int (*write_init)(struct fpga_manager *mgr, u32 flags,
++	int (*write_init)(struct fpga_manager *mgr,
++			  struct fpga_image_info *info,
+ 			  const char *buf, size_t count);
+ 	int (*write)(struct fpga_manager *mgr, const char *buf, size_t count);
+-	int (*write_complete)(struct fpga_manager *mgr, u32 flags);
++	int (*write_complete)(struct fpga_manager *mgr,
++			      struct fpga_image_info *info);
+ 	void (*fpga_remove)(struct fpga_manager *mgr);
+ };
+ 
+@@ -109,10 +123,11 @@ struct fpga_manager {
+ 
+ #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
+ 
+-int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags,
++int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
+ 		      const char *buf, size_t count);
+ 
+-int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags,
++int fpga_mgr_firmware_load(struct fpga_manager *mgr,
++			   struct fpga_image_info *info,
+ 			   const char *image_name);
+ 
+ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
diff --git a/patches.socfpga/0029-add-sysfs-document-for-fpga-bridge-class.patch b/patches.socfpga/0029-add-sysfs-document-for-fpga-bridge-class.patch
new file mode 100644
index 0000000..9fe70d9
--- /dev/null
+++ b/patches.socfpga/0029-add-sysfs-document-for-fpga-bridge-class.patch
@@ -0,0 +1,29 @@
+From 61dfd4be91d2b0b62631b47d6fe2e775b97ca990 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:27 -0500
+Subject: [PATCH 029/103] add sysfs document for fpga bridge class
+
+Add documentation for new FPGA bridge class's sysfs interface.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/testing/sysfs-class-fpga-bridge |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-bridge
+
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-class-fpga-bridge
+@@ -0,0 +1,11 @@
++What:		/sys/class/fpga_bridge/<bridge>/name
++Date:		January 2016
++KernelVersion:	4.5
++Contact:	Alan Tull <atull@opensource.altera.com>
++Description:	Name of low level FPGA bridge driver.
++
++What:		/sys/class/fpga_bridge/<bridge>/state
++Date:		January 2016
++KernelVersion:	4.5
++Contact:	Alan Tull <atull@opensource.altera.com>
++Description:	Show bridge state as "enabled" or "disabled"
diff --git a/patches.socfpga/0030-fpga-add-fpga-bridge-framework.patch b/patches.socfpga/0030-fpga-add-fpga-bridge-framework.patch
new file mode 100644
index 0000000..5a582d3
--- /dev/null
+++ b/patches.socfpga/0030-fpga-add-fpga-bridge-framework.patch
@@ -0,0 +1,534 @@
+From 2649550bc9bf2246dfe843874012c7cf621bdfca Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:28 -0500
+Subject: [PATCH 030/103] fpga: add fpga bridge framework
+
+This framework adds API functions for enabling/
+disabling FPGA bridges under kernel control.
+
+This allows the Linux kernel to disable FPGA bridges
+during FPGA reprogramming and to enable FPGA bridges
+when FPGA reprogramming is done.  This framework is
+be manufacturer-agnostic, allowing it to be used in
+interfaces that use the FPGA Manager Framework to
+reprogram FPGA's.
+
+The functions are:
+* of_fpga_bridge_get
+* fpga_bridge_put
+   Get/put an exclusive reference to a FPGA bridge.
+
+* fpga_bridge_enable
+* fpga_bridge_disable
+   Enable/Disable traffic through a bridge.
+
+* fpga_bridge_register
+* fpga_bridge_unregister
+   Register/unregister a device-specific low level FPGA
+   Bridge driver.
+
+Get an exclusive reference to a bridge and add it to a list:
+* fpga_bridge_get_to_list
+
+To enable/disable/put a set of bridges that are on a list:
+* fpga_bridges_enable
+* fpga_bridges_disable
+* fpga_bridges_put
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig             |    7 
+ drivers/fpga/Makefile            |    3 
+ drivers/fpga/fpga-bridge.c       |  395 +++++++++++++++++++++++++++++++++++++++
+ include/linux/fpga/fpga-bridge.h |   60 +++++
+ 4 files changed, 465 insertions(+)
+ create mode 100644 drivers/fpga/fpga-bridge.c
+ create mode 100644 include/linux/fpga/fpga-bridge.h
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -26,6 +26,13 @@ config FPGA_MGR_ZYNQ_FPGA
+ 	help
+ 	  FPGA manager driver support for Xilinx Zynq FPGAs.
+ 
++config FPGA_BRIDGE
++	tristate "FPGA Bridge Framework"
++	depends on OF
++	help
++	  Say Y here if you want to support bridges connected between host
++	  processors and FPGAs or between FPGAs.
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -8,3 +8,6 @@ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
+ # FPGA Manager Drivers
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
++
++# FPGA Bridge Drivers
++obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+--- /dev/null
++++ b/drivers/fpga/fpga-bridge.c
+@@ -0,0 +1,395 @@
++/*
++ * FPGA Bridge Framework Driver
++ *
++ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++#include <linux/fpga/fpga-bridge.h>
++#include <linux/idr.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++static DEFINE_IDA(fpga_bridge_ida);
++static struct class *fpga_bridge_class;
++
++/* Lock for adding/removing bridges to linked lists*/
++spinlock_t bridge_list_lock;
++
++static int fpga_bridge_of_node_match(struct device *dev, const void *data)
++{
++	return dev->of_node == data;
++}
++
++/**
++ * fpga_bridge_enable - Enable transactions on the bridge
++ *
++ * @bridge: FPGA bridge
++ *
++ * Return: 0 for success, error code otherwise.
++ */
++int fpga_bridge_enable(struct fpga_bridge *bridge)
++{
++	dev_dbg(&bridge->dev, "enable\n");
++
++	if (bridge->br_ops && bridge->br_ops->enable_set)
++		return bridge->br_ops->enable_set(bridge, 1);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_enable);
++
++/**
++ * fpga_bridge_disable - Disable transactions on the bridge
++ *
++ * @bridge: FPGA bridge
++ *
++ * Return: 0 for success, error code otherwise.
++ */
++int fpga_bridge_disable(struct fpga_bridge *bridge)
++{
++	dev_dbg(&bridge->dev, "disable\n");
++
++	if (bridge->br_ops && bridge->br_ops->enable_set)
++		return bridge->br_ops->enable_set(bridge, 0);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_disable);
++
++/**
++ * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
++ *
++ * @np: node pointer of a FPGA bridge
++ * @info: fpga image specific information
++ *
++ * Return fpga_bridge struct if successful.
++ * Return -EBUSY if someone already has a reference to the bridge.
++ * Return -ENODEV if @np is not a FPGA Bridge.
++ */
++struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
++				       struct fpga_image_info *info)
++
++{
++	struct device *dev;
++	struct fpga_bridge *bridge;
++	int ret = -ENODEV;
++
++	dev = class_find_device(fpga_bridge_class, NULL, np,
++				fpga_bridge_of_node_match);
++	if (!dev)
++		goto err_dev;
++
++	bridge = to_fpga_bridge(dev);
++	if (!bridge)
++		goto err_dev;
++
++	bridge->info = info;
++
++	if (!mutex_trylock(&bridge->mutex)) {
++		ret = -EBUSY;
++		goto err_dev;
++	}
++
++	if (!try_module_get(dev->parent->driver->owner))
++		goto err_ll_mod;
++
++	dev_dbg(&bridge->dev, "get\n");
++
++	return bridge;
++
++err_ll_mod:
++	mutex_unlock(&bridge->mutex);
++err_dev:
++	put_device(dev);
++	return ERR_PTR(ret);
++}
++EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
++
++/**
++ * fpga_bridge_put - release a reference to a bridge
++ *
++ * @bridge: FPGA bridge
++ */
++void fpga_bridge_put(struct fpga_bridge *bridge)
++{
++	dev_dbg(&bridge->dev, "put\n");
++
++	bridge->info = NULL;
++	module_put(bridge->dev.parent->driver->owner);
++	mutex_unlock(&bridge->mutex);
++	put_device(&bridge->dev);
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_put);
++
++/**
++ * fpga_bridges_enable - enable bridges in a list
++ * @bridge_list: list of FPGA bridges
++ *
++ * Enable each bridge in the list.  If list is empty, do nothing.
++ *
++ * Return 0 for success or empty bridge list; return error code otherwise.
++ */
++int fpga_bridges_enable(struct list_head *bridge_list)
++{
++	struct fpga_bridge *bridge;
++	struct list_head *node;
++	int ret;
++
++	list_for_each(node, bridge_list) {
++		bridge = list_entry(node, struct fpga_bridge, node);
++		ret = fpga_bridge_enable(bridge);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fpga_bridges_enable);
++
++/**
++ * fpga_bridges_disable - disable bridges in a list
++ *
++ * @bridge_list: list of FPGA bridges
++ *
++ * Disable each bridge in the list.  If list is empty, do nothing.
++ *
++ * Return 0 for success or empty bridge list; return error code otherwise.
++ */
++int fpga_bridges_disable(struct list_head *bridge_list)
++{
++	struct fpga_bridge *bridge;
++	struct list_head *node;
++	int ret;
++
++	list_for_each(node, bridge_list) {
++		bridge = list_entry(node, struct fpga_bridge, node);
++		ret = fpga_bridge_disable(bridge);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fpga_bridges_disable);
++
++/**
++ * fpga_bridges_put - put bridges
++ *
++ * @bridge_list: list of FPGA bridges
++ *
++ * For each bridge in the list, put the bridge and remove it from the list.
++ * If list is empty, do nothing.
++ */
++void fpga_bridges_put(struct list_head *bridge_list)
++{
++	struct fpga_bridge *bridge;
++	struct list_head *node, *next;
++	unsigned long flags;
++
++	list_for_each_safe(node, next, bridge_list) {
++		bridge = list_entry(node, struct fpga_bridge, node);
++
++		fpga_bridge_put(bridge);
++
++		spin_lock_irqsave(&bridge_list_lock, flags);
++		list_del(&bridge->node);
++		spin_unlock_irqrestore(&bridge_list_lock, flags);
++	}
++}
++EXPORT_SYMBOL_GPL(fpga_bridges_put);
++
++/**
++ * fpga_bridges_get_to_list - get a bridge, add it to a list
++ *
++ * @np: node pointer of a FPGA bridge
++ * @info: fpga image specific information
++ * @bridge_list: list of FPGA bridges
++ *
++ * Get an exclusive reference to the bridge and and it to the list.
++ *
++ * Return 0 for success, error code from of_fpga_bridge_get() othewise.
++ */
++int fpga_bridge_get_to_list(struct device_node *np,
++			    struct fpga_image_info *info,
++			    struct list_head *bridge_list)
++{
++	struct fpga_bridge *bridge;
++	unsigned long flags;
++
++	bridge = of_fpga_bridge_get(np, info);
++	if (IS_ERR(bridge))
++		return PTR_ERR(bridge);
++
++	spin_lock_irqsave(&bridge_list_lock, flags);
++	list_add(&bridge->node, bridge_list);
++	spin_unlock_irqrestore(&bridge_list_lock, flags);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
++
++static ssize_t name_show(struct device *dev,
++			 struct device_attribute *attr, char *buf)
++{
++	struct fpga_bridge *bridge = to_fpga_bridge(dev);
++
++	return sprintf(buf, "%s\n", bridge->name);
++}
++
++static ssize_t state_show(struct device *dev,
++			  struct device_attribute *attr, char *buf)
++{
++	struct fpga_bridge *bridge = to_fpga_bridge(dev);
++	int enable = 1;
++
++	if (bridge->br_ops && bridge->br_ops->enable_show)
++		enable = bridge->br_ops->enable_show(bridge);
++
++	return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
++}
++
++static DEVICE_ATTR_RO(name);
++static DEVICE_ATTR_RO(state);
++
++static struct attribute *fpga_bridge_attrs[] = {
++	&dev_attr_name.attr,
++	&dev_attr_state.attr,
++	NULL,
++};
++ATTRIBUTE_GROUPS(fpga_bridge);
++
++/**
++ * fpga_bridge_register - register a fpga bridge driver
++ * @dev:	FPGA bridge device from pdev
++ * @name:	FPGA bridge name
++ * @br_ops:	pointer to structure of fpga bridge ops
++ * @priv:	FPGA bridge private data
++ *
++ * Return: 0 for success, error code otherwise.
++ */
++int fpga_bridge_register(struct device *dev, const char *name,
++			 const struct fpga_bridge_ops *br_ops, void *priv)
++{
++	struct fpga_bridge *bridge;
++	int id, ret = 0;
++
++	if (!name || !strlen(name)) {
++		dev_err(dev, "Attempt to register with no name!\n");
++		return -EINVAL;
++	}
++
++	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
++	if (!bridge)
++		return -ENOMEM;
++
++	id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
++	if (id < 0) {
++		ret = id;
++		goto error_kfree;
++	}
++
++	mutex_init(&bridge->mutex);
++	INIT_LIST_HEAD(&bridge->node);
++
++	bridge->name = name;
++	bridge->br_ops = br_ops;
++	bridge->priv = priv;
++
++	device_initialize(&bridge->dev);
++	bridge->dev.class = fpga_bridge_class;
++	bridge->dev.parent = dev;
++	bridge->dev.of_node = dev->of_node;
++	bridge->dev.id = id;
++	dev_set_drvdata(dev, bridge);
++
++	ret = dev_set_name(&bridge->dev, "br%d", id);
++	if (ret)
++		goto error_device;
++
++	ret = device_add(&bridge->dev);
++	if (ret)
++		goto error_device;
++
++	of_platform_populate(dev->of_node, NULL, NULL, dev);
++
++	dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
++		 bridge->name);
++
++	return 0;
++
++error_device:
++	ida_simple_remove(&fpga_bridge_ida, id);
++error_kfree:
++	kfree(bridge);
++
++	return ret;
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_register);
++
++/**
++ * fpga_bridge_unregister - unregister a fpga bridge driver
++ * @dev: FPGA bridge device from pdev
++ */
++void fpga_bridge_unregister(struct device *dev)
++{
++	struct fpga_bridge *bridge = dev_get_drvdata(dev);
++
++	/*
++	 * If the low level driver provides a method for putting bridge into
++	 * a desired state upon unregister, do it.
++	 */
++	if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
++		bridge->br_ops->fpga_bridge_remove(bridge);
++
++	device_unregister(&bridge->dev);
++}
++EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
++
++static void fpga_bridge_dev_release(struct device *dev)
++{
++	struct fpga_bridge *bridge = to_fpga_bridge(dev);
++
++	ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
++	kfree(bridge);
++}
++
++static int __init fpga_bridge_dev_init(void)
++{
++	spin_lock_init(&bridge_list_lock);
++
++	fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
++	if (IS_ERR(fpga_bridge_class))
++		return PTR_ERR(fpga_bridge_class);
++
++	fpga_bridge_class->dev_groups = fpga_bridge_groups;
++	fpga_bridge_class->dev_release = fpga_bridge_dev_release;
++
++	return 0;
++}
++
++static void __exit fpga_bridge_dev_exit(void)
++{
++	class_destroy(fpga_bridge_class);
++	ida_destroy(&fpga_bridge_ida);
++}
++
++MODULE_DESCRIPTION("FPGA Bridge Driver");
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_LICENSE("GPL v2");
++
++subsys_initcall(fpga_bridge_dev_init);
++module_exit(fpga_bridge_dev_exit);
+--- /dev/null
++++ b/include/linux/fpga/fpga-bridge.h
+@@ -0,0 +1,60 @@
++#include <linux/device.h>
++#include <linux/fpga/fpga-mgr.h>
++
++#ifndef _LINUX_FPGA_BRIDGE_H
++#define _LINUX_FPGA_BRIDGE_H
++
++struct fpga_bridge;
++
++/**
++ * struct fpga_bridge_ops - ops for low level FPGA bridge drivers
++ * @enable_show: returns the FPGA bridge's status
++ * @enable_set: set a FPGA bridge as enabled or disabled
++ * @fpga_bridge_remove: set FPGA into a specific state during driver remove
++ */
++struct fpga_bridge_ops {
++	int (*enable_show)(struct fpga_bridge *bridge);
++	int (*enable_set)(struct fpga_bridge *bridge, bool enable);
++	void (*fpga_bridge_remove)(struct fpga_bridge *bridge);
++};
++
++/**
++ * struct fpga_bridge - FPGA bridge structure
++ * @name: name of low level FPGA bridge
++ * @dev: FPGA bridge device
++ * @mutex: enforces exclusive reference to bridge
++ * @br_ops: pointer to struct of FPGA bridge ops
++ * @info: fpga image specific information
++ * @node: FPGA bridge list node
++ * @priv: low level driver private date
++ */
++struct fpga_bridge {
++	const char *name;
++	struct device dev;
++	struct mutex mutex; /* for exclusive reference to bridge */
++	const struct fpga_bridge_ops *br_ops;
++	struct fpga_image_info *info;
++	struct list_head node;
++	void *priv;
++};
++
++#define to_fpga_bridge(d) container_of(d, struct fpga_bridge, dev)
++
++struct fpga_bridge *of_fpga_bridge_get(struct device_node *node,
++				       struct fpga_image_info *info);
++void fpga_bridge_put(struct fpga_bridge *bridge);
++int fpga_bridge_enable(struct fpga_bridge *bridge);
++int fpga_bridge_disable(struct fpga_bridge *bridge);
++
++int fpga_bridges_enable(struct list_head *bridge_list);
++int fpga_bridges_disable(struct list_head *bridge_list);
++void fpga_bridges_put(struct list_head *bridge_list);
++int fpga_bridge_get_to_list(struct device_node *np,
++			    struct fpga_image_info *info,
++			    struct list_head *bridge_list);
++
++int fpga_bridge_register(struct device *dev, const char *name,
++			 const struct fpga_bridge_ops *br_ops, void *priv);
++void fpga_bridge_unregister(struct device *dev);
++
++#endif /* _LINUX_FPGA_BRIDGE_H */
diff --git a/patches.socfpga/0031-fpga-fpga-region-device-tree-control-for-FPGA.patch b/patches.socfpga/0031-fpga-fpga-region-device-tree-control-for-FPGA.patch
new file mode 100644
index 0000000..e69a9ba
--- /dev/null
+++ b/patches.socfpga/0031-fpga-fpga-region-device-tree-control-for-FPGA.patch
@@ -0,0 +1,662 @@
+From 1959ad1708f7ec01af7377787b9e117e2eae61f8 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:29 -0500
+Subject: [PATCH 031/103] fpga: fpga-region: device tree control for FPGA
+
+FPGA Regions support programming FPGA under control of the Device
+Tree.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig          |    7 
+ drivers/fpga/Makefile         |    3 
+ drivers/fpga/fpga-region.c    |  603 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/fpga/fpga-mgr.h |    2 
+ 4 files changed, 615 insertions(+)
+ create mode 100644 drivers/fpga/fpga-region.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -13,6 +13,13 @@ config FPGA
+ 
+ if FPGA
+ 
++config FPGA_REGION
++	tristate "FPGA Region"
++	depends on OF && FPGA_BRIDGE
++	help
++	  FPGA Regions allow loading FPGA images under control of
++	  the Device Tree.
++
+ config FPGA_MGR_SOCFPGA
+ 	tristate "Altera SOCFPGA FPGA Manager"
+ 	depends on ARCH_SOCFPGA
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -11,3 +11,6 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq
+ 
+ # FPGA Bridge Drivers
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
++
++# High Level Interfaces
++obj-$(CONFIG_FPGA_REGION)		+= fpga-region.o
+--- /dev/null
++++ b/drivers/fpga/fpga-region.c
+@@ -0,0 +1,603 @@
++/*
++ * FPGA Region - Device Tree support for FPGA programming under Linux
++ *
++ *  Copyright (C) 2013-2016 Altera Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/fpga/fpga-bridge.h>
++#include <linux/fpga/fpga-mgr.h>
++#include <linux/idr.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++/**
++ * struct fpga_region - FPGA Region structure
++ * @dev: FPGA Region device
++ * @mutex: enforces exclusive reference to region
++ * @bridge_list: list of FPGA bridges specified in region
++ * @info: fpga image specific information
++ */
++struct fpga_region {
++	struct device dev;
++	struct mutex mutex; /* for exclusive reference to region */
++	struct list_head bridge_list;
++	struct fpga_image_info *info;
++};
++
++#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
++
++static DEFINE_IDA(fpga_region_ida);
++static struct class *fpga_region_class;
++
++static const struct of_device_id fpga_region_of_match[] = {
++	{ .compatible = "fpga-region", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, fpga_region_of_match);
++
++static int fpga_region_of_node_match(struct device *dev, const void *data)
++{
++	return dev->of_node == data;
++}
++
++/**
++ * fpga_region_find - find FPGA region
++ * @np: device node of FPGA Region
++ * Caller will need to put_device(&region->dev) when done.
++ * Returns FPGA Region struct or NULL
++ */
++static struct fpga_region *fpga_region_find(struct device_node *np)
++{
++	struct device *dev;
++
++	dev = class_find_device(fpga_region_class, NULL, np,
++				fpga_region_of_node_match);
++	if (!dev)
++		return NULL;
++
++	return to_fpga_region(dev);
++}
++
++/**
++ * fpga_region_get - get an exclusive reference to a fpga region
++ * @region: FPGA Region struct
++ *
++ * Caller should call fpga_region_put() when done with region.
++ *
++ * Return fpga_region struct if successful.
++ * Return -EBUSY if someone already has a reference to the region.
++ * Return -ENODEV if @np is not a FPGA Region.
++ */
++static struct fpga_region *fpga_region_get(struct fpga_region *region)
++{
++	struct device *dev = &region->dev;
++
++	if (!mutex_trylock(&region->mutex)) {
++		dev_dbg(dev, "%s: FPGA Region already in use\n", __func__);
++		return ERR_PTR(-EBUSY);
++	}
++
++	get_device(dev);
++	of_node_get(dev->of_node);
++	if (!try_module_get(dev->parent->driver->owner)) {
++		of_node_put(dev->of_node);
++		put_device(dev);
++		mutex_unlock(&region->mutex);
++		return ERR_PTR(-ENODEV);
++	}
++
++	dev_dbg(&region->dev, "get\n");
++
++	return region;
++}
++
++/**
++ * fpga_region_put - release a reference to a region
++ *
++ * @region: FPGA region
++ */
++static void fpga_region_put(struct fpga_region *region)
++{
++	struct device *dev = &region->dev;
++
++	dev_dbg(&region->dev, "put\n");
++
++	module_put(dev->parent->driver->owner);
++	of_node_put(dev->of_node);
++	put_device(dev);
++	mutex_unlock(&region->mutex);
++}
++
++/**
++ * fpga_region_get_manager - get exclusive reference for FPGA manager
++ * @region: FPGA region
++ *
++ * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
++ *
++ * Caller should call fpga_mgr_put() when done with manager.
++ *
++ * Return: fpga manager struct or IS_ERR() condition containing error code.
++ */
++static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region)
++{
++	struct device *dev = &region->dev;
++	struct device_node *np = dev->of_node;
++	struct device_node  *mgr_node;
++	struct fpga_manager *mgr;
++
++	of_node_get(np);
++	while (np) {
++		if (of_device_is_compatible(np, "fpga-region")) {
++			mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
++			if (mgr_node) {
++				mgr = of_fpga_mgr_get(mgr_node);
++				of_node_put(np);
++				return mgr;
++			}
++		}
++		np = of_get_next_parent(np);
++	}
++	of_node_put(np);
++
++	return ERR_PTR(-EINVAL);
++}
++
++/**
++ * fpga_region_get_bridges - create a list of bridges
++ * @region: FPGA region
++ * @overlay: device node of the overlay
++ *
++ * Create a list of bridges including the parent bridge and the bridges
++ * specified by "fpga-bridges" property.  Note that the
++ * fpga_bridges_enable/disable/put functions are all fine with an empty list
++ * if that happens.
++ *
++ * Caller should call fpga_bridges_put(&region->bridge_list) when
++ * done with the bridges.
++ *
++ * Return 0 for success (even if there are no bridges specified)
++ * or -EBUSY if any of the bridges are in use.
++ */
++static int fpga_region_get_bridges(struct fpga_region *region,
++				   struct device_node *overlay)
++{
++	struct device *dev = &region->dev;
++	struct device_node *region_np = dev->of_node;
++	struct device_node *br, *np, *parent_br = NULL;
++	int i, ret;
++
++	/* If parent is a bridge, add to list */
++	ret = fpga_bridge_get_to_list(region_np->parent, region->info,
++				      &region->bridge_list);
++	if (ret == -EBUSY)
++		return ret;
++
++	if (!ret)
++		parent_br = region_np->parent;
++
++	/* If overlay has a list of bridges, use it. */
++	if (of_parse_phandle(overlay, "fpga-bridges", 0))
++		np = overlay;
++	else
++		np = region_np;
++
++	for (i = 0; ; i++) {
++		br = of_parse_phandle(np, "fpga-bridges", i);
++		if (!br)
++			break;
++
++		/* If parent bridge is in list, skip it. */
++		if (br == parent_br)
++			continue;
++
++		/* If node is a bridge, get it and add to list */
++		ret = fpga_bridge_get_to_list(br, region->info,
++					      &region->bridge_list);
++
++		/* If any of the bridges are in use, give up */
++		if (ret == -EBUSY) {
++			fpga_bridges_put(&region->bridge_list);
++			return -EBUSY;
++		}
++	}
++
++	return 0;
++}
++
++/**
++ * fpga_region_program_fpga - program FPGA
++ * @region: FPGA region
++ * @firmware_name: name of FPGA image firmware file
++ * @overlay: device node of the overlay
++ * Program an FPGA using information in the device tree.
++ * Function assumes that there is a firmware-name property.
++ * Return 0 for success or negative error code.
++ */
++static int fpga_region_program_fpga(struct fpga_region *region,
++				    const char *firmware_name,
++				    struct device_node *overlay)
++{
++	struct fpga_manager *mgr;
++	int ret;
++
++	region = fpga_region_get(region);
++	if (IS_ERR(region)) {
++		pr_err("failed to get fpga region\n");
++		return PTR_ERR(region);
++	}
++
++	mgr = fpga_region_get_manager(region);
++	if (IS_ERR(mgr)) {
++		pr_err("failed to get fpga region manager\n");
++		return PTR_ERR(mgr);
++	}
++
++	ret = fpga_region_get_bridges(region, overlay);
++	if (ret) {
++		pr_err("failed to get fpga region bridges\n");
++		goto err_put_mgr;
++	}
++
++	ret = fpga_bridges_disable(&region->bridge_list);
++	if (ret) {
++		pr_err("failed to disable region bridges\n");
++		goto err_put_br;
++	}
++
++	ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name);
++	if (ret) {
++		pr_err("failed to load fpga image\n");
++		goto err_put_br;
++	}
++
++	ret = fpga_bridges_enable(&region->bridge_list);
++	if (ret) {
++		pr_err("failed to enable region bridges\n");
++		goto err_put_br;
++	}
++
++	fpga_mgr_put(mgr);
++	fpga_region_put(region);
++
++	return 0;
++
++err_put_br:
++	fpga_bridges_put(&region->bridge_list);
++err_put_mgr:
++	fpga_mgr_put(mgr);
++	fpga_region_put(region);
++
++	return ret;
++}
++
++/**
++ * child_regions_with_firmware
++ * @overlay: device node of the overlay
++ *
++ * If the overlay adds child FPGA regions, they are not allowed to have
++ * firmware-name property.
++ *
++ * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name.
++ */
++static int child_regions_with_firmware(struct device_node *overlay)
++{
++	struct device_node *child_region;
++	const char *child_firmware_name;
++	int ret = 0;
++
++	of_node_get(overlay);
++
++	child_region = of_find_matching_node(overlay, fpga_region_of_match);
++	while (child_region) {
++		if (!of_property_read_string(child_region, "firmware-name",
++					     &child_firmware_name)) {
++			ret = -EINVAL;
++			break;
++		}
++		child_region = of_find_matching_node(child_region,
++						     fpga_region_of_match);
++	}
++
++	of_node_put(child_region);
++
++	if (ret)
++		pr_err("firmware-name not allowed in child FPGA region: %s",
++		       child_region->full_name);
++
++	return ret;
++}
++
++/**
++ * fpga_region_notify_pre_apply - pre-apply overlay notification
++ *
++ * @region: FPGA region that the overlay was applied to
++ * @nd: overlay notification data
++ *
++ * Called after when an overlay targeted to a FPGA Region is about to be
++ * applied.  Function will check the properties that will be added to the FPGA
++ * region.  If the checks pass, it will program the FPGA.
++ *
++ * The checks are:
++ * The overlay must add either firmware-name or external-fpga-config property
++ * to the FPGA Region.
++ *
++ *   firmware-name        : program the FPGA
++ *   external-fpga-config : FPGA is already programmed
++ *
++ * The overlay can add other FPGA regions, but child FPGA regions cannot have a
++ * firmware-name property since those regions don't exist yet.
++ *
++ * If the overlay that breaks the rules, notifier returns an error and the
++ * overlay is rejected before it goes into the main tree.
++ *
++ * Returns 0 for success or negative error code for failure.
++ */
++static int fpga_region_notify_pre_apply(struct fpga_region *region,
++					struct of_overlay_notify_data *nd)
++{
++	const char *firmware_name = NULL;
++	struct fpga_image_info *info;
++	int ret;
++
++	info = devm_kzalloc(&region->dev, sizeof(*info), GFP_KERNEL);
++	if (!info)
++		return -ENOMEM;
++
++	region->info = info;
++
++	/* Reject overlay if child FPGA Regions have firmware-name property */
++	ret = child_regions_with_firmware(nd->overlay);
++	if (ret)
++		return ret;
++
++	/* Read FPGA region properties from the overlay */
++	if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
++		info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
++
++	if (of_property_read_bool(nd->overlay, "external-fpga-config"))
++		info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
++
++	of_property_read_string(nd->overlay, "firmware-name", &firmware_name);
++
++	of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us",
++			     &info->enable_timeout_us);
++
++	of_property_read_u32(nd->overlay, "region-freeze-timeout-us",
++			     &info->disable_timeout_us);
++
++	/* If FPGA was externally programmed, don't specify firmware */
++	if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) {
++		pr_err("error: specified firmware and external-fpga-config");
++		return -EINVAL;
++	}
++
++	/* FPGA is already configured externally.  We're done. */
++	if (info->flags & FPGA_MGR_EXTERNAL_CONFIG)
++		return 0;
++
++	/* If we got this far, we should be programming the FPGA */
++	if (!firmware_name) {
++		pr_err("should specify firmware-name or external-fpga-config\n");
++		return -EINVAL;
++	}
++
++	return fpga_region_program_fpga(region, firmware_name, nd->overlay);
++}
++
++/**
++ * fpga_region_notify_post_remove - post-remove overlay notification
++ *
++ * @region: FPGA region that was targeted by the overlay that was removed
++ * @nd: overlay notification data
++ *
++ * Called after an overlay has been removed if the overlay's target was a
++ * FPGA region.
++ */
++static void fpga_region_notify_post_remove(struct fpga_region *region,
++					   struct of_overlay_notify_data *nd)
++{
++	fpga_bridges_disable(&region->bridge_list);
++	fpga_bridges_put(&region->bridge_list);
++	devm_kfree(&region->dev, region->info);
++	region->info = NULL;
++}
++
++/**
++ * of_fpga_region_notify - reconfig notifier for dynamic DT changes
++ * @nb:		notifier block
++ * @action:	notifier action
++ * @arg:	reconfig data
++ *
++ * This notifier handles programming a FPGA when a "firmware-name" property is
++ * added to a fpga-region.
++ *
++ * Returns NOTIFY_OK or error if FPGA programming fails.
++ */
++static int of_fpga_region_notify(struct notifier_block *nb,
++				 unsigned long action, void *arg)
++{
++	struct of_overlay_notify_data *nd = arg;
++	struct fpga_region *region;
++	int ret;
++
++	switch (action) {
++	case OF_OVERLAY_PRE_APPLY:
++		pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
++		break;
++	case OF_OVERLAY_POST_APPLY:
++		pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
++		return NOTIFY_OK;       /* not for us */
++	case OF_OVERLAY_PRE_REMOVE:
++		pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
++		return NOTIFY_OK;       /* not for us */
++	case OF_OVERLAY_POST_REMOVE:
++		pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__);
++		break;
++	default:			/* should not happen */
++		return NOTIFY_OK;
++	}
++
++	region = fpga_region_find(nd->target);
++	if (!region)
++		return NOTIFY_OK;
++
++	ret = 0;
++	switch (action) {
++	case OF_OVERLAY_PRE_APPLY:
++		ret = fpga_region_notify_pre_apply(region, nd);
++		break;
++
++	case OF_OVERLAY_POST_REMOVE:
++		fpga_region_notify_post_remove(region, nd);
++		break;
++	}
++
++	put_device(&region->dev);
++
++	if (ret)
++		return notifier_from_errno(ret);
++
++	return NOTIFY_OK;
++}
++
++static struct notifier_block fpga_region_of_nb = {
++	.notifier_call = of_fpga_region_notify,
++};
++
++static int fpga_region_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct device_node *np = dev->of_node;
++	struct fpga_region *region;
++	int id, ret = 0;
++
++	region = kzalloc(sizeof(*region), GFP_KERNEL);
++	if (!region)
++		return -ENOMEM;
++
++	id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
++	if (id < 0) {
++		ret = id;
++		goto err_kfree;
++	}
++
++	mutex_init(&region->mutex);
++	INIT_LIST_HEAD(&region->bridge_list);
++
++	device_initialize(&region->dev);
++	region->dev.class = fpga_region_class;
++	region->dev.parent = dev;
++	region->dev.of_node = np;
++	region->dev.id = id;
++	dev_set_drvdata(dev, region);
++
++	ret = dev_set_name(&region->dev, "region%d", id);
++	if (ret)
++		goto err_remove;
++
++	ret = device_add(&region->dev);
++	if (ret)
++		goto err_remove;
++
++	of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
++
++	dev_info(dev, "FPGA Region probed\n");
++
++	return 0;
++
++err_remove:
++	ida_simple_remove(&fpga_region_ida, id);
++err_kfree:
++	kfree(region);
++
++	return ret;
++}
++
++static int fpga_region_remove(struct platform_device *pdev)
++{
++	struct fpga_region *region = platform_get_drvdata(pdev);
++
++	device_unregister(&region->dev);
++
++	return 0;
++}
++
++static struct platform_driver fpga_region_driver = {
++	.probe = fpga_region_probe,
++	.remove = fpga_region_remove,
++	.driver = {
++		.name	= "fpga-region",
++		.of_match_table = of_match_ptr(fpga_region_of_match),
++	},
++};
++
++static void fpga_region_dev_release(struct device *dev)
++{
++	struct fpga_region *region = to_fpga_region(dev);
++
++	ida_simple_remove(&fpga_region_ida, region->dev.id);
++	kfree(region);
++}
++
++/**
++ * fpga_region_init - init function for fpga_region class
++ * Creates the fpga_region class and registers a reconfig notifier.
++ */
++static int __init fpga_region_init(void)
++{
++	int ret;
++
++	fpga_region_class = class_create(THIS_MODULE, "fpga_region");
++	if (IS_ERR(fpga_region_class))
++		return PTR_ERR(fpga_region_class);
++
++	fpga_region_class->dev_release = fpga_region_dev_release;
++
++	ret = of_overlay_notifier_register(&fpga_region_of_nb);
++	if (ret)
++		goto err_class;
++
++	ret = platform_driver_register(&fpga_region_driver);
++	if (ret)
++		goto err_plat;
++
++	return 0;
++
++err_plat:
++	of_overlay_notifier_unregister(&fpga_region_of_nb);
++err_class:
++	class_destroy(fpga_region_class);
++	ida_destroy(&fpga_region_ida);
++	return ret;
++}
++
++static void __exit fpga_region_exit(void)
++{
++	platform_driver_unregister(&fpga_region_driver);
++	of_overlay_notifier_unregister(&fpga_region_of_nb);
++	class_destroy(fpga_region_class);
++	ida_destroy(&fpga_region_ida);
++}
++
++subsys_initcall(fpga_region_init);
++module_exit(fpga_region_exit);
++
++MODULE_DESCRIPTION("FPGA Region");
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_LICENSE("GPL v2");
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -65,8 +65,10 @@ enum fpga_mgr_states {
+ /*
+  * FPGA Manager flags
+  * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
++ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
+  */
+ #define FPGA_MGR_PARTIAL_RECONFIG	BIT(0)
++#define FPGA_MGR_EXTERNAL_CONFIG	BIT(1)
+ 
+ /**
+  * struct fpga_image_info - information specific to a FPGA image
diff --git a/patches.socfpga/0032-ARM-socfpga-fpga-bridge-driver-support.patch b/patches.socfpga/0032-ARM-socfpga-fpga-bridge-driver-support.patch
new file mode 100644
index 0000000..c5a8ca9
--- /dev/null
+++ b/patches.socfpga/0032-ARM-socfpga-fpga-bridge-driver-support.patch
@@ -0,0 +1,473 @@
+From ffe325ed88d349106ded4459366514e91fd1a175 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:30 -0500
+Subject: [PATCH 032/103] ARM: socfpga: fpga bridge driver support
+
+Supports Altera SOCFPGA bridges:
+ * fpga2sdram
+ * fpga2hps
+ * hps2fpga
+ * lwhps2fpga
+
+Allows enabling/disabling the bridges through the FPGA
+Bridge Framework API functions.
+
+The fpga2sdram driver only supports enabling and disabling
+of the ports that been configured early on.  This is due to
+a hardware limitation where the read, write, and command
+ports on the fpga2sdram bridge can only be reconfigured
+while there are no transactions to the sdram, i.e. when
+running out of OCRAM before the kernel boots.
+
+Device tree property 'init-val' configures the driver to
+enable or disable the bridge during probe.  If the property
+does not exist, the driver will leave the bridge in its
+current state.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig             |    7 +
+ drivers/fpga/Makefile            |    1 
+ drivers/fpga/altera-fpga2sdram.c |  180 +++++++++++++++++++++++++++++++
+ drivers/fpga/altera-hps2fpga.c   |  222 +++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 410 insertions(+)
+ create mode 100644 drivers/fpga/altera-fpga2sdram.c
+ create mode 100644 drivers/fpga/altera-hps2fpga.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -40,6 +40,13 @@ config FPGA_BRIDGE
+ 	  Say Y here if you want to support bridges connected between host
+ 	  processors and FPGAs or between FPGAs.
+ 
++config SOCFPGA_FPGA_BRIDGE
++	tristate "Altera SoCFPGA FPGA Bridges"
++	depends on ARCH_SOCFPGA && FPGA_BRIDGE
++	help
++	  Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
++	  devices.
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq
+ 
+ # FPGA Bridge Drivers
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
++obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
+ 
+ # High Level Interfaces
+ obj-$(CONFIG_FPGA_REGION)		+= fpga-region.o
+--- /dev/null
++++ b/drivers/fpga/altera-fpga2sdram.c
+@@ -0,0 +1,180 @@
++/*
++ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
++ *
++ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/*
++ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
++ * host processor system (HPS).
++ *
++ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
++ * Reconfiguring these ports requires that no SDRAM transactions occur during
++ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
++ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
++ * not support reconfiguring the ports.  The ports are configured by code
++ * running out of on chip ram before Linux is started and the configuration
++ * is passed in a handoff register in the system manager.
++ *
++ * This driver supports enabling and disabling of the configured ports, which
++ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
++ * uses the same port configuration.  Bridges must be disabled before
++ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
++ */
++
++#include <linux/fpga/fpga-bridge.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/regmap.h>
++
++#define ALT_SDR_CTL_FPGAPORTRST_OFST		0x80
++#define ALT_SDR_CTL_FPGAPORTRST_PORTRSTN_MSK	0x00003fff
++#define ALT_SDR_CTL_FPGAPORTRST_RD_SHIFT	0
++#define ALT_SDR_CTL_FPGAPORTRST_WR_SHIFT	4
++#define ALT_SDR_CTL_FPGAPORTRST_CTRL_SHIFT	8
++
++/*
++ * From the Cyclone V HPS Memory Map document:
++ *   These registers are used to store handoff information between the
++ *   preloader and the OS. These 8 registers can be used to store any
++ *   information. The contents of these registers have no impact on
++ *   the state of the HPS hardware.
++ */
++#define SYSMGR_ISWGRP_HANDOFF3          (0x8C)
++
++#define F2S_BRIDGE_NAME "fpga2sdram"
++
++struct alt_fpga2sdram_data {
++	struct device *dev;
++	struct regmap *sdrctl;
++	int mask;
++};
++
++static int alt_fpga2sdram_enable_show(struct fpga_bridge *bridge)
++{
++	struct alt_fpga2sdram_data *priv = bridge->priv;
++	int value;
++
++	regmap_read(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST, &value);
++
++	return (value & priv->mask) == priv->mask;
++}
++
++static inline int _alt_fpga2sdram_enable_set(struct alt_fpga2sdram_data *priv,
++					     bool enable)
++{
++	return regmap_update_bits(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST,
++				  priv->mask, enable ? priv->mask : 0);
++}
++
++static int alt_fpga2sdram_enable_set(struct fpga_bridge *bridge, bool enable)
++{
++	return _alt_fpga2sdram_enable_set(bridge->priv, enable);
++}
++
++struct prop_map {
++	char *prop_name;
++	u32 *prop_value;
++	u32 prop_max;
++};
++
++static const struct fpga_bridge_ops altera_fpga2sdram_br_ops = {
++	.enable_set = alt_fpga2sdram_enable_set,
++	.enable_show = alt_fpga2sdram_enable_show,
++};
++
++static const struct of_device_id altera_fpga_of_match[] = {
++	{ .compatible = "altr,socfpga-fpga2sdram-bridge" },
++	{},
++};
++
++static int alt_fpga_bridge_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct alt_fpga2sdram_data *priv;
++	u32 enable;
++	struct regmap *sysmgr;
++	int ret = 0;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->dev = dev;
++
++	priv->sdrctl = syscon_regmap_lookup_by_compatible("altr,sdr-ctl");
++	if (IS_ERR(priv->sdrctl)) {
++		dev_err(dev, "regmap for altr,sdr-ctl lookup failed.\n");
++		return PTR_ERR(priv->sdrctl);
++	}
++
++	sysmgr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
++	if (IS_ERR(priv->sdrctl)) {
++		dev_err(dev, "regmap for altr,sys-mgr lookup failed.\n");
++		return PTR_ERR(sysmgr);
++	}
++
++	/* Get f2s bridge configuration saved in handoff register */
++	regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
++
++	ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
++				   &altera_fpga2sdram_br_ops, priv);
++	if (ret)
++		return ret;
++
++	dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
++
++	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
++		if (enable > 1) {
++			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
++		} else {
++			dev_info(dev, "%s bridge\n",
++				 (enable ? "enabling" : "disabling"));
++			ret = _alt_fpga2sdram_enable_set(priv, enable);
++			if (ret) {
++				fpga_bridge_unregister(&pdev->dev);
++				return ret;
++			}
++		}
++	}
++
++	return ret;
++}
++
++static int alt_fpga_bridge_remove(struct platform_device *pdev)
++{
++	fpga_bridge_unregister(&pdev->dev);
++
++	return 0;
++}
++
++MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
++
++static struct platform_driver altera_fpga_driver = {
++	.probe = alt_fpga_bridge_probe,
++	.remove = alt_fpga_bridge_remove,
++	.driver = {
++		.name	= "altera_fpga2sdram_bridge",
++		.of_match_table = of_match_ptr(altera_fpga_of_match),
++	},
++};
++
++module_platform_driver(altera_fpga_driver);
++
++MODULE_DESCRIPTION("Altera SoCFPGA FPGA to SDRAM Bridge");
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/fpga/altera-hps2fpga.c
+@@ -0,0 +1,222 @@
++/*
++ * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
++ *
++ *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
++ *
++ * Includes this patch from the mailing list:
++ *   fpga: altera-hps2fpga: fix HPS2FPGA bridge visibility to L3 masters
++ *   Signed-off-by: Anatolij Gustschin <agust@denx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/*
++ * This driver manages bridges on a Altera SOCFPGA between the ARM host
++ * processor system (HPS) and the embedded FPGA.
++ *
++ * This driver supports enabling and disabling of the configured ports, which
++ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
++ * uses the same port configuration.  Bridges must be disabled before
++ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
++ */
++
++#include <linux/clk.h>
++#include <linux/fpga/fpga-bridge.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_platform.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/spinlock.h>
++
++#define ALT_L3_REMAP_OFST			0x0
++#define ALT_L3_REMAP_MPUZERO_MSK		0x00000001
++#define ALT_L3_REMAP_H2F_MSK			0x00000008
++#define ALT_L3_REMAP_LWH2F_MSK			0x00000010
++
++#define HPS2FPGA_BRIDGE_NAME			"hps2fpga"
++#define LWHPS2FPGA_BRIDGE_NAME			"lwhps2fpga"
++#define FPGA2HPS_BRIDGE_NAME			"fpga2hps"
++
++struct altera_hps2fpga_data {
++	const char *name;
++	struct reset_control *bridge_reset;
++	struct regmap *l3reg;
++	unsigned int remap_mask;
++	struct clk *clk;
++};
++
++static int alt_hps2fpga_enable_show(struct fpga_bridge *bridge)
++{
++	struct altera_hps2fpga_data *priv = bridge->priv;
++
++	return reset_control_status(priv->bridge_reset);
++}
++
++/* The L3 REMAP register is write only, so keep a cached value. */
++static unsigned int l3_remap_shadow;
++static spinlock_t l3_remap_lock;
++
++static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv,
++				    bool enable)
++{
++	unsigned long flags;
++	int ret;
++
++	/* bring bridge out of reset */
++	if (enable)
++		ret = reset_control_deassert(priv->bridge_reset);
++	else
++		ret = reset_control_assert(priv->bridge_reset);
++	if (ret)
++		return ret;
++
++	/* Allow bridge to be visible to L3 masters or not */
++	if (priv->remap_mask) {
++		spin_lock_irqsave(&l3_remap_lock, flags);
++		l3_remap_shadow |= ALT_L3_REMAP_MPUZERO_MSK;
++
++		if (enable)
++			l3_remap_shadow |= priv->remap_mask;
++		else
++			l3_remap_shadow &= ~priv->remap_mask;
++
++		ret = regmap_write(priv->l3reg, ALT_L3_REMAP_OFST,
++				   l3_remap_shadow);
++		spin_unlock_irqrestore(&l3_remap_lock, flags);
++	}
++
++	return ret;
++}
++
++static int alt_hps2fpga_enable_set(struct fpga_bridge *bridge, bool enable)
++{
++	return _alt_hps2fpga_enable_set(bridge->priv, enable);
++}
++
++static const struct fpga_bridge_ops altera_hps2fpga_br_ops = {
++	.enable_set = alt_hps2fpga_enable_set,
++	.enable_show = alt_hps2fpga_enable_show,
++};
++
++static struct altera_hps2fpga_data hps2fpga_data  = {
++	.name = HPS2FPGA_BRIDGE_NAME,
++	.remap_mask = ALT_L3_REMAP_H2F_MSK,
++};
++
++static struct altera_hps2fpga_data lwhps2fpga_data  = {
++	.name = LWHPS2FPGA_BRIDGE_NAME,
++	.remap_mask = ALT_L3_REMAP_LWH2F_MSK,
++};
++
++static struct altera_hps2fpga_data fpga2hps_data  = {
++	.name = FPGA2HPS_BRIDGE_NAME,
++};
++
++static const struct of_device_id altera_fpga_of_match[] = {
++	{ .compatible = "altr,socfpga-hps2fpga-bridge",
++	  .data = &hps2fpga_data },
++	{ .compatible = "altr,socfpga-lwhps2fpga-bridge",
++	  .data = &lwhps2fpga_data },
++	{ .compatible = "altr,socfpga-fpga2hps-bridge",
++	  .data = &fpga2hps_data },
++	{},
++};
++
++static int alt_fpga_bridge_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct altera_hps2fpga_data *priv;
++	const struct of_device_id *of_id;
++	u32 enable;
++	int ret;
++
++	of_id = of_match_device(altera_fpga_of_match, dev);
++	priv = (struct altera_hps2fpga_data *)of_id->data;
++
++	priv->bridge_reset = of_reset_control_get_by_index(dev->of_node, 0);
++	if (IS_ERR(priv->bridge_reset)) {
++		dev_err(dev, "Could not get %s reset control\n", priv->name);
++		return PTR_ERR(priv->bridge_reset);
++	}
++
++	if (priv->remap_mask) {
++		priv->l3reg = syscon_regmap_lookup_by_compatible("altr,l3regs");
++		if (IS_ERR(priv->l3reg)) {
++			dev_err(dev, "regmap for altr,l3regs lookup failed\n");
++			return PTR_ERR(priv->l3reg);
++		}
++	}
++
++	priv->clk = devm_clk_get(dev, NULL);
++	if (IS_ERR(priv->clk)) {
++		dev_err(dev, "no clock specified\n");
++		return PTR_ERR(priv->clk);
++	}
++
++	ret = clk_prepare_enable(priv->clk);
++	if (ret) {
++		dev_err(dev, "could not enable clock\n");
++		return -EBUSY;
++	}
++
++	spin_lock_init(&l3_remap_lock);
++
++	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
++		if (enable > 1) {
++			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
++		} else {
++			dev_info(dev, "%s bridge\n",
++				 (enable ? "enabling" : "disabling"));
++
++			ret = _alt_hps2fpga_enable_set(priv, enable);
++			if (ret) {
++				fpga_bridge_unregister(&pdev->dev);
++				return ret;
++			}
++		}
++	}
++
++	return fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
++				    priv);
++}
++
++static int alt_fpga_bridge_remove(struct platform_device *pdev)
++{
++	struct fpga_bridge *bridge = platform_get_drvdata(pdev);
++	struct altera_hps2fpga_data *priv = bridge->priv;
++
++	fpga_bridge_unregister(&pdev->dev);
++
++	clk_disable_unprepare(priv->clk);
++
++	return 0;
++}
++
++MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
++
++static struct platform_driver alt_fpga_bridge_driver = {
++	.probe = alt_fpga_bridge_probe,
++	.remove = alt_fpga_bridge_remove,
++	.driver = {
++		.name	= "altera_hps2fpga_bridge",
++		.of_match_table = of_match_ptr(altera_fpga_of_match),
++	},
++};
++
++module_platform_driver(alt_fpga_bridge_driver);
++
++MODULE_DESCRIPTION("Altera SoCFPGA HPS to FPGA Bridge");
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0033-fpga-add-altera-freeze-bridge-support.patch b/patches.socfpga/0033-fpga-add-altera-freeze-bridge-support.patch
new file mode 100644
index 0000000..f63baf1
--- /dev/null
+++ b/patches.socfpga/0033-fpga-add-altera-freeze-bridge-support.patch
@@ -0,0 +1,324 @@
+From cd1d46154270d9ee1e740b310999ae0bb7449e21 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:31 -0500
+Subject: [PATCH 033/103] fpga: add altera freeze bridge support
+
+Add a low level driver for Altera Freeze Bridges to the FPGA Bridge
+framework.  A freeze bridge is a bridge that exists in the FPGA
+fabric to isolate one region of the FPGA from the busses while that
+one region is being reprogrammed.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Matthew Gerlach <mgerlach@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig                |    9 +
+ drivers/fpga/Makefile               |    1 
+ drivers/fpga/altera-freeze-bridge.c |  273 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 283 insertions(+)
+ create mode 100644 drivers/fpga/altera-freeze-bridge.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -47,6 +47,15 @@ config SOCFPGA_FPGA_BRIDGE
+ 	  Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+ 	  devices.
+ 
++config ALTERA_FREEZE_BRIDGE
++	tristate "Altera FPGA Freeze Bridge"
++	depends on ARCH_SOCFPGA && FPGA_BRIDGE
++	help
++	  Say Y to enable drivers for Altera FPGA Freeze bridges.  A
++	  freeze bridge is a bridge that exists in the FPGA fabric to
++	  isolate one region of the FPGA from the busses while that
++	  region is being reprogrammed.
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -12,6 +12,7 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq
+ # FPGA Bridge Drivers
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+ obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
++obj-$(CONFIG_ALTERA_FREEZE_BRIDGE)	+= altera-freeze-bridge.o
+ 
+ # High Level Interfaces
+ obj-$(CONFIG_FPGA_REGION)		+= fpga-region.o
+--- /dev/null
++++ b/drivers/fpga/altera-freeze-bridge.c
+@@ -0,0 +1,273 @@
++/*
++ * FPGA Freeze Bridge Controller
++ *
++ *  Copyright (C) 2016 Altera Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/of_device.h>
++#include <linux/module.h>
++#include <linux/fpga/fpga-bridge.h>
++
++#define FREEZE_CSR_STATUS_OFFSET		0
++#define FREEZE_CSR_CTRL_OFFSET			4
++#define FREEZE_CSR_ILLEGAL_REQ_OFFSET		8
++#define FREEZE_CSR_REG_VERSION			12
++
++#define FREEZE_CSR_SUPPORTED_VERSION		2
++
++#define FREEZE_CSR_STATUS_FREEZE_REQ_DONE	BIT(0)
++#define FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE	BIT(1)
++
++#define FREEZE_CSR_CTRL_FREEZE_REQ		BIT(0)
++#define FREEZE_CSR_CTRL_RESET_REQ		BIT(1)
++#define FREEZE_CSR_CTRL_UNFREEZE_REQ		BIT(2)
++
++#define FREEZE_BRIDGE_NAME			"freeze"
++
++struct altera_freeze_br_data {
++	struct device *dev;
++	void __iomem *base_addr;
++	bool enable;
++};
++
++/*
++ * Poll status until status bit is set or we have a timeout.
++ */
++static int altera_freeze_br_req_ack(struct altera_freeze_br_data *priv,
++				    u32 timeout, u32 req_ack)
++{
++	struct device *dev = priv->dev;
++	void __iomem *csr_illegal_req_addr = priv->base_addr +
++					     FREEZE_CSR_ILLEGAL_REQ_OFFSET;
++	u32 status, illegal, ctrl;
++	int ret = -ETIMEDOUT;
++
++	do {
++		illegal = readl(csr_illegal_req_addr);
++		if (illegal) {
++			dev_err(dev, "illegal request detected 0x%x", illegal);
++
++			writel(1, csr_illegal_req_addr);
++
++			illegal = readl(csr_illegal_req_addr);
++			if (illegal)
++				dev_err(dev, "illegal request not cleared 0x%x",
++					illegal);
++
++			ret = -EINVAL;
++			break;
++		}
++
++		status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++		dev_dbg(dev, "%s %x %x\n", __func__, status, req_ack);
++		status &= req_ack;
++		if (status) {
++			ctrl = readl(priv->base_addr + FREEZE_CSR_CTRL_OFFSET);
++			dev_dbg(dev, "%s request %x acknowledged %x %x\n",
++				__func__, req_ack, status, ctrl);
++			ret = 0;
++			break;
++		}
++
++		udelay(1);
++	} while (timeout--);
++
++	if (ret == -ETIMEDOUT)
++		dev_err(dev, "%s timeout waiting for 0x%x\n",
++			__func__, req_ack);
++
++	return ret;
++}
++
++static int altera_freeze_br_do_freeze(struct altera_freeze_br_data *priv,
++				      u32 timeout)
++{
++	struct device *dev = priv->dev;
++	void __iomem *csr_ctrl_addr = priv->base_addr +
++				      FREEZE_CSR_CTRL_OFFSET;
++	u32 status;
++	int ret;
++
++	status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++
++	dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
++
++	if (status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE) {
++		dev_dbg(dev, "%s bridge already disabled %d\n",
++			__func__, status);
++		return 0;
++	} else if (!(status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)) {
++		dev_err(dev, "%s bridge not enabled %d\n", __func__, status);
++		return -EINVAL;
++	}
++
++	writel(FREEZE_CSR_CTRL_FREEZE_REQ, csr_ctrl_addr);
++
++	ret = altera_freeze_br_req_ack(priv, timeout,
++				       FREEZE_CSR_STATUS_FREEZE_REQ_DONE);
++
++	if (ret)
++		writel(0, csr_ctrl_addr);
++	else
++		writel(FREEZE_CSR_CTRL_RESET_REQ, csr_ctrl_addr);
++
++	return ret;
++}
++
++static int altera_freeze_br_do_unfreeze(struct altera_freeze_br_data *priv,
++					u32 timeout)
++{
++	struct device *dev = priv->dev;
++	void __iomem *csr_ctrl_addr = priv->base_addr +
++				      FREEZE_CSR_CTRL_OFFSET;
++	u32 status;
++	int ret;
++
++	writel(0, csr_ctrl_addr);
++
++	status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++
++	dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
++
++	if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE) {
++		dev_dbg(dev, "%s bridge already enabled %d\n",
++			__func__, status);
++		return 0;
++	} else if (!(status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE)) {
++		dev_err(dev, "%s bridge not frozen %d\n", __func__, status);
++		return -EINVAL;
++	}
++
++	writel(FREEZE_CSR_CTRL_UNFREEZE_REQ, csr_ctrl_addr);
++
++	ret = altera_freeze_br_req_ack(priv, timeout,
++				       FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE);
++
++	status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++
++	dev_dbg(dev, "%s %d %d\n", __func__, status, readl(csr_ctrl_addr));
++
++	writel(0, csr_ctrl_addr);
++
++	return ret;
++}
++
++/*
++ * enable = 1 : allow traffic through the bridge
++ * enable = 0 : disable traffic through the bridge
++ */
++static int altera_freeze_br_enable_set(struct fpga_bridge *bridge,
++				       bool enable)
++{
++	struct altera_freeze_br_data *priv = bridge->priv;
++	struct fpga_image_info *info = bridge->info;
++	u32 timeout = 0;
++	int ret;
++
++	if (enable) {
++		if (info)
++			timeout = info->enable_timeout_us;
++
++		ret = altera_freeze_br_do_unfreeze(bridge->priv, timeout);
++	} else {
++		if (info)
++			timeout = info->disable_timeout_us;
++
++		ret = altera_freeze_br_do_freeze(bridge->priv, timeout);
++	}
++
++	if (!ret)
++		priv->enable = enable;
++
++	return ret;
++}
++
++static int altera_freeze_br_enable_show(struct fpga_bridge *bridge)
++{
++	struct altera_freeze_br_data *priv = bridge->priv;
++
++	return priv->enable;
++}
++
++static struct fpga_bridge_ops altera_freeze_br_br_ops = {
++	.enable_set = altera_freeze_br_enable_set,
++	.enable_show = altera_freeze_br_enable_show,
++};
++
++static const struct of_device_id altera_freeze_br_of_match[] = {
++	{ .compatible = "altr,freeze-bridge-controller", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, altera_freeze_br_of_match);
++
++static int altera_freeze_br_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct device_node *np = pdev->dev.of_node;
++	struct altera_freeze_br_data *priv;
++	struct resource *res;
++	u32 status, revision;
++
++	if (!np)
++		return -ENODEV;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->dev = dev;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	priv->base_addr = devm_ioremap_resource(dev, res);
++	if (IS_ERR(priv->base_addr))
++		return PTR_ERR(priv->base_addr);
++
++	status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++	if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)
++		priv->enable = 1;
++
++	revision = readl(priv->base_addr + FREEZE_CSR_REG_VERSION);
++	if (revision != FREEZE_CSR_SUPPORTED_VERSION)
++		dev_warn(dev,
++			 "%s Freeze Controller unexpected revision %d != %d\n",
++			 __func__, revision, FREEZE_CSR_SUPPORTED_VERSION);
++
++	return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
++				    &altera_freeze_br_br_ops, priv);
++}
++
++static int altera_freeze_br_remove(struct platform_device *pdev)
++{
++	fpga_bridge_unregister(&pdev->dev);
++
++	return 0;
++}
++
++static struct platform_driver altera_freeze_br_driver = {
++	.probe = altera_freeze_br_probe,
++	.remove = altera_freeze_br_remove,
++	.driver = {
++		.name	= "altera_freeze_br",
++		.of_match_table = of_match_ptr(altera_freeze_br_of_match),
++	},
++};
++
++module_platform_driver(altera_freeze_br_driver);
++
++MODULE_DESCRIPTION("Altera Freeze Bridge");
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0034-fpga-manager-Add-Socfpga-Arria10-support.patch b/patches.socfpga/0034-fpga-manager-Add-Socfpga-Arria10-support.patch
new file mode 100644
index 0000000..7eed0ff
--- /dev/null
+++ b/patches.socfpga/0034-fpga-manager-Add-Socfpga-Arria10-support.patch
@@ -0,0 +1,602 @@
+From d2d6523f3ef50daee666b364d8438de62ed5a40b Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 1 Nov 2016 14:14:32 -0500
+Subject: [PATCH 034/103] fpga-manager: Add Socfpga Arria10 support
+
+Add low level driver to support reprogramming FPGAs for Altera
+SoCFPGA Arria10.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Reviewed-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig       |    6 
+ drivers/fpga/Makefile      |    1 
+ drivers/fpga/socfpga-a10.c |  556 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 563 insertions(+)
+ create mode 100644 drivers/fpga/socfpga-a10.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -26,6 +26,12 @@ config FPGA_MGR_SOCFPGA
+ 	help
+ 	  FPGA manager driver support for Altera SOCFPGA.
+ 
++config FPGA_MGR_SOCFPGA_A10
++	tristate "Altera SoCFPGA Arria10"
++	depends on ARCH_SOCFPGA
++	help
++	  FPGA manager driver support for Altera Arria10 SoCFPGA.
++
+ config FPGA_MGR_ZYNQ_FPGA
+ 	tristate "Xilinx Zynq FPGA"
+ 	depends on ARCH_ZYNQ || COMPILE_TEST
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
+ 
+ # FPGA Manager Drivers
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
++obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+ 
+ # FPGA Bridge Drivers
+--- /dev/null
++++ b/drivers/fpga/socfpga-a10.c
+@@ -0,0 +1,556 @@
++/*
++ * FPGA Manager Driver for Altera Arria10 SoCFPGA
++ *
++ * Copyright (C) 2015-2016 Altera Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/delay.h>
++#include <linux/fpga/fpga-mgr.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/regmap.h>
++
++#define A10_FPGAMGR_DCLKCNT_OFST				0x08
++#define A10_FPGAMGR_DCLKSTAT_OFST				0x0c
++#define A10_FPGAMGR_IMGCFG_CTL_00_OFST				0x70
++#define A10_FPGAMGR_IMGCFG_CTL_01_OFST				0x74
++#define A10_FPGAMGR_IMGCFG_CTL_02_OFST				0x78
++#define A10_FPGAMGR_IMGCFG_STAT_OFST				0x80
++
++#define A10_FPGAMGR_DCLKSTAT_DCLKDONE				BIT(0)
++
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG		BIT(0)
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS		BIT(1)
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE		BIT(2)
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG			BIT(8)
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE		BIT(16)
++#define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE		BIT(24)
++
++#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG		BIT(0)
++#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST		BIT(16)
++#define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE			BIT(24)
++
++#define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL			BIT(0)
++#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK		(BIT(16) | BIT(17))
++#define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT			16
++#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH			BIT(24)
++#define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT		24
++
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR			BIT(0)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE		BIT(1)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE			BIT(2)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN			BIT(4)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN			BIT(6)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY			BIT(9)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE			BIT(10)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR			BIT(11)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN			BIT(12)
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK	(BIT(16) | BIT(17) | BIT(18))
++#define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT		        16
++
++/* FPGA CD Ratio Value */
++#define CDRATIO_x1						0x0
++#define CDRATIO_x2						0x1
++#define CDRATIO_x4						0x2
++#define CDRATIO_x8						0x3
++
++/* Configuration width 16/32 bit */
++#define CFGWDTH_32						1
++#define CFGWDTH_16						0
++
++/*
++ * struct a10_fpga_priv - private data for fpga manager
++ * @regmap: regmap for register access
++ * @fpga_data_addr: iomap for single address data register to FPGA
++ * @clk: clock
++ */
++struct a10_fpga_priv {
++	struct regmap *regmap;
++	void __iomem *fpga_data_addr;
++	struct clk *clk;
++};
++
++static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg)
++{
++	switch (reg) {
++	case A10_FPGAMGR_DCLKCNT_OFST:
++	case A10_FPGAMGR_DCLKSTAT_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
++		return true;
++	}
++	return false;
++}
++
++static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg)
++{
++	switch (reg) {
++	case A10_FPGAMGR_DCLKCNT_OFST:
++	case A10_FPGAMGR_DCLKSTAT_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
++	case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
++	case A10_FPGAMGR_IMGCFG_STAT_OFST:
++		return true;
++	}
++	return false;
++}
++
++static const struct regmap_config socfpga_a10_fpga_regmap_config = {
++	.reg_bits = 32,
++	.reg_stride = 4,
++	.val_bits = 32,
++	.writeable_reg = socfpga_a10_fpga_writeable_reg,
++	.readable_reg = socfpga_a10_fpga_readable_reg,
++	.max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
++	.cache_type = REGCACHE_NONE,
++};
++
++/*
++ * from the register map description of cdratio in imgcfg_ctrl_02:
++ *  Normal Configuration    : 32bit Passive Parallel
++ *  Partial Reconfiguration : 16bit Passive Parallel
++ */
++static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
++					   int width)
++{
++	width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;
++
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
++}
++
++static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
++					    u32 count)
++{
++	u32 val;
++
++	/* Clear any existing DONE status. */
++	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
++		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
++
++	/* Issue the DCLK regmap. */
++	regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);
++
++	/* wait till the dclkcnt done */
++	regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
++				 val, 1, 100);
++
++	/* Clear DONE status. */
++	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
++		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
++}
++
++#define RBF_ENCRYPTION_MODE_OFFSET		69
++#define RBF_DECOMPRESS_OFFSET			229
++
++static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
++{
++	if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
++		return -EINVAL;
++
++	/* Is the bitstream encrypted? */
++	return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
++}
++
++static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size)
++{
++	if (buf32_size < RBF_DECOMPRESS_OFFSET + 1)
++		return -EINVAL;
++
++	/* Is the bitstream compressed? */
++	return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1);
++}
++
++static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width,
++						  bool encrypt, bool compress)
++{
++	unsigned int cd_ratio;
++
++	/*
++	 * cd ratio is dependent on cfg width and whether the bitstream
++	 * is encrypted and/or compressed.
++	 *
++	 * | width | encr. | compr. | cd ratio |
++	 * |  16   |   0   |   0    |     1    |
++	 * |  16   |   0   |   1    |     4    |
++	 * |  16   |   1   |   0    |     2    |
++	 * |  16   |   1   |   1    |     4    |
++	 * |  32   |   0   |   0    |     1    |
++	 * |  32   |   0   |   1    |     8    |
++	 * |  32   |   1   |   0    |     4    |
++	 * |  32   |   1   |   1    |     8    |
++	 */
++	if (!compress && !encrypt)
++		return CDRATIO_x1;
++
++	if (compress)
++		cd_ratio = CDRATIO_x4;
++	else
++		cd_ratio = CDRATIO_x2;
++
++	/* If 32 bit, double the cd ratio by incrementing the field  */
++	if (cfg_width == CFGWDTH_32)
++		cd_ratio += 1;
++
++	return cd_ratio;
++}
++
++static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr,
++					unsigned int cfg_width,
++					const char *buf, size_t count)
++{
++	struct a10_fpga_priv *priv = mgr->priv;
++	unsigned int cd_ratio;
++	int encrypt, compress;
++
++	encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4);
++	if (encrypt < 0)
++		return -EINVAL;
++
++	compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4);
++	if (compress < 0)
++		return -EINVAL;
++
++	cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress);
++
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK,
++			   cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT);
++
++	return 0;
++}
++
++static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv)
++{
++	u32 val;
++
++	regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val);
++
++	return val;
++}
++
++static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv)
++{
++	u32 reg, i;
++
++	for (i = 0; i < 10 ; i++) {
++		reg = socfpga_a10_fpga_read_stat(priv);
++
++		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
++			return -EINVAL;
++
++		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
++			return 0;
++	}
++
++	return -ETIMEDOUT;
++}
++
++static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv)
++{
++	u32 reg, i;
++
++	for (i = 0; i < 10 ; i++) {
++		reg = socfpga_a10_fpga_read_stat(priv);
++
++		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
++			return -EINVAL;
++
++		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE)
++			return 0;
++	}
++
++	return -ETIMEDOUT;
++}
++
++/* Start the FPGA programming by initialize the FPGA Manager */
++static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
++				       struct fpga_image_info *info,
++				       const char *buf, size_t count)
++{
++	struct a10_fpga_priv *priv = mgr->priv;
++	unsigned int cfg_width;
++	u32 msel, stat, mask;
++	int ret;
++
++	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
++		cfg_width = CFGWDTH_16;
++	else
++		return -EINVAL;
++
++	/* Check for passive parallel (msel == 000 or 001) */
++	msel = socfpga_a10_fpga_read_stat(priv);
++	msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
++	msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
++	if ((msel != 0) && (msel != 1)) {
++		dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
++		return -EINVAL;
++	}
++
++	/* Make sure no external devices are interfering */
++	stat = socfpga_a10_fpga_read_stat(priv);
++	mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
++	       A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
++	if ((stat & mask) != mask)
++		return -EINVAL;
++
++	/* Set cfg width */
++	socfpga_a10_fpga_set_cfg_width(priv, cfg_width);
++
++	/* Determine cd ratio from bitstream header and set cd ratio */
++	ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
++	if (ret)
++		return ret;
++
++	/*
++	 * Clear s2f_nce to enable chip select.  Leave pr_request
++	 * unasserted and override disabled.
++	 */
++	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++		     A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
++
++	/* Set cfg_ctrl to enable s2f dclk and data */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
++			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);
++
++	/*
++	 * Disable overrides not needed for pr.
++	 * s2f_config==1 leaves reset deasseted.
++	 */
++	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
++		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
++		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
++		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
++		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);
++
++	/* Enable override for data, dclk, nce, and pr_request to CSS */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);
++
++	/* Send some clocks to clear out any errors */
++	socfpga_a10_fpga_generate_dclks(priv, 256);
++
++	/* Assert pr_request */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);
++
++	/* Provide 2048 DCLKs before starting the config data streaming. */
++	socfpga_a10_fpga_generate_dclks(priv, 0x7ff);
++
++	/* Wait for pr_ready */
++	return socfpga_a10_fpga_wait_for_pr_ready(priv);
++}
++
++/*
++ * write data to the FPGA data register
++ */
++static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf,
++				  size_t count)
++{
++	struct a10_fpga_priv *priv = mgr->priv;
++	u32 *buffer_32 = (u32 *)buf;
++	size_t i = 0;
++
++	if (count <= 0)
++		return -EINVAL;
++
++	/* Write out the complete 32-bit chunks */
++	while (count >= sizeof(u32)) {
++		writel(buffer_32[i++], priv->fpga_data_addr);
++		count -= sizeof(u32);
++	}
++
++	/* Write out remaining non 32-bit chunks */
++	switch (count) {
++	case 3:
++		writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr);
++		break;
++	case 2:
++		writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr);
++		break;
++	case 1:
++		writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr);
++		break;
++	case 0:
++		break;
++	default:
++		/* This will never happen */
++		return -EFAULT;
++	}
++
++	return 0;
++}
++
++static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr,
++					   struct fpga_image_info *info)
++{
++	struct a10_fpga_priv *priv = mgr->priv;
++	u32 reg;
++	int ret;
++
++	/* Wait for pr_done */
++	ret = socfpga_a10_fpga_wait_for_pr_done(priv);
++
++	/* Clear pr_request */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0);
++
++	/* Send some clocks to clear out any errors */
++	socfpga_a10_fpga_generate_dclks(priv, 256);
++
++	/* Disable s2f dclk and data */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0);
++
++	/* Deassert chip select */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE);
++
++	/* Disable data, dclk, nce, and pr_request override to CSS */
++	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG,
++			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
++
++	/* Return any errors regarding pr_done or pr_error */
++	if (ret)
++		return ret;
++
++	/* Final check */
++	reg = socfpga_a10_fpga_read_stat(priv);
++
++	if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) ||
++	    ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) ||
++	    ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) {
++		dev_dbg(&mgr->dev,
++			"Timeout in final check. Status=%08xf\n", reg);
++		return -ETIMEDOUT;
++	}
++
++	return 0;
++}
++
++static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
++{
++	struct a10_fpga_priv *priv = mgr->priv;
++	u32 reg = socfpga_a10_fpga_read_stat(priv);
++
++	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)
++		return FPGA_MGR_STATE_OPERATING;
++
++	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
++		return FPGA_MGR_STATE_WRITE;
++
++	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR)
++		return FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
++
++	if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)
++		return FPGA_MGR_STATE_RESET;
++
++	return FPGA_MGR_STATE_UNKNOWN;
++}
++
++static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
++	.state = socfpga_a10_fpga_state,
++	.write_init = socfpga_a10_fpga_write_init,
++	.write = socfpga_a10_fpga_write,
++	.write_complete = socfpga_a10_fpga_write_complete,
++};
++
++static int socfpga_a10_fpga_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct a10_fpga_priv *priv;
++	void __iomem *reg_base;
++	struct resource *res;
++	int ret;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	/* First mmio base is for register access */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	reg_base = devm_ioremap_resource(dev, res);
++	if (IS_ERR(reg_base))
++		return PTR_ERR(reg_base);
++
++	/* Second mmio base is for writing FPGA image data */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++	priv->fpga_data_addr = devm_ioremap_resource(dev, res);
++	if (IS_ERR(priv->fpga_data_addr))
++		return PTR_ERR(priv->fpga_data_addr);
++
++	/* regmap for register access */
++	priv->regmap = devm_regmap_init_mmio(dev, reg_base,
++					     &socfpga_a10_fpga_regmap_config);
++	if (IS_ERR(priv->regmap))
++		return -ENODEV;
++
++	priv->clk = devm_clk_get(dev, NULL);
++	if (IS_ERR(priv->clk)) {
++		dev_err(dev, "no clock specified\n");
++		return PTR_ERR(priv->clk);
++	}
++
++	ret = clk_prepare_enable(priv->clk);
++	if (ret) {
++		dev_err(dev, "could not enable clock\n");
++		return -EBUSY;
++	}
++
++	return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
++				 &socfpga_a10_fpga_mgr_ops, priv);
++}
++
++static int socfpga_a10_fpga_remove(struct platform_device *pdev)
++{
++	struct fpga_manager *mgr = platform_get_drvdata(pdev);
++	struct a10_fpga_priv *priv = mgr->priv;
++
++	fpga_mgr_unregister(&pdev->dev);
++	clk_disable_unprepare(priv->clk);
++
++	return 0;
++}
++
++static const struct of_device_id socfpga_a10_fpga_of_match[] = {
++	{ .compatible = "altr,socfpga-a10-fpga-mgr", },
++	{},
++};
++
++MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match);
++
++static struct platform_driver socfpga_a10_fpga_driver = {
++	.probe = socfpga_a10_fpga_probe,
++	.remove = socfpga_a10_fpga_remove,
++	.driver = {
++		.name	= "socfpga_a10_fpga_manager",
++		.of_match_table = socfpga_a10_fpga_of_match,
++	},
++};
++
++module_platform_driver(socfpga_a10_fpga_driver);
++
++MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
++MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0035-ARM-socfpga-checking-the-wrong-variable.patch b/patches.socfpga/0035-ARM-socfpga-checking-the-wrong-variable.patch
new file mode 100644
index 0000000..91fbf44
--- /dev/null
+++ b/patches.socfpga/0035-ARM-socfpga-checking-the-wrong-variable.patch
@@ -0,0 +1,27 @@
+From 66990794c5c8e372ef07dd76272f5ac550e5be74 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 16 Nov 2016 19:54:40 -0600
+Subject: [PATCH 035/103] ARM: socfpga: checking the wrong variable
+
+This is a cut and paste bug.  We had intended to check "sysmgr".
+
+Fixes: e5f8efa5c8bf ("ARM: socfpga: fpga bridge driver support")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/altera-fpga2sdram.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/fpga/altera-fpga2sdram.c
++++ b/drivers/fpga/altera-fpga2sdram.c
+@@ -123,7 +123,7 @@ static int alt_fpga_bridge_probe(struct
+ 	}
+ 
+ 	sysmgr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+-	if (IS_ERR(priv->sdrctl)) {
++	if (IS_ERR(sysmgr)) {
+ 		dev_err(dev, "regmap for altr,sys-mgr lookup failed.\n");
+ 		return PTR_ERR(sysmgr);
+ 	}
diff --git a/patches.socfpga/0036-fpga-Add-COMPILE_TEST-to-all-drivers.patch b/patches.socfpga/0036-fpga-Add-COMPILE_TEST-to-all-drivers.patch
new file mode 100644
index 0000000..be90b9b
--- /dev/null
+++ b/patches.socfpga/0036-fpga-Add-COMPILE_TEST-to-all-drivers.patch
@@ -0,0 +1,36 @@
+From 9ab5031fea8fa46c96663d537ad0652d944cf880 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Mon, 21 Nov 2016 22:26:42 +0000
+Subject: [PATCH 036/103] fpga: Add COMPILE_TEST to all drivers
+
+Like Zynq the Altera drivers compile fine on x86 and others too,
+so make it easier to compile test this stuff.
+
+A10 requires REGMAP_MMIO to compile, so be explicit rather than
+relying on it via ARCH_SOCFPGA.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+---
+ drivers/fpga/Kconfig |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -22,13 +22,14 @@ config FPGA_REGION
+ 
+ config FPGA_MGR_SOCFPGA
+ 	tristate "Altera SOCFPGA FPGA Manager"
+-	depends on ARCH_SOCFPGA
++	depends on ARCH_SOCFPGA || COMPILE_TEST
+ 	help
+ 	  FPGA manager driver support for Altera SOCFPGA.
+ 
+ config FPGA_MGR_SOCFPGA_A10
+ 	tristate "Altera SoCFPGA Arria10"
+-	depends on ARCH_SOCFPGA
++	depends on ARCH_SOCFPGA || COMPILE_TEST
++	select REGMAP_MMIO
+ 	help
+ 	  FPGA manager driver support for Altera Arria10 SoCFPGA.
+ 
diff --git a/patches.socfpga/0037-fpga-zynq-Add-missing-n-to-messages.patch b/patches.socfpga/0037-fpga-zynq-Add-missing-n-to-messages.patch
new file mode 100644
index 0000000..0a8a31a
--- /dev/null
+++ b/patches.socfpga/0037-fpga-zynq-Add-missing-n-to-messages.patch
@@ -0,0 +1,112 @@
+From 5dc43314ce4663a705a0a91a3ad6e9aba3457de1 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Mon, 21 Nov 2016 22:26:43 +0000
+Subject: [PATCH 037/103] fpga zynq: Add missing \n to messages
+
+Function dev_err doesn't add a newline at the end of the string. This will
+lead to a hard to read kernel log.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Reviewed-by: Moritz Fischer <moritz.fischer@ettus.com>
+Reviewed-by: Matthias Brugger <mbrugger@suse.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+---
+ drivers/fpga/zynq-fpga.c |   22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -218,7 +218,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
++			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 
+@@ -232,7 +232,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for !PCFG_INIT");
++			dev_err(priv->dev, "Timeout waiting for !PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 
+@@ -246,7 +246,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for PCFG_INIT");
++			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 	}
+@@ -263,7 +263,7 @@ static int zynq_fpga_ops_write_init(stru
+ 	/* check that we have room in the command queue */
+ 	status = zynq_fpga_read(priv, STATUS_OFFSET);
+ 	if (status & STATUS_DMA_Q_F) {
+-		dev_err(priv->dev, "DMA command queue full");
++		dev_err(priv->dev, "DMA command queue full\n");
+ 		err = -EBUSY;
+ 		goto out_err;
+ 	}
+@@ -332,7 +332,7 @@ static int zynq_fpga_ops_write(struct fp
+ 	zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
+ 
+ 	if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
+-		dev_err(priv->dev, "Error configuring FPGA");
++		dev_err(priv->dev, "Error configuring FPGA\n");
+ 		err = -EFAULT;
+ 	}
+ 
+@@ -428,7 +428,7 @@ static int zynq_fpga_probe(struct platfo
+ 	priv->slcr = syscon_regmap_lookup_by_phandle(dev->of_node,
+ 		"syscon");
+ 	if (IS_ERR(priv->slcr)) {
+-		dev_err(dev, "unable to get zynq-slcr regmap");
++		dev_err(dev, "unable to get zynq-slcr regmap\n");
+ 		return PTR_ERR(priv->slcr);
+ 	}
+ 
+@@ -436,26 +436,26 @@ static int zynq_fpga_probe(struct platfo
+ 
+ 	priv->irq = platform_get_irq(pdev, 0);
+ 	if (priv->irq < 0) {
+-		dev_err(dev, "No IRQ available");
++		dev_err(dev, "No IRQ available\n");
+ 		return priv->irq;
+ 	}
+ 
+ 	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
+ 			       dev_name(dev), priv);
+ 	if (err) {
+-		dev_err(dev, "unable to request IRQ");
++		dev_err(dev, "unable to request IRQ\n");
+ 		return err;
+ 	}
+ 
+ 	priv->clk = devm_clk_get(dev, "ref_clk");
+ 	if (IS_ERR(priv->clk)) {
+-		dev_err(dev, "input clock not found");
++		dev_err(dev, "input clock not found\n");
+ 		return PTR_ERR(priv->clk);
+ 	}
+ 
+ 	err = clk_prepare_enable(priv->clk);
+ 	if (err) {
+-		dev_err(dev, "unable to enable clock");
++		dev_err(dev, "unable to enable clock\n");
+ 		return err;
+ 	}
+ 
+@@ -467,7 +467,7 @@ static int zynq_fpga_probe(struct platfo
+ 	err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
+ 				&zynq_fpga_ops, priv);
+ 	if (err) {
+-		dev_err(dev, "unable to register FPGA manager");
++		dev_err(dev, "unable to register FPGA manager\n");
+ 		clk_unprepare(priv->clk);
+ 		return err;
+ 	}
diff --git a/patches.socfpga/0038-fpga-zynq-Remove-priv-dev.patch b/patches.socfpga/0038-fpga-zynq-Remove-priv-dev.patch
new file mode 100644
index 0000000..869b493
--- /dev/null
+++ b/patches.socfpga/0038-fpga-zynq-Remove-priv-dev.patch
@@ -0,0 +1,99 @@
+From df7528d1c3d7c2151dfe9419c7b3eed183860b8f Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Mon, 21 Nov 2016 22:26:44 +0000
+Subject: [PATCH 038/103] fpga zynq: Remove priv->dev
+
+socfpga uses mgr->dev for debug prints, there should be consistency
+here, so standardize on that. The only other use was for dma
+which can be replaced with mgr->dev.parent.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+---
+ drivers/fpga/zynq-fpga.c |   19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -118,7 +118,6 @@
+ #define FPGA_RST_NONE_MASK		0x0
+ 
+ struct zynq_fpga_priv {
+-	struct device *dev;
+ 	int irq;
+ 	struct clk *clk;
+ 
+@@ -218,7 +217,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
++			dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 
+@@ -232,7 +231,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for !PCFG_INIT\n");
++			dev_err(&mgr->dev, "Timeout waiting for !PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 
+@@ -246,7 +245,7 @@ static int zynq_fpga_ops_write_init(stru
+ 					     INIT_POLL_DELAY,
+ 					     INIT_POLL_TIMEOUT);
+ 		if (err) {
+-			dev_err(priv->dev, "Timeout waiting for PCFG_INIT\n");
++			dev_err(&mgr->dev, "Timeout waiting for PCFG_INIT\n");
+ 			goto out_err;
+ 		}
+ 	}
+@@ -263,7 +262,7 @@ static int zynq_fpga_ops_write_init(stru
+ 	/* check that we have room in the command queue */
+ 	status = zynq_fpga_read(priv, STATUS_OFFSET);
+ 	if (status & STATUS_DMA_Q_F) {
+-		dev_err(priv->dev, "DMA command queue full\n");
++		dev_err(&mgr->dev, "DMA command queue full\n");
+ 		err = -EBUSY;
+ 		goto out_err;
+ 	}
+@@ -296,7 +295,8 @@ static int zynq_fpga_ops_write(struct fp
+ 	in_count = count;
+ 	priv = mgr->priv;
+ 
+-	kbuf = dma_alloc_coherent(priv->dev, count, &dma_addr, GFP_KERNEL);
++	kbuf =
++	    dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL);
+ 	if (!kbuf)
+ 		return -ENOMEM;
+ 
+@@ -332,15 +332,14 @@ static int zynq_fpga_ops_write(struct fp
+ 	zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
+ 
+ 	if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
+-		dev_err(priv->dev, "Error configuring FPGA\n");
++		dev_err(&mgr->dev, "Error configuring FPGA\n");
+ 		err = -EFAULT;
+ 	}
+ 
+ 	clk_disable(priv->clk);
+ 
+ out_free:
+-	dma_free_coherent(priv->dev, in_count, kbuf, dma_addr);
+-
++	dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr);
+ 	return err;
+ }
+ 
+@@ -418,8 +417,6 @@ static int zynq_fpga_probe(struct platfo
+ 	if (!priv)
+ 		return -ENOMEM;
+ 
+-	priv->dev = dev;
+-
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	priv->io_base = devm_ioremap_resource(dev, res);
+ 	if (IS_ERR(priv->io_base))
diff --git a/patches.socfpga/0039-fpga-zynq-Fix-incorrect-ISR-state-on-bootup.patch b/patches.socfpga/0039-fpga-zynq-Fix-incorrect-ISR-state-on-bootup.patch
new file mode 100644
index 0000000..21d94e8
--- /dev/null
+++ b/patches.socfpga/0039-fpga-zynq-Fix-incorrect-ISR-state-on-bootup.patch
@@ -0,0 +1,56 @@
+From fb85a83e56bbe1a3899b8293a2db442696aa7631 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Mon, 21 Nov 2016 22:26:45 +0000
+Subject: [PATCH 039/103] fpga zynq: Fix incorrect ISR state on bootup
+
+It is best practice to clear and mask all interrupts before
+associating the IRQ, and this should be done after the clock
+is enabled.
+
+This corrects a bad result from zynq_fpga_ops_state on bootup
+where left over latched values in INT_STS_OFFSET caused it to
+report an unconfigured FPGA as configured.
+
+After this change the boot up operating state for an unconfigured
+FPGA reports 'unknown'.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+---
+ drivers/fpga/zynq-fpga.c |   17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -437,13 +437,6 @@ static int zynq_fpga_probe(struct platfo
+ 		return priv->irq;
+ 	}
+ 
+-	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0,
+-			       dev_name(dev), priv);
+-	if (err) {
+-		dev_err(dev, "unable to request IRQ\n");
+-		return err;
+-	}
+-
+ 	priv->clk = devm_clk_get(dev, "ref_clk");
+ 	if (IS_ERR(priv->clk)) {
+ 		dev_err(dev, "input clock not found\n");
+@@ -459,6 +452,16 @@ static int zynq_fpga_probe(struct platfo
+ 	/* unlock the device */
+ 	zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
+ 
++	zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF);
++	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
++	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
++			       priv);
++	if (err) {
++		dev_err(dev, "unable to request IRQ\n");
++		clk_disable_unprepare(priv->clk);
++		return err;
++	}
++
+ 	clk_disable(priv->clk);
+ 
+ 	err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
diff --git a/patches.socfpga/0040-fpga-Clarify-how-write_init-works-streaming-modes.patch b/patches.socfpga/0040-fpga-Clarify-how-write_init-works-streaming-modes.patch
new file mode 100644
index 0000000..b5e5f0c
--- /dev/null
+++ b/patches.socfpga/0040-fpga-Clarify-how-write_init-works-streaming-modes.patch
@@ -0,0 +1,82 @@
+From 66eb655c5286bd01e7fbe9db237ed4cbde6c4857 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Tue, 22 Nov 2016 18:22:09 +0000
+Subject: [PATCH 040/103] fpga: Clarify how write_init works streaming modes
+
+This interface was designed for streaming, but write_init's buf
+argument has an unclear purpose. Define it to be the first bytes
+of the bitstream. Each driver gets to set how many bytes (at most)
+it wants to see. Short bitstreams will be passed through as-is, while
+long ones will be truncated.
+
+The intent is to allow drivers to peek at the header before the transfer
+actually starts.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+---
+ Documentation/fpga/fpga-mgr.txt |    5 ++++-
+ drivers/fpga/fpga-mgr.c         |    6 ++++--
+ drivers/fpga/socfpga-a10.c      |    1 +
+ include/linux/fpga/fpga-mgr.h   |    2 ++
+ 4 files changed, 11 insertions(+), 3 deletions(-)
+
+--- a/Documentation/fpga/fpga-mgr.txt
++++ b/Documentation/fpga/fpga-mgr.txt
+@@ -169,7 +169,10 @@ The programming sequence is:
+  2. .write (may be called once or multiple times)
+  3. .write_complete
+ 
+-The .write_init function will prepare the FPGA to receive the image data.
++The .write_init function will prepare the FPGA to receive the image data.  The
++buffer passed into .write_init will be atmost .initial_header_size bytes long,
++if the whole bitstream is not immediately available then the core code will
++buffer up at least this much before starting.
+ 
+ The .write function writes a buffer to the FPGA. The buffer may be contain the
+ whole FPGA image or may be a smaller chunk of an FPGA image.  In the latter
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -53,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manage
+ 	/*
+ 	 * Call the low level driver's write_init function.  This will do the
+ 	 * device-specific things to get the FPGA into the state where it is
+-	 * ready to receive an FPGA image.
++	 * ready to receive an FPGA image. The low level driver only gets to
++	 * see the first initial_header_size bytes in the buffer.
+ 	 */
+ 	mgr->state = FPGA_MGR_STATE_WRITE_INIT;
+-	ret = mgr->mops->write_init(mgr, info, buf, count);
++	ret = mgr->mops->write_init(mgr, info, buf,
++				    min(mgr->mops->initial_header_size, count));
+ 	if (ret) {
+ 		dev_err(dev, "Error preparing FPGA for writing\n");
+ 		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
+--- a/drivers/fpga/socfpga-a10.c
++++ b/drivers/fpga/socfpga-a10.c
+@@ -470,6 +470,7 @@ static enum fpga_mgr_states socfpga_a10_
+ }
+ 
+ static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
++	.initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
+ 	.state = socfpga_a10_fpga_state,
+ 	.write_init = socfpga_a10_fpga_write_init,
+ 	.write = socfpga_a10_fpga_write,
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -84,6 +84,7 @@ struct fpga_image_info {
+ 
+ /**
+  * struct fpga_manager_ops - ops for low level fpga manager drivers
++ * @initial_header_size: Maximum number of bytes that should be passed into write_init
+  * @state: returns an enum value of the FPGA's state
+  * @write_init: prepare the FPGA to receive confuration data
+  * @write: write count bytes of configuration data to the FPGA
+@@ -95,6 +96,7 @@ struct fpga_image_info {
+  * called, so leaving them out is fine.
+  */
+ struct fpga_manager_ops {
++	size_t initial_header_size;
+ 	enum fpga_mgr_states (*state)(struct fpga_manager *mgr);
+ 	int (*write_init)(struct fpga_manager *mgr,
+ 			  struct fpga_image_info *info,
diff --git a/patches.socfpga/0041-fpga-zynq-Check-for-errors-after-completing-DMA.patch b/patches.socfpga/0041-fpga-zynq-Check-for-errors-after-completing-DMA.patch
new file mode 100644
index 0000000..2a0f8b5
--- /dev/null
+++ b/patches.socfpga/0041-fpga-zynq-Check-for-errors-after-completing-DMA.patch
@@ -0,0 +1,130 @@
+From 5340a4560aaaaa7807b8e0070d6ee6541ee5fb3b Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 1 Feb 2017 12:48:42 -0700
+Subject: [PATCH 041/103] fpga zynq: Check for errors after completing DMA
+
+The completion did not check the interrupt status to see if any error
+bits were asserted, check error bits and dump some registers if things
+went wrong.
+
+A few fixes are needed to make this work, the IXR_ERROR_FLAGS_MASK was
+wrong, it included the done bits, which shows a bug in mask/unmask_irqs
+which were using the wrong bits, simplify all of this stuff.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Reviewed-by: Moritz Fischer <moritz.fischer@ettus.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/zynq-fpga.c |   54 +++++++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 22 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -89,7 +89,7 @@
+ #define IXR_D_P_DONE_MASK		BIT(12)
+  /* FPGA programmed */
+ #define IXR_PCFG_DONE_MASK		BIT(2)
+-#define IXR_ERROR_FLAGS_MASK		0x00F0F860
++#define IXR_ERROR_FLAGS_MASK		0x00F0C860
+ #define IXR_ALL_MASK			0xF8F7F87F
+ 
+ /* Miscellaneous constant values */
+@@ -143,23 +143,10 @@ static inline u32 zynq_fpga_read(const s
+ 	readl_poll_timeout(priv->io_base + addr, val, cond, sleep_us, \
+ 			   timeout_us)
+ 
+-static void zynq_fpga_mask_irqs(struct zynq_fpga_priv *priv)
++/* Cause the specified irq mask bits to generate IRQs */
++static inline void zynq_fpga_set_irq(struct zynq_fpga_priv *priv, u32 enable)
+ {
+-	u32 intr_mask;
+-
+-	intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
+-	zynq_fpga_write(priv, INT_MASK_OFFSET,
+-			intr_mask | IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
+-}
+-
+-static void zynq_fpga_unmask_irqs(struct zynq_fpga_priv *priv)
+-{
+-	u32 intr_mask;
+-
+-	intr_mask = zynq_fpga_read(priv, INT_MASK_OFFSET);
+-	zynq_fpga_write(priv, INT_MASK_OFFSET,
+-			intr_mask
+-			& ~(IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK));
++	zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable);
+ }
+ 
+ static irqreturn_t zynq_fpga_isr(int irq, void *data)
+@@ -167,7 +154,7 @@ static irqreturn_t zynq_fpga_isr(int irq
+ 	struct zynq_fpga_priv *priv = data;
+ 
+ 	/* disable DMA and error IRQs */
+-	zynq_fpga_mask_irqs(priv);
++	zynq_fpga_set_irq(priv, 0);
+ 
+ 	complete(&priv->dma_done);
+ 
+@@ -285,6 +272,7 @@ static int zynq_fpga_ops_write(struct fp
+ 			       const char *buf, size_t count)
+ {
+ 	struct zynq_fpga_priv *priv;
++	const char *why;
+ 	int err;
+ 	char *kbuf;
+ 	size_t in_count;
+@@ -312,7 +300,7 @@ static int zynq_fpga_ops_write(struct fp
+ 	reinit_completion(&priv->dma_done);
+ 
+ 	/* enable DMA and error IRQs */
+-	zynq_fpga_unmask_irqs(priv);
++	zynq_fpga_set_irq(priv, IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK);
+ 
+ 	/* the +1 in the src addr is used to hold off on DMA_DONE IRQ
+ 	 * until both AXI and PCAP are done ...
+@@ -331,11 +319,33 @@ static int zynq_fpga_ops_write(struct fp
+ 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
+ 	zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
+ 
++	if (intr_status & IXR_ERROR_FLAGS_MASK) {
++		why = "DMA reported error";
++		err = -EIO;
++		goto out_report;
++	}
++
+ 	if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
+-		dev_err(&mgr->dev, "Error configuring FPGA\n");
+-		err = -EFAULT;
++		why = "DMA did not complete";
++		err = -EIO;
++		goto out_report;
+ 	}
+ 
++	err = 0;
++	goto out_clk;
++
++out_report:
++	dev_err(&mgr->dev,
++		"%s: INT_STS:0x%x CTRL:0x%x LOCK:0x%x INT_MASK:0x%x STATUS:0x%x MCTRL:0x%x\n",
++		why,
++		intr_status,
++		zynq_fpga_read(priv, CTRL_OFFSET),
++		zynq_fpga_read(priv, LOCK_OFFSET),
++		zynq_fpga_read(priv, INT_MASK_OFFSET),
++		zynq_fpga_read(priv, STATUS_OFFSET),
++		zynq_fpga_read(priv, MCTRL_OFFSET));
++
++out_clk:
+ 	clk_disable(priv->clk);
+ 
+ out_free:
+@@ -452,7 +462,7 @@ static int zynq_fpga_probe(struct platfo
+ 	/* unlock the device */
+ 	zynq_fpga_write(priv, UNLOCK_OFFSET, UNLOCK_MASK);
+ 
+-	zynq_fpga_write(priv, INT_MASK_OFFSET, 0xFFFFFFFF);
++	zynq_fpga_set_irq(priv, 0);
+ 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
+ 	err = devm_request_irq(dev, priv->irq, zynq_fpga_isr, 0, dev_name(dev),
+ 			       priv);
diff --git a/patches.socfpga/0042-fpga-zynq-Check-the-bitstream-for-validity.patch b/patches.socfpga/0042-fpga-zynq-Check-the-bitstream-for-validity.patch
new file mode 100644
index 0000000..b5a3ac8
--- /dev/null
+++ b/patches.socfpga/0042-fpga-zynq-Check-the-bitstream-for-validity.patch
@@ -0,0 +1,72 @@
+From 1e390eb9365008a5f3713e390ffe4484f078468c Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 1 Feb 2017 12:48:43 -0700
+Subject: [PATCH 042/103] fpga zynq: Check the bitstream for validity
+
+There is no sense in sending a bitstream we know will not work, and
+with the variety of options for bitstream generation in Xilinx tools
+it is not terribly clear what the correct input should be.
+
+This is particularly important for Zynq since auto-correction was
+removed from the driver and the Zynq hardware only accepts a bitstream
+format that is different from what the Xilinx tools typically produce.
+
+Worse, the hardware provides no indication why the bitstream fails,
+it simply times out if the input is wrong.
+
+The best option here is to have the kernel print a message informing
+the user they are using a malformed bistream and programming failure
+isn't for any of the myriad of other reasons.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/zynq-fpga.c |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -161,6 +161,19 @@ static irqreturn_t zynq_fpga_isr(int irq
+ 	return IRQ_HANDLED;
+ }
+ 
++/* Sanity check the proposed bitstream. It must start with the sync word in
++ * the correct byte order, and be dword aligned. The input is a Xilinx .bin
++ * file with every 32 bit quantity swapped.
++ */
++static bool zynq_fpga_has_sync(const u8 *buf, size_t count)
++{
++	for (; count >= 4; buf += 4, count -= 4)
++		if (buf[0] == 0x66 && buf[1] == 0x55 && buf[2] == 0x99 &&
++		    buf[3] == 0xaa)
++			return true;
++	return false;
++}
++
+ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
+ 				    struct fpga_image_info *info,
+ 				    const char *buf, size_t count)
+@@ -177,6 +190,13 @@ static int zynq_fpga_ops_write_init(stru
+ 
+ 	/* don't globally reset PL if we're doing partial reconfig */
+ 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
++		if (!zynq_fpga_has_sync(buf, count)) {
++			dev_err(&mgr->dev,
++				"Invalid bitstream, could not find a sync word. Bitstream must be a byte swapped .bin file\n");
++			err = -EINVAL;
++			goto out_err;
++		}
++
+ 		/* assert AXI interface resets */
+ 		regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
+ 			     FPGA_RST_ALL_MASK);
+@@ -410,6 +430,7 @@ static enum fpga_mgr_states zynq_fpga_op
+ }
+ 
+ static const struct fpga_manager_ops zynq_fpga_ops = {
++	.initial_header_size = 128,
+ 	.state = zynq_fpga_ops_state,
+ 	.write_init = zynq_fpga_ops_write_init,
+ 	.write = zynq_fpga_ops_write,
diff --git a/patches.socfpga/0043-fpga-Add-scatterlist-based-programming.patch b/patches.socfpga/0043-fpga-Add-scatterlist-based-programming.patch
new file mode 100644
index 0000000..b2b44e9
--- /dev/null
+++ b/patches.socfpga/0043-fpga-Add-scatterlist-based-programming.patch
@@ -0,0 +1,396 @@
+From 5b97663f81233b359315a0e26af540ad11e24171 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 1 Feb 2017 12:48:44 -0700
+Subject: [PATCH 043/103] fpga: Add scatterlist based programming
+
+Requiring contiguous kernel memory is not a good idea, this is a limited
+resource and allocation can fail under normal work loads.
+
+This introduces a .write_sg op that supporting drivers can provide
+to DMA directly from dis-contiguous memory and a new entry point
+fpga_mgr_buf_load_sg that users can call to directly provide page
+lists.
+
+The full matrix of compatibility is provided, either the linear or sg
+interface can be used by the user with a driver supporting either
+interface.
+
+A notable change for drivers is that the .write op can now be called
+multiple times.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/fpga/fpga-mgr.txt |   19 ++-
+ drivers/fpga/fpga-mgr.c         |  236 ++++++++++++++++++++++++++++++++++------
+ include/linux/fpga/fpga-mgr.h   |    5 
+ 3 files changed, 227 insertions(+), 33 deletions(-)
+
+--- a/Documentation/fpga/fpga-mgr.txt
++++ b/Documentation/fpga/fpga-mgr.txt
+@@ -22,7 +22,16 @@ To program the FPGA from a file or from
+ 			      struct fpga_image_info *info,
+ 		              const char *buf, size_t count);
+ 
+-Load the FPGA from an image which exists as a buffer in memory.
++Load the FPGA from an image which exists as a contiguous buffer in
++memory. Allocating contiguous kernel memory for the buffer should be avoided,
++users are encouraged to use the _sg interface instead of this.
++
++        int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
++				 struct fpga_image_info *info,
++				 struct sg_table *sgt);
++
++Load the FPGA from an image from non-contiguous in memory. Callers can
++construct a sg_table using alloc_page backed memory.
+ 
+ 	int fpga_mgr_firmware_load(struct fpga_manager *mgr,
+ 				   struct fpga_image_info *info,
+@@ -166,7 +175,7 @@ success or negative error codes otherwis
+ 
+ The programming sequence is:
+  1. .write_init
+- 2. .write (may be called once or multiple times)
++ 2. .write or .write_sg (may be called once or multiple times)
+  3. .write_complete
+ 
+ The .write_init function will prepare the FPGA to receive the image data.  The
+@@ -176,7 +185,11 @@ buffer up at least this much before star
+ 
+ The .write function writes a buffer to the FPGA. The buffer may be contain the
+ whole FPGA image or may be a smaller chunk of an FPGA image.  In the latter
+-case, this function is called multiple times for successive chunks.
++case, this function is called multiple times for successive chunks. This interface
++is suitable for drivers which use PIO.
++
++The .write_sg version behaves the same as .write except the input is a sg_table
++scatter list. This interface is suitable for drivers which use DMA.
+ 
+ The .write_complete function is called after all the image has been written
+ to put the FPGA into operating mode.
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -25,16 +25,106 @@
+ #include <linux/of.h>
+ #include <linux/mutex.h>
+ #include <linux/slab.h>
++#include <linux/scatterlist.h>
++#include <linux/highmem.h>
+ 
+ static DEFINE_IDA(fpga_mgr_ida);
+ static struct class *fpga_mgr_class;
+ 
++/*
++ * Call the low level driver's write_init function.  This will do the
++ * device-specific things to get the FPGA into the state where it is ready to
++ * receive an FPGA image. The low level driver only gets to see the first
++ * initial_header_size bytes in the buffer.
++ */
++static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
++				   struct fpga_image_info *info,
++				   const char *buf, size_t count)
++{
++	int ret;
++
++	mgr->state = FPGA_MGR_STATE_WRITE_INIT;
++	if (!mgr->mops->initial_header_size)
++		ret = mgr->mops->write_init(mgr, info, NULL, 0);
++	else
++		ret = mgr->mops->write_init(
++		    mgr, info, buf, min(mgr->mops->initial_header_size, count));
++
++	if (ret) {
++		dev_err(&mgr->dev, "Error preparing FPGA for writing\n");
++		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
++		return ret;
++	}
++
++	return 0;
++}
++
++static int fpga_mgr_write_init_sg(struct fpga_manager *mgr,
++				  struct fpga_image_info *info,
++				  struct sg_table *sgt)
++{
++	struct sg_mapping_iter miter;
++	size_t len;
++	char *buf;
++	int ret;
++
++	if (!mgr->mops->initial_header_size)
++		return fpga_mgr_write_init_buf(mgr, info, NULL, 0);
++
++	/*
++	 * First try to use miter to map the first fragment to access the
++	 * header, this is the typical path.
++	 */
++	sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
++	if (sg_miter_next(&miter) &&
++	    miter.length >= mgr->mops->initial_header_size) {
++		ret = fpga_mgr_write_init_buf(mgr, info, miter.addr,
++					      miter.length);
++		sg_miter_stop(&miter);
++		return ret;
++	}
++	sg_miter_stop(&miter);
++
++	/* Otherwise copy the fragments into temporary memory. */
++	buf = kmalloc(mgr->mops->initial_header_size, GFP_KERNEL);
++	if (!buf)
++		return -ENOMEM;
++
++	len = sg_copy_to_buffer(sgt->sgl, sgt->nents, buf,
++				mgr->mops->initial_header_size);
++	ret = fpga_mgr_write_init_buf(mgr, info, buf, len);
++
++	kfree(buf);
++
++	return ret;
++}
++
++/*
++ * After all the FPGA image has been written, do the device specific steps to
++ * finish and set the FPGA into operating mode.
++ */
++static int fpga_mgr_write_complete(struct fpga_manager *mgr,
++				   struct fpga_image_info *info)
++{
++	int ret;
++
++	mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
++	ret = mgr->mops->write_complete(mgr, info);
++	if (ret) {
++		dev_err(&mgr->dev, "Error after writing image data to FPGA\n");
++		mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
++		return ret;
++	}
++	mgr->state = FPGA_MGR_STATE_OPERATING;
++
++	return 0;
++}
++
+ /**
+- * fpga_mgr_buf_load - load fpga from image in buffer
++ * fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list
+  * @mgr:	fpga manager
+  * @info:	fpga image specific information
+- * @buf:	buffer contain fpga image
+- * @count:	byte count of buf
++ * @sgt:	scatterlist table
+  *
+  * Step the low level fpga manager through the device-specific steps of getting
+  * an FPGA ready to be configured, writing the image to it, then doing whatever
+@@ -42,54 +132,139 @@ static struct class *fpga_mgr_class;
+  * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is
+  * not an error code.
+  *
++ * This is the preferred entry point for FPGA programming, it does not require
++ * any contiguous kernel memory.
++ *
+  * Return: 0 on success, negative error code otherwise.
+  */
+-int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
+-		      const char *buf, size_t count)
++int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info,
++			 struct sg_table *sgt)
+ {
+-	struct device *dev = &mgr->dev;
+ 	int ret;
+ 
+-	/*
+-	 * Call the low level driver's write_init function.  This will do the
+-	 * device-specific things to get the FPGA into the state where it is
+-	 * ready to receive an FPGA image. The low level driver only gets to
+-	 * see the first initial_header_size bytes in the buffer.
+-	 */
+-	mgr->state = FPGA_MGR_STATE_WRITE_INIT;
+-	ret = mgr->mops->write_init(mgr, info, buf,
+-				    min(mgr->mops->initial_header_size, count));
++	ret = fpga_mgr_write_init_sg(mgr, info, sgt);
++	if (ret)
++		return ret;
++
++	/* Write the FPGA image to the FPGA. */
++	mgr->state = FPGA_MGR_STATE_WRITE;
++	if (mgr->mops->write_sg) {
++		ret = mgr->mops->write_sg(mgr, sgt);
++	} else {
++		struct sg_mapping_iter miter;
++
++		sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
++		while (sg_miter_next(&miter)) {
++			ret = mgr->mops->write(mgr, miter.addr, miter.length);
++			if (ret)
++				break;
++		}
++		sg_miter_stop(&miter);
++	}
++
+ 	if (ret) {
+-		dev_err(dev, "Error preparing FPGA for writing\n");
+-		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
++		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
++		mgr->state = FPGA_MGR_STATE_WRITE_ERR;
+ 		return ret;
+ 	}
+ 
++	return fpga_mgr_write_complete(mgr, info);
++}
++EXPORT_SYMBOL_GPL(fpga_mgr_buf_load_sg);
++
++static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
++				    struct fpga_image_info *info,
++				    const char *buf, size_t count)
++{
++	int ret;
++
++	ret = fpga_mgr_write_init_buf(mgr, info, buf, count);
++	if (ret)
++		return ret;
++
+ 	/*
+ 	 * Write the FPGA image to the FPGA.
+ 	 */
+ 	mgr->state = FPGA_MGR_STATE_WRITE;
+ 	ret = mgr->mops->write(mgr, buf, count);
+ 	if (ret) {
+-		dev_err(dev, "Error while writing image data to FPGA\n");
++		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
+ 		mgr->state = FPGA_MGR_STATE_WRITE_ERR;
+ 		return ret;
+ 	}
+ 
++	return fpga_mgr_write_complete(mgr, info);
++}
++
++/**
++ * fpga_mgr_buf_load - load fpga from image in buffer
++ * @mgr:	fpga manager
++ * @flags:	flags setting fpga confuration modes
++ * @buf:	buffer contain fpga image
++ * @count:	byte count of buf
++ *
++ * Step the low level fpga manager through the device-specific steps of getting
++ * an FPGA ready to be configured, writing the image to it, then doing whatever
++ * post-configuration steps necessary.  This code assumes the caller got the
++ * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.
++ *
++ * Return: 0 on success, negative error code otherwise.
++ */
++int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
++		      const char *buf, size_t count)
++{
++	struct page **pages;
++	struct sg_table sgt;
++	const void *p;
++	int nr_pages;
++	int index;
++	int rc;
++
+ 	/*
+-	 * After all the FPGA image has been written, do the device specific
+-	 * steps to finish and set the FPGA into operating mode.
++	 * This is just a fast path if the caller has already created a
++	 * contiguous kernel buffer and the driver doesn't require SG, non-SG
++	 * drivers will still work on the slow path.
+ 	 */
+-	mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
+-	ret = mgr->mops->write_complete(mgr, info);
+-	if (ret) {
+-		dev_err(dev, "Error after writing image data to FPGA\n");
+-		mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
+-		return ret;
++	if (mgr->mops->write)
++		return fpga_mgr_buf_load_mapped(mgr, info, buf, count);
++
++	/*
++	 * Convert the linear kernel pointer into a sg_table of pages for use
++	 * by the driver.
++	 */
++	nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) -
++		   (unsigned long)buf / PAGE_SIZE;
++	pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
++	if (!pages)
++		return -ENOMEM;
++
++	p = buf - offset_in_page(buf);
++	for (index = 0; index < nr_pages; index++) {
++		if (is_vmalloc_addr(p))
++			pages[index] = vmalloc_to_page(p);
++		else
++			pages[index] = kmap_to_page((void *)p);
++		if (!pages[index]) {
++			kfree(pages);
++			return -EFAULT;
++		}
++		p += PAGE_SIZE;
+ 	}
+-	mgr->state = FPGA_MGR_STATE_OPERATING;
+ 
+-	return 0;
++	/*
++	 * The temporary pages list is used to code share the merging algorithm
++	 * in sg_alloc_table_from_pages
++	 */
++	rc = sg_alloc_table_from_pages(&sgt, pages, index, offset_in_page(buf),
++				       count, GFP_KERNEL);
++	kfree(pages);
++	if (rc)
++		return rc;
++
++	rc = fpga_mgr_buf_load_sg(mgr, info, &sgt);
++	sg_free_table(&sgt);
++
++	return rc;
+ }
+ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
+ 
+@@ -291,8 +466,9 @@ int fpga_mgr_register(struct device *dev
+ 	struct fpga_manager *mgr;
+ 	int id, ret;
+ 
+-	if (!mops || !mops->write_init || !mops->write ||
+-	    !mops->write_complete || !mops->state) {
++	if (!mops || !mops->write_complete || !mops->state ||
++	    !mops->write_init || (!mops->write && !mops->write_sg) ||
++	    (mops->write && mops->write_sg)) {
+ 		dev_err(dev, "Attempt to register without fpga_manager_ops\n");
+ 		return -EINVAL;
+ 	}
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -22,6 +22,7 @@
+ #define _LINUX_FPGA_MGR_H
+ 
+ struct fpga_manager;
++struct sg_table;
+ 
+ /**
+  * enum fpga_mgr_states - fpga framework states
+@@ -88,6 +89,7 @@ struct fpga_image_info {
+  * @state: returns an enum value of the FPGA's state
+  * @write_init: prepare the FPGA to receive confuration data
+  * @write: write count bytes of configuration data to the FPGA
++ * @write_sg: write the scatter list of configuration data to the FPGA
+  * @write_complete: set FPGA to operating state after writing is done
+  * @fpga_remove: optional: Set FPGA into a specific state during driver remove
+  *
+@@ -102,6 +104,7 @@ struct fpga_manager_ops {
+ 			  struct fpga_image_info *info,
+ 			  const char *buf, size_t count);
+ 	int (*write)(struct fpga_manager *mgr, const char *buf, size_t count);
++	int (*write_sg)(struct fpga_manager *mgr, struct sg_table *sgt);
+ 	int (*write_complete)(struct fpga_manager *mgr,
+ 			      struct fpga_image_info *info);
+ 	void (*fpga_remove)(struct fpga_manager *mgr);
+@@ -129,6 +132,8 @@ struct fpga_manager {
+ 
+ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
+ 		      const char *buf, size_t count);
++int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info,
++			 struct sg_table *sgt);
+ 
+ int fpga_mgr_firmware_load(struct fpga_manager *mgr,
+ 			   struct fpga_image_info *info,
diff --git a/patches.socfpga/0044-fpga-zynq-Use-the-scatterlist-interface.patch b/patches.socfpga/0044-fpga-zynq-Use-the-scatterlist-interface.patch
new file mode 100644
index 0000000..f14aebd
--- /dev/null
+++ b/patches.socfpga/0044-fpga-zynq-Use-the-scatterlist-interface.patch
@@ -0,0 +1,304 @@
+From d8b26435b18259639f39aab9ff96cfbf5fdd1076 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 1 Feb 2017 12:48:45 -0700
+Subject: [PATCH 044/103] fpga zynq: Use the scatterlist interface
+
+This allows the driver to avoid a high order coherent DMA allocation
+and memory copy. With this patch it can DMA directly from the kernel
+pages that the bitfile is stored in.
+
+Since this is now a gather DMA operation the driver uses the ISR
+to feed the chips DMA queue with each entry from the SGL.
+
+Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/zynq-fpga.c |  174 ++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 135 insertions(+), 39 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -30,6 +30,7 @@
+ #include <linux/pm.h>
+ #include <linux/regmap.h>
+ #include <linux/string.h>
++#include <linux/scatterlist.h>
+ 
+ /* Offsets into SLCR regmap */
+ 
+@@ -80,6 +81,7 @@
+ 
+ /* FPGA init status */
+ #define STATUS_DMA_Q_F			BIT(31)
++#define STATUS_DMA_Q_E			BIT(30)
+ #define STATUS_PCFG_INIT_MASK		BIT(4)
+ 
+ /* Interrupt Status/Mask Register Bit definitions */
+@@ -98,12 +100,16 @@
+ #define DMA_INVALID_ADDRESS		GENMASK(31, 0)
+ /* Used to unlock the dev */
+ #define UNLOCK_MASK			0x757bdf0d
+-/* Timeout for DMA to complete */
+-#define DMA_DONE_TIMEOUT		msecs_to_jiffies(1000)
+ /* Timeout for polling reset bits */
+ #define INIT_POLL_TIMEOUT		2500000
+ /* Delay for polling reset bits */
+ #define INIT_POLL_DELAY			20
++/* Signal this is the last DMA transfer, wait for the AXI and PCAP before
++ * interrupting
++ */
++#define DMA_SRC_LAST_TRANSFER		1
++/* Timeout for DMA completion */
++#define DMA_TIMEOUT_MS			5000
+ 
+ /* Masks for controlling stuff in SLCR */
+ /* Disable all Level shifters */
+@@ -124,6 +130,11 @@ struct zynq_fpga_priv {
+ 	void __iomem *io_base;
+ 	struct regmap *slcr;
+ 
++	spinlock_t dma_lock;
++	unsigned int dma_elm;
++	unsigned int dma_nelms;
++	struct scatterlist *cur_sg;
++
+ 	struct completion dma_done;
+ };
+ 
+@@ -149,13 +160,80 @@ static inline void zynq_fpga_set_irq(str
+ 	zynq_fpga_write(priv, INT_MASK_OFFSET, ~enable);
+ }
+ 
++/* Must be called with dma_lock held */
++static void zynq_step_dma(struct zynq_fpga_priv *priv)
++{
++	u32 addr;
++	u32 len;
++	bool first;
++
++	first = priv->dma_elm == 0;
++	while (priv->cur_sg) {
++		/* Feed the DMA queue until it is full. */
++		if (zynq_fpga_read(priv, STATUS_OFFSET) & STATUS_DMA_Q_F)
++			break;
++
++		addr = sg_dma_address(priv->cur_sg);
++		len = sg_dma_len(priv->cur_sg);
++		if (priv->dma_elm + 1 == priv->dma_nelms) {
++			/* The last transfer waits for the PCAP to finish too,
++			 * notice this also changes the irq_mask to ignore
++			 * IXR_DMA_DONE_MASK which ensures we do not trigger
++			 * the completion too early.
++			 */
++			addr |= DMA_SRC_LAST_TRANSFER;
++			priv->cur_sg = NULL;
++		} else {
++			priv->cur_sg = sg_next(priv->cur_sg);
++			priv->dma_elm++;
++		}
++
++		zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, addr);
++		zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, DMA_INVALID_ADDRESS);
++		zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, len / 4);
++		zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0);
++	}
++
++	/* Once the first transfer is queued we can turn on the ISR, future
++	 * calls to zynq_step_dma will happen from the ISR context. The
++	 * dma_lock spinlock guarentees this handover is done coherently, the
++	 * ISR enable is put at the end to avoid another CPU spinning in the
++	 * ISR on this lock.
++	 */
++	if (first && priv->cur_sg) {
++		zynq_fpga_set_irq(priv,
++				  IXR_DMA_DONE_MASK | IXR_ERROR_FLAGS_MASK);
++	} else if (!priv->cur_sg) {
++		/* The last transfer changes to DMA & PCAP mode since we do
++		 * not want to continue until everything has been flushed into
++		 * the PCAP.
++		 */
++		zynq_fpga_set_irq(priv,
++				  IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK);
++	}
++}
++
+ static irqreturn_t zynq_fpga_isr(int irq, void *data)
+ {
+ 	struct zynq_fpga_priv *priv = data;
++	u32 intr_status;
+ 
+-	/* disable DMA and error IRQs */
+-	zynq_fpga_set_irq(priv, 0);
++	/* If anything other than DMA completion is reported stop and hand
++	 * control back to zynq_fpga_ops_write, something went wrong,
++	 * otherwise progress the DMA.
++	 */
++	spin_lock(&priv->dma_lock);
++	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
++	if (!(intr_status & IXR_ERROR_FLAGS_MASK) &&
++	    (intr_status & IXR_DMA_DONE_MASK) && priv->cur_sg) {
++		zynq_fpga_write(priv, INT_STS_OFFSET, IXR_DMA_DONE_MASK);
++		zynq_step_dma(priv);
++		spin_unlock(&priv->dma_lock);
++		return IRQ_HANDLED;
++	}
++	spin_unlock(&priv->dma_lock);
+ 
++	zynq_fpga_set_irq(priv, 0);
+ 	complete(&priv->dma_done);
+ 
+ 	return IRQ_HANDLED;
+@@ -266,10 +344,11 @@ static int zynq_fpga_ops_write_init(stru
+ 	zynq_fpga_write(priv, CTRL_OFFSET,
+ 			(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl));
+ 
+-	/* check that we have room in the command queue */
++	/* We expect that the command queue is empty right now. */
+ 	status = zynq_fpga_read(priv, STATUS_OFFSET);
+-	if (status & STATUS_DMA_Q_F) {
+-		dev_err(&mgr->dev, "DMA command queue full\n");
++	if ((status & STATUS_DMA_Q_F) ||
++	    (status & STATUS_DMA_Q_E) != STATUS_DMA_Q_E) {
++		dev_err(&mgr->dev, "DMA command queue not right\n");
+ 		err = -EBUSY;
+ 		goto out_err;
+ 	}
+@@ -288,27 +367,36 @@ out_err:
+ 	return err;
+ }
+ 
+-static int zynq_fpga_ops_write(struct fpga_manager *mgr,
+-			       const char *buf, size_t count)
++static int zynq_fpga_ops_write(struct fpga_manager *mgr, struct sg_table *sgt)
+ {
+ 	struct zynq_fpga_priv *priv;
+ 	const char *why;
+ 	int err;
+-	char *kbuf;
+-	size_t in_count;
+-	dma_addr_t dma_addr;
+-	u32 transfer_length;
+ 	u32 intr_status;
++	unsigned long timeout;
++	unsigned long flags;
++	struct scatterlist *sg;
++	int i;
+ 
+-	in_count = count;
+ 	priv = mgr->priv;
+ 
+-	kbuf =
+-	    dma_alloc_coherent(mgr->dev.parent, count, &dma_addr, GFP_KERNEL);
+-	if (!kbuf)
+-		return -ENOMEM;
++	/* The hardware can only DMA multiples of 4 bytes, and it requires the
++	 * starting addresses to be aligned to 64 bits (UG585 pg 212).
++	 */
++	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
++		if ((sg->offset % 8) || (sg->length % 4)) {
++			dev_err(&mgr->dev,
++			    "Invalid bitstream, chunks must be aligned\n");
++			return -EINVAL;
++		}
++	}
+ 
+-	memcpy(kbuf, buf, count);
++	priv->dma_nelms =
++	    dma_map_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
++	if (priv->dma_nelms == 0) {
++		dev_err(&mgr->dev, "Unable to DMA map (TO_DEVICE)\n");
++		return -ENOMEM;
++	}
+ 
+ 	/* enable clock */
+ 	err = clk_enable(priv->clk);
+@@ -316,28 +404,31 @@ static int zynq_fpga_ops_write(struct fp
+ 		goto out_free;
+ 
+ 	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
+-
+ 	reinit_completion(&priv->dma_done);
+ 
+-	/* enable DMA and error IRQs */
+-	zynq_fpga_set_irq(priv, IXR_D_P_DONE_MASK | IXR_ERROR_FLAGS_MASK);
+-
+-	/* the +1 in the src addr is used to hold off on DMA_DONE IRQ
+-	 * until both AXI and PCAP are done ...
+-	 */
+-	zynq_fpga_write(priv, DMA_SRC_ADDR_OFFSET, (u32)(dma_addr) + 1);
+-	zynq_fpga_write(priv, DMA_DST_ADDR_OFFSET, (u32)DMA_INVALID_ADDRESS);
+-
+-	/* convert #bytes to #words */
+-	transfer_length = (count + 3) / 4;
++	/* zynq_step_dma will turn on interrupts */
++	spin_lock_irqsave(&priv->dma_lock, flags);
++	priv->dma_elm = 0;
++	priv->cur_sg = sgt->sgl;
++	zynq_step_dma(priv);
++	spin_unlock_irqrestore(&priv->dma_lock, flags);
+ 
+-	zynq_fpga_write(priv, DMA_SRC_LEN_OFFSET, transfer_length);
+-	zynq_fpga_write(priv, DMA_DEST_LEN_OFFSET, 0);
++	timeout = wait_for_completion_timeout(&priv->dma_done,
++					      msecs_to_jiffies(DMA_TIMEOUT_MS));
+ 
+-	wait_for_completion(&priv->dma_done);
++	spin_lock_irqsave(&priv->dma_lock, flags);
++	zynq_fpga_set_irq(priv, 0);
++	priv->cur_sg = NULL;
++	spin_unlock_irqrestore(&priv->dma_lock, flags);
+ 
+ 	intr_status = zynq_fpga_read(priv, INT_STS_OFFSET);
+-	zynq_fpga_write(priv, INT_STS_OFFSET, intr_status);
++	zynq_fpga_write(priv, INT_STS_OFFSET, IXR_ALL_MASK);
++
++	/* There doesn't seem to be a way to force cancel any DMA, so if
++	 * something went wrong we are relying on the hardware to have halted
++	 * the DMA before we get here, if there was we could use
++	 * wait_for_completion_interruptible too.
++	 */
+ 
+ 	if (intr_status & IXR_ERROR_FLAGS_MASK) {
+ 		why = "DMA reported error";
+@@ -345,8 +436,12 @@ static int zynq_fpga_ops_write(struct fp
+ 		goto out_report;
+ 	}
+ 
+-	if (!((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
+-		why = "DMA did not complete";
++	if (priv->cur_sg ||
++	    !((intr_status & IXR_D_P_DONE_MASK) == IXR_D_P_DONE_MASK)) {
++		if (timeout == 0)
++			why = "DMA timed out";
++		else
++			why = "DMA did not complete";
+ 		err = -EIO;
+ 		goto out_report;
+ 	}
+@@ -369,7 +464,7 @@ out_clk:
+ 	clk_disable(priv->clk);
+ 
+ out_free:
+-	dma_free_coherent(mgr->dev.parent, count, kbuf, dma_addr);
++	dma_unmap_sg(mgr->dev.parent, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
+ 	return err;
+ }
+ 
+@@ -433,7 +528,7 @@ static const struct fpga_manager_ops zyn
+ 	.initial_header_size = 128,
+ 	.state = zynq_fpga_ops_state,
+ 	.write_init = zynq_fpga_ops_write_init,
+-	.write = zynq_fpga_ops_write,
++	.write_sg = zynq_fpga_ops_write,
+ 	.write_complete = zynq_fpga_ops_write_complete,
+ };
+ 
+@@ -447,6 +542,7 @@ static int zynq_fpga_probe(struct platfo
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv)
+ 		return -ENOMEM;
++	spin_lock_init(&priv->dma_lock);
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	priv->io_base = devm_ioremap_resource(dev, res);
diff --git a/patches.socfpga/0045-fpga-fix-sparse-warnings-in-fpga-mgr-and-fpga-bridge.patch b/patches.socfpga/0045-fpga-fix-sparse-warnings-in-fpga-mgr-and-fpga-bridge.patch
new file mode 100644
index 0000000..8c9fde3
--- /dev/null
+++ b/patches.socfpga/0045-fpga-fix-sparse-warnings-in-fpga-mgr-and-fpga-bridge.patch
@@ -0,0 +1,41 @@
+From e465a0699c040d68ea3790af91f6e73cd4797ea7 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Mon, 27 Feb 2017 09:18:59 -0600
+Subject: [PATCH 045/103] fpga: fix sparse warnings in fpga-mgr and fpga-bridge
+
+Fix up these sparse warnings:
+
+drivers/fpga/fpga-mgr.c:189:21: warning: symbol '__fpga_mgr_get' was not declared. Should it be static?
+drivers/fpga/fpga-bridge.c:30:12: warning: symbol 'bridge_list_lock' was not declared. Should it be static?
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Acked-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/fpga-bridge.c |    2 +-
+ drivers/fpga/fpga-mgr.c    |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/fpga/fpga-bridge.c
++++ b/drivers/fpga/fpga-bridge.c
+@@ -27,7 +27,7 @@ static DEFINE_IDA(fpga_bridge_ida);
+ static struct class *fpga_bridge_class;
+ 
+ /* Lock for adding/removing bridges to linked lists*/
+-spinlock_t bridge_list_lock;
++static spinlock_t bridge_list_lock;
+ 
+ static int fpga_bridge_of_node_match(struct device *dev, const void *data)
+ {
+--- a/drivers/fpga/fpga-mgr.c
++++ b/drivers/fpga/fpga-mgr.c
+@@ -361,7 +361,7 @@ static struct attribute *fpga_mgr_attrs[
+ };
+ ATTRIBUTE_GROUPS(fpga_mgr);
+ 
+-struct fpga_manager *__fpga_mgr_get(struct device *dev)
++static struct fpga_manager *__fpga_mgr_get(struct device *dev)
+ {
+ 	struct fpga_manager *mgr;
+ 	int ret = -ENODEV;
diff --git a/patches.socfpga/0046-fpga-Add-flag-to-indicate-bitstream-needs-decrypting.patch b/patches.socfpga/0046-fpga-Add-flag-to-indicate-bitstream-needs-decrypting.patch
new file mode 100644
index 0000000..f2327b0
--- /dev/null
+++ b/patches.socfpga/0046-fpga-Add-flag-to-indicate-bitstream-needs-decrypting.patch
@@ -0,0 +1,29 @@
+From 52ae233165163bb6c71e8be8ee703a1eb0fa3e25 Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Mon, 27 Feb 2017 09:19:00 -0600
+Subject: [PATCH 046/103] fpga: Add flag to indicate bitstream needs decrypting
+
+Add a flag that is passed to the write_init() callback, indicating
+that the bitstream is encrypted.
+
+The low-level driver will deal with the flag, or return an error,
+if encrypted bitstreams are not supported.
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/fpga/fpga-mgr.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -70,6 +70,7 @@ enum fpga_mgr_states {
+  */
+ #define FPGA_MGR_PARTIAL_RECONFIG	BIT(0)
+ #define FPGA_MGR_EXTERNAL_CONFIG	BIT(1)
++#define FPGA_MGR_ENCRYPTED_BITSTREAM	BIT(2)
+ 
+ /**
+  * struct fpga_image_info - information specific to a FPGA image
diff --git a/patches.socfpga/0047-fpga-zynq-Add-support-for-encrypted-bitstreams.patch b/patches.socfpga/0047-fpga-zynq-Add-support-for-encrypted-bitstreams.patch
new file mode 100644
index 0000000..db09d00
--- /dev/null
+++ b/patches.socfpga/0047-fpga-zynq-Add-support-for-encrypted-bitstreams.patch
@@ -0,0 +1,73 @@
+From 478e30d8b329c3c6212e903e6ba68997e2f0582a Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Mon, 27 Feb 2017 09:19:01 -0600
+Subject: [PATCH 047/103] fpga: zynq: Add support for encrypted bitstreams
+
+Add support for encrypted bitstreams. For this to work the system
+must be booted in secure mode.
+
+In order for on-the-fly decryption to work, the PCAP clock rate
+needs to be lowered via the PCAP_RATE_EN bit.
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/zynq-fpga.c |   28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+--- a/drivers/fpga/zynq-fpga.c
++++ b/drivers/fpga/zynq-fpga.c
+@@ -72,6 +72,10 @@
+ #define CTRL_PCAP_PR_MASK		BIT(27)
+ /* Enable PCAP */
+ #define CTRL_PCAP_MODE_MASK		BIT(26)
++/* Lower rate to allow decrypt on the fly */
++#define CTRL_PCAP_RATE_EN_MASK		BIT(25)
++/* System booted in secure mode */
++#define CTRL_SEC_EN_MASK		BIT(7)
+ 
+ /* Miscellaneous Control Register bit definitions */
+ /* Internal PCAP loopback */
+@@ -266,6 +270,17 @@ static int zynq_fpga_ops_write_init(stru
+ 	if (err)
+ 		return err;
+ 
++	/* check if bitstream is encrypted & and system's still secure */
++	if (info->flags & FPGA_MGR_ENCRYPTED_BITSTREAM) {
++		ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
++		if (!(ctrl & CTRL_SEC_EN_MASK)) {
++			dev_err(&mgr->dev,
++				"System not secure, can't use crypted bitstreams\n");
++			err = -EINVAL;
++			goto out_err;
++		}
++	}
++
+ 	/* don't globally reset PL if we're doing partial reconfig */
+ 	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ 		if (!zynq_fpga_has_sync(buf, count)) {
+@@ -337,12 +352,19 @@ static int zynq_fpga_ops_write_init(stru
+ 
+ 	/* set configuration register with following options:
+ 	 * - enable PCAP interface
+-	 * - set throughput for maximum speed
++	 * - set throughput for maximum speed (if bistream not crypted)
+ 	 * - set CPU in user mode
+ 	 */
+ 	ctrl = zynq_fpga_read(priv, CTRL_OFFSET);
+-	zynq_fpga_write(priv, CTRL_OFFSET,
+-			(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK | ctrl));
++	if (info->flags & FPGA_MGR_ENCRYPTED_BITSTREAM)
++		zynq_fpga_write(priv, CTRL_OFFSET,
++				(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK
++				 | CTRL_PCAP_RATE_EN_MASK | ctrl));
++	else
++		zynq_fpga_write(priv, CTRL_OFFSET,
++				(CTRL_PCAP_PR_MASK | CTRL_PCAP_MODE_MASK
++				 | ctrl));
++
+ 
+ 	/* We expect that the command queue is empty right now. */
+ 	status = zynq_fpga_read(priv, STATUS_OFFSET);
diff --git a/patches.socfpga/0048-fpga-region-Add-fpga-region-property-encrypted-fpga-.patch b/patches.socfpga/0048-fpga-region-Add-fpga-region-property-encrypted-fpga-.patch
new file mode 100644
index 0000000..2b425ec
--- /dev/null
+++ b/patches.socfpga/0048-fpga-region-Add-fpga-region-property-encrypted-fpga-.patch
@@ -0,0 +1,52 @@
+From 273c66a75fbbc3ca0afc73fc39c36932da94b37f Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Mon, 27 Feb 2017 09:19:02 -0600
+Subject: [PATCH 048/103] fpga: region: Add fpga-region property
+ 'encrypted-fpga-config'
+
+Add fpga-region property to allow passing the fact that the bitstream is
+encrypted to the fpga-region and ultimately to the low-level driver.
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/fpga/fpga-region.txt |    1 +
+ drivers/fpga/fpga-region.c                             |    8 ++++++--
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/fpga/fpga-region.txt
++++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt
+@@ -186,6 +186,7 @@ Optional properties:
+ 	otherwise full reconfiguration is done.
+ - external-fpga-config : boolean, set if the FPGA has already been configured
+ 	prior to OS boot up.
++- encrypted-fpga-config : boolean, set if the bitstream is encrypted
+ - region-unfreeze-timeout-us : The maximum time in microseconds to wait for
+ 	bridges to successfully become enabled after the region has been
+ 	programmed.
+--- a/drivers/fpga/fpga-region.c
++++ b/drivers/fpga/fpga-region.c
+@@ -337,8 +337,9 @@ static int child_regions_with_firmware(s
+  * The overlay must add either firmware-name or external-fpga-config property
+  * to the FPGA Region.
+  *
+- *   firmware-name        : program the FPGA
+- *   external-fpga-config : FPGA is already programmed
++ *   firmware-name         : program the FPGA
++ *   external-fpga-config  : FPGA is already programmed
++ *   encrypted-fpga-config : FPGA bitstream is encrypted
+  *
+  * The overlay can add other FPGA regions, but child FPGA regions cannot have a
+  * firmware-name property since those regions don't exist yet.
+@@ -373,6 +374,9 @@ static int fpga_region_notify_pre_apply(
+ 	if (of_property_read_bool(nd->overlay, "external-fpga-config"))
+ 		info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
+ 
++	if (of_property_read_bool(nd->overlay, "encrypted-fpga-config"))
++		info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
++
+ 	of_property_read_string(nd->overlay, "firmware-name", &firmware_name);
+ 
+ 	of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us",
diff --git a/patches.socfpga/0049-FPGA-Add-TS-7300-FPGA-manager.patch b/patches.socfpga/0049-FPGA-Add-TS-7300-FPGA-manager.patch
new file mode 100644
index 0000000..6dbc86a
--- /dev/null
+++ b/patches.socfpga/0049-FPGA-Add-TS-7300-FPGA-manager.patch
@@ -0,0 +1,211 @@
+From bed35874b4fe30165188c479341d04fdb7d74230 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 27 Feb 2017 16:14:22 -0600
+Subject: [PATCH 049/103] FPGA: Add TS-7300 FPGA manager
+
+Add support for loading bitstreams on the Altera Cyclone II FPGA
+populated on the TS-7300 board. This is done through the configuration
+and data registers offered through a memory interface between the EP93xx
+SoC and the FPGA via an intermediate CPLD device.
+
+The EP93xx SoC on the TS-7300 does not have direct means of configuring
+the on-board FPGA other than by using the special memory mapped
+interface to the CPLD. No other entity on the system can control the
+FPGA bitstream.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig       |    7 ++
+ drivers/fpga/Makefile      |    1 
+ drivers/fpga/ts73xx-fpga.c |  156 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 164 insertions(+)
+ create mode 100644 drivers/fpga/ts73xx-fpga.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -33,6 +33,13 @@ config FPGA_MGR_SOCFPGA_A10
+ 	help
+ 	  FPGA manager driver support for Altera Arria10 SoCFPGA.
+ 
++config FPGA_MGR_TS73XX
++	tristate "Technologic Systems TS-73xx SBC FPGA Manager"
++	depends on ARCH_EP93XX && MACH_TS72XX
++	help
++	  FPGA manager driver support for the Altera Cyclone II FPGA
++	  present on the TS-73xx SBC boards.
++
+ config FPGA_MGR_ZYNQ_FPGA
+ 	tristate "Xilinx Zynq FPGA"
+ 	depends on ARCH_ZYNQ || COMPILE_TEST
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
+ # FPGA Manager Drivers
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
++obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+ 
+ # FPGA Bridge Drivers
+--- /dev/null
++++ b/drivers/fpga/ts73xx-fpga.c
+@@ -0,0 +1,156 @@
++/*
++ * Technologic Systems TS-73xx SBC FPGA loader
++ *
++ * Copyright (C) 2016 Florian Fainelli <f.fainelli@gmail.com>
++ *
++ * FPGA Manager Driver for the on-board Altera Cyclone II FPGA found on
++ * TS-7300, heavily based on load_fpga.c in their vendor tree.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/string.h>
++#include <linux/iopoll.h>
++#include <linux/fpga/fpga-mgr.h>
++
++#define TS73XX_FPGA_DATA_REG		0
++#define TS73XX_FPGA_CONFIG_REG		1
++
++#define TS73XX_FPGA_WRITE_DONE		0x1
++#define TS73XX_FPGA_WRITE_DONE_TIMEOUT	1000	/* us */
++#define TS73XX_FPGA_RESET		0x2
++#define TS73XX_FPGA_RESET_LOW_DELAY	30	/* us */
++#define TS73XX_FPGA_RESET_HIGH_DELAY	80	/* us */
++#define TS73XX_FPGA_LOAD_OK		0x4
++#define TS73XX_FPGA_CONFIG_LOAD		0x8
++
++struct ts73xx_fpga_priv {
++	void __iomem	*io_base;
++	struct device	*dev;
++};
++
++static enum fpga_mgr_states ts73xx_fpga_state(struct fpga_manager *mgr)
++{
++	return FPGA_MGR_STATE_UNKNOWN;
++}
++
++static int ts73xx_fpga_write_init(struct fpga_manager *mgr,
++				  struct fpga_image_info *info,
++				  const char *buf, size_t count)
++{
++	struct ts73xx_fpga_priv *priv = mgr->priv;
++
++	/* Reset the FPGA */
++	writeb(0, priv->io_base + TS73XX_FPGA_CONFIG_REG);
++	udelay(TS73XX_FPGA_RESET_LOW_DELAY);
++	writeb(TS73XX_FPGA_RESET, priv->io_base + TS73XX_FPGA_CONFIG_REG);
++	udelay(TS73XX_FPGA_RESET_HIGH_DELAY);
++
++	return 0;
++}
++
++static int ts73xx_fpga_write(struct fpga_manager *mgr, const char *buf,
++			     size_t count)
++{
++	struct ts73xx_fpga_priv *priv = mgr->priv;
++	size_t i = 0;
++	int ret;
++	u8 reg;
++
++	while (count--) {
++		ret = readb_poll_timeout(priv->io_base + TS73XX_FPGA_CONFIG_REG,
++					 reg, !(reg & TS73XX_FPGA_WRITE_DONE),
++					 1, TS73XX_FPGA_WRITE_DONE_TIMEOUT);
++		if (ret < 0)
++			return ret;
++
++		writeb(buf[i], priv->io_base + TS73XX_FPGA_DATA_REG);
++		i++;
++	}
++
++	return 0;
++}
++
++static int ts73xx_fpga_write_complete(struct fpga_manager *mgr,
++				      struct fpga_image_info *info)
++{
++	struct ts73xx_fpga_priv *priv = mgr->priv;
++	u8 reg;
++
++	usleep_range(1000, 2000);
++	reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
++	reg |= TS73XX_FPGA_CONFIG_LOAD;
++	writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
++
++	usleep_range(1000, 2000);
++	reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
++	reg &= ~TS73XX_FPGA_CONFIG_LOAD;
++	writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
++
++	reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
++	if ((reg & TS73XX_FPGA_LOAD_OK) != TS73XX_FPGA_LOAD_OK)
++		return -ETIMEDOUT;
++
++	return 0;
++}
++
++static const struct fpga_manager_ops ts73xx_fpga_ops = {
++	.state		= ts73xx_fpga_state,
++	.write_init	= ts73xx_fpga_write_init,
++	.write		= ts73xx_fpga_write,
++	.write_complete	= ts73xx_fpga_write_complete,
++};
++
++static int ts73xx_fpga_probe(struct platform_device *pdev)
++{
++	struct device *kdev = &pdev->dev;
++	struct ts73xx_fpga_priv *priv;
++	struct resource *res;
++
++	priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->dev = kdev;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	priv->io_base = devm_ioremap_resource(kdev, res);
++	if (IS_ERR(priv->io_base)) {
++		dev_err(kdev, "unable to remap registers\n");
++		return PTR_ERR(priv->io_base);
++	}
++
++	return fpga_mgr_register(kdev, "TS-73xx FPGA Manager",
++				 &ts73xx_fpga_ops, priv);
++}
++
++static int ts73xx_fpga_remove(struct platform_device *pdev)
++{
++	fpga_mgr_unregister(&pdev->dev);
++
++	return 0;
++}
++
++static struct platform_driver ts73xx_fpga_driver = {
++	.driver	= {
++		.name	= "ts73xx-fpga-mgr",
++	},
++	.probe	= ts73xx_fpga_probe,
++	.remove	= ts73xx_fpga_remove,
++};
++module_platform_driver(ts73xx_fpga_driver);
++
++MODULE_AUTHOR("Florian Fainelli <f.fainelli@gmail.com>");
++MODULE_DESCRIPTION("TS-73xx FPGA Manager driver");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0050-Documentation-Add-binding-document-for-Lattice-iCE40.patch b/patches.socfpga/0050-Documentation-Add-binding-document-for-Lattice-iCE40.patch
new file mode 100644
index 0000000..c933e57
--- /dev/null
+++ b/patches.socfpga/0050-Documentation-Add-binding-document-for-Lattice-iCE40.patch
@@ -0,0 +1,44 @@
+From 17e3c8974a87f231c91825ff809988797a001f35 Mon Sep 17 00:00:00 2001
+From: Joel Holdsworth <joel@airwebreathe.org.uk>
+Date: Mon, 27 Feb 2017 16:14:25 -0600
+Subject: [PATCH 050/103] Documentation: Add binding document for Lattice iCE40
+ FPGA manager
+
+This adds documentation of the device tree bindings of the Lattice iCE40
+FPGA driver for the FPGA manager framework.
+
+Signed-off-by: Joel Holdsworth <joel@airwebreathe.org.uk>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Acked-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt |   21 ++++++++++
+ 1 file changed, 21 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/lattice-ice40-fpga-mgr.txt
+@@ -0,0 +1,21 @@
++Lattice iCE40 FPGA Manager
++
++Required properties:
++- compatible:		Should contain "lattice,ice40-fpga-mgr"
++- reg:			SPI chip select
++- spi-max-frequency:	Maximum SPI frequency (>=1000000, <=25000000)
++- cdone-gpios:		GPIO input connected to CDONE pin
++- reset-gpios:		Active-low GPIO output connected to CRESET_B pin. Note
++			that unless the GPIO is held low during startup, the
++			FPGA will enter Master SPI mode and drive SCK with a
++			clock signal potentially jamming other devices on the
++			bus until the firmware is loaded.
++
++Example:
++	fpga: fpga@0 {
++		compatible = "lattice,ice40-fpga-mgr";
++		reg = <0>;
++		spi-max-frequency = <1000000>;
++		cdone-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
++		reset-gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
++	};
diff --git a/patches.socfpga/0051-fpga-Add-support-for-Lattice-iCE40-FPGAs.patch b/patches.socfpga/0051-fpga-Add-support-for-Lattice-iCE40-FPGAs.patch
new file mode 100644
index 0000000..afe02a5
--- /dev/null
+++ b/patches.socfpga/0051-fpga-Add-support-for-Lattice-iCE40-FPGAs.patch
@@ -0,0 +1,256 @@
+From dea9de651d978f61922c8cebd01a3089c0acfd04 Mon Sep 17 00:00:00 2001
+From: Joel Holdsworth <joel@airwebreathe.org.uk>
+Date: Mon, 27 Feb 2017 16:14:26 -0600
+Subject: [PATCH 051/103] fpga: Add support for Lattice iCE40 FPGAs
+
+This patch adds support to the FPGA manager for configuring the SRAM of
+iCE40LM, iCE40LP, iCE40HX, iCE40 Ultra, iCE40 UltraLite and iCE40
+UltraPlus devices, through slave SPI.
+
+Signed-off-by: Joel Holdsworth <joel@airwebreathe.org.uk>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Moritz Fischer <moritz.fischer@ettus.com>
+Acked-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig     |    6 +
+ drivers/fpga/Makefile    |    1 
+ drivers/fpga/ice40-spi.c |  207 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 214 insertions(+)
+ create mode 100644 drivers/fpga/ice40-spi.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -20,6 +20,12 @@ config FPGA_REGION
+ 	  FPGA Regions allow loading FPGA images under control of
+ 	  the Device Tree.
+ 
++config FPGA_MGR_ICE40_SPI
++	tristate "Lattice iCE40 SPI"
++	depends on OF && SPI
++	help
++	  FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
++
+ config FPGA_MGR_SOCFPGA
+ 	tristate "Altera SOCFPGA FPGA Manager"
+ 	depends on ARCH_SOCFPGA || COMPILE_TEST
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -6,6 +6,7 @@
+ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
+ 
+ # FPGA Manager Drivers
++obj-$(CONFIG_FPGA_MGR_ICE40_SPI)	+= ice40-spi.o
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
+ obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
+--- /dev/null
++++ b/drivers/fpga/ice40-spi.c
+@@ -0,0 +1,207 @@
++/*
++ * FPGA Manager Driver for Lattice iCE40.
++ *
++ *  Copyright (c) 2016 Joel Holdsworth
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This driver adds support to the FPGA manager for configuring the SRAM of
++ * Lattice iCE40 FPGAs through slave SPI.
++ */
++
++#include <linux/fpga/fpga-mgr.h>
++#include <linux/gpio/consumer.h>
++#include <linux/module.h>
++#include <linux/of_gpio.h>
++#include <linux/spi/spi.h>
++#include <linux/stringify.h>
++
++#define ICE40_SPI_MAX_SPEED 25000000 /* Hz */
++#define ICE40_SPI_MIN_SPEED 1000000 /* Hz */
++
++#define ICE40_SPI_RESET_DELAY 1 /* us (>200ns) */
++#define ICE40_SPI_HOUSEKEEPING_DELAY 1200 /* us */
++
++#define ICE40_SPI_NUM_ACTIVATION_BYTES DIV_ROUND_UP(49, 8)
++
++struct ice40_fpga_priv {
++	struct spi_device *dev;
++	struct gpio_desc *reset;
++	struct gpio_desc *cdone;
++};
++
++static enum fpga_mgr_states ice40_fpga_ops_state(struct fpga_manager *mgr)
++{
++	struct ice40_fpga_priv *priv = mgr->priv;
++
++	return gpiod_get_value(priv->cdone) ? FPGA_MGR_STATE_OPERATING :
++		FPGA_MGR_STATE_UNKNOWN;
++}
++
++static int ice40_fpga_ops_write_init(struct fpga_manager *mgr,
++				     struct fpga_image_info *info,
++				     const char *buf, size_t count)
++{
++	struct ice40_fpga_priv *priv = mgr->priv;
++	struct spi_device *dev = priv->dev;
++	struct spi_message message;
++	struct spi_transfer assert_cs_then_reset_delay = {
++		.cs_change   = 1,
++		.delay_usecs = ICE40_SPI_RESET_DELAY
++	};
++	struct spi_transfer housekeeping_delay_then_release_cs = {
++		.delay_usecs = ICE40_SPI_HOUSEKEEPING_DELAY
++	};
++	int ret;
++
++	if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
++		dev_err(&dev->dev,
++			"Partial reconfiguration is not supported\n");
++		return -ENOTSUPP;
++	}
++
++	/* Lock the bus, assert CRESET_B and SS_B and delay >200ns */
++	spi_bus_lock(dev->master);
++
++	gpiod_set_value(priv->reset, 1);
++
++	spi_message_init(&message);
++	spi_message_add_tail(&assert_cs_then_reset_delay, &message);
++	ret = spi_sync_locked(dev, &message);
++
++	/* Come out of reset */
++	gpiod_set_value(priv->reset, 0);
++
++	/* Abort if the chip-select failed */
++	if (ret)
++		goto fail;
++
++	/* Check CDONE is de-asserted i.e. the FPGA is reset */
++	if (gpiod_get_value(priv->cdone)) {
++		dev_err(&dev->dev, "Device reset failed, CDONE is asserted\n");
++		ret = -EIO;
++		goto fail;
++	}
++
++	/* Wait for the housekeeping to complete, and release SS_B */
++	spi_message_init(&message);
++	spi_message_add_tail(&housekeeping_delay_then_release_cs, &message);
++	ret = spi_sync_locked(dev, &message);
++
++fail:
++	spi_bus_unlock(dev->master);
++
++	return ret;
++}
++
++static int ice40_fpga_ops_write(struct fpga_manager *mgr,
++				const char *buf, size_t count)
++{
++	struct ice40_fpga_priv *priv = mgr->priv;
++
++	return spi_write(priv->dev, buf, count);
++}
++
++static int ice40_fpga_ops_write_complete(struct fpga_manager *mgr,
++					 struct fpga_image_info *info)
++{
++	struct ice40_fpga_priv *priv = mgr->priv;
++	struct spi_device *dev = priv->dev;
++	const u8 padding[ICE40_SPI_NUM_ACTIVATION_BYTES] = {0};
++
++	/* Check CDONE is asserted */
++	if (!gpiod_get_value(priv->cdone)) {
++		dev_err(&dev->dev,
++			"CDONE was not asserted after firmware transfer\n");
++		return -EIO;
++	}
++
++	/* Send of zero-padding to activate the firmware */
++	return spi_write(dev, padding, sizeof(padding));
++}
++
++static const struct fpga_manager_ops ice40_fpga_ops = {
++	.state = ice40_fpga_ops_state,
++	.write_init = ice40_fpga_ops_write_init,
++	.write = ice40_fpga_ops_write,
++	.write_complete = ice40_fpga_ops_write_complete,
++};
++
++static int ice40_fpga_probe(struct spi_device *spi)
++{
++	struct device *dev = &spi->dev;
++	struct ice40_fpga_priv *priv;
++	int ret;
++
++	priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->dev = spi;
++
++	/* Check board setup data. */
++	if (spi->max_speed_hz > ICE40_SPI_MAX_SPEED) {
++		dev_err(dev, "SPI speed is too high, maximum speed is "
++			__stringify(ICE40_SPI_MAX_SPEED) "\n");
++		return -EINVAL;
++	}
++
++	if (spi->max_speed_hz < ICE40_SPI_MIN_SPEED) {
++		dev_err(dev, "SPI speed is too low, minimum speed is "
++			__stringify(ICE40_SPI_MIN_SPEED) "\n");
++		return -EINVAL;
++	}
++
++	if (spi->mode & SPI_CPHA) {
++		dev_err(dev, "Bad SPI mode, CPHA not supported\n");
++		return -EINVAL;
++	}
++
++	/* Set up the GPIOs */
++	priv->cdone = devm_gpiod_get(dev, "cdone", GPIOD_IN);
++	if (IS_ERR(priv->cdone)) {
++		ret = PTR_ERR(priv->cdone);
++		dev_err(dev, "Failed to get CDONE GPIO: %d\n", ret);
++		return ret;
++	}
++
++	priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
++	if (IS_ERR(priv->reset)) {
++		ret = PTR_ERR(priv->reset);
++		dev_err(dev, "Failed to get CRESET_B GPIO: %d\n", ret);
++		return ret;
++	}
++
++	/* Register with the FPGA manager */
++	return fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager",
++				 &ice40_fpga_ops, priv);
++}
++
++static int ice40_fpga_remove(struct spi_device *spi)
++{
++	fpga_mgr_unregister(&spi->dev);
++	return 0;
++}
++
++static const struct of_device_id ice40_fpga_of_match[] = {
++	{ .compatible = "lattice,ice40-fpga-mgr", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ice40_fpga_of_match);
++
++static struct spi_driver ice40_fpga_driver = {
++	.probe = ice40_fpga_probe,
++	.remove = ice40_fpga_remove,
++	.driver = {
++		.name = "ice40spi",
++		.of_match_table = of_match_ptr(ice40_fpga_of_match),
++	},
++};
++
++module_spi_driver(ice40_fpga_driver);
++
++MODULE_AUTHOR("Joel Holdsworth <joel@airwebreathe.org.uk>");
++MODULE_DESCRIPTION("Lattice iCE40 FPGA Manager");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0052-fpga-bridge-Replace-open-coded-list_for_each-list_en.patch b/patches.socfpga/0052-fpga-bridge-Replace-open-coded-list_for_each-list_en.patch
new file mode 100644
index 0000000..a218c13
--- /dev/null
+++ b/patches.socfpga/0052-fpga-bridge-Replace-open-coded-list_for_each-list_en.patch
@@ -0,0 +1,62 @@
+From 65107537be49563835a6accd0a7ef0dd078020cb Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Fri, 10 Mar 2017 12:47:11 -0800
+Subject: [PATCH 052/103] fpga: bridge: Replace open-coded list_for_each +
+ list_entry
+
+Replaces open-coded list_for_each() + list_entry() with macro
+list_for_each_entry()
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Cc: linux-fpga@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/fpga-bridge.c |   15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+--- a/drivers/fpga/fpga-bridge.c
++++ b/drivers/fpga/fpga-bridge.c
+@@ -146,11 +146,9 @@ EXPORT_SYMBOL_GPL(fpga_bridge_put);
+ int fpga_bridges_enable(struct list_head *bridge_list)
+ {
+ 	struct fpga_bridge *bridge;
+-	struct list_head *node;
+ 	int ret;
+ 
+-	list_for_each(node, bridge_list) {
+-		bridge = list_entry(node, struct fpga_bridge, node);
++	list_for_each_entry(bridge, bridge_list, node) {
+ 		ret = fpga_bridge_enable(bridge);
+ 		if (ret)
+ 			return ret;
+@@ -172,11 +170,9 @@ EXPORT_SYMBOL_GPL(fpga_bridges_enable);
+ int fpga_bridges_disable(struct list_head *bridge_list)
+ {
+ 	struct fpga_bridge *bridge;
+-	struct list_head *node;
+ 	int ret;
+ 
+-	list_for_each(node, bridge_list) {
+-		bridge = list_entry(node, struct fpga_bridge, node);
++	list_for_each_entry(bridge, bridge_list, node) {
+ 		ret = fpga_bridge_disable(bridge);
+ 		if (ret)
+ 			return ret;
+@@ -196,13 +192,10 @@ EXPORT_SYMBOL_GPL(fpga_bridges_disable);
+  */
+ void fpga_bridges_put(struct list_head *bridge_list)
+ {
+-	struct fpga_bridge *bridge;
+-	struct list_head *node, *next;
++	struct fpga_bridge *bridge, *next;
+ 	unsigned long flags;
+ 
+-	list_for_each_safe(node, next, bridge_list) {
+-		bridge = list_entry(node, struct fpga_bridge, node);
+-
++	list_for_each_entry_safe(bridge, next, bridge_list, node) {
+ 		fpga_bridge_put(bridge);
+ 
+ 		spin_lock_irqsave(&bridge_list_lock, flags);
diff --git a/patches.socfpga/0053-fpga-altera_freeze_bridge-Constify-ops.patch b/patches.socfpga/0053-fpga-altera_freeze_bridge-Constify-ops.patch
new file mode 100644
index 0000000..2747428
--- /dev/null
+++ b/patches.socfpga/0053-fpga-altera_freeze_bridge-Constify-ops.patch
@@ -0,0 +1,28 @@
+From a55d3c2ff9848a13ccd78a45551bd38c390426fb Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Thu, 23 Mar 2017 19:34:24 -0500
+Subject: [PATCH 053/103] fpga: altera_freeze_bridge: Constify ops
+
+The ops are not changing, make them const.
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Cc: Alan Tull <atull@kernel.org>
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-fpga@vger.kernel.org
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/altera-freeze-bridge.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/fpga/altera-freeze-bridge.c
++++ b/drivers/fpga/altera-freeze-bridge.c
+@@ -203,7 +203,7 @@ static int altera_freeze_br_enable_show(
+ 	return priv->enable;
+ }
+ 
+-static struct fpga_bridge_ops altera_freeze_br_br_ops = {
++static const struct fpga_bridge_ops altera_freeze_br_br_ops = {
+ 	.enable_set = altera_freeze_br_enable_set,
+ 	.enable_show = altera_freeze_br_enable_show,
+ };
diff --git a/patches.socfpga/0054-dt-bindings-fpga-add-xilinx-slave-serial-binding-des.patch b/patches.socfpga/0054-dt-bindings-fpga-add-xilinx-slave-serial-binding-des.patch
new file mode 100644
index 0000000..1c4bcc6
--- /dev/null
+++ b/patches.socfpga/0054-dt-bindings-fpga-add-xilinx-slave-serial-binding-des.patch
@@ -0,0 +1,67 @@
+From bad33a7dfec8bc8eb393519a9b2348d009a2fa6d Mon Sep 17 00:00:00 2001
+From: Anatolij Gustschin <agust@denx.de>
+Date: Thu, 23 Mar 2017 19:34:25 -0500
+Subject: [PATCH 054/103] dt: bindings: fpga: add xilinx slave-serial binding
+ description
+
+Add dt binding documentation details for Xilinx FPGA configuration
+over slave serial interface.
+
+Signed-off-by: Anatolij Gustschin <agust@denx.de>
+Acked-by: Moritz Fischer <mdf@kernel.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt |   44 ++++++++++
+ 1 file changed, 44 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt
+@@ -0,0 +1,44 @@
++Xilinx Slave Serial SPI FPGA Manager
++
++Xilinx Spartan-6 FPGAs support a method of loading the bitstream over
++what is referred to as "slave serial" interface.
++The slave serial link is not technically SPI, and might require extra
++circuits in order to play nicely with other SPI slaves on the same bus.
++
++See https://www.xilinx.com/support/documentation/user_guides/ug380.pdf
++
++Required properties:
++- compatible: should contain "xlnx,fpga-slave-serial"
++- reg: spi chip select of the FPGA
++- prog_b-gpios: config pin (referred to as PROGRAM_B in the manual)
++- done-gpios: config status pin (referred to as DONE in the manual)
++
++Example for full FPGA configuration:
++
++	fpga-region0 {
++		compatible = "fpga-region";
++		fpga-mgr = <&fpga_mgr_spi>;
++		#address-cells = <0x1>;
++		#size-cells = <0x1>;
++	};
++
++	spi1: spi@10680 {
++		compatible = "marvell,armada-xp-spi", "marvell,orion-spi";
++		pinctrl-0 = <&spi0_pins>;
++		pinctrl-names = "default";
++		#address-cells = <1>;
++		#size-cells = <0>;
++		cell-index = <1>;
++		interrupts = <92>;
++		clocks = <&coreclk 0>;
++		status = "okay";
++
++		fpga_mgr_spi: fpga-mgr@0 {
++			compatible = "xlnx,fpga-slave-serial";
++			spi-max-frequency = <60000000>;
++			spi-cpha;
++			reg = <0>;
++			done-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++			prog_b-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
++		};
++	};
diff --git a/patches.socfpga/0055-fpga-manager-Add-Xilinx-slave-serial-SPI-driver.patch b/patches.socfpga/0055-fpga-manager-Add-Xilinx-slave-serial-SPI-driver.patch
new file mode 100644
index 0000000..0f10393
--- /dev/null
+++ b/patches.socfpga/0055-fpga-manager-Add-Xilinx-slave-serial-SPI-driver.patch
@@ -0,0 +1,247 @@
+From d4cd4955c34d18b9849d52ddfe6ca83f9f04e5a5 Mon Sep 17 00:00:00 2001
+From: Anatolij Gustschin <agust@denx.de>
+Date: Thu, 23 Mar 2017 19:34:26 -0500
+Subject: [PATCH 055/103] fpga manager: Add Xilinx slave serial SPI driver
+
+The driver loads FPGA firmware over SPI, using the "slave serial"
+configuration interface on Xilinx FPGAs.
+
+Signed-off-by: Anatolij Gustschin <agust@denx.de>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Reviewed-by: Moritz Fischer <mdf@kernel.org>
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig      |    7 +
+ drivers/fpga/Makefile     |    1 
+ drivers/fpga/xilinx-spi.c |  198 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 206 insertions(+)
+ create mode 100644 drivers/fpga/xilinx-spi.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -46,6 +46,13 @@ config FPGA_MGR_TS73XX
+ 	  FPGA manager driver support for the Altera Cyclone II FPGA
+ 	  present on the TS-73xx SBC boards.
+ 
++config FPGA_MGR_XILINX_SPI
++	tristate "Xilinx Configuration over Slave Serial (SPI)"
++	depends on SPI
++	help
++	  FPGA manager driver support for Xilinx FPGA configuration
++	  over slave serial interface.
++
+ config FPGA_MGR_ZYNQ_FPGA
+ 	tristate "Xilinx Zynq FPGA"
+ 	depends on ARCH_ZYNQ || COMPILE_TEST
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_FPGA_MGR_ICE40_SPI)	+= ice4
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
+ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= socfpga-a10.o
+ obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
++obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+ 
+ # FPGA Bridge Drivers
+--- /dev/null
++++ b/drivers/fpga/xilinx-spi.c
+@@ -0,0 +1,198 @@
++/*
++ * Xilinx Spartan6 Slave Serial SPI Driver
++ *
++ * Copyright (C) 2017 DENX Software Engineering
++ *
++ * Anatolij Gustschin <agust@denx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * Manage Xilinx FPGA firmware that is loaded over SPI using
++ * the slave serial configuration interface.
++ */
++
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/fpga/fpga-mgr.h>
++#include <linux/gpio/consumer.h>
++#include <linux/module.h>
++#include <linux/mod_devicetable.h>
++#include <linux/of.h>
++#include <linux/spi/spi.h>
++#include <linux/sizes.h>
++
++struct xilinx_spi_conf {
++	struct spi_device *spi;
++	struct gpio_desc *prog_b;
++	struct gpio_desc *done;
++};
++
++static enum fpga_mgr_states xilinx_spi_state(struct fpga_manager *mgr)
++{
++	struct xilinx_spi_conf *conf = mgr->priv;
++
++	if (!gpiod_get_value(conf->done))
++		return FPGA_MGR_STATE_RESET;
++
++	return FPGA_MGR_STATE_UNKNOWN;
++}
++
++static int xilinx_spi_write_init(struct fpga_manager *mgr,
++				 struct fpga_image_info *info,
++				 const char *buf, size_t count)
++{
++	struct xilinx_spi_conf *conf = mgr->priv;
++	const size_t prog_latency_7500us = 7500;
++	const size_t prog_pulse_1us = 1;
++
++	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) {
++		dev_err(&mgr->dev, "Partial reconfiguration not supported.\n");
++		return -EINVAL;
++	}
++
++	gpiod_set_value(conf->prog_b, 1);
++
++	udelay(prog_pulse_1us); /* min is 500 ns */
++
++	gpiod_set_value(conf->prog_b, 0);
++
++	if (gpiod_get_value(conf->done)) {
++		dev_err(&mgr->dev, "Unexpected DONE pin state...\n");
++		return -EIO;
++	}
++
++	/* program latency */
++	usleep_range(prog_latency_7500us, prog_latency_7500us + 100);
++	return 0;
++}
++
++static int xilinx_spi_write(struct fpga_manager *mgr, const char *buf,
++			    size_t count)
++{
++	struct xilinx_spi_conf *conf = mgr->priv;
++	const char *fw_data = buf;
++	const char *fw_data_end = fw_data + count;
++
++	while (fw_data < fw_data_end) {
++		size_t remaining, stride;
++		int ret;
++
++		remaining = fw_data_end - fw_data;
++		stride = min_t(size_t, remaining, SZ_4K);
++
++		ret = spi_write(conf->spi, fw_data, stride);
++		if (ret) {
++			dev_err(&mgr->dev, "SPI error in firmware write: %d\n",
++				ret);
++			return ret;
++		}
++		fw_data += stride;
++	}
++
++	return 0;
++}
++
++static int xilinx_spi_apply_cclk_cycles(struct xilinx_spi_conf *conf)
++{
++	struct spi_device *spi = conf->spi;
++	const u8 din_data[1] = { 0xff };
++	int ret;
++
++	ret = spi_write(conf->spi, din_data, sizeof(din_data));
++	if (ret)
++		dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret);
++
++	return ret;
++}
++
++static int xilinx_spi_write_complete(struct fpga_manager *mgr,
++				     struct fpga_image_info *info)
++{
++	struct xilinx_spi_conf *conf = mgr->priv;
++	unsigned long timeout;
++	int ret;
++
++	if (gpiod_get_value(conf->done))
++		return xilinx_spi_apply_cclk_cycles(conf);
++
++	timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us);
++
++	while (time_before(jiffies, timeout)) {
++
++		ret = xilinx_spi_apply_cclk_cycles(conf);
++		if (ret)
++			return ret;
++
++		if (gpiod_get_value(conf->done))
++			return xilinx_spi_apply_cclk_cycles(conf);
++	}
++
++	dev_err(&mgr->dev, "Timeout after config data transfer.\n");
++	return -ETIMEDOUT;
++}
++
++static const struct fpga_manager_ops xilinx_spi_ops = {
++	.state = xilinx_spi_state,
++	.write_init = xilinx_spi_write_init,
++	.write = xilinx_spi_write,
++	.write_complete = xilinx_spi_write_complete,
++};
++
++static int xilinx_spi_probe(struct spi_device *spi)
++{
++	struct xilinx_spi_conf *conf;
++
++	conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
++	if (!conf)
++		return -ENOMEM;
++
++	conf->spi = spi;
++
++	/* PROGRAM_B is active low */
++	conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW);
++	if (IS_ERR(conf->prog_b)) {
++		dev_err(&spi->dev, "Failed to get PROGRAM_B gpio: %ld\n",
++			PTR_ERR(conf->prog_b));
++		return PTR_ERR(conf->prog_b);
++	}
++
++	conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN);
++	if (IS_ERR(conf->done)) {
++		dev_err(&spi->dev, "Failed to get DONE gpio: %ld\n",
++			PTR_ERR(conf->done));
++		return PTR_ERR(conf->done);
++	}
++
++	return fpga_mgr_register(&spi->dev, "Xilinx Slave Serial FPGA Manager",
++				 &xilinx_spi_ops, conf);
++}
++
++static int xilinx_spi_remove(struct spi_device *spi)
++{
++	fpga_mgr_unregister(&spi->dev);
++
++	return 0;
++}
++
++static const struct of_device_id xlnx_spi_of_match[] = {
++	{ .compatible = "xlnx,fpga-slave-serial", },
++	{}
++};
++MODULE_DEVICE_TABLE(of, xlnx_spi_of_match);
++
++static struct spi_driver xilinx_slave_spi_driver = {
++	.driver = {
++		.name = "xlnx-slave-spi",
++		.of_match_table = of_match_ptr(xlnx_spi_of_match),
++	},
++	.probe = xilinx_spi_probe,
++	.remove = xilinx_spi_remove,
++};
++
++module_spi_driver(xilinx_slave_spi_driver)
++
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
++MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SPI");
diff --git a/patches.socfpga/0056-ARM-socfpga-add-bindings-document-for-fpga-bridge-dr.patch b/patches.socfpga/0056-ARM-socfpga-add-bindings-document-for-fpga-bridge-dr.patch
new file mode 100644
index 0000000..3665718
--- /dev/null
+++ b/patches.socfpga/0056-ARM-socfpga-add-bindings-document-for-fpga-bridge-dr.patch
@@ -0,0 +1,85 @@
+From be625b6c7234e180a34bcee690d64bfd52ae116d Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 12 Jul 2016 14:36:41 -0500
+Subject: [PATCH 056/103] ARM: socfpga: add bindings document for fpga bridge
+ drivers
+
+Add bindings documentation for Altera SOCFPGA bridges:
+ * fpga2sdram
+ * fpga2hps
+ * hps2fpga
+ * lwhps2fpga
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt |   16 ++++
+ Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt   |   39 ++++++++++
+ 2 files changed, 55 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
+ create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
+@@ -0,0 +1,16 @@
++Altera FPGA To SDRAM Bridge Driver
++
++Required properties:
++- compatible		: Should contain "altr,socfpga-fpga2sdram-bridge"
++
++Optional properties:
++- bridge-enable		: 0 if driver should disable bridge at startup
++			  1 if driver should enable bridge at startup
++			  Default is to leave bridge in current state.
++
++Example:
++	fpga_bridge3: fpga-bridge@ffc25080 {
++		compatible = "altr,socfpga-fpga2sdram-bridge";
++		reg = <0xffc25080 0x4>;
++		bridge-enable = <0>;
++	};
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
+@@ -0,0 +1,39 @@
++Altera FPGA/HPS Bridge Driver
++
++Required properties:
++- regs		: base address and size for AXI bridge module
++- compatible	: Should contain one of:
++		  "altr,socfpga-lwhps2fpga-bridge",
++		  "altr,socfpga-hps2fpga-bridge", or
++		  "altr,socfpga-fpga2hps-bridge"
++- resets	: Phandle and reset specifier for this bridge's reset
++- clocks	: Clocks used by this module.
++
++Optional properties:
++- bridge-enable	: 0 if driver should disable bridge at startup.
++		  1 if driver should enable bridge at startup.
++		  Default is to leave bridge in its current state.
++
++Example:
++	fpga_bridge0: fpga-bridge@ff400000 {
++		compatible = "altr,socfpga-lwhps2fpga-bridge";
++		reg = <0xff400000 0x100000>;
++		resets = <&rst LWHPS2FPGA_RESET>;
++		clocks = <&l4_main_clk>;
++		bridge-enable = <0>;
++	};
++
++	fpga_bridge1: fpga-bridge@ff500000 {
++		compatible = "altr,socfpga-hps2fpga-bridge";
++		reg = <0xff500000 0x10000>;
++		resets = <&rst HPS2FPGA_RESET>;
++		clocks = <&l4_main_clk>;
++		bridge-enable = <1>;
++	};
++
++	fpga_bridge2: fpga-bridge@ff600000 {
++		compatible = "altr,socfpga-fpga2hps-bridge";
++		reg = <0xff600000 0x100000>;
++		resets = <&rst FPGA2HPS_RESET>;
++		clocks = <&l4_main_clk>;
++	};
diff --git a/patches.socfpga/0057-ARM-socfpga-add-bindings-doc-for-arria10-fpga-manage.patch b/patches.socfpga/0057-ARM-socfpga-add-bindings-doc-for-arria10-fpga-manage.patch
new file mode 100644
index 0000000..a7a2904
--- /dev/null
+++ b/patches.socfpga/0057-ARM-socfpga-add-bindings-doc-for-arria10-fpga-manage.patch
@@ -0,0 +1,40 @@
+From 94068d8c8be80b81e019683b4997a46627e3dd86 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 12 Jul 2016 14:07:08 -0500
+Subject: [PATCH 057/103] ARM: socfpga: add bindings doc for arria10 fpga
+ manager
+
+Add a device tree bindings document for the SoCFPGA Arria10
+FPGA Manager driver.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-By: Moritz Fischer <moritz.fischer@ettus.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt |   19 ++++++++++
+ 1 file changed, 19 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/altera-socfpga-a10-fpga-mgr.txt
+@@ -0,0 +1,19 @@
++Altera SOCFPGA Arria10 FPGA Manager
++
++Required properties:
++- compatible : should contain "altr,socfpga-a10-fpga-mgr"
++- reg        : base address and size for memory mapped io.
++               - The first index is for FPGA manager register access.
++               - The second index is for writing FPGA configuration data.
++- resets     : Phandle and reset specifier for the device's reset.
++- clocks     : Clocks used by the device.
++
++Example:
++
++	fpga_mgr: fpga-mgr@ffd03000 {
++		compatible = "altr,socfpga-a10-fpga-mgr";
++		reg = <0xffd03000 0x100
++		       0xffcfe400 0x20>;
++		clocks = <&l4_mp_clk>;
++		resets = <&rst FPGAMGR_RESET>;
++	};
diff --git a/patches.socfpga/0058-add-bindings-document-for-altera-freeze-bridge.patch b/patches.socfpga/0058-add-bindings-document-for-altera-freeze-bridge.patch
new file mode 100644
index 0000000..8863758
--- /dev/null
+++ b/patches.socfpga/0058-add-bindings-document-for-altera-freeze-bridge.patch
@@ -0,0 +1,45 @@
+From 48e56f16d7bc13665e037dc17935a23dc440e0df Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Mon, 17 Oct 2016 11:09:34 -0500
+Subject: [PATCH 058/103] add bindings document for altera freeze bridge
+
+Add bindings document for the Altera Freeze Bridge.  A Freeze
+Bridge is used to gate traffic to/from a region of a FPGA
+such that that region can be reprogrammed.  The Freeze Bridge
+exist in FPGA fabric that is not currently being reconfigured.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Matthew Gerlach <mgerlach@opensource.altera.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Rob Herring <robh@kernel.org>
+---
+ Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt |   23 ++++++++++
+ 1 file changed, 23 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/altera-freeze-bridge.txt
+@@ -0,0 +1,23 @@
++Altera Freeze Bridge Controller Driver
++
++The Altera Freeze Bridge Controller manages one or more freeze bridges.
++The controller can freeze/disable the bridges which prevents signal
++changes from passing through the bridge.  The controller can also
++unfreeze/enable the bridges which allows traffic to pass through the
++bridge normally.
++
++Required properties:
++- compatible		: Should contain "altr,freeze-bridge-controller"
++- regs			: base address and size for freeze bridge module
++
++Optional properties:
++- bridge-enable		: 0 if driver should disable bridge at startup
++			  1 if driver should enable bridge at startup
++			  Default is to leave bridge in current state.
++
++Example:
++	freeze-controller@100000450 {
++		compatible = "altr,freeze-bridge-controller";
++		regs = <0x1000 0x10>;
++		bridge-enable = <0>;
++	};
diff --git a/patches.socfpga/0059-MAINTAINERS-add-git-url-for-fpga.patch b/patches.socfpga/0059-MAINTAINERS-add-git-url-for-fpga.patch
new file mode 100644
index 0000000..e7a9286
--- /dev/null
+++ b/patches.socfpga/0059-MAINTAINERS-add-git-url-for-fpga.patch
@@ -0,0 +1,22 @@
+From c642ff14e89edf9cb54008765c97e75e505545b7 Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Tue, 29 Nov 2016 15:15:45 -0600
+Subject: [PATCH 059/103] MAINTAINERS: add git url for fpga
+
+Add git url for fpga stuff.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+---
+ MAINTAINERS |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4959,6 +4959,7 @@ FPGA MANAGER FRAMEWORK
+ M:	Alan Tull <atull@opensource.altera.com>
+ R:	Moritz Fischer <moritz.fischer@ettus.com>
+ S:	Maintained
++T:	git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
+ F:	drivers/fpga/
+ F:	include/linux/fpga/fpga-mgr.h
+ W:	http://www.rocketboards.org
diff --git a/patches.socfpga/0060-ARM-dts-socfpga-add-base-fpga-region-and-fpga-bridge.patch b/patches.socfpga/0060-ARM-dts-socfpga-add-base-fpga-region-and-fpga-bridge.patch
new file mode 100644
index 0000000..704a2dc
--- /dev/null
+++ b/patches.socfpga/0060-ARM-dts-socfpga-add-base-fpga-region-and-fpga-bridge.patch
@@ -0,0 +1,68 @@
+From d063b52520c412dccb99b0737b5e2b462d83dd8a Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Fri, 26 Feb 2016 14:21:04 -0600
+Subject: [PATCH 060/103] ARM: dts: socfpga: add base fpga region and fpga
+ bridges
+
+Add h2f and lwh2f bridges.
+Add base FPGA Region to support DT overlays for FPGA programming.
+Add l3regs.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+v2: removed fpga-bridges, ranges, and reset-names
+---
+ arch/arm/boot/dts/socfpga.dtsi |   27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga.dtsi
++++ b/arch/arm/boot/dts/socfpga.dtsi
+@@ -93,6 +93,14 @@
+ 			};
+ 		};
+ 
++		base_fpga_region {
++			compatible = "fpga-region";
++			fpga-mgr = <&fpgamgr0>;
++
++			#address-cells = <0x1>;
++			#size-cells = <0x1>;
++		};
++
+ 		can0: can@ffc00000 {
+ 			compatible = "bosch,d_can";
+ 			reg = <0xffc00000 0x1000>;
+@@ -513,6 +521,20 @@
+ 				};
+ 		};
+ 
++		fpga_bridge0: fpga_bridge@ff400000 {
++			compatible = "altr,socfpga-lwhps2fpga-bridge";
++			reg = <0xff400000 0x100000>;
++			resets = <&rst LWHPS2FPGA_RESET>;
++			clocks = <&l4_main_clk>;
++		};
++
++		fpga_bridge1: fpga_bridge@ff500000 {
++			compatible = "altr,socfpga-hps2fpga-bridge";
++			reg = <0xff500000 0x10000>;
++			resets = <&rst HPS2FPGA_RESET>;
++			clocks = <&l4_main_clk>;
++		};
++
+ 		fpgamgr0: fpgamgr@ff706000 {
+ 			compatible = "altr,socfpga-fpga-mgr";
+ 			reg = <0xff706000 0x1000
+@@ -689,6 +711,11 @@
+ 			arm,shared-override;
+ 		};
+ 
++		l3regs@0xff800000 {
++			compatible = "altr,l3regs", "syscon";
++			reg = <0xff800000 0x1000>;
++		};
++
+ 		mmc: dwmmc0@ff704000 {
+ 			compatible = "altr,socfpga-dw-mshc";
+ 			reg = <0xff704000 0x1000>;
diff --git a/patches.socfpga/0061-fpga-add-config-complete-timeout.patch b/patches.socfpga/0061-fpga-add-config-complete-timeout.patch
new file mode 100644
index 0000000..b3594a4
--- /dev/null
+++ b/patches.socfpga/0061-fpga-add-config-complete-timeout.patch
@@ -0,0 +1,44 @@
+From 3871c39c6683965dbafdedc7b9f9b558cf620f0f Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Thu, 23 Mar 2017 19:34:27 -0500
+Subject: [PATCH 061/103] fpga: add config complete timeout
+
+Adding timeout for maximum allowed time for FPGA to go to
+operating mode after a FPGA region has been programmed.
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/fpga-region.c    |    3 +++
+ include/linux/fpga/fpga-mgr.h |    3 +++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/fpga/fpga-region.c
++++ b/drivers/fpga/fpga-region.c
+@@ -385,6 +385,9 @@ static int fpga_region_notify_pre_apply(
+ 	of_property_read_u32(nd->overlay, "region-freeze-timeout-us",
+ 			     &info->disable_timeout_us);
+ 
++	of_property_read_u32(nd->overlay, "config-complete-timeout-us",
++			     &info->config_complete_timeout_us);
++
+ 	/* If FPGA was externally programmed, don't specify firmware */
+ 	if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) {
+ 		pr_err("error: specified firmware and external-fpga-config");
+--- a/include/linux/fpga/fpga-mgr.h
++++ b/include/linux/fpga/fpga-mgr.h
+@@ -77,11 +77,14 @@ enum fpga_mgr_states {
+  * @flags: boolean flags as defined above
+  * @enable_timeout_us: maximum time to enable traffic through bridge (uSec)
+  * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
++ * @config_complete_timeout_us: maximum time for FPGA to switch to operating
++ *	   status in the write_complete op.
+  */
+ struct fpga_image_info {
+ 	u32 flags;
+ 	u32 enable_timeout_us;
+ 	u32 disable_timeout_us;
++	u32 config_complete_timeout_us;
+ };
+ 
+ /**
diff --git a/patches.socfpga/0062-MAINTAINERS-Add-file-patterns-for-fpga-device-tree-b.patch b/patches.socfpga/0062-MAINTAINERS-Add-file-patterns-for-fpga-device-tree-b.patch
new file mode 100644
index 0000000..5180d45
--- /dev/null
+++ b/patches.socfpga/0062-MAINTAINERS-Add-file-patterns-for-fpga-device-tree-b.patch
@@ -0,0 +1,30 @@
+From f2e9e7db072f6445f9fea325f93f3406b78edc11 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Thu, 23 Mar 2017 19:34:31 -0500
+Subject: [PATCH 062/103] MAINTAINERS: Add file patterns for fpga device tree
+ bindings
+
+Submitters of device tree binding documentation may forget to CC
+the subsystem maintainer if this is missing.
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Moritz Fischer <moritz.fischer@ettus.com>
+Cc: Alan Tull <atull@opensource.altera.com>
+Cc: Moritz Fischer <moritz.fischer@ettus.com>
+Cc: linux-fpga@vger.kernel.org
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4960,6 +4960,7 @@ M:	Alan Tull <atull@opensource.altera.co
+ R:	Moritz Fischer <moritz.fischer@ettus.com>
+ S:	Maintained
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
++F:	Documentation/devicetree/bindings/fpga/
+ F:	drivers/fpga/
+ F:	include/linux/fpga/fpga-mgr.h
+ W:	http://www.rocketboards.org
diff --git a/patches.socfpga/0063-MAINTAINERS-fpga-update-email-and-directory-paths.patch b/patches.socfpga/0063-MAINTAINERS-fpga-update-email-and-directory-paths.patch
new file mode 100644
index 0000000..499db05
--- /dev/null
+++ b/patches.socfpga/0063-MAINTAINERS-fpga-update-email-and-directory-paths.patch
@@ -0,0 +1,35 @@
+From efcf802e63e2d545f6695ed386a3737ed9f1d77e Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@kernel.org>
+Date: Thu, 30 Mar 2017 13:23:12 -0500
+Subject: [PATCH 063/103] MAINTAINERS: fpga: update email and directory paths
+
+A few updates:
+* Updating my email address
+* Adding another docs directory: Documentation/fpga
+* Making the include path not specific to fpga-mgr.h only
+
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4956,13 +4956,14 @@ F:	include/linux/ipmi-fru.h
+ K:	fmc_d.*register
+ 
+ FPGA MANAGER FRAMEWORK
+-M:	Alan Tull <atull@opensource.altera.com>
++M:	Alan Tull <atull@kernel.org>
+ R:	Moritz Fischer <moritz.fischer@ettus.com>
+ S:	Maintained
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
++F:	Documentation/fpga/
+ F:	Documentation/devicetree/bindings/fpga/
+ F:	drivers/fpga/
+-F:	include/linux/fpga/fpga-mgr.h
++F:	include/linux/fpga/
+ W:	http://www.rocketboards.org
+ 
+ FPU EMULATOR
diff --git a/patches.socfpga/0064-spi-Add-Flag-to-Enable-Slave-Select-with-GPIO-Chip-S.patch b/patches.socfpga/0064-spi-Add-Flag-to-Enable-Slave-Select-with-GPIO-Chip-S.patch
new file mode 100644
index 0000000..b64e9d5
--- /dev/null
+++ b/patches.socfpga/0064-spi-Add-Flag-to-Enable-Slave-Select-with-GPIO-Chip-S.patch
@@ -0,0 +1,56 @@
+From d500a6439c32092db46195c550ef617ce3a3ffc2 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Mon, 10 Oct 2016 09:25:24 -0500
+Subject: [PATCH 064/103] spi: Add Flag to Enable Slave Select with GPIO Chip
+ Select.
+
+Some SPI masters require slave selection before the transfer
+can begin [1]. The SPI framework currently selects the chip using
+either 1) the internal CS mechanism or 2) the GPIO CS, but not both.
+
+This patch adds a new master->flags define to indicate both the GPIO
+CS and the internal chip select mechanism should be used.
+
+Tested On:
+    Altera CycloneV development kit
+    Compile tested for build errors on x86_64 (allyesconfigs)
+
+[1] DesignWare dw_apb_ssi Databook, Version 3.20a (page 39)
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ drivers/spi/spi.c       |    9 +++++++--
+ include/linux/spi/spi.h |    1 +
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -699,10 +699,15 @@ static void spi_set_cs(struct spi_device
+ 	if (spi->mode & SPI_CS_HIGH)
+ 		enable = !enable;
+ 
+-	if (gpio_is_valid(spi->cs_gpio))
++	if (gpio_is_valid(spi->cs_gpio)) {
+ 		gpio_set_value(spi->cs_gpio, !enable);
+-	else if (spi->master->set_cs)
++		/* Some SPI masters need both GPIO CS & slave_select */
++		if ((spi->master->flags & SPI_MASTER_GPIO_SS) &&
++		    spi->master->set_cs)
++			spi->master->set_cs(spi, !enable);
++	} else if (spi->master->set_cs) {
+ 		spi->master->set_cs(spi, !enable);
++	}
+ }
+ 
+ #ifdef CONFIG_HAS_DMA
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -442,6 +442,7 @@ struct spi_master {
+ #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
+ #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
+ #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
++#define SPI_MASTER_GPIO_SS      BIT(5)		/* GPIO CS must select slave */
+ 
+ 	/*
+ 	 * on some hardware transfer / message size may be constrained
diff --git a/patches.socfpga/0065-spi-dw-Set-GPIO_SS-flag-to-toggle-Slave-Select-on-GP.patch b/patches.socfpga/0065-spi-dw-Set-GPIO_SS-flag-to-toggle-Slave-Select-on-GP.patch
new file mode 100644
index 0000000..861baed
--- /dev/null
+++ b/patches.socfpga/0065-spi-dw-Set-GPIO_SS-flag-to-toggle-Slave-Select-on-GP.patch
@@ -0,0 +1,34 @@
+From 1d1b6b573a601464ca8ec40ace560a30fa00bdf4 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Mon, 10 Oct 2016 09:25:25 -0500
+Subject: [PATCH 065/103] spi: dw: Set GPIO_SS flag to toggle Slave Select on
+ GPIO CS
+
+The Designware SPI master requires slave selection before the transfer
+can begin [1].
+
+This patch uses the new master flag to indicate both the GPIO CS and
+the internal chip select should be used.
+
+Tested On:
+    Altera CycloneV development kit
+    Compile tested for build errors on x86_64 (allyesconfigs)
+
+[1] DesignWare dw_apb_ssi Databook, Version 3.20a (page 39)
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ drivers/spi/spi-dw.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/spi/spi-dw.c
++++ b/drivers/spi/spi-dw.c
+@@ -502,6 +502,7 @@ int dw_spi_add_host(struct device *dev,
+ 	master->handle_err = dw_spi_handle_err;
+ 	master->max_speed_hz = dws->max_freq;
+ 	master->dev.of_node = dev->of_node;
++	master->flags = SPI_MASTER_GPIO_SS;
+ 
+ 	/* Basic HW init */
+ 	spi_hw_init(dev, dws);
diff --git a/patches.socfpga/0066-ARM-dts-socfpga-Add-SPI-Master1-for-Arria10-SR-chip.patch b/patches.socfpga/0066-ARM-dts-socfpga-Add-SPI-Master1-for-Arria10-SR-chip.patch
new file mode 100644
index 0000000..a6a2449
--- /dev/null
+++ b/patches.socfpga/0066-ARM-dts-socfpga-Add-SPI-Master1-for-Arria10-SR-chip.patch
@@ -0,0 +1,39 @@
+From 591692b01bed97f524daa7623e58543276e32abd Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 17:52:25 +0000
+Subject: [PATCH 066/103] ARM: dts: socfpga: Add SPI Master1 for Arria10 SR
+ chip
+
+Add the Altera Arria10 SPI Master Node in preparation for
+the A10SR MFD node.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria10.dtsi |   15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -579,6 +579,21 @@
+ 			status = "disabled";
+ 		};
+ 
++		spi1: spi@ffda5000 {
++			compatible = "snps,dw-apb-ssi";
++			#address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xffda5000 0x100>;
++			interrupts = <0 102 4>;
++			num-chipselect = <4>;
++			bus-num = <0>;
++			/*32bit_access;*/
++			tx-dma-channel = <&pdma 16>;
++			rx-dma-channel = <&pdma 17>;
++			clocks = <&spi_m_clk>;
++			status = "disabled";
++		};
++
+ 		sdr: sdr@ffc25000 {
+ 			compatible = "altr,sdr-ctl", "syscon";
+ 			reg = <0xffcfb100 0x80>;
diff --git a/patches.socfpga/0067-ARM-dts-socfpga-Add-Devkit-A10-SR-fields-for-Arria10.patch b/patches.socfpga/0067-ARM-dts-socfpga-Add-Devkit-A10-SR-fields-for-Arria10.patch
new file mode 100644
index 0000000..4797dfc
--- /dev/null
+++ b/patches.socfpga/0067-ARM-dts-socfpga-Add-Devkit-A10-SR-fields-for-Arria10.patch
@@ -0,0 +1,45 @@
+From dd696cdcf4973ec6ba54ed24283548c1e57948cf Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 17:52:26 +0000
+Subject: [PATCH 067/103] ARM: dts: socfpga: Add Devkit A10-SR fields for
+ Arria10
+
+Add the Altera Arria10 System Resource node. This is a Multi-Function
+device with GPIO expander support.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -75,6 +75,27 @@
+ 	status = "okay";
+ };
+ 
++&spi1 {
++	status = "okay";
++
++	resource-manager@0 {
++		compatible = "altr,a10sr";
++		reg = <0>;
++		spi-max-frequency = <100000>;
++		/* low-level active IRQ at GPIO1_5 */
++		interrupt-parent = <&portb>;
++		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
++		interrupt-controller;
++		#interrupt-cells = <2>;
++
++		a10sr_gpio: gpio-controller {
++			compatible = "altr,a10sr-gpio";
++			gpio-controller;
++			#gpio-cells = <2>;
++		};
++	};
++};
++
+ &i2c1 {
+ 	speed-mode = <0>;
+ 	status = "okay";
diff --git a/patches.socfpga/0068-ARM-dts-socfpga-Enable-GPIO-parent-for-Arria10-SR-ch.patch b/patches.socfpga/0068-ARM-dts-socfpga-Enable-GPIO-parent-for-Arria10-SR-ch.patch
new file mode 100644
index 0000000..d24d027
--- /dev/null
+++ b/patches.socfpga/0068-ARM-dts-socfpga-Enable-GPIO-parent-for-Arria10-SR-ch.patch
@@ -0,0 +1,27 @@
+From a672d36e350129ca4b0d5fd127d2672c6484100d Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 17:52:27 +0000
+Subject: [PATCH 068/103] ARM: dts: socfpga: Enable GPIO parent for Arria10 SR
+ chip
+
+Enable the Altera Arria10 GPIO parent for MFD operation.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -75,6 +75,10 @@
+ 	status = "okay";
+ };
+ 
++&gpio1 {
++	status = "okay";
++};
++
+ &spi1 {
+ 	status = "okay";
+ 
diff --git a/patches.socfpga/0069-ARM-dts-socfpga-Add-LED-framework-to-A10-SR-GPIO.patch b/patches.socfpga/0069-ARM-dts-socfpga-Add-LED-framework-to-A10-SR-GPIO.patch
new file mode 100644
index 0000000..0a3341b
--- /dev/null
+++ b/patches.socfpga/0069-ARM-dts-socfpga-Add-LED-framework-to-A10-SR-GPIO.patch
@@ -0,0 +1,46 @@
+From 40c6c417eabe97c7a3364f418880e00e9da7b420 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 17:52:28 +0000
+Subject: [PATCH 069/103] ARM: dts: socfpga: Add LED framework to A10-SR GPIO
+
+Add the LED framework to the Arria10 System Resource chip GPIO hooks.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |   24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -36,6 +36,30 @@
+ 		reg = <0x0 0x40000000>; /* 1GB */
+ 	};
+ 
++	a10leds {
++		compatible = "gpio-leds";
++
++		a10sr_led0 {
++			label = "a10sr-led0";
++			gpios = <&a10sr_gpio 0 1>;
++		};
++
++		a10sr_led1 {
++			label = "a10sr-led1";
++			gpios = <&a10sr_gpio 1 1>;
++		};
++
++		a10sr_led2 {
++			label = "a10sr-led2";
++			gpios = <&a10sr_gpio 2 1>;
++		};
++
++		a10sr_led3 {
++			label = "a10sr-led3";
++			gpios = <&a10sr_gpio 3 1>;
++		};
++	};
++
+ 	soc {
+ 		clkmgr@ffd04000 {
+ 			clocks {
diff --git a/patches.socfpga/0070-EDAC-altera-Disable-IRQs-while-injecting-SDRAM-error.patch b/patches.socfpga/0070-EDAC-altera-Disable-IRQs-while-injecting-SDRAM-error.patch
new file mode 100644
index 0000000..6edb883
--- /dev/null
+++ b/patches.socfpga/0070-EDAC-altera-Disable-IRQs-while-injecting-SDRAM-error.patch
@@ -0,0 +1,40 @@
+From ea62c7b1bf6a7fa765bddfc710a279e233ead67c Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Wed, 19 Oct 2016 14:53:47 -0500
+Subject: [PATCH 070/103] EDAC, altera: Disable IRQs while injecting SDRAM
+ errors
+
+Disable IRQs while injecting SDRAM errors. The RT patches exposed
+a spinlock deadlock where the spinlock taken for the regmap write
+deadlocked with the IRQ clear regmap write.
+
+Error injection is not normally enabled for ECC but only for testing.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Link: http://lkml.kernel.org/r/1476906827-9412-1-git-send-email-tthayer@opensource.altera.com
+Signed-off-by: Borislav Petkov <bp@suse.de>
+---
+ drivers/edac/altera_edac.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/edac/altera_edac.c
++++ b/drivers/edac/altera_edac.c
+@@ -153,13 +153,17 @@ static ssize_t altr_sdr_mc_err_inject_wr
+ 	if (count == 3) {
+ 		edac_printk(KERN_ALERT, EDAC_MC,
+ 			    "Inject Double bit error\n");
++		local_irq_disable();
+ 		regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
+ 			     (read_reg | priv->ue_set_mask));
++		local_irq_enable();
+ 	} else {
+ 		edac_printk(KERN_ALERT, EDAC_MC,
+ 			    "Inject Single bit error\n");
++		local_irq_disable();
+ 		regmap_write(drvdata->mc_vbase,	priv->ce_ue_trgr_offset,
+ 			     (read_reg | priv->ce_set_mask));
++		local_irq_enable();
+ 	}
+ 
+ 	ptemp[0] = 0x5A5A5A5A;
diff --git a/patches.socfpga/0071-gpio-altera-a10sr-Add-A10-System-Resource-Chip-GPIO-.patch b/patches.socfpga/0071-gpio-altera-a10sr-Add-A10-System-Resource-Chip-GPIO-.patch
new file mode 100644
index 0000000..29332fa
--- /dev/null
+++ b/patches.socfpga/0071-gpio-altera-a10sr-Add-A10-System-Resource-Chip-GPIO-.patch
@@ -0,0 +1,190 @@
+From 26b18f6bff88d437c9949a2251c5bc62de427311 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 12:52:24 -0500
+Subject: [PATCH 071/103] gpio: altera-a10sr: Add A10 System Resource Chip GPIO
+ support.
+
+Add the GPIO functionality for the Altera Arria10 MAX5 System Resource
+Chip. The A10 MAX5 has 12 bits of GPIO assigned to switches, buttons,
+and LEDs as a GPIO extender on the SPI bus.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>i
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/gpio/Kconfig             |    8 ++
+ drivers/gpio/Makefile            |    1 
+ drivers/gpio/gpio-altera-a10sr.c |  140 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 149 insertions(+)
+ create mode 100644 drivers/gpio/gpio-altera-a10sr.c
+
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -814,6 +814,14 @@ config GPIO_ADP5520
+ 	  This option enables support for on-chip GPIO found
+ 	  on Analog Devices ADP5520 PMICs.
+ 
++config GPIO_ALTERA_A10SR
++	tristate "Altera Arria10 System Resource GPIO"
++	depends on MFD_ALTERA_A10SR
++	help
++	  Driver for Arria10 Development Kit GPIO expansion which
++	  includes reads of pushbuttons and DIP switches as well
++	  as writes to LEDs.
++
+ config GPIO_ARIZONA
+ 	tristate "Wolfson Microelectronics Arizona class devices"
+ 	depends on MFD_ARIZONA
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_ADNP)		+= gpio-adnp.o
+ obj-$(CONFIG_GPIO_ADP5520)	+= gpio-adp5520.o
+ obj-$(CONFIG_GPIO_ADP5588)	+= gpio-adp5588.o
+ obj-$(CONFIG_GPIO_ALTERA)  	+= gpio-altera.o
++obj-$(CONFIG_GPIO_ALTERA_A10SR)	+= gpio-altera-a10sr.o
+ obj-$(CONFIG_GPIO_AMD8111)	+= gpio-amd8111.o
+ obj-$(CONFIG_GPIO_AMDPT)	+= gpio-amdpt.o
+ obj-$(CONFIG_GPIO_ARIZONA)	+= gpio-arizona.o
+--- /dev/null
++++ b/drivers/gpio/gpio-altera-a10sr.c
+@@ -0,0 +1,140 @@
++/*
++ *  Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * GPIO driver for  Altera Arria10 MAX5 System Resource Chip
++ *
++ * Adapted from gpio-tps65910.c
++ */
++
++#include <linux/gpio/driver.h>
++#include <linux/mfd/altera-a10sr.h>
++#include <linux/module.h>
++
++/**
++ * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure
++ * @gp:   : instance of the gpio_chip
++ * @regmap: the regmap from the parent device.
++ */
++struct altr_a10sr_gpio {
++	struct gpio_chip gp;
++	struct regmap *regmap;
++};
++
++static int altr_a10sr_gpio_get(struct gpio_chip *chip, unsigned int offset)
++{
++	struct altr_a10sr_gpio *gpio = gpiochip_get_data(chip);
++	int ret, val;
++
++	ret = regmap_read(gpio->regmap, ALTR_A10SR_PBDSW_REG, &val);
++	if (ret < 0)
++		return ret;
++
++	return !!(val & BIT(offset - ALTR_A10SR_LED_VALID_SHIFT));
++}
++
++static void altr_a10sr_gpio_set(struct gpio_chip *chip, unsigned int offset,
++				int value)
++{
++	struct altr_a10sr_gpio *gpio = gpiochip_get_data(chip);
++
++	regmap_update_bits(gpio->regmap, ALTR_A10SR_LED_REG,
++			   BIT(ALTR_A10SR_LED_VALID_SHIFT + offset),
++			   value ? BIT(ALTR_A10SR_LED_VALID_SHIFT + offset)
++			   : 0);
++}
++
++static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc,
++					   unsigned int nr)
++{
++	if (nr >= (ALTR_A10SR_IN_VALID_RANGE_LO - ALTR_A10SR_LED_VALID_SHIFT))
++		return 0;
++	return -EINVAL;
++}
++
++static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
++					    unsigned int nr, int value)
++{
++	if (nr <= (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT))
++		return 0;
++	return -EINVAL;
++}
++
++static struct gpio_chip altr_a10sr_gc = {
++	.label = "altr_a10sr_gpio",
++	.owner = THIS_MODULE,
++	.get = altr_a10sr_gpio_get,
++	.set = altr_a10sr_gpio_set,
++	.direction_input = altr_a10sr_gpio_direction_input,
++	.direction_output = altr_a10sr_gpio_direction_output,
++	.can_sleep = true,
++	.ngpio = 12,
++	.base = -1,
++};
++
++static int altr_a10sr_gpio_probe(struct platform_device *pdev)
++{
++	struct altr_a10sr_gpio *gpio;
++	int ret;
++	struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent);
++
++	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
++	if (!gpio)
++		return -ENOMEM;
++
++	gpio->regmap = a10sr->regmap;
++
++	gpio->gp = altr_a10sr_gc;
++
++	gpio->gp.of_node = pdev->dev.of_node;
++
++	ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
++		return ret;
++	}
++
++	platform_set_drvdata(pdev, gpio);
++
++	return 0;
++}
++
++static int altr_a10sr_gpio_remove(struct platform_device *pdev)
++{
++	struct altr_a10sr_gpio *gpio = platform_get_drvdata(pdev);
++
++	gpiochip_remove(&gpio->gp);
++
++	return 0;
++}
++
++static const struct of_device_id altr_a10sr_gpio_of_match[] = {
++	{ .compatible = "altr,a10sr-gpio" },
++	{ },
++};
++MODULE_DEVICE_TABLE(of, altr_a10sr_gpio_of_match);
++
++static struct platform_driver altr_a10sr_gpio_driver = {
++	.probe = altr_a10sr_gpio_probe,
++	.remove = altr_a10sr_gpio_remove,
++	.driver = {
++		.name	= "altr_a10sr_gpio",
++		.of_match_table = of_match_ptr(altr_a10sr_gpio_of_match),
++	},
++};
++module_platform_driver(altr_a10sr_gpio_driver);
++
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
++MODULE_DESCRIPTION("Altera Arria10 System Resource Chip GPIO");
diff --git a/patches.socfpga/0072-dt-bindings-mfd-Add-Altera-Arria10-System-Resource-C.patch b/patches.socfpga/0072-dt-bindings-mfd-Add-Altera-Arria10-System-Resource-C.patch
new file mode 100644
index 0000000..48faa04
--- /dev/null
+++ b/patches.socfpga/0072-dt-bindings-mfd-Add-Altera-Arria10-System-Resource-C.patch
@@ -0,0 +1,67 @@
+From e9ea91f657e4f88cbedf1e93a19176d45d47548e Mon Sep 17 00:00:00 2001
+From: Thor Thayer <tthayer@opensource.altera.com>
+Date: Thu, 2 Jun 2016 12:52:21 -0500
+Subject: [PATCH 072/103] dt-bindings: mfd: Add Altera Arria10 System Resource
+ Chip bindings
+
+The Altera Arria10 Devkit System Resource chip is a Multi-Function
+Device with a GPIO expander.
+
+This patch adds documentation for the Altera A10-SR DT bindings.
+
+Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+---
+ Documentation/devicetree/bindings/mfd/altera-a10sr.txt |   46 +++++++++++++++++
+ 1 file changed, 46 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mfd/altera-a10sr.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
+@@ -0,0 +1,46 @@
++* Altera Arria10 Development Kit System Resource Chip
++
++Required parent device properties:
++- compatible		: "altr,a10sr"
++- spi-max-frequency	: Maximum SPI frequency.
++- reg			: The SPI Chip Select address for the Arria10
++			  System Resource chip
++- interrupt-parent	: The parent interrupt controller.
++- interrupts		: The interrupt line the device is connected to.
++- interrupt-controller	: Marks the device node as an interrupt controller.
++- #interrupt-cells	: The number of cells to describe an IRQ, should be 2.
++			    The first cell is the IRQ number.
++			    The second cell is the flags, encoded as trigger
++			    masks from ../interrupt-controller/interrupts.txt.
++
++The A10SR consists of these sub-devices:
++
++Device                   Description
++------                   ----------
++a10sr_gpio               GPIO Controller
++
++Arria10 GPIO
++Required Properties:
++- compatible        : Should be "altr,a10sr-gpio"
++- gpio-controller   : Marks the device node as a GPIO Controller.
++- #gpio-cells       : Should be two.  The first cell is the pin number and
++                      the second cell is used to specify flags.
++                      See ../gpio/gpio.txt for more information.
++
++Example:
++
++        resource-manager@0 {
++		compatible = "altr,a10sr";
++		reg = <0>;
++		spi-max-frequency = <100000>;
++		interrupt-parent = <&portb>;
++		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
++		interrupt-controller;
++		#interrupt-cells = <2>;
++
++		a10sr_gpio: gpio-controller {
++			compatible = "altr,a10sr-gpio";
++			gpio-controller;
++			#gpio-cells = <2>;
++		};
++	};
diff --git a/patches.socfpga/0073-ARM-dts-Add-EMAC-AXI-settings-for-Arria10.patch b/patches.socfpga/0073-ARM-dts-Add-EMAC-AXI-settings-for-Arria10.patch
new file mode 100644
index 0000000..a721ede
--- /dev/null
+++ b/patches.socfpga/0073-ARM-dts-Add-EMAC-AXI-settings-for-Arria10.patch
@@ -0,0 +1,53 @@
+From 0484444cbff352dc6c1882ed5a6f9ac502875ad7 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Thu, 2 Feb 2017 16:05:21 -0600
+Subject: [PATCH 073/103] ARM: dts: Add EMAC AXI settings for Arria10
+
+Add the device tree entries needed to support the EMAC AXI
+bus settings on the Arria10 SoCFPGA chip.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10.dtsi |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -408,6 +408,12 @@
+ 				};
+ 		};
+ 
++		socfpga_axi_setup: stmmac-axi-config {
++			snps,wr_osr_lmt = <0xf>;
++			snps,rd_osr_lmt = <0xf>;
++			snps,blen = <0 0 0 0 16 0 0>;
++		};
++
+ 		gmac0: ethernet@ff800000 {
+ 			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.72a", "snps,dwmac";
+ 			altr,sysmgr-syscon = <&sysmgr 0x44 0>;
+@@ -424,6 +430,7 @@
+ 			clock-names = "stmmaceth";
+ 			resets = <&rst EMAC0_RESET>;
+ 			reset-names = "stmmaceth";
++			snps,axi-config = <&socfpga_axi_setup>;
+ 			status = "disabled";
+ 		};
+ 
+@@ -443,6 +450,7 @@
+ 			clock-names = "stmmaceth";
+ 			resets = <&rst EMAC1_RESET>;
+ 			reset-names = "stmmaceth";
++			snps,axi-config = <&socfpga_axi_setup>;
+ 			status = "disabled";
+ 		};
+ 
+@@ -460,6 +468,7 @@
+ 			rx-fifo-depth = <16384>;
+ 			clocks = <&l4_mp_clk>;
+ 			clock-names = "stmmaceth";
++			snps,axi-config = <&socfpga_axi_setup>;
+ 			status = "disabled";
+ 		};
+ 
diff --git a/patches.socfpga/0074-MAINTAINERS-EDAC-Update-email-for-Thor-Thayer.patch b/patches.socfpga/0074-MAINTAINERS-EDAC-Update-email-for-Thor-Thayer.patch
new file mode 100644
index 0000000..2a20ff5
--- /dev/null
+++ b/patches.socfpga/0074-MAINTAINERS-EDAC-Update-email-for-Thor-Thayer.patch
@@ -0,0 +1,36 @@
+From 46436c057d4b2210fe487f76a51fdfe7eb9c3d15 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Mon, 13 Feb 2017 13:30:41 -0600
+Subject: [PATCH 074/103] MAINTAINERS, EDAC: Update email for Thor Thayer
+
+My opensource.altera.com email will be going away soon. Switch to new
+email address (linux.intel.com).
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Link: http://lkml.kernel.org/r/1487014241-3771-1-git-send-email-thor.thayer@linux.intel.com
+Signed-off-by: Borislav Petkov <bp@suse.de>
+---
+ MAINTAINERS |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -628,7 +628,7 @@ S:	Maintained
+ F:	drivers/gpio/gpio-altera.c
+ 
+ ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
+-M:	Thor Thayer <tthayer@opensource.altera.com>
++M:	Thor Thayer <thor.thayer@linux.intel.com>
+ S:	Maintained
+ F:	drivers/gpio/gpio-altera-a10sr.c
+ F:	drivers/mfd/altera-a10sr.c
+@@ -1766,7 +1766,7 @@ S:	Maintained
+ F:	drivers/clk/socfpga/
+ 
+ ARM/SOCFPGA EDAC SUPPORT
+-M:	Thor Thayer <tthayer@opensource.altera.com>
++M:	Thor Thayer <thor.thayer@linux.intel.com>
+ S:	Maintained
+ F:	drivers/edac/altera_edac.
+ 
diff --git a/patches.socfpga/0075-gpio-altera-a10sr-Set-gpio_chip-parent-property.patch b/patches.socfpga/0075-gpio-altera-a10sr-Set-gpio_chip-parent-property.patch
new file mode 100644
index 0000000..22a0a2e
--- /dev/null
+++ b/patches.socfpga/0075-gpio-altera-a10sr-Set-gpio_chip-parent-property.patch
@@ -0,0 +1,25 @@
+From 53c9bf5edfe4359a3baa2e42da49dabcc25d789a Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Mon, 13 Feb 2017 13:49:58 -0600
+Subject: [PATCH 075/103] gpio: altera-a10sr: Set gpio_chip parent property
+
+Set the gpio_chip parent property since some recent functions
+such as devprop_gpiochip_set_names() can use it.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/gpio/gpio-altera-a10sr.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-altera-a10sr.c
++++ b/drivers/gpio/gpio-altera-a10sr.c
+@@ -96,7 +96,7 @@ static int altr_a10sr_gpio_probe(struct
+ 	gpio->regmap = a10sr->regmap;
+ 
+ 	gpio->gp = altr_a10sr_gc;
+-
++	gpio->gp.parent = pdev->dev.parent;
+ 	gpio->gp.of_node = pdev->dev.of_node;
+ 
+ 	ret = devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
diff --git a/patches.socfpga/0076-dt-bindings-reset-a10sr-Add-Arria10-SR-Reset-Control.patch b/patches.socfpga/0076-dt-bindings-reset-a10sr-Add-Arria10-SR-Reset-Control.patch
new file mode 100644
index 0000000..343c5d3
--- /dev/null
+++ b/patches.socfpga/0076-dt-bindings-reset-a10sr-Add-Arria10-SR-Reset-Control.patch
@@ -0,0 +1,64 @@
+From 472534014030a4dc7abfa55952e6fdcb60d12f55 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Wed, 22 Feb 2017 11:10:16 -0600
+Subject: [PATCH 076/103] dt-bindings: reset: a10sr: Add Arria10 SR Reset
+ Controller offsets
+
+The Arria10 System Resource Chip reset controller handles the
+Arria10 peripheral PHYs. This patch adds the offsets for
+these PHYs.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ MAINTAINERS                                    |    1 
+ include/dt-bindings/reset/altr,rst-mgr-a10sr.h |   33 +++++++++++++++++++++++++
+ 2 files changed, 34 insertions(+)
+ create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10sr.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -633,6 +633,7 @@ S:	Maintained
+ F:	drivers/gpio/gpio-altera-a10sr.c
+ F:	drivers/mfd/altera-a10sr.c
+ F:	include/linux/mfd/altera-a10sr.h
++F:	include/dt-bindings/reset/altr,rst-mgr-a10sr.h
+ 
+ ALTERA TRIPLE SPEED ETHERNET DRIVER
+ M:	Vince Bridgers <vbridger@opensource.altera.com>
+--- /dev/null
++++ b/include/dt-bindings/reset/altr,rst-mgr-a10sr.h
+@@ -0,0 +1,33 @@
++/*
++ *  Copyright Intel Corporation (C) 2017. All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Reset binding definitions for Altera Arria10 MAX5 System Resource Chip
++ *
++ * Adapted from altr,rst-mgr-a10.h
++ */
++
++#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H
++#define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H
++
++/* Peripheral PHY resets */
++#define A10SR_RESET_ENET_HPS	0
++#define A10SR_RESET_PCIE	1
++#define A10SR_RESET_FILE	2
++#define A10SR_RESET_BQSPI	3
++#define A10SR_RESET_USB		4
++
++#define A10SR_RESET_NUM		5
++
++#endif
diff --git a/patches.socfpga/0077-reset-Add-Altera-Arria10-SR-Reset-Controller.patch b/patches.socfpga/0077-reset-Add-Altera-Arria10-SR-Reset-Controller.patch
new file mode 100644
index 0000000..e845232
--- /dev/null
+++ b/patches.socfpga/0077-reset-Add-Altera-Arria10-SR-Reset-Controller.patch
@@ -0,0 +1,199 @@
+From 5d4c070628323b330cd36b4013d373ed0433a4eb Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Wed, 22 Feb 2017 11:10:17 -0600
+Subject: [PATCH 077/103] reset: Add Altera Arria10 SR Reset Controller
+
+This patch adds the reset controller functionality for
+Peripheral PHYs to the Arria10 System Resource Chip.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+
+Conflicts:
+
+	drivers/reset/Makefile
+---
+ MAINTAINERS                 |    1 
+ drivers/reset/Kconfig       |    7 ++
+ drivers/reset/Makefile      |    1 
+ drivers/reset/reset-a10sr.c |  138 ++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 147 insertions(+)
+ create mode 100644 drivers/reset/reset-a10sr.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -632,6 +632,7 @@ M:	Thor Thayer <thor.thayer@linux.intel.
+ S:	Maintained
+ F:	drivers/gpio/gpio-altera-a10sr.c
+ F:	drivers/mfd/altera-a10sr.c
++F:	drivers/reset/reset-a10sr.c
+ F:	include/linux/mfd/altera-a10sr.h
+ F:	include/dt-bindings/reset/altr,rst-mgr-a10sr.h
+ 
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -14,6 +14,13 @@ menuconfig RESET_CONTROLLER
+ 
+ if RESET_CONTROLLER
+ 
++config RESET_A10SR
++	tristate "Altera Arria10 System Resource Reset"
++	depends on MFD_ALTERA_A10SR
++	help
++	  This option enables support for the external reset functions for
++	  peripheral PHYs on the Altera Arria10 System Resource Chip.
++
+ config RESET_ATH79
+ 	bool "AR71xx Reset Driver" if COMPILE_TEST
+ 	default ATH79
+--- a/drivers/reset/Makefile
++++ b/drivers/reset/Makefile
+@@ -1,6 +1,7 @@
+ obj-y += core.o
+ obj-y += hisilicon/
+ obj-$(CONFIG_ARCH_STI) += sti/
++obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
+ obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
+ obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
+ obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
+--- /dev/null
++++ b/drivers/reset/reset-a10sr.c
+@@ -0,0 +1,138 @@
++/*
++ *  Copyright Intel Corporation (C) 2017. All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Reset driver for Altera Arria10 MAX5 System Resource Chip
++ *
++ * Adapted from reset-socfpga.c
++ */
++
++#include <linux/err.h>
++#include <linux/mfd/altera-a10sr.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/reset-controller.h>
++
++#include <dt-bindings/reset/altr,rst-mgr-a10sr.h>
++
++struct a10sr_reset {
++	struct reset_controller_dev     rcdev;
++	struct regmap *regmap;
++};
++
++static inline struct a10sr_reset *to_a10sr_rst(struct reset_controller_dev *rc)
++{
++	return container_of(rc, struct a10sr_reset, rcdev);
++}
++
++static inline int a10sr_reset_shift(unsigned long id)
++{
++	switch (id) {
++	case A10SR_RESET_ENET_HPS:
++		return 1;
++	case A10SR_RESET_PCIE:
++	case A10SR_RESET_FILE:
++	case A10SR_RESET_BQSPI:
++	case A10SR_RESET_USB:
++		return id + 11;
++	default:
++		return -EINVAL;
++	}
++}
++
++static int a10sr_reset_update(struct reset_controller_dev *rcdev,
++			      unsigned long id, bool assert)
++{
++	struct a10sr_reset *a10r = to_a10sr_rst(rcdev);
++	int offset = a10sr_reset_shift(id);
++	u8 mask = ALTR_A10SR_REG_BIT_MASK(offset);
++	int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset);
++
++	return regmap_update_bits(a10r->regmap, index, mask, assert ? 0 : mask);
++}
++
++static int a10sr_reset_assert(struct reset_controller_dev *rcdev,
++			      unsigned long id)
++{
++	return a10sr_reset_update(rcdev, id, true);
++}
++
++static int a10sr_reset_deassert(struct reset_controller_dev *rcdev,
++				unsigned long id)
++{
++	return a10sr_reset_update(rcdev, id, false);
++}
++
++static int a10sr_reset_status(struct reset_controller_dev *rcdev,
++			      unsigned long id)
++{
++	int ret;
++	struct a10sr_reset *a10r = to_a10sr_rst(rcdev);
++	int offset = a10sr_reset_shift(id);
++	u8 mask = ALTR_A10SR_REG_BIT_MASK(offset);
++	int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset);
++	unsigned int value;
++
++	ret = regmap_read(a10r->regmap, index, &value);
++	if (ret < 0)
++		return ret;
++
++	return !!(value & mask);
++}
++
++static const struct reset_control_ops a10sr_reset_ops = {
++	.assert		= a10sr_reset_assert,
++	.deassert	= a10sr_reset_deassert,
++	.status		= a10sr_reset_status,
++};
++
++static int a10sr_reset_probe(struct platform_device *pdev)
++{
++	struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent);
++	struct a10sr_reset *a10r;
++
++	a10r = devm_kzalloc(&pdev->dev, sizeof(struct a10sr_reset),
++			    GFP_KERNEL);
++	if (!a10r)
++		return -ENOMEM;
++
++	a10r->rcdev.owner = THIS_MODULE;
++	a10r->rcdev.nr_resets = A10SR_RESET_NUM;
++	a10r->rcdev.ops = &a10sr_reset_ops;
++	a10r->rcdev.of_node = pdev->dev.of_node;
++	a10r->regmap = a10sr->regmap;
++
++	platform_set_drvdata(pdev, a10r);
++
++	return devm_reset_controller_register(&pdev->dev, &a10r->rcdev);
++}
++
++static const struct of_device_id a10sr_reset_of_match[] = {
++	{ .compatible = "altr,a10sr-reset" },
++	{ },
++};
++MODULE_DEVICE_TABLE(of, a10sr_reset_of_match);
++
++static struct platform_driver a10sr_reset_driver = {
++	.probe	= a10sr_reset_probe,
++	.driver = {
++		.name		= "altr_a10sr_reset",
++	},
++};
++module_platform_driver(a10sr_reset_driver);
++
++MODULE_AUTHOR("Thor Thayer <thor.thayer@linux.intel.com>");
++MODULE_DESCRIPTION("Altera Arria10 System Resource Reset Controller Driver");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0078-ARM-dts-socfpga-Add-Devkit-A10-SR-Reset-Controller.patch b/patches.socfpga/0078-ARM-dts-socfpga-Add-Devkit-A10-SR-Reset-Controller.patch
new file mode 100644
index 0000000..bbbafba
--- /dev/null
+++ b/patches.socfpga/0078-ARM-dts-socfpga-Add-Devkit-A10-SR-Reset-Controller.patch
@@ -0,0 +1,29 @@
+From c948058fb2a34b35c935b947f4c4f07c3d3e7d24 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Thu, 16 Mar 2017 07:57:16 -0500
+Subject: [PATCH 078/103] ARM: dts: socfpga: Add Devkit A10-SR Reset Controller
+
+Add the Altera Arria10 System Resource Reset Controller to the MFD
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+v2  change commit header to ARM: dts: socfpga.
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -121,6 +121,11 @@
+ 			gpio-controller;
+ 			#gpio-cells = <2>;
+ 		};
++
++		a10sr_rst: reset-controller {
++			compatible = "altr,a10sr-reset";
++			#reset-cells = <1>;
++		};
+ 	};
+ };
+ 
diff --git a/patches.socfpga/0079-EDAC-altera-Fix-peripheral-warnings-for-Cyclone5.patch b/patches.socfpga/0079-EDAC-altera-Fix-peripheral-warnings-for-Cyclone5.patch
new file mode 100644
index 0000000..7f6e80c
--- /dev/null
+++ b/patches.socfpga/0079-EDAC-altera-Fix-peripheral-warnings-for-Cyclone5.patch
@@ -0,0 +1,61 @@
+From 5a77f16dd47f75102d12d86a6ad7bb230b256077 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Wed, 5 Apr 2017 13:01:02 -0500
+Subject: [PATCH 079/103] EDAC, altera: Fix peripheral warnings for Cyclone5
+
+The peripherals' RAS functionality only exist on the Arria10 SoCFPGA.
+The Cyclone5 initialization generates EDAC warnings when the peripherals
+aren't found in the device tree. Fix by checking for Arria10 in the init
+functions.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Link: http://lkml.kernel.org/r/1491415262-5018-1-git-send-email-thor.thayer@linux.intel.com
+Signed-off-by: Borislav Petkov <bp@suse.de>
+---
+ drivers/edac/altera_edac.c |   22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/edac/altera_edac.c
++++ b/drivers/edac/altera_edac.c
+@@ -1024,13 +1024,23 @@ out:
+ 	return ret;
+ }
+ 
++static int socfpga_is_a10(void)
++{
++	return of_machine_is_compatible("altr,socfpga-arria10");
++}
++
+ static int validate_parent_available(struct device_node *np);
+ static const struct of_device_id altr_edac_a10_device_of_match[];
+ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
+ {
+ 	int irq;
+-	struct device_node *child, *np = of_find_compatible_node(NULL, NULL,
+-					"altr,socfpga-a10-ecc-manager");
++	struct device_node *child, *np;
++
++	if (!socfpga_is_a10())
++		return -ENODEV;
++
++	np = of_find_compatible_node(NULL, NULL,
++				     "altr,socfpga-a10-ecc-manager");
+ 	if (!np) {
+ 		edac_printk(KERN_ERR, EDAC_DEVICE, "ECC Manager not found\n");
+ 		return -ENODEV;
+@@ -1546,8 +1556,12 @@ static const struct edac_device_prv_data
+ static int __init socfpga_init_sdmmc_ecc(void)
+ {
+ 	int rc = -ENODEV;
+-	struct device_node *child = of_find_compatible_node(NULL, NULL,
+-						"altr,socfpga-sdmmc-ecc");
++	struct device_node *child;
++
++	if (!socfpga_is_a10())
++		return -ENODEV;
++
++	child = of_find_compatible_node(NULL, NULL, "altr,socfpga-sdmmc-ecc");
+ 	if (!child) {
+ 		edac_printk(KERN_WARNING, EDAC_DEVICE, "SDMMC node not found\n");
+ 		return -ENODEV;
diff --git a/patches.socfpga/0080-mfd-altr_a10sr-Add-Arria10-DevKit-Reset-Controller.patch b/patches.socfpga/0080-mfd-altr_a10sr-Add-Arria10-DevKit-Reset-Controller.patch
new file mode 100644
index 0000000..8da8b04
--- /dev/null
+++ b/patches.socfpga/0080-mfd-altr_a10sr-Add-Arria10-DevKit-Reset-Controller.patch
@@ -0,0 +1,27 @@
+From 3c7b3fce2cf21f284518116f77bff9d6c7f4b327 Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Wed, 22 Feb 2017 11:10:18 -0600
+Subject: [PATCH 080/103] mfd: altr_a10sr: Add Arria10 DevKit Reset Controller
+
+Add Peripheral PHY Reset Controller to the Arria10
+Development Kit System Resource Chip's MFD.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+---
+ drivers/mfd/altera-a10sr.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mfd/altera-a10sr.c
++++ b/drivers/mfd/altera-a10sr.c
+@@ -33,6 +33,10 @@ static const struct mfd_cell altr_a10sr_
+ 		.name = "altr_a10sr_gpio",
+ 		.of_compatible = "altr,a10sr-gpio",
+ 	},
++	{
++		.name = "altr_a10sr_reset",
++		.of_compatible = "altr,a10sr-reset",
++	},
+ };
+ 
+ static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
diff --git a/patches.socfpga/0081-dt-bindings-mfd-Add-Altera-Arria10-SR-Reset-Controll.patch b/patches.socfpga/0081-dt-bindings-mfd-Add-Altera-Arria10-SR-Reset-Controll.patch
new file mode 100644
index 0000000..2541f56
--- /dev/null
+++ b/patches.socfpga/0081-dt-bindings-mfd-Add-Altera-Arria10-SR-Reset-Controll.patch
@@ -0,0 +1,48 @@
+From f12e2e73318394511538aa49c150a864d4f1a91a Mon Sep 17 00:00:00 2001
+From: Thor Thayer <thor.thayer@linux.intel.com>
+Date: Wed, 22 Feb 2017 11:10:15 -0600
+Subject: [PATCH 081/103] dt-bindings: mfd: Add Altera Arria10 SR Reset
+ Controller bindings
+
+This patch adds documentation for the Altera A10-SR Reset
+Controller DT bindings.
+
+Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+---
+ Documentation/devicetree/bindings/mfd/altera-a10sr.txt |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
++++ b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
+@@ -18,6 +18,7 @@ The A10SR consists of these sub-devices:
+ Device                   Description
+ ------                   ----------
+ a10sr_gpio               GPIO Controller
++a10sr_rst                Reset Controller
+ 
+ Arria10 GPIO
+ Required Properties:
+@@ -27,6 +28,11 @@ Required Properties:
+                       the second cell is used to specify flags.
+                       See ../gpio/gpio.txt for more information.
+ 
++Arria10 Peripheral PHY Reset
++Required Properties:
++- compatible        : Should be "altr,a10sr-reset"
++- #reset-cells      : Should be one.
++
+ Example:
+ 
+         resource-manager@0 {
+@@ -43,4 +49,9 @@ Example:
+ 			gpio-controller;
+ 			#gpio-cells = <2>;
+ 		};
++
++		a10sr_rst: reset-controller {
++			compatible = "altr,a10sr-reset";
++			#reset-cells = <1>;
++		};
+ 	};
diff --git a/patches.socfpga/0082-ARM-socfpga-defconfig-enable-qspi.patch b/patches.socfpga/0082-ARM-socfpga-defconfig-enable-qspi.patch
new file mode 100644
index 0000000..406f407
--- /dev/null
+++ b/patches.socfpga/0082-ARM-socfpga-defconfig-enable-qspi.patch
@@ -0,0 +1,23 @@
+From fa54ece4ad77749237745ea23796f8a2a368cbfc Mon Sep 17 00:00:00 2001
+From: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Date: Tue, 18 Oct 2016 07:43:04 +0000
+Subject: [PATCH 082/103] ARM: socfpga: defconfig: enable qspi
+
+Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/configs/socfpga_defconfig |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -51,6 +51,9 @@ CONFIG_CAN_DEBUG_DEVICES=y
+ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_SPI_CADENCE_QUADSPI=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=2
+ CONFIG_BLK_DEV_RAM_SIZE=8192
diff --git a/patches.socfpga/0083-ARM-socfpga-updates-for-socfpga_defconfig.patch b/patches.socfpga/0083-ARM-socfpga-updates-for-socfpga_defconfig.patch
new file mode 100644
index 0000000..3fc4ef2
--- /dev/null
+++ b/patches.socfpga/0083-ARM-socfpga-updates-for-socfpga_defconfig.patch
@@ -0,0 +1,58 @@
+From b7e82058125354c24224ef475ffed4a8f30d025c Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@opensource.altera.com>
+Date: Wed, 2 Nov 2016 16:22:36 -0500
+Subject: [PATCH 083/103] ARM: socfpga: updates for socfpga_defconfig
+
+This patch enables the following in the
+socfpga_defconfig:
+
++CONFIG_OF_OVERLAY=y
+  Enable support for Device Tree Overlays
+
++CONFIG_FPGA_REGION=y
+  Enable device tree overlay support for FPGA
+  programming
+
++CONFIG_FPGA_MGR_SOCFPGA_A10=y
+  Enable partial reconfiguration for Altera
+  Arria 10 FPGA
+
++CONFIG_FPGA_BRIDGE=y
+  Enable the FPGA Bridges framework
+
++CONFIG_SOCFPGA_FPGA_BRIDGE=y
+  Enable support for SoCFPGA hardware
+  bridges
+
++CONFIG_ALTERA_FREEZE_BRIDGE=y
+  Enable support for the Altera Soft IP
+  Freeze bridges
+
+Signed-off-by: Alan Tull <atull@opensource.altera.com>
+---
+ arch/arm/configs/socfpga_defconfig |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -54,6 +54,7 @@ CONFIG_DEVTMPFS_MOUNT=y
+ CONFIG_MTD=y
+ CONFIG_MTD_SPI_NOR=y
+ CONFIG_SPI_CADENCE_QUADSPI=y
++CONFIG_OF_OVERLAY=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=2
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+@@ -105,7 +106,12 @@ CONFIG_DMADEVICES=y
+ CONFIG_PL330_DMA=y
+ CONFIG_DMATEST=m
+ CONFIG_FPGA=y
++CONFIG_FPGA_REGION=y
+ CONFIG_FPGA_MGR_SOCFPGA=y
++CONFIG_FPGA_MGR_SOCFPGA_A10=y
++CONFIG_FPGA_BRIDGE=y
++CONFIG_SOCFPGA_FPGA_BRIDGE=y
++CONFIG_ALTERA_FREEZE_BRIDGE=y
+ CONFIG_EXT2_FS=y
+ CONFIG_EXT2_FS_XATTR=y
+ CONFIG_EXT2_FS_POSIX_ACL=y
diff --git a/patches.socfpga/0084-ARM-socfpga_defconfig-update-defconfig-for-SoCFPGA.patch b/patches.socfpga/0084-ARM-socfpga_defconfig-update-defconfig-for-SoCFPGA.patch
new file mode 100644
index 0000000..8930358
--- /dev/null
+++ b/patches.socfpga/0084-ARM-socfpga_defconfig-update-defconfig-for-SoCFPGA.patch
@@ -0,0 +1,112 @@
+From b0068141c565214d7682a9fa95c1673648ab159d Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Wed, 14 Dec 2016 04:25:54 -0600
+Subject: [PATCH 084/103] ARM: socfpga_defconfig: update defconfig for SoCFPGA
+
+MARVELL_PHY - support for the Marvell PHY that is on most of the devkits
+EEPROM_AT24 - support for I2C EEPROMs on the devkits
+GPIO_ALTERA - support for Altera's GPIO driver
+NAND - support for the Denali NAND controller along with MTD subsystem
+SPI_DESIGNWARE - support for SPI that is on SoCFPGA
+SPI_DW_MMIO - support for the memory-mapped io interface for the DW SPI core
+OF_CONFIGFS - SoCFPGA makes use of DT overlays using configfs, enable it
+GPIO_ALTERA_A10SR - support for the newly added Altera HWMON driver
+LEDS - support for the GPIO LEDs on the SoCFPGA devkits
+RTC - support for the DS1307 RTC
+JFFS2_FS - support for the JFFS2 filesystem
+NFS_V4 - supports for v4 NFS
+FUNCTION_TRACER - supports debug function tracing
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/configs/socfpga_defconfig |   28 ++++++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -52,14 +52,20 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
+ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
+ CONFIG_MTD=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_M25P80=y
++CONFIG_MTD_NAND=y
++CONFIG_MTD_NAND_DENALI_DT=y
+ CONFIG_MTD_SPI_NOR=y
+ CONFIG_SPI_CADENCE_QUADSPI=y
+ CONFIG_OF_OVERLAY=y
++CONFIG_OF_CONFIGFS=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_COUNT=2
+ CONFIG_BLK_DEV_RAM_SIZE=8192
+ CONFIG_BLK_DEV_NVME=m
+ CONFIG_SRAM=y
++CONFIG_EEPROM_AT24=y
+ CONFIG_SCSI=y
+ # CONFIG_SCSI_PROC_FS is not set
+ CONFIG_BLK_DEV_SD=y
+@@ -69,6 +75,7 @@ CONFIG_E1000E=m
+ CONFIG_IGB=m
+ CONFIG_IXGBE=m
+ CONFIG_STMMAC_ETH=y
++CONFIG_MARVELL_PHY=y
+ CONFIG_MICREL_PHY=y
+ CONFIG_INPUT_EVDEV=y
+ CONFIG_INPUT_TOUCHSCREEN=y
+@@ -84,14 +91,22 @@ CONFIG_SERIAL_8250_DW=y
+ CONFIG_I2C=y
+ CONFIG_I2C_CHARDEV=y
+ CONFIG_I2C_DESIGNWARE_PLATFORM=y
++CONFIG_SPI=y
++CONFIG_SPI_DESIGNWARE=y
++CONFIG_SPI_DW_MMIO=y
++CONFIG_SPI_SPIDEV=y
+ CONFIG_GPIOLIB=y
+ CONFIG_GPIO_SYSFS=y
++CONFIG_GPIO_ALTERA=y
+ CONFIG_GPIO_DWAPB=y
++CONFIG_GPIO_ALTERA_A10SR=y
++CONFIG_SENSORS_MAX1619=y
+ CONFIG_PMBUS=y
+ CONFIG_SENSORS_LTC2978=y
+ CONFIG_SENSORS_LTC2978_REGULATOR=y
+ CONFIG_WATCHDOG=y
+ CONFIG_DW_WATCHDOG=y
++CONFIG_MFD_ALTERA_A10SR=y
+ CONFIG_MFD_STMPE=y
+ CONFIG_REGULATOR=y
+ CONFIG_REGULATOR_FIXED_VOLTAGE=y
+@@ -102,6 +117,14 @@ CONFIG_NOP_USB_XCEIV=y
+ CONFIG_USB_GADGET=y
+ CONFIG_MMC=y
+ CONFIG_MMC_DW=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_TRIGGERS=y
++CONFIG_LEDS_TRIGGER_TIMER=y
++CONFIG_LEDS_TRIGGER_CPU=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_DRV_DS1307=y
+ CONFIG_DMADEVICES=y
+ CONFIG_PL330_DMA=y
+ CONFIG_DMATEST=m
+@@ -121,9 +144,10 @@ CONFIG_VFAT_FS=y
+ CONFIG_NTFS_FS=y
+ CONFIG_NTFS_RW=y
+ CONFIG_TMPFS=y
+-CONFIG_CONFIGFS_FS=y
++CONFIG_JFFS2_FS=y
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3_ACL=y
+@@ -135,5 +159,5 @@ CONFIG_DEBUG_INFO=y
+ CONFIG_MAGIC_SYSRQ=y
+ CONFIG_DETECT_HUNG_TASK=y
+ # CONFIG_SCHED_DEBUG is not set
+-CONFIG_ENABLE_DEFAULT_TRACERS=y
++CONFIG_FUNCTION_TRACER=y
+ CONFIG_DEBUG_USER=y
diff --git a/patches.socfpga/0085-ARM-socfpga-updates-for-socfpga_defconfig.patch b/patches.socfpga/0085-ARM-socfpga-updates-for-socfpga_defconfig.patch
new file mode 100644
index 0000000..022150a
--- /dev/null
+++ b/patches.socfpga/0085-ARM-socfpga-updates-for-socfpga_defconfig.patch
@@ -0,0 +1,23 @@
+From 6dd0a8c7a2e167fd63ef04f038b0e1cbf6e33188 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <ho.jia.jie@intel.com>
+Date: Thu, 16 Mar 2017 08:05:46 -0500
+Subject: [PATCH 085/103] ARM: socfpga: updates for socfpga_defconfig
+
+This patch enables Altera TSE support in socfpga_defconfig
+
+Signed-off-by: Jia Jie Ho <ho.jia.jie@intel.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/configs/socfpga_defconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/configs/socfpga_defconfig
++++ b/arch/arm/configs/socfpga_defconfig
+@@ -71,6 +71,7 @@ CONFIG_SCSI=y
+ CONFIG_BLK_DEV_SD=y
+ # CONFIG_SCSI_LOWLEVEL is not set
+ CONFIG_NETDEVICES=y
++CONFIG_ALTERA_TSE=m
+ CONFIG_E1000E=m
+ CONFIG_IGB=m
+ CONFIG_IXGBE=m
diff --git a/patches.socfpga/0086-ARM-dts-socfpga-Add-new-MCVEVK-manufacturer-compat.patch b/patches.socfpga/0086-ARM-dts-socfpga-Add-new-MCVEVK-manufacturer-compat.patch
new file mode 100644
index 0000000..f5c7e4e
--- /dev/null
+++ b/patches.socfpga/0086-ARM-dts-socfpga-Add-new-MCVEVK-manufacturer-compat.patch
@@ -0,0 +1,37 @@
+From 3bf20e590278aeae0493d36dead11207a5a3b6d7 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Mon, 19 Sep 2016 21:40:43 +0000
+Subject: [PATCH 086/103] ARM: dts: socfpga: Add new MCVEVK manufacturer compat
+
+The board is now manufactured by Aries Embedded GmbH, update compat string.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Dinh Nguyen <dinguyen@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi   |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
++++ b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
+@@ -18,7 +18,7 @@
+ #include "socfpga_cyclone5.dtsi"
+ 
+ / {
+-	model = "DENX MCV";
++	model = "Aries/DENX MCV";
+ 	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	memory {
+--- a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
+@@ -18,7 +18,7 @@
+ #include "socfpga_cyclone5_mcv.dtsi"
+ 
+ / {
+-	model = "DENX MCV EVK";
++	model = "Aries/DENX MCV EVK";
+ 	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	aliases {
diff --git a/patches.socfpga/0087-ARM-dts-socfpga-Add-Macnica-sodia-board.patch b/patches.socfpga/0087-ARM-dts-socfpga-Add-Macnica-sodia-board.patch
new file mode 100644
index 0000000..f004121
--- /dev/null
+++ b/patches.socfpga/0087-ARM-dts-socfpga-Add-Macnica-sodia-board.patch
@@ -0,0 +1,162 @@
+From 3cd00779ac5363f30cccb685ae6ca56990d363b1 Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Date: Sat, 24 Sep 2016 23:59:45 +0000
+Subject: [PATCH 087/103] ARM: dts: socfpga: Add Macnica sodia board
+
+Add support for board based on the Altera Cyclone V SoC.
+This board has the following functions:
+    - 1 GiB of DRAM
+    - 1 Gigabit ethernet
+    - 1 SD card slot
+    - 1 USB gadget port
+    - QSPI NOR Flash
+    - I2C EEPROMs and I2C RTC
+    - DVI output
+    - Audio port
+
+This commit supports without QSPI, DVI and Audio.
+
+Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/Makefile                   |    1 
+ arch/arm/boot/dts/socfpga_cyclone5_sodia.dts |  123 +++++++++++++++++++++++++++
+ 2 files changed, 124 insertions(+)
+ create mode 100644 arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -700,6 +700,7 @@ dtb-$(CONFIG_ARCH_SOCFPGA) += \
+ 	socfpga_cyclone5_de0_sockit.dtb \
+ 	socfpga_cyclone5_sockit.dtb \
+ 	socfpga_cyclone5_socrates.dtb \
++	socfpga_cyclone5_sodia.dtb \
+ 	socfpga_cyclone5_vining_fpga.dtb \
+ 	socfpga_vt.dtb
+ dtb-$(CONFIG_ARCH_SPEAR13XX) += \
+--- /dev/null
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+@@ -0,0 +1,123 @@
++/*
++ *  Copyright (C) 2016 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "socfpga_cyclone5.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++
++/ {
++	model = "Altera SOCFPGA Cyclone V SoC Macnica Sodia board";
++	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++
++	chosen {
++		bootargs = "earlyprintk";
++		stdout-path = "serial0:115200n8";
++	};
++
++	memory {
++		name = "memory";
++		device_type = "memory";
++		reg = <0x0 0x40000000>;
++	};
++
++	aliases {
++		ethernet0 = &gmac1;
++	};
++
++	regulator_3_3v: 3-3-v-regulator {
++		compatible = "regulator-fixed";
++		regulator-name = "3.3V";
++		regulator-min-microvolt = <3300000>;
++		regulator-max-microvolt = <3300000>;
++	};
++
++	leds: gpio-leds {
++		compatible = "gpio-leds";
++
++		hps_led0 {
++			label = "hps:green:led0";
++			gpios = <&portb 12 GPIO_ACTIVE_LOW>;
++		};
++
++		hps_led1 {
++			label = "hps:green:led1";
++			gpios = <&portb 13 GPIO_ACTIVE_LOW>;
++		};
++
++		hps_led2 {
++			label = "hps:green:led2";
++			gpios = <&portb 14 GPIO_ACTIVE_LOW>;
++		};
++
++		hps_led3 {
++			label = "hps:green:led3";
++			gpios = <&portb 15 GPIO_ACTIVE_LOW>;
++		};
++	};
++};
++
++&gmac1 {
++	status = "okay";
++	phy-mode = "rgmii";
++	phy = <&phy0>;
++
++	mdio0 {
++		#address-cells = <1>;
++		#size-cells = <0>;
++		phy0: ethernet-phy@0 {
++			reg = <0>;
++			rxd0-skew-ps = <0>;
++			rxd1-skew-ps = <0>;
++			rxd2-skew-ps = <0>;
++			rxd3-skew-ps = <0>;
++			rxdv-skew-ps = <0>;
++			rxc-skew-ps = <3000>;
++			txen-skew-ps = <0>;
++			txc-skew-ps = <3000>;
++		};
++	};
++};
++
++&gpio1 {
++	status = "okay";
++};
++
++&i2c0 {
++	status = "okay";
++
++	eeprom@51 {
++		compatible = "atmel,24c32";
++		reg = <0x51>;
++		pagesize = <32>;
++	};
++
++	rtc@68 {
++		compatible = "dallas,ds1339";
++		reg = <0x68>;
++	};
++};
++
++&mmc0 {
++	cd-gpios = <&portb 18 0>;
++	vmmc-supply = <&regulator_3_3v>;
++	vqmmc-supply = <&regulator_3_3v>;
++	status = "okay";
++};
++
++&usb1 {
++	status = "okay";
++};
diff --git a/patches.socfpga/0088-ARM-dts-socfpga-add-specific-compatible-strings-for-.patch b/patches.socfpga/0088-ARM-dts-socfpga-add-specific-compatible-strings-for-.patch
new file mode 100644
index 0000000..4a87d3b
--- /dev/null
+++ b/patches.socfpga/0088-ARM-dts-socfpga-add-specific-compatible-strings-for-.patch
@@ -0,0 +1,89 @@
+From d5b1b034ae10a0fcbd24a3af638558c93e17ca4a Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@kernel.org>
+Date: Tue, 1 Nov 2016 09:57:06 -0500
+Subject: [PATCH 088/103] ARM: dts: socfpga: add specific compatible strings
+ for boards
+
+Add a more specific board compatible entry for all of the SOCFPGA
+Cyclone 5 based boards.
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+v3: Be a bit more specific with the c5 dk and sockit, use
+    "altr,socfpga-cyclone5-socdk" and "terasic,socfpga-cyclone5-sockit"
+v2: remove extra space and add a comma between compatible entries
+---
+ arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts  |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts      |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts       |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_sockit.dts      |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_sodia.dts       |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts |    2 +-
+ 6 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
+@@ -18,7 +18,7 @@
+ 
+ / {
+ 	model = "Terasic DE-0(Atlas)";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "terasic,de0-atlas", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	chosen {
+ 		bootargs = "earlyprintk";
+--- a/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_mcvevk.dts
+@@ -19,7 +19,7 @@
+ 
+ / {
+ 	model = "Aries/DENX MCV EVK";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "denx,mcvevk", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	aliases {
+ 		ethernet0 = &gmac0;
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -19,7 +19,7 @@
+ 
+ / {
+ 	model = "Altera SOCFPGA Cyclone V SoC Development Kit";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "altr,socfpga-cyclone5-socdk", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	chosen {
+ 		bootargs = "earlyprintk";
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+@@ -19,7 +19,7 @@
+ 
+ / {
+ 	model = "Terasic SoCkit";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "terasic,socfpga-cyclone5-sockit", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	chosen {
+ 		bootargs = "earlyprintk";
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+@@ -21,7 +21,7 @@
+ 
+ / {
+ 	model = "Altera SOCFPGA Cyclone V SoC Macnica Sodia board";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "macnica,sodia", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	chosen {
+ 		bootargs = "earlyprintk";
+--- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
+@@ -51,7 +51,7 @@
+ 
+ / {
+ 	model = "samtec VIN|ING FPGA";
+-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
++	compatible = "samtec,vining", "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+ 	chosen {
+ 		bootargs = "console=ttyS0,115200";
diff --git a/patches.socfpga/0089-ARM-dts-socfpga-Add-unit-name-to-memory-nodes.patch b/patches.socfpga/0089-ARM-dts-socfpga-Add-unit-name-to-memory-nodes.patch
new file mode 100644
index 0000000..c89c152
--- /dev/null
+++ b/patches.socfpga/0089-ARM-dts-socfpga-Add-unit-name-to-memory-nodes.patch
@@ -0,0 +1,138 @@
+From 053c4886aa63bf59091841b2a7635ce14921fb37 Mon Sep 17 00:00:00 2001
+From: Florian Vaussard <florian.vaussard@gmail.com>
+Date: Mon, 27 Feb 2017 10:38:39 -0600
+Subject: [PATCH 089/103] ARM: dts: socfpga: Add unit name to memory nodes
+
+Memory nodes in Arria5, Cyclone5 and Arria10 do not have a unit name.
+This will trigger several warnings like this one (when compiled with
+W=1):
+
+Node /memory has a reg or ranges property, but no unit name
+
+Add the corresponding unit name to each node.
+
+Signed-off-by: Florian Vaussard <florian.vaussard@heig-vd.ch>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_arria10_socdk.dtsi       |    2 +-
+ arch/arm/boot/dts/socfpga_arria5_socdk.dts         |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts  |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi        |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_socdk.dts       |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_sockit.dts      |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_socrates.dts    |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_sodia.dts       |    2 +-
+ arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts |    2 +-
+ arch/arm/boot/dts/socfpga_vt.dts                   |    2 +-
+ 10 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk.dtsi
+@@ -30,7 +30,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+@@ -26,7 +26,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
+@@ -25,7 +25,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
++++ b/arch/arm/boot/dts/socfpga_cyclone5_mcv.dtsi
+@@ -21,7 +21,7 @@
+ 	model = "Aries/DENX MCV";
+ 	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1 GiB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+@@ -26,7 +26,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+@@ -26,7 +26,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts
+@@ -25,7 +25,7 @@
+ 		bootargs = "console=ttyS0,115200";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+@@ -28,7 +28,7 @@
+ 		stdout-path = "serial0:115200n8";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>;
+--- a/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
+@@ -57,7 +57,7 @@
+ 		bootargs = "console=ttyS0,115200";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1GB */
+--- a/arch/arm/boot/dts/socfpga_vt.dts
++++ b/arch/arm/boot/dts/socfpga_vt.dts
+@@ -26,7 +26,7 @@
+ 		bootargs = "console=ttyS0,57600";
+ 	};
+ 
+-	memory {
++	memory@0 {
+ 		name = "memory";
+ 		device_type = "memory";
+ 		reg = <0x0 0x40000000>; /* 1 GB */
diff --git a/patches.socfpga/0090-ARM-dts-socfpga-sodia-enable-qspi.patch b/patches.socfpga/0090-ARM-dts-socfpga-sodia-enable-qspi.patch
new file mode 100644
index 0000000..9d3cdf3
--- /dev/null
+++ b/patches.socfpga/0090-ARM-dts-socfpga-sodia-enable-qspi.patch
@@ -0,0 +1,41 @@
+From d59a294e24214c1d45314e38eac346256973f389 Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Date: Fri, 10 Feb 2017 11:21:33 -0600
+Subject: [PATCH 090/103] ARM: dts: socfpga: sodia: enable qspi
+
+Enable the qspi controller on sodia board and add the flash chip
+(n25q512a).
+
+Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+ arch/arm/boot/dts/socfpga_cyclone5_sodia.dts |   21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
++++ b/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts
+@@ -121,3 +121,24 @@
+ &usb1 {
+ 	status = "okay";
+ };
++
++&qspi {
++        status = "okay";
++
++        flash0: n25q512a@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "n25q512a";
++		reg = <0>;
++		spi-max-frequency = <100000000>;
++
++		m25p,fast-read;
++		cdns,page-size = <256>;
++		cdns,block-size = <16>;
++		cdns,read-delay = <4>;
++		cdns,tshsl-ns = <50>;
++		cdns,tsd2d-ns = <50>;
++		cdns,tchsh-ns = <4>;
++		cdns,tslch-ns = <4>;
++	};
++};
diff --git a/patches.socfpga/0091-ARM-dts-socfpga-add-qspi-node.patch b/patches.socfpga/0091-ARM-dts-socfpga-add-qspi-node.patch
new file mode 100644
index 0000000..f07477c
--- /dev/null
+++ b/patches.socfpga/0091-ARM-dts-socfpga-add-qspi-node.patch
@@ -0,0 +1,36 @@
+From 5420a09156d6bc2cb61aad87b1277c6c9e3ba788 Mon Sep 17 00:00:00 2001
+From: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Date: Tue, 18 Oct 2016 07:43:02 +0000
+Subject: [PATCH 091/103] ARM: dts: socfpga: add qspi node
+
+Add the qspi node to the socfpga dtsi file.
+
+Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
+---
+ arch/arm/boot/dts/socfpga.dtsi |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm/boot/dts/socfpga.dtsi
++++ b/arch/arm/boot/dts/socfpga.dtsi
+@@ -733,6 +733,20 @@
+ 			reg = <0xffff0000 0x10000>;
+ 		};
+ 
++		qspi: spi@ff705000 {
++			compatible = "cdns,qspi-nor";
++                        #address-cells = <1>;
++			#size-cells = <0>;
++			reg = <0xff705000 0x1000>,
++			      <0xffa00000 0x1000>;
++			interrupts = <0 151 4>;
++			cdns,fifo-depth = <128>;
++			cdns,fifo-width = <4>;
++			cdns,trigger-address = <0x00000000>;
++			clocks = <&qspi_clk>;
++			status = "disabled";
++		};
++
+ 		rst: rstmgr@ffd05000 {
+ 			#reset-cells = <1>;
+ 			compatible = "altr,rst-mgr";
diff --git a/patches.socfpga/0092-fpga-pr-ip-Core-driver-support-for-Altera-Partial-Re.patch b/patches.socfpga/0092-fpga-pr-ip-Core-driver-support-for-Altera-Partial-Re.patch
new file mode 100644
index 0000000..6d6a335
--- /dev/null
+++ b/patches.socfpga/0092-fpga-pr-ip-Core-driver-support-for-Altera-Partial-Re.patch
@@ -0,0 +1,302 @@
+From dee4f9e2e4dd5ee90ad2910be5546ff32f42aa55 Mon Sep 17 00:00:00 2001
+From: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Date: Thu, 23 Mar 2017 19:34:28 -0500
+Subject: [PATCH 092/103] fpga pr ip: Core driver support for Altera Partial
+ Reconfiguration IP.
+
+Adding the core functions necessary for a fpga-mgr driver
+for the Altera Partial IP component.  It is intended for
+these functions to be used by the various bus implementations
+like the platform bus or the PCIe bus.
+
+Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig                   |    5 
+ drivers/fpga/Makefile                  |    1 
+ drivers/fpga/altera-pr-ip-core.c       |  220 +++++++++++++++++++++++++++++++++
+ include/linux/fpga/altera-pr-ip-core.h |   29 ++++
+ 4 files changed, 255 insertions(+)
+ create mode 100644 drivers/fpga/altera-pr-ip-core.c
+ create mode 100644 include/linux/fpga/altera-pr-ip-core.h
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -83,6 +83,11 @@ config ALTERA_FREEZE_BRIDGE
+ 	  isolate one region of the FPGA from the busses while that
+ 	  region is being reprogrammed.
+ 
++config ALTERA_PR_IP_CORE
++        tristate "Altera Partial Reconfiguration IP Core"
++        help
++          Core driver support for Altera Partial Reconfiguration IP component
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -12,6 +12,7 @@ obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10)	+= so
+ obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx-fpga.o
+ obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
++obj-$(CONFIG_ALTERA_PR_IP_CORE)         += altera-pr-ip-core.o
+ 
+ # FPGA Bridge Drivers
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+--- /dev/null
++++ b/drivers/fpga/altera-pr-ip-core.c
+@@ -0,0 +1,220 @@
++/*
++ * Driver for Altera Partial Reconfiguration IP Core
++ *
++ * Copyright (C) 2016-2017 Intel Corporation
++ *
++ * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
++ *  by Alan Tull <atull@opensource.altera.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++#include <linux/delay.h>
++#include <linux/fpga/altera-pr-ip-core.h>
++#include <linux/fpga/fpga-mgr.h>
++#include <linux/module.h>
++
++#define ALT_PR_DATA_OFST		0x00
++#define ALT_PR_CSR_OFST			0x04
++
++#define ALT_PR_CSR_PR_START		BIT(0)
++#define ALT_PR_CSR_STATUS_SFT		2
++#define ALT_PR_CSR_STATUS_MSK		(7 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_NRESET	(0 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_PR_ERR	(1 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_CRC_ERR	(2 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_BAD_BITS	(3 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_PR_IN_PROG	(4 << ALT_PR_CSR_STATUS_SFT)
++#define ALT_PR_CSR_STATUS_PR_SUCCESS	(5 << ALT_PR_CSR_STATUS_SFT)
++
++struct alt_pr_priv {
++	void __iomem *reg_base;
++};
++
++static enum fpga_mgr_states alt_pr_fpga_state(struct fpga_manager *mgr)
++{
++	struct alt_pr_priv *priv = mgr->priv;
++	const char *err = "unknown";
++	enum fpga_mgr_states ret = FPGA_MGR_STATE_UNKNOWN;
++	u32 val;
++
++	val = readl(priv->reg_base + ALT_PR_CSR_OFST);
++
++	val &= ALT_PR_CSR_STATUS_MSK;
++
++	switch (val) {
++	case ALT_PR_CSR_STATUS_NRESET:
++		return FPGA_MGR_STATE_RESET;
++
++	case ALT_PR_CSR_STATUS_PR_ERR:
++		err = "pr error";
++		ret = FPGA_MGR_STATE_WRITE_ERR;
++		break;
++
++	case ALT_PR_CSR_STATUS_CRC_ERR:
++		err = "crc error";
++		ret = FPGA_MGR_STATE_WRITE_ERR;
++		break;
++
++	case ALT_PR_CSR_STATUS_BAD_BITS:
++		err = "bad bits";
++		ret = FPGA_MGR_STATE_WRITE_ERR;
++		break;
++
++	case ALT_PR_CSR_STATUS_PR_IN_PROG:
++		return FPGA_MGR_STATE_WRITE;
++
++	case ALT_PR_CSR_STATUS_PR_SUCCESS:
++		return FPGA_MGR_STATE_OPERATING;
++
++	default:
++		break;
++	}
++
++	dev_err(&mgr->dev, "encountered error code %d (%s) in %s()\n",
++		val, err, __func__);
++	return ret;
++}
++
++static int alt_pr_fpga_write_init(struct fpga_manager *mgr,
++				  struct fpga_image_info *info,
++				  const char *buf, size_t count)
++{
++	struct alt_pr_priv *priv = mgr->priv;
++	u32 val;
++
++	if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
++		dev_err(&mgr->dev, "%s Partial Reconfiguration flag not set\n",
++			__func__);
++		return -EINVAL;
++	}
++
++	val = readl(priv->reg_base + ALT_PR_CSR_OFST);
++
++	if (val & ALT_PR_CSR_PR_START) {
++		dev_err(&mgr->dev,
++			"%s Partial Reconfiguration already started\n",
++		       __func__);
++		return -EINVAL;
++	}
++
++	writel(val | ALT_PR_CSR_PR_START, priv->reg_base + ALT_PR_CSR_OFST);
++
++	return 0;
++}
++
++static int alt_pr_fpga_write(struct fpga_manager *mgr, const char *buf,
++			     size_t count)
++{
++	struct alt_pr_priv *priv = mgr->priv;
++	u32 *buffer_32 = (u32 *)buf;
++	size_t i = 0;
++
++	if (count <= 0)
++		return -EINVAL;
++
++	/* Write out the complete 32-bit chunks */
++	while (count >= sizeof(u32)) {
++		writel(buffer_32[i++], priv->reg_base);
++		count -= sizeof(u32);
++	}
++
++	/* Write out remaining non 32-bit chunks */
++	switch (count) {
++	case 3:
++		writel(buffer_32[i++] & 0x00ffffff, priv->reg_base);
++		break;
++	case 2:
++		writel(buffer_32[i++] & 0x0000ffff, priv->reg_base);
++		break;
++	case 1:
++		writel(buffer_32[i++] & 0x000000ff, priv->reg_base);
++		break;
++	case 0:
++		break;
++	default:
++		/* This will never happen */
++		return -EFAULT;
++	}
++
++	if (alt_pr_fpga_state(mgr) == FPGA_MGR_STATE_WRITE_ERR)
++		return -EIO;
++
++	return 0;
++}
++
++static int alt_pr_fpga_write_complete(struct fpga_manager *mgr,
++				      struct fpga_image_info *info)
++{
++	u32 i = 0;
++
++	do {
++		switch (alt_pr_fpga_state(mgr)) {
++		case FPGA_MGR_STATE_WRITE_ERR:
++			return -EIO;
++
++		case FPGA_MGR_STATE_OPERATING:
++			dev_info(&mgr->dev,
++				 "successful partial reconfiguration\n");
++			return 0;
++
++		default:
++			break;
++		}
++		udelay(1);
++	} while (info->config_complete_timeout_us > i++);
++
++	dev_err(&mgr->dev, "timed out waiting for write to complete\n");
++	return -ETIMEDOUT;
++}
++
++static const struct fpga_manager_ops alt_pr_ops = {
++	.state = alt_pr_fpga_state,
++	.write_init = alt_pr_fpga_write_init,
++	.write = alt_pr_fpga_write,
++	.write_complete = alt_pr_fpga_write_complete,
++};
++
++int alt_pr_register(struct device *dev, void __iomem *reg_base)
++{
++	struct alt_pr_priv *priv;
++	u32 val;
++
++	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->reg_base = reg_base;
++
++	val = readl(priv->reg_base + ALT_PR_CSR_OFST);
++
++	dev_dbg(dev, "%s status=%d start=%d\n", __func__,
++		(val & ALT_PR_CSR_STATUS_MSK) >> ALT_PR_CSR_STATUS_SFT,
++		(int)(val & ALT_PR_CSR_PR_START));
++
++	return fpga_mgr_register(dev, dev_name(dev), &alt_pr_ops, priv);
++}
++EXPORT_SYMBOL_GPL(alt_pr_register);
++
++int alt_pr_unregister(struct device *dev)
++{
++	dev_dbg(dev, "%s\n", __func__);
++
++	fpga_mgr_unregister(dev);
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(alt_pr_unregister);
++
++MODULE_AUTHOR("Matthew Gerlach <matthew.gerlach@linux.intel.com>");
++MODULE_DESCRIPTION("Altera Partial Reconfiguration IP Core");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/include/linux/fpga/altera-pr-ip-core.h
+@@ -0,0 +1,29 @@
++/*
++ * Driver for Altera Partial Reconfiguration IP Core
++ *
++ * Copyright (C) 2016 Intel Corporation
++ *
++ * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
++ *  by Alan Tull <atull@opensource.altera.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#ifndef _ALT_PR_IP_CORE_H
++#define _ALT_PR_IP_CORE_H
++#include <linux/io.h>
++
++int alt_pr_register(struct device *dev, void __iomem *reg_base);
++int alt_pr_unregister(struct device *dev);
++
++#endif /* _ALT_PR_IP_CORE_H */
diff --git a/patches.socfpga/0093-fpga-dt-bindings-for-Altera-Partial-Reconfiguration-.patch b/patches.socfpga/0093-fpga-dt-bindings-for-Altera-Partial-Reconfiguration-.patch
new file mode 100644
index 0000000..b394e1e
--- /dev/null
+++ b/patches.socfpga/0093-fpga-dt-bindings-for-Altera-Partial-Reconfiguration-.patch
@@ -0,0 +1,32 @@
+From 4d9e84bcd82101758a0c21563d7740c1be578631 Mon Sep 17 00:00:00 2001
+From: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Date: Thu, 23 Mar 2017 19:34:29 -0500
+Subject: [PATCH 093/103] fpga dt: bindings for Altera Partial Reconfiguration
+ IP.
+
+Device Tree bindings for Altera Partial Reconfiguration IP.
+
+Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/fpga/altera-pr-ip.txt |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/fpga/altera-pr-ip.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/fpga/altera-pr-ip.txt
+@@ -0,0 +1,12 @@
++Altera Arria10 Partial Reconfiguration IP
++
++Required properties:
++- compatible : should contain "altr,a10-pr-ip"
++- reg        : base address and size for memory mapped io.
++
++Example:
++
++	fpga_mgr: fpga-mgr@ff20c000 {
++		compatible = "altr,a10-pr-ip";
++		reg = <0xff20c000 0x10>;
++	};
diff --git a/patches.socfpga/0094-fpga-pr-ip-Platform-driver-for-Altera-Partial-Reconf.patch b/patches.socfpga/0094-fpga-pr-ip-Platform-driver-for-Altera-Partial-Reconf.patch
new file mode 100644
index 0000000..0a14547
--- /dev/null
+++ b/patches.socfpga/0094-fpga-pr-ip-Platform-driver-for-Altera-Partial-Reconf.patch
@@ -0,0 +1,116 @@
+From 78ffcb1fd105ec0289d496df641c391d87e3c773 Mon Sep 17 00:00:00 2001
+From: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Date: Thu, 23 Mar 2017 19:34:30 -0500
+Subject: [PATCH 094/103] fpga pr ip: Platform driver for Altera Partial
+ Reconfiguration IP.
+
+This adds a platform bus driver for a fpga-mgr driver
+that uses the Altera Partial Reconfiguration IP component.
+
+Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig                  |    7 +++
+ drivers/fpga/Makefile                 |    1 
+ drivers/fpga/altera-pr-ip-core-plat.c |   68 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 76 insertions(+)
+ create mode 100644 drivers/fpga/altera-pr-ip-core-plat.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -88,6 +88,13 @@ config ALTERA_PR_IP_CORE
+         help
+           Core driver support for Altera Partial Reconfiguration IP component
+ 
++config ALTERA_PR_IP_CORE_PLAT
++	tristate "Platform support of Altera Partial Reconfiguration IP Core"
++	depends on ALTERA_PR_IP_CORE && OF && HAS_IOMEM
++	help
++	  Platform driver support for Altera Partial Reconfiguration IP
++	  component
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_FPGA_MGR_TS73XX)		+= ts73xx
+ obj-$(CONFIG_FPGA_MGR_XILINX_SPI)	+= xilinx-spi.o
+ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+ obj-$(CONFIG_ALTERA_PR_IP_CORE)         += altera-pr-ip-core.o
++obj-$(CONFIG_ALTERA_PR_IP_CORE_PLAT)    += altera-pr-ip-core-plat.o
+ 
+ # FPGA Bridge Drivers
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+--- /dev/null
++++ b/drivers/fpga/altera-pr-ip-core-plat.c
+@@ -0,0 +1,68 @@
++/*
++ * Driver for Altera Partial Reconfiguration IP Core
++ *
++ * Copyright (C) 2016-2017 Intel Corporation
++ *
++ * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
++ *  by Alan Tull <atull@opensource.altera.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++#include <linux/fpga/altera-pr-ip-core.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++
++static int alt_pr_platform_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	void __iomem *reg_base;
++	struct resource *res;
++
++	/* First mmio base is for register access */
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++	reg_base = devm_ioremap_resource(dev, res);
++
++	if (IS_ERR(reg_base))
++		return PTR_ERR(reg_base);
++
++	return alt_pr_register(dev, reg_base);
++}
++
++static int alt_pr_platform_remove(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++
++	return alt_pr_unregister(dev);
++}
++
++static const struct of_device_id alt_pr_of_match[] = {
++	{ .compatible = "altr,a10-pr-ip", },
++	{},
++};
++
++MODULE_DEVICE_TABLE(of, alt_pr_of_match);
++
++static struct platform_driver alt_pr_platform_driver = {
++	.probe = alt_pr_platform_probe,
++	.remove = alt_pr_platform_remove,
++	.driver = {
++		.name	= "alt_a10_pr_ip",
++		.of_match_table = alt_pr_of_match,
++	},
++};
++
++module_platform_driver(alt_pr_platform_driver);
++MODULE_AUTHOR("Matthew Gerlach <matthew.gerlach@linux.intel.com>");
++MODULE_DESCRIPTION("Altera Partial Reconfiguration IP Platform Driver");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0095-fpga-Add-support-for-Xilinx-LogiCORE-PR-Decoupler.patch b/patches.socfpga/0095-fpga-Add-support-for-Xilinx-LogiCORE-PR-Decoupler.patch
new file mode 100644
index 0000000..496db77
--- /dev/null
+++ b/patches.socfpga/0095-fpga-Add-support-for-Xilinx-LogiCORE-PR-Decoupler.patch
@@ -0,0 +1,219 @@
+From f978b7b1a45263dc1cfc46e6e0df91c608764910 Mon Sep 17 00:00:00 2001
+From: Moritz Fischer <mdf@kernel.org>
+Date: Fri, 24 Mar 2017 10:33:21 -0500
+Subject: [PATCH 095/103] fpga: Add support for Xilinx LogiCORE PR Decoupler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This adds support for the Xilinx LogiCORE PR Decoupler
+soft-ip that does decoupling of PR regions in the FPGA
+fabric during partial reconfiguration.
+
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Michal Simek <michal.simek@xilinx.com>
+Cc: Sören Brinkmann <soren.brinkmann@xilinx.com>
+Cc: linux-kernel@vger.kernel.org
+Cc: devicetree@vger.kernel.org
+Acked-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/Kconfig               |   10 ++
+ drivers/fpga/Makefile              |    1 
+ drivers/fpga/xilinx-pr-decoupler.c |  161 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 172 insertions(+)
+ create mode 100644 drivers/fpga/xilinx-pr-decoupler.c
+
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -95,6 +95,16 @@ config ALTERA_PR_IP_CORE_PLAT
+ 	  Platform driver support for Altera Partial Reconfiguration IP
+ 	  component
+ 
++config XILINX_PR_DECOUPLER
++	tristate "Xilinx LogiCORE PR Decoupler"
++	depends on FPGA_BRIDGE
++	depends on HAS_IOMEM
++	help
++	  Say Y to enable drivers for Xilinx LogiCORE PR Decoupler.
++	  The PR Decoupler exists in the FPGA fabric to isolate one
++	  region of the FPGA from the busses while that region is
++	  being reprogrammed during partial reconfig.
++
+ endif # FPGA
+ 
+ endmenu
+--- a/drivers/fpga/Makefile
++++ b/drivers/fpga/Makefile
+@@ -19,6 +19,7 @@ obj-$(CONFIG_ALTERA_PR_IP_CORE_PLAT)
+ obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+ obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
+ obj-$(CONFIG_ALTERA_FREEZE_BRIDGE)	+= altera-freeze-bridge.o
++obj-$(CONFIG_XILINX_PR_DECOUPLER)	+= xilinx-pr-decoupler.o
+ 
+ # High Level Interfaces
+ obj-$(CONFIG_FPGA_REGION)		+= fpga-region.o
+--- /dev/null
++++ b/drivers/fpga/xilinx-pr-decoupler.c
+@@ -0,0 +1,161 @@
++/*
++ * Copyright (c) 2017, National Instruments Corp.
++ * Copyright (c) 2017, Xilix Inc
++ *
++ * FPGA Bridge Driver for the Xilinx LogiCORE Partial Reconfiguration
++ * Decoupler IP Core.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/of_device.h>
++#include <linux/module.h>
++#include <linux/fpga/fpga-bridge.h>
++
++#define CTRL_CMD_DECOUPLE	BIT(0)
++#define CTRL_CMD_COUPLE		0
++#define CTRL_OFFSET		0
++
++struct xlnx_pr_decoupler_data {
++	void __iomem *io_base;
++	struct clk *clk;
++};
++
++static inline void xlnx_pr_decoupler_write(struct xlnx_pr_decoupler_data *d,
++					   u32 offset, u32 val)
++{
++	writel(val, d->io_base + offset);
++}
++
++static inline u32 xlnx_pr_decouple_read(const struct xlnx_pr_decoupler_data *d,
++					u32 offset)
++{
++	return readl(d->io_base + offset);
++}
++
++static int xlnx_pr_decoupler_enable_set(struct fpga_bridge *bridge, bool enable)
++{
++	int err;
++	struct xlnx_pr_decoupler_data *priv = bridge->priv;
++
++	err = clk_enable(priv->clk);
++	if (err)
++		return err;
++
++	if (enable)
++		xlnx_pr_decoupler_write(priv, CTRL_OFFSET, CTRL_CMD_COUPLE);
++	else
++		xlnx_pr_decoupler_write(priv, CTRL_OFFSET, CTRL_CMD_DECOUPLE);
++
++	clk_disable(priv->clk);
++
++	return 0;
++}
++
++static int xlnx_pr_decoupler_enable_show(struct fpga_bridge *bridge)
++{
++	const struct xlnx_pr_decoupler_data *priv = bridge->priv;
++	u32 status;
++	int err;
++
++	err = clk_enable(priv->clk);
++	if (err)
++		return err;
++
++	status = readl(priv->io_base);
++
++	clk_disable(priv->clk);
++
++	return !status;
++}
++
++static struct fpga_bridge_ops xlnx_pr_decoupler_br_ops = {
++	.enable_set = xlnx_pr_decoupler_enable_set,
++	.enable_show = xlnx_pr_decoupler_enable_show,
++};
++
++static const struct of_device_id xlnx_pr_decoupler_of_match[] = {
++	{ .compatible = "xlnx,pr-decoupler-1.00", },
++	{ .compatible = "xlnx,pr-decoupler", },
++	{},
++};
++MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
++
++static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
++{
++	struct xlnx_pr_decoupler_data *priv;
++	int err;
++	struct resource *res;
++
++	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	priv->io_base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(priv->io_base))
++		return PTR_ERR(priv->io_base);
++
++	priv->clk = devm_clk_get(&pdev->dev, "aclk");
++	if (IS_ERR(priv->clk)) {
++		dev_err(&pdev->dev, "input clock not found\n");
++		return PTR_ERR(priv->clk);
++	}
++
++	err = clk_prepare_enable(priv->clk);
++	if (err) {
++		dev_err(&pdev->dev, "unable to enable clock\n");
++		return err;
++	}
++
++	clk_disable(priv->clk);
++
++	err = fpga_bridge_register(&pdev->dev, "Xilinx PR Decoupler",
++				   &xlnx_pr_decoupler_br_ops, priv);
++
++	if (err) {
++		dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler");
++		clk_unprepare(priv->clk);
++		return err;
++	}
++
++	return 0;
++}
++
++static int xlnx_pr_decoupler_remove(struct platform_device *pdev)
++{
++	struct fpga_bridge *bridge = platform_get_drvdata(pdev);
++	struct xlnx_pr_decoupler_data *p = bridge->priv;
++
++	fpga_bridge_unregister(&pdev->dev);
++
++	clk_unprepare(p->clk);
++
++	return 0;
++}
++
++static struct platform_driver xlnx_pr_decoupler_driver = {
++	.probe = xlnx_pr_decoupler_probe,
++	.remove = xlnx_pr_decoupler_remove,
++	.driver = {
++		.name = "xlnx_pr_decoupler",
++		.of_match_table = of_match_ptr(xlnx_pr_decoupler_of_match),
++	},
++};
++
++module_platform_driver(xlnx_pr_decoupler_driver);
++
++MODULE_DESCRIPTION("Xilinx Partial Reconfiguration Decoupler");
++MODULE_AUTHOR("Moritz Fischer <mdf@kernel.org>");
++MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>");
++MODULE_LICENSE("GPL v2");
diff --git a/patches.socfpga/0096-fpga-altera-hps2fpga-disable-unprepare-clock-on-erro.patch b/patches.socfpga/0096-fpga-altera-hps2fpga-disable-unprepare-clock-on-erro.patch
new file mode 100644
index 0000000..d117a93
--- /dev/null
+++ b/patches.socfpga/0096-fpga-altera-hps2fpga-disable-unprepare-clock-on-erro.patch
@@ -0,0 +1,51 @@
+From fa2e7c7a675e9523bd558009e966661e0ba50ddd Mon Sep 17 00:00:00 2001
+From: Tobias Klauser <tklauser@distanz.ch>
+Date: Mon, 24 Apr 2017 16:34:20 -0500
+Subject: [PATCH 096/103] fpga altera-hps2fpga: disable/unprepare clock on
+ error in alt_fpga_bridge_probe()
+
+If either _alt_hps2fpga_enable_set() or fpga_bridge_register() fail in
+alt_fpga_bridge_probe(), the clock remains enabled and prepared. Also,
+in the error path for _alt_hps2fpga_enable_set() a call to
+fpga_bridge_unregister() is made even though the bridge was not
+registered yet.
+
+Remove the unnecessary call to fpga_bridge_unregister() and call
+clk_disable_unprepare() in both error paths in order to make sure the
+clock gets properly disabled and unprepared.
+
+Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
+Acked-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/altera-hps2fpga.c |   15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/fpga/altera-hps2fpga.c
++++ b/drivers/fpga/altera-hps2fpga.c
+@@ -181,15 +181,18 @@ static int alt_fpga_bridge_probe(struct
+ 				 (enable ? "enabling" : "disabling"));
+ 
+ 			ret = _alt_hps2fpga_enable_set(priv, enable);
+-			if (ret) {
+-				fpga_bridge_unregister(&pdev->dev);
+-				return ret;
+-			}
++			if (ret)
++				goto err;
+ 		}
+ 	}
+ 
+-	return fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
+-				    priv);
++	ret = fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
++				   priv);
++err:
++	if (ret)
++		clk_disable_unprepare(priv->clk);
++
++	return ret;
+ }
+ 
+ static int alt_fpga_bridge_remove(struct platform_device *pdev)
diff --git a/patches.socfpga/0097-fpga-region-release-FPGA-region-reference-in-error-p.patch b/patches.socfpga/0097-fpga-region-release-FPGA-region-reference-in-error-p.patch
new file mode 100644
index 0000000..4466666
--- /dev/null
+++ b/patches.socfpga/0097-fpga-region-release-FPGA-region-reference-in-error-p.patch
@@ -0,0 +1,40 @@
+From d5363219287e11386f82638a6bd4ad78a8ba7071 Mon Sep 17 00:00:00 2001
+From: Tobias Klauser <tklauser@distanz.ch>
+Date: Mon, 24 Apr 2017 16:34:21 -0500
+Subject: [PATCH 097/103] fpga: region: release FPGA region reference in error
+ path
+
+If fpga_region_get_manager() fails in fpga_region_program_fpga(), a
+reference to the fpga_manager instance previously acquired through
+fpga_region_get() is retained. Make sure to properly release it in the
+error case by using a separate jump label which will call
+fpga_region_put() in before returning.
+
+Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
+Acked-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/fpga-region.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/fpga/fpga-region.c
++++ b/drivers/fpga/fpga-region.c
+@@ -245,7 +245,8 @@ static int fpga_region_program_fpga(stru
+ 	mgr = fpga_region_get_manager(region);
+ 	if (IS_ERR(mgr)) {
+ 		pr_err("failed to get fpga region manager\n");
+-		return PTR_ERR(mgr);
++		ret = PTR_ERR(mgr);
++		goto err_put_region;
+ 	}
+ 
+ 	ret = fpga_region_get_bridges(region, overlay);
+@@ -281,6 +282,7 @@ err_put_br:
+ 	fpga_bridges_put(&region->bridge_list);
+ err_put_mgr:
+ 	fpga_mgr_put(mgr);
++err_put_region:
+ 	fpga_region_put(region);
+ 
+ 	return ret;
diff --git a/patches.socfpga/0098-fpga-fr-br-update-supported-version-numbers.patch b/patches.socfpga/0098-fpga-fr-br-update-supported-version-numbers.patch
new file mode 100644
index 0000000..13a3209
--- /dev/null
+++ b/patches.socfpga/0098-fpga-fr-br-update-supported-version-numbers.patch
@@ -0,0 +1,82 @@
+From 1ac2b755e3a514fb74fbe7574042364c97a8e572 Mon Sep 17 00:00:00 2001
+From: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Date: Mon, 24 Apr 2017 16:34:22 -0500
+Subject: [PATCH 098/103] fpga fr br: update supported version numbers
+
+The value in the version register of the altera freeze bridge
+controller changed from the beta value of 2 to the
+value of 0xad000003 in the official release of the IP.
+This patch supports the old and new version numbers, and the
+driver's probe function will fail if neither of the supported
+versions is found.
+
+Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
+Reviewed-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/fpga/altera-freeze-bridge.c |   30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+--- a/drivers/fpga/altera-freeze-bridge.c
++++ b/drivers/fpga/altera-freeze-bridge.c
+@@ -28,6 +28,7 @@
+ #define FREEZE_CSR_REG_VERSION			12
+ 
+ #define FREEZE_CSR_SUPPORTED_VERSION		2
++#define FREEZE_CSR_OFFICIAL_VERSION		0xad000003
+ 
+ #define FREEZE_CSR_STATUS_FREEZE_REQ_DONE	BIT(0)
+ #define FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE	BIT(1)
+@@ -218,6 +219,7 @@ static int altera_freeze_br_probe(struct
+ {
+ 	struct device *dev = &pdev->dev;
+ 	struct device_node *np = pdev->dev.of_node;
++	void __iomem *base_addr;
+ 	struct altera_freeze_br_data *priv;
+ 	struct resource *res;
+ 	u32 status, revision;
+@@ -225,26 +227,32 @@ static int altera_freeze_br_probe(struct
+ 	if (!np)
+ 		return -ENODEV;
+ 
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	base_addr = devm_ioremap_resource(dev, res);
++	if (IS_ERR(base_addr))
++		return PTR_ERR(base_addr);
++
++	revision = readl(base_addr + FREEZE_CSR_REG_VERSION);
++	if ((revision != FREEZE_CSR_SUPPORTED_VERSION) &&
++	    (revision != FREEZE_CSR_OFFICIAL_VERSION)) {
++		dev_err(dev,
++			"%s unexpected revision 0x%x != 0x%x != 0x%x\n",
++			__func__, revision, FREEZE_CSR_SUPPORTED_VERSION,
++			FREEZE_CSR_OFFICIAL_VERSION);
++		return -EINVAL;
++	}
++
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv)
+ 		return -ENOMEM;
+ 
+ 	priv->dev = dev;
+ 
+-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	priv->base_addr = devm_ioremap_resource(dev, res);
+-	if (IS_ERR(priv->base_addr))
+-		return PTR_ERR(priv->base_addr);
+-
+-	status = readl(priv->base_addr + FREEZE_CSR_STATUS_OFFSET);
++	status = readl(base_addr + FREEZE_CSR_STATUS_OFFSET);
+ 	if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)
+ 		priv->enable = 1;
+ 
+-	revision = readl(priv->base_addr + FREEZE_CSR_REG_VERSION);
+-	if (revision != FREEZE_CSR_SUPPORTED_VERSION)
+-		dev_warn(dev,
+-			 "%s Freeze Controller unexpected revision %d != %d\n",
+-			 __func__, revision, FREEZE_CSR_SUPPORTED_VERSION);
++	priv->base_addr = base_addr;
+ 
+ 	return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
+ 				    &altera_freeze_br_br_ops, priv);
diff --git a/patches.socfpga/0099-ARM-dts-socfpga-Add-NAND-device-tree-for-Arria10.patch b/patches.socfpga/0099-ARM-dts-socfpga-Add-NAND-device-tree-for-Arria10.patch
new file mode 100644
index 0000000..b0255ad
--- /dev/null
+++ b/patches.socfpga/0099-ARM-dts-socfpga-Add-NAND-device-tree-for-Arria10.patch
@@ -0,0 +1,84 @@
+From 969f7218e1e460db033b6c1c04300a47c0cab279 Mon Sep 17 00:00:00 2001
+From: Graham Moore <grmoore@opensource.altera.com>
+Date: Tue, 7 Jul 2015 09:58:36 -0500
+Subject: [PATCH 099/103] ARM: dts: socfpga: Add NAND device tree for Arria10
+
+Add socfpga_arria10_socdk_nand.dts board file for supporting NAND.
+
+Signed-off-by: Graham Moore <grmoore@opensource.altera.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+---
+v2: move nand dts node to socfpga_arria10.dtsi
+---
+ arch/arm/boot/dts/Makefile                       |    1 
+ arch/arm/boot/dts/socfpga_arria10.dtsi           |   13 +++++++++
+ arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts |   31 +++++++++++++++++++++++
+ 3 files changed, 45 insertions(+)
+ create mode 100644 arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts
+
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -693,6 +693,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
+ 	sh73a0-kzm9g.dtb
+ dtb-$(CONFIG_ARCH_SOCFPGA) += \
+ 	socfpga_arria5_socdk.dtb \
++	socfpga_arria10_socdk_nand.dtb \
+ 	socfpga_arria10_socdk_qspi.dtb \
+ 	socfpga_arria10_socdk_sdmmc.dtb \
+ 	socfpga_cyclone5_mcvevk.dtb \
+--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
++++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
+@@ -631,6 +631,19 @@
+ 			status = "disabled";
+ 		};
+ 
++		nand: nand@ffb90000 {
++			#address-cells = <1>;
++			#size-cells = <1>;
++			compatible = "denali,denali-nand-dt", "altr,socfpga-denali-nand";
++			reg = <0xffb90000 0x72000>,
++			      <0xffb80000 0x10000>;
++			reg-names = "nand_data", "denali_reg";
++			interrupts = <0 99 4>;
++			dma-mask = <0xffffffff>;
++			clocks = <&nand_clk>;
++			status = "disabled";
++		};
++
+ 		ocram: sram@ffe00000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0xffe00000 0x40000>;
+--- /dev/null
++++ b/arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2015 Altera Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++/dts-v1/;
++#include "socfpga_arria10_socdk.dtsi"
++
++&nand {
++	status = "okay";
++
++	partition@nand-boot {
++		label = "Boot and fpga data";
++		reg = <0x0 0x1C00000>;
++	};
++	partition@nand-rootfs {
++		label = "Root Filesystem - JFFS2";
++		reg = <0x1C00000 0x6400000>;
++	};
++};
diff --git a/patches.socfpga/0100-dt-bindings-reset-Add-reset-manager-offsets-for-Stra.patch b/patches.socfpga/0100-dt-bindings-reset-Add-reset-manager-offsets-for-Stra.patch
new file mode 100644
index 0000000..8998406
--- /dev/null
+++ b/patches.socfpga/0100-dt-bindings-reset-Add-reset-manager-offsets-for-Stra.patch
@@ -0,0 +1,127 @@
+From 5cfbeefdedaa7850b4e4cd121df2352947af0556 Mon Sep 17 00:00:00 2001
+From: Richard Gong <richard.gong@intel.com>
+Date: Thu, 1 Jun 2017 09:23:59 -0500
+Subject: [PATCH 100/103] dt-bindings: reset: Add reset manager offsets for
+ Stratix10
+
+There are several changes in reset manager offsets from Arria10 to
+Stratix10. This patch is based on one from Arria10 and adds offset
+updates for Stratix10
+
+Signed-off-by: Richard Gong <richard.gong@intel.com>
+---
+ include/dt-bindings/reset/altr,rst-mgr-s10.h |  108 +++++++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+ create mode 100644 include/dt-bindings/reset/altr,rst-mgr-s10.h
+
+--- /dev/null
++++ b/include/dt-bindings/reset/altr,rst-mgr-s10.h
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (C) 2016 Intel Corporation. All rights reserved
++ * Copyright (C) 2016 Altera Corporation. All rights reserved
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * derived from Steffen Trumtrar's "altr,rst-mgr-a10.h"
++ */
++
++#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_S10_H
++#define _DT_BINDINGS_RESET_ALTR_RST_MGR_S10_H
++
++/* MPUMODRST */
++#define CPU0_RESET		0
++#define CPU1_RESET		1
++#define CPU2_RESET		2
++#define CPU3_RESET		3
++
++/* PER0MODRST */
++#define EMAC0_RESET		32
++#define EMAC1_RESET		33
++#define EMAC2_RESET		34
++#define USB0_RESET		35
++#define USB1_RESET		36
++#define NAND_RESET		37
++/* 38 is empty */
++#define SDMMC_RESET		39
++#define EMAC0_OCP_RESET		40
++#define EMAC1_OCP_RESET		41
++#define EMAC2_OCP_RESET		42
++#define USB0_OCP_RESET		43
++#define USB1_OCP_RESET		44
++#define NAND_OCP_RESET		45
++/* 46 is empty */
++#define SDMMC_OCP_RESET		47
++#define DMA_RESET		48
++#define SPIM0_RESET		49
++#define SPIM1_RESET		50
++#define SPIS0_RESET		51
++#define SPIS1_RESET		52
++#define DMA_OCP_RESET		53
++#define EMAC_PTP_RESET		54
++/* 55 is empty*/
++#define DMAIF0_RESET		56
++#define DMAIF1_RESET		57
++#define DMAIF2_RESET		58
++#define DMAIF3_RESET		59
++#define DMAIF4_RESET		60
++#define DMAIF5_RESET		61
++#define DMAIF6_RESET		62
++#define DMAIF7_RESET		63
++
++/* PER1MODRST */
++#define WATCHDOG0_RESET		64
++#define WATCHDOG1_RESET		65
++#define WATCHDOG2_RESET		66
++#define WATCHDOG3_RESET		67
++#define L4SYSTIMER0_RESET	68
++#define L4SYSTIMER1_RESET	69
++#define SPTIMER0_RESET		70
++#define SPTIMER1_RESET		71
++#define I2C0_RESET		72
++#define I2C1_RESET		73
++#define I2C2_RESET		74
++#define I2C3_RESET		75
++#define I2C4_RESET		76
++/* 77-79 is empty */
++#define UART0_RESET		80
++#define UART1_RESET		81
++/* 82-87 is empty */
++#define GPIO0_RESET		88
++#define GPIO1_RESET		89
++
++/* BRGMODRST */
++#define SOC2FPGA_RESET		96
++#define LWHPS2FPGA_RESET	97
++#define FPGA2SOC_RESET		98
++#define F2SSDRAM0_RESET		99
++#define F2SSDRAM1_RESET		100
++#define F2SSDRAM2_RESET		101
++#define DDRSCH_RESET		102
++
++/* COLDMODRST */
++#define CPUPO0_RESET		160
++#define CPUPO1_RESET		161
++#define CPUPO2_RESET		162
++#define CPUPO3_RESET		163
++/* 164-167 is empty */
++#define L2_RESET		168
++
++/* DBGMODRST */
++#define DBG_RESET		224
++#define CSDAP_RESET		225
++
++/* TAPMODRST */
++#define TAP_RESET		256
++
++#endif
diff --git a/patches.socfpga/0101-nios2-add-screen_info.patch b/patches.socfpga/0101-nios2-add-screen_info.patch
new file mode 100644
index 0000000..6e33cf1
--- /dev/null
+++ b/patches.socfpga/0101-nios2-add-screen_info.patch
@@ -0,0 +1,35 @@
+From b3e0ba2525523283d68e8a8f7a464faf8662a632 Mon Sep 17 00:00:00 2001
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+Date: Wed, 7 Dec 2016 15:44:19 +0800
+Subject: [PATCH 101/103] nios2: add screen_info
+
+Fix build error when enable VGA console.
+
+drivers/video/console/vgacon.c:586: undefined reference to `screen_info'
+
+Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
+---
+ arch/nios2/kernel/setup.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/nios2/kernel/setup.c
++++ b/arch/nios2/kernel/setup.c
+@@ -18,6 +18,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/initrd.h>
+ #include <linux/of_fdt.h>
++#include <linux/screen_info.h>
+ 
+ #include <asm/mmu_context.h>
+ #include <asm/sections.h>
+@@ -36,6 +37,10 @@ static struct pt_regs fake_regs = { 0, 0
+ 					0, 0, 0, 0, 0, 0,
+ 					0};
+ 
++#ifdef CONFIG_VT
++struct screen_info screen_info;
++#endif
++
+ /* Copy a short hook instruction sequence to the exception address */
+ static inline void copy_exception_handler(unsigned int addr)
+ {
diff --git a/patches.socfpga/0102-nios2-switch-to-RAW_COPY_USER.patch b/patches.socfpga/0102-nios2-switch-to-RAW_COPY_USER.patch
new file mode 100644
index 0000000..09391d9
--- /dev/null
+++ b/patches.socfpga/0102-nios2-switch-to-RAW_COPY_USER.patch
@@ -0,0 +1,108 @@
+From 0b5d6273491a3b5dc69b794b0e6c678884f68157 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Wed, 22 Mar 2017 13:08:32 -0400
+Subject: [PATCH 102/103] nios2: switch to RAW_COPY_USER
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+---
+ arch/nios2/Kconfig               |    1 +
+ arch/nios2/include/asm/uaccess.h |   31 ++++++-------------------------
+ arch/nios2/mm/uaccess.c          |   16 ++++++++--------
+ 3 files changed, 15 insertions(+), 33 deletions(-)
+
+--- a/arch/nios2/Kconfig
++++ b/arch/nios2/Kconfig
+@@ -16,6 +16,7 @@ config NIOS2
+ 	select SPARSE_IRQ
+ 	select USB_ARCH_HAS_HCD if USB_SUPPORT
+ 	select CPU_NO_EFFICIENT_FFS
++	select ARCH_HAS_RAW_COPY_USER
+ 
+ config GENERIC_CSUM
+ 	def_bool y
+--- a/arch/nios2/include/asm/uaccess.h
++++ b/arch/nios2/include/asm/uaccess.h
+@@ -95,36 +95,17 @@ static inline unsigned long __must_check
+ 	return __clear_user(to, n);
+ }
+ 
+-extern long __copy_from_user(void *to, const void __user *from,
+-				unsigned long n);
+-extern long __copy_to_user(void __user *to, const void *from, unsigned long n);
+-
+-static inline long copy_from_user(void *to, const void __user *from,
+-				unsigned long n)
+-{
+-	unsigned long res = n;
+-	if (access_ok(VERIFY_READ, from, n))
+-		res = __copy_from_user(to, from, n);
+-	if (unlikely(res))
+-		memset(to + (n - res), 0, res);
+-	return res;
+-}
+-
+-static inline long copy_to_user(void __user *to, const void *from,
+-				unsigned long n)
+-{
+-	if (!access_ok(VERIFY_WRITE, to, n))
+-		return n;
+-	return __copy_to_user(to, from, n);
+-}
++extern unsigned long
++raw_copy_from_user(void *to, const void __user *from, unsigned long n);
++extern unsigned long
++raw_copy_to_user(void __user *to, const void *from, unsigned long n);
++#define INLINE_COPY_FROM_USER
++#define INLINE_COPY_TO_USER
+ 
+ extern long strncpy_from_user(char *__to, const char __user *__from,
+ 				long __len);
+ extern long strnlen_user(const char __user *s, long n);
+ 
+-#define __copy_from_user_inatomic	__copy_from_user
+-#define __copy_to_user_inatomic		__copy_to_user
+-
+ /* Optimized macros */
+ #define __get_user_asm(val, insn, addr, err)				\
+ {									\
+--- a/arch/nios2/mm/uaccess.c
++++ b/arch/nios2/mm/uaccess.c
+@@ -10,9 +10,9 @@
+ #include <linux/export.h>
+ #include <linux/uaccess.h>
+ 
+-asm(".global	__copy_from_user\n"
+-	"   .type __copy_from_user, @function\n"
+-	"__copy_from_user:\n"
++asm(".global	raw_copy_from_user\n"
++	"   .type raw_copy_from_user, @function\n"
++	"raw_copy_from_user:\n"
+ 	"   movi  r2,7\n"
+ 	"   mov   r3,r4\n"
+ 	"   bge   r2,r6,1f\n"
+@@ -65,12 +65,12 @@ asm(".global	__copy_from_user\n"
+ 	".word 7b,13b\n"
+ 	".previous\n"
+ 	);
+-EXPORT_SYMBOL(__copy_from_user);
++EXPORT_SYMBOL(raw_copy_from_user);
+ 
+ asm(
+-	"   .global __copy_to_user\n"
+-	"   .type __copy_to_user, @function\n"
+-	"__copy_to_user:\n"
++	"   .global raw_copy_to_user\n"
++	"   .type raw_copy_to_user, @function\n"
++	"raw_copy_to_user:\n"
+ 	"   movi  r2,7\n"
+ 	"   mov   r3,r4\n"
+ 	"   bge   r2,r6,1f\n"
+@@ -127,7 +127,7 @@ asm(
+ 	".word 11b,13b\n"
+ 	".word 12b,13b\n"
+ 	".previous\n");
+-EXPORT_SYMBOL(__copy_to_user);
++EXPORT_SYMBOL(raw_copy_to_user);
+ 
+ long strncpy_from_user(char *__to, const char __user *__from, long __len)
+ {
diff --git a/patches.socfpga/0103-nios2-use-generic-strncpy_from_user-and-strnlen_user.patch b/patches.socfpga/0103-nios2-use-generic-strncpy_from_user-and-strnlen_user.patch
new file mode 100644
index 0000000..8701cfa
--- /dev/null
+++ b/patches.socfpga/0103-nios2-use-generic-strncpy_from_user-and-strnlen_user.patch
@@ -0,0 +1,88 @@
+From 1e114cbc9496ee8376e0ad899890a1eff7e58230 Mon Sep 17 00:00:00 2001
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+Date: Mon, 8 May 2017 17:14:14 +0800
+Subject: [PATCH 103/103] nios2: use generic strncpy_from_user() and
+ strnlen_user()
+
+This change enables the generic strncpy_from_user() and strnlen_user()
+
+Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
+---
+ arch/nios2/Kconfig               |    2 ++
+ arch/nios2/include/asm/uaccess.h |    7 +++++--
+ arch/nios2/mm/uaccess.c          |   33 ---------------------------------
+ 3 files changed, 7 insertions(+), 35 deletions(-)
+
+--- a/arch/nios2/Kconfig
++++ b/arch/nios2/Kconfig
+@@ -6,6 +6,8 @@ config NIOS2
+ 	select GENERIC_CPU_DEVICES
+ 	select GENERIC_IRQ_PROBE
+ 	select GENERIC_IRQ_SHOW
++	select GENERIC_STRNCPY_FROM_USER
++	select GENERIC_STRNLEN_USER
+ 	select HAVE_ARCH_TRACEHOOK
+ 	select HAVE_ARCH_KGDB
+ 	select IRQ_DOMAIN
+--- a/arch/nios2/include/asm/uaccess.h
++++ b/arch/nios2/include/asm/uaccess.h
+@@ -64,6 +64,8 @@ extern int fixup_exception(struct pt_reg
+ 
+ # define __EX_TABLE_SECTION	".section __ex_table,\"a\"\n"
+ 
++#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
++
+ /*
+  * Zero Userspace
+  */
+@@ -103,8 +105,9 @@ raw_copy_to_user(void __user *to, const
+ #define INLINE_COPY_TO_USER
+ 
+ extern long strncpy_from_user(char *__to, const char __user *__from,
+-				long __len);
+-extern long strnlen_user(const char __user *s, long n);
++			      long __len);
++extern __must_check long strlen_user(const char __user *str);
++extern __must_check long strnlen_user(const char __user *s, long n);
+ 
+ /* Optimized macros */
+ #define __get_user_asm(val, insn, addr, err)				\
+--- a/arch/nios2/mm/uaccess.c
++++ b/arch/nios2/mm/uaccess.c
+@@ -128,36 +128,3 @@ asm(
+ 	".word 12b,13b\n"
+ 	".previous\n");
+ EXPORT_SYMBOL(raw_copy_to_user);
+-
+-long strncpy_from_user(char *__to, const char __user *__from, long __len)
+-{
+-	int l = strnlen_user(__from, __len);
+-	int is_zt = 1;
+-
+-	if (l > __len) {
+-		is_zt = 0;
+-		l = __len;
+-	}
+-
+-	if (l == 0 || copy_from_user(__to, __from, l))
+-		return -EFAULT;
+-
+-	if (is_zt)
+-		l--;
+-	return l;
+-}
+-
+-long strnlen_user(const char __user *s, long n)
+-{
+-	long i;
+-
+-	for (i = 0; i < n; i++) {
+-		char c;
+-
+-		if (get_user(c, s + i) == -EFAULT)
+-			return 0;
+-		if (c == 0)
+-			return i + 1;
+-	}
+-	return n + 1;
+-}
diff --git a/series b/series
index 228a079..c607364 100644
--- a/series
+++ b/series
@@ -857,6 +857,112 @@
 patches.renesas/0286-ARM-dts-r8a7791-Drop-_clk-suffix-from-external-CAN-c.patch
 
 #############################################################################
+# SoCFPGA patches
+patches.socfpga/0001-ARM-dts-socfpga-enable-arm-shared-override-in-the-pl.patch
+patches.socfpga/0002-ARM-socfpga_defconfig-Enable-HIGHMEM.patch
+patches.socfpga/0003-ARM-dts-socfpga-enable-qspi-on-the-Cyclone5-devkit.patch
+patches.socfpga/0004-ARM-dts-socfpga-Add-QSPI-node-for-the-Arria10.patch
+patches.socfpga/0005-ARM-dts-socfpga-Enable-QSPI-in-Arria10-devkit.patch
+patches.socfpga/0006-ARM-dts-socfpga-Enable-QSPI-on-the-Cyclone5-sockit.patch
+patches.socfpga/0007-ARM-dts-socfpga-Enable-QSPI-on-the-Arria5-devkit.patch
+patches.socfpga/0008-ARM-socfpga_defconfig-enable-FS-configs-to-support-A.patch
+patches.socfpga/0009-dt-bindings-Add-Macnica-Americas-vendor-prefix.patch
+patches.socfpga/0010-dt-bindings-Add-vendor-prefix-for-Terasic-Inc.patch
+patches.socfpga/0011-dt-bindings-Add-vendor-prefix-for-Samtec.patch
+patches.socfpga/0012-ARM-dts-socfpga-enable-GPIO-and-LEDs-for-Cyclone5-an.patch
+patches.socfpga/0013-ARM-dts-socfpga-set-desired-i2c-clock-on-Cyclone5-an.patch
+patches.socfpga/0014-ARM-dts-socfpga-Add-Rohm-DH2228FV-DAC.patch
+patches.socfpga/0015-ARM-dts-socfpga-enable-CAN-on-Cyclone5-devkit.patch
+patches.socfpga/0016-ARM-dts-socfpga-enable-watchdog-timer-on-Arria5-and-.patch
+patches.socfpga/0017-ARM-dts-socfpga-add-the-LTC2977-power-monitor-on-Arr.patch
+patches.socfpga/0018-ARM-dts-socfpga-add-fpga-manager-node-for-Arria10.patch
+patches.socfpga/0019-ARM-dts-socfpga-fpga-manager-data-is-32-bits.patch
+patches.socfpga/0020-ARM-dts-socfpga-add-fpga-region-support-on-Arria10.patch
+patches.socfpga/0021-ARM-dts-socfpga-add-missing-compatible-string-for-SD.patch
+patches.socfpga/0022-ARM-dts-watchdog0-cannot-reliably-trigger-reset.patch
+patches.socfpga/0023-MAINTAINERS-socfpga-update-email-for-Dinh-Nguyen.patch
+patches.socfpga/0024-of-overlay-add-of-overlay-notifications.patch
+patches.socfpga/0025-fpga-add-method-to-get-fpga-manager-from-device.patch
+patches.socfpga/0026-doc-fpga-mgr-add-fpga-image-info-to-api.patch
+patches.socfpga/0027-fpga-add-bindings-document-for-fpga-region.patch
+patches.socfpga/0028-fpga-mgr-add-fpga-image-information-struct.patch
+patches.socfpga/0029-add-sysfs-document-for-fpga-bridge-class.patch
+patches.socfpga/0030-fpga-add-fpga-bridge-framework.patch
+patches.socfpga/0031-fpga-fpga-region-device-tree-control-for-FPGA.patch
+patches.socfpga/0032-ARM-socfpga-fpga-bridge-driver-support.patch
+patches.socfpga/0033-fpga-add-altera-freeze-bridge-support.patch
+patches.socfpga/0034-fpga-manager-Add-Socfpga-Arria10-support.patch
+patches.socfpga/0035-ARM-socfpga-checking-the-wrong-variable.patch
+patches.socfpga/0036-fpga-Add-COMPILE_TEST-to-all-drivers.patch
+patches.socfpga/0037-fpga-zynq-Add-missing-n-to-messages.patch
+patches.socfpga/0038-fpga-zynq-Remove-priv-dev.patch
+patches.socfpga/0039-fpga-zynq-Fix-incorrect-ISR-state-on-bootup.patch
+patches.socfpga/0040-fpga-Clarify-how-write_init-works-streaming-modes.patch
+patches.socfpga/0041-fpga-zynq-Check-for-errors-after-completing-DMA.patch
+patches.socfpga/0042-fpga-zynq-Check-the-bitstream-for-validity.patch
+patches.socfpga/0043-fpga-Add-scatterlist-based-programming.patch
+patches.socfpga/0044-fpga-zynq-Use-the-scatterlist-interface.patch
+patches.socfpga/0045-fpga-fix-sparse-warnings-in-fpga-mgr-and-fpga-bridge.patch
+patches.socfpga/0046-fpga-Add-flag-to-indicate-bitstream-needs-decrypting.patch
+patches.socfpga/0047-fpga-zynq-Add-support-for-encrypted-bitstreams.patch
+patches.socfpga/0048-fpga-region-Add-fpga-region-property-encrypted-fpga-.patch
+patches.socfpga/0049-FPGA-Add-TS-7300-FPGA-manager.patch
+patches.socfpga/0050-Documentation-Add-binding-document-for-Lattice-iCE40.patch
+patches.socfpga/0051-fpga-Add-support-for-Lattice-iCE40-FPGAs.patch
+patches.socfpga/0052-fpga-bridge-Replace-open-coded-list_for_each-list_en.patch
+patches.socfpga/0053-fpga-altera_freeze_bridge-Constify-ops.patch
+patches.socfpga/0054-dt-bindings-fpga-add-xilinx-slave-serial-binding-des.patch
+patches.socfpga/0055-fpga-manager-Add-Xilinx-slave-serial-SPI-driver.patch
+patches.socfpga/0056-ARM-socfpga-add-bindings-document-for-fpga-bridge-dr.patch
+patches.socfpga/0057-ARM-socfpga-add-bindings-doc-for-arria10-fpga-manage.patch
+patches.socfpga/0058-add-bindings-document-for-altera-freeze-bridge.patch
+patches.socfpga/0059-MAINTAINERS-add-git-url-for-fpga.patch
+patches.socfpga/0060-ARM-dts-socfpga-add-base-fpga-region-and-fpga-bridge.patch
+patches.socfpga/0061-fpga-add-config-complete-timeout.patch
+patches.socfpga/0062-MAINTAINERS-Add-file-patterns-for-fpga-device-tree-b.patch
+patches.socfpga/0063-MAINTAINERS-fpga-update-email-and-directory-paths.patch
+patches.socfpga/0064-spi-Add-Flag-to-Enable-Slave-Select-with-GPIO-Chip-S.patch
+patches.socfpga/0065-spi-dw-Set-GPIO_SS-flag-to-toggle-Slave-Select-on-GP.patch
+patches.socfpga/0066-ARM-dts-socfpga-Add-SPI-Master1-for-Arria10-SR-chip.patch
+patches.socfpga/0067-ARM-dts-socfpga-Add-Devkit-A10-SR-fields-for-Arria10.patch
+patches.socfpga/0068-ARM-dts-socfpga-Enable-GPIO-parent-for-Arria10-SR-ch.patch
+patches.socfpga/0069-ARM-dts-socfpga-Add-LED-framework-to-A10-SR-GPIO.patch
+patches.socfpga/0070-EDAC-altera-Disable-IRQs-while-injecting-SDRAM-error.patch
+patches.socfpga/0071-gpio-altera-a10sr-Add-A10-System-Resource-Chip-GPIO-.patch
+patches.socfpga/0072-dt-bindings-mfd-Add-Altera-Arria10-System-Resource-C.patch
+patches.socfpga/0073-ARM-dts-Add-EMAC-AXI-settings-for-Arria10.patch
+patches.socfpga/0074-MAINTAINERS-EDAC-Update-email-for-Thor-Thayer.patch
+patches.socfpga/0075-gpio-altera-a10sr-Set-gpio_chip-parent-property.patch
+patches.socfpga/0076-dt-bindings-reset-a10sr-Add-Arria10-SR-Reset-Control.patch
+patches.socfpga/0077-reset-Add-Altera-Arria10-SR-Reset-Controller.patch
+patches.socfpga/0078-ARM-dts-socfpga-Add-Devkit-A10-SR-Reset-Controller.patch
+patches.socfpga/0079-EDAC-altera-Fix-peripheral-warnings-for-Cyclone5.patch
+patches.socfpga/0080-mfd-altr_a10sr-Add-Arria10-DevKit-Reset-Controller.patch
+patches.socfpga/0081-dt-bindings-mfd-Add-Altera-Arria10-SR-Reset-Controll.patch
+patches.socfpga/0082-ARM-socfpga-defconfig-enable-qspi.patch
+patches.socfpga/0083-ARM-socfpga-updates-for-socfpga_defconfig.patch
+patches.socfpga/0084-ARM-socfpga_defconfig-update-defconfig-for-SoCFPGA.patch
+patches.socfpga/0085-ARM-socfpga-updates-for-socfpga_defconfig.patch
+patches.socfpga/0086-ARM-dts-socfpga-Add-new-MCVEVK-manufacturer-compat.patch
+patches.socfpga/0087-ARM-dts-socfpga-Add-Macnica-sodia-board.patch
+patches.socfpga/0088-ARM-dts-socfpga-add-specific-compatible-strings-for-.patch
+patches.socfpga/0089-ARM-dts-socfpga-Add-unit-name-to-memory-nodes.patch
+patches.socfpga/0090-ARM-dts-socfpga-sodia-enable-qspi.patch
+patches.socfpga/0091-ARM-dts-socfpga-add-qspi-node.patch
+patches.socfpga/0092-fpga-pr-ip-Core-driver-support-for-Altera-Partial-Re.patch
+patches.socfpga/0093-fpga-dt-bindings-for-Altera-Partial-Reconfiguration-.patch
+patches.socfpga/0094-fpga-pr-ip-Platform-driver-for-Altera-Partial-Reconf.patch
+patches.socfpga/0095-fpga-Add-support-for-Xilinx-LogiCORE-PR-Decoupler.patch
+patches.socfpga/0096-fpga-altera-hps2fpga-disable-unprepare-clock-on-erro.patch
+patches.socfpga/0097-fpga-region-release-FPGA-region-reference-in-error-p.patch
+patches.socfpga/0098-fpga-fr-br-update-supported-version-numbers.patch
+patches.socfpga/0099-ARM-dts-socfpga-Add-NAND-device-tree-for-Arria10.patch
+patches.socfpga/0100-dt-bindings-reset-Add-reset-manager-offsets-for-Stra.patch
+patches.socfpga/0101-nios2-add-screen_info.patch
+patches.socfpga/0102-nios2-switch-to-RAW_COPY_USER.patch
+patches.socfpga/0103-nios2-use-generic-strncpy_from_user-and-strnlen_user.patch
+
+#############################################################################
 # Misc patches
 
 ##############################################################################