diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arc/include/asm/delay.h linux-libre-4.9-rc8-gnu/arch/arc/include/asm/delay.h
--- linux-libre-4.9-rc7-gnu/arch/arc/include/asm/delay.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arc/include/asm/delay.h	2016-12-04 15:50:51.000000000 -0500
@@ -22,10 +22,11 @@
 static inline void __delay(unsigned long loops)
 {
 	__asm__ __volatile__(
-	"	lp  1f	\n"
-	"	nop	\n"
-	"1:		\n"
-	: "+l"(loops));
+	"	mov lp_count, %0	\n"
+	"	lp  1f			\n"
+	"	nop			\n"
+	"1:				\n"
+	: : "r"(loops));
 }
 
 extern void __bad_udelay(void);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arc/include/asm/pgtable.h linux-libre-4.9-rc8-gnu/arch/arc/include/asm/pgtable.h
--- linux-libre-4.9-rc7-gnu/arch/arc/include/asm/pgtable.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arc/include/asm/pgtable.h	2016-12-04 15:50:51.000000000 -0500
@@ -280,7 +280,7 @@ static inline void pmd_set(pmd_t *pmdp,
 
 #define pte_page(pte)		pfn_to_page(pte_pfn(pte))
 #define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
-#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pte(pfn, prot)	__pte(__pfn_to_phys(pfn) | pgprot_val(prot))
 
 /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/
 #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arc/mm/cache.c linux-libre-4.9-rc8-gnu/arch/arc/mm/cache.c
--- linux-libre-4.9-rc7-gnu/arch/arc/mm/cache.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arc/mm/cache.c	2016-12-04 15:50:51.000000000 -0500
@@ -23,7 +23,7 @@
 
 static int l2_line_sz;
 static int ioc_exists;
-int slc_enable = 1, ioc_enable = 1;
+int slc_enable = 1, ioc_enable = 0;
 unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */
 unsigned long perip_end = 0xFFFFFFFF; /* legacy value */
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/Makefile linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/Makefile
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/Makefile	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/Makefile	2016-12-04 15:50:51.000000000 -0500
@@ -745,7 +745,6 @@ dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-pcduino2.dtb \
 	sun4i-a10-pov-protab2-ips9.dtb
 dtb-$(CONFIG_MACH_SUN5I) += \
-	ntc-gr8-evb.dtb \
 	sun5i-a10s-auxtek-t003.dtb \
 	sun5i-a10s-auxtek-t004.dtb \
 	sun5i-a10s-mk802.dtb \
@@ -761,6 +760,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
 	sun5i-a13-olinuxino-micro.dtb \
 	sun5i-a13-q8-tablet.dtb \
 	sun5i-a13-utoo-p66.dtb \
+	sun5i-gr8-evb.dtb \
 	sun5i-r8-chip.dtb
 dtb-$(CONFIG_MACH_SUN6I) += \
 	sun6i-a31-app4-evb1.dtb \
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/ntc-gr8.dtsi linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/ntc-gr8.dtsi
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/ntc-gr8.dtsi	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/ntc-gr8.dtsi	1969-12-31 19:00:00.000000000 -0500
@@ -1,1087 +0,0 @@
-/*
- * Copyright 2016 Mylène Josserand
- *
- * Mylène Josserand <mylene.josserand@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library 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 library 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dt-bindings/clock/sun4i-a10-pll2.h>
-#include <dt-bindings/dma/sun4i-a10.h>
-#include <dt-bindings/pinctrl/sun4i-a10.h>
-
-/ {
-	interrupt-parent = <&intc>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu0: cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a8";
-			reg = <0x0>;
-			clocks = <&cpu>;
-		};
-	};
-
-	clocks {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		/*
-		 * This is a dummy clock, to be used as placeholder on
-		 * other mux clocks when a specific parent clock is not
-		 * yet implemented. It should be dropped when the driver
-		 * is complete.
-		 */
-		dummy: dummy {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <0>;
-		};
-
-		osc24M: clk@01c20050 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-osc-clk";
-			reg = <0x01c20050 0x4>;
-			clock-frequency = <24000000>;
-			clock-output-names = "osc24M";
-		};
-
-		osc3M: osc3M-clk {
-			compatible = "fixed-factor-clock";
-			#clock-cells = <0>;
-			clock-div = <8>;
-			clock-mult = <1>;
-			clocks = <&osc24M>;
-			clock-output-names = "osc3M";
-		};
-
-		osc32k: clk@0 {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <32768>;
-			clock-output-names = "osc32k";
-		};
-
-		pll1: clk@01c20000 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20000 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll1";
-		};
-
-		pll2: clk@01c20008 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-pll2-clk";
-			reg = <0x01c20008 0x8>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll2-1x", "pll2-2x",
-					     "pll2-4x", "pll2-8x";
-		};
-
-		pll3: clk@01c20010 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20010 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll3";
-		};
-
-		pll3x2: pll3x2-clk {
-			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll3>;
-			clock-output-names = "pll3-2x";
-		};
-
-		pll4: clk@01c20018 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll1-clk";
-			reg = <0x01c20018 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll4";
-		};
-
-		pll5: clk@01c20020 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll5-clk";
-			reg = <0x01c20020 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll5_ddr", "pll5_other";
-		};
-
-		pll6: clk@01c20028 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-pll6-clk";
-			reg = <0x01c20028 0x4>;
-			clocks = <&osc24M>;
-			clock-output-names = "pll6_sata", "pll6_other", "pll6";
-		};
-
-		pll7: clk@01c20030 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-pll3-clk";
-			reg = <0x01c20030 0x4>;
-			clocks = <&osc3M>;
-			clock-output-names = "pll7";
-		};
-
-		pll7x2: pll7x2-clk {
-			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
-			#clock-cells = <0>;
-			clock-div = <1>;
-			clock-mult = <2>;
-			clocks = <&pll7>;
-			clock-output-names = "pll7-2x";
-		};
-
-		/* dummy is 200M */
-		cpu: cpu@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-cpu-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
-			clock-output-names = "cpu";
-		};
-
-		axi: axi@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-axi-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&cpu>;
-			clock-output-names = "axi";
-		};
-
-		ahb: ahb@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-ahb-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&axi>, <&cpu>, <&pll6 1>;
-			clock-output-names = "ahb";
-			/*
-			 * Use PLL6 as parent, instead of CPU/AXI
-			 * which has rate changes due to cpufreq
-			 */
-			assigned-clocks = <&ahb>;
-			assigned-clock-parents = <&pll6 1>;
-		};
-
-		apb0: apb0@01c20054 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb0-clk";
-			reg = <0x01c20054 0x4>;
-			clocks = <&ahb>;
-			clock-output-names = "apb0";
-		};
-
-		apb1: clk@01c20058 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-apb1-clk";
-			reg = <0x01c20058 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
-			clock-output-names = "apb1";
-		};
-
-		axi_gates: clk@01c2005c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c2005c 0x4>;
-			clocks = <&axi>;
-			clock-indices = <0>;
-			clock-output-names = "axi_dram";
-		};
-
-		ahb_gates: clk@01c20060 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun5i-a13-ahb-gates-clk";
-			reg = <0x01c20060 0x8>;
-			clocks = <&ahb>;
-			clock-indices = <0>, <1>,
-					<2>, <5>, <6>,
-					<7>, <8>, <9>,
-					<10>, <13>,
-					<14>, <17>, <20>,
-					<21>, <22>,
-					<28>, <32>, <34>,
-					<36>, <40>, <44>,
-					<46>, <51>,
-					<52>;
-			clock-output-names = "ahb_usbotg", "ahb_ehci",
-					     "ahb_ohci", "ahb_ss", "ahb_dma",
-					     "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-					     "ahb_mmc2", "ahb_nand",
-					     "ahb_sdram", "ahb_emac", "ahb_spi0",
-					     "ahb_spi1", "ahb_spi2",
-					     "ahb_hstimer", "ahb_ve", "ahb_tve",
-					     "ahb_lcd", "ahb_csi", "ahb_de_be",
-					     "ahb_de_fe", "ahb_iep",
-					     "ahb_mali400";
-		};
-
-		apb0_gates: clk@01c20068 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c20068 0x4>;
-			clocks = <&apb0>;
-			clock-indices = <0>, <3>,
-					<5>, <6>;
-			clock-output-names = "apb0_codec", "apb0_i2s0",
-					     "apb0_pio", "apb0_ir";
-		};
-
-		apb1_gates: clk@01c2006c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c2006c 0x4>;
-			clocks = <&apb1>;
-			clock-indices = <0>, <1>,
-					<2>, <17>,
-					<18>, <19>;
-			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-					     "apb1_i2c2", "apb1_uart1",
-					     "apb1_uart2", "apb1_uart3";
-		};
-
-		nand_clk: clk@01c20080 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20080 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "nand";
-		};
-
-		ms_clk: clk@01c20084 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20084 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ms";
-		};
-
-		mmc0_clk: clk@01c20088 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20088 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc0",
-					     "mmc0_output",
-					     "mmc0_sample";
-		};
-
-		mmc1_clk: clk@01c2008c {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c2008c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc1",
-					     "mmc1_output",
-					     "mmc1_sample";
-		};
-
-		mmc2_clk: clk@01c20090 {
-			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-a10-mmc-clk";
-			reg = <0x01c20090 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mmc2",
-					     "mmc2_output",
-					     "mmc2_sample";
-		};
-
-		ts_clk: clk@01c20098 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c20098 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ts";
-		};
-
-		ss_clk: clk@01c2009c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c2009c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ss";
-		};
-
-		spi0_clk: clk@01c200a0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi0";
-		};
-
-		spi1_clk: clk@01c200a4 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a4 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi1";
-		};
-
-		spi2_clk: clk@01c200a8 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200a8 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "spi2";
-		};
-
-		ir0_clk: clk@01c200b0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod0-clk";
-			reg = <0x01c200b0 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "ir0";
-		};
-
-		i2s0_clk: clk@01c200b8 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod1-clk";
-			reg = <0x01c200b8 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-				 <&pll2 SUN4I_A10_PLL2_4X>,
-				 <&pll2 SUN4I_A10_PLL2_2X>,
-				 <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "i2s0";
-		};
-
-		spdif_clk: clk@01c200c0 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-mod1-clk";
-			reg = <0x01c200c0 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
-				 <&pll2 SUN4I_A10_PLL2_4X>,
-				 <&pll2 SUN4I_A10_PLL2_2X>,
-				 <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "spdif";
-		};
-
-		usb_clk: clk@01c200cc {
-			#clock-cells = <1>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun5i-a13-usb-clk";
-			reg = <0x01c200cc 0x4>;
-			clocks = <&pll6 1>;
-			clock-output-names = "usb_ohci0", "usb_phy";
-		};
-
-		dram_gates: clk@01c20100 {
-			#clock-cells = <1>;
-			compatible = "nextthing,gr8-dram-gates-clk",
-				     "allwinner,sun4i-a10-gates-clk";
-			reg = <0x01c20100 0x4>;
-			clocks = <&pll5 0>;
-			clock-indices = <0>,
-					<1>,
-					<25>,
-					<26>,
-					<29>,
-					<31>;
-			clock-output-names = "dram_ve",
-					     "dram_csi",
-					     "dram_de_fe",
-					     "dram_de_be",
-					     "dram_ace",
-					     "dram_iep";
-		};
-
-		de_be_clk: clk@01c20104 {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c20104 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-be";
-		};
-
-		de_fe_clk: clk@01c2010c {
-			#clock-cells = <0>;
-			#reset-cells = <0>;
-			compatible = "allwinner,sun4i-a10-display-clk";
-			reg = <0x01c2010c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll5 1>;
-			clock-output-names = "de-fe";
-		};
-
-		tcon_ch0_clk: clk@01c20118 {
-			#clock-cells = <0>;
-			#reset-cells = <1>;
-			compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
-			reg = <0x01c20118 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch0-sclk";
-		};
-
-		tcon_ch1_clk: clk@01c2012c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
-			reg = <0x01c2012c 0x4>;
-			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
-			clock-output-names = "tcon-ch1-sclk";
-		};
-
-		codec_clk: clk@01c20140 {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun4i-a10-codec-clk";
-			reg = <0x01c20140 0x4>;
-			clocks = <&pll2 SUN4I_A10_PLL2_1X>;
-			clock-output-names = "codec";
-		};
-
-		mbus_clk: clk@01c2015c {
-			#clock-cells = <0>;
-			compatible = "allwinner,sun5i-a13-mbus-clk";
-			reg = <0x01c2015c 0x4>;
-			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
-			clock-output-names = "mbus";
-		};
-	};
-
-	display-engine {
-		compatible = "allwinner,sun5i-a13-display-engine";
-		allwinner,pipelines = <&fe0>;
-	};
-
-	soc@01c00000 {
-		compatible = "simple-bus";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		sram-controller@01c00000 {
-			compatible = "allwinner,sun4i-a10-sram-controller";
-			reg = <0x01c00000 0x30>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges;
-
-			sram_a: sram@00000000 {
-				compatible = "mmio-sram";
-				reg = <0x00000000 0xc000>;
-				#address-cells = <1>;
-				#size-cells = <1>;
-				ranges = <0 0x00000000 0xc000>;
-			};
-
-			sram_d: sram@00010000 {
-				compatible = "mmio-sram";
-				reg = <0x00010000 0x1000>;
-				#address-cells = <1>;
-				#size-cells = <1>;
-				ranges = <0 0x00010000 0x1000>;
-
-				otg_sram: sram-section@0000 {
-					compatible = "allwinner,sun4i-a10-sram-d";
-					reg = <0x0000 0x1000>;
-					status = "disabled";
-				};
-			};
-		};
-
-		dma: dma-controller@01c02000 {
-			compatible = "allwinner,sun4i-a10-dma";
-			reg = <0x01c02000 0x1000>;
-			interrupts = <27>;
-			clocks = <&ahb_gates 6>;
-			#dma-cells = <2>;
-		};
-
-		nfc: nand@01c03000 {
-			compatible = "allwinner,sun4i-a10-nand";
-			reg = <0x01c03000 0x1000>;
-			interrupts = <37>;
-			clocks = <&ahb_gates 13>, <&nand_clk>;
-			clock-names = "ahb", "mod";
-			dmas = <&dma SUN4I_DMA_DEDICATED 3>;
-			dma-names = "rxtx";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		spi0: spi@01c05000 {
-			compatible = "allwinner,sun4i-a10-spi";
-			reg = <0x01c05000 0x1000>;
-			interrupts = <10>;
-			clocks = <&ahb_gates 20>, <&spi0_clk>;
-			clock-names = "ahb", "mod";
-			dmas = <&dma SUN4I_DMA_DEDICATED 27>,
-			       <&dma SUN4I_DMA_DEDICATED 26>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		spi1: spi@01c06000 {
-			compatible = "allwinner,sun4i-a10-spi";
-			reg = <0x01c06000 0x1000>;
-			interrupts = <11>;
-			clocks = <&ahb_gates 21>, <&spi1_clk>;
-			clock-names = "ahb", "mod";
-			dmas = <&dma SUN4I_DMA_DEDICATED 9>,
-			       <&dma SUN4I_DMA_DEDICATED 8>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		tve0: tv-encoder@01c0a000 {
-			compatible = "allwinner,sun4i-a10-tv-encoder";
-			reg = <0x01c0a000 0x1000>;
-			clocks = <&ahb_gates 34>;
-			resets = <&tcon_ch0_clk 0>;
-			status = "disabled";
-
-			port {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				tve0_in_tcon0: endpoint@0 {
-					reg = <0>;
-					remote-endpoint = <&tcon0_out_tve0>;
-				};
-			};
-		};
-
-		tcon0: lcd-controller@01c0c000 {
-			compatible = "allwinner,sun5i-a13-tcon";
-			reg = <0x01c0c000 0x1000>;
-			interrupts = <44>;
-			resets = <&tcon_ch0_clk 1>;
-			reset-names = "lcd";
-			clocks = <&ahb_gates 36>,
-				 <&tcon_ch0_clk>,
-				 <&tcon_ch1_clk>;
-			clock-names = "ahb",
-				      "tcon-ch0",
-				      "tcon-ch1";
-			clock-output-names = "tcon-pixel-clock";
-			status = "disabled";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				tcon0_in: port@0 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <0>;
-
-					tcon0_in_be0: endpoint@0 {
-						reg = <0>;
-						remote-endpoint = <&be0_out_tcon0>;
-					};
-				};
-
-				tcon0_out: port@1 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <1>;
-
-					tcon0_out_tve0: endpoint@1 {
-						reg = <1>;
-						remote-endpoint = <&tve0_in_tcon0>;
-					};
-				};
-			};
-		};
-
-		mmc0: mmc@01c0f000 {
-			compatible = "allwinner,sun5i-a13-mmc";
-			reg = <0x01c0f000 0x1000>;
-			clocks = <&ahb_gates 8>,
-				 <&mmc0_clk 0>,
-				 <&mmc0_clk 1>,
-				 <&mmc0_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
-			interrupts = <32>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		mmc1: mmc@01c10000 {
-			compatible = "allwinner,sun5i-a13-mmc";
-			reg = <0x01c10000 0x1000>;
-			clocks = <&ahb_gates 9>,
-				 <&mmc1_clk 0>,
-				 <&mmc1_clk 1>,
-				 <&mmc1_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
-			interrupts = <33>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		mmc2: mmc@01c11000 {
-			compatible = "allwinner,sun5i-a13-mmc";
-			reg = <0x01c11000 0x1000>;
-			clocks = <&ahb_gates 10>,
-				 <&mmc2_clk 0>,
-				 <&mmc2_clk 1>,
-				 <&mmc2_clk 2>;
-			clock-names = "ahb",
-				      "mmc",
-				      "output",
-				      "sample";
-			interrupts = <34>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		usb_otg: usb@01c13000 {
-			compatible = "allwinner,sun4i-a10-musb";
-			reg = <0x01c13000 0x0400>;
-			clocks = <&ahb_gates 0>;
-			interrupts = <38>;
-			interrupt-names = "mc";
-			phys = <&usbphy 0>;
-			phy-names = "usb";
-			extcon = <&usbphy 0>;
-			allwinner,sram = <&otg_sram 1>;
-			status = "disabled";
-
-			dr_mode = "otg";
-		};
-
-		usbphy: phy@01c13400 {
-			#phy-cells = <1>;
-			compatible = "allwinner,sun5i-a13-usb-phy";
-			reg = <0x01c13400 0x10 0x01c14800 0x4>;
-			reg-names = "phy_ctrl", "pmu1";
-			clocks = <&usb_clk 8>;
-			clock-names = "usb_phy";
-			resets = <&usb_clk 0>, <&usb_clk 1>;
-			reset-names = "usb0_reset", "usb1_reset";
-			status = "disabled";
-		};
-
-		ehci0: usb@01c14000 {
-			compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
-			reg = <0x01c14000 0x100>;
-			interrupts = <39>;
-			clocks = <&ahb_gates 1>;
-			phys = <&usbphy 1>;
-			phy-names = "usb";
-			status = "disabled";
-		};
-
-		ohci0: usb@01c14400 {
-			compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
-			reg = <0x01c14400 0x100>;
-			interrupts = <40>;
-			clocks = <&usb_clk 6>, <&ahb_gates 2>;
-			phys = <&usbphy 1>;
-			phy-names = "usb";
-			status = "disabled";
-		};
-
-		spi2: spi@01c17000 {
-			compatible = "allwinner,sun4i-a10-spi";
-			reg = <0x01c17000 0x1000>;
-			interrupts = <12>;
-			clocks = <&ahb_gates 22>, <&spi2_clk>;
-			clock-names = "ahb", "mod";
-			dmas = <&dma SUN4I_DMA_DEDICATED 29>,
-			       <&dma SUN4I_DMA_DEDICATED 28>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		intc: interrupt-controller@01c20400 {
-			compatible = "allwinner,sun4i-a10-ic";
-			reg = <0x01c20400 0x400>;
-			interrupt-controller;
-			#interrupt-cells = <1>;
-		};
-
-		pio: pinctrl@01c20800 {
-			compatible = "nextthing,gr8-pinctrl";
-			reg = <0x01c20800 0x400>;
-			interrupts = <28>;
-			clocks = <&apb0_gates 5>;
-			gpio-controller;
-			interrupt-controller;
-			#interrupt-cells = <3>;
-			#gpio-cells = <3>;
-
-			i2c0_pins_a: i2c0@0 {
-				allwinner,pins = "PB0", "PB1";
-				allwinner,function = "i2c0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			i2c1_pins_a: i2c1@0 {
-				allwinner,pins = "PB15", "PB16";
-				allwinner,function = "i2c1";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			i2c2_pins_a: i2c2@0 {
-				allwinner,pins = "PB17", "PB18";
-				allwinner,function = "i2c2";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			i2s0_data_pins_a: i2s0-data@0 {
-				allwinner,pins = "PB6", "PB7", "PB8", "PB9";
-				allwinner,function = "i2s0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			i2s0_mclk_pins_a: i2s0-mclk@0 {
-				allwinner,pins = "PB6", "PB7", "PB8", "PB9";
-				allwinner,function = "i2s0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			ir0_rx_pins_a: ir0@0 {
-				allwinner,pins = "PB4";
-				allwinner,function = "ir0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			lcd_rgb666_pins: lcd-rgb666@0 {
-				allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
-						 "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
-						 "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
-						 "PD24", "PD25", "PD26", "PD27";
-				allwinner,function = "lcd0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			mmc0_pins_a: mmc0@0 {
-				allwinner,pins = "PF0", "PF1", "PF2", "PF3",
-						 "PF4", "PF5";
-				allwinner,function = "mmc0";
-				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			nand_pins_a: nand-base0@0 {
-				allwinner,pins = "PC0", "PC1", "PC2",
-						"PC5", "PC8", "PC9", "PC10",
-						"PC11", "PC12", "PC13", "PC14",
-						"PC15";
-				allwinner,function = "nand0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			nand_cs0_pins_a: nand-cs@0 {
-				allwinner,pins = "PC4";
-				allwinner,function = "nand0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			nand_rb0_pins_a: nand-rb@0 {
-				allwinner,pins = "PC6";
-				allwinner,function = "nand0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			pwm0_pins_a: pwm0@0 {
-				allwinner,pins = "PB2";
-				allwinner,function = "pwm0";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			spdif_tx_pins_a: spdif@0 {
-				allwinner,pins = "PB10";
-				allwinner,function = "spdif";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
-			};
-
-			uart1_pins_a: uart1@1 {
-				allwinner,pins = "PG3", "PG4";
-				allwinner,function = "uart1";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-
-			uart1_cts_rts_pins_a: uart1-cts-rts@0 {
-				allwinner,pins = "PG5", "PG6";
-				allwinner,function = "uart1";
-				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-			};
-		};
-
-		pwm: pwm@01c20e00 {
-			compatible = "allwinner,sun5i-a10s-pwm";
-			reg = <0x01c20e00 0xc>;
-			clocks = <&osc24M>;
-			#pwm-cells = <3>;
-			status = "disabled";
-		};
-
-		timer@01c20c00 {
-			compatible = "allwinner,sun4i-a10-timer";
-			reg = <0x01c20c00 0x90>;
-			interrupts = <22>;
-			clocks = <&osc24M>;
-		};
-
-		wdt: watchdog@01c20c90 {
-			compatible = "allwinner,sun4i-a10-wdt";
-			reg = <0x01c20c90 0x10>;
-		};
-
-		spdif: spdif@01c21000 {
-			#sound-dai-cells = <0>;
-			compatible = "allwinner,sun4i-a10-spdif";
-			reg = <0x01c21000 0x400>;
-			interrupts = <13>;
-			clocks = <&apb0_gates 1>, <&spdif_clk>;
-			clock-names = "apb", "spdif";
-			dmas = <&dma SUN4I_DMA_NORMAL 2>,
-			       <&dma SUN4I_DMA_NORMAL 2>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-		};
-
-		ir0: ir@01c21800 {
-			compatible = "allwinner,sun4i-a10-ir";
-			clocks = <&apb0_gates 6>, <&ir0_clk>;
-			clock-names = "apb", "ir";
-			interrupts = <5>;
-			reg = <0x01c21800 0x40>;
-			status = "disabled";
-		};
-
-		i2s0: i2s@01c22400 {
-			#sound-dai-cells = <0>;
-			compatible = "allwinner,sun4i-a10-i2s";
-			reg = <0x01c22400 0x400>;
-			interrupts = <16>;
-			clocks = <&apb0_gates 3>, <&i2s0_clk>;
-			clock-names = "apb", "mod";
-			dmas = <&dma SUN4I_DMA_NORMAL 3>,
-			       <&dma SUN4I_DMA_NORMAL 3>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-		};
-
-		lradc: lradc@01c22800 {
-			compatible = "allwinner,sun4i-a10-lradc-keys";
-			reg = <0x01c22800 0x100>;
-			interrupts = <31>;
-			status = "disabled";
-		};
-
-		codec: codec@01c22c00 {
-			#sound-dai-cells = <0>;
-			compatible = "allwinner,sun4i-a10-codec";
-			reg = <0x01c22c00 0x40>;
-			interrupts = <30>;
-			clocks = <&apb0_gates 0>, <&codec_clk>;
-			clock-names = "apb", "codec";
-			dmas = <&dma SUN4I_DMA_NORMAL 19>,
-			       <&dma SUN4I_DMA_NORMAL 19>;
-			dma-names = "rx", "tx";
-			status = "disabled";
-		};
-
-		rtp: rtp@01c25000 {
-			compatible = "allwinner,sun5i-a13-ts";
-			reg = <0x01c25000 0x100>;
-			interrupts = <29>;
-			#thermal-sensor-cells = <0>;
-		};
-
-		uart1: serial@01c28400 {
-			compatible = "snps,dw-apb-uart";
-			reg = <0x01c28400 0x400>;
-			interrupts = <2>;
-			reg-shift = <2>;
-			reg-io-width = <4>;
-			clocks = <&apb1_gates 17>;
-			status = "disabled";
-		};
-
-		uart2: serial@01c28800 {
-			compatible = "snps,dw-apb-uart";
-			reg = <0x01c28800 0x400>;
-			interrupts = <3>;
-			reg-shift = <2>;
-			reg-io-width = <4>;
-			clocks = <&apb1_gates 18>;
-			status = "disabled";
-		};
-
-		i2c0: i2c@01c2ac00 {
-			compatible = "allwinner,sun4i-a10-i2c";
-			reg = <0x01c2ac00 0x400>;
-			interrupts = <7>;
-			clocks = <&apb1_gates 0>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		i2c1: i2c@01c2b000 {
-			compatible = "allwinner,sun4i-a10-i2c";
-			reg = <0x01c2b000 0x400>;
-			interrupts = <8>;
-			clocks = <&apb1_gates 1>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		i2c2: i2c@01c2b400 {
-			compatible = "allwinner,sun4i-a10-i2c";
-			reg = <0x01c2b400 0x400>;
-			interrupts = <9>;
-			clocks = <&apb1_gates 2>;
-			status = "disabled";
-			#address-cells = <1>;
-			#size-cells = <0>;
-		};
-
-		timer@01c60000 {
-			compatible = "allwinner,sun5i-a13-hstimer";
-			reg = <0x01c60000 0x1000>;
-			interrupts = <82>, <83>;
-			clocks = <&ahb_gates 28>;
-		};
-
-		fe0: display-frontend@01e00000 {
-			compatible = "allwinner,sun5i-a13-display-frontend";
-			reg = <0x01e00000 0x20000>;
-			interrupts = <47>;
-			clocks = <&ahb_gates 46>, <&de_fe_clk>,
-				 <&dram_gates 25>;
-			clock-names = "ahb", "mod",
-				      "ram";
-			resets = <&de_fe_clk>;
-			status = "disabled";
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				fe0_out: port@1 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <1>;
-
-					fe0_out_be0: endpoint@0 {
-						reg = <0>;
-						remote-endpoint = <&be0_in_fe0>;
-					};
-				};
-			};
-		};
-
-		be0: display-backend@01e60000 {
-			compatible = "allwinner,sun5i-a13-display-backend";
-			reg = <0x01e60000 0x10000>;
-			clocks = <&ahb_gates 44>, <&de_be_clk>,
-				 <&dram_gates 26>;
-			clock-names = "ahb", "mod",
-				      "ram";
-			resets = <&de_be_clk>;
-			status = "disabled";
-
-			assigned-clocks = <&de_be_clk>;
-			assigned-clock-rates = <300000000>;
-
-			ports {
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				be0_in: port@0 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <0>;
-
-					be0_in_fe0: endpoint@0 {
-						reg = <0>;
-						remote-endpoint = <&fe0_out_be0>;
-					};
-				};
-
-				be0_out: port@1 {
-					#address-cells = <1>;
-					#size-cells = <0>;
-					reg = <1>;
-
-					be0_out_tcon0: endpoint@0 {
-						reg = <0>;
-						remote-endpoint = <&tcon0_in_be0>;
-					};
-				};
-			};
-		};
-	};
-};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/ntc-gr8-evb.dts linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/ntc-gr8-evb.dts
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/ntc-gr8-evb.dts	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/ntc-gr8-evb.dts	1969-12-31 19:00:00.000000000 -0500
@@ -1,342 +0,0 @@
-/*
- * Copyright 2016 Free Electrons
- * Copyright 2016 NextThing Co
- *
- * Mylène Josserand <mylene.josserand@free-electrons.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file 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 file 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.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-#include "ntc-gr8.dtsi"
-#include "sunxi-common-regulators.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
-/ {
-	model = "NextThing GR8-EVB";
-	compatible = "nextthing,gr8-evb", "nextthing,gr8";
-
-	aliases {
-		i2c0 = &i2c0;
-		i2c1 = &i2c1;
-		i2c2 = &i2c2;
-		serial0 = &uart1;
-		serial1 = &uart2;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-
-	backlight: backlight {
-		compatible = "pwm-backlight";
-		pwms = <&pwm 0 10000 0>;
-		enable-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
-
-		brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
-		default-brightness-level = <8>;
-	};
-};
-
-&be0 {
-	status = "okay";
-};
-
-&codec {
-	status = "okay";
-};
-
-&ehci0 {
-	status = "okay";
-};
-
-&i2c0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c0_pins_a>;
-	status = "okay";
-
-	axp209: pmic@34 {
-		reg = <0x34>;
-
-		/*
-		* The interrupt is routed through the "External Fast
-		* Interrupt Request" pin (ball G13 of the module)
-		* directly to the main interrupt controller, without
-		* any other controller interfering.
-		*/
-		interrupts = <0>;
-	};
-};
-
-#include "axp209.dtsi"
-
-&i2c1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c1_pins_a>;
-	status = "okay";
-
-	wm8978: codec@1a {
-		#sound-dai-cells = <0>;
-		compatible = "wlf,wm8978";
-		reg = <0x1a>;
-	};
-
-	pcf8563: rtc@51 {
-		compatible = "phg,pcf8563";
-		reg = <0x51>;
-	};
-};
-
-&i2c2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c2_pins_a>;
-	status = "okay";
-};
-
-&i2s0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
-	status = "okay";
-};
-
-&ir0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&ir0_rx_pins_a>;
-	status = "okay";
-};
-
-&lradc {
-	vref-supply = <&reg_ldo2>;
-	status = "okay";
-
-	button@190 {
-		label = "Volume Up";
-		linux,code = <KEY_VOLUMEUP>;
-		channel = <0>;
-		voltage = <190000>;
-	};
-
-	button@390 {
-		label = "Volume Down";
-		linux,code = <KEY_VOLUMEDOWN>;
-		channel = <0>;
-		voltage = <390000>;
-	};
-
-	button@600 {
-		label = "Menu";
-		linux,code = <KEY_MENU>;
-		channel = <0>;
-		voltage = <600000>;
-	};
-
-	button@800 {
-		label = "Search";
-		linux,code = <KEY_SEARCH>;
-		channel = <0>;
-		voltage = <800000>;
-	};
-
-	button@980 {
-		label = "Home";
-		linux,code = <KEY_HOMEPAGE>;
-		channel = <0>;
-		voltage = <980000>;
-	};
-
-	button@1180 {
-		label = "Esc";
-		linux,code = <KEY_ESC>;
-		channel = <0>;
-		voltage = <1180000>;
-	};
-
-	button@1400 {
-		label = "Enter";
-		linux,code = <KEY_ENTER>;
-		channel = <0>;
-		voltage = <1400000>;
-	};
-};
-
-&mmc0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gr8_evb>;
-	vmmc-supply = <&reg_vcc3v3>;
-	bus-width = <4>;
-	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
-	cd-inverted;
-	status = "okay";
-};
-
-&nfc {
-	pinctrl-names = "default";
-	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
-
-	/* MLC Support sucks for now */
-	status = "disabled";
-};
-
-&ohci0 {
-	status = "okay";
-};
-
-&otg_sram {
-	status = "okay";
-};
-
-&pio {
-	mmc0_cd_pin_gr8_evb: mmc0-cd-pin@0 {
-		allwinner,pins = "PG0";
-		allwinner,function = "gpio_in";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	usb0_id_pin_gr8_evb: usb0-id-pin@0 {
-		allwinner,pins = "PG2";
-		allwinner,function = "gpio_in";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	usb0_vbus_det_pin_gr8_evb: usb0-vbus-det-pin@0 {
-		allwinner,pins = "PG1";
-		allwinner,function = "gpio_in";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-
-	usb1_vbus_pin_gr8_evb: usb1-vbus-pin@0 {
-		allwinner,pins = "PG13";
-		allwinner,function = "gpio_out";
-		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
-		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
-	};
-};
-
-&pwm {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pwm0_pins_a>;
-	status = "okay";
-};
-
-&reg_dcdc2 {
-	regulator-min-microvolt = <1000000>;
-	regulator-max-microvolt = <1400000>;
-	regulator-name = "vdd-cpu";
-	regulator-always-on;
-};
-
-&reg_dcdc3 {
-	regulator-min-microvolt = <1000000>;
-	regulator-max-microvolt = <1300000>;
-	regulator-name = "vdd-sys";
-	regulator-always-on;
-};
-
-&reg_ldo1 {
-	regulator-name = "vdd-rtc";
-};
-
-&reg_ldo2 {
-	regulator-min-microvolt = <2700000>;
-	regulator-max-microvolt = <3300000>;
-	regulator-name = "avcc";
-	regulator-always-on;
-};
-
-&reg_usb1_vbus {
-	pinctrl-0 = <&usb1_vbus_pin_gr8_evb>;
-	gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
-	status = "okay";
-};
-
-&rtp {
-	allwinner,ts-attached;
-};
-
-&spdif {
-	pinctrl-names = "default";
-	pinctrl-0 = <&spdif_tx_pins_a>;
-	status = "okay";
-};
-
-&tve0 {
-	status = "okay";
-};
-
-&uart1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
-	status = "okay";
-};
-
-&usb_otg {
-	/*
-	 * The GR8-EVB has a somewhat interesting design. There's a
-	 * pin supposed to control VBUS, an ID pin, a VBUS detect pin,
-	 * so everything should work just fine.
-	 *
-	 * Except that the pin supposed to control VBUS is not
-	 * connected to any controllable output, neither to the SoC
-	 * through a GPIO or to the PMIC, and it is pulled down,
-	 * meaning that we will never be able to enable VBUS on this
-	 * board.
-	 */
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&usb_power_supply {
-	status = "okay";
-};
-
-&usbphy {
-	pinctrl-names = "default";
-	pinctrl-0 = <&usb0_id_pin_gr8_evb>, <&usb0_vbus_det_pin_gr8_evb>;
-	usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
-	usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
-	usb0_vbus_power-supply = <&usb_power_supply>;
-	usb1_vbus-supply = <&reg_usb1_vbus>;
-	status = "okay";
-};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/stih407-family.dtsi linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/stih407-family.dtsi
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/stih407-family.dtsi	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/stih407-family.dtsi	2016-12-04 15:50:51.000000000 -0500
@@ -283,6 +283,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c0_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -296,6 +298,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c1_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -309,6 +313,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c2_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -322,6 +328,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c3_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -335,6 +343,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c4_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -348,6 +358,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c5_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -363,6 +375,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c10_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
@@ -376,6 +390,8 @@
 			clock-frequency = <400000>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_i2c11_default>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 
 			status = "disabled";
 		};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/sun5i-gr8.dtsi linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun5i-gr8.dtsi
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/sun5i-gr8.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun5i-gr8.dtsi	2016-12-04 15:50:51.000000000 -0500
@@ -0,0 +1,1087 @@
+/*
+ * Copyright 2016 Mylène Josserand
+ *
+ * Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library 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 library 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/clock/sun4i-a10-pll2.h>
+#include <dt-bindings/dma/sun4i-a10.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	interrupt-parent = <&intc>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a8";
+			reg = <0x0>;
+			clocks = <&cpu>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/*
+		 * This is a dummy clock, to be used as placeholder on
+		 * other mux clocks when a specific parent clock is not
+		 * yet implemented. It should be dropped when the driver
+		 * is complete.
+		 */
+		dummy: dummy {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+
+		osc24M: clk@01c20050 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-osc-clk";
+			reg = <0x01c20050 0x4>;
+			clock-frequency = <24000000>;
+			clock-output-names = "osc24M";
+		};
+
+		osc3M: osc3M-clk {
+			compatible = "fixed-factor-clock";
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+			clocks = <&osc24M>;
+			clock-output-names = "osc3M";
+		};
+
+		osc32k: clk@0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+			clock-output-names = "osc32k";
+		};
+
+		pll1: clk@01c20000 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-pll1-clk";
+			reg = <0x01c20000 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll1";
+		};
+
+		pll2: clk@01c20008 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun5i-a13-pll2-clk";
+			reg = <0x01c20008 0x8>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll2-1x", "pll2-2x",
+					     "pll2-4x", "pll2-8x";
+		};
+
+		pll3: clk@01c20010 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-pll3-clk";
+			reg = <0x01c20010 0x4>;
+			clocks = <&osc3M>;
+			clock-output-names = "pll3";
+		};
+
+		pll3x2: pll3x2-clk {
+			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
+			#clock-cells = <0>;
+			clock-div = <1>;
+			clock-mult = <2>;
+			clocks = <&pll3>;
+			clock-output-names = "pll3-2x";
+		};
+
+		pll4: clk@01c20018 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-pll1-clk";
+			reg = <0x01c20018 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll4";
+		};
+
+		pll5: clk@01c20020 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-pll5-clk";
+			reg = <0x01c20020 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll5_ddr", "pll5_other";
+		};
+
+		pll6: clk@01c20028 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-pll6-clk";
+			reg = <0x01c20028 0x4>;
+			clocks = <&osc24M>;
+			clock-output-names = "pll6_sata", "pll6_other", "pll6";
+		};
+
+		pll7: clk@01c20030 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-pll3-clk";
+			reg = <0x01c20030 0x4>;
+			clocks = <&osc3M>;
+			clock-output-names = "pll7";
+		};
+
+		pll7x2: pll7x2-clk {
+			compatible = "allwinner,sun4i-a10-pll3-2x-clk";
+			#clock-cells = <0>;
+			clock-div = <1>;
+			clock-mult = <2>;
+			clocks = <&pll7>;
+			clock-output-names = "pll7-2x";
+		};
+
+		/* dummy is 200M */
+		cpu: cpu@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-cpu-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+			clock-output-names = "cpu";
+		};
+
+		axi: axi@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-axi-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&cpu>;
+			clock-output-names = "axi";
+		};
+
+		ahb: ahb@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun5i-a13-ahb-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&axi>, <&cpu>, <&pll6 1>;
+			clock-output-names = "ahb";
+			/*
+			 * Use PLL6 as parent, instead of CPU/AXI
+			 * which has rate changes due to cpufreq
+			 */
+			assigned-clocks = <&ahb>;
+			assigned-clock-parents = <&pll6 1>;
+		};
+
+		apb0: apb0@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-apb0-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&ahb>;
+			clock-output-names = "apb0";
+		};
+
+		apb1: clk@01c20058 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-apb1-clk";
+			reg = <0x01c20058 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
+			clock-output-names = "apb1";
+		};
+
+		axi_gates: clk@01c2005c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-gates-clk";
+			reg = <0x01c2005c 0x4>;
+			clocks = <&axi>;
+			clock-indices = <0>;
+			clock-output-names = "axi_dram";
+		};
+
+		ahb_gates: clk@01c20060 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun5i-a13-ahb-gates-clk";
+			reg = <0x01c20060 0x8>;
+			clocks = <&ahb>;
+			clock-indices = <0>, <1>,
+					<2>, <5>, <6>,
+					<7>, <8>, <9>,
+					<10>, <13>,
+					<14>, <17>, <20>,
+					<21>, <22>,
+					<28>, <32>, <34>,
+					<36>, <40>, <44>,
+					<46>, <51>,
+					<52>;
+			clock-output-names = "ahb_usbotg", "ahb_ehci",
+					     "ahb_ohci", "ahb_ss", "ahb_dma",
+					     "ahb_bist", "ahb_mmc0", "ahb_mmc1",
+					     "ahb_mmc2", "ahb_nand",
+					     "ahb_sdram", "ahb_emac", "ahb_spi0",
+					     "ahb_spi1", "ahb_spi2",
+					     "ahb_hstimer", "ahb_ve", "ahb_tve",
+					     "ahb_lcd", "ahb_csi", "ahb_de_be",
+					     "ahb_de_fe", "ahb_iep",
+					     "ahb_mali400";
+		};
+
+		apb0_gates: clk@01c20068 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-gates-clk";
+			reg = <0x01c20068 0x4>;
+			clocks = <&apb0>;
+			clock-indices = <0>, <3>,
+					<5>, <6>;
+			clock-output-names = "apb0_codec", "apb0_i2s0",
+					     "apb0_pio", "apb0_ir";
+		};
+
+		apb1_gates: clk@01c2006c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-gates-clk";
+			reg = <0x01c2006c 0x4>;
+			clocks = <&apb1>;
+			clock-indices = <0>, <1>,
+					<2>, <17>,
+					<18>, <19>;
+			clock-output-names = "apb1_i2c0", "apb1_i2c1",
+					     "apb1_i2c2", "apb1_uart1",
+					     "apb1_uart2", "apb1_uart3";
+		};
+
+		nand_clk: clk@01c20080 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20080 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "nand";
+		};
+
+		ms_clk: clk@01c20084 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20084 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ms";
+		};
+
+		mmc0_clk: clk@01c20088 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
+			reg = <0x01c20088 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc0",
+					     "mmc0_output",
+					     "mmc0_sample";
+		};
+
+		mmc1_clk: clk@01c2008c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
+			reg = <0x01c2008c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc1",
+					     "mmc1_output",
+					     "mmc1_sample";
+		};
+
+		mmc2_clk: clk@01c20090 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-a10-mmc-clk";
+			reg = <0x01c20090 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mmc2",
+					     "mmc2_output",
+					     "mmc2_sample";
+		};
+
+		ts_clk: clk@01c20098 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c20098 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ts";
+		};
+
+		ss_clk: clk@01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ss";
+		};
+
+		spi0_clk: clk@01c200a0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi0";
+		};
+
+		spi1_clk: clk@01c200a4 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a4 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi1";
+		};
+
+		spi2_clk: clk@01c200a8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200a8 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "spi2";
+		};
+
+		ir0_clk: clk@01c200b0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c200b0 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "ir0";
+		};
+
+		i2s0_clk: clk@01c200b8 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod1-clk";
+			reg = <0x01c200b8 0x4>;
+			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
+				 <&pll2 SUN4I_A10_PLL2_4X>,
+				 <&pll2 SUN4I_A10_PLL2_2X>,
+				 <&pll2 SUN4I_A10_PLL2_1X>;
+			clock-output-names = "i2s0";
+		};
+
+		spdif_clk: clk@01c200c0 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod1-clk";
+			reg = <0x01c200c0 0x4>;
+			clocks = <&pll2 SUN4I_A10_PLL2_8X>,
+				 <&pll2 SUN4I_A10_PLL2_4X>,
+				 <&pll2 SUN4I_A10_PLL2_2X>,
+				 <&pll2 SUN4I_A10_PLL2_1X>;
+			clock-output-names = "spdif";
+		};
+
+		usb_clk: clk@01c200cc {
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			compatible = "allwinner,sun5i-a13-usb-clk";
+			reg = <0x01c200cc 0x4>;
+			clocks = <&pll6 1>;
+			clock-output-names = "usb_ohci0", "usb_phy";
+		};
+
+		dram_gates: clk@01c20100 {
+			#clock-cells = <1>;
+			compatible = "nextthing,gr8-dram-gates-clk",
+				     "allwinner,sun4i-a10-gates-clk";
+			reg = <0x01c20100 0x4>;
+			clocks = <&pll5 0>;
+			clock-indices = <0>,
+					<1>,
+					<25>,
+					<26>,
+					<29>,
+					<31>;
+			clock-output-names = "dram_ve",
+					     "dram_csi",
+					     "dram_de_fe",
+					     "dram_de_be",
+					     "dram_ace",
+					     "dram_iep";
+		};
+
+		de_be_clk: clk@01c20104 {
+			#clock-cells = <0>;
+			#reset-cells = <0>;
+			compatible = "allwinner,sun4i-a10-display-clk";
+			reg = <0x01c20104 0x4>;
+			clocks = <&pll3>, <&pll7>, <&pll5 1>;
+			clock-output-names = "de-be";
+		};
+
+		de_fe_clk: clk@01c2010c {
+			#clock-cells = <0>;
+			#reset-cells = <0>;
+			compatible = "allwinner,sun4i-a10-display-clk";
+			reg = <0x01c2010c 0x4>;
+			clocks = <&pll3>, <&pll7>, <&pll5 1>;
+			clock-output-names = "de-fe";
+		};
+
+		tcon_ch0_clk: clk@01c20118 {
+			#clock-cells = <0>;
+			#reset-cells = <1>;
+			compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
+			reg = <0x01c20118 0x4>;
+			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
+			clock-output-names = "tcon-ch0-sclk";
+		};
+
+		tcon_ch1_clk: clk@01c2012c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
+			reg = <0x01c2012c 0x4>;
+			clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
+			clock-output-names = "tcon-ch1-sclk";
+		};
+
+		codec_clk: clk@01c20140 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-codec-clk";
+			reg = <0x01c20140 0x4>;
+			clocks = <&pll2 SUN4I_A10_PLL2_1X>;
+			clock-output-names = "codec";
+		};
+
+		mbus_clk: clk@01c2015c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun5i-a13-mbus-clk";
+			reg = <0x01c2015c 0x4>;
+			clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
+			clock-output-names = "mbus";
+		};
+	};
+
+	display-engine {
+		compatible = "allwinner,sun5i-a13-display-engine";
+		allwinner,pipelines = <&fe0>;
+	};
+
+	soc@01c00000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		sram-controller@01c00000 {
+			compatible = "allwinner,sun4i-a10-sram-controller";
+			reg = <0x01c00000 0x30>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			sram_a: sram@00000000 {
+				compatible = "mmio-sram";
+				reg = <0x00000000 0xc000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00000000 0xc000>;
+			};
+
+			sram_d: sram@00010000 {
+				compatible = "mmio-sram";
+				reg = <0x00010000 0x1000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00010000 0x1000>;
+
+				otg_sram: sram-section@0000 {
+					compatible = "allwinner,sun4i-a10-sram-d";
+					reg = <0x0000 0x1000>;
+					status = "disabled";
+				};
+			};
+		};
+
+		dma: dma-controller@01c02000 {
+			compatible = "allwinner,sun4i-a10-dma";
+			reg = <0x01c02000 0x1000>;
+			interrupts = <27>;
+			clocks = <&ahb_gates 6>;
+			#dma-cells = <2>;
+		};
+
+		nfc: nand@01c03000 {
+			compatible = "allwinner,sun4i-a10-nand";
+			reg = <0x01c03000 0x1000>;
+			interrupts = <37>;
+			clocks = <&ahb_gates 13>, <&nand_clk>;
+			clock-names = "ahb", "mod";
+			dmas = <&dma SUN4I_DMA_DEDICATED 3>;
+			dma-names = "rxtx";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		spi0: spi@01c05000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c05000 0x1000>;
+			interrupts = <10>;
+			clocks = <&ahb_gates 20>, <&spi0_clk>;
+			clock-names = "ahb", "mod";
+			dmas = <&dma SUN4I_DMA_DEDICATED 27>,
+			       <&dma SUN4I_DMA_DEDICATED 26>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		spi1: spi@01c06000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c06000 0x1000>;
+			interrupts = <11>;
+			clocks = <&ahb_gates 21>, <&spi1_clk>;
+			clock-names = "ahb", "mod";
+			dmas = <&dma SUN4I_DMA_DEDICATED 9>,
+			       <&dma SUN4I_DMA_DEDICATED 8>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		tve0: tv-encoder@01c0a000 {
+			compatible = "allwinner,sun4i-a10-tv-encoder";
+			reg = <0x01c0a000 0x1000>;
+			clocks = <&ahb_gates 34>;
+			resets = <&tcon_ch0_clk 0>;
+			status = "disabled";
+
+			port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tve0_in_tcon0: endpoint@0 {
+					reg = <0>;
+					remote-endpoint = <&tcon0_out_tve0>;
+				};
+			};
+		};
+
+		tcon0: lcd-controller@01c0c000 {
+			compatible = "allwinner,sun5i-a13-tcon";
+			reg = <0x01c0c000 0x1000>;
+			interrupts = <44>;
+			resets = <&tcon_ch0_clk 1>;
+			reset-names = "lcd";
+			clocks = <&ahb_gates 36>,
+				 <&tcon_ch0_clk>,
+				 <&tcon_ch1_clk>;
+			clock-names = "ahb",
+				      "tcon-ch0",
+				      "tcon-ch1";
+			clock-output-names = "tcon-pixel-clock";
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				tcon0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					tcon0_in_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_out_tcon0>;
+					};
+				};
+
+				tcon0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					tcon0_out_tve0: endpoint@1 {
+						reg = <1>;
+						remote-endpoint = <&tve0_in_tcon0>;
+					};
+				};
+			};
+		};
+
+		mmc0: mmc@01c0f000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ahb_gates 8>,
+				 <&mmc0_clk 0>,
+				 <&mmc0_clk 1>,
+				 <&mmc0_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			interrupts = <32>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc@01c10000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&ahb_gates 9>,
+				 <&mmc1_clk 0>,
+				 <&mmc1_clk 1>,
+				 <&mmc1_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			interrupts = <33>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc2: mmc@01c11000 {
+			compatible = "allwinner,sun5i-a13-mmc";
+			reg = <0x01c11000 0x1000>;
+			clocks = <&ahb_gates 10>,
+				 <&mmc2_clk 0>,
+				 <&mmc2_clk 1>,
+				 <&mmc2_clk 2>;
+			clock-names = "ahb",
+				      "mmc",
+				      "output",
+				      "sample";
+			interrupts = <34>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		usb_otg: usb@01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			extcon = <&usbphy 0>;
+			allwinner,sram = <&otg_sram 1>;
+			status = "disabled";
+
+			dr_mode = "otg";
+		};
+
+		usbphy: phy@01c13400 {
+			#phy-cells = <1>;
+			compatible = "allwinner,sun5i-a13-usb-phy";
+			reg = <0x01c13400 0x10 0x01c14800 0x4>;
+			reg-names = "phy_ctrl", "pmu1";
+			clocks = <&usb_clk 8>;
+			clock-names = "usb_phy";
+			resets = <&usb_clk 0>, <&usb_clk 1>;
+			reset-names = "usb0_reset", "usb1_reset";
+			status = "disabled";
+		};
+
+		ehci0: usb@01c14000 {
+			compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
+			reg = <0x01c14000 0x100>;
+			interrupts = <39>;
+			clocks = <&ahb_gates 1>;
+			phys = <&usbphy 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		ohci0: usb@01c14400 {
+			compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
+			reg = <0x01c14400 0x100>;
+			interrupts = <40>;
+			clocks = <&usb_clk 6>, <&ahb_gates 2>;
+			phys = <&usbphy 1>;
+			phy-names = "usb";
+			status = "disabled";
+		};
+
+		spi2: spi@01c17000 {
+			compatible = "allwinner,sun4i-a10-spi";
+			reg = <0x01c17000 0x1000>;
+			interrupts = <12>;
+			clocks = <&ahb_gates 22>, <&spi2_clk>;
+			clock-names = "ahb", "mod";
+			dmas = <&dma SUN4I_DMA_DEDICATED 29>,
+			       <&dma SUN4I_DMA_DEDICATED 28>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		intc: interrupt-controller@01c20400 {
+			compatible = "allwinner,sun4i-a10-ic";
+			reg = <0x01c20400 0x400>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		pio: pinctrl@01c20800 {
+			compatible = "nextthing,gr8-pinctrl";
+			reg = <0x01c20800 0x400>;
+			interrupts = <28>;
+			clocks = <&apb0_gates 5>;
+			gpio-controller;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#gpio-cells = <3>;
+
+			i2c0_pins_a: i2c0@0 {
+				allwinner,pins = "PB0", "PB1";
+				allwinner,function = "i2c0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			i2c1_pins_a: i2c1@0 {
+				allwinner,pins = "PB15", "PB16";
+				allwinner,function = "i2c1";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			i2c2_pins_a: i2c2@0 {
+				allwinner,pins = "PB17", "PB18";
+				allwinner,function = "i2c2";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			i2s0_data_pins_a: i2s0-data@0 {
+				allwinner,pins = "PB6", "PB7", "PB8", "PB9";
+				allwinner,function = "i2s0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			i2s0_mclk_pins_a: i2s0-mclk@0 {
+				allwinner,pins = "PB6", "PB7", "PB8", "PB9";
+				allwinner,function = "i2s0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			ir0_rx_pins_a: ir0@0 {
+				allwinner,pins = "PB4";
+				allwinner,function = "ir0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			lcd_rgb666_pins: lcd-rgb666@0 {
+				allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
+						 "PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
+						 "PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
+						 "PD24", "PD25", "PD26", "PD27";
+				allwinner,function = "lcd0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			mmc0_pins_a: mmc0@0 {
+				allwinner,pins = "PF0", "PF1", "PF2", "PF3",
+						 "PF4", "PF5";
+				allwinner,function = "mmc0";
+				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			nand_pins_a: nand-base0@0 {
+				allwinner,pins = "PC0", "PC1", "PC2",
+						"PC5", "PC8", "PC9", "PC10",
+						"PC11", "PC12", "PC13", "PC14",
+						"PC15";
+				allwinner,function = "nand0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			nand_cs0_pins_a: nand-cs@0 {
+				allwinner,pins = "PC4";
+				allwinner,function = "nand0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			nand_rb0_pins_a: nand-rb@0 {
+				allwinner,pins = "PC6";
+				allwinner,function = "nand0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			pwm0_pins_a: pwm0@0 {
+				allwinner,pins = "PB2";
+				allwinner,function = "pwm0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spdif_tx_pins_a: spdif@0 {
+				allwinner,pins = "PB10";
+				allwinner,function = "spdif";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+			};
+
+			uart1_pins_a: uart1@1 {
+				allwinner,pins = "PG3", "PG4";
+				allwinner,function = "uart1";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			uart1_cts_rts_pins_a: uart1-cts-rts@0 {
+				allwinner,pins = "PG5", "PG6";
+				allwinner,function = "uart1";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+		};
+
+		pwm: pwm@01c20e00 {
+			compatible = "allwinner,sun5i-a10s-pwm";
+			reg = <0x01c20e00 0xc>;
+			clocks = <&osc24M>;
+			#pwm-cells = <3>;
+			status = "disabled";
+		};
+
+		timer@01c20c00 {
+			compatible = "allwinner,sun4i-a10-timer";
+			reg = <0x01c20c00 0x90>;
+			interrupts = <22>;
+			clocks = <&osc24M>;
+		};
+
+		wdt: watchdog@01c20c90 {
+			compatible = "allwinner,sun4i-a10-wdt";
+			reg = <0x01c20c90 0x10>;
+		};
+
+		spdif: spdif@01c21000 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun4i-a10-spdif";
+			reg = <0x01c21000 0x400>;
+			interrupts = <13>;
+			clocks = <&apb0_gates 1>, <&spdif_clk>;
+			clock-names = "apb", "spdif";
+			dmas = <&dma SUN4I_DMA_NORMAL 2>,
+			       <&dma SUN4I_DMA_NORMAL 2>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		ir0: ir@01c21800 {
+			compatible = "allwinner,sun4i-a10-ir";
+			clocks = <&apb0_gates 6>, <&ir0_clk>;
+			clock-names = "apb", "ir";
+			interrupts = <5>;
+			reg = <0x01c21800 0x40>;
+			status = "disabled";
+		};
+
+		i2s0: i2s@01c22400 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun4i-a10-i2s";
+			reg = <0x01c22400 0x400>;
+			interrupts = <16>;
+			clocks = <&apb0_gates 3>, <&i2s0_clk>;
+			clock-names = "apb", "mod";
+			dmas = <&dma SUN4I_DMA_NORMAL 3>,
+			       <&dma SUN4I_DMA_NORMAL 3>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		lradc: lradc@01c22800 {
+			compatible = "allwinner,sun4i-a10-lradc-keys";
+			reg = <0x01c22800 0x100>;
+			interrupts = <31>;
+			status = "disabled";
+		};
+
+		codec: codec@01c22c00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun4i-a10-codec";
+			reg = <0x01c22c00 0x40>;
+			interrupts = <30>;
+			clocks = <&apb0_gates 0>, <&codec_clk>;
+			clock-names = "apb", "codec";
+			dmas = <&dma SUN4I_DMA_NORMAL 19>,
+			       <&dma SUN4I_DMA_NORMAL 19>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		rtp: rtp@01c25000 {
+			compatible = "allwinner,sun5i-a13-ts";
+			reg = <0x01c25000 0x100>;
+			interrupts = <29>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		uart1: serial@01c28400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28400 0x400>;
+			interrupts = <2>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 17>;
+			status = "disabled";
+		};
+
+		uart2: serial@01c28800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28800 0x400>;
+			interrupts = <3>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 18>;
+			status = "disabled";
+		};
+
+		i2c0: i2c@01c2ac00 {
+			compatible = "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <7>;
+			clocks = <&apb1_gates 0>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c@01c2b000 {
+			compatible = "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <8>;
+			clocks = <&apb1_gates 1>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c2: i2c@01c2b400 {
+			compatible = "allwinner,sun4i-a10-i2c";
+			reg = <0x01c2b400 0x400>;
+			interrupts = <9>;
+			clocks = <&apb1_gates 2>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		timer@01c60000 {
+			compatible = "allwinner,sun5i-a13-hstimer";
+			reg = <0x01c60000 0x1000>;
+			interrupts = <82>, <83>;
+			clocks = <&ahb_gates 28>;
+		};
+
+		fe0: display-frontend@01e00000 {
+			compatible = "allwinner,sun5i-a13-display-frontend";
+			reg = <0x01e00000 0x20000>;
+			interrupts = <47>;
+			clocks = <&ahb_gates 46>, <&de_fe_clk>,
+				 <&dram_gates 25>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_fe_clk>;
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				fe0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					fe0_out_be0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&be0_in_fe0>;
+					};
+				};
+			};
+		};
+
+		be0: display-backend@01e60000 {
+			compatible = "allwinner,sun5i-a13-display-backend";
+			reg = <0x01e60000 0x10000>;
+			clocks = <&ahb_gates 44>, <&de_be_clk>,
+				 <&dram_gates 26>;
+			clock-names = "ahb", "mod",
+				      "ram";
+			resets = <&de_be_clk>;
+			status = "disabled";
+
+			assigned-clocks = <&de_be_clk>;
+			assigned-clock-rates = <300000000>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				be0_in: port@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					be0_in_fe0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&fe0_out_be0>;
+					};
+				};
+
+				be0_out: port@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+
+					be0_out_tcon0: endpoint@0 {
+						reg = <0>;
+						remote-endpoint = <&tcon0_in_be0>;
+					};
+				};
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/sun5i-gr8-evb.dts linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun5i-gr8-evb.dts
--- linux-libre-4.9-rc7-gnu/arch/arm/boot/dts/sun5i-gr8-evb.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun5i-gr8-evb.dts	2016-12-04 15:50:51.000000000 -0500
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2016 Free Electrons
+ * Copyright 2016 NextThing Co
+ *
+ * Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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 file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-gr8.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "NextThing GR8-EVB";
+	compatible = "nextthing,gr8-evb", "nextthing,gr8";
+
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		serial0 = &uart1;
+		serial1 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 10000 0>;
+		enable-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
+
+		brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
+		default-brightness-level = <8>;
+	};
+};
+
+&be0 {
+	status = "okay";
+};
+
+&codec {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic@34 {
+		reg = <0x34>;
+
+		/*
+		* The interrupt is routed through the "External Fast
+		* Interrupt Request" pin (ball G13 of the module)
+		* directly to the main interrupt controller, without
+		* any other controller interfering.
+		*/
+		interrupts = <0>;
+	};
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+
+	wm8978: codec@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8978";
+		reg = <0x1a>;
+	};
+
+	pcf8563: rtc@51 {
+		compatible = "phg,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+};
+
+&i2s0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
+	status = "okay";
+};
+
+&ir0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ir0_rx_pins_a>;
+	status = "okay";
+};
+
+&lradc {
+	vref-supply = <&reg_ldo2>;
+	status = "okay";
+
+	button@190 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <190000>;
+	};
+
+	button@390 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <390000>;
+	};
+
+	button@600 {
+		label = "Menu";
+		linux,code = <KEY_MENU>;
+		channel = <0>;
+		voltage = <600000>;
+	};
+
+	button@800 {
+		label = "Search";
+		linux,code = <KEY_SEARCH>;
+		channel = <0>;
+		voltage = <800000>;
+	};
+
+	button@980 {
+		label = "Home";
+		linux,code = <KEY_HOMEPAGE>;
+		channel = <0>;
+		voltage = <980000>;
+	};
+
+	button@1180 {
+		label = "Esc";
+		linux,code = <KEY_ESC>;
+		channel = <0>;
+		voltage = <1180000>;
+	};
+
+	button@1400 {
+		label = "Enter";
+		linux,code = <KEY_ENTER>;
+		channel = <0>;
+		voltage = <1400000>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gr8_evb>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+	cd-inverted;
+	status = "okay";
+};
+
+&nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
+
+	/* MLC Support sucks for now */
+	status = "disabled";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_gr8_evb: mmc0-cd-pin@0 {
+		allwinner,pins = "PG0";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_id_pin_gr8_evb: usb0-id-pin@0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_vbus_det_pin_gr8_evb: usb0-vbus-det-pin@0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb1_vbus_pin_gr8_evb: usb1-vbus-pin@0 {
+		allwinner,pins = "PG13";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm0_pins_a>;
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+	regulator-always-on;
+};
+
+&reg_dcdc3 {
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-sys";
+	regulator-always-on;
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-min-microvolt = <2700000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "avcc";
+	regulator-always-on;
+};
+
+&reg_usb1_vbus {
+	pinctrl-0 = <&usb1_vbus_pin_gr8_evb>;
+	gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&rtp {
+	allwinner,ts-attached;
+};
+
+&spdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spdif_tx_pins_a>;
+	status = "okay";
+};
+
+&tve0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
+	status = "okay";
+};
+
+&usb_otg {
+	/*
+	 * The GR8-EVB has a somewhat interesting design. There's a
+	 * pin supposed to control VBUS, an ID pin, a VBUS detect pin,
+	 * so everything should work just fine.
+	 *
+	 * Except that the pin supposed to control VBUS is not
+	 * connected to any controllable output, neither to the SoC
+	 * through a GPIO or to the PMIC, and it is pulled down,
+	 * meaning that we will never be able to enable VBUS on this
+	 * board.
+	 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb_power_supply {
+	status = "okay";
+};
+
+&usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_pin_gr8_evb>, <&usb0_vbus_det_pin_gr8_evb>;
+	usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	usb0_vbus_power-supply = <&usb_power_supply>;
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-base.dtsi linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-base.dtsi
--- linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-base.dtsi	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-base.dtsi	2016-12-04 15:50:51.000000000 -0500
@@ -393,7 +393,7 @@
 		#address-cells = <3>;
 		#size-cells = <2>;
 		dma-coherent;
-		ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>,
+		ranges = <0x01000000 0x00 0x00000000 0x00 0x5f800000 0x0 0x00800000>,
 			 <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
 			 <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
 		#interrupt-cells = <1>;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno.dts linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno.dts
--- linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno.dts	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno.dts	2016-12-04 15:50:51.000000000 -0500
@@ -76,7 +76,7 @@
 				compatible = "arm,idle-state";
 				arm,psci-suspend-param = <0x1010000>;
 				local-timer-stop;
-				entry-latency-us = <300>;
+				entry-latency-us = <400>;
 				exit-latency-us = <1200>;
 				min-residency-us = <2500>;
 			};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-r1.dts linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-r1.dts
--- linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-r1.dts	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-r1.dts	2016-12-04 15:50:51.000000000 -0500
@@ -76,7 +76,7 @@
 				compatible = "arm,idle-state";
 				arm,psci-suspend-param = <0x1010000>;
 				local-timer-stop;
-				entry-latency-us = <300>;
+				entry-latency-us = <400>;
 				exit-latency-us = <1200>;
 				min-residency-us = <2500>;
 			};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-r2.dts linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-r2.dts
--- linux-libre-4.9-rc7-gnu/arch/arm64/boot/dts/arm/juno-r2.dts	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/arch/arm64/boot/dts/arm/juno-r2.dts	2016-12-04 15:50:51.000000000 -0500
@@ -76,7 +76,7 @@
 				compatible = "arm,idle-state";
 				arm,psci-suspend-param = <0x1010000>;
 				local-timer-stop;
-				entry-latency-us = <300>;
+				entry-latency-us = <400>;
 				exit-latency-us = <1200>;
 				min-residency-us = <2500>;
 			};
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/CREDITS linux-libre-4.9-rc8-gnu/CREDITS
--- linux-libre-4.9-rc7-gnu/CREDITS	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/CREDITS	2016-12-04 15:50:51.000000000 -0500
@@ -9,7 +9,7 @@
 			Linus
 ----------
 
-M: Matt Mackal
+N: Matt Mackal
 E: mpm@selenic.com
 D: SLOB slab allocator
 
@@ -1910,7 +1910,7 @@ S: Ra'annana, Israel
 
 N: Andi Kleen
 E: andi@firstfloor.org
-U: http://www.halobates.de
+W: http://www.halobates.de
 D: network, x86, NUMA, various hacks
 S: Schwalbenstr. 96
 S: 85551 Ottobrunn
@@ -2089,8 +2089,8 @@ D: ST Microelectronics SPEAr13xx PCI hos
 D: Synopsys Designware PCI host bridge driver
 
 N: Gabor Kuti
-M: seasons@falcon.sch.bme.hu
-M: seasons@makosteszta.sote.hu
+E: seasons@falcon.sch.bme.hu
+E: seasons@makosteszta.sote.hu
 D: Original author of software suspend
 
 N: Jaroslav Kysela
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/Documentation/devicetree/bindings/net/ethernet.txt linux-libre-4.9-rc8-gnu/Documentation/devicetree/bindings/net/ethernet.txt
--- linux-libre-4.9-rc7-gnu/Documentation/devicetree/bindings/net/ethernet.txt	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/Documentation/devicetree/bindings/net/ethernet.txt	2016-12-04 15:50:51.000000000 -0500
@@ -9,10 +9,26 @@ The following properties are common to t
 - max-speed: number, specifies maximum speed in Mbit/s supported by the device;
 - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
   the maximum frame size (there's contradiction in ePAPR).
-- phy-mode: string, operation mode of the PHY interface; supported values are
-  "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
-  "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii", "trgmii"; this is now a
-  de-facto standard property;
+- phy-mode: string, operation mode of the PHY interface. This is now a de-facto
+  standard property; supported values are:
+  * "mii"
+  * "gmii"
+  * "sgmii"
+  * "qsgmii"
+  * "tbi"
+  * "rev-mii"
+  * "rmii"
+  * "rgmii" (RX and TX delays are added by the MAC when required)
+  * "rgmii-id" (RGMII with internal RX and TX delays provided by the PHY, the
+     MAC should not add the RX or TX delays in this case)
+  * "rgmii-rxid" (RGMII with internal RX delay provided by the PHY, the MAC
+     should not add an RX delay in this case)
+  * "rgmii-txid" (RGMII with internal TX delay provided by the PHY, the MAC
+     should not add an TX delay in this case)
+  * "rtbi"
+  * "smii"
+  * "xgmii"
+  * "trgmii"
 - phy-connection-type: the same as "phy-mode" property but described in ePAPR;
 - phy-handle: phandle, specifies a reference to a node representing a PHY
   device; this property is described in ePAPR and so preferred;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/Documentation/networking/nf_conntrack-sysctl.txt linux-libre-4.9-rc8-gnu/Documentation/networking/nf_conntrack-sysctl.txt
--- linux-libre-4.9-rc7-gnu/Documentation/networking/nf_conntrack-sysctl.txt	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/Documentation/networking/nf_conntrack-sysctl.txt	2016-12-04 15:50:51.000000000 -0500
@@ -62,10 +62,13 @@ nf_conntrack_generic_timeout - INTEGER (
 	protocols.
 
 nf_conntrack_helper - BOOLEAN
-	0 - disabled
-	not 0 - enabled (default)
+	0 - disabled (default)
+	not 0 - enabled
 
 	Enable automatic conntrack helper assignment.
+	If disabled it is required to set up iptables rules to assign
+	helpers to connections.  See the CT target description in the
+	iptables-extensions(8) man page for further information.
 
 nf_conntrack_icmp_timeout - INTEGER (seconds)
 	default 30
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/ata/ahci.c linux-libre-4.9-rc8-gnu/drivers/ata/ahci.c
--- linux-libre-4.9-rc7-gnu/drivers/ata/ahci.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/ata/ahci.c	2016-12-04 15:50:51.000000000 -0500
@@ -1436,13 +1436,6 @@ static int ahci_init_msi(struct pci_dev
 				"ahci: MRSM is on, fallback to single MSI\n");
 			pci_free_irq_vectors(pdev);
 		}
-
-		/*
-		 * -ENOSPC indicated we don't have enough vectors.  Don't bother
-		 * trying a single vectors for any other error:
-		 */
-		if (nvec < 0 && nvec != -ENOSPC)
-			return nvec;
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/ata/libata-scsi.c linux-libre-4.9-rc8-gnu/drivers/ata/libata-scsi.c
--- linux-libre-4.9-rc7-gnu/drivers/ata/libata-scsi.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/ata/libata-scsi.c	2016-12-04 15:50:51.000000000 -0500
@@ -1088,7 +1088,7 @@ static void ata_gen_passthru_sense(struc
 		desc[1] = tf->command; /* status */
 		desc[2] = tf->device;
 		desc[3] = tf->nsect;
-		desc[0] = 0;
+		desc[7] = 0;
 		if (tf->flags & ATA_TFLAG_LBA48)  {
 			desc[8] |= 0x80;
 			if (tf->hob_nsect)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/block/zram/zram_drv.c linux-libre-4.9-rc8-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-4.9-rc7-gnu/drivers/block/zram/zram_drv.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/block/zram/zram_drv.c	2016-12-04 15:50:51.000000000 -0500
@@ -1403,7 +1403,8 @@ static ssize_t hot_remove_store(struct c
 	zram = idr_find(&zram_index_idr, dev_id);
 	if (zram) {
 		ret = zram_remove(zram);
-		idr_remove(&zram_index_idr, dev_id);
+		if (!ret)
+			idr_remove(&zram_index_idr, dev_id);
 	} else {
 		ret = -ENODEV;
 	}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/clk/bcm/Kconfig linux-libre-4.9-rc8-gnu/drivers/clk/bcm/Kconfig
--- linux-libre-4.9-rc7-gnu/drivers/clk/bcm/Kconfig	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/clk/bcm/Kconfig	2016-12-04 15:50:51.000000000 -0500
@@ -20,7 +20,7 @@ config CLK_BCM_KONA
 
 config COMMON_CLK_IPROC
 	bool "Broadcom iProc clock support"
-	depends on ARCH_BCM_IPROC || COMPILE_TEST
+	depends on ARCH_BCM_IPROC || ARCH_BCM_63XX || COMPILE_TEST
 	depends on COMMON_CLK
 	default ARCH_BCM_IPROC
 	help
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/clk/sunxi-ng/ccu-sun6i-a31.c linux-libre-4.9-rc8-gnu/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
--- linux-libre-4.9-rc7-gnu/drivers/clk/sunxi-ng/ccu-sun6i-a31.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/clk/sunxi-ng/ccu-sun6i-a31.c	2016-12-04 15:50:51.000000000 -0500
@@ -143,7 +143,7 @@ static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(
 					4, 2,	/* K */
 					0, 4,	/* M */
 					21, 0,	/* mux */
-					BIT(31),	/* gate */
+					BIT(31) | BIT(23) | BIT(22), /* gate */
 					BIT(28),	/* lock */
 					CLK_SET_RATE_UNGATE);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/clk/sunxi-ng/ccu-sun8i-a33.c linux-libre-4.9-rc8-gnu/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
--- linux-libre-4.9-rc7-gnu/drivers/clk/sunxi-ng/ccu-sun8i-a33.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/clk/sunxi-ng/ccu-sun8i-a33.c	2016-12-04 15:50:51.000000000 -0500
@@ -131,7 +131,7 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_
 				    8, 4,		/* N */
 				    4, 2,		/* K */
 				    0, 4,		/* M */
-				    BIT(31),		/* gate */
+				    BIT(31) | BIT(23) | BIT(22), /* gate */
 				    BIT(28),		/* lock */
 				    CLK_SET_RATE_UNGATE);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c	2016-12-04 15:50:51.000000000 -0500
@@ -485,7 +485,6 @@ static int amdgpu_atpx_power_state(enum
  */
 static bool amdgpu_atpx_pci_probe_handle(struct pci_dev *pdev)
 {
-	struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
 	acpi_handle dhandle, atpx_handle;
 	acpi_status status;
 
@@ -500,7 +499,6 @@ static bool amdgpu_atpx_pci_probe_handle
 	}
 	amdgpu_atpx_priv.dhandle = dhandle;
 	amdgpu_atpx_priv.atpx.handle = atpx_handle;
-	amdgpu_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
 	return true;
 }
 
@@ -562,17 +560,25 @@ static bool amdgpu_atpx_detect(void)
 	struct pci_dev *pdev = NULL;
 	bool has_atpx = false;
 	int vga_count = 0;
+	bool d3_supported = false;
+	struct pci_dev *parent_pdev;
 
 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
 		vga_count++;
 
 		has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+		parent_pdev = pci_upstream_bridge(pdev);
+		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
 	}
 
 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
 		vga_count++;
 
 		has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
+
+		parent_pdev = pci_upstream_bridge(pdev);
+		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
 	}
 
 	if (has_atpx && vga_count == 2) {
@@ -580,6 +586,7 @@ static bool amdgpu_atpx_detect(void)
 		printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
 		       acpi_method_name);
 		amdgpu_atpx_priv.atpx_detected = true;
+		amdgpu_atpx_priv.bridge_pm_usable = d3_supported;
 		amdgpu_atpx_init();
 		return true;
 	}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c	2016-12-04 15:50:51.000000000 -0500
@@ -2214,6 +2214,7 @@ uint32_t polaris10_get_mac_definition(ui
 int polaris10_process_firmware_header(struct pp_hwmgr *hwmgr)
 {
 	struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smumgr->backend);
+	struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 	uint32_t tmp;
 	int result;
 	bool error = false;
@@ -2233,8 +2234,10 @@ int polaris10_process_firmware_header(st
 			offsetof(SMU74_Firmware_Header, SoftRegisters),
 			&tmp, SMC_RAM_END);
 
-	if (!result)
+	if (!result) {
+		data->soft_regs_start = tmp;
 		smu_data->smu7_data.soft_regs_start = tmp;
+	}
 
 	error |= (0 != result);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/arm/hdlcd_drv.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/arm/hdlcd_drv.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/arm/hdlcd_drv.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/arm/hdlcd_drv.c	2016-12-04 15:50:51.000000000 -0500
@@ -375,7 +375,6 @@ static int hdlcd_drm_bind(struct device
 
 err_fbdev:
 	drm_kms_helper_poll_fini(drm);
-	drm_mode_config_cleanup(drm);
 	drm_vblank_cleanup(drm);
 err_vblank:
 	pm_runtime_disable(drm->dev);
@@ -387,6 +386,7 @@ err_unload:
 	drm_irq_uninstall(drm);
 	of_reserved_mem_device_release(drm->dev);
 err_free:
+	drm_mode_config_cleanup(drm);
 	dev_set_drvdata(dev, NULL);
 	drm_dev_unref(drm);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/drm_ioctl.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/drm_ioctl.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/drm_ioctl.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/drm_ioctl.c	2016-12-04 15:50:51.000000000 -0500
@@ -254,10 +254,12 @@ static int drm_getcap(struct drm_device
 		req->value = dev->mode_config.async_page_flip;
 		break;
 	case DRM_CAP_PAGE_FLIP_TARGET:
-		req->value = 1;
-		drm_for_each_crtc(crtc, dev) {
-			if (!crtc->funcs->page_flip_target)
-				req->value = 0;
+		if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+			req->value = 1;
+			drm_for_each_crtc(crtc, dev) {
+				if (!crtc->funcs->page_flip_target)
+					req->value = 0;
+			}
 		}
 		break;
 	case DRM_CAP_CURSOR_WIDTH:
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/i915/i915_gem.c	2016-12-04 15:50:51.000000000 -0500
@@ -2268,7 +2268,7 @@ i915_gem_object_get_pages_gtt(struct drm
 			page = shmem_read_mapping_page(mapping, i);
 			if (IS_ERR(page)) {
 				ret = PTR_ERR(page);
-				goto err_pages;
+				goto err_sg;
 			}
 		}
 #ifdef CONFIG_SWIOTLB
@@ -2311,8 +2311,9 @@ i915_gem_object_get_pages_gtt(struct drm
 
 	return 0;
 
-err_pages:
+err_sg:
 	sg_mark_end(sg);
+err_pages:
 	for_each_sgt_page(page, sgt_iter, st)
 		put_page(page);
 	sg_free_table(st);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/i915/intel_display.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/i915/intel_display.c	2016-12-04 15:50:51.000000000 -0500
@@ -12260,7 +12260,7 @@ static int intel_crtc_page_flip(struct d
 	intel_crtc->reset_count = i915_reset_count(&dev_priv->gpu_error);
 	if (i915_reset_in_progress_or_wedged(&dev_priv->gpu_error)) {
 		ret = -EIO;
-		goto cleanup;
+		goto unlock;
 	}
 
 	atomic_inc(&intel_crtc->unpin_work_count);
@@ -12352,6 +12352,7 @@ cleanup_unpin:
 	intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
 cleanup_pending:
 	atomic_dec(&intel_crtc->unpin_work_count);
+unlock:
 	mutex_unlock(&dev->struct_mutex);
 cleanup:
 	crtc->primary->fb = old_fb;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/gpu/drm/radeon/radeon_atpx_handler.c linux-libre-4.9-rc8-gnu/drivers/gpu/drm/radeon/radeon_atpx_handler.c
--- linux-libre-4.9-rc7-gnu/drivers/gpu/drm/radeon/radeon_atpx_handler.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/gpu/drm/radeon/radeon_atpx_handler.c	2016-12-04 15:50:51.000000000 -0500
@@ -479,7 +479,6 @@ static int radeon_atpx_power_state(enum
  */
 static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
 {
-	struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
 	acpi_handle dhandle, atpx_handle;
 	acpi_status status;
 
@@ -493,7 +492,6 @@ static bool radeon_atpx_pci_probe_handle
 
 	radeon_atpx_priv.dhandle = dhandle;
 	radeon_atpx_priv.atpx.handle = atpx_handle;
-	radeon_atpx_priv.bridge_pm_usable = parent_pdev && parent_pdev->bridge_d3;
 	return true;
 }
 
@@ -555,11 +553,16 @@ static bool radeon_atpx_detect(void)
 	struct pci_dev *pdev = NULL;
 	bool has_atpx = false;
 	int vga_count = 0;
+	bool d3_supported = false;
+	struct pci_dev *parent_pdev;
 
 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
 		vga_count++;
 
 		has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+
+		parent_pdev = pci_upstream_bridge(pdev);
+		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
 	}
 
 	/* some newer PX laptops mark the dGPU as a non-VGA display device */
@@ -567,6 +570,9 @@ static bool radeon_atpx_detect(void)
 		vga_count++;
 
 		has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+
+		parent_pdev = pci_upstream_bridge(pdev);
+		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
 	}
 
 	if (has_atpx && vga_count == 2) {
@@ -574,6 +580,7 @@ static bool radeon_atpx_detect(void)
 		printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
 		       acpi_method_name);
 		radeon_atpx_priv.atpx_detected = true;
+		radeon_atpx_priv.bridge_pm_usable = d3_supported;
 		radeon_atpx_init();
 		return true;
 	}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/i2c/busses/i2c-octeon-core.c linux-libre-4.9-rc8-gnu/drivers/i2c/busses/i2c-octeon-core.c
--- linux-libre-4.9-rc7-gnu/drivers/i2c/busses/i2c-octeon-core.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/i2c/busses/i2c-octeon-core.c	2016-12-04 15:50:51.000000000 -0500
@@ -381,9 +381,7 @@ static int octeon_i2c_read(struct octeon
 		if (result)
 			return result;
 
-		data[i] = octeon_i2c_data_read(i2c, &result);
-		if (result)
-			return result;
+		data[i] = octeon_i2c_data_read(i2c);
 		if (recv_len && i == 0) {
 			if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
 				return -EPROTO;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/i2c/busses/i2c-octeon-core.h linux-libre-4.9-rc8-gnu/drivers/i2c/busses/i2c-octeon-core.h
--- linux-libre-4.9-rc7-gnu/drivers/i2c/busses/i2c-octeon-core.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/i2c/busses/i2c-octeon-core.h	2016-12-04 15:50:51.000000000 -0500
@@ -5,7 +5,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c-smbus.h>
 #include <linux/io.h>
-#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 
@@ -145,9 +144,9 @@ static inline void octeon_i2c_reg_write(
 	u64 tmp;
 
 	__raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
-
-	readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp, tmp & SW_TWSI_V,
-			   I2C_OCTEON_EVENT_WAIT, i2c->adap.timeout);
+	do {
+		tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+	} while ((tmp & SW_TWSI_V) != 0);
 }
 
 #define octeon_i2c_ctl_write(i2c, val)					\
@@ -164,28 +163,24 @@ static inline void octeon_i2c_reg_write(
  *
  * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
  */
-static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
-				      int *error)
+static inline u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg)
 {
 	u64 tmp;
-	int ret;
 
 	__raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
+	do {
+		tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
+	} while ((tmp & SW_TWSI_V) != 0);
 
-	ret = readq_poll_timeout(i2c->twsi_base + SW_TWSI(i2c), tmp,
-				 tmp & SW_TWSI_V, I2C_OCTEON_EVENT_WAIT,
-				 i2c->adap.timeout);
-	if (error)
-		*error = ret;
 	return tmp & 0xFF;
 }
 
 #define octeon_i2c_ctl_read(i2c)					\
-	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
-#define octeon_i2c_data_read(i2c, error)				\
-	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
+	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL)
+#define octeon_i2c_data_read(i2c)					\
+	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA)
 #define octeon_i2c_stat_read(i2c)					\
-	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
+	octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT)
 
 /**
  * octeon_i2c_read_int - read the TWSI_INT register
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/input/mouse/psmouse-base.c linux-libre-4.9-rc8-gnu/drivers/input/mouse/psmouse-base.c
--- linux-libre-4.9-rc7-gnu/drivers/input/mouse/psmouse-base.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/input/mouse/psmouse-base.c	2016-12-04 15:50:51.000000000 -0500
@@ -1115,10 +1115,6 @@ static int psmouse_extensions(struct psm
 		if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2,
 					 &max_proto, set_properties, true))
 			return PSMOUSE_TOUCHKIT_PS2;
-
-		if (psmouse_try_protocol(psmouse, PSMOUSE_BYD,
-					 &max_proto, set_properties, true))
-			return PSMOUSE_BYD;
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_ucan.h linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_ucan.h
--- linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_ucan.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_ucan.h	2016-12-04 15:50:51.000000000 -0500
@@ -43,11 +43,22 @@ struct __packed pucan_command {
 	u16	args[3];
 };
 
+#define PUCAN_TSLOW_BRP_BITS		10
+#define PUCAN_TSLOW_TSGEG1_BITS		8
+#define PUCAN_TSLOW_TSGEG2_BITS		7
+#define PUCAN_TSLOW_SJW_BITS		7
+
+#define PUCAN_TSLOW_BRP_MASK		((1 << PUCAN_TSLOW_BRP_BITS) - 1)
+#define PUCAN_TSLOW_TSEG1_MASK		((1 << PUCAN_TSLOW_TSGEG1_BITS) - 1)
+#define PUCAN_TSLOW_TSEG2_MASK		((1 << PUCAN_TSLOW_TSGEG2_BITS) - 1)
+#define PUCAN_TSLOW_SJW_MASK		((1 << PUCAN_TSLOW_SJW_BITS) - 1)
+
 /* uCAN TIMING_SLOW command fields */
-#define PUCAN_TSLOW_SJW_T(s, t)		(((s) & 0xf) | ((!!(t)) << 7))
-#define PUCAN_TSLOW_TSEG2(t)		((t) & 0xf)
-#define PUCAN_TSLOW_TSEG1(t)		((t) & 0x3f)
-#define PUCAN_TSLOW_BRP(b)		((b) & 0x3ff)
+#define PUCAN_TSLOW_SJW_T(s, t)		(((s) & PUCAN_TSLOW_SJW_MASK) | \
+								((!!(t)) << 7))
+#define PUCAN_TSLOW_TSEG2(t)		((t) & PUCAN_TSLOW_TSEG2_MASK)
+#define PUCAN_TSLOW_TSEG1(t)		((t) & PUCAN_TSLOW_TSEG1_MASK)
+#define PUCAN_TSLOW_BRP(b)		((b) & PUCAN_TSLOW_BRP_MASK)
 
 struct __packed pucan_timing_slow {
 	__le16	opcode_channel;
@@ -60,11 +71,21 @@ struct __packed pucan_timing_slow {
 	__le16	brp;		/* BaudRate Prescaler */
 };
 
+#define PUCAN_TFAST_BRP_BITS		10
+#define PUCAN_TFAST_TSGEG1_BITS		5
+#define PUCAN_TFAST_TSGEG2_BITS		4
+#define PUCAN_TFAST_SJW_BITS		4
+
+#define PUCAN_TFAST_BRP_MASK		((1 << PUCAN_TFAST_BRP_BITS) - 1)
+#define PUCAN_TFAST_TSEG1_MASK		((1 << PUCAN_TFAST_TSGEG1_BITS) - 1)
+#define PUCAN_TFAST_TSEG2_MASK		((1 << PUCAN_TFAST_TSGEG2_BITS) - 1)
+#define PUCAN_TFAST_SJW_MASK		((1 << PUCAN_TFAST_SJW_BITS) - 1)
+
 /* uCAN TIMING_FAST command fields */
-#define PUCAN_TFAST_SJW(s)		((s) & 0x3)
-#define PUCAN_TFAST_TSEG2(t)		((t) & 0x7)
-#define PUCAN_TFAST_TSEG1(t)		((t) & 0xf)
-#define PUCAN_TFAST_BRP(b)		((b) & 0x3ff)
+#define PUCAN_TFAST_SJW(s)		((s) & PUCAN_TFAST_SJW_MASK)
+#define PUCAN_TFAST_TSEG2(t)		((t) & PUCAN_TFAST_TSEG2_MASK)
+#define PUCAN_TFAST_TSEG1(t)		((t) & PUCAN_TFAST_TSEG1_MASK)
+#define PUCAN_TFAST_BRP(b)		((b) & PUCAN_TFAST_BRP_MASK)
 
 struct __packed pucan_timing_fast {
 	__le16	opcode_channel;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c
--- linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2016-12-04 15:50:51.000000000 -0500
@@ -39,6 +39,7 @@ static struct usb_device_id peak_usb_tab
 	{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
 	{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBFD_PRODUCT_ID)},
 	{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPROFD_PRODUCT_ID)},
+	{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBX6_PRODUCT_ID)},
 	{} /* Terminating entry */
 };
 
@@ -50,6 +51,7 @@ static const struct peak_usb_adapter *co
 	&pcan_usb_pro,
 	&pcan_usb_fd,
 	&pcan_usb_pro_fd,
+	&pcan_usb_x6,
 };
 
 /*
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.h linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.h
--- linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.h	2016-12-04 15:50:51.000000000 -0500
@@ -27,6 +27,7 @@
 #define PCAN_USBPRO_PRODUCT_ID		0x000d
 #define PCAN_USBPROFD_PRODUCT_ID	0x0011
 #define PCAN_USBFD_PRODUCT_ID		0x0012
+#define PCAN_USBX6_PRODUCT_ID		0x0014
 
 #define PCAN_USB_DRIVER_NAME		"peak_usb"
 
@@ -90,6 +91,7 @@ extern const struct peak_usb_adapter pca
 extern const struct peak_usb_adapter pcan_usb_pro;
 extern const struct peak_usb_adapter pcan_usb_fd;
 extern const struct peak_usb_adapter pcan_usb_pro_fd;
+extern const struct peak_usb_adapter pcan_usb_x6;
 
 struct peak_time_ref {
 	struct timeval tv_host_0, tv_host;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_fd.c linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
--- linux-libre-4.9-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb_fd.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_fd.c	2016-12-04 15:50:51.000000000 -0500
@@ -993,24 +993,24 @@ static void pcan_usb_fd_free(struct peak
 static const struct can_bittiming_const pcan_usb_fd_const = {
 	.name = "pcan_usb_fd",
 	.tseg1_min = 1,
-	.tseg1_max = 64,
+	.tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
 	.tseg2_min = 1,
-	.tseg2_max = 16,
-	.sjw_max = 16,
+	.tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
 	.brp_min = 1,
-	.brp_max = 1024,
+	.brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
 	.brp_inc = 1,
 };
 
 static const struct can_bittiming_const pcan_usb_fd_data_const = {
 	.name = "pcan_usb_fd",
 	.tseg1_min = 1,
-	.tseg1_max = 16,
+	.tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
 	.tseg2_min = 1,
-	.tseg2_max = 8,
-	.sjw_max = 4,
+	.tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
 	.brp_min = 1,
-	.brp_max = 1024,
+	.brp_max = (1 << PUCAN_TFAST_BRP_BITS),
 	.brp_inc = 1,
 };
 
@@ -1065,24 +1065,24 @@ const struct peak_usb_adapter pcan_usb_f
 static const struct can_bittiming_const pcan_usb_pro_fd_const = {
 	.name = "pcan_usb_pro_fd",
 	.tseg1_min = 1,
-	.tseg1_max = 64,
+	.tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
 	.tseg2_min = 1,
-	.tseg2_max = 16,
-	.sjw_max = 16,
+	.tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
 	.brp_min = 1,
-	.brp_max = 1024,
+	.brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
 	.brp_inc = 1,
 };
 
 static const struct can_bittiming_const pcan_usb_pro_fd_data_const = {
 	.name = "pcan_usb_pro_fd",
 	.tseg1_min = 1,
-	.tseg1_max = 16,
+	.tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
 	.tseg2_min = 1,
-	.tseg2_max = 8,
-	.sjw_max = 4,
+	.tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
 	.brp_min = 1,
-	.brp_max = 1024,
+	.brp_max = (1 << PUCAN_TFAST_BRP_BITS),
 	.brp_inc = 1,
 };
 
@@ -1100,6 +1100,78 @@ const struct peak_usb_adapter pcan_usb_p
 
 	/* size of device private data */
 	.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
+
+	/* timestamps usage */
+	.ts_used_bits = 32,
+	.ts_period = 1000000, /* calibration period in ts. */
+	.us_per_ts_scale = 1, /* us = (ts * scale) >> shift */
+	.us_per_ts_shift = 0,
+
+	/* give here messages in/out endpoints */
+	.ep_msg_in = PCAN_USBPRO_EP_MSGIN,
+	.ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0, PCAN_USBPRO_EP_MSGOUT_1},
+
+	/* size of rx/tx usb buffers */
+	.rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE,
+	.tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
+
+	/* device callbacks */
+	.intf_probe = pcan_usb_pro_probe,	/* same as PCAN-USB Pro */
+	.dev_init = pcan_usb_fd_init,
+
+	.dev_exit = pcan_usb_fd_exit,
+	.dev_free = pcan_usb_fd_free,
+	.dev_set_bus = pcan_usb_fd_set_bus,
+	.dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
+	.dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+	.dev_decode_buf = pcan_usb_fd_decode_buf,
+	.dev_start = pcan_usb_fd_start,
+	.dev_stop = pcan_usb_fd_stop,
+	.dev_restart_async = pcan_usb_fd_restart_async,
+	.dev_encode_msg = pcan_usb_fd_encode_msg,
+
+	.do_get_berr_counter = pcan_usb_fd_get_berr_counter,
+};
+
+/* describes the PCAN-USB X6 adapter */
+static const struct can_bittiming_const pcan_usb_x6_const = {
+	.name = "pcan_usb_x6",
+	.tseg1_min = 1,
+	.tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
+	.tseg2_min = 1,
+	.tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
+	.brp_min = 1,
+	.brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
+	.brp_inc = 1,
+};
+
+static const struct can_bittiming_const pcan_usb_x6_data_const = {
+	.name = "pcan_usb_x6",
+	.tseg1_min = 1,
+	.tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
+	.tseg2_min = 1,
+	.tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+	.sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
+	.brp_min = 1,
+	.brp_max = (1 << PUCAN_TFAST_BRP_BITS),
+	.brp_inc = 1,
+};
+
+const struct peak_usb_adapter pcan_usb_x6 = {
+	.name = "PCAN-USB X6",
+	.device_id = PCAN_USBX6_PRODUCT_ID,
+	.ctrl_count = PCAN_USBPROFD_CHANNEL_COUNT,
+	.ctrlmode_supported = CAN_CTRLMODE_FD |
+			CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
+	.clock = {
+		.freq = PCAN_UFD_CRYSTAL_HZ,
+	},
+	.bittiming_const = &pcan_usb_x6_const,
+	.data_bittiming_const = &pcan_usb_x6_data_const,
+
+	/* size of device private data */
+	.sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
 
 	/* timestamps usage */
 	.ts_used_bits = 32,
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/altera/altera_tse_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/altera/altera_tse_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/altera/altera_tse_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/altera/altera_tse_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -400,12 +400,6 @@ static int tse_rx(struct altera_tse_priv
 
 		skb_put(skb, pktlength);
 
-		/* make cache consistent with receive packet buffer */
-		dma_sync_single_for_cpu(priv->device,
-					priv->rx_ring[entry].dma_addr,
-					priv->rx_ring[entry].len,
-					DMA_FROM_DEVICE);
-
 		dma_unmap_single(priv->device, priv->rx_ring[entry].dma_addr,
 				 priv->rx_ring[entry].len, DMA_FROM_DEVICE);
 
@@ -469,7 +463,6 @@ static int tse_tx_complete(struct altera
 
 	if (unlikely(netif_queue_stopped(priv->dev) &&
 		     tse_tx_avail(priv) > TSE_TX_THRESH(priv))) {
-		netif_tx_lock(priv->dev);
 		if (netif_queue_stopped(priv->dev) &&
 		    tse_tx_avail(priv) > TSE_TX_THRESH(priv)) {
 			if (netif_msg_tx_done(priv))
@@ -477,7 +470,6 @@ static int tse_tx_complete(struct altera
 					   __func__);
 			netif_wake_queue(priv->dev);
 		}
-		netif_tx_unlock(priv->dev);
 	}
 
 	spin_unlock(&priv->tx_lock);
@@ -592,10 +584,6 @@ static int tse_start_xmit(struct sk_buff
 	buffer->dma_addr = dma_addr;
 	buffer->len = nopaged_len;
 
-	/* Push data out of the cache hierarchy into main memory */
-	dma_sync_single_for_device(priv->device, buffer->dma_addr,
-				   buffer->len, DMA_TO_DEVICE);
-
 	priv->dmaops->tx_buffer(priv, buffer);
 
 	skb_tx_timestamp(skb);
@@ -819,6 +807,8 @@ static int init_phy(struct net_device *d
 
 	if (!phydev) {
 		netdev_err(dev, "Could not find the PHY\n");
+		if (fixed_link)
+			of_phy_deregister_fixed_link(priv->device->of_node);
 		return -ENODEV;
 	}
 
@@ -1545,10 +1535,15 @@ err_free_netdev:
 static int altera_tse_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct altera_tse_private *priv = netdev_priv(ndev);
 
-	if (ndev->phydev)
+	if (ndev->phydev) {
 		phy_disconnect(ndev->phydev);
 
+		if (of_phy_is_fixed_link(priv->device->of_node))
+			of_phy_deregister_fixed_link(priv->device->of_node);
+	}
+
 	platform_set_drvdata(pdev, NULL);
 	altera_tse_mdio_destroy(ndev);
 	unregister_netdev(ndev);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/amd/xgbe/xgbe-main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/amd/xgbe/xgbe-main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/amd/xgbe/xgbe-main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/amd/xgbe/xgbe-main.c	2016-12-04 15:50:51.000000000 -0500
@@ -829,7 +829,7 @@ static int xgbe_remove(struct platform_d
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int xgbe_suspend(struct device *dev)
 {
 	struct net_device *netdev = dev_get_drvdata(dev);
@@ -874,7 +874,7 @@ static int xgbe_resume(struct device *de
 
 	return ret;
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id xgbe_acpi_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/aurora/nb8800.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/aurora/nb8800.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/aurora/nb8800.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/aurora/nb8800.c	2016-12-04 15:50:51.000000000 -0500
@@ -1466,12 +1466,12 @@ static int nb8800_probe(struct platform_
 
 	ret = nb8800_hw_init(dev);
 	if (ret)
-		goto err_free_bus;
+		goto err_deregister_fixed_link;
 
 	if (ops && ops->init) {
 		ret = ops->init(dev);
 		if (ret)
-			goto err_free_bus;
+			goto err_deregister_fixed_link;
 	}
 
 	dev->netdev_ops = &nb8800_netdev_ops;
@@ -1504,6 +1504,9 @@ static int nb8800_probe(struct platform_
 
 err_free_dma:
 	nb8800_dma_free(dev);
+err_deregister_fixed_link:
+	if (of_phy_is_fixed_link(pdev->dev.of_node))
+		of_phy_deregister_fixed_link(pdev->dev.of_node);
 err_free_bus:
 	of_node_put(priv->phy_node);
 	mdiobus_unregister(bus);
@@ -1521,6 +1524,8 @@ static int nb8800_remove(struct platform
 	struct nb8800_priv *priv = netdev_priv(ndev);
 
 	unregister_netdev(ndev);
+	if (of_phy_is_fixed_link(pdev->dev.of_node))
+		of_phy_deregister_fixed_link(pdev->dev.of_node);
 	of_node_put(priv->phy_node);
 
 	mdiobus_unregister(priv->mii_bus);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/bcmsysport.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bcmsysport.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/bcmsysport.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bcmsysport.c	2016-12-04 15:50:51.000000000 -0500
@@ -1755,13 +1755,13 @@ static int bcm_sysport_probe(struct plat
 	if (priv->irq0 <= 0 || priv->irq1 <= 0) {
 		dev_err(&pdev->dev, "invalid interrupts\n");
 		ret = -EINVAL;
-		goto err;
+		goto err_free_netdev;
 	}
 
 	priv->base = devm_ioremap_resource(&pdev->dev, r);
 	if (IS_ERR(priv->base)) {
 		ret = PTR_ERR(priv->base);
-		goto err;
+		goto err_free_netdev;
 	}
 
 	priv->netdev = dev;
@@ -1779,7 +1779,7 @@ static int bcm_sysport_probe(struct plat
 		ret = of_phy_register_fixed_link(dn);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to register fixed PHY\n");
-			goto err;
+			goto err_free_netdev;
 		}
 
 		priv->phy_dn = dn;
@@ -1821,7 +1821,7 @@ static int bcm_sysport_probe(struct plat
 	ret = register_netdev(dev);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register net_device\n");
-		goto err;
+		goto err_deregister_fixed_link;
 	}
 
 	priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
@@ -1832,7 +1832,11 @@ static int bcm_sysport_probe(struct plat
 		 priv->base, priv->irq0, priv->irq1, txq, rxq);
 
 	return 0;
-err:
+
+err_deregister_fixed_link:
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
+err_free_netdev:
 	free_netdev(dev);
 	return ret;
 }
@@ -1840,11 +1844,14 @@ err:
 static int bcm_sysport_remove(struct platform_device *pdev)
 {
 	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct device_node *dn = pdev->dev.of_node;
 
 	/* Not much to do, ndo_close has been called
 	 * and we use managed allocations
 	 */
 	unregister_netdev(dev);
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
 	free_netdev(dev);
 	dev_set_drvdata(&pdev->dev, NULL);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2016-12-04 15:50:51.000000000 -0500
@@ -1172,6 +1172,7 @@ static unsigned int __bcmgenet_tx_reclai
 					  struct bcmgenet_tx_ring *ring)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct device *kdev = &priv->pdev->dev;
 	struct enet_cb *tx_cb_ptr;
 	struct netdev_queue *txq;
 	unsigned int pkts_compl = 0;
@@ -1199,13 +1200,13 @@ static unsigned int __bcmgenet_tx_reclai
 		if (tx_cb_ptr->skb) {
 			pkts_compl++;
 			bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent;
-			dma_unmap_single(&dev->dev,
+			dma_unmap_single(kdev,
 					 dma_unmap_addr(tx_cb_ptr, dma_addr),
 					 dma_unmap_len(tx_cb_ptr, dma_len),
 					 DMA_TO_DEVICE);
 			bcmgenet_free_cb(tx_cb_ptr);
 		} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
-			dma_unmap_page(&dev->dev,
+			dma_unmap_page(kdev,
 				       dma_unmap_addr(tx_cb_ptr, dma_addr),
 				       dma_unmap_len(tx_cb_ptr, dma_len),
 				       DMA_TO_DEVICE);
@@ -1775,6 +1776,7 @@ static int bcmgenet_alloc_rx_buffers(str
 
 static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
 {
+	struct device *kdev = &priv->pdev->dev;
 	struct enet_cb *cb;
 	int i;
 
@@ -1782,7 +1784,7 @@ static void bcmgenet_free_rx_buffers(str
 		cb = &priv->rx_cbs[i];
 
 		if (dma_unmap_addr(cb, dma_addr)) {
-			dma_unmap_single(&priv->dev->dev,
+			dma_unmap_single(kdev,
 					 dma_unmap_addr(cb, dma_addr),
 					 priv->rx_buf_len, DMA_FROM_DEVICE);
 			dma_unmap_addr_set(cb, dma_addr, 0);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/genet/bcmmii.c	2016-12-04 15:50:51.000000000 -0500
@@ -542,8 +542,10 @@ static int bcmgenet_mii_of_init(struct b
 	/* Make sure we initialize MoCA PHYs with a link down */
 	if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
 		phydev = of_phy_find_device(dn);
-		if (phydev)
+		if (phydev) {
 			phydev->link = 0;
+			put_device(&phydev->mdio.dev);
+		}
 	}
 
 	return 0;
@@ -625,6 +627,7 @@ static int bcmgenet_mii_bus_init(struct
 int bcmgenet_mii_init(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct device_node *dn = priv->pdev->dev.of_node;
 	int ret;
 
 	ret = bcmgenet_mii_alloc(priv);
@@ -638,6 +641,8 @@ int bcmgenet_mii_init(struct net_device
 	return 0;
 
 out:
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
 	of_node_put(priv->phy_dn);
 	mdiobus_unregister(priv->mii_bus);
 	mdiobus_free(priv->mii_bus);
@@ -647,7 +652,10 @@ out:
 void bcmgenet_mii_exit(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct device_node *dn = priv->pdev->dev.of_node;
 
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
 	of_node_put(priv->phy_dn);
 	mdiobus_unregister(priv->mii_bus);
 	mdiobus_free(priv->mii_bus);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/cadence/macb.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/cadence/macb.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/cadence/macb.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/cadence/macb.c	2016-12-04 15:50:51.000000000 -0500
@@ -975,6 +975,7 @@ static inline void macb_init_rx_ring(str
 		addr += bp->rx_buffer_size;
 	}
 	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+	bp->rx_tail = 0;
 }
 
 static int macb_rx(struct macb *bp, int budget)
@@ -1156,6 +1157,7 @@ static irqreturn_t macb_interrupt(int ir
 		if (status & MACB_BIT(RXUBR)) {
 			ctrl = macb_readl(bp, NCR);
 			macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
+			wmb();
 			macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
 
 			if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
@@ -1616,8 +1618,6 @@ static void macb_init_rings(struct macb
 	bp->queues[0].tx_head = 0;
 	bp->queues[0].tx_tail = 0;
 	bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
-
-	bp->rx_tail = 0;
 }
 
 static void macb_reset_hw(struct macb *bp)
@@ -2770,6 +2770,7 @@ static irqreturn_t at91ether_interrupt(i
 	if (intstatus & MACB_BIT(RXUBR)) {
 		ctl = macb_readl(lp, NCR);
 		macb_writel(lp, NCR, ctl & ~MACB_BIT(RE));
+		wmb();
 		macb_writel(lp, NCR, ctl | MACB_BIT(RE));
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h	2016-12-04 15:50:51.000000000 -0500
@@ -168,6 +168,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
 	CH_PCI_ID_TABLE_FENTRY(0x509a),	/* Custom T520-CR */
 	CH_PCI_ID_TABLE_FENTRY(0x509b),	/* Custom T540-CR LOM */
 	CH_PCI_ID_TABLE_FENTRY(0x509c),	/* Custom T520-CR*/
+	CH_PCI_ID_TABLE_FENTRY(0x509d),	/* Custom T540-CR*/
 
 	/* T6 adapters:
 	 */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fec.h linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec.h
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fec.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec.h	2016-12-04 15:50:51.000000000 -0500
@@ -574,6 +574,8 @@ struct fec_enet_private {
 	unsigned int reload_period;
 	int pps_enable;
 	unsigned int next_counter;
+
+	u64 ethtool_stats[0];
 };
 
 void fec_ptp_init(struct platform_device *pdev);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -2313,14 +2313,24 @@ static const struct fec_stat {
 	{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
 };
 
-static void fec_enet_get_ethtool_stats(struct net_device *dev,
-	struct ethtool_stats *stats, u64 *data)
+static void fec_enet_update_ethtool_stats(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
-		data[i] = readl(fep->hwp + fec_stats[i].offset);
+		fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset);
+}
+
+static void fec_enet_get_ethtool_stats(struct net_device *dev,
+				       struct ethtool_stats *stats, u64 *data)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+
+	if (netif_running(dev))
+		fec_enet_update_ethtool_stats(dev);
+
+	memcpy(data, fep->ethtool_stats, ARRAY_SIZE(fec_stats) * sizeof(u64));
 }
 
 static void fec_enet_get_strings(struct net_device *netdev,
@@ -2874,6 +2884,8 @@ fec_enet_close(struct net_device *ndev)
 	if (fep->quirks & FEC_QUIRK_ERR006687)
 		imx6q_cpuidle_fec_irqs_unused();
 
+	fec_enet_update_ethtool_stats(ndev);
+
 	fec_enet_clk_enable(ndev, false);
 	pinctrl_pm_select_sleep_state(&fep->pdev->dev);
 	pm_runtime_mark_last_busy(&fep->pdev->dev);
@@ -3180,6 +3192,8 @@ static int fec_enet_init(struct net_devi
 
 	fec_restart(ndev);
 
+	fec_enet_update_ethtool_stats(ndev);
+
 	return 0;
 }
 
@@ -3278,7 +3292,8 @@ fec_probe(struct platform_device *pdev)
 	fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
 
 	/* Init network device */
-	ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
+	ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
+				  ARRAY_SIZE(fec_stats) * sizeof(u64),
 				  num_tx_qs, num_rx_qs);
 	if (!ndev)
 		return -ENOMEM;
@@ -3475,6 +3490,8 @@ failed_regulator:
 failed_clk_ipg:
 	fec_enet_clk_enable(ndev, false);
 failed_clk:
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
 failed_phy:
 	of_node_put(phy_node);
 failed_ioremap:
@@ -3488,6 +3505,7 @@ fec_drv_remove(struct platform_device *p
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct device_node *np = pdev->dev.of_node;
 
 	cancel_work_sync(&fep->tx_timeout_work);
 	fec_ptp_stop(pdev);
@@ -3495,6 +3513,8 @@ fec_drv_remove(struct platform_device *p
 	fec_enet_mii_remove(fep);
 	if (fep->reg_phy)
 		regulator_disable(fep->reg_phy);
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
 	of_node_put(fep->phy_node);
 	free_netdev(ndev);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fman/fman_memac.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fman/fman_memac.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fman/fman_memac.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fman/fman_memac.c	2016-12-04 15:50:51.000000000 -0500
@@ -1107,6 +1107,9 @@ int memac_free(struct fman_mac *memac)
 {
 	free_init_resources(memac);
 
+	if (memac->pcsphy)
+		put_device(&memac->pcsphy->mdio.dev);
+
 	kfree(memac->memac_drv_param);
 	kfree(memac);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fman/mac.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fman/mac.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fman/mac.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fman/mac.c	2016-12-04 15:50:51.000000000 -0500
@@ -892,6 +892,8 @@ static int mac_probe(struct platform_dev
 		priv->fixed_link->duplex = phy->duplex;
 		priv->fixed_link->pause = phy->pause;
 		priv->fixed_link->asym_pause = phy->asym_pause;
+
+		put_device(&phy->mdio.dev);
 	}
 
 	err = mac_dev->init(mac_dev);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2016-12-04 15:50:51.000000000 -0500
@@ -980,7 +980,7 @@ static int fs_enet_probe(struct platform
 		err = clk_prepare_enable(clk);
 		if (err) {
 			ret = err;
-			goto out_free_fpi;
+			goto out_deregister_fixed_link;
 		}
 		fpi->clk_per = clk;
 	}
@@ -1061,6 +1061,9 @@ out_put:
 	of_node_put(fpi->phy_node);
 	if (fpi->clk_per)
 		clk_disable_unprepare(fpi->clk_per);
+out_deregister_fixed_link:
+	if (of_phy_is_fixed_link(ofdev->dev.of_node))
+		of_phy_deregister_fixed_link(ofdev->dev.of_node);
 out_free_fpi:
 	kfree(fpi);
 	return ret;
@@ -1079,6 +1082,8 @@ static int fs_enet_remove(struct platfor
 	of_node_put(fep->fpi->phy_node);
 	if (fep->fpi->clk_per)
 		clk_disable_unprepare(fep->fpi->clk_per);
+	if (of_phy_is_fixed_link(ofdev->dev.of_node))
+		of_phy_deregister_fixed_link(ofdev->dev.of_node);
 	free_netdev(ndev);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/gianfar.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/gianfar.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/gianfar.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/gianfar.c	2016-12-04 15:50:51.000000000 -0500
@@ -1312,6 +1312,7 @@ static void gfar_init_addr_hash_table(st
  */
 static int gfar_probe(struct platform_device *ofdev)
 {
+	struct device_node *np = ofdev->dev.of_node;
 	struct net_device *dev = NULL;
 	struct gfar_private *priv = NULL;
 	int err = 0, i;
@@ -1462,6 +1463,8 @@ static int gfar_probe(struct platform_de
 	return 0;
 
 register_fail:
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
 	unmap_group_regs(priv);
 	gfar_free_rx_queues(priv);
 	gfar_free_tx_queues(priv);
@@ -1474,11 +1477,16 @@ register_fail:
 static int gfar_remove(struct platform_device *ofdev)
 {
 	struct gfar_private *priv = platform_get_drvdata(ofdev);
+	struct device_node *np = ofdev->dev.of_node;
 
 	of_node_put(priv->phy_node);
 	of_node_put(priv->tbi_node);
 
 	unregister_netdev(priv->ndev);
+
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
+
 	unmap_group_regs(priv);
 	gfar_free_rx_queues(priv);
 	gfar_free_tx_queues(priv);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/ucc_geth.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/ucc_geth.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2016-12-04 15:50:51.000000000 -0500
@@ -3868,9 +3868,8 @@ static int ucc_geth_probe(struct platfor
 	dev = alloc_etherdev(sizeof(*ugeth));
 
 	if (dev == NULL) {
-		of_node_put(ug_info->tbi_node);
-		of_node_put(ug_info->phy_node);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_deregister_fixed_link;
 	}
 
 	ugeth = netdev_priv(dev);
@@ -3907,10 +3906,7 @@ static int ucc_geth_probe(struct platfor
 		if (netif_msg_probe(ugeth))
 			pr_err("%s: Cannot register net device, aborting\n",
 			       dev->name);
-		free_netdev(dev);
-		of_node_put(ug_info->tbi_node);
-		of_node_put(ug_info->phy_node);
-		return err;
+		goto err_free_netdev;
 	}
 
 	mac_addr = of_get_mac_address(np);
@@ -3923,16 +3919,29 @@ static int ucc_geth_probe(struct platfor
 	ugeth->node = np;
 
 	return 0;
+
+err_free_netdev:
+	free_netdev(dev);
+err_deregister_fixed_link:
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
+	of_node_put(ug_info->tbi_node);
+	of_node_put(ug_info->phy_node);
+
+	return err;
 }
 
 static int ucc_geth_remove(struct platform_device* ofdev)
 {
 	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct device_node *np = ofdev->dev.of_node;
 
 	unregister_netdev(dev);
 	free_netdev(dev);
 	ucc_geth_memclean(ugeth);
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
 	of_node_put(ugeth->ug_info->tbi_node);
 	of_node_put(ugeth->ug_info->phy_node);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/igb/igb_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/igb/igb_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -4931,11 +4931,15 @@ static int igb_tso(struct igb_ring *tx_r
 
 	/* initialize outer IP header fields */
 	if (ip.v4->version == 4) {
+		unsigned char *csum_start = skb_checksum_start(skb);
+		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
 		/* IP header will have to cancel out any data that
 		 * is not a part of the outer IP header
 		 */
-		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-						  csum_unfold(l4.tcp->check)));
+		ip.v4->check = csum_fold(csum_partial(trans_start,
+						      csum_start - trans_start,
+						      0));
 		type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
 
 		ip.v4->tot_len = 0;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/igbvf/netdev.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/igbvf/netdev.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/igbvf/netdev.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/igbvf/netdev.c	2016-12-04 15:50:51.000000000 -0500
@@ -1965,11 +1965,15 @@ static int igbvf_tso(struct igbvf_ring *
 
 	/* initialize outer IP header fields */
 	if (ip.v4->version == 4) {
+		unsigned char *csum_start = skb_checksum_start(skb);
+		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
 		/* IP header will have to cancel out any data that
 		 * is not a part of the outer IP header
 		 */
-		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-						  csum_unfold(l4.tcp->check)));
+		ip.v4->check = csum_fold(csum_partial(trans_start,
+						      csum_start - trans_start,
+						      0));
 		type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
 
 		ip.v4->tot_len = 0;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -7277,11 +7277,15 @@ static int ixgbe_tso(struct ixgbe_ring *
 
 	/* initialize outer IP header fields */
 	if (ip.v4->version == 4) {
+		unsigned char *csum_start = skb_checksum_start(skb);
+		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
 		/* IP header will have to cancel out any data that
 		 * is not a part of the outer IP header
 		 */
-		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-						  csum_unfold(l4.tcp->check)));
+		ip.v4->check = csum_fold(csum_partial(trans_start,
+						      csum_start - trans_start,
+						      0));
 		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
 
 		ip.v4->tot_len = 0;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -3329,11 +3329,15 @@ static int ixgbevf_tso(struct ixgbevf_ri
 
 	/* initialize outer IP header fields */
 	if (ip.v4->version == 4) {
+		unsigned char *csum_start = skb_checksum_start(skb);
+		unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
+
 		/* IP header will have to cancel out any data that
 		 * is not a part of the outer IP header
 		 */
-		ip.v4->check = csum_fold(csum_add(lco_csum(skb),
-						  csum_unfold(l4.tcp->check)));
+		ip.v4->check = csum_fold(csum_partial(trans_start,
+						      csum_start - trans_start,
+						      0));
 		type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
 
 		ip.v4->tot_len = 0;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/marvell/mvneta.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/marvell/mvneta.c	2016-12-04 15:50:51.000000000 -0500
@@ -4191,6 +4191,8 @@ err_clk:
 	clk_disable_unprepare(pp->clk);
 err_put_phy_node:
 	of_node_put(phy_node);
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
 err_free_irq:
 	irq_dispose_mapping(dev->irq);
 err_free_netdev:
@@ -4202,6 +4204,7 @@ err_free_netdev:
 static int mvneta_remove(struct platform_device *pdev)
 {
 	struct net_device  *dev = platform_get_drvdata(pdev);
+	struct device_node *dn = pdev->dev.of_node;
 	struct mvneta_port *pp = netdev_priv(dev);
 
 	unregister_netdev(dev);
@@ -4209,6 +4212,8 @@ static int mvneta_remove(struct platform
 	clk_disable_unprepare(pp->clk);
 	free_percpu(pp->ports);
 	free_percpu(pp->stats);
+	if (of_phy_is_fixed_link(dn))
+		of_phy_deregister_fixed_link(dn);
 	irq_dispose_mapping(dev->irq);
 	of_node_put(pp->phy_node);
 	free_netdev(dev);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mediatek/mtk_eth_soc.c	2016-12-04 15:50:51.000000000 -0500
@@ -318,6 +318,8 @@ static int mtk_phy_connect(struct net_de
 	return 0;
 
 err_phy:
+	if (of_phy_is_fixed_link(mac->of_node))
+		of_phy_deregister_fixed_link(mac->of_node);
 	of_node_put(np);
 	dev_err(eth->dev, "%s: invalid phy\n", __func__);
 	return -EINVAL;
@@ -1923,6 +1925,8 @@ static void mtk_uninit(struct net_device
 	struct mtk_eth *eth = mac->hw;
 
 	phy_disconnect(dev->phydev);
+	if (of_phy_is_fixed_link(mac->of_node))
+		of_phy_deregister_fixed_link(mac->of_node);
 	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
 	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2016-12-04 15:50:51.000000000 -0500
@@ -2079,13 +2079,6 @@ err:
 	return -ENOMEM;
 }
 
-static void mlx4_en_shutdown(struct net_device *dev)
-{
-	rtnl_lock();
-	netif_device_detach(dev);
-	mlx4_en_close(dev);
-	rtnl_unlock();
-}
 
 static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
 			     struct mlx4_en_priv *src,
@@ -2162,8 +2155,6 @@ void mlx4_en_destroy_netdev(struct net_d
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
-	bool shutdown = mdev->dev->persist->interface_state &
-					    MLX4_INTERFACE_STATE_SHUTDOWN;
 
 	en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 
@@ -2171,10 +2162,7 @@ void mlx4_en_destroy_netdev(struct net_d
 	if (priv->registered) {
 		devlink_port_type_clear(mlx4_get_devlink_port(mdev->dev,
 							      priv->port));
-		if (shutdown)
-			mlx4_en_shutdown(dev);
-		else
-			unregister_netdev(dev);
+		unregister_netdev(dev);
 	}
 
 	if (priv->allocated)
@@ -2203,8 +2191,7 @@ void mlx4_en_destroy_netdev(struct net_d
 	kfree(priv->tx_ring);
 	kfree(priv->tx_cq);
 
-	if (!shutdown)
-		free_netdev(dev);
+	free_netdev(dev);
 }
 
 static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2016-12-04 15:50:51.000000000 -0500
@@ -4147,11 +4147,8 @@ static void mlx4_shutdown(struct pci_dev
 
 	mlx4_info(persist->dev, "mlx4_shutdown was called\n");
 	mutex_lock(&persist->interface_state_mutex);
-	if (persist->interface_state & MLX4_INTERFACE_STATE_UP) {
-		/* Notify mlx4 clients that the kernel is being shut down */
-		persist->interface_state |= MLX4_INTERFACE_STATE_SHUTDOWN;
+	if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
 		mlx4_unload_one(pdev);
-	}
 	mutex_unlock(&persist->interface_state_mutex);
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2016-12-04 15:50:51.000000000 -0500
@@ -1457,7 +1457,12 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_detach)
 int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
 				u32 qpn, enum mlx4_net_trans_promisc_mode mode)
 {
-	struct mlx4_net_trans_rule rule;
+	struct mlx4_net_trans_rule rule = {
+		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
+		.exclusive = 0,
+		.allow_loopback = 1,
+	};
+
 	u64 *regid_p;
 
 	switch (mode) {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/qualcomm/emac/emac.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qualcomm/emac/emac.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/qualcomm/emac/emac.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qualcomm/emac/emac.c	2016-12-04 15:50:51.000000000 -0500
@@ -711,6 +711,8 @@ static int emac_probe(struct platform_de
 err_undo_napi:
 	netif_napi_del(&adpt->rx_q.napi);
 err_undo_mdiobus:
+	if (!has_acpi_companion(&pdev->dev))
+		put_device(&adpt->phydev->mdio.dev);
 	mdiobus_unregister(adpt->mii_bus);
 err_undo_clocks:
 	emac_clks_teardown(adpt);
@@ -730,6 +732,8 @@ static int emac_remove(struct platform_d
 
 	emac_clks_teardown(adpt);
 
+	if (!has_acpi_companion(&pdev->dev))
+		put_device(&adpt->phydev->mdio.dev);
 	mdiobus_unregister(adpt->mii_bus);
 	free_netdev(netdev);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/qualcomm/emac/emac-phy.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qualcomm/emac/emac-phy.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/qualcomm/emac/emac-phy.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qualcomm/emac/emac-phy.c	2016-12-04 15:50:51.000000000 -0500
@@ -212,6 +212,7 @@ int emac_phy_config(struct platform_devi
 
 		phy_np = of_parse_phandle(np, "phy-handle", 0);
 		adpt->phydev = of_phy_find_device(phy_np);
+		of_node_put(phy_np);
 	}
 
 	if (!adpt->phydev) {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/renesas/ravb_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/renesas/ravb_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/renesas/ravb_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/renesas/ravb_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -1008,20 +1008,18 @@ static int ravb_phy_init(struct net_devi
 	of_node_put(pn);
 	if (!phydev) {
 		netdev_err(ndev, "failed to connect PHY\n");
-		return -ENOENT;
+		err = -ENOENT;
+		goto err_deregister_fixed_link;
 	}
 
 	/* This driver only support 10/100Mbit speeds on Gen3
 	 * at this time.
 	 */
 	if (priv->chip_id == RCAR_GEN3) {
-		int err;
-
 		err = phy_set_max_speed(phydev, SPEED_100);
 		if (err) {
 			netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n");
-			phy_disconnect(phydev);
-			return err;
+			goto err_phy_disconnect;
 		}
 
 		netdev_info(ndev, "limited PHY to 100Mbit/s\n");
@@ -1033,6 +1031,14 @@ static int ravb_phy_init(struct net_devi
 	phy_attached_info(phydev);
 
 	return 0;
+
+err_phy_disconnect:
+	phy_disconnect(phydev);
+err_deregister_fixed_link:
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
+
+	return err;
 }
 
 /* PHY control start function */
@@ -1634,6 +1640,7 @@ static void ravb_set_rx_mode(struct net_
 /* Device close function for Ethernet AVB */
 static int ravb_close(struct net_device *ndev)
 {
+	struct device_node *np = ndev->dev.parent->of_node;
 	struct ravb_private *priv = netdev_priv(ndev);
 	struct ravb_tstamp_skb *ts_skb, *ts_skb2;
 
@@ -1663,6 +1670,8 @@ static int ravb_close(struct net_device
 	if (ndev->phydev) {
 		phy_stop(ndev->phydev);
 		phy_disconnect(ndev->phydev);
+		if (of_phy_is_fixed_link(np))
+			of_phy_deregister_fixed_link(np);
 	}
 
 	if (priv->chip_id != RCAR_GEN2) {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/renesas/sh_eth.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/renesas/sh_eth.c	2016-12-04 15:50:51.000000000 -0500
@@ -518,7 +518,7 @@ static struct sh_eth_cpu_data r7s72100_d
 
 	.ecsr_value	= ECSR_ICD,
 	.ecsipr_value	= ECSIPR_ICDIP,
-	.eesipr_value	= 0xff7f009f,
+	.eesipr_value	= 0xe77f009f,
 
 	.tx_check	= EESR_TC1 | EESR_FTC,
 	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c	2016-12-04 15:50:51.000000000 -0500
@@ -50,10 +50,23 @@ static int dwmac_generic_probe(struct pl
 	if (plat_dat->init) {
 		ret = plat_dat->init(pdev, plat_dat->bsp_priv);
 		if (ret)
-			return ret;
+			goto err_remove_config_dt;
 	}
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_exit;
+
+	return 0;
+
+err_exit:
+	if (plat_dat->exit)
+		plat_dat->exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+	if (pdev->dev.of_node)
+		stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static const struct of_device_id dwmac_generic_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c	2016-12-04 15:50:51.000000000 -0500
@@ -271,15 +271,17 @@ static int ipq806x_gmac_probe(struct pla
 		return PTR_ERR(plat_dat);
 
 	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-	if (!gmac)
-		return -ENOMEM;
+	if (!gmac) {
+		err = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	gmac->pdev = pdev;
 
 	err = ipq806x_gmac_of_parse(gmac);
 	if (err) {
 		dev_err(dev, "device tree parsing error\n");
-		return err;
+		goto err_remove_config_dt;
 	}
 
 	regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
@@ -300,7 +302,8 @@ static int ipq806x_gmac_probe(struct pla
 	default:
 		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
 			phy_modes(gmac->phy_mode));
-		return -EINVAL;
+		err = -EINVAL;
+		goto err_remove_config_dt;
 	}
 	regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
 
@@ -319,7 +322,8 @@ static int ipq806x_gmac_probe(struct pla
 	default:
 		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
 			phy_modes(gmac->phy_mode));
-		return -EINVAL;
+		err = -EINVAL;
+		goto err_remove_config_dt;
 	}
 	regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
 
@@ -346,7 +350,16 @@ static int ipq806x_gmac_probe(struct pla
 	plat_dat->bsp_priv = gmac;
 	plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (err)
+		goto err_remove_config_dt;
+
+	return 0;
+
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return err;
 }
 
 static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c	2016-12-04 15:50:51.000000000 -0500
@@ -46,7 +46,8 @@ static int lpc18xx_dwmac_probe(struct pl
 	reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
 	if (IS_ERR(reg)) {
 		dev_err(&pdev->dev, "syscon lookup failed\n");
-		return PTR_ERR(reg);
+		ret = PTR_ERR(reg);
+		goto err_remove_config_dt;
 	}
 
 	if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
@@ -55,13 +56,23 @@ static int lpc18xx_dwmac_probe(struct pl
 		ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
 	} else {
 		dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_remove_config_dt;
 	}
 
 	regmap_update_bits(reg, LPC18XX_CREG_CREG6,
 			   LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_remove_config_dt;
+
+	return 0;
+
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static const struct of_device_id lpc18xx_dwmac_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c	2016-12-04 15:50:51.000000000 -0500
@@ -264,32 +264,48 @@ static int meson8b_dwmac_probe(struct pl
 		return PTR_ERR(plat_dat);
 
 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-	if (!dwmac)
-		return -ENOMEM;
+	if (!dwmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(dwmac->regs))
-		return PTR_ERR(dwmac->regs);
+	if (IS_ERR(dwmac->regs)) {
+		ret = PTR_ERR(dwmac->regs);
+		goto err_remove_config_dt;
+	}
 
 	dwmac->pdev = pdev;
 	dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
 	if (dwmac->phy_mode < 0) {
 		dev_err(&pdev->dev, "missing phy-mode property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_remove_config_dt;
 	}
 
 	ret = meson8b_init_clk(dwmac);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
 	ret = meson8b_init_prg_eth(dwmac);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
 	plat_dat->bsp_priv = dwmac;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_clk_disable;
+
+	return 0;
+
+err_clk_disable:
+	clk_disable_unprepare(dwmac->m25_div_clk);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static int meson8b_dwmac_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c	2016-12-04 15:50:51.000000000 -0500
@@ -64,18 +64,31 @@ static int meson6_dwmac_probe(struct pla
 		return PTR_ERR(plat_dat);
 
 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-	if (!dwmac)
-		return -ENOMEM;
+	if (!dwmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(dwmac->reg))
-		return PTR_ERR(dwmac->reg);
+	if (IS_ERR(dwmac->reg)) {
+		ret = PTR_ERR(dwmac->reg);
+		goto err_remove_config_dt;
+	}
 
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_remove_config_dt;
+
+	return 0;
+
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static const struct of_device_id meson6_dwmac_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c	2016-12-04 15:50:51.000000000 -0500
@@ -981,14 +981,27 @@ static int rk_gmac_probe(struct platform
 	plat_dat->resume = rk_gmac_resume;
 
 	plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
-	if (IS_ERR(plat_dat->bsp_priv))
-		return PTR_ERR(plat_dat->bsp_priv);
+	if (IS_ERR(plat_dat->bsp_priv)) {
+		ret = PTR_ERR(plat_dat->bsp_priv);
+		goto err_remove_config_dt;
+	}
 
 	ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_gmac_exit;
+
+	return 0;
+
+err_gmac_exit:
+	rk_gmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static const struct of_device_id rk_gmac_dwmac_match[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c	2016-12-04 15:50:51.000000000 -0500
@@ -304,6 +304,8 @@ static int socfpga_dwmac_probe(struct pl
 	struct device		*dev = &pdev->dev;
 	int			ret;
 	struct socfpga_dwmac	*dwmac;
+	struct net_device	*ndev;
+	struct stmmac_priv	*stpriv;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
 	if (ret)
@@ -314,32 +316,43 @@ static int socfpga_dwmac_probe(struct pl
 		return PTR_ERR(plat_dat);
 
 	dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
-	if (!dwmac)
-		return -ENOMEM;
+	if (!dwmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	ret = socfpga_dwmac_parse_data(dwmac, dev);
 	if (ret) {
 		dev_err(dev, "Unable to parse OF data\n");
-		return ret;
+		goto err_remove_config_dt;
 	}
 
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_remove_config_dt;
 
-	if (!ret) {
-		struct net_device *ndev = platform_get_drvdata(pdev);
-		struct stmmac_priv *stpriv = netdev_priv(ndev);
+	ndev = platform_get_drvdata(pdev);
+	stpriv = netdev_priv(ndev);
 
-		/* The socfpga driver needs to control the stmmac reset to
-		 * set the phy mode. Create a copy of the core reset handel
-		 * so it can be used by the driver later.
-		 */
-		dwmac->stmmac_rst = stpriv->stmmac_rst;
+	/* The socfpga driver needs to control the stmmac reset to set the phy
+	 * mode. Create a copy of the core reset handle so it can be used by
+	 * the driver later.
+	 */
+	dwmac->stmmac_rst = stpriv->stmmac_rst;
 
-		ret = socfpga_dwmac_set_phy_mode(dwmac);
-	}
+	ret = socfpga_dwmac_set_phy_mode(dwmac);
+	if (ret)
+		goto err_dvr_remove;
+
+	return 0;
+
+err_dvr_remove:
+	stmmac_dvr_remove(&pdev->dev);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c	2016-12-04 15:50:51.000000000 -0500
@@ -345,13 +345,15 @@ static int sti_dwmac_probe(struct platfo
 		return PTR_ERR(plat_dat);
 
 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-	if (!dwmac)
-		return -ENOMEM;
+	if (!dwmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	ret = sti_dwmac_parse_data(dwmac, pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "Unable to parse OF data\n");
-		return ret;
+		goto err_remove_config_dt;
 	}
 
 	dwmac->fix_retime_src = data->fix_retime_src;
@@ -363,9 +365,20 @@ static int sti_dwmac_probe(struct platfo
 
 	ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_dwmac_exit;
+
+	return 0;
+
+err_dwmac_exit:
+	sti_dwmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
+
+	return ret;
 }
 
 static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c	2016-12-04 15:50:51.000000000 -0500
@@ -107,24 +107,33 @@ static int stm32_dwmac_probe(struct plat
 		return PTR_ERR(plat_dat);
 
 	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-	if (!dwmac)
-		return -ENOMEM;
+	if (!dwmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Unable to parse OF data\n");
-		return ret;
+		goto err_remove_config_dt;
 	}
 
 	plat_dat->bsp_priv = dwmac;
 
 	ret = stm32_dwmac_init(plat_dat);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 	if (ret)
-		stm32_dwmac_clk_disable(dwmac);
+		goto err_clk_disable;
+
+	return 0;
+
+err_clk_disable:
+	stm32_dwmac_clk_disable(dwmac);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c	2016-12-04 15:50:51.000000000 -0500
@@ -120,22 +120,27 @@ static int sun7i_gmac_probe(struct platf
 		return PTR_ERR(plat_dat);
 
 	gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
-	if (!gmac)
-		return -ENOMEM;
+	if (!gmac) {
+		ret = -ENOMEM;
+		goto err_remove_config_dt;
+	}
 
 	gmac->interface = of_get_phy_mode(dev->of_node);
 
 	gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
 	if (IS_ERR(gmac->tx_clk)) {
 		dev_err(dev, "could not get tx clock\n");
-		return PTR_ERR(gmac->tx_clk);
+		ret = PTR_ERR(gmac->tx_clk);
+		goto err_remove_config_dt;
 	}
 
 	/* Optional regulator for PHY */
 	gmac->regulator = devm_regulator_get_optional(dev, "phy");
 	if (IS_ERR(gmac->regulator)) {
-		if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
+		if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			goto err_remove_config_dt;
+		}
 		dev_info(dev, "no regulator found\n");
 		gmac->regulator = NULL;
 	}
@@ -151,11 +156,18 @@ static int sun7i_gmac_probe(struct platf
 
 	ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
 	if (ret)
-		return ret;
+		goto err_remove_config_dt;
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 	if (ret)
-		sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
+		goto err_gmac_exit;
+
+	return 0;
+
+err_gmac_exit:
+	sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+	stmmac_remove_config_dt(pdev, plat_dat);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -3416,7 +3416,6 @@ int stmmac_dvr_remove(struct device *dev
 	stmmac_set_mac(priv->ioaddr, false);
 	netif_carrier_off(ndev);
 	unregister_netdev(ndev);
-	of_node_put(priv->plat->phy_node);
 	if (priv->stmmac_rst)
 		reset_control_assert(priv->stmmac_rst);
 	clk_disable_unprepare(priv->pclk);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2016-12-04 15:50:51.000000000 -0500
@@ -200,7 +200,6 @@ static int stmmac_dt_phy(struct plat_stm
 /**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
- * @plat: driver data platform structure
  * @mac: MAC address to use
  * Description:
  * this function is to read the driver parameters from device-tree and
@@ -306,7 +305,7 @@ stmmac_probe_config_dt(struct platform_d
 		dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
 				       GFP_KERNEL);
 		if (!dma_cfg) {
-			of_node_put(plat->phy_node);
+			stmmac_remove_config_dt(pdev, plat);
 			return ERR_PTR(-ENOMEM);
 		}
 		plat->dma_cfg = dma_cfg;
@@ -329,14 +328,37 @@ stmmac_probe_config_dt(struct platform_d
 
 	return plat;
 }
+
+/**
+ * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
+ * @pdev: platform_device structure
+ * @plat: driver data platform structure
+ *
+ * Release resources claimed by stmmac_probe_config_dt().
+ */
+void stmmac_remove_config_dt(struct platform_device *pdev,
+			     struct plat_stmmacenet_data *plat)
+{
+	struct device_node *np = pdev->dev.of_node;
+
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
+	of_node_put(plat->phy_node);
+}
 #else
 struct plat_stmmacenet_data *
 stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
 {
 	return ERR_PTR(-ENOSYS);
 }
+
+void stmmac_remove_config_dt(struct platform_device *pdev,
+			     struct plat_stmmacenet_data *plat)
+{
+}
 #endif /* CONFIG_OF */
 EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
+EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res)
@@ -392,10 +414,13 @@ int stmmac_pltfr_remove(struct platform_
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
+	struct plat_stmmacenet_data *plat = priv->plat;
 	int ret = stmmac_dvr_remove(&pdev->dev);
 
-	if (priv->plat->exit)
-		priv->plat->exit(pdev, priv->plat->bsp_priv);
+	if (plat->exit)
+		plat->exit(pdev, plat->bsp_priv);
+
+	stmmac_remove_config_dt(pdev, plat);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h	2016-12-04 15:50:51.000000000 -0500
@@ -23,6 +23,8 @@
 
 struct plat_stmmacenet_data *
 stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
+void stmmac_remove_config_dt(struct platform_device *pdev,
+			     struct plat_stmmacenet_data *plat);
 
 int stmmac_get_platform_resources(struct platform_device *pdev,
 				  struct stmmac_resources *stmmac_res);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/synopsys/dwc_eth_qos.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/synopsys/dwc_eth_qos.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/synopsys/dwc_eth_qos.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/synopsys/dwc_eth_qos.c	2016-12-04 15:50:51.000000000 -0500
@@ -2881,7 +2881,7 @@ static int dwceqos_probe(struct platform
 	ret = of_get_phy_mode(lp->pdev->dev.of_node);
 	if (ret < 0) {
 		dev_err(&lp->pdev->dev, "error in getting phy i/f\n");
-		goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 
 	lp->phy_interface = ret;
@@ -2889,14 +2889,14 @@ static int dwceqos_probe(struct platform
 	ret = dwceqos_mii_init(lp);
 	if (ret) {
 		dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n");
-		goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 
 	ret = dwceqos_mii_probe(ndev);
 	if (ret != 0) {
 		netdev_err(ndev, "mii_probe fail.\n");
 		ret = -ENXIO;
-		goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 
 	dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0);
@@ -2914,7 +2914,7 @@ static int dwceqos_probe(struct platform
 	if (ret) {
 		dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n",
 			ret);
-		goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 	dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n",
 		 pdev->id, ndev->base_addr, ndev->irq);
@@ -2924,7 +2924,7 @@ static int dwceqos_probe(struct platform
 	if (ret) {
 		dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n",
 			ndev->irq, ret);
-		goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 
 	if (netif_msg_probe(lp))
@@ -2935,11 +2935,14 @@ static int dwceqos_probe(struct platform
 	ret = register_netdev(ndev);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
-			goto err_out_clk_dis_phy;
+		goto err_out_deregister_fixed_link;
 	}
 
 	return 0;
 
+err_out_deregister_fixed_link:
+	if (of_phy_is_fixed_link(pdev->dev.of_node))
+		of_phy_deregister_fixed_link(pdev->dev.of_node);
 err_out_clk_dis_phy:
 	clk_disable_unprepare(lp->phy_ref_clk);
 err_out_clk_dis_aper:
@@ -2959,8 +2962,11 @@ static int dwceqos_remove(struct platfor
 	if (ndev) {
 		lp = netdev_priv(ndev);
 
-		if (ndev->phydev)
+		if (ndev->phydev) {
 			phy_disconnect(ndev->phydev);
+			if (of_phy_is_fixed_link(pdev->dev.of_node))
+				of_phy_deregister_fixed_link(pdev->dev.of_node);
+		}
 		mdiobus_unregister(lp->mii_bus);
 		mdiobus_free(lp->mii_bus);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/ti/cpsw.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpsw.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/ti/cpsw.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpsw.c	2016-12-04 15:50:51.000000000 -0500
@@ -2459,20 +2459,8 @@ static void cpsw_remove_dt(struct platfo
 		if (strcmp(slave_node->name, "slave"))
 			continue;
 
-		if (of_phy_is_fixed_link(slave_node)) {
-			struct phy_device *phydev;
-
-			phydev = of_phy_find_device(slave_node);
-			if (phydev) {
-				fixed_phy_unregister(phydev);
-				/* Put references taken by
-				 * of_phy_find_device() and
-				 * of_phy_register_fixed_link().
-				 */
-				phy_device_free(phydev);
-				phy_device_free(phydev);
-			}
-		}
+		if (of_phy_is_fixed_link(slave_node))
+			of_phy_deregister_fixed_link(slave_node);
 
 		of_node_put(slave_data->phy_node);
 
@@ -2942,6 +2930,8 @@ static int cpsw_resume(struct device *de
 	/* Select default pin state */
 	pinctrl_pm_select_default_state(dev);
 
+	/* shut up ASSERT_RTNL() warning in netif_set_real_num_tx/rx_queues */
+	rtnl_lock();
 	if (cpsw->data.dual_emac) {
 		int i;
 
@@ -2953,6 +2943,8 @@ static int cpsw_resume(struct device *de
 		if (netif_running(ndev))
 			cpsw_ndo_open(ndev);
 	}
+	rtnl_unlock();
+
 	return 0;
 }
 #endif
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ethernet/ti/davinci_emac.c linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/davinci_emac.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ethernet/ti/davinci_emac.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/davinci_emac.c	2016-12-04 15:50:51.000000000 -0500
@@ -1767,6 +1767,7 @@ static int davinci_emac_try_get_mac(stru
  */
 static int davinci_emac_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	int rc = 0;
 	struct resource *res, *res_ctrl;
 	struct net_device *ndev;
@@ -1805,7 +1806,7 @@ static int davinci_emac_probe(struct pla
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data\n");
 		rc = -ENODEV;
-		goto no_pdata;
+		goto err_free_netdev;
 	}
 
 	/* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1941,6 +1942,10 @@ no_cpdma_chan:
 		cpdma_chan_destroy(priv->rxchan);
 	cpdma_ctlr_destroy(priv->dma);
 no_pdata:
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
+	of_node_put(priv->phy_node);
+err_free_netdev:
 	free_netdev(ndev);
 	return rc;
 }
@@ -1956,6 +1961,7 @@ static int davinci_emac_remove(struct pl
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct emac_priv *priv = netdev_priv(ndev);
+	struct device_node *np = pdev->dev.of_node;
 
 	dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
 
@@ -1968,6 +1974,8 @@ static int davinci_emac_remove(struct pl
 	unregister_netdev(ndev);
 	of_node_put(priv->phy_node);
 	pm_runtime_disable(&pdev->dev);
+	if (of_phy_is_fixed_link(np))
+		of_phy_deregister_fixed_link(np);
 	free_netdev(ndev);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/geneve.c linux-libre-4.9-rc8-gnu/drivers/net/geneve.c
--- linux-libre-4.9-rc7-gnu/drivers/net/geneve.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/geneve.c	2016-12-04 15:50:51.000000000 -0500
@@ -859,7 +859,6 @@ static netdev_tx_t geneve_xmit_skb(struc
 	struct geneve_dev *geneve = netdev_priv(dev);
 	struct geneve_sock *gs4;
 	struct rtable *rt = NULL;
-	const struct iphdr *iip; /* interior IP header */
 	int err = -EINVAL;
 	struct flowi4 fl4;
 	__u8 tos, ttl;
@@ -890,8 +889,6 @@ static netdev_tx_t geneve_xmit_skb(struc
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	skb_reset_mac_header(skb);
 
-	iip = ip_hdr(skb);
-
 	if (info) {
 		const struct ip_tunnel_key *key = &info->key;
 		u8 *opts = NULL;
@@ -911,7 +908,7 @@ static netdev_tx_t geneve_xmit_skb(struc
 		if (unlikely(err))
 			goto tx_error;
 
-		tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
+		tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
 		ttl = key->ttl;
 		df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
 	} else {
@@ -920,7 +917,7 @@ static netdev_tx_t geneve_xmit_skb(struc
 		if (unlikely(err))
 			goto tx_error;
 
-		tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
+		tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
 		ttl = geneve->ttl;
 		if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
 			ttl = 1;
@@ -952,7 +949,6 @@ static netdev_tx_t geneve6_xmit_skb(stru
 {
 	struct geneve_dev *geneve = netdev_priv(dev);
 	struct dst_entry *dst = NULL;
-	const struct iphdr *iip; /* interior IP header */
 	struct geneve_sock *gs6;
 	int err = -EINVAL;
 	struct flowi6 fl6;
@@ -982,8 +978,6 @@ static netdev_tx_t geneve6_xmit_skb(stru
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	skb_reset_mac_header(skb);
 
-	iip = ip_hdr(skb);
-
 	if (info) {
 		const struct ip_tunnel_key *key = &info->key;
 		u8 *opts = NULL;
@@ -1004,7 +998,7 @@ static netdev_tx_t geneve6_xmit_skb(stru
 		if (unlikely(err))
 			goto tx_error;
 
-		prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
+		prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
 		ttl = key->ttl;
 		label = info->key.label;
 	} else {
@@ -1014,7 +1008,7 @@ static netdev_tx_t geneve6_xmit_skb(stru
 			goto tx_error;
 
 		prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
-					   iip, skb);
+					   ip_hdr(skb), skb);
 		ttl = geneve->ttl;
 		if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
 			ttl = 1;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/ipvlan/ipvlan_main.c linux-libre-4.9-rc8-gnu/drivers/net/ipvlan/ipvlan_main.c
--- linux-libre-4.9-rc7-gnu/drivers/net/ipvlan/ipvlan_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/ipvlan/ipvlan_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -497,6 +497,7 @@ static int ipvlan_link_new(struct net *s
 	struct net_device *phy_dev;
 	int err;
 	u16 mode = IPVLAN_MODE_L3;
+	bool create = false;
 
 	if (!tb[IFLA_LINK])
 		return -EINVAL;
@@ -513,6 +514,7 @@ static int ipvlan_link_new(struct net *s
 		err = ipvlan_port_create(phy_dev);
 		if (err < 0)
 			return err;
+		create = true;
 	}
 
 	if (data && data[IFLA_IPVLAN_MODE])
@@ -536,22 +538,27 @@ static int ipvlan_link_new(struct net *s
 
 	err = register_netdevice(dev);
 	if (err < 0)
-		return err;
+		goto destroy_ipvlan_port;
 
 	err = netdev_upper_dev_link(phy_dev, dev);
 	if (err) {
-		unregister_netdevice(dev);
-		return err;
+		goto unregister_netdev;
 	}
 	err = ipvlan_set_port_mode(port, mode);
 	if (err) {
-		unregister_netdevice(dev);
-		return err;
+		goto unregister_netdev;
 	}
 
 	list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans);
 	netif_stacked_transfer_operstate(phy_dev, dev);
 	return 0;
+
+unregister_netdev:
+	unregister_netdevice(dev);
+destroy_ipvlan_port:
+	if (create)
+		ipvlan_port_destroy(phy_dev);
+	return err;
 }
 
 static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/irda/w83977af_ir.c linux-libre-4.9-rc8-gnu/drivers/net/irda/w83977af_ir.c
--- linux-libre-4.9-rc7-gnu/drivers/net/irda/w83977af_ir.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/irda/w83977af_ir.c	2016-12-04 15:50:51.000000000 -0500
@@ -518,7 +518,9 @@ static netdev_tx_t w83977af_hard_xmit(st
 		
 		mtt = irda_get_mtt(skb);
 		pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
-			if (mtt)
+			if (mtt > 1000)
+				mdelay(mtt/1000);
+			else if (mtt)
 				udelay(mtt);
 
 			/* Enable DMA interrupt */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/macvtap.c linux-libre-4.9-rc8-gnu/drivers/net/macvtap.c
--- linux-libre-4.9-rc7-gnu/drivers/net/macvtap.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/macvtap.c	2016-12-04 15:50:51.000000000 -0500
@@ -491,7 +491,13 @@ static int macvtap_newlink(struct net *s
 	/* Don't put anything that may fail after macvlan_common_newlink
 	 * because we can't undo what it does.
 	 */
-	return macvlan_common_newlink(src_net, dev, tb, data);
+	err = macvlan_common_newlink(src_net, dev, tb, data);
+	if (err) {
+		netdev_rx_handler_unregister(dev);
+		return err;
+	}
+
+	return 0;
 }
 
 static void macvtap_dellink(struct net_device *dev,
@@ -736,13 +742,8 @@ static ssize_t macvtap_get_user(struct m
 
 	if (zerocopy)
 		err = zerocopy_sg_from_iter(skb, from);
-	else {
+	else
 		err = skb_copy_datagram_from_iter(skb, 0, from, len);
-		if (!err && m && m->msg_control) {
-			struct ubuf_info *uarg = m->msg_control;
-			uarg->callback(uarg, false);
-		}
-	}
 
 	if (err)
 		goto err_kfree;
@@ -773,7 +774,11 @@ static ssize_t macvtap_get_user(struct m
 		skb_shinfo(skb)->destructor_arg = m->msg_control;
 		skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+	} else if (m && m->msg_control) {
+		struct ubuf_info *uarg = m->msg_control;
+		uarg->callback(uarg, false);
 	}
+
 	if (vlan) {
 		skb->dev = vlan->dev;
 		dev_queue_xmit(skb);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/phy/realtek.c linux-libre-4.9-rc8-gnu/drivers/net/phy/realtek.c
--- linux-libre-4.9-rc7-gnu/drivers/net/phy/realtek.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/phy/realtek.c	2016-12-04 15:50:51.000000000 -0500
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct p
 	if (ret < 0)
 		return ret;
 
-	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-		/* enable TXDLY */
-		phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
-		reg = phy_read(phydev, 0x11);
+	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+	reg = phy_read(phydev, 0x11);
+
+	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
 		reg |= RTL8211F_TX_DELAY;
-		phy_write(phydev, 0x11, reg);
-		/* restore to default page 0 */
-		phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
-	}
+	else
+		reg &= ~RTL8211F_TX_DELAY;
+
+	phy_write(phydev, 0x11, reg);
+	/* restore to default page 0 */
+	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/tun.c linux-libre-4.9-rc8-gnu/drivers/net/tun.c
--- linux-libre-4.9-rc7-gnu/drivers/net/tun.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/tun.c	2016-12-04 15:50:51.000000000 -0500
@@ -1246,13 +1246,8 @@ static ssize_t tun_get_user(struct tun_s
 
 	if (zerocopy)
 		err = zerocopy_sg_from_iter(skb, from);
-	else {
+	else
 		err = skb_copy_datagram_from_iter(skb, 0, from, len);
-		if (!err && msg_control) {
-			struct ubuf_info *uarg = msg_control;
-			uarg->callback(uarg, false);
-		}
-	}
 
 	if (err) {
 		this_cpu_inc(tun->pcpu_stats->rx_dropped);
@@ -1298,6 +1293,9 @@ static ssize_t tun_get_user(struct tun_s
 		skb_shinfo(skb)->destructor_arg = msg_control;
 		skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+	} else if (msg_control) {
+		struct ubuf_info *uarg = msg_control;
+		uarg->callback(uarg, false);
 	}
 
 	skb_reset_network_header(skb);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/usb/asix_devices.c linux-libre-4.9-rc8-gnu/drivers/net/usb/asix_devices.c
--- linux-libre-4.9-rc7-gnu/drivers/net/usb/asix_devices.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/usb/asix_devices.c	2016-12-04 15:50:51.000000000 -0500
@@ -603,12 +603,12 @@ static void ax88772_suspend(struct usbne
 	u16 medium;
 
 	/* Stop MAC operation */
-	medium = asix_read_medium_status(dev, 0);
+	medium = asix_read_medium_status(dev, 1);
 	medium &= ~AX_MEDIUM_RE;
-	asix_write_medium_mode(dev, medium, 0);
+	asix_write_medium_mode(dev, medium, 1);
 
 	netdev_dbg(dev->net, "ax88772_suspend: medium=0x%04x\n",
-		   asix_read_medium_status(dev, 0));
+		   asix_read_medium_status(dev, 1));
 
 	/* Preserve BMCR for restoring */
 	priv->presvd_phy_bmcr =
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/usb/cdc_ether.c linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_ether.c
--- linux-libre-4.9-rc7-gnu/drivers/net/usb/cdc_ether.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_ether.c	2016-12-04 15:50:51.000000000 -0500
@@ -388,12 +388,6 @@ void usbnet_cdc_status(struct usbnet *de
 	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
 		netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
 			  event->wValue ? "on" : "off");
-
-		/* Work-around for devices with broken off-notifications */
-		if (event->wValue &&
-		    !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state))
-			usbnet_link_change(dev, 0, 0);
-
 		usbnet_link_change(dev, !!event->wValue, 0);
 		break;
 	case USB_CDC_NOTIFY_SPEED_CHANGE:	/* tx/rx rates */
@@ -466,6 +460,36 @@ static int usbnet_cdc_zte_rx_fixup(struc
 	return 1;
 }
 
+/* Ensure correct link state
+ *
+ * Some devices (ZTE MF823/831/910) export two carrier on notifications when
+ * connected. This causes the link state to be incorrect. Work around this by
+ * always setting the state to off, then on.
+ */
+void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb)
+{
+	struct usb_cdc_notification *event;
+
+	if (urb->actual_length < sizeof(*event))
+		return;
+
+	event = urb->transfer_buffer;
+
+	if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) {
+		usbnet_cdc_status(dev, urb);
+		return;
+	}
+
+	netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
+		  event->wValue ? "on" : "off");
+
+	if (event->wValue &&
+	    netif_carrier_ok(dev->net))
+		netif_carrier_off(dev->net);
+
+	usbnet_link_change(dev, !!event->wValue, 0);
+}
+
 static const struct driver_info	cdc_info = {
 	.description =	"CDC Ethernet Device",
 	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
@@ -481,7 +505,7 @@ static const struct driver_info	zte_cdc_
 	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
 	.bind =		usbnet_cdc_zte_bind,
 	.unbind =	usbnet_cdc_unbind,
-	.status =	usbnet_cdc_status,
+	.status =	usbnet_cdc_zte_status,
 	.set_rx_mode =	usbnet_cdc_update_filter,
 	.manage_power =	usbnet_manage_power,
 	.rx_fixup = usbnet_cdc_zte_rx_fixup,
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/usb/qmi_wwan.c linux-libre-4.9-rc8-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-4.9-rc7-gnu/drivers/net/usb/qmi_wwan.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/usb/qmi_wwan.c	2016-12-04 15:50:51.000000000 -0500
@@ -894,6 +894,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},	/* Alcatel L800MA */
 	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
 	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)},	/* Telit LE922A */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)},	/* Telit LE920 */
 	{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},	/* XS Stick W100-2 from 4G Systems */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/vxlan.c linux-libre-4.9-rc8-gnu/drivers/net/vxlan.c
--- linux-libre-4.9-rc7-gnu/drivers/net/vxlan.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/vxlan.c	2016-12-04 15:50:51.000000000 -0500
@@ -611,6 +611,7 @@ static int vxlan_fdb_create(struct vxlan
 	struct vxlan_rdst *rd = NULL;
 	struct vxlan_fdb *f;
 	int notify = 0;
+	int rc;
 
 	f = __vxlan_find_mac(vxlan, mac);
 	if (f) {
@@ -641,8 +642,7 @@ static int vxlan_fdb_create(struct vxlan
 		if ((flags & NLM_F_APPEND) &&
 		    (is_multicast_ether_addr(f->eth_addr) ||
 		     is_zero_ether_addr(f->eth_addr))) {
-			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex,
-						  &rd);
+			rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
 
 			if (rc < 0)
 				return rc;
@@ -673,7 +673,11 @@ static int vxlan_fdb_create(struct vxlan
 		INIT_LIST_HEAD(&f->remotes);
 		memcpy(f->eth_addr, mac, ETH_ALEN);
 
-		vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
+		rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
+		if (rc < 0) {
+			kfree(f);
+			return rc;
+		}
 
 		++vxlan->addrcnt;
 		hlist_add_head_rcu(&f->hlist,
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c linux-libre-4.9-rc8-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c
--- linux-libre-4.9-rc7-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/net/wireless/marvell/mwifiex/cfg80211.c	2016-12-04 15:50:51.000000000 -0500
@@ -2222,8 +2222,9 @@ done:
 			is_scanning_required = 1;
 		} else {
 			mwifiex_dbg(priv->adapter, MSG,
-				    "info: trying to associate to '%s' bssid %pM\n",
-				    (char *)req_ssid.ssid, bss->bssid);
+				    "info: trying to associate to '%.*s' bssid %pM\n",
+				    req_ssid.ssid_len, (char *)req_ssid.ssid,
+				    bss->bssid);
 			memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
 			break;
 		}
@@ -2283,8 +2284,8 @@ mwifiex_cfg80211_connect(struct wiphy *w
 	}
 
 	mwifiex_dbg(adapter, INFO,
-		    "info: Trying to associate to %s and bssid %pM\n",
-		    (char *)sme->ssid, sme->bssid);
+		    "info: Trying to associate to %.*s and bssid %pM\n",
+		    (int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
 
 	if (!mwifiex_stop_bg_scan(priv))
 		cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
@@ -2417,8 +2418,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy
 	}
 
 	mwifiex_dbg(priv->adapter, MSG,
-		    "info: trying to join to %s and bssid %pM\n",
-		    (char *)params->ssid, params->bssid);
+		    "info: trying to join to %.*s and bssid %pM\n",
+		    params->ssid_len, (char *)params->ssid, params->bssid);
 
 	mwifiex_set_ibss_params(priv, params);
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/of/of_mdio.c linux-libre-4.9-rc8-gnu/drivers/of/of_mdio.c
--- linux-libre-4.9-rc7-gnu/drivers/of/of_mdio.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/of/of_mdio.c	2016-12-04 15:50:51.000000000 -0500
@@ -490,3 +490,18 @@ int of_phy_register_fixed_link(struct de
 	return -ENODEV;
 }
 EXPORT_SYMBOL(of_phy_register_fixed_link);
+
+void of_phy_deregister_fixed_link(struct device_node *np)
+{
+	struct phy_device *phydev;
+
+	phydev = of_phy_find_device(np);
+	if (!phydev)
+		return;
+
+	fixed_phy_unregister(phydev);
+
+	put_device(&phydev->mdio.dev);	/* of_phy_find_device() */
+	phy_device_free(phydev);	/* fixed_phy_register() */
+}
+EXPORT_SYMBOL(of_phy_deregister_fixed_link);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/pci/host/pcie-designware-plat.c linux-libre-4.9-rc8-gnu/drivers/pci/host/pcie-designware-plat.c
--- linux-libre-4.9-rc7-gnu/drivers/pci/host/pcie-designware-plat.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/pci/host/pcie-designware-plat.c	2016-12-04 15:50:51.000000000 -0500
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
  *
- * Authors: Joao Pinto <jpmpinto@gmail.com>
+ * Authors: Joao Pinto <Joao.Pinto@synopsys.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/pci/pcie/aer/aer_inject.c linux-libre-4.9-rc8-gnu/drivers/pci/pcie/aer/aer_inject.c
--- linux-libre-4.9-rc7-gnu/drivers/pci/pcie/aer/aer_inject.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/pci/pcie/aer/aer_inject.c	2016-12-04 15:50:51.000000000 -0500
@@ -307,20 +307,6 @@ out:
 	return 0;
 }
 
-static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
-{
-	while (1) {
-		if (!pci_is_pcie(dev))
-			break;
-		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
-			return dev;
-		if (!dev->bus->self)
-			break;
-		dev = dev->bus->self;
-	}
-	return NULL;
-}
-
 static int find_aer_device_iter(struct device *device, void *data)
 {
 	struct pcie_device **result = data;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/pci/probe.c linux-libre-4.9-rc8-gnu/drivers/pci/probe.c
--- linux-libre-4.9-rc7-gnu/drivers/pci/probe.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/pci/probe.c	2016-12-04 15:50:51.000000000 -0500
@@ -1439,6 +1439,21 @@ static void program_hpp_type1(struct pci
 		dev_warn(&dev->dev, "PCI-X settings not supported\n");
 }
 
+static bool pcie_root_rcb_set(struct pci_dev *dev)
+{
+	struct pci_dev *rp = pcie_find_root_port(dev);
+	u16 lnkctl;
+
+	if (!rp)
+		return false;
+
+	pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
+	if (lnkctl & PCI_EXP_LNKCTL_RCB)
+		return true;
+
+	return false;
+}
+
 static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 {
 	int pos;
@@ -1468,9 +1483,20 @@ static void program_hpp_type2(struct pci
 			~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
 
 	/* Initialize Link Control Register */
-	if (pcie_cap_has_lnkctl(dev))
+	if (pcie_cap_has_lnkctl(dev)) {
+
+		/*
+		 * If the Root Port supports Read Completion Boundary of
+		 * 128, set RCB to 128.  Otherwise, clear it.
+		 */
+		hpp->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+		hpp->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+		if (pcie_root_rcb_set(dev))
+			hpp->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+
 		pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
 			~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
+	}
 
 	/* Find Advanced Error Reporting Enhanced Capability */
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/pwm/pwm-meson.c linux-libre-4.9-rc8-gnu/drivers/pwm/pwm-meson.c
--- linux-libre-4.9-rc7-gnu/drivers/pwm/pwm-meson.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/pwm/pwm-meson.c	2016-12-04 15:50:51.000000000 -0500
@@ -474,6 +474,7 @@ static int meson_pwm_probe(struct platfo
 	if (IS_ERR(meson->base))
 		return PTR_ERR(meson->base);
 
+	spin_lock_init(&meson->lock);
 	meson->chip.dev = &pdev->dev;
 	meson->chip.ops = &meson_pwm_ops;
 	meson->chip.base = -1;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/pwm/sysfs.c linux-libre-4.9-rc8-gnu/drivers/pwm/sysfs.c
--- linux-libre-4.9-rc7-gnu/drivers/pwm/sysfs.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/pwm/sysfs.c	2016-12-04 15:50:51.000000000 -0500
@@ -425,6 +425,8 @@ void pwmchip_sysfs_unexport_children(str
 		if (test_bit(PWMF_EXPORTED, &pwm->flags))
 			pwm_unexport_child(parent, pwm);
 	}
+
+	put_device(parent);
 }
 
 static int __init pwm_sysfs_init(void)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/be2iscsi/be_mgmt.c linux-libre-4.9-rc8-gnu/drivers/scsi/be2iscsi/be_mgmt.c
--- linux-libre-4.9-rc7-gnu/drivers/scsi/be2iscsi/be_mgmt.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/be2iscsi/be_mgmt.c	2016-12-04 15:50:51.000000000 -0500
@@ -1083,7 +1083,7 @@ unsigned int beiscsi_boot_get_sinfo(stru
 	nonemb_cmd = &phba->boot_struct.nonemb_cmd;
 	nonemb_cmd->size = sizeof(*resp);
 	nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
-					      sizeof(nonemb_cmd->size),
+					      nonemb_cmd->size,
 					      &nonemb_cmd->dma);
 	if (!nonemb_cmd->va) {
 		mutex_unlock(&ctrl->mbox_lock);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/hpsa.c linux-libre-4.9-rc8-gnu/drivers/scsi/hpsa.c
--- linux-libre-4.9-rc7-gnu/drivers/scsi/hpsa.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/hpsa.c	2016-12-04 15:50:51.000000000 -0500
@@ -2009,7 +2009,7 @@ static struct hpsa_scsi_dev_t *lookup_hp
 
 static int hpsa_slave_alloc(struct scsi_device *sdev)
 {
-	struct hpsa_scsi_dev_t *sd;
+	struct hpsa_scsi_dev_t *sd = NULL;
 	unsigned long flags;
 	struct ctlr_info *h;
 
@@ -2026,7 +2026,8 @@ static int hpsa_slave_alloc(struct scsi_
 			sd->target = sdev_id(sdev);
 			sd->lun = sdev->lun;
 		}
-	} else
+	}
+	if (!sd)
 		sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
 					sdev_id(sdev), sdev->lun);
 
@@ -3840,6 +3841,7 @@ static int hpsa_update_device_info(struc
 		sizeof(this_device->vendor));
 	memcpy(this_device->model, &inq_buff[16],
 		sizeof(this_device->model));
+	this_device->rev = inq_buff[2];
 	memset(this_device->device_id, 0,
 		sizeof(this_device->device_id));
 	if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8,
@@ -3929,10 +3931,14 @@ static void figure_bus_target_lun(struct
 
 	if (!is_logical_dev_addr_mode(lunaddrbytes)) {
 		/* physical device, target and lun filled in later */
-		if (is_hba_lunid(lunaddrbytes))
+		if (is_hba_lunid(lunaddrbytes)) {
+			int bus = HPSA_HBA_BUS;
+
+			if (!device->rev)
+				bus = HPSA_LEGACY_HBA_BUS;
 			hpsa_set_bus_target_lun(device,
-					HPSA_HBA_BUS, 0, lunid & 0x3fff);
-		else
+					bus, 0, lunid & 0x3fff);
+		} else
 			/* defer target, lun assignment for physical devices */
 			hpsa_set_bus_target_lun(device,
 					HPSA_PHYSICAL_DEVICE_BUS, -1, -1);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/hpsa.h linux-libre-4.9-rc8-gnu/drivers/scsi/hpsa.h
--- linux-libre-4.9-rc7-gnu/drivers/scsi/hpsa.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/hpsa.h	2016-12-04 15:50:51.000000000 -0500
@@ -69,6 +69,7 @@ struct hpsa_scsi_dev_t {
 	u64 sas_address;
 	unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
 	unsigned char model[16];        /* bytes 16-31 of inquiry data */
+	unsigned char rev;		/* byte 2 of inquiry data */
 	unsigned char raid_level;	/* from inquiry page 0xC1 */
 	unsigned char volume_offline;	/* discovered via TUR or VPD */
 	u16 queue_depth;		/* max queue_depth for this device */
@@ -402,6 +403,7 @@ struct offline_device_entry {
 #define HPSA_RAID_VOLUME_BUS		1
 #define HPSA_EXTERNAL_RAID_VOLUME_BUS	2
 #define HPSA_HBA_BUS			0
+#define HPSA_LEGACY_HBA_BUS		3
 
 /*
 	Send the command to the hardware
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/libfc/fc_lport.c linux-libre-4.9-rc8-gnu/drivers/scsi/libfc/fc_lport.c
--- linux-libre-4.9-rc7-gnu/drivers/scsi/libfc/fc_lport.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/libfc/fc_lport.c	2016-12-04 15:50:51.000000000 -0500
@@ -308,7 +308,7 @@ struct fc_host_statistics *fc_get_host_s
 	fc_stats = &lport->host_stats;
 	memset(fc_stats, 0, sizeof(struct fc_host_statistics));
 
-	fc_stats->seconds_since_last_reset = (lport->boot_time - jiffies) / HZ;
+	fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
 
 	for_each_possible_cpu(cpu) {
 		struct fc_stats *stats;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c linux-libre-4.9-rc8-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c
--- linux-libre-4.9-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-12-04 15:50:51.000000000 -0500
@@ -3885,6 +3885,11 @@ _scsih_temp_threshold_events(struct MPT3
 	}
 }
 
+static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
+{
+	return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
+}
+
 /**
  * _scsih_flush_running_cmds - completing outstanding commands.
  * @ioc: per adapter object
@@ -3906,6 +3911,9 @@ _scsih_flush_running_cmds(struct MPT3SAS
 		if (!scmd)
 			continue;
 		count++;
+		if (ata_12_16_cmd(scmd))
+			scsi_internal_device_unblock(scmd->device,
+							SDEV_RUNNING);
 		mpt3sas_base_free_smid(ioc, smid);
 		scsi_dma_unmap(scmd);
 		if (ioc->pci_error_recovery)
@@ -4010,11 +4018,6 @@ _scsih_eedp_error_handling(struct scsi_c
 	    SAM_STAT_CHECK_CONDITION;
 }
 
-static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
-{
-	return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
-}
-
 /**
  * scsih_qcmd - main scsi request entry point
  * @scmd: pointer to scsi command object
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/mvsas/mv_sas.c linux-libre-4.9-rc8-gnu/drivers/scsi/mvsas/mv_sas.c
--- linux-libre-4.9-rc7-gnu/drivers/scsi/mvsas/mv_sas.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/mvsas/mv_sas.c	2016-12-04 15:50:51.000000000 -0500
@@ -791,8 +791,10 @@ static int mvs_task_prep(struct sas_task
 	slot->slot_tag = tag;
 
 	slot->buf = pci_pool_alloc(mvi->dma_pool, GFP_ATOMIC, &slot->buf_dma);
-	if (!slot->buf)
+	if (!slot->buf) {
+		rc = -ENOMEM;
 		goto err_out_tag;
+	}
 	memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
 
 	tei.task = task;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/drivers/scsi/qlogicpti.h linux-libre-4.9-rc8-gnu/drivers/scsi/qlogicpti.h
--- linux-libre-4.9-rc7-gnu/drivers/scsi/qlogicpti.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/drivers/scsi/qlogicpti.h	2016-12-04 15:50:51.000000000 -0500
@@ -356,8 +356,8 @@ struct qlogicpti {
 
 	/* The rest of the elements are unimportant for performance. */
 	struct qlogicpti         *next;
-	__u32                     res_dvma;             /* Ptr to RESPONSE bufs (DVMA)*/
-	__u32                     req_dvma;             /* Ptr to REQUEST bufs (DVMA) */
+	dma_addr_t                res_dvma;             /* Ptr to RESPONSE bufs (DVMA)*/
+	dma_addr_t                req_dvma;             /* Ptr to REQUEST bufs (DVMA) */
 	u_char	                  fware_majrev, fware_minrev, fware_micrev;
 	struct Scsi_Host         *qhost;
 	int                       qpti_id;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/fs/cifs/cifsencrypt.c linux-libre-4.9-rc8-gnu/fs/cifs/cifsencrypt.c
--- linux-libre-4.9-rc7-gnu/fs/cifs/cifsencrypt.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/fs/cifs/cifsencrypt.c	2016-12-04 15:50:51.000000000 -0500
@@ -808,7 +808,11 @@ calc_seckey(struct cifs_ses *ses)
 	struct crypto_skcipher *tfm_arc4;
 	struct scatterlist sgin, sgout;
 	struct skcipher_request *req;
-	unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
+	unsigned char *sec_key;
+
+	sec_key = kmalloc(CIFS_SESS_KEY_SIZE, GFP_KERNEL);
+	if (sec_key == NULL)
+		return -ENOMEM;
 
 	get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
 
@@ -816,7 +820,7 @@ calc_seckey(struct cifs_ses *ses)
 	if (IS_ERR(tfm_arc4)) {
 		rc = PTR_ERR(tfm_arc4);
 		cifs_dbg(VFS, "could not allocate crypto API arc4\n");
-		return rc;
+		goto out;
 	}
 
 	rc = crypto_skcipher_setkey(tfm_arc4, ses->auth_key.response,
@@ -854,7 +858,8 @@ calc_seckey(struct cifs_ses *ses)
 
 out_free_cipher:
 	crypto_free_skcipher(tfm_arc4);
-
+out:
+	kfree(sec_key);
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/fs/cifs/cifssmb.c linux-libre-4.9-rc8-gnu/fs/cifs/cifssmb.c
--- linux-libre-4.9-rc7-gnu/fs/cifs/cifssmb.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/fs/cifs/cifssmb.c	2016-12-04 15:50:51.000000000 -0500
@@ -3427,6 +3427,7 @@ static __u16 ACL_to_cifs_posix(char *par
 	__u16 rc = 0;
 	struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
 	struct posix_acl_xattr_header *local_acl = (void *)pACL;
+	struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
 	int count;
 	int i;
 
@@ -3453,8 +3454,7 @@ static __u16 ACL_to_cifs_posix(char *par
 		return 0;
 	}
 	for (i = 0; i < count; i++) {
-		rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
-			(struct posix_acl_xattr_entry *)(local_acl + 1));
+		rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]);
 		if (rc != 0) {
 			/* ACE not converted */
 			break;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/fs/cifs/connect.c linux-libre-4.9-rc8-gnu/fs/cifs/connect.c
--- linux-libre-4.9-rc7-gnu/fs/cifs/connect.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/fs/cifs/connect.c	2016-12-04 15:50:51.000000000 -0500
@@ -412,6 +412,9 @@ cifs_reconnect(struct TCP_Server_Info *s
 		}
 	} while (server->tcpStatus == CifsNeedReconnect);
 
+	if (server->tcpStatus == CifsNeedNegotiate)
+		mod_delayed_work(cifsiod_wq, &server->echo, 0);
+
 	return rc;
 }
 
@@ -421,17 +424,25 @@ cifs_echo_request(struct work_struct *wo
 	int rc;
 	struct TCP_Server_Info *server = container_of(work,
 					struct TCP_Server_Info, echo.work);
-	unsigned long echo_interval = server->echo_interval;
+	unsigned long echo_interval;
 
 	/*
-	 * We cannot send an echo if it is disabled or until the
-	 * NEGOTIATE_PROTOCOL request is done, which is indicated by
-	 * server->ops->need_neg() == true. Also, no need to ping if
-	 * we got a response recently.
+	 * If we need to renegotiate, set echo interval to zero to
+	 * immediately call echo service where we can renegotiate.
+	 */
+	if (server->tcpStatus == CifsNeedNegotiate)
+		echo_interval = 0;
+	else
+		echo_interval = server->echo_interval;
+
+	/*
+	 * We cannot send an echo if it is disabled.
+	 * Also, no need to ping if we got a response recently.
 	 */
 
 	if (server->tcpStatus == CifsNeedReconnect ||
-	    server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
+	    server->tcpStatus == CifsExiting ||
+	    server->tcpStatus == CifsNew ||
 	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
 	    time_before(jiffies, server->lstrp + echo_interval - HZ))
 		goto requeue_echo;
@@ -442,7 +453,7 @@ cifs_echo_request(struct work_struct *wo
 			 server->hostname);
 
 requeue_echo:
-	queue_delayed_work(cifsiod_wq, &server->echo, echo_interval);
+	queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
 }
 
 static bool
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/fs/isofs/rock.c linux-libre-4.9-rc8-gnu/fs/isofs/rock.c
--- linux-libre-4.9-rc7-gnu/fs/isofs/rock.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/fs/isofs/rock.c	2016-12-04 15:50:51.000000000 -0500
@@ -377,9 +377,9 @@ repeat:
 			{
 				int p;
 				for (p = 0; p < rr->u.ER.len_id; p++)
-					printk("%c", rr->u.ER.data[p]);
+					printk(KERN_CONT "%c", rr->u.ER.data[p]);
 			}
-			printk("\n");
+			printk(KERN_CONT "\n");
 			break;
 		case SIG('P', 'X'):
 			inode->i_mode = isonum_733(rr->u.PX.mode);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/fs/overlayfs/super.c linux-libre-4.9-rc8-gnu/fs/overlayfs/super.c
--- linux-libre-4.9-rc7-gnu/fs/overlayfs/super.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/fs/overlayfs/super.c	2016-12-04 15:50:51.000000000 -0500
@@ -328,11 +328,11 @@ static struct dentry *ovl_d_real(struct
 	if (!real)
 		goto bug;
 
+	/* Handle recursion */
+	real = d_real(real, inode, open_flags);
+
 	if (!inode || inode == d_inode(real))
 		return real;
-
-	/* Handle recursion */
-	return d_real(real, inode, open_flags);
 bug:
 	WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found\n", dentry,
 	     inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/asm-generic/export.h linux-libre-4.9-rc8-gnu/include/asm-generic/export.h
--- linux-libre-4.9-rc7-gnu/include/asm-generic/export.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/asm-generic/export.h	2016-12-04 15:50:51.000000000 -0500
@@ -54,6 +54,7 @@ KSYM(__kstrtab_\name):
 KSYM(__kcrctab_\name):
 	__put KSYM(__crc_\name)
 	.weak KSYM(__crc_\name)
+	.set KSYM(__crc_\name), 0
 	.previous
 #endif
 #endif
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/linux/compiler-gcc.h linux-libre-4.9-rc8-gnu/include/linux/compiler-gcc.h
--- linux-libre-4.9-rc7-gnu/include/linux/compiler-gcc.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/linux/compiler-gcc.h	2016-12-04 15:50:51.000000000 -0500
@@ -263,7 +263,9 @@
 #endif
 #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
 
-#if GCC_VERSION >= 50000
+#if GCC_VERSION >= 70000
+#define KASAN_ABI_VERSION 5
+#elif GCC_VERSION >= 50000
 #define KASAN_ABI_VERSION 4
 #elif GCC_VERSION >= 40902
 #define KASAN_ABI_VERSION 3
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/linux/mlx4/device.h linux-libre-4.9-rc8-gnu/include/linux/mlx4/device.h
--- linux-libre-4.9-rc7-gnu/include/linux/mlx4/device.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/linux/mlx4/device.h	2016-12-04 15:50:51.000000000 -0500
@@ -476,7 +476,6 @@ enum {
 enum {
 	MLX4_INTERFACE_STATE_UP		= 1 << 0,
 	MLX4_INTERFACE_STATE_DELETION	= 1 << 1,
-	MLX4_INTERFACE_STATE_SHUTDOWN	= 1 << 2,
 };
 
 #define MSTR_SM_CHANGE_MASK (MLX4_EQ_PORT_INFO_MSTR_SM_SL_CHANGE_MASK | \
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/linux/of_mdio.h linux-libre-4.9-rc8-gnu/include/linux/of_mdio.h
--- linux-libre-4.9-rc7-gnu/include/linux/of_mdio.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/linux/of_mdio.h	2016-12-04 15:50:51.000000000 -0500
@@ -29,6 +29,7 @@ struct phy_device *of_phy_attach(struct
 extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
 extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
 extern int of_phy_register_fixed_link(struct device_node *np);
+extern void of_phy_deregister_fixed_link(struct device_node *np);
 extern bool of_phy_is_fixed_link(struct device_node *np);
 
 #else /* CONFIG_OF */
@@ -83,6 +84,9 @@ static inline int of_phy_register_fixed_
 {
 	return -ENOSYS;
 }
+static inline void of_phy_deregister_fixed_link(struct device_node *np)
+{
+}
 static inline bool of_phy_is_fixed_link(struct device_node *np)
 {
 	return false;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/linux/pagemap.h linux-libre-4.9-rc8-gnu/include/linux/pagemap.h
--- linux-libre-4.9-rc7-gnu/include/linux/pagemap.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/linux/pagemap.h	2016-12-04 15:50:51.000000000 -0500
@@ -374,16 +374,13 @@ static inline struct page *read_mapping_
 }
 
 /*
- * Get the offset in PAGE_SIZE.
- * (TODO: hugepage should have ->index in PAGE_SIZE)
+ * Get index of the page with in radix-tree
+ * (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE)
  */
-static inline pgoff_t page_to_pgoff(struct page *page)
+static inline pgoff_t page_to_index(struct page *page)
 {
 	pgoff_t pgoff;
 
-	if (unlikely(PageHeadHuge(page)))
-		return page->index << compound_order(page);
-
 	if (likely(!PageTransTail(page)))
 		return page->index;
 
@@ -397,6 +394,18 @@ static inline pgoff_t page_to_pgoff(stru
 }
 
 /*
+ * Get the offset in PAGE_SIZE.
+ * (TODO: hugepage should have ->index in PAGE_SIZE)
+ */
+static inline pgoff_t page_to_pgoff(struct page *page)
+{
+	if (unlikely(PageHeadHuge(page)))
+		return page->index << compound_order(page);
+
+	return page_to_index(page);
+}
+
+/*
  * Return byte-offset into filesystem object for page.
  */
 static inline loff_t page_offset(struct page *page)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/linux/pci.h linux-libre-4.9-rc8-gnu/include/linux/pci.h
--- linux-libre-4.9-rc7-gnu/include/linux/pci.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/linux/pci.h	2016-12-04 15:50:51.000000000 -0500
@@ -1928,6 +1928,20 @@ static inline int pci_pcie_type(const st
 	return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
+static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+{
+	while (1) {
+		if (!pci_is_pcie(dev))
+			break;
+		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+			return dev;
+		if (!dev->bus->self)
+			break;
+		dev = dev->bus->self;
+	}
+	return NULL;
+}
+
 void pci_request_acs(void);
 bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
 bool pci_acs_path_enabled(struct pci_dev *start,
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/net/ipv6.h linux-libre-4.9-rc8-gnu/include/net/ipv6.h
--- linux-libre-4.9-rc7-gnu/include/net/ipv6.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/net/ipv6.h	2016-12-04 15:50:51.000000000 -0500
@@ -970,6 +970,8 @@ int compat_ipv6_setsockopt(struct sock *
 int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
 			   char __user *optval, int __user *optlen);
 
+int __ip6_datagram_connect(struct sock *sk, struct sockaddr *addr,
+			   int addr_len);
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len);
 int ip6_datagram_connect_v6_only(struct sock *sk, struct sockaddr *addr,
 				 int addr_len);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/net/netfilter/nf_conntrack.h linux-libre-4.9-rc8-gnu/include/net/netfilter/nf_conntrack.h
--- linux-libre-4.9-rc7-gnu/include/net/netfilter/nf_conntrack.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/net/netfilter/nf_conntrack.h	2016-12-04 15:50:51.000000000 -0500
@@ -100,6 +100,9 @@ struct nf_conn {
 
 	possible_net_t ct_net;
 
+#if IS_ENABLED(CONFIG_NF_NAT)
+	struct rhlist_head nat_bysource;
+#endif
 	/* all members below initialized via memset */
 	u8 __nfct_init_offset[0];
 
@@ -117,9 +120,6 @@ struct nf_conn {
 	/* Extensions */
 	struct nf_ct_ext *ext;
 
-#if IS_ENABLED(CONFIG_NF_NAT)
-	struct rhash_head	nat_bysource;
-#endif
 	/* Storage reserved for other modules, must be the last member */
 	union nf_conntrack_proto proto;
 };
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/net/netfilter/nf_tables.h linux-libre-4.9-rc8-gnu/include/net/netfilter/nf_tables.h
--- linux-libre-4.9-rc7-gnu/include/net/netfilter/nf_tables.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/net/netfilter/nf_tables.h	2016-12-04 15:50:51.000000000 -0500
@@ -313,7 +313,7 @@ void nft_unregister_set(struct nft_set_o
  * 	@size: maximum set size
  * 	@nelems: number of elements
  * 	@ndeact: number of deactivated elements queued for removal
- * 	@timeout: default timeout value in msecs
+ *	@timeout: default timeout value in jiffies
  * 	@gc_int: garbage collection interval in msecs
  *	@policy: set parameterization (see enum nft_set_policies)
  *	@udlen: user data length
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/uapi/linux/input-event-codes.h linux-libre-4.9-rc8-gnu/include/uapi/linux/input-event-codes.h
--- linux-libre-4.9-rc7-gnu/include/uapi/linux/input-event-codes.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/uapi/linux/input-event-codes.h	2016-12-04 15:50:51.000000000 -0500
@@ -640,7 +640,7 @@
  * Control a data application associated with the currently viewed channel,
  * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
  */
-#define KEY_DATA			0x275
+#define KEY_DATA			0x277
 
 #define BTN_TRIGGER_HAPPY		0x2c0
 #define BTN_TRIGGER_HAPPY1		0x2c0
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/include/uapi/linux/tc_act/Kbuild linux-libre-4.9-rc8-gnu/include/uapi/linux/tc_act/Kbuild
--- linux-libre-4.9-rc7-gnu/include/uapi/linux/tc_act/Kbuild	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/include/uapi/linux/tc_act/Kbuild	2016-12-04 15:50:51.000000000 -0500
@@ -11,3 +11,4 @@ header-y += tc_vlan.h
 header-y += tc_bpf.h
 header-y += tc_connmark.h
 header-y += tc_ife.h
+header-y += tc_tunnel_key.h
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/init/Kconfig linux-libre-4.9-rc8-gnu/init/Kconfig
--- linux-libre-4.9-rc7-gnu/init/Kconfig	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/init/Kconfig	2016-12-04 15:50:51.000000000 -0500
@@ -1945,7 +1945,6 @@ config MODULE_FORCE_UNLOAD
 
 config MODVERSIONS
 	bool "Module versioning support"
-	depends on BROKEN
 	help
 	  Usually, you have to use modules compiled with your kernel.
 	  Saying Y here makes it sometimes possible to use modules
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/kernel/bpf/verifier.c linux-libre-4.9-rc8-gnu/kernel/bpf/verifier.c
--- linux-libre-4.9-rc7-gnu/kernel/bpf/verifier.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/kernel/bpf/verifier.c	2016-12-04 15:50:51.000000000 -0500
@@ -2454,6 +2454,7 @@ static bool states_equal(struct bpf_veri
 			 struct bpf_verifier_state *old,
 			 struct bpf_verifier_state *cur)
 {
+	bool varlen_map_access = env->varlen_map_value_access;
 	struct bpf_reg_state *rold, *rcur;
 	int i;
 
@@ -2467,12 +2468,17 @@ static bool states_equal(struct bpf_veri
 		/* If the ranges were not the same, but everything else was and
 		 * we didn't do a variable access into a map then we are a-ok.
 		 */
-		if (!env->varlen_map_value_access &&
+		if (!varlen_map_access &&
 		    rold->type == rcur->type && rold->imm == rcur->imm)
 			continue;
 
+		/* If we didn't map access then again we don't care about the
+		 * mismatched range values and it's ok if our old type was
+		 * UNKNOWN and we didn't go to a NOT_INIT'ed reg.
+		 */
 		if (rold->type == NOT_INIT ||
-		    (rold->type == UNKNOWN_VALUE && rcur->type != NOT_INIT))
+		    (!varlen_map_access && rold->type == UNKNOWN_VALUE &&
+		     rcur->type != NOT_INIT))
 			continue;
 
 		if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET &&
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/kernel/module.c linux-libre-4.9-rc8-gnu/kernel/module.c
--- linux-libre-4.9-rc7-gnu/kernel/module.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/kernel/module.c	2016-12-04 15:50:51.000000000 -0500
@@ -1301,8 +1301,9 @@ static int check_version(Elf_Shdr *sechd
 		goto bad_version;
 	}
 
-	pr_warn("%s: no symbol version for %s\n", mod->name, symname);
-	return 0;
+	/* Broken toolchain. Warn once, then let it go.. */
+	pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
+	return 1;
 
 bad_version:
 	pr_warn("%s: disagrees about version of symbol %s\n",
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/lib/debugobjects.c linux-libre-4.9-rc8-gnu/lib/debugobjects.c
--- linux-libre-4.9-rc7-gnu/lib/debugobjects.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/lib/debugobjects.c	2016-12-04 15:50:51.000000000 -0500
@@ -362,6 +362,7 @@ void debug_object_init(void *addr, struc
 
 	__debug_object_init(addr, descr, 0);
 }
+EXPORT_SYMBOL_GPL(debug_object_init);
 
 /**
  * debug_object_init_on_stack - debug checks when an object on stack is
@@ -376,6 +377,7 @@ void debug_object_init_on_stack(void *ad
 
 	__debug_object_init(addr, descr, 1);
 }
+EXPORT_SYMBOL_GPL(debug_object_init_on_stack);
 
 /**
  * debug_object_activate - debug checks when an object is activated
@@ -449,6 +451,7 @@ int debug_object_activate(void *addr, st
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(debug_object_activate);
 
 /**
  * debug_object_deactivate - debug checks when an object is deactivated
@@ -496,6 +499,7 @@ void debug_object_deactivate(void *addr,
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_deactivate);
 
 /**
  * debug_object_destroy - debug checks when an object is destroyed
@@ -542,6 +546,7 @@ void debug_object_destroy(void *addr, st
 out_unlock:
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_destroy);
 
 /**
  * debug_object_free - debug checks when an object is freed
@@ -582,6 +587,7 @@ void debug_object_free(void *addr, struc
 out_unlock:
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_free);
 
 /**
  * debug_object_assert_init - debug checks when object should be init-ed
@@ -626,6 +632,7 @@ void debug_object_assert_init(void *addr
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_assert_init);
 
 /**
  * debug_object_active_state - debug checks object usage state machine
@@ -673,6 +680,7 @@ debug_object_active_state(void *addr, st
 
 	raw_spin_unlock_irqrestore(&db->lock, flags);
 }
+EXPORT_SYMBOL_GPL(debug_object_active_state);
 
 #ifdef CONFIG_DEBUG_OBJECTS_FREE
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/lib/test_kasan.c linux-libre-4.9-rc8-gnu/lib/test_kasan.c
--- linux-libre-4.9-rc7-gnu/lib/test_kasan.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/lib/test_kasan.c	2016-12-04 15:50:51.000000000 -0500
@@ -20,6 +20,11 @@
 #include <linux/uaccess.h>
 #include <linux/module.h>
 
+/*
+ * Note: test functions are marked noinline so that their names appear in
+ * reports.
+ */
+
 static noinline void __init kmalloc_oob_right(void)
 {
 	char *ptr;
@@ -411,6 +416,29 @@ static noinline void __init copy_user_te
 	kfree(kmem);
 }
 
+static noinline void __init use_after_scope_test(void)
+{
+	volatile char *volatile p;
+
+	pr_info("use-after-scope on int\n");
+	{
+		int local = 0;
+
+		p = (char *)&local;
+	}
+	p[0] = 1;
+	p[3] = 1;
+
+	pr_info("use-after-scope on array\n");
+	{
+		char local[1024] = {0};
+
+		p = local;
+	}
+	p[0] = 1;
+	p[1023] = 1;
+}
+
 static int __init kmalloc_tests_init(void)
 {
 	kmalloc_oob_right();
@@ -436,6 +464,7 @@ static int __init kmalloc_tests_init(voi
 	kasan_global_oob();
 	ksize_unpoisons_memory();
 	copy_user_test();
+	use_after_scope_test();
 	return -EAGAIN;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/MAINTAINERS linux-libre-4.9-rc8-gnu/MAINTAINERS
--- linux-libre-4.9-rc7-gnu/MAINTAINERS	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/MAINTAINERS	2016-12-04 15:50:51.000000000 -0500
@@ -9257,11 +9257,12 @@ S:	Maintained
 F:	drivers/pci/host/*layerscape*
 
 PCI DRIVER FOR IMX6
-M:	Richard Zhu <Richard.Zhu@freescale.com>
+M:	Richard Zhu <hongxing.zhu@nxp.com>
 M:	Lucas Stach <l.stach@pengutronix.de>
 L:	linux-pci@vger.kernel.org
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F:	drivers/pci/host/*imx6*
 
 PCI DRIVER FOR TI KEYSTONE
@@ -9320,17 +9321,11 @@ F:	drivers/pci/host/pci-exynos.c
 
 PCI DRIVER FOR SYNOPSIS DESIGNWARE
 M:	Jingoo Han <jingoohan1@gmail.com>
-M:	Pratyush Anand <pratyush.anand@gmail.com>
-L:	linux-pci@vger.kernel.org
-S:	Maintained
-F:	drivers/pci/host/*designware*
-
-PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE
-M:	Jose Abreu <Jose.Abreu@synopsys.com>
+M:	Joao Pinto <Joao.Pinto@synopsys.com>
 L:	linux-pci@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/pci/designware-pcie.txt
-F:	drivers/pci/host/pcie-designware-plat.c
+F:	drivers/pci/host/*designware*
 
 PCI DRIVER FOR GENERIC OF HOSTS
 M:	Will Deacon <will.deacon@arm.com>
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/Makefile linux-libre-4.9-rc8-gnu/Makefile
--- linux-libre-4.9-rc7-gnu/Makefile	2016-11-29 01:25:49.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/Makefile	2016-12-04 17:34:26.000000000 -0500
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc7-gnu
+EXTRAVERSION = -rc8-gnu
 NAME = Psychotic Stoned Sheep
 
 # *DOCUMENTATION*
@@ -607,6 +607,13 @@ else
 include/config/auto.conf: ;
 endif # $(dot-config)
 
+# For the kernel to actually contain only the needed exported symbols,
+# we have to build modules as well to determine what those symbols are.
+# (this can be evaluated only once include/config/auto.conf has been included)
+ifdef CONFIG_TRIM_UNUSED_KSYMS
+  KBUILD_MODULES := 1
+endif
+
 # The all: target is the default when no target is given on the
 # command line.
 # This allow a user to issue only 'make' to build a kernel including modules
@@ -944,7 +951,7 @@ ifdef CONFIG_GDB_SCRIPTS
 endif
 ifdef CONFIG_TRIM_UNUSED_KSYMS
 	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
-	  "$(MAKE) KBUILD_MODULES=1 -f $(srctree)/Makefile vmlinux_prereq"
+	  "$(MAKE) -f $(srctree)/Makefile vmlinux"
 endif
 
 # standalone target for easier testing
@@ -1019,8 +1026,6 @@ prepare2: prepare3 prepare-compiler-chec
 prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
                    include/config/auto.conf
 	$(cmd_crmodverdir)
-	$(Q)test -e include/generated/autoksyms.h || \
-	    touch   include/generated/autoksyms.h
 
 archprepare: archheaders archscripts prepare1 scripts_basic
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/huge_memory.c linux-libre-4.9-rc8-gnu/mm/huge_memory.c
--- linux-libre-4.9-rc7-gnu/mm/huge_memory.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/huge_memory.c	2016-12-04 15:50:51.000000000 -0500
@@ -1456,9 +1456,9 @@ bool move_huge_pmd(struct vm_area_struct
 		new_ptl = pmd_lockptr(mm, new_pmd);
 		if (new_ptl != old_ptl)
 			spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
-		if (pmd_present(*old_pmd) && pmd_dirty(*old_pmd))
-			force_flush = true;
 		pmd = pmdp_huge_get_and_clear(mm, old_addr, old_pmd);
+		if (pmd_present(pmd) && pmd_dirty(pmd))
+			force_flush = true;
 		VM_BUG_ON(!pmd_none(*new_pmd));
 
 		if (pmd_move_must_withdraw(new_ptl, old_ptl) &&
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/kasan/kasan.c linux-libre-4.9-rc8-gnu/mm/kasan/kasan.c
--- linux-libre-4.9-rc7-gnu/mm/kasan/kasan.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/kasan/kasan.c	2016-12-04 15:50:51.000000000 -0500
@@ -764,6 +764,25 @@ EXPORT_SYMBOL(__asan_storeN_noabort);
 void __asan_handle_no_return(void) {}
 EXPORT_SYMBOL(__asan_handle_no_return);
 
+/* Emitted by compiler to poison large objects when they go out of scope. */
+void __asan_poison_stack_memory(const void *addr, size_t size)
+{
+	/*
+	 * Addr is KASAN_SHADOW_SCALE_SIZE-aligned and the object is surrounded
+	 * by redzones, so we simply round up size to simplify logic.
+	 */
+	kasan_poison_shadow(addr, round_up(size, KASAN_SHADOW_SCALE_SIZE),
+			    KASAN_USE_AFTER_SCOPE);
+}
+EXPORT_SYMBOL(__asan_poison_stack_memory);
+
+/* Emitted by compiler to unpoison large objects when they go into scope. */
+void __asan_unpoison_stack_memory(const void *addr, size_t size)
+{
+	kasan_unpoison_shadow(addr, size);
+}
+EXPORT_SYMBOL(__asan_unpoison_stack_memory);
+
 #ifdef CONFIG_MEMORY_HOTPLUG
 static int kasan_mem_notifier(struct notifier_block *nb,
 			unsigned long action, void *data)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/kasan/kasan.h linux-libre-4.9-rc8-gnu/mm/kasan/kasan.h
--- linux-libre-4.9-rc7-gnu/mm/kasan/kasan.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/kasan/kasan.h	2016-12-04 15:50:51.000000000 -0500
@@ -21,6 +21,7 @@
 #define KASAN_STACK_MID         0xF2
 #define KASAN_STACK_RIGHT       0xF3
 #define KASAN_STACK_PARTIAL     0xF4
+#define KASAN_USE_AFTER_SCOPE   0xF8
 
 /* Don't break randconfig/all*config builds */
 #ifndef KASAN_ABI_VERSION
@@ -53,6 +54,9 @@ struct kasan_global {
 #if KASAN_ABI_VERSION >= 4
 	struct kasan_source_location *location;
 #endif
+#if KASAN_ABI_VERSION >= 5
+	char *odr_indicator;
+#endif
 };
 
 /**
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/kasan/report.c linux-libre-4.9-rc8-gnu/mm/kasan/report.c
--- linux-libre-4.9-rc7-gnu/mm/kasan/report.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/kasan/report.c	2016-12-04 15:50:51.000000000 -0500
@@ -90,6 +90,9 @@ static void print_error_description(stru
 	case KASAN_KMALLOC_FREE:
 		bug_type = "use-after-free";
 		break;
+	case KASAN_USE_AFTER_SCOPE:
+		bug_type = "use-after-scope";
+		break;
 	}
 
 	pr_err("BUG: KASAN: %s in %pS at addr %p\n",
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/khugepaged.c linux-libre-4.9-rc8-gnu/mm/khugepaged.c
--- linux-libre-4.9-rc7-gnu/mm/khugepaged.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/khugepaged.c	2016-12-04 15:50:51.000000000 -0500
@@ -103,6 +103,7 @@ static struct khugepaged_scan khugepaged
 	.mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
 };
 
+#ifdef CONFIG_SYSFS
 static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
 					 struct kobj_attribute *attr,
 					 char *buf)
@@ -295,6 +296,7 @@ struct attribute_group khugepaged_attr_g
 	.attrs = khugepaged_attr,
 	.name = "khugepaged",
 };
+#endif /* CONFIG_SYSFS */
 
 #define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB)
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/mlock.c linux-libre-4.9-rc8-gnu/mm/mlock.c
--- linux-libre-4.9-rc7-gnu/mm/mlock.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/mlock.c	2016-12-04 15:50:51.000000000 -0500
@@ -190,10 +190,13 @@ unsigned int munlock_vma_page(struct pag
 	 */
 	spin_lock_irq(zone_lru_lock(zone));
 
-	nr_pages = hpage_nr_pages(page);
-	if (!TestClearPageMlocked(page))
+	if (!TestClearPageMlocked(page)) {
+		/* Potentially, PTE-mapped THP: do not skip the rest PTEs */
+		nr_pages = 1;
 		goto unlock_out;
+	}
 
+	nr_pages = hpage_nr_pages(page);
 	__mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
 
 	if (__munlock_isolate_lru_page(page, true)) {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/mremap.c linux-libre-4.9-rc8-gnu/mm/mremap.c
--- linux-libre-4.9-rc7-gnu/mm/mremap.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/mremap.c	2016-12-04 15:50:51.000000000 -0500
@@ -149,14 +149,18 @@ static void move_ptes(struct vm_area_str
 		if (pte_none(*old_pte))
 			continue;
 
+		pte = ptep_get_and_clear(mm, old_addr, old_pte);
 		/*
-		 * We are remapping a dirty PTE, make sure to
-		 * flush TLB before we drop the PTL for the
+		 * If we are remapping a dirty PTE, make sure
+		 * to flush TLB before we drop the PTL for the
 		 * old PTE or we may race with page_mkclean().
+		 *
+		 * This check has to be done after we removed the
+		 * old PTE from page tables or another thread may
+		 * dirty it after the check and before the removal.
 		 */
-		if (pte_present(*old_pte) && pte_dirty(*old_pte))
+		if (pte_present(pte) && pte_dirty(pte))
 			force_flush = true;
-		pte = ptep_get_and_clear(mm, old_addr, old_pte);
 		pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
 		pte = move_soft_dirty_pte(pte);
 		set_pte_at(mm, new_addr, new_pte, pte);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/truncate.c linux-libre-4.9-rc8-gnu/mm/truncate.c
--- linux-libre-4.9-rc7-gnu/mm/truncate.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/truncate.c	2016-12-04 15:50:51.000000000 -0500
@@ -283,7 +283,7 @@ void truncate_inode_pages_range(struct a
 
 			if (!trylock_page(page))
 				continue;
-			WARN_ON(page_to_pgoff(page) != index);
+			WARN_ON(page_to_index(page) != index);
 			if (PageWriteback(page)) {
 				unlock_page(page);
 				continue;
@@ -371,7 +371,7 @@ void truncate_inode_pages_range(struct a
 			}
 
 			lock_page(page);
-			WARN_ON(page_to_pgoff(page) != index);
+			WARN_ON(page_to_index(page) != index);
 			wait_on_page_writeback(page);
 			truncate_inode_page(mapping, page);
 			unlock_page(page);
@@ -492,7 +492,7 @@ unsigned long invalidate_mapping_pages(s
 			if (!trylock_page(page))
 				continue;
 
-			WARN_ON(page_to_pgoff(page) != index);
+			WARN_ON(page_to_index(page) != index);
 
 			/* Middle of THP: skip */
 			if (PageTransTail(page)) {
@@ -612,7 +612,7 @@ int invalidate_inode_pages2_range(struct
 			}
 
 			lock_page(page);
-			WARN_ON(page_to_pgoff(page) != index);
+			WARN_ON(page_to_index(page) != index);
 			if (page->mapping != mapping) {
 				unlock_page(page);
 				continue;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/vmscan.c linux-libre-4.9-rc8-gnu/mm/vmscan.c
--- linux-libre-4.9-rc7-gnu/mm/vmscan.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/vmscan.c	2016-12-04 15:50:51.000000000 -0500
@@ -2354,6 +2354,8 @@ static void shrink_node_memcg(struct pgl
 			}
 		}
 
+		cond_resched();
+
 		if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
 			continue;
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/mm/workingset.c linux-libre-4.9-rc8-gnu/mm/workingset.c
--- linux-libre-4.9-rc7-gnu/mm/workingset.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/mm/workingset.c	2016-12-04 15:50:51.000000000 -0500
@@ -348,7 +348,7 @@ static unsigned long count_shadow_nodes(
 	shadow_nodes = list_lru_shrink_count(&workingset_shadow_nodes, sc);
 	local_irq_enable();
 
-	if (memcg_kmem_enabled()) {
+	if (sc->memcg) {
 		pages = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid,
 						     LRU_ALL_FILE);
 	} else {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/core/flow.c linux-libre-4.9-rc8-gnu/net/core/flow.c
--- linux-libre-4.9-rc7-gnu/net/core/flow.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/core/flow.c	2016-12-04 15:50:51.000000000 -0500
@@ -95,7 +95,6 @@ static void flow_cache_gc_task(struct wo
 	list_for_each_entry_safe(fce, n, &gc_list, u.gc_list) {
 		flow_entry_kill(fce, xfrm);
 		atomic_dec(&xfrm->flow_cache_gc_count);
-		WARN_ON(atomic_read(&xfrm->flow_cache_gc_count) < 0);
 	}
 }
 
@@ -236,9 +235,8 @@ flow_cache_lookup(struct net *net, const
 		if (fcp->hash_count > fc->high_watermark)
 			flow_cache_shrink(fc, fcp);
 
-		if (fcp->hash_count > 2 * fc->high_watermark ||
-		    atomic_read(&net->xfrm.flow_cache_gc_count) > fc->high_watermark) {
-			atomic_inc(&net->xfrm.flow_cache_genid);
+		if (atomic_read(&net->xfrm.flow_cache_gc_count) >
+		    2 * num_online_cpus() * fc->high_watermark) {
 			flo = ERR_PTR(-ENOBUFS);
 			goto ret_object;
 		}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/core/rtnetlink.c linux-libre-4.9-rc8-gnu/net/core/rtnetlink.c
--- linux-libre-4.9-rc7-gnu/net/core/rtnetlink.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/core/rtnetlink.c	2016-12-04 15:50:51.000000000 -0500
@@ -931,8 +931,8 @@ static noinline size_t if_nlmsg_size(con
 	       + nla_total_size(4) /* IFLA_PROMISCUITY */
 	       + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */
 	       + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
-	       + nla_total_size(4) /* IFLA_MAX_GSO_SEGS */
-	       + nla_total_size(4) /* IFLA_MAX_GSO_SIZE */
+	       + nla_total_size(4) /* IFLA_GSO_MAX_SEGS */
+	       + nla_total_size(4) /* IFLA_GSO_MAX_SIZE */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/core/sock.c linux-libre-4.9-rc8-gnu/net/core/sock.c
--- linux-libre-4.9-rc7-gnu/net/core/sock.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/core/sock.c	2016-12-04 15:50:51.000000000 -0500
@@ -715,7 +715,7 @@ int sock_setsockopt(struct socket *sock,
 		val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
 		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+		sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
 		/* Wake up sending tasks if we upped the value. */
 		sk->sk_write_space(sk);
 		break;
@@ -751,7 +751,7 @@ set_rcvbuf:
 		 * returning the value we actually used in getsockopt
 		 * is the most desirable behavior.
 		 */
-		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
+		sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
 		break;
 
 	case SO_RCVBUFFORCE:
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/dccp/ipv4.c linux-libre-4.9-rc8-gnu/net/dccp/ipv4.c
--- linux-libre-4.9-rc7-gnu/net/dccp/ipv4.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/dccp/ipv4.c	2016-12-04 15:50:51.000000000 -0500
@@ -700,6 +700,7 @@ int dccp_invalid_packet(struct sk_buff *
 {
 	const struct dccp_hdr *dh;
 	unsigned int cscov;
+	u8 dccph_doff;
 
 	if (skb->pkt_type != PACKET_HOST)
 		return 1;
@@ -721,18 +722,19 @@ int dccp_invalid_packet(struct sk_buff *
 	/*
 	 * If P.Data Offset is too small for packet type, drop packet and return
 	 */
-	if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
-		DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
+	dccph_doff = dh->dccph_doff;
+	if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
+		DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
 		return 1;
 	}
 	/*
 	 * If P.Data Offset is too too large for packet, drop packet and return
 	 */
-	if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
-		DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
+	if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
+		DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
 		return 1;
 	}
-
+	dh = dccp_hdr(skb);
 	/*
 	 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
 	 * has short sequence numbers), drop packet and return
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/dsa/dsa2.c linux-libre-4.9-rc8-gnu/net/dsa/dsa2.c
--- linux-libre-4.9-rc7-gnu/net/dsa/dsa2.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/dsa/dsa2.c	2016-12-04 15:50:51.000000000 -0500
@@ -28,8 +28,10 @@ static struct dsa_switch_tree *dsa_get_d
 	struct dsa_switch_tree *dst;
 
 	list_for_each_entry(dst, &dsa_switch_trees, list)
-		if (dst->tree == tree)
+		if (dst->tree == tree) {
+			kref_get(&dst->refcount);
 			return dst;
+		}
 	return NULL;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/dsa/dsa.c linux-libre-4.9-rc8-gnu/net/dsa/dsa.c
--- linux-libre-4.9-rc7-gnu/net/dsa/dsa.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/dsa/dsa.c	2016-12-04 15:50:51.000000000 -0500
@@ -233,6 +233,8 @@ int dsa_cpu_dsa_setup(struct dsa_switch
 		genphy_read_status(phydev);
 		if (ds->ops->adjust_link)
 			ds->ops->adjust_link(ds, port, phydev);
+
+		put_device(&phydev->mdio.dev);
 	}
 
 	return 0;
@@ -504,15 +506,8 @@ dsa_switch_setup(struct dsa_switch_tree
 
 void dsa_cpu_dsa_destroy(struct device_node *port_dn)
 {
-	struct phy_device *phydev;
-
-	if (of_phy_is_fixed_link(port_dn)) {
-		phydev = of_phy_find_device(port_dn);
-		if (phydev) {
-			phy_device_free(phydev);
-			fixed_phy_unregister(phydev);
-		}
-	}
+	if (of_phy_is_fixed_link(port_dn))
+		of_phy_deregister_fixed_link(port_dn);
 }
 
 static void dsa_switch_destroy(struct dsa_switch *ds)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/dsa/slave.c linux-libre-4.9-rc8-gnu/net/dsa/slave.c
--- linux-libre-4.9-rc7-gnu/net/dsa/slave.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/dsa/slave.c	2016-12-04 15:50:51.000000000 -0500
@@ -1125,7 +1125,7 @@ static int dsa_slave_phy_setup(struct ds
 	p->phy_interface = mode;
 
 	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
-	if (of_phy_is_fixed_link(port_dn)) {
+	if (!phy_dn && of_phy_is_fixed_link(port_dn)) {
 		/* In the case of a fixed PHY, the DT node associated
 		 * to the fixed PHY is the Port DT node
 		 */
@@ -1135,7 +1135,7 @@ static int dsa_slave_phy_setup(struct ds
 			return ret;
 		}
 		phy_is_fixed = true;
-		phy_dn = port_dn;
+		phy_dn = of_node_get(port_dn);
 	}
 
 	if (ds->ops->get_phy_flags)
@@ -1154,6 +1154,7 @@ static int dsa_slave_phy_setup(struct ds
 			ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
 			if (ret) {
 				netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
+				of_node_put(phy_dn);
 				return ret;
 			}
 		} else {
@@ -1162,6 +1163,8 @@ static int dsa_slave_phy_setup(struct ds
 						phy_flags,
 						p->phy_interface);
 		}
+
+		of_node_put(phy_dn);
 	}
 
 	if (p->phy && phy_is_fixed)
@@ -1174,6 +1177,8 @@ static int dsa_slave_phy_setup(struct ds
 		ret = dsa_slave_phy_connect(p, slave_dev, p->port);
 		if (ret) {
 			netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret);
+			if (phy_is_fixed)
+				of_phy_deregister_fixed_link(port_dn);
 			return ret;
 		}
 	}
@@ -1289,10 +1294,18 @@ int dsa_slave_create(struct dsa_switch *
 void dsa_slave_destroy(struct net_device *slave_dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(slave_dev);
+	struct dsa_switch *ds = p->parent;
+	struct device_node *port_dn;
+
+	port_dn = ds->ports[p->port].dn;
 
 	netif_carrier_off(slave_dev);
-	if (p->phy)
+	if (p->phy) {
 		phy_disconnect(p->phy);
+
+		if (of_phy_is_fixed_link(port_dn))
+			of_phy_deregister_fixed_link(port_dn);
+	}
 	unregister_netdev(slave_dev);
 	free_netdev(slave_dev);
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/af_inet.c linux-libre-4.9-rc8-gnu/net/ipv4/af_inet.c
--- linux-libre-4.9-rc7-gnu/net/ipv4/af_inet.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/af_inet.c	2016-12-04 15:50:51.000000000 -0500
@@ -1233,7 +1233,7 @@ struct sk_buff *inet_gso_segment(struct
 		fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
 
 		/* fixed ID is invalid if DF bit is not set */
-		if (fixedid && !(iph->frag_off & htons(IP_DF)))
+		if (fixedid && !(ip_hdr(skb)->frag_off & htons(IP_DF)))
 			goto out;
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/esp4.c linux-libre-4.9-rc8-gnu/net/ipv4/esp4.c
--- linux-libre-4.9-rc7-gnu/net/ipv4/esp4.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/esp4.c	2016-12-04 15:50:51.000000000 -0500
@@ -476,7 +476,7 @@ static int esp_input(struct xfrm_state *
 		esph = (void *)skb_push(skb, 4);
 		*seqhi = esph->spi;
 		esph->spi = esph->seq_no;
-		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
+		esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
 		aead_request_set_callback(req, 0, esp_input_done_esn, skb);
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/ip_output.c linux-libre-4.9-rc8-gnu/net/ipv4/ip_output.c
--- linux-libre-4.9-rc7-gnu/net/ipv4/ip_output.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/ip_output.c	2016-12-04 15:50:51.000000000 -0500
@@ -107,6 +107,8 @@ int __ip_local_out(struct net *net, stru
 	if (unlikely(!skb))
 		return 0;
 
+	skb->protocol = htons(ETH_P_IP);
+
 	return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
 		       net, sk, skb, NULL, skb_dst(skb)->dev,
 		       dst_output);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/Kconfig linux-libre-4.9-rc8-gnu/net/ipv4/Kconfig
--- linux-libre-4.9-rc7-gnu/net/ipv4/Kconfig	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/Kconfig	2016-12-04 15:50:51.000000000 -0500
@@ -715,6 +715,7 @@ config DEFAULT_TCP_CONG
 	default "reno" if DEFAULT_RENO
 	default "dctcp" if DEFAULT_DCTCP
 	default "cdg" if DEFAULT_CDG
+	default "bbr" if DEFAULT_BBR
 	default "cubic"
 
 config TCP_MD5SIG
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/netfilter/arp_tables.c linux-libre-4.9-rc8-gnu/net/ipv4/netfilter/arp_tables.c
--- linux-libre-4.9-rc7-gnu/net/ipv4/netfilter/arp_tables.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/netfilter/arp_tables.c	2016-12-04 15:50:51.000000000 -0500
@@ -1201,8 +1201,8 @@ static int translate_compat_table(struct
 
 	newinfo->number = compatr->num_entries;
 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-		newinfo->hook_entry[i] = info->hook_entry[i];
-		newinfo->underflow[i] = info->underflow[i];
+		newinfo->hook_entry[i] = compatr->hook_entry[i];
+		newinfo->underflow[i] = compatr->underflow[i];
 	}
 	entry1 = newinfo->entries;
 	pos = entry1;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv4/netfilter.c linux-libre-4.9-rc8-gnu/net/ipv4/netfilter.c
--- linux-libre-4.9-rc7-gnu/net/ipv4/netfilter.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv4/netfilter.c	2016-12-04 15:50:51.000000000 -0500
@@ -24,10 +24,11 @@ int ip_route_me_harder(struct net *net,
 	struct flowi4 fl4 = {};
 	__be32 saddr = iph->saddr;
 	__u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
+	struct net_device *dev = skb_dst(skb)->dev;
 	unsigned int hh_len;
 
 	if (addr_type == RTN_UNSPEC)
-		addr_type = inet_addr_type(net, saddr);
+		addr_type = inet_addr_type_dev_table(net, dev, saddr);
 	if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
 		flags |= FLOWI_FLAG_ANYSRC;
 	else
@@ -40,6 +41,8 @@ int ip_route_me_harder(struct net *net,
 	fl4.saddr = saddr;
 	fl4.flowi4_tos = RT_TOS(iph->tos);
 	fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
+	if (!fl4.flowi4_oif)
+		fl4.flowi4_oif = l3mdev_master_ifindex(dev);
 	fl4.flowi4_mark = skb->mark;
 	fl4.flowi4_flags = flags;
 	rt = ip_route_output_key(net, &fl4);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/datagram.c linux-libre-4.9-rc8-gnu/net/ipv6/datagram.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/datagram.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/datagram.c	2016-12-04 15:50:51.000000000 -0500
@@ -139,7 +139,8 @@ void ip6_datagram_release_cb(struct sock
 }
 EXPORT_SYMBOL_GPL(ip6_datagram_release_cb);
 
-static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
+			   int addr_len)
 {
 	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
 	struct inet_sock	*inet = inet_sk(sk);
@@ -252,6 +253,7 @@ ipv4_connected:
 out:
 	return err;
 }
+EXPORT_SYMBOL_GPL(__ip6_datagram_connect);
 
 int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/esp6.c linux-libre-4.9-rc8-gnu/net/ipv6/esp6.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/esp6.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/esp6.c	2016-12-04 15:50:51.000000000 -0500
@@ -418,7 +418,7 @@ static int esp6_input(struct xfrm_state
 		esph = (void *)skb_push(skb, 4);
 		*seqhi = esph->spi;
 		esph->spi = esph->seq_no;
-		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
+		esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
 		aead_request_set_callback(req, 0, esp_input_done_esn, skb);
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/icmp.c linux-libre-4.9-rc8-gnu/net/ipv6/icmp.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/icmp.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/icmp.c	2016-12-04 15:50:51.000000000 -0500
@@ -447,8 +447,10 @@ static void icmp6_send(struct sk_buff *s
 
 	if (__ipv6_addr_needs_scope_id(addr_type))
 		iif = skb->dev->ifindex;
-	else
-		iif = l3mdev_master_ifindex(skb_dst(skb)->dev);
+	else {
+		dst = skb_dst(skb);
+		iif = l3mdev_master_ifindex(dst ? dst->dev : skb->dev);
+	}
 
 	/*
 	 *	Must not send error if the source does not uniquely
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/ip6_offload.c linux-libre-4.9-rc8-gnu/net/ipv6/ip6_offload.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/ip6_offload.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/ip6_offload.c	2016-12-04 15:50:51.000000000 -0500
@@ -99,7 +99,7 @@ static struct sk_buff *ipv6_gso_segment(
 		segs = ops->callbacks.gso_segment(skb, features);
 	}
 
-	if (IS_ERR(segs))
+	if (IS_ERR_OR_NULL(segs))
 		goto out;
 
 	gso_partial = !!(skb_shinfo(segs)->gso_type & SKB_GSO_PARTIAL);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/ip6_tunnel.c linux-libre-4.9-rc8-gnu/net/ipv6/ip6_tunnel.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/ip6_tunnel.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/ip6_tunnel.c	2016-12-04 15:50:51.000000000 -0500
@@ -1181,7 +1181,6 @@ route_lookup:
 	if (err)
 		return err;
 
-	skb->protocol = htons(ETH_P_IPV6);
 	skb_push(skb, sizeof(struct ipv6hdr));
 	skb_reset_network_header(skb);
 	ipv6h = ipv6_hdr(skb);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/ip6_vti.c linux-libre-4.9-rc8-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/ip6_vti.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/ip6_vti.c	2016-12-04 15:50:51.000000000 -0500
@@ -1138,6 +1138,33 @@ static struct xfrm6_protocol vti_ipcomp6
 	.priority	=	100,
 };
 
+static bool is_vti6_tunnel(const struct net_device *dev)
+{
+	return dev->netdev_ops == &vti6_netdev_ops;
+}
+
+static int vti6_device_event(struct notifier_block *unused,
+			     unsigned long event, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct ip6_tnl *t = netdev_priv(dev);
+
+	if (!is_vti6_tunnel(dev))
+		return NOTIFY_DONE;
+
+	switch (event) {
+	case NETDEV_DOWN:
+		if (!net_eq(t->net, dev_net(dev)))
+			xfrm_garbage_collect(t->net);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block vti6_notifier_block __read_mostly = {
+	.notifier_call = vti6_device_event,
+};
+
 /**
  * vti6_tunnel_init - register protocol and reserve needed resources
  *
@@ -1148,6 +1175,8 @@ static int __init vti6_tunnel_init(void)
 	const char *msg;
 	int err;
 
+	register_netdevice_notifier(&vti6_notifier_block);
+
 	msg = "tunnel device";
 	err = register_pernet_device(&vti6_net_ops);
 	if (err < 0)
@@ -1180,6 +1209,7 @@ xfrm_proto_ah_failed:
 xfrm_proto_esp_failed:
 	unregister_pernet_device(&vti6_net_ops);
 pernet_dev_failed:
+	unregister_netdevice_notifier(&vti6_notifier_block);
 	pr_err("vti6 init: failed to register %s\n", msg);
 	return err;
 }
@@ -1194,6 +1224,7 @@ static void __exit vti6_tunnel_cleanup(v
 	xfrm6_protocol_deregister(&vti_ah6_protocol, IPPROTO_AH);
 	xfrm6_protocol_deregister(&vti_esp6_protocol, IPPROTO_ESP);
 	unregister_pernet_device(&vti6_net_ops);
+	unregister_netdevice_notifier(&vti6_notifier_block);
 }
 
 module_init(vti6_tunnel_init);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_conntrack_reasm.c	2016-12-04 15:50:51.000000000 -0500
@@ -576,11 +576,11 @@ int nf_ct_frag6_gather(struct net *net,
 	/* Jumbo payload inhibits frag. header */
 	if (ipv6_hdr(skb)->payload_len == 0) {
 		pr_debug("payload len = 0\n");
-		return -EINVAL;
+		return 0;
 	}
 
 	if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
-		return -EINVAL;
+		return 0;
 
 	if (!pskb_may_pull(skb, fhoff + sizeof(*fhdr)))
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c	2016-12-04 15:50:51.000000000 -0500
@@ -69,7 +69,7 @@ static unsigned int ipv6_defrag(void *pr
 	if (err == -EINPROGRESS)
 		return NF_STOLEN;
 
-	return NF_ACCEPT;
+	return err == 0 ? NF_ACCEPT : NF_DROP;
 }
 
 static struct nf_hook_ops ipv6_defrag_ops[] = {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_reject_ipv6.c linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_reject_ipv6.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/netfilter/nf_reject_ipv6.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/netfilter/nf_reject_ipv6.c	2016-12-04 15:50:51.000000000 -0500
@@ -156,6 +156,7 @@ void nf_send_reset6(struct net *net, str
 	fl6.daddr = oip6h->saddr;
 	fl6.fl6_sport = otcph->dest;
 	fl6.fl6_dport = otcph->source;
+	fl6.flowi6_oif = l3mdev_master_ifindex(skb_dst(oldskb)->dev);
 	security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6));
 	dst = ip6_route_output(net, NULL, &fl6);
 	if (dst->error) {
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/ipv6/output_core.c linux-libre-4.9-rc8-gnu/net/ipv6/output_core.c
--- linux-libre-4.9-rc7-gnu/net/ipv6/output_core.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/ipv6/output_core.c	2016-12-04 15:50:51.000000000 -0500
@@ -155,6 +155,8 @@ int __ip6_local_out(struct net *net, str
 	if (unlikely(!skb))
 		return 0;
 
+	skb->protocol = htons(ETH_P_IPV6);
+
 	return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
 		       net, sk, skb, NULL, skb_dst(skb)->dev,
 		       dst_output);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/l2tp/l2tp_ip6.c linux-libre-4.9-rc8-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-4.9-rc7-gnu/net/l2tp/l2tp_ip6.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/l2tp/l2tp_ip6.c	2016-12-04 15:50:51.000000000 -0500
@@ -72,8 +72,9 @@ static struct sock *__l2tp_ip6_bind_look
 
 		if ((l2tp->conn_id == tunnel_id) &&
 		    net_eq(sock_net(sk), net) &&
-		    !(addr && ipv6_addr_equal(addr, laddr)) &&
-		    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+		    (!addr || ipv6_addr_equal(addr, laddr)) &&
+		    (!sk->sk_bound_dev_if || !dif ||
+		     sk->sk_bound_dev_if == dif))
 			goto found;
 	}
 
@@ -196,16 +197,17 @@ pass_up:
 		struct ipv6hdr *iph = ipv6_hdr(skb);
 
 		read_lock_bh(&l2tp_ip6_lock);
-		sk = __l2tp_ip6_bind_lookup(net, &iph->daddr,
-					    0, tunnel_id);
+		sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
+					    tunnel_id);
+		if (!sk) {
+			read_unlock_bh(&l2tp_ip6_lock);
+			goto discard;
+		}
+
+		sock_hold(sk);
 		read_unlock_bh(&l2tp_ip6_lock);
 	}
 
-	if (sk == NULL)
-		goto discard;
-
-	sock_hold(sk);
-
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_put;
 
@@ -266,6 +268,7 @@ static int l2tp_ip6_bind(struct sock *sk
 	struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr;
 	struct net *net = sock_net(sk);
 	__be32 v4addr = 0;
+	int bound_dev_if;
 	int addr_type;
 	int err;
 
@@ -284,13 +287,6 @@ static int l2tp_ip6_bind(struct sock *sk
 	if (addr_type & IPV6_ADDR_MULTICAST)
 		return -EADDRNOTAVAIL;
 
-	err = -EADDRINUSE;
-	read_lock_bh(&l2tp_ip6_lock);
-	if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr,
-				   sk->sk_bound_dev_if, addr->l2tp_conn_id))
-		goto out_in_use;
-	read_unlock_bh(&l2tp_ip6_lock);
-
 	lock_sock(sk);
 
 	err = -EINVAL;
@@ -300,28 +296,25 @@ static int l2tp_ip6_bind(struct sock *sk
 	if (sk->sk_state != TCP_CLOSE)
 		goto out_unlock;
 
+	bound_dev_if = sk->sk_bound_dev_if;
+
 	/* Check if the address belongs to the host. */
 	rcu_read_lock();
 	if (addr_type != IPV6_ADDR_ANY) {
 		struct net_device *dev = NULL;
 
 		if (addr_type & IPV6_ADDR_LINKLOCAL) {
-			if (addr_len >= sizeof(struct sockaddr_in6) &&
-			    addr->l2tp_scope_id) {
-				/* Override any existing binding, if another
-				 * one is supplied by user.
-				 */
-				sk->sk_bound_dev_if = addr->l2tp_scope_id;
-			}
+			if (addr->l2tp_scope_id)
+				bound_dev_if = addr->l2tp_scope_id;
 
 			/* Binding to link-local address requires an
-			   interface */
-			if (!sk->sk_bound_dev_if)
+			 * interface.
+			 */
+			if (!bound_dev_if)
 				goto out_unlock_rcu;
 
 			err = -ENODEV;
-			dev = dev_get_by_index_rcu(sock_net(sk),
-						   sk->sk_bound_dev_if);
+			dev = dev_get_by_index_rcu(sock_net(sk), bound_dev_if);
 			if (!dev)
 				goto out_unlock_rcu;
 		}
@@ -336,13 +329,22 @@ static int l2tp_ip6_bind(struct sock *sk
 	}
 	rcu_read_unlock();
 
-	inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
+	write_lock_bh(&l2tp_ip6_lock);
+	if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
+				   addr->l2tp_conn_id)) {
+		write_unlock_bh(&l2tp_ip6_lock);
+		err = -EADDRINUSE;
+		goto out_unlock;
+	}
+
+	inet->inet_saddr = v4addr;
+	inet->inet_rcv_saddr = v4addr;
+	sk->sk_bound_dev_if = bound_dev_if;
 	sk->sk_v6_rcv_saddr = addr->l2tp_addr;
 	np->saddr = addr->l2tp_addr;
 
 	l2tp_ip6_sk(sk)->conn_id = addr->l2tp_conn_id;
 
-	write_lock_bh(&l2tp_ip6_lock);
 	sk_add_bind_node(sk, &l2tp_ip6_bind_table);
 	sk_del_node_init(sk);
 	write_unlock_bh(&l2tp_ip6_lock);
@@ -355,10 +357,7 @@ out_unlock_rcu:
 	rcu_read_unlock();
 out_unlock:
 	release_sock(sk);
-	return err;
 
-out_in_use:
-	read_unlock_bh(&l2tp_ip6_lock);
 	return err;
 }
 
@@ -371,9 +370,6 @@ static int l2tp_ip6_connect(struct sock
 	int	addr_type;
 	int rc;
 
-	if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
-		return -EINVAL;
-
 	if (addr_len < sizeof(*lsa))
 		return -EINVAL;
 
@@ -390,10 +386,18 @@ static int l2tp_ip6_connect(struct sock
 			return -EINVAL;
 	}
 
-	rc = ip6_datagram_connect(sk, uaddr, addr_len);
-
 	lock_sock(sk);
 
+	 /* Must bind first - autobinding does not work */
+	if (sock_flag(sk, SOCK_ZAPPED)) {
+		rc = -EINVAL;
+		goto out_sk;
+	}
+
+	rc = __ip6_datagram_connect(sk, uaddr, addr_len);
+	if (rc < 0)
+		goto out_sk;
+
 	l2tp_ip6_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
 
 	write_lock_bh(&l2tp_ip6_lock);
@@ -401,6 +405,7 @@ static int l2tp_ip6_connect(struct sock
 	sk_add_bind_node(sk, &l2tp_ip6_bind_table);
 	write_unlock_bh(&l2tp_ip6_lock);
 
+out_sk:
 	release_sock(sk);
 
 	return rc;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/l2tp/l2tp_ip.c linux-libre-4.9-rc8-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-4.9-rc7-gnu/net/l2tp/l2tp_ip.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/l2tp/l2tp_ip.c	2016-12-04 15:50:51.000000000 -0500
@@ -61,7 +61,8 @@ static struct sock *__l2tp_ip_bind_looku
 		if ((l2tp->conn_id == tunnel_id) &&
 		    net_eq(sock_net(sk), net) &&
 		    !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
-		    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+		    (!sk->sk_bound_dev_if || !dif ||
+		     sk->sk_bound_dev_if == dif))
 			goto found;
 	}
 
@@ -182,15 +183,17 @@ pass_up:
 		struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
 
 		read_lock_bh(&l2tp_ip_lock);
-		sk = __l2tp_ip_bind_lookup(net, iph->daddr, 0, tunnel_id);
+		sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
+					   tunnel_id);
+		if (!sk) {
+			read_unlock_bh(&l2tp_ip_lock);
+			goto discard;
+		}
+
+		sock_hold(sk);
 		read_unlock_bh(&l2tp_ip_lock);
 	}
 
-	if (sk == NULL)
-		goto discard;
-
-	sock_hold(sk);
-
 	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_put;
 
@@ -256,15 +259,9 @@ static int l2tp_ip_bind(struct sock *sk,
 	if (addr->l2tp_family != AF_INET)
 		return -EINVAL;
 
-	ret = -EADDRINUSE;
-	read_lock_bh(&l2tp_ip_lock);
-	if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
-				  sk->sk_bound_dev_if, addr->l2tp_conn_id))
-		goto out_in_use;
-
-	read_unlock_bh(&l2tp_ip_lock);
-
 	lock_sock(sk);
+
+	ret = -EINVAL;
 	if (!sock_flag(sk, SOCK_ZAPPED))
 		goto out;
 
@@ -281,14 +278,22 @@ static int l2tp_ip_bind(struct sock *sk,
 		inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr;
 	if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
 		inet->inet_saddr = 0;  /* Use device */
-	sk_dst_reset(sk);
 
+	write_lock_bh(&l2tp_ip_lock);
+	if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
+				  sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
+		write_unlock_bh(&l2tp_ip_lock);
+		ret = -EADDRINUSE;
+		goto out;
+	}
+
+	sk_dst_reset(sk);
 	l2tp_ip_sk(sk)->conn_id = addr->l2tp_conn_id;
 
-	write_lock_bh(&l2tp_ip_lock);
 	sk_add_bind_node(sk, &l2tp_ip_bind_table);
 	sk_del_node_init(sk);
 	write_unlock_bh(&l2tp_ip_lock);
+
 	ret = 0;
 	sock_reset_flag(sk, SOCK_ZAPPED);
 
@@ -296,11 +301,6 @@ out:
 	release_sock(sk);
 
 	return ret;
-
-out_in_use:
-	read_unlock_bh(&l2tp_ip_lock);
-
-	return ret;
 }
 
 static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -308,21 +308,24 @@ static int l2tp_ip_connect(struct sock *
 	struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
 	int rc;
 
-	if (sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
-		return -EINVAL;
-
 	if (addr_len < sizeof(*lsa))
 		return -EINVAL;
 
 	if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
 		return -EINVAL;
 
-	rc = ip4_datagram_connect(sk, uaddr, addr_len);
-	if (rc < 0)
-		return rc;
-
 	lock_sock(sk);
 
+	/* Must bind first - autobinding does not work */
+	if (sock_flag(sk, SOCK_ZAPPED)) {
+		rc = -EINVAL;
+		goto out_sk;
+	}
+
+	rc = __ip4_datagram_connect(sk, uaddr, addr_len);
+	if (rc < 0)
+		goto out_sk;
+
 	l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
 
 	write_lock_bh(&l2tp_ip_lock);
@@ -330,7 +333,9 @@ static int l2tp_ip_connect(struct sock *
 	sk_add_bind_node(sk, &l2tp_ip_bind_table);
 	write_unlock_bh(&l2tp_ip_lock);
 
+out_sk:
 	release_sock(sk);
+
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netfilter/nf_nat_core.c linux-libre-4.9-rc8-gnu/net/netfilter/nf_nat_core.c
--- linux-libre-4.9-rc7-gnu/net/netfilter/nf_nat_core.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netfilter/nf_nat_core.c	2016-12-04 15:50:51.000000000 -0500
@@ -42,7 +42,7 @@ struct nf_nat_conn_key {
 	const struct nf_conntrack_zone *zone;
 };
 
-static struct rhashtable nf_nat_bysource_table;
+static struct rhltable nf_nat_bysource_table;
 
 inline const struct nf_nat_l3proto *
 __nf_nat_l3proto_find(u8 family)
@@ -193,9 +193,12 @@ static int nf_nat_bysource_cmp(struct rh
 	const struct nf_nat_conn_key *key = arg->key;
 	const struct nf_conn *ct = obj;
 
-	return same_src(ct, key->tuple) &&
-	       net_eq(nf_ct_net(ct), key->net) &&
-	       nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL);
+	if (!same_src(ct, key->tuple) ||
+	    !net_eq(nf_ct_net(ct), key->net) ||
+	    !nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL))
+		return 1;
+
+	return 0;
 }
 
 static struct rhashtable_params nf_nat_bysource_params = {
@@ -204,7 +207,6 @@ static struct rhashtable_params nf_nat_b
 	.obj_cmpfn = nf_nat_bysource_cmp,
 	.nelem_hint = 256,
 	.min_size = 1024,
-	.nulls_base = (1U << RHT_BASE_SHIFT),
 };
 
 /* Only called for SRC manip */
@@ -223,12 +225,15 @@ find_appropriate_src(struct net *net,
 		.tuple = tuple,
 		.zone = zone
 	};
+	struct rhlist_head *hl;
 
-	ct = rhashtable_lookup_fast(&nf_nat_bysource_table, &key,
-				    nf_nat_bysource_params);
-	if (!ct)
+	hl = rhltable_lookup(&nf_nat_bysource_table, &key,
+			     nf_nat_bysource_params);
+	if (!hl)
 		return 0;
 
+	ct = container_of(hl, typeof(*ct), nat_bysource);
+
 	nf_ct_invert_tuplepr(result,
 			     &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 	result->dst = tuple->dst;
@@ -446,11 +451,17 @@ nf_nat_setup_info(struct nf_conn *ct,
 	}
 
 	if (maniptype == NF_NAT_MANIP_SRC) {
+		struct nf_nat_conn_key key = {
+			.net = nf_ct_net(ct),
+			.tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+			.zone = nf_ct_zone(ct),
+		};
 		int err;
 
-		err = rhashtable_insert_fast(&nf_nat_bysource_table,
-					     &ct->nat_bysource,
-					     nf_nat_bysource_params);
+		err = rhltable_insert_key(&nf_nat_bysource_table,
+					  &key,
+					  &ct->nat_bysource,
+					  nf_nat_bysource_params);
 		if (err)
 			return NF_DROP;
 	}
@@ -567,8 +578,8 @@ static int nf_nat_proto_clean(struct nf_
 	 * will delete entry from already-freed table.
 	 */
 	ct->status &= ~IPS_NAT_DONE_MASK;
-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
-			       nf_nat_bysource_params);
+	rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource,
+			nf_nat_bysource_params);
 
 	/* don't delete conntrack.  Although that would make things a lot
 	 * simpler, we'd end up flushing all conntracks on nat rmmod.
@@ -698,8 +709,8 @@ static void nf_nat_cleanup_conntrack(str
 	if (!nat)
 		return;
 
-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
-			       nf_nat_bysource_params);
+	rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource,
+			nf_nat_bysource_params);
 }
 
 static struct nf_ct_ext_type nat_extend __read_mostly = {
@@ -834,13 +845,13 @@ static int __init nf_nat_init(void)
 {
 	int ret;
 
-	ret = rhashtable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
+	ret = rhltable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
 	if (ret)
 		return ret;
 
 	ret = nf_ct_extend_register(&nat_extend);
 	if (ret < 0) {
-		rhashtable_destroy(&nf_nat_bysource_table);
+		rhltable_destroy(&nf_nat_bysource_table);
 		printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
 		return ret;
 	}
@@ -864,7 +875,7 @@ static int __init nf_nat_init(void)
 	return 0;
 
  cleanup_extend:
-	rhashtable_destroy(&nf_nat_bysource_table);
+	rhltable_destroy(&nf_nat_bysource_table);
 	nf_ct_extend_unregister(&nat_extend);
 	return ret;
 }
@@ -883,7 +894,7 @@ static void __exit nf_nat_cleanup(void)
 	for (i = 0; i < NFPROTO_NUMPROTO; i++)
 		kfree(nf_nat_l4protos[i]);
 
-	rhashtable_destroy(&nf_nat_bysource_table);
+	rhltable_destroy(&nf_nat_bysource_table);
 }
 
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netfilter/nf_tables_api.c linux-libre-4.9-rc8-gnu/net/netfilter/nf_tables_api.c
--- linux-libre-4.9-rc7-gnu/net/netfilter/nf_tables_api.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netfilter/nf_tables_api.c	2016-12-04 15:50:51.000000000 -0500
@@ -2570,7 +2570,8 @@ static int nf_tables_fill_set(struct sk_
 	}
 
 	if (set->timeout &&
-	    nla_put_be64(skb, NFTA_SET_TIMEOUT, cpu_to_be64(set->timeout),
+	    nla_put_be64(skb, NFTA_SET_TIMEOUT,
+			 cpu_to_be64(jiffies_to_msecs(set->timeout)),
 			 NFTA_SET_PAD))
 		goto nla_put_failure;
 	if (set->gc_int &&
@@ -2859,7 +2860,8 @@ static int nf_tables_newset(struct net *
 	if (nla[NFTA_SET_TIMEOUT] != NULL) {
 		if (!(flags & NFT_SET_TIMEOUT))
 			return -EINVAL;
-		timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_TIMEOUT]));
+		timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
+						nla[NFTA_SET_TIMEOUT])));
 	}
 	gc_int = 0;
 	if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
@@ -3178,7 +3180,8 @@ static int nf_tables_fill_setelem(struct
 
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
 	    nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
-			 cpu_to_be64(*nft_set_ext_timeout(ext)),
+			 cpu_to_be64(jiffies_to_msecs(
+						*nft_set_ext_timeout(ext))),
 			 NFTA_SET_ELEM_PAD))
 		goto nla_put_failure;
 
@@ -3447,7 +3450,7 @@ void *nft_set_elem_init(const struct nft
 		memcpy(nft_set_ext_data(ext), data, set->dlen);
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
 		*nft_set_ext_expiration(ext) =
-			jiffies + msecs_to_jiffies(timeout);
+			jiffies + timeout;
 	if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
 		*nft_set_ext_timeout(ext) = timeout;
 
@@ -3535,7 +3538,8 @@ static int nft_add_set_elem(struct nft_c
 	if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
 		if (!(set->flags & NFT_SET_TIMEOUT))
 			return -EINVAL;
-		timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_ELEM_TIMEOUT]));
+		timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
+					nla[NFTA_SET_ELEM_TIMEOUT])));
 	} else if (set->flags & NFT_SET_TIMEOUT) {
 		timeout = set->timeout;
 	}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netfilter/nft_hash.c linux-libre-4.9-rc8-gnu/net/netfilter/nft_hash.c
--- linux-libre-4.9-rc7-gnu/net/netfilter/nft_hash.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netfilter/nft_hash.c	2016-12-04 15:50:51.000000000 -0500
@@ -53,6 +53,7 @@ static int nft_hash_init(const struct nf
 {
 	struct nft_hash *priv = nft_expr_priv(expr);
 	u32 len;
+	int err;
 
 	if (!tb[NFTA_HASH_SREG] ||
 	    !tb[NFTA_HASH_DREG] ||
@@ -67,8 +68,10 @@ static int nft_hash_init(const struct nf
 	priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
 	priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
 
-	len = ntohl(nla_get_be32(tb[NFTA_HASH_LEN]));
-	if (len == 0 || len > U8_MAX)
+	err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len);
+	if (err < 0)
+		return err;
+	if (len == 0)
 		return -ERANGE;
 
 	priv->len = len;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netfilter/nft_range.c linux-libre-4.9-rc8-gnu/net/netfilter/nft_range.c
--- linux-libre-4.9-rc7-gnu/net/netfilter/nft_range.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netfilter/nft_range.c	2016-12-04 15:50:51.000000000 -0500
@@ -59,6 +59,12 @@ static int nft_range_init(const struct n
 	int err;
 	u32 op;
 
+	if (!tb[NFTA_RANGE_SREG]      ||
+	    !tb[NFTA_RANGE_OP]	      ||
+	    !tb[NFTA_RANGE_FROM_DATA] ||
+	    !tb[NFTA_RANGE_TO_DATA])
+		return -EINVAL;
+
 	err = nft_data_init(NULL, &priv->data_from, sizeof(priv->data_from),
 			    &desc_from, tb[NFTA_RANGE_FROM_DATA]);
 	if (err < 0)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netlink/af_netlink.c linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.c
--- linux-libre-4.9-rc7-gnu/net/netlink/af_netlink.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.c	2016-12-04 15:50:51.000000000 -0500
@@ -322,14 +322,11 @@ static void netlink_skb_set_owner_r(stru
 	sk_mem_charge(sk, skb->truesize);
 }
 
-static void netlink_sock_destruct(struct sock *sk)
+static void __netlink_sock_destruct(struct sock *sk)
 {
 	struct netlink_sock *nlk = nlk_sk(sk);
 
 	if (nlk->cb_running) {
-		if (nlk->cb.done)
-			nlk->cb.done(&nlk->cb);
-
 		module_put(nlk->cb.module);
 		kfree_skb(nlk->cb.skb);
 	}
@@ -346,6 +343,28 @@ static void netlink_sock_destruct(struct
 	WARN_ON(nlk_sk(sk)->groups);
 }
 
+static void netlink_sock_destruct_work(struct work_struct *work)
+{
+	struct netlink_sock *nlk = container_of(work, struct netlink_sock,
+						work);
+
+	nlk->cb.done(&nlk->cb);
+	__netlink_sock_destruct(&nlk->sk);
+}
+
+static void netlink_sock_destruct(struct sock *sk)
+{
+	struct netlink_sock *nlk = nlk_sk(sk);
+
+	if (nlk->cb_running && nlk->cb.done) {
+		INIT_WORK(&nlk->work, netlink_sock_destruct_work);
+		schedule_work(&nlk->work);
+		return;
+	}
+
+	__netlink_sock_destruct(sk);
+}
+
 /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
  * SMP. Look, when several writers sleep and reader wakes them up, all but one
  * immediately hit write lock and grab all the cpus. Exclusive sleep solves
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/netlink/af_netlink.h linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.h
--- linux-libre-4.9-rc7-gnu/net/netlink/af_netlink.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.h	2016-12-04 15:50:51.000000000 -0500
@@ -3,6 +3,7 @@
 
 #include <linux/rhashtable.h>
 #include <linux/atomic.h>
+#include <linux/workqueue.h>
 #include <net/sock.h>
 
 #define NLGRPSZ(x)	(ALIGN(x, sizeof(unsigned long) * 8) / 8)
@@ -33,6 +34,7 @@ struct netlink_sock {
 
 	struct rhash_head	node;
 	struct rcu_head		rcu;
+	struct work_struct	work;
 };
 
 static inline struct netlink_sock *nlk_sk(struct sock *sk)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/openvswitch/conntrack.c linux-libre-4.9-rc8-gnu/net/openvswitch/conntrack.c
--- linux-libre-4.9-rc7-gnu/net/openvswitch/conntrack.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/openvswitch/conntrack.c	2016-12-04 15:50:51.000000000 -0500
@@ -370,8 +370,11 @@ static int handle_fragments(struct net *
 		skb_orphan(skb);
 		memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
 		err = nf_ct_frag6_gather(net, skb, user);
-		if (err)
+		if (err) {
+			if (err != -EINPROGRESS)
+				kfree_skb(skb);
 			return err;
+		}
 
 		key->ip.proto = ipv6_hdr(skb)->nexthdr;
 		ovs_cb.mru = IP6CB(skb)->frag_max_size;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/packet/af_packet.c linux-libre-4.9-rc8-gnu/net/packet/af_packet.c
--- linux-libre-4.9-rc7-gnu/net/packet/af_packet.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/packet/af_packet.c	2016-12-04 15:50:51.000000000 -0500
@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, i
 
 		if (optlen != sizeof(val))
 			return -EINVAL;
-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
 		switch (val) {
 		case TPACKET_V1:
 		case TPACKET_V2:
 		case TPACKET_V3:
-			po->tp_version = val;
-			return 0;
+			break;
 		default:
 			return -EINVAL;
 		}
+		lock_sock(sk);
+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+			ret = -EBUSY;
+		} else {
+			po->tp_version = val;
+			ret = 0;
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_RESERVE:
 	{
@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *
 	/* Added to avoid minimal code churn */
 	struct tpacket_req *req = &req_u->req;
 
+	lock_sock(sk);
 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
 		net_warn_ratelimited("Tx-ring is not supported.\n");
@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *
 			goto out;
 	}
 
-	lock_sock(sk);
 
 	/* Detach socket from network */
 	spin_lock(&po->bind_lock);
@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *
 		if (!tx_ring)
 			prb_shutdown_retire_blk_timer(po, rb_queue);
 	}
-	release_sock(sk);
 
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
+	release_sock(sk);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/rds/tcp.c linux-libre-4.9-rc8-gnu/net/rds/tcp.c
--- linux-libre-4.9-rc7-gnu/net/rds/tcp.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/rds/tcp.c	2016-12-04 15:50:51.000000000 -0500
@@ -659,6 +659,8 @@ out_recv:
 out_pernet:
 	unregister_pernet_subsys(&rds_tcp_net_ops);
 out_slab:
+	if (unregister_netdevice_notifier(&rds_tcp_dev_notifier))
+		pr_warn("could not unregister rds_tcp_dev_notifier\n");
 	kmem_cache_destroy(rds_tcp_conn_slab);
 out:
 	return ret;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/act_pedit.c linux-libre-4.9-rc8-gnu/net/sched/act_pedit.c
--- linux-libre-4.9-rc7-gnu/net/sched/act_pedit.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/act_pedit.c	2016-12-04 15:50:51.000000000 -0500
@@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_
 	kfree(keys);
 }
 
+static bool offset_valid(struct sk_buff *skb, int offset)
+{
+	if (offset > 0 && offset > skb->len)
+		return false;
+
+	if  (offset < 0 && -offset > skb_headroom(skb))
+		return false;
+
+	return true;
+}
+
 static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
 		     struct tcf_result *res)
 {
@@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb
 			if (tkey->offmask) {
 				char *d, _d;
 
+				if (!offset_valid(skb, off + tkey->at)) {
+					pr_info("tc filter pedit 'at' offset %d out of bounds\n",
+						off + tkey->at);
+					goto bad;
+				}
 				d = skb_header_pointer(skb, off + tkey->at, 1,
 						       &_d);
 				if (!d)
@@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb
 					" offset must be on 32 bit boundaries\n");
 				goto bad;
 			}
-			if (offset > 0 && offset > skb->len) {
-				pr_info("tc filter pedit"
-					" offset %d can't exceed pkt length %d\n",
-				       offset, skb->len);
+
+			if (!offset_valid(skb, off + offset)) {
+				pr_info("tc filter pedit offset %d out of bounds\n",
+					offset);
 				goto bad;
 			}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_basic.c linux-libre-4.9-rc8-gnu/net/sched/cls_basic.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_basic.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_basic.c	2016-12-04 15:50:51.000000000 -0500
@@ -62,9 +62,6 @@ static unsigned long basic_get(struct tc
 	struct basic_head *head = rtnl_dereference(tp->root);
 	struct basic_filter *f;
 
-	if (head == NULL)
-		return 0UL;
-
 	list_for_each_entry(f, &head->flist, link) {
 		if (f->handle == handle) {
 			l = (unsigned long) f;
@@ -109,7 +106,6 @@ static bool basic_destroy(struct tcf_pro
 		tcf_unbind_filter(tp, &f->res);
 		call_rcu(&f->rcu, basic_delete_filter);
 	}
-	RCU_INIT_POINTER(tp->root, NULL);
 	kfree_rcu(head, rcu);
 	return true;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_bpf.c linux-libre-4.9-rc8-gnu/net/sched/cls_bpf.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_bpf.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_bpf.c	2016-12-04 15:50:51.000000000 -0500
@@ -292,7 +292,6 @@ static bool cls_bpf_destroy(struct tcf_p
 		call_rcu(&prog->rcu, __cls_bpf_delete_prog);
 	}
 
-	RCU_INIT_POINTER(tp->root, NULL);
 	kfree_rcu(head, rcu);
 	return true;
 }
@@ -303,9 +302,6 @@ static unsigned long cls_bpf_get(struct
 	struct cls_bpf_prog *prog;
 	unsigned long ret = 0UL;
 
-	if (head == NULL)
-		return 0UL;
-
 	list_for_each_entry(prog, &head->plist, link) {
 		if (prog->handle == handle) {
 			ret = (unsigned long) prog;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_cgroup.c linux-libre-4.9-rc8-gnu/net/sched/cls_cgroup.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_cgroup.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_cgroup.c	2016-12-04 15:50:51.000000000 -0500
@@ -137,11 +137,10 @@ static bool cls_cgroup_destroy(struct tc
 
 	if (!force)
 		return false;
-
-	if (head) {
-		RCU_INIT_POINTER(tp->root, NULL);
+	/* Head can still be NULL due to cls_cgroup_init(). */
+	if (head)
 		call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
-	}
+
 	return true;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_flow.c linux-libre-4.9-rc8-gnu/net/sched/cls_flow.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_flow.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_flow.c	2016-12-04 15:50:51.000000000 -0500
@@ -596,7 +596,6 @@ static bool flow_destroy(struct tcf_prot
 		list_del_rcu(&f->list);
 		call_rcu(&f->rcu, flow_destroy_filter);
 	}
-	RCU_INIT_POINTER(tp->root, NULL);
 	kfree_rcu(head, rcu);
 	return true;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_flower.c linux-libre-4.9-rc8-gnu/net/sched/cls_flower.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_flower.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_flower.c	2016-12-04 15:50:51.000000000 -0500
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/rhashtable.h>
+#include <linux/workqueue.h>
 
 #include <linux/if_ether.h>
 #include <linux/in6.h>
@@ -64,7 +65,10 @@ struct cls_fl_head {
 	bool mask_assigned;
 	struct list_head filters;
 	struct rhashtable_params ht_params;
-	struct rcu_head rcu;
+	union {
+		struct work_struct work;
+		struct rcu_head	rcu;
+	};
 };
 
 struct cls_fl_filter {
@@ -269,6 +273,24 @@ static void fl_hw_update_stats(struct tc
 	dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc);
 }
 
+static void fl_destroy_sleepable(struct work_struct *work)
+{
+	struct cls_fl_head *head = container_of(work, struct cls_fl_head,
+						work);
+	if (head->mask_assigned)
+		rhashtable_destroy(&head->ht);
+	kfree(head);
+	module_put(THIS_MODULE);
+}
+
+static void fl_destroy_rcu(struct rcu_head *rcu)
+{
+	struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu);
+
+	INIT_WORK(&head->work, fl_destroy_sleepable);
+	schedule_work(&head->work);
+}
+
 static bool fl_destroy(struct tcf_proto *tp, bool force)
 {
 	struct cls_fl_head *head = rtnl_dereference(tp->root);
@@ -282,10 +304,9 @@ static bool fl_destroy(struct tcf_proto
 		list_del_rcu(&f->list);
 		call_rcu(&f->rcu, fl_destroy_filter);
 	}
-	RCU_INIT_POINTER(tp->root, NULL);
-	if (head->mask_assigned)
-		rhashtable_destroy(&head->ht);
-	kfree_rcu(head, rcu);
+
+	__module_get(THIS_MODULE);
+	call_rcu(&head->rcu, fl_destroy_rcu);
 	return true;
 }
 
@@ -711,8 +732,9 @@ static int fl_change(struct net *net, st
 		goto errout;
 
 	if (fold) {
-		rhashtable_remove_fast(&head->ht, &fold->ht_node,
-				       head->ht_params);
+		if (!tc_skip_sw(fold->flags))
+			rhashtable_remove_fast(&head->ht, &fold->ht_node,
+					       head->ht_params);
 		fl_hw_destroy_filter(tp, (unsigned long)fold);
 	}
 
@@ -739,8 +761,9 @@ static int fl_delete(struct tcf_proto *t
 	struct cls_fl_head *head = rtnl_dereference(tp->root);
 	struct cls_fl_filter *f = (struct cls_fl_filter *) arg;
 
-	rhashtable_remove_fast(&head->ht, &f->ht_node,
-			       head->ht_params);
+	if (!tc_skip_sw(f->flags))
+		rhashtable_remove_fast(&head->ht, &f->ht_node,
+				       head->ht_params);
 	list_del_rcu(&f->list);
 	fl_hw_destroy_filter(tp, (unsigned long)f);
 	tcf_unbind_filter(tp, &f->res);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_matchall.c linux-libre-4.9-rc8-gnu/net/sched/cls_matchall.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_matchall.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_matchall.c	2016-12-04 15:50:51.000000000 -0500
@@ -114,7 +114,6 @@ static bool mall_destroy(struct tcf_prot
 
 		call_rcu(&f->rcu, mall_destroy_filter);
 	}
-	RCU_INIT_POINTER(tp->root, NULL);
 	kfree_rcu(head, rcu);
 	return true;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_rsvp.h linux-libre-4.9-rc8-gnu/net/sched/cls_rsvp.h
--- linux-libre-4.9-rc7-gnu/net/sched/cls_rsvp.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_rsvp.h	2016-12-04 15:50:51.000000000 -0500
@@ -152,7 +152,8 @@ static int rsvp_classify(struct sk_buff
 		return -1;
 	nhptr = ip_hdr(skb);
 #endif
-
+	if (unlikely(!head))
+		return -1;
 restart:
 
 #if RSVP_DST_LEN == 4
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/sched/cls_tcindex.c linux-libre-4.9-rc8-gnu/net/sched/cls_tcindex.c
--- linux-libre-4.9-rc7-gnu/net/sched/cls_tcindex.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/sched/cls_tcindex.c	2016-12-04 15:50:51.000000000 -0500
@@ -543,7 +543,6 @@ static bool tcindex_destroy(struct tcf_p
 	walker.fn = tcindex_destroy_element;
 	tcindex_walk(tp, &walker);
 
-	RCU_INIT_POINTER(tp->root, NULL);
 	call_rcu(&p->rcu, __tcindex_destroy);
 	return true;
 }
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/tipc/bearer.c linux-libre-4.9-rc8-gnu/net/tipc/bearer.c
--- linux-libre-4.9-rc7-gnu/net/tipc/bearer.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/tipc/bearer.c	2016-12-04 15:50:51.000000000 -0500
@@ -421,6 +421,10 @@ int tipc_enable_l2_media(struct net *net
 	dev = dev_get_by_name(net, driver_name);
 	if (!dev)
 		return -ENODEV;
+	if (tipc_mtu_bad(dev, 0)) {
+		dev_put(dev);
+		return -EINVAL;
+	}
 
 	/* Associate TIPC bearer with L2 bearer */
 	rcu_assign_pointer(b->media_ptr, dev);
@@ -610,8 +614,6 @@ static int tipc_l2_device_event(struct n
 	if (!b)
 		return NOTIFY_DONE;
 
-	b->mtu = dev->mtu;
-
 	switch (evt) {
 	case NETDEV_CHANGE:
 		if (netif_carrier_ok(dev))
@@ -624,6 +626,11 @@ static int tipc_l2_device_event(struct n
 		tipc_reset_bearer(net, b);
 		break;
 	case NETDEV_CHANGEMTU:
+		if (tipc_mtu_bad(dev, 0)) {
+			bearer_disable(net, b);
+			break;
+		}
+		b->mtu = dev->mtu;
 		tipc_reset_bearer(net, b);
 		break;
 	case NETDEV_CHANGEADDR:
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/tipc/bearer.h linux-libre-4.9-rc8-gnu/net/tipc/bearer.h
--- linux-libre-4.9-rc7-gnu/net/tipc/bearer.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/tipc/bearer.h	2016-12-04 15:50:51.000000000 -0500
@@ -39,6 +39,7 @@
 
 #include "netlink.h"
 #include "core.h"
+#include "msg.h"
 #include <net/genetlink.h>
 
 #define MAX_MEDIA	3
@@ -59,6 +60,9 @@
 #define TIPC_MEDIA_TYPE_IB	2
 #define TIPC_MEDIA_TYPE_UDP	3
 
+/* minimum bearer MTU */
+#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + INT_H_SIZE)
+
 /**
  * struct tipc_media_addr - destination address used by TIPC bearers
  * @value: address info (format defined by media)
@@ -215,4 +219,13 @@ void tipc_bearer_xmit(struct net *net, u
 void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
 			 struct sk_buff_head *xmitq);
 
+/* check if device MTU is too low for tipc headers */
+static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)
+{
+	if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
+		return false;
+	netdev_warn(dev, "MTU too low for tipc bearer\n");
+	return true;
+}
+
 #endif	/* _TIPC_BEARER_H */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/tipc/link.c linux-libre-4.9-rc8-gnu/net/tipc/link.c
--- linux-libre-4.9-rc7-gnu/net/tipc/link.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/tipc/link.c	2016-12-04 15:50:51.000000000 -0500
@@ -47,8 +47,8 @@
 #include <linux/pkt_sched.h>
 
 struct tipc_stats {
-	u32 sent_info;		/* used in counting # sent packets */
-	u32 recv_info;		/* used in counting # recv'd packets */
+	u32 sent_pkts;
+	u32 recv_pkts;
 	u32 sent_states;
 	u32 recv_states;
 	u32 sent_probes;
@@ -857,7 +857,6 @@ void tipc_link_reset(struct tipc_link *l
 	l->acked = 0;
 	l->silent_intv_cnt = 0;
 	l->rst_cnt = 0;
-	l->stats.recv_info = 0;
 	l->stale_count = 0;
 	l->bc_peer_is_up = false;
 	memset(&l->mon_state, 0, sizeof(l->mon_state));
@@ -888,6 +887,7 @@ int tipc_link_xmit(struct tipc_link *l,
 	struct sk_buff_head *transmq = &l->transmq;
 	struct sk_buff_head *backlogq = &l->backlogq;
 	struct sk_buff *skb, *_skb, *bskb;
+	int pkt_cnt = skb_queue_len(list);
 
 	/* Match msg importance against this and all higher backlog limits: */
 	if (!skb_queue_empty(backlogq)) {
@@ -901,6 +901,11 @@ int tipc_link_xmit(struct tipc_link *l,
 		return -EMSGSIZE;
 	}
 
+	if (pkt_cnt > 1) {
+		l->stats.sent_fragmented++;
+		l->stats.sent_fragments += pkt_cnt;
+	}
+
 	/* Prepare each packet for sending, and add to relevant queue: */
 	while (skb_queue_len(list)) {
 		skb = skb_peek(list);
@@ -920,6 +925,7 @@ int tipc_link_xmit(struct tipc_link *l,
 			__skb_queue_tail(xmitq, _skb);
 			TIPC_SKB_CB(skb)->ackers = l->ackers;
 			l->rcv_unacked = 0;
+			l->stats.sent_pkts++;
 			seqno++;
 			continue;
 		}
@@ -968,6 +974,7 @@ void tipc_link_advance_backlog(struct ti
 		msg_set_ack(hdr, ack);
 		msg_set_bcast_ack(hdr, bc_ack);
 		l->rcv_unacked = 0;
+		l->stats.sent_pkts++;
 		seqno++;
 	}
 	l->snd_nxt = seqno;
@@ -1260,7 +1267,7 @@ int tipc_link_rcv(struct tipc_link *l, s
 
 		/* Deliver packet */
 		l->rcv_nxt++;
-		l->stats.recv_info++;
+		l->stats.recv_pkts++;
 		if (!tipc_data_input(l, skb, l->inputq))
 			rc |= tipc_link_input(l, skb, l->inputq);
 		if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN))
@@ -1800,10 +1807,6 @@ void tipc_link_set_queue_limits(struct t
 void tipc_link_reset_stats(struct tipc_link *l)
 {
 	memset(&l->stats, 0, sizeof(l->stats));
-	if (!link_is_bc_sndlink(l)) {
-		l->stats.sent_info = l->snd_nxt;
-		l->stats.recv_info = l->rcv_nxt;
-	}
 }
 
 static void link_print(struct tipc_link *l, const char *str)
@@ -1867,12 +1870,12 @@ static int __tipc_nl_add_stats(struct sk
 	};
 
 	struct nla_map map[] = {
-		{TIPC_NLA_STATS_RX_INFO, s->recv_info},
+		{TIPC_NLA_STATS_RX_INFO, 0},
 		{TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments},
 		{TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented},
 		{TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles},
 		{TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled},
-		{TIPC_NLA_STATS_TX_INFO, s->sent_info},
+		{TIPC_NLA_STATS_TX_INFO, 0},
 		{TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments},
 		{TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented},
 		{TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles},
@@ -1947,9 +1950,9 @@ int __tipc_nl_add_link(struct net *net,
 		goto attr_msg_full;
 	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->mtu))
 		goto attr_msg_full;
-	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->rcv_nxt))
+	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->stats.recv_pkts))
 		goto attr_msg_full;
-	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->snd_nxt))
+	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->stats.sent_pkts))
 		goto attr_msg_full;
 
 	if (tipc_link_is_up(link))
@@ -2004,12 +2007,12 @@ static int __tipc_nl_add_bc_link_stat(st
 	};
 
 	struct nla_map map[] = {
-		{TIPC_NLA_STATS_RX_INFO, stats->recv_info},
+		{TIPC_NLA_STATS_RX_INFO, stats->recv_pkts},
 		{TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
 		{TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
 		{TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
 		{TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
-		{TIPC_NLA_STATS_TX_INFO, stats->sent_info},
+		{TIPC_NLA_STATS_TX_INFO, stats->sent_pkts},
 		{TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
 		{TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
 		{TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
@@ -2076,9 +2079,9 @@ int tipc_nl_add_bc_link(struct net *net,
 		goto attr_msg_full;
 	if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
 		goto attr_msg_full;
-	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->rcv_nxt))
+	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, 0))
 		goto attr_msg_full;
-	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->snd_nxt))
+	if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, 0))
 		goto attr_msg_full;
 
 	prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/tipc/udp_media.c linux-libre-4.9-rc8-gnu/net/tipc/udp_media.c
--- linux-libre-4.9-rc7-gnu/net/tipc/udp_media.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/tipc/udp_media.c	2016-12-04 15:50:51.000000000 -0500
@@ -697,6 +697,11 @@ static int tipc_udp_enable(struct net *n
 		udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
 		udp_conf.use_udp_checksums = false;
 		ub->ifindex = dev->ifindex;
+		if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
+				      sizeof(struct udphdr))) {
+			err = -EINVAL;
+			goto err;
+		}
 		b->mtu = dev->mtu - sizeof(struct iphdr)
 			- sizeof(struct udphdr);
 #if IS_ENABLED(CONFIG_IPV6)
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/xfrm/xfrm_policy.c linux-libre-4.9-rc8-gnu/net/xfrm/xfrm_policy.c
--- linux-libre-4.9-rc7-gnu/net/xfrm/xfrm_policy.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/xfrm/xfrm_policy.c	2016-12-04 15:50:51.000000000 -0500
@@ -1268,12 +1268,14 @@ static struct xfrm_policy *xfrm_sk_polic
 			err = security_xfrm_policy_lookup(pol->security,
 						      fl->flowi_secid,
 						      policy_to_flow_dir(dir));
-			if (!err && !xfrm_pol_hold_rcu(pol))
-				goto again;
-			else if (err == -ESRCH)
+			if (!err) {
+				if (!xfrm_pol_hold_rcu(pol))
+					goto again;
+			} else if (err == -ESRCH) {
 				pol = NULL;
-			else
+			} else {
 				pol = ERR_PTR(err);
+			}
 		} else
 			pol = NULL;
 	}
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/net/xfrm/xfrm_user.c linux-libre-4.9-rc8-gnu/net/xfrm/xfrm_user.c
--- linux-libre-4.9-rc7-gnu/net/xfrm/xfrm_user.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/net/xfrm/xfrm_user.c	2016-12-04 15:50:51.000000000 -0500
@@ -2450,7 +2450,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 
 #ifdef CONFIG_COMPAT
 	if (in_compat_syscall())
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 #endif
 
 	type = nlh->nlmsg_type;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/samples/bpf/bpf_helpers.h linux-libre-4.9-rc8-gnu/samples/bpf/bpf_helpers.h
--- linux-libre-4.9-rc7-gnu/samples/bpf/bpf_helpers.h	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/samples/bpf/bpf_helpers.h	2016-12-04 15:50:51.000000000 -0500
@@ -113,7 +113,7 @@ static int (*bpf_skb_under_cgroup)(void
 #define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
 #define PT_REGS_RC(x) ((x)->gprs[2])
 #define PT_REGS_SP(x) ((x)->gprs[15])
-#define PT_REGS_IP(x) ((x)->ip)
+#define PT_REGS_IP(x) ((x)->psw.addr)
 
 #elif defined(__aarch64__)
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/samples/bpf/sampleip_kern.c linux-libre-4.9-rc8-gnu/samples/bpf/sampleip_kern.c
--- linux-libre-4.9-rc7-gnu/samples/bpf/sampleip_kern.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/samples/bpf/sampleip_kern.c	2016-12-04 15:50:51.000000000 -0500
@@ -25,7 +25,7 @@ int do_sample(struct bpf_perf_event_data
 	u64 ip;
 	u32 *value, init_val = 1;
 
-	ip = ctx->regs.ip;
+	ip = PT_REGS_IP(&ctx->regs);
 	value = bpf_map_lookup_elem(&ip_map, &ip);
 	if (value)
 		*value += 1;
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/samples/bpf/trace_event_kern.c linux-libre-4.9-rc8-gnu/samples/bpf/trace_event_kern.c
--- linux-libre-4.9-rc7-gnu/samples/bpf/trace_event_kern.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/samples/bpf/trace_event_kern.c	2016-12-04 15:50:51.000000000 -0500
@@ -50,7 +50,7 @@ int bpf_prog1(struct bpf_perf_event_data
 	key.userstack = bpf_get_stackid(ctx, &stackmap, USER_STACKID_FLAGS);
 	if ((int)key.kernstack < 0 && (int)key.userstack < 0) {
 		bpf_trace_printk(fmt, sizeof(fmt), cpu, ctx->sample_period,
-				 ctx->regs.ip);
+				 PT_REGS_IP(&ctx->regs));
 		return 0;
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/scripts/kconfig/Makefile linux-libre-4.9-rc8-gnu/scripts/kconfig/Makefile
--- linux-libre-4.9-rc7-gnu/scripts/kconfig/Makefile	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/scripts/kconfig/Makefile	2016-12-04 15:50:51.000000000 -0500
@@ -35,6 +35,8 @@ nconfig: $(obj)/nconf
 
 silentoldconfig: $(obj)/conf
 	$(Q)mkdir -p include/config include/generated
+	$(Q)test -e include/generated/autoksyms.h || \
+	    touch   include/generated/autoksyms.h
 	$< $(silent) --$@ $(Kconfig)
 
 localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/sound/sparc/dbri.c linux-libre-4.9-rc8-gnu/sound/sparc/dbri.c
--- linux-libre-4.9-rc7-gnu/sound/sparc/dbri.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/sound/sparc/dbri.c	2016-12-04 15:50:51.000000000 -0500
@@ -304,7 +304,7 @@ struct snd_dbri {
 	spinlock_t lock;
 
 	struct dbri_dma *dma;	/* Pointer to our DMA block */
-	u32 dma_dvma;		/* DBRI visible DMA address */
+	dma_addr_t dma_dvma;	/* DBRI visible DMA address */
 
 	void __iomem *regs;	/* dbri HW regs */
 	int dbri_irqp;		/* intr queue pointer */
@@ -657,12 +657,14 @@ static void dbri_cmdwait(struct snd_dbri
  */
 static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
 {
+	u32 dvma_addr = (u32)dbri->dma_dvma;
+
 	/* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
 	len += 2;
 	spin_lock(&dbri->cmdlock);
 	if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
 		return dbri->cmdptr + 2;
-	else if (len < sbus_readl(dbri->regs + REG8) - dbri->dma_dvma)
+	else if (len < sbus_readl(dbri->regs + REG8) - dvma_addr)
 		return dbri->dma->cmd;
 	else
 		printk(KERN_ERR "DBRI: no space for commands.");
@@ -680,6 +682,7 @@ static s32 *dbri_cmdlock(struct snd_dbri
  */
 static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
 {
+	u32 dvma_addr = (u32)dbri->dma_dvma;
 	s32 tmp, addr;
 	static int wait_id = 0;
 
@@ -689,7 +692,7 @@ static void dbri_cmdsend(struct snd_dbri
 	*(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
 
 	/* Replace the last command with JUMP */
-	addr = dbri->dma_dvma + (cmd - len - dbri->dma->cmd) * sizeof(s32);
+	addr = dvma_addr + (cmd - len - dbri->dma->cmd) * sizeof(s32);
 	*(dbri->cmdptr+1) = addr;
 	*(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
 
@@ -747,6 +750,7 @@ static void dbri_reset(struct snd_dbri *
 /* Lock must not be held before calling this */
 static void dbri_initialize(struct snd_dbri *dbri)
 {
+	u32 dvma_addr = (u32)dbri->dma_dvma;
 	s32 *cmd;
 	u32 dma_addr;
 	unsigned long flags;
@@ -764,7 +768,7 @@ static void dbri_initialize(struct snd_d
 	/*
 	 * Initialize the interrupt ring buffer.
 	 */
-	dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
+	dma_addr = dvma_addr + dbri_dma_off(intr, 0);
 	dbri->dma->intr[0] = dma_addr;
 	dbri->dbri_irqp = 1;
 	/*
@@ -778,7 +782,7 @@ static void dbri_initialize(struct snd_d
 	dbri->cmdptr = cmd;
 	*(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
 	*(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
-	dma_addr = dbri->dma_dvma + dbri_dma_off(cmd, 0);
+	dma_addr = dvma_addr + dbri_dma_off(cmd, 0);
 	sbus_writel(dma_addr, dbri->regs + REG8);
 	spin_unlock(&dbri->cmdlock);
 
@@ -1077,6 +1081,7 @@ static void recv_fixed(struct snd_dbri *
 static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
 {
 	struct dbri_streaminfo *info = &dbri->stream_info[streamno];
+	u32 dvma_addr = (u32)dbri->dma_dvma;
 	__u32 dvma_buffer;
 	int desc;
 	int len;
@@ -1177,7 +1182,7 @@ static int setup_descs(struct snd_dbri *
 		else {
 			dbri->next_desc[last_desc] = desc;
 			dbri->dma->desc[last_desc].nda =
-			    dbri->dma_dvma + dbri_dma_off(desc, desc);
+			    dvma_addr + dbri_dma_off(desc, desc);
 		}
 
 		last_desc = desc;
@@ -1192,7 +1197,7 @@ static int setup_descs(struct snd_dbri *
 	}
 
 	dbri->dma->desc[last_desc].nda =
-	    dbri->dma_dvma + dbri_dma_off(desc, first_desc);
+	    dvma_addr + dbri_dma_off(desc, first_desc);
 	dbri->next_desc[last_desc] = first_desc;
 	dbri->pipes[info->pipe].first_desc = first_desc;
 	dbri->pipes[info->pipe].desc = first_desc;
@@ -1697,6 +1702,7 @@ interrupts are disabled.
 static void xmit_descs(struct snd_dbri *dbri)
 {
 	struct dbri_streaminfo *info;
+	u32 dvma_addr = (u32)dbri->dma_dvma;
 	s32 *cmd;
 	unsigned long flags;
 	int first_td;
@@ -1718,7 +1724,7 @@ static void xmit_descs(struct snd_dbri *
 			*(cmd++) = DBRI_CMD(D_SDP, 0,
 					    dbri->pipes[info->pipe].sdp
 					    | D_SDP_P | D_SDP_EVERY | D_SDP_C);
-			*(cmd++) = dbri->dma_dvma +
+			*(cmd++) = dvma_addr +
 				   dbri_dma_off(desc, first_td);
 			dbri_cmdsend(dbri, cmd, 2);
 
@@ -1740,7 +1746,7 @@ static void xmit_descs(struct snd_dbri *
 			*(cmd++) = DBRI_CMD(D_SDP, 0,
 					    dbri->pipes[info->pipe].sdp
 					    | D_SDP_P | D_SDP_EVERY | D_SDP_C);
-			*(cmd++) = dbri->dma_dvma +
+			*(cmd++) = dvma_addr +
 				   dbri_dma_off(desc, first_td);
 			dbri_cmdsend(dbri, cmd, 2);
 
@@ -2539,7 +2545,7 @@ static int snd_dbri_create(struct snd_ca
 	if (!dbri->dma)
 		return -ENOMEM;
 
-	dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
+	dprintk(D_GEN, "DMA Cmd Block 0x%p (%pad)\n",
 		dbri->dma, dbri->dma_dvma);
 
 	/* Map the registers into memory. */
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/virt/kvm/arm/vgic/vgic-v2.c linux-libre-4.9-rc8-gnu/virt/kvm/arm/vgic/vgic-v2.c
--- linux-libre-4.9-rc7-gnu/virt/kvm/arm/vgic/vgic-v2.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/virt/kvm/arm/vgic/vgic-v2.c	2016-12-04 15:50:51.000000000 -0500
@@ -50,8 +50,10 @@ void vgic_v2_process_maintenance(struct
 
 			WARN_ON(cpuif->vgic_lr[lr] & GICH_LR_STATE);
 
-			kvm_notify_acked_irq(vcpu->kvm, 0,
-					     intid - VGIC_NR_PRIVATE_IRQS);
+			/* Only SPIs require notification */
+			if (vgic_valid_spi(vcpu->kvm, intid))
+				kvm_notify_acked_irq(vcpu->kvm, 0,
+						     intid - VGIC_NR_PRIVATE_IRQS);
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/virt/kvm/arm/vgic/vgic-v3.c linux-libre-4.9-rc8-gnu/virt/kvm/arm/vgic/vgic-v3.c
--- linux-libre-4.9-rc7-gnu/virt/kvm/arm/vgic/vgic-v3.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/virt/kvm/arm/vgic/vgic-v3.c	2016-12-04 15:50:51.000000000 -0500
@@ -41,8 +41,10 @@ void vgic_v3_process_maintenance(struct
 
 			WARN_ON(cpuif->vgic_lr[lr] & ICH_LR_STATE);
 
-			kvm_notify_acked_irq(vcpu->kvm, 0,
-					     intid - VGIC_NR_PRIVATE_IRQS);
+			/* Only SPIs require notification */
+			if (vgic_valid_spi(vcpu->kvm, intid))
+				kvm_notify_acked_irq(vcpu->kvm, 0,
+						     intid - VGIC_NR_PRIVATE_IRQS);
 		}
 
 		/*
diff -druNp --no-dereference linux-libre-4.9-rc7-gnu/virt/kvm/kvm_main.c linux-libre-4.9-rc8-gnu/virt/kvm/kvm_main.c
--- linux-libre-4.9-rc7-gnu/virt/kvm/kvm_main.c	2016-11-27 16:08:04.000000000 -0500
+++ linux-libre-4.9-rc8-gnu/virt/kvm/kvm_main.c	2016-12-04 15:50:51.000000000 -0500
@@ -2889,10 +2889,10 @@ static int kvm_ioctl_create_device(struc
 
 	ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
 	if (ret < 0) {
-		ops->destroy(dev);
 		mutex_lock(&kvm->lock);
 		list_del(&dev->vm_node);
 		mutex_unlock(&kvm->lock);
+		ops->destroy(dev);
 		return ret;
 	}
 
