[linux-next] LinuxNextTracking branch, master, updated. next-20161205

batman at open-mesh.org batman at open-mesh.org
Tue Dec 6 00:15:41 CET 2016


The following commit has been merged in the master branch:
commit f142c3284c9a86e590fd2890f9b62251dd9c9871
Merge: 2ede594ac51b39b92ae58f0f0ca40255c0491eb5 adc176c5472214971d77c1a61c83db9b01e9cdc7
Author: Stephen Rothwell <sfr at canb.auug.org.au>
Date:   Mon Dec 5 11:59:11 2016 +1100

    Merge remote-tracking branch 'net-next/master'

diff --combined MAINTAINERS
index b1cadd8,e773ad5..94b03b6
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@@ -35,13 -35,13 +35,13 @@@ trivial patch so apply some common sens
  
  	PLEASE check your patch with the automated style checker
  	(scripts/checkpatch.pl) to catch trivial style violations.
 -	See Documentation/CodingStyle for guidance here.
 +	See Documentation/process/coding-style.rst for guidance here.
  
  	PLEASE CC: the maintainers and mailing lists that are generated
  	by scripts/get_maintainer.pl.  The results returned by the
  	script will be best if you have git installed and are making
  	your changes in a branch derived from Linus' latest git tree.
 -	See Documentation/SubmittingPatches for details.
 +	See Documentation/process/submitting-patches.rst for details.
  
  	PLEASE try to include any credit lines you want added with the
  	patch. It avoids people being missed off by mistake and makes
@@@ -54,7 -54,7 +54,7 @@@
  	of the Linux Foundation certificate of contribution and should
  	include a Signed-off-by: line.  The current version of this
  	"Developer's Certificate of Origin" (DCO) is listed in the file
 -	Documentation/SubmittingPatches.
 +	Documentation/process/submitting-patches.rst.
  
  6.	Make sure you have the right to send any changes you make. If you
  	do changes at work you may find your employer owns the patch
@@@ -1026,7 -1026,6 +1026,7 @@@ L:	linux-arm-kernel at lists.infradead.or
  S:	Maintained
  N:	sun[x456789]i
  F:	arch/arm/boot/dts/ntc-gr8*
 +F:	arch/arm64/boot/dts/allwinner/
  
  ARM/Allwinner SoC Clock Support
  M:	Emilio López <emilio at elopez.com.ar>
@@@ -1487,9 -1486,8 +1487,9 @@@ L:	linux-arm-kernel at lists.infradead.or
  L:	linux-oxnas at lists.tuxfamily.org (moderated for non-subscribers)
  S:	Maintained
  F:	arch/arm/mach-oxnas/
 -F:	arch/arm/boot/dts/oxnas*
 +F:	arch/arm/boot/dts/ox8*.dtsi
  F:	arch/arm/boot/dts/wd-mbwe.dts
 +F:	arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
  N:	oxnas
  
  ARM/Mediatek RTC DRIVER
@@@ -1610,7 -1608,6 +1610,7 @@@ F:	arch/arm/mach-qcom
  F:	arch/arm64/boot/dts/qcom/*
  F:	drivers/i2c/busses/i2c-qup.c
  F:	drivers/clk/qcom/
 +F:	drivers/pinctrl/qcom/
  F:	drivers/soc/qcom/
  F:	drivers/spi/spi-qup.c
  F:	drivers/tty/serial/msm_serial.h
@@@ -1790,7 -1787,9 +1790,7 @@@ F:	drivers/media/rc/st_rc.
  F:	drivers/media/platform/sti/c8sectpfe/
  F:	drivers/mmc/host/sdhci-st.c
  F:	drivers/phy/phy-miphy28lp.c
 -F:	drivers/phy/phy-miphy365x.c
  F:	drivers/phy/phy-stih407-usb.c
 -F:	drivers/phy/phy-stih41x-usb.c
  F:	drivers/pinctrl/pinctrl-st.c
  F:	drivers/remoteproc/st_remoteproc.c
  F:	drivers/reset/sti/
@@@ -2538,6 -2537,8 +2538,8 @@@ L:	netdev at vger.kernel.or
  L:	linux-kernel at vger.kernel.org
  S:	Supported
  F:	kernel/bpf/
+ F:	tools/testing/selftests/bpf/
+ F:	lib/test_bpf.c
  
  BROADCOM B44 10/100 ETHERNET DRIVER
  M:	Michael Chan <michael.chan at broadcom.com>
@@@ -2750,14 -2751,6 +2752,14 @@@ L:	bcm-kernel-feedback-list at broadcom.co
  S:	Maintained
  F:	drivers/mtd/nand/brcmnand/
  
 +BROADCOM STB AVS CPUFREQ DRIVER
 +M:	Markus Mayer <mmayer at broadcom.com>
 +M:	bcm-kernel-feedback-list at broadcom.com
 +L:	linux-pm at vger.kernel.org
 +S:	Maintained
 +F:	Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
 +F:	drivers/cpufreq/brcmstb*
 +
  BROADCOM SPECIFIC AMBA DRIVER (BCMA)
  M:	Rafał Miłecki <zajec5 at gmail.com>
  L:	linux-wireless at vger.kernel.org
@@@ -2772,7 -2765,7 +2774,7 @@@ S:	Supporte
  F:	drivers/net/ethernet/broadcom/bcmsysport.*
  
  BROADCOM VULCAN ARM64 SOC
 -M:	Jayachandran C. <jchandra at broadcom.com>
 +M:	Jayachandran C. <c.jayachandran at gmail.com>
  M:	bcm-kernel-feedback-list at broadcom.com
  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
  S:	Maintained
@@@ -2946,7 -2939,7 +2948,7 @@@ CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVE
  M:	Kevin Tsai <ktsai at capellamicro.com>
  S:	Maintained
  F:	drivers/iio/light/cm*
 -F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
 +F:	Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst
  
  CAVIUM I2C DRIVER
  M:	Jan Glauber <jglauber at cavium.com>
@@@ -2980,15 -2973,15 +2982,15 @@@ L:	linux-media at vger.kernel.or
  T:	git git://linuxtv.org/media_tree.git
  W:	http://linuxtv.org
  S:	Supported
 -F:	Documentation/cec.txt
 +F:	Documentation/media/kapi/cec-core.rst
  F:	Documentation/media/uapi/cec
 -F:	drivers/staging/media/cec/
 +F:	drivers/media/cec/
  F:	drivers/media/cec-edid.c
  F:	drivers/media/rc/keymaps/rc-cec.c
  F:	include/media/cec.h
  F:	include/media/cec-edid.h
 -F:	include/linux/cec.h
 -F:	include/linux/cec-funcs.h
 +F:	include/uapi/linux/cec.h
 +F:	include/uapi/linux/cec-funcs.h
  
  CELL BROADBAND ENGINE ARCHITECTURE
  M:	Arnd Bergmann <arnd at arndb.de>
@@@ -3094,7 -3087,7 +3096,7 @@@ M:	Harry Wei <harryxiyou at gmail.com
  L:	xiyoulinuxkernelgroup at googlegroups.com (subscribers-only)
  L:	linux-kernel at zh-kernel.org (moderated for non-subscribers)
  S:	Maintained
 -F:	Documentation/zh_CN/
 +F:	Documentation/translations/zh_CN/
  
  CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
  M:	Peter Chen <Peter.Chen at nxp.com>
@@@ -3350,7 -3343,6 +3352,7 @@@ L:	linux-pm at vger.kernel.or
  S:	Maintained
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
  T:	git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
 +B:	https://bugzilla.kernel.org
  F:	Documentation/cpu-freq/
  F:	drivers/cpufreq/
  F:	include/linux/cpufreq.h
@@@ -3390,7 -3382,6 +3392,7 @@@ M:	Daniel Lezcano <daniel.lezcano at linar
  L:	linux-pm at vger.kernel.org
  S:	Maintained
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
 +B:	https://bugzilla.kernel.org
  F:	drivers/cpuidle/*
  F:	include/linux/cpuidle.h
  
@@@ -6300,11 -6291,9 +6302,11 @@@ S:	Maintaine
  F:	drivers/platform/x86/intel-vbtn.c
  
  INTEL IDLE DRIVER
 +M:	Jacob Pan <jacob.jun.pan at linux.intel.com>
  M:	Len Brown <lenb at kernel.org>
  L:	linux-pm at vger.kernel.org
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
 +B:	https://bugzilla.kernel.org
  S:	Supported
  F:	drivers/idle/intel_idle.c
  
@@@ -7578,8 -7567,10 +7580,10 @@@ S:	Maintaine
  MARVELL 88E6XXX ETHERNET SWITCH FABRIC DRIVER
  M:	Andrew Lunn <andrew at lunn.ch>
  M:	Vivien Didelot <vivien.didelot at savoirfairelinux.com>
+ L:	netdev at vger.kernel.org
  S:	Maintained
  F:	drivers/net/dsa/mv88e6xxx/
+ F:	Documentation/devicetree/bindings/net/dsa/marvell.txt
  
  MARVELL ARMADA DRM SUPPORT
  M:	Russell King <rmk+kernel at armlinux.org.uk>
@@@ -7747,15 -7738,6 +7751,15 @@@ F:	Documentation/devicetree/bindings/me
  F:	drivers/media/platform/rcar-fcp.c
  F:	include/media/rcar-fcp.h
  
 +MEDIA DRIVERS FOR RENESAS - FDP1
 +M:	Kieran Bingham <kieran at bingham.xyz>
 +L:	linux-media at vger.kernel.org
 +L:	linux-renesas-soc at vger.kernel.org
 +T:	git git://linuxtv.org/media_tree.git
 +S:	Supported
 +F:	Documentation/devicetree/bindings/media/renesas,fdp1.txt
 +F:	drivers/media/platform/rcar_fdp1.c
 +
  MEDIA DRIVERS FOR RENESAS - VIN
  M:	Niklas Söderlund <niklas.soderlund at ragnatech.se>
  L:	linux-media at vger.kernel.org
@@@ -7862,24 -7844,6 +7866,24 @@@ L:	netdev at vger.kernel.or
  S:	Maintained
  F:	drivers/net/ethernet/mediatek/
  
 +MEDIATEK MEDIA DRIVER
 +M:	Tiffany Lin <tiffany.lin at mediatek.com>
 +M:	Andrew-CT Chen <andrew-ct.chen at mediatek.com>
 +S:	Supported
 +F:	drivers/media/platform/mtk-vcodec/
 +F:	drivers/media/platform/mtk-vpu/
 +F:	Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 +F:	Documentation/devicetree/bindings/media/mediatek-vpu.txt
 +
 +MEDIATEK MDP DRIVER
 +M:	Minghsiu Tsai <minghsiu.tsai at mediatek.com>
 +M:	Houlong Wei <houlong.wei at mediatek.com>
 +M:	Andrew-CT Chen <andrew-ct.chen at mediatek.com>
 +S:	Supported
 +F:	drivers/media/platform/mtk-mdp/
 +F:	drivers/media/platform/mtk-vpu/
 +F:	Documentation/devicetree/bindings/media/mediatek-mdp.txt
 +
  MEDIATEK MT7601U WIRELESS LAN DRIVER
  M:	Jakub Kicinski <kubakici at wp.pl>
  L:	linux-wireless at vger.kernel.org
@@@ -7930,15 -7894,6 +7934,15 @@@ W:	http://www.mellanox.co
  Q:	http://patchwork.ozlabs.org/project/netdev/list/
  F:	drivers/net/ethernet/mellanox/mlxsw/
  
 +MELLANOX MLXCPLD I2C AND MUX DRIVER
 +M:	Vadim Pasternak <vadimp at mellanox.com>
 +M:	Michael Shych <michaelsh at mellanox.com>
 +L:	linux-i2c at vger.kernel.org
 +S:	Supported
 +F:	drivers/i2c/busses/i2c-mlxcpld.c
 +F:	drivers/i2c/muxes/i2c-mux-mlxcpld.c
 +F:	Documentation/i2c/busses/i2c-mlxcpld
 +
  MELLANOX MLXCPLD LED DRIVER
  M:	Vadim Pasternak <vadimp at mellanox.com>
  L:	linux-leds at vger.kernel.org
@@@ -8506,7 -8461,6 +8510,6 @@@ F:	include/uapi/linux/net_namespace.
  F:	tools/net/
  F:	tools/testing/selftests/net/
  F:	lib/random32.c
- F:	lib/test_bpf.c
  
  NETWORKING [IPv4/IPv6]
  M:	"David S. Miller" <davem at davemloft.net>
@@@ -9017,11 -8971,9 +9020,11 @@@ F:	drivers/of/resolver.
  
  OPENRISC ARCHITECTURE
  M:	Jonas Bonn <jonas at southpole.se>
 -W:	http://openrisc.net
 +M:	Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
 +M:	Stafford Horne <shorne at gmail.com>
 +L:	openrisc at lists.librecores.org
 +W:	http://openrisc.io
  S:	Maintained
 -T:	git git://openrisc.net/~jonas/linux
  F:	arch/openrisc/
  
  OPENVSWITCH
@@@ -9839,7 -9791,7 +9842,7 @@@ M:	Hans Verkuil <hverkuil at xs4all.nl
  L:	linux-media at vger.kernel.org
  T:	git git://linuxtv.org/media_tree.git
  S:	Maintained
 -F:	drivers/staging/media/pulse8-cec
 +F:	drivers/media/usb/pulse8-cec/*
  
  PVRUSB2 VIDEO4LINUX DRIVER
  M:	Mike Isely <isely at pobox.com>
@@@ -10464,7 -10416,7 +10467,7 @@@ F:	arch/s390/pci
  F:	drivers/pci/hotplug/s390_pci_hpc.c
  
  S390 ZCRYPT DRIVER
 -M:	Ingo Tuchscherer <ingo.tuchscherer at de.ibm.com>
 +M:	Harald Freudenberger <freude at de.ibm.com>
  L:	linux-s390 at vger.kernel.org
  W:	http://www.ibm.com/developerworks/linux/linux390/
  S:	Supported
@@@ -10659,12 -10611,6 +10662,12 @@@ S:	Maintaine
  F:	Documentation/devicetree/bindings/serial/
  F:	drivers/tty/serial/
  
 +SERIAL IR RECEIVER
 +M:	Sean Young <sean at mess.org>
 +L:	linux-media at vger.kernel.org
 +S:	Maintained
 +F:	drivers/media/rc/serial_ir.c
 +
  STI CEC DRIVER
  M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
  L:	kernel at stlinux.com
@@@ -11528,7 -11474,7 +11531,7 @@@ STABLE BRANC
  M:	Greg Kroah-Hartman <gregkh at linuxfoundation.org>
  L:	stable at vger.kernel.org
  S:	Supported
 -F:	Documentation/stable_kernel_rules.txt
 +F:	Documentation/process/stable-kernel-rules.rst
  
  STAGING SUBSYSTEM
  M:	Greg Kroah-Hartman <gregkh at linuxfoundation.org>
@@@ -11714,7 -11660,6 +11717,7 @@@ S:	Supporte
  F:	arch/arc/
  F:	Documentation/devicetree/bindings/arc/*
  F:	Documentation/devicetree/bindings/interrupt-controller/snps,arc*
 +F:	drivers/clocksource/arc_timer.c
  F:	drivers/tty/serial/arc_uart.c
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git
  
@@@ -11975,16 -11920,6 +11978,16 @@@ S:	Maintaine
  F:	arch/xtensa/
  F:	drivers/irqchip/irq-xtensa-*
  
 +Texas Instruments' System Control Interface (TISCI) Protocol Driver
 +M:	Nishanth Menon <nm at ti.com>
 +M:	Tero Kristo <t-kristo at ti.com>
 +M:	Santosh Shilimkar <ssantosh at kernel.org>
 +L:	linux-arm-kernel at lists.infradead.org
 +S:	Maintained
 +F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 +F:	drivers/firmware/ti_sci*
 +F:	include/linux/soc/ti/ti_sci_protocol.h
 +
  THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
  M:	Hans Verkuil <hverkuil at xs4all.nl>
  L:	linux-media at vger.kernel.org
@@@ -12415,12 -12350,6 +12418,12 @@@ S:	Maintaine
  F:	Documentation/filesystems/udf.txt
  F:	fs/udf/
  
 +UDRAW TABLET
 +M:	Bastien Nocera <hadess at hadess.net>
 +L:	linux-input at vger.kernel.org
 +S:	Maintained
 +F:	drivers/hid/hid-udraw.c
 +
  UFS FILESYSTEM
  M:	Evgeniy Dushistov <dushistov at mail.ru>
  S:	Maintained
@@@ -12987,7 -12916,7 +12990,7 @@@ M:	Greg Kroah-Hartman <gregkh at linuxfoun
  L:	devel at driverdev.osuosl.org
  S:	Maintained
  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
 -F:	Documentation/vme_api.txt
 +F:	Documentation/driver-api/vme.rst
  F:	drivers/staging/vme/
  F:	drivers/vme/
  F:	include/linux/vme*
@@@ -13211,7 -13140,7 +13214,7 @@@ T:	git git://git.kernel.org/pub/scm/lin
  S:	Maintained
  F:	include/linux/workqueue.h
  F:	kernel/workqueue.c
 -F:	Documentation/workqueue.txt
 +F:	Documentation/core-api/workqueue.rst
  
  X-POWERS MULTIFUNCTION PMIC DEVICE DRIVERS
  M:	Chen-Yu Tsai <wens at csie.org>
diff --combined arch/arm/boot/dts/dra72-evm-revc.dts
index 4ea2a0c,3b23b32..c3d939c
--- a/arch/arm/boot/dts/dra72-evm-revc.dts
+++ b/arch/arm/boot/dts/dra72-evm-revc.dts
@@@ -17,22 -17,17 +17,22 @@@
  	};
  };
  
 -&tps65917_regulators {
 -	ldo2_reg: ldo2 {
 -		/* LDO2_OUT --> VDDA_1V8_PHY2 */
 -		regulator-name = "ldo2";
 -		regulator-min-microvolt = <1800000>;
 -		regulator-max-microvolt = <1800000>;
 -		regulator-always-on;
 -		regulator-boot-on;
 +&i2c1 {
 +	tps65917: tps65917 at 58 {
 +		reg = <0x58>;
 +
 +		interrupts = <GIC_SPI 2 IRQ_TYPE_NONE>;  /* IRQ_SYS_1N */
  	};
  };
  
 +#include "dra72-evm-tps65917.dtsi"
 +
 +&ldo2_reg {
 +	/* LDO2_OUT --> VDDA_1V8_PHY2 */
 +	regulator-always-on;
 +	regulator-boot-on;
 +};
 +
  &hdmi {
  	vdda-supply = <&ldo2_reg>;
  };
@@@ -64,15 -59,17 +64,17 @@@
  &davinci_mdio {
  	dp83867_0: ethernet-phy at 2 {
  		reg = <2>;
- 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
- 		ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_NS>;
+ 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ 		ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
  		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ 		ti,min-output-impedance;
  	};
  
  	dp83867_1: ethernet-phy at 3 {
  		reg = <3>;
- 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
- 		ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_NS>;
+ 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ 		ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
  		ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+ 		ti,min-output-imepdance;
  	};
  };
diff --combined arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index fa19cfd,1552db0..7ea617e
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@@ -88,10 -88,16 +88,16 @@@
  
  			switch0: switch0 at 0 {
  				compatible = "marvell,mv88e6085";
+ 				pinctrl-0 = <&pinctrl_gpio_switch0>;
+ 				pinctrl-names = "default";
  				#address-cells = <1>;
  				#size-cells = <0>;
  				reg = <0>;
  				dsa,member = <0 0>;
+ 				interrupt-parent = <&gpio0>;
+ 				interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
  
  				ports {
  					#address-cells = <1>;
@@@ -99,16 -105,19 +105,19 @@@
  					port at 0 {
  						reg = <0>;
  						label = "lan0";
+ 						phy-handle = <&switch0phy0>;
  					};
  
  					port at 1 {
  						reg = <1>;
  						label = "lan1";
+ 						phy-handle = <&switch0phy1>;
  					};
  
  					port at 2 {
  						reg = <2>;
  						label = "lan2";
+ 						phy-handle = <&switch0phy2>;
  					};
  
  					switch0port5: port at 5 {
@@@ -133,6 -142,24 +142,24 @@@
  						};
  					};
  				};
+ 				mdio {
+ 					#address-cells = <1>;
+ 					#size-cells = <0>;
+ 					switch0phy0: switch0phy0 at 0 {
+ 						reg = <0>;
+ 						interrupt-parent = <&switch0>;
+ 						interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+ 					};
+ 					switch0phy1: switch1phy0 at 1 {
+ 						reg = <1>;
+ 						interrupt-parent = <&switch0>;
+ 						interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;					};
+ 					switch0phy2: switch1phy0 at 2 {
+ 						reg = <2>;
+ 						interrupt-parent = <&switch0>;
+ 						interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+ 					};
+ 				};
  			};
  		};
  
@@@ -143,10 -170,16 +170,16 @@@
  
  			switch1: switch1 at 0 {
  				compatible = "marvell,mv88e6085";
+ 				pinctrl-0 = <&pinctrl_gpio_switch1>;
+ 				pinctrl-names = "default";
  				#address-cells = <1>;
  				#size-cells = <0>;
  				reg = <0>;
  				dsa,member = <0 1>;
+ 				interrupt-parent = <&gpio0>;
+ 				interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ 				interrupt-controller;
+ 				#interrupt-cells = <2>;
  
  				ports {
  					#address-cells = <1>;
@@@ -196,12 -229,18 +229,18 @@@
  					#size-cells = <0>;
  					switch1phy0: switch1phy0 at 0 {
  						reg = <0>;
+ 						interrupt-parent = <&switch1>;
+ 						interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
  					};
  					switch1phy1: switch1phy0 at 1 {
  						reg = <1>;
+ 						interrupt-parent = <&switch1>;
+ 						interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
  					};
  					switch1phy2: switch1phy0 at 2 {
  						reg = <2>;
+ 						interrupt-parent = <&switch1>;
+ 						interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
  					};
  				};
  			};
@@@ -499,6 -538,13 +538,6 @@@
  	};
  };
  
 -&i2c3 {
 -	clock-frequency = <100000>;
 -	pinctrl-names = "default";
 -	pinctrl-0 = <&pinctrl_i2c3>;
 -	status = "okay";
 -};
 -
  &uart0 {
  	pinctrl-names = "default";
  	pinctrl-0 = <&pinctrl_uart0>;
@@@ -629,6 -675,18 +668,18 @@@
  		>;
  	};
  
+ 	pinctrl_gpio_switch0: pinctrl-gpio-switch0 {
+ 		fsl,pins = <
+ 			VF610_PAD_PTB5__GPIO_27		0x219d
+ 		>;
+ 	};
+ 
+ 	pinctrl_gpio_switch1: pinctrl-gpio-switch1 {
+ 		fsl,pins = <
+ 			VF610_PAD_PTB4__GPIO_26		0x219d
+ 		>;
+ 	};
+ 
  	pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
  		fsl,pins = <
  			 VF610_PAD_PTE14__GPIO_119	0x31c2
@@@ -656,6 -714,13 +707,6 @@@
  		>;
  	};
  
 -	pinctrl_i2c3: i2c3grp {
 -		fsl,pins = <
 -			VF610_PAD_PTA30__I2C3_SCL	0x37ff
 -			VF610_PAD_PTA31__I2C3_SDA	0x37ff
 -		>;
 -	};
 -
  	pinctrl_leds_debug: pinctrl-leds-debug {
  		fsl,pins = <
  			 VF610_PAD_PTD20__GPIO_74	0x31c2
diff --combined arch/arm64/boot/dts/broadcom/ns2-svk.dts
index 3461907,c4d5442..de8d379
--- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts
+++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts
@@@ -56,6 -56,10 +56,10 @@@
  	};
  };
  
+ &enet {
+ 	status = "ok";
+ };
+ 
  &pci_phy0 {
  	status = "ok";
  };
@@@ -157,10 -161,6 +161,10 @@@
  	status = "ok";
  };
  
 +&sdio1 {
 +	status = "ok";
 +};
 +
  &nand {
  	nandcs at 0 {
  		compatible = "brcm,nandcs";
@@@ -178,6 -178,7 +182,7 @@@
  &mdio_mux_iproc {
  	mdio at 10 {
  		gphy0: eth-phy at 10 {
+ 			enet-phy-lane-swap;
  			reg = <0x10>;
  		};
  	};
@@@ -191,37 -192,3 +196,37 @@@
  		groups = "nand_grp";
  	};
  };
 +
 +&qspi {
 +	bspi-sel = <0>;
 +	flash: m25p80 at 0 {
 +		#address-cells = <1>;
 +		#size-cells = <1>;
 +		compatible = "m25p80";
 +		reg = <0x0>;
 +		spi-max-frequency = <12500000>;
 +		m25p,fast-read;
 +		spi-cpol;
 +		spi-cpha;
 +
 +		partition at 0 {
 +			label = "boot";
 +			reg = <0x00000000 0x000a0000>;
 +		};
 +
 +		partition at a0000 {
 +			label = "env";
 +			reg = <0x000a0000 0x00060000>;
 +		};
 +
 +		partition at 100000 {
 +			label = "system";
 +			reg = <0x00100000 0x00600000>;
 +		};
 +
 +		partition at 700000 {
 +			label = "rootfs";
 +			reg = <0x00700000 0x01900000>;
 +		};
 +	};
 +};
diff --combined arch/arm64/boot/dts/broadcom/ns2.dtsi
index 863503d,773ed59..07704b5
--- a/arch/arm64/boot/dts/broadcom/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi
@@@ -133,9 -133,6 +133,9 @@@
  
  		status = "disabled";
  
 +		phys = <&pci_phy0>;
 +		phy-names = "pcie-phy";
 +
  		msi-parent = <&msi0>;
  		msi0: msi at 20020000 {
  			compatible = "brcm,iproc-msi";
@@@ -174,9 -171,6 +174,9 @@@
  
  		status = "disabled";
  
 +		phys = <&pci_phy1>;
 +		phy-names = "pcie-phy";
 +
  		msi-parent = <&msi4>;
  		msi4: msi at 50020000 {
  			compatible = "brcm,iproc-msi";
@@@ -197,42 -191,18 +197,54 @@@
  
  		#include "ns2-clock.dtsi"
  
 +		pdc0: iproc-pdc0 at 612c0000 {
 +			compatible = "brcm,iproc-pdc-mbox";
 +			reg = <0x612c0000 0x445>;  /* PDC FS0 regs */
 +			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
 +			#mbox-cells = <1>;
 +			brcm,rx-status-len = <32>;
 +			brcm,use-bcm-hdr;
 +		};
 +
 +		pdc1: iproc-pdc1 at 612e0000 {
 +			compatible = "brcm,iproc-pdc-mbox";
 +			reg = <0x612e0000 0x445>;  /* PDC FS1 regs */
 +			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
 +			#mbox-cells = <1>;
 +			brcm,rx-status-len = <32>;
 +			brcm,use-bcm-hdr;
 +		};
 +
 +		pdc2: iproc-pdc2 at 61300000 {
 +			compatible = "brcm,iproc-pdc-mbox";
 +			reg = <0x61300000 0x445>;  /* PDC FS2 regs */
 +			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
 +			#mbox-cells = <1>;
 +			brcm,rx-status-len = <32>;
 +			brcm,use-bcm-hdr;
 +		};
 +
 +		pdc3: iproc-pdc3 at 61320000 {
 +			compatible = "brcm,iproc-pdc-mbox";
 +			reg = <0x61320000 0x445>;  /* PDC FS3 regs */
 +			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
 +			#mbox-cells = <1>;
 +			brcm,rx-status-len = <32>;
 +			brcm,use-bcm-hdr;
 +		};
 +
+ 		enet: ethernet at 61000000 {
+ 			compatible = "brcm,ns2-amac";
+ 			reg = <0x61000000 0x1000>,
+ 			      <0x61090000 0x1000>,
+ 			      <0x61030000 0x100>;
+ 			reg-names = "amac_base", "idm_base", "nicpm_base";
+ 			interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+ 			phy-handle = <&gphy0>;
+ 			phy-mode = "rgmii";
+ 			status = "disabled";
+ 		};
+ 
  		dma0: dma at 61360000 {
  			compatible = "arm,pl330", "arm,primecell";
  			reg = <0x61360000 0x1000>;
@@@ -290,7 -260,7 +302,7 @@@
  				     <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
  				     <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
  				     <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
 -			mmu-masters;
 +			#iommu-cells = <1>;
  		};
  
  		pinctrl: pinctrl at 6501d130 {
@@@ -607,23 -577,5 +619,23 @@@
  
  			brcm,nand-has-wp;
  		};
 +
 +		qspi: spi at 66470200 {
 +			compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi";
 +			reg = <0x66470200 0x184>,
 +				<0x66470000 0x124>,
 +				<0x67017408 0x004>,
 +				<0x664703a0 0x01c>;
 +			reg-names = "mspi", "bspi", "intr_regs",
 +				"intr_status_reg";
 +			interrupts = <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>;
 +			interrupt-names = "spi_l1_intr";
 +			clocks = <&iprocmed>;
 +			clock-names = "iprocmed";
 +			num-cs = <2>;
 +			#address-cells = <1>;
 +			#size-cells = <0>;
 +		};
 +
  	};
  };
diff --combined arch/arm64/boot/dts/marvell/armada-3720-db.dts
index a260ae2,a59d36c..89de0a7
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@@ -56,7 -56,7 +56,7 @@@
  		stdout-path = "serial0:115200n8";
  	};
  
 -	memory {
 +	memory at 0 {
  		device_type = "memory";
  		reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
  	};
@@@ -81,3 -81,26 +81,26 @@@
  &pcie0 {
  	status = "okay";
  };
+ 
+ &mdio {
+ 	status = "okay";
+ 	phy0: ethernet-phy at 0 {
+ 		reg = <0>;
+ 	};
+ 
+ 	phy1: ethernet-phy at 1 {
+ 		reg = <1>;
+ 	};
+ };
+ 
+ &eth0 {
+ 	phy-mode = "rgmii-id";
+ 	phy = <&phy0>;
+ 	status = "okay";
+ };
+ 
+ &eth1 {
+ 	phy-mode = "sgmii";
+ 	phy = <&phy1>;
+ 	status = "okay";
+ };
diff --combined arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index eba2e38,3b8eb45..bab5c6f
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@@ -91,7 -91,7 +91,7 @@@
  		#size-cells = <2>;
  		ranges;
  
 -		internal-regs {
 +		internal-regs at d0000000 {
  			#address-cells = <1>;
  			#size-cells = <1>;
  			compatible = "simple-bus";
@@@ -140,6 -140,29 +140,29 @@@
  				};
  			};
  
+ 			eth0: ethernet at 30000 {
+ 				   compatible = "marvell,armada-3700-neta";
+ 				   reg = <0x30000 0x4000>;
+ 				   interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ 				   clocks = <&sb_periph_clk 8>;
+ 				   status = "disabled";
+ 			};
+ 
+ 			mdio: mdio at 32004 {
+ 				#address-cells = <1>;
+ 				#size-cells = <0>;
+ 				compatible = "marvell,orion-mdio";
+ 				reg = <0x32004 0x4>;
+ 			};
+ 
+ 			eth1: ethernet at 40000 {
+ 				compatible = "marvell,armada-3700-neta";
+ 				reg = <0x40000 0x4000>;
+ 				interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ 				clocks = <&sb_periph_clk 7>;
+ 				status = "disabled";
+ 			};
+ 
  			usb3: usb at 58000 {
  				compatible = "marvell,armada3700-xhci",
  				"generic-xhci";
diff --combined arch/arm64/configs/defconfig
index 0bba32a,6be0811..869dded
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@@ -11,6 -11,7 +11,6 @@@ CONFIG_TASK_XACCT=
  CONFIG_TASK_IO_ACCOUNTING=y
  CONFIG_IKCONFIG=y
  CONFIG_IKCONFIG_PROC=y
 -CONFIG_LOG_BUF_SHIFT=14
  CONFIG_MEMCG=y
  CONFIG_MEMCG_SWAP=y
  CONFIG_BLK_CGROUP=y
@@@ -33,7 -34,6 +33,7 @@@ CONFIG_MODULE_UNLOAD=
  # CONFIG_IOSCHED_DEADLINE is not set
  CONFIG_ARCH_SUNXI=y
  CONFIG_ARCH_ALPINE=y
 +CONFIG_ARCH_BCM2835=y
  CONFIG_ARCH_BCM_IPROC=y
  CONFIG_ARCH_BERLIN=y
  CONFIG_ARCH_EXYNOS=y
@@@ -82,7 -82,6 +82,7 @@@ CONFIG_KEXEC=
  # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  CONFIG_COMPAT=y
  CONFIG_CPU_IDLE=y
 +CONFIG_HIBERNATION=y
  CONFIG_ARM_CPUIDLE=y
  CONFIG_CPU_FREQ=y
  CONFIG_CPUFREQ_DT=y
@@@ -148,7 -147,6 +148,7 @@@ CONFIG_MTD_SPI_NOR=
  CONFIG_BLK_DEV_LOOP=y
  CONFIG_BLK_DEV_NBD=m
  CONFIG_VIRTIO_BLK=y
 +CONFIG_EEPROM_AT25=m
  CONFIG_SRAM=y
  # CONFIG_SCSI_PROC_FS is not set
  CONFIG_BLK_DEV_SD=y
@@@ -185,10 -183,7 +185,10 @@@ CONFIG_SMC91X=
  CONFIG_SMSC911X=y
  CONFIG_STMMAC_ETH=m
  CONFIG_REALTEK_PHY=m
 +CONFIG_MESON_GXL_PHY=m
  CONFIG_MICREL_PHY=y
 +CONFIG_MDIO_BUS_MUX=y
 +CONFIG_MDIO_BUS_MUX_MMIOREG=y
  CONFIG_USB_PEGASUS=m
  CONFIG_USB_RTL8150=m
  CONFIG_USB_RTL8152=m
@@@ -199,7 -194,6 +199,7 @@@ CONFIG_USB_NET_SMSC75XX=
  CONFIG_USB_NET_SMSC95XX=m
  CONFIG_USB_NET_PLUSB=m
  CONFIG_USB_NET_MCS7830=m
 +CONFIG_BRCMFMAC=m
  CONFIG_WL18XX=m
  CONFIG_WLCORE_SDIO=m
  CONFIG_INPUT_EVDEV=y
@@@ -212,9 -206,6 +212,9 @@@ CONFIG_SERIO_AMBAKMI=
  CONFIG_LEGACY_PTY_COUNT=16
  CONFIG_SERIAL_8250=y
  CONFIG_SERIAL_8250_CONSOLE=y
 +CONFIG_SERIAL_8250_EXTENDED=y
 +CONFIG_SERIAL_8250_SHARE_IRQ=y
 +CONFIG_SERIAL_8250_BCM2835AUX=y
  CONFIG_SERIAL_8250_DW=y
  CONFIG_SERIAL_8250_MT6577=y
  CONFIG_SERIAL_8250_UNIPHIER=y
@@@ -238,21 -229,17 +238,21 @@@ CONFIG_VIRTIO_CONSOLE=
  CONFIG_I2C_CHARDEV=y
  CONFIG_I2C_MUX=y
  CONFIG_I2C_MUX_PCA954x=y
 +CONFIG_I2C_BCM2835=m
  CONFIG_I2C_DESIGNWARE_PLATFORM=y
  CONFIG_I2C_IMX=y
  CONFIG_I2C_MESON=y
  CONFIG_I2C_MV64XXX=y
  CONFIG_I2C_QUP=y
 +CONFIG_I2C_RK3X=y
  CONFIG_I2C_TEGRA=y
  CONFIG_I2C_UNIPHIER_F=y
  CONFIG_I2C_RCAR=y
  CONFIG_I2C_CROS_EC_TUNNEL=y
  CONFIG_SPI=y
  CONFIG_SPI_MESON_SPIFC=m
 +CONFIG_SPI_BCM2835=m
 +CONFIG_SPI_BCM2835AUX=m
  CONFIG_SPI_ORION=y
  CONFIG_SPI_PL022=y
  CONFIG_SPI_QUP=y
@@@ -262,14 -249,15 +262,15 @@@ CONFIG_SPMI=
  CONFIG_PINCTRL_SINGLE=y
  CONFIG_PINCTRL_MAX77620=y
  CONFIG_PINCTRL_MSM8916=y
 +CONFIG_PINCTRL_MSM8994=y
  CONFIG_PINCTRL_MSM8996=y
  CONFIG_PINCTRL_QDF2XXX=y
  CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 -CONFIG_GPIO_SYSFS=y
  CONFIG_GPIO_DWAPB=y
  CONFIG_GPIO_PL061=y
  CONFIG_GPIO_RCAR=y
  CONFIG_GPIO_XGENE=y
+ CONFIG_GPIO_XGENE_SB=y
  CONFIG_GPIO_PCA953X=y
  CONFIG_GPIO_PCA953X_IRQ=y
  CONFIG_GPIO_MAX77620=y
@@@ -284,16 -272,13 +285,16 @@@ CONFIG_THERMAL=
  CONFIG_THERMAL_EMULATION=y
  CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
  CONFIG_CPU_THERMAL=y
 +CONFIG_BCM2835_THERMAL=y
  CONFIG_EXYNOS_THERMAL=y
  CONFIG_WATCHDOG=y
 +CONFIG_BCM2835_WDT=y
  CONFIG_RENESAS_WDT=y
  CONFIG_S3C2410_WATCHDOG=y
  CONFIG_MESON_GXBB_WATCHDOG=m
  CONFIG_MESON_WATCHDOG=m
  CONFIG_MFD_MAX77620=y
 +CONFIG_MFD_RK808=y
  CONFIG_MFD_SPMI_PMIC=y
  CONFIG_MFD_SEC_CORE=y
  CONFIG_MFD_HI655X_PMIC=y
@@@ -307,26 -292,10 +308,26 @@@ CONFIG_REGULATOR_MAX77620=
  CONFIG_REGULATOR_PWM=y
  CONFIG_REGULATOR_QCOM_SMD_RPM=y
  CONFIG_REGULATOR_QCOM_SPMI=y
 +CONFIG_REGULATOR_RK808=y
  CONFIG_REGULATOR_S2MPS11=y
 +CONFIG_MEDIA_SUPPORT=m
 +CONFIG_MEDIA_CAMERA_SUPPORT=y
 +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 +CONFIG_MEDIA_CONTROLLER=y
 +CONFIG_VIDEO_V4L2_SUBDEV_API=y
 +# CONFIG_DVB_NET is not set
 +CONFIG_V4L_MEM2MEM_DRIVERS=y
 +CONFIG_VIDEO_RENESAS_FCP=m
 +CONFIG_VIDEO_RENESAS_VSP1=m
  CONFIG_DRM=m
  CONFIG_DRM_NOUVEAU=m
 +CONFIG_DRM_RCAR_DU=m
 +CONFIG_DRM_RCAR_HDMI=y
 +CONFIG_DRM_RCAR_LVDS=y
 +CONFIG_DRM_RCAR_VSP=y
  CONFIG_DRM_TEGRA=m
 +CONFIG_DRM_VC4=m
  CONFIG_DRM_PANEL_SIMPLE=m
  CONFIG_DRM_I2C_ADV7511=m
  CONFIG_DRM_HISI_KIRIN=m
@@@ -341,7 -310,6 +342,7 @@@ CONFIG_LOGO=
  CONFIG_SOUND=y
  CONFIG_SND=y
  CONFIG_SND_SOC=y
 +CONFIG_SND_BCM2835_SOC_I2S=m
  CONFIG_SND_SOC_RCAR=y
  CONFIG_SND_SOC_SAMSUNG=y
  CONFIG_SND_SOC_AK4613=y
@@@ -374,11 -342,9 +375,11 @@@ CONFIG_USB_RENESAS_USBHS_UDC=
  CONFIG_MMC=y
  CONFIG_MMC_BLOCK_MINORS=32
  CONFIG_MMC_ARMMMCI=y
 +CONFIG_MMC_MESON_GX=y
  CONFIG_MMC_SDHCI=y
  CONFIG_MMC_SDHCI_ACPI=y
  CONFIG_MMC_SDHCI_PLTFM=y
 +CONFIG_MMC_SDHCI_OF_ARASAN=y
  CONFIG_MMC_SDHCI_OF_ESDHC=y
  CONFIG_MMC_SDHCI_TEGRA=y
  CONFIG_MMC_SDHCI_MSM=y
@@@ -387,7 -353,6 +388,7 @@@ CONFIG_MMC_SDHI=
  CONFIG_MMC_DW=y
  CONFIG_MMC_DW_EXYNOS=y
  CONFIG_MMC_DW_K3=y
 +CONFIG_MMC_DW_ROCKCHIP=y
  CONFIG_MMC_SUNXI=y
  CONFIG_NEW_LEDS=y
  CONFIG_LEDS_CLASS=y
@@@ -403,13 -368,11 +404,13 @@@ CONFIG_RTC_DRV_DS3232=
  CONFIG_RTC_DRV_EFI=y
  CONFIG_RTC_DRV_PL031=y
  CONFIG_RTC_DRV_SUN6I=y
 +CONFIG_RTC_DRV_RK808=m
  CONFIG_RTC_DRV_TEGRA=y
  CONFIG_RTC_DRV_XGENE=y
  CONFIG_RTC_DRV_S3C=y
  CONFIG_DMADEVICES=y
  CONFIG_PL330_DMA=y
 +CONFIG_DMA_BCM2835=m
  CONFIG_TEGRA20_APB_DMA=y
  CONFIG_QCOM_BAM_DMA=y
  CONFIG_QCOM_HIDMA_MGMT=y
@@@ -425,39 -388,26 +426,39 @@@ CONFIG_XEN_GRANT_DEV_ALLOC=
  CONFIG_COMMON_CLK_SCPI=y
  CONFIG_COMMON_CLK_CS2000_CP=y
  CONFIG_COMMON_CLK_S2MPS11=y
 +CONFIG_COMMON_CLK_PWM=y
 +CONFIG_COMMON_CLK_RK808=y
  CONFIG_CLK_QORIQ=y
  CONFIG_COMMON_CLK_QCOM=y
  CONFIG_MSM_GCC_8916=y
 +CONFIG_MSM_GCC_8994=y
  CONFIG_MSM_MMCC_8996=y
  CONFIG_HWSPINLOCK_QCOM=y
  CONFIG_MAILBOX=y
  CONFIG_ARM_MHU=y
 +CONFIG_PLATFORM_MHU=y
 +CONFIG_BCM2835_MBOX=y
  CONFIG_HI6220_MBOX=y
  CONFIG_ARM_SMMU=y
 +CONFIG_RASPBERRYPI_POWER=y
  CONFIG_QCOM_SMEM=y
  CONFIG_QCOM_SMD=y
  CONFIG_QCOM_SMD_RPM=y
 +CONFIG_ROCKCHIP_PM_DOMAINS=y
  CONFIG_ARCH_TEGRA_132_SOC=y
  CONFIG_ARCH_TEGRA_210_SOC=y
 +CONFIG_ARCH_TEGRA_186_SOC=y
  CONFIG_EXTCON_USB_GPIO=y
  CONFIG_PWM=y
 +CONFIG_PWM_BCM2835=m
 +CONFIG_PWM_ROCKCHIP=y
  CONFIG_PWM_TEGRA=m
 +CONFIG_PWM_MESON=m
  CONFIG_COMMON_RESET_HI6220=y
  CONFIG_PHY_RCAR_GEN3_USB2=y
  CONFIG_PHY_HI6220_USB=y
 +CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 +CONFIG_PHY_ROCKCHIP_EMMC=y
  CONFIG_PHY_XGENE=y
  CONFIG_PHY_TEGRA_XUSB=y
  CONFIG_ARM_SCPI_PROTOCOL=y
@@@ -465,7 -415,6 +466,7 @@@ CONFIG_ACPI=
  CONFIG_IIO=y
  CONFIG_EXYNOS_ADC=y
  CONFIG_PWM_SAMSUNG=y
 +CONFIG_RASPBERRYPI_FIRMWARE=y
  CONFIG_EXT2_FS=y
  CONFIG_EXT3_FS=y
  CONFIG_EXT4_FS_POSIX_ACL=y
diff --combined drivers/media/dvb-core/dvb_net.c
index bd833b0,0da622f..dfc03a9
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@@ -54,8 -54,6 +54,8 @@@
   *
   */
  
 +#define pr_fmt(fmt) "dvb_net: " fmt
 +
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
@@@ -311,589 -309,451 +311,589 @@@ static inline void reset_ule( struct dv
   * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of
   * TS cells of a single PID.
   */
 -static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 -{
 -	struct dvb_net_priv *priv = netdev_priv(dev);
 -	unsigned long skipped = 0L;
 -	const u8 *ts, *ts_end, *from_where = NULL;
 -	u8 ts_remain = 0, how_much = 0, new_ts = 1;
 -	struct ethhdr *ethh = NULL;
 -	bool error = false;
  
 +struct dvb_net_ule_handle {
 +	struct net_device *dev;
 +	struct dvb_net_priv *priv;
 +	struct ethhdr *ethh;
 +	const u8 *buf;
 +	size_t buf_len;
 +	unsigned long skipped;
 +	const u8 *ts, *ts_end, *from_where;
 +	u8 ts_remain, how_much, new_ts;
 +	bool error;
  #ifdef ULE_DEBUG
 -	/* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
 +	/*
 +	 * The code inside ULE_DEBUG keeps a history of the
 +	 * last 100 TS cells processed.
 +	 */
  	static unsigned char ule_hist[100*TS_SZ];
  	static unsigned char *ule_where = ule_hist, ule_dump;
  #endif
 +};
  
 -	/* For all TS cells in current buffer.
 -	 * Appearently, we are called for every single TS cell.
 -	 */
 -	for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) {
 -
 -		if (new_ts) {
 -			/* We are about to process a new TS cell. */
 +static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h)
 +{
 +	/* We are about to process a new TS cell. */
  
  #ifdef ULE_DEBUG
 -			if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist;
 -			memcpy( ule_where, ts, TS_SZ );
 -			if (ule_dump) {
 -				hexdump( ule_where, TS_SZ );
 -				ule_dump = 0;
 -			}
 -			ule_where += TS_SZ;
 +	if (h->ule_where >= &h->ule_hist[100*TS_SZ])
 +		h->ule_where = h->ule_hist;
 +	memcpy(h->ule_where, h->ts, TS_SZ);
 +	if (h->ule_dump) {
 +		hexdump(h->ule_where, TS_SZ);
 +		h->ule_dump = 0;
 +	}
 +	h->ule_where += TS_SZ;
  #endif
  
 -			/* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */
 -			if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) {
 -				printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
 -				       priv->ts_count, ts[0],
 -				       (ts[1] & TS_TEI) >> 7,
 -				       (ts[3] & TS_SC) >> 6);
 -
 -				/* Drop partly decoded SNDU, reset state, resync on PUSI. */
 -				if (priv->ule_skb) {
 -					dev_kfree_skb( priv->ule_skb );
 -					/* Prepare for next SNDU. */
 -					dev->stats.rx_errors++;
 -					dev->stats.rx_frame_errors++;
 -				}
 -				reset_ule(priv);
 -				priv->need_pusi = 1;
 +	/*
 +	 * Check TS h->error conditions: sync_byte, transport_error_indicator,
 +	 * scrambling_control .
 +	 */
 +	if ((h->ts[0] != TS_SYNC) || (h->ts[1] & TS_TEI) ||
 +	    ((h->ts[3] & TS_SC) != 0)) {
 +		pr_warn("%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n",
 +			h->priv->ts_count, h->ts[0],
 +			(h->ts[1] & TS_TEI) >> 7,
 +			(h->ts[3] & TS_SC) >> 6);
 +
 +		/* Drop partly decoded SNDU, reset state, resync on PUSI. */
 +		if (h->priv->ule_skb) {
 +			dev_kfree_skb(h->priv->ule_skb);
 +			/* Prepare for next SNDU. */
 +			h->dev->stats.rx_errors++;
 +			h->dev->stats.rx_frame_errors++;
 +		}
 +		reset_ule(h->priv);
 +		h->priv->need_pusi = 1;
  
 -				/* Continue with next TS cell. */
 -				ts += TS_SZ;
 -				priv->ts_count++;
 -				continue;
 -			}
 +		/* Continue with next TS cell. */
 +		h->ts += TS_SZ;
 +		h->priv->ts_count++;
 +		return 1;
 +	}
 +
 +	h->ts_remain = 184;
 +	h->from_where = h->ts + 4;
  
 -			ts_remain = 184;
 -			from_where = ts + 4;
 +	return 0;
 +}
 +
 +static int dvb_net_ule_ts_pusi(struct dvb_net_ule_handle *h)
 +{
 +	if (h->ts[1] & TS_PUSI) {
 +		/* Find beginning of first ULE SNDU in current TS cell. */
 +		/* Synchronize continuity counter. */
 +		h->priv->tscc = h->ts[3] & 0x0F;
 +		/* There is a pointer field here. */
 +		if (h->ts[4] > h->ts_remain) {
 +			pr_err("%lu: Invalid ULE packet (pointer field %d)\n",
 +				h->priv->ts_count, h->ts[4]);
 +			h->ts += TS_SZ;
 +			h->priv->ts_count++;
 +			return 1;
  		}
 -		/* Synchronize on PUSI, if required. */
 -		if (priv->need_pusi) {
 -			if (ts[1] & TS_PUSI) {
 -				/* Find beginning of first ULE SNDU in current TS cell. */
 -				/* Synchronize continuity counter. */
 -				priv->tscc = ts[3] & 0x0F;
 -				/* There is a pointer field here. */
 -				if (ts[4] > ts_remain) {
 -					printk(KERN_ERR "%lu: Invalid ULE packet "
 -					       "(pointer field %d)\n", priv->ts_count, ts[4]);
 -					ts += TS_SZ;
 -					priv->ts_count++;
 -					continue;
 -				}
 -				/* Skip to destination of pointer field. */
 -				from_where = &ts[5] + ts[4];
 -				ts_remain -= 1 + ts[4];
 -				skipped = 0;
 -			} else {
 -				skipped++;
 -				ts += TS_SZ;
 -				priv->ts_count++;
 -				continue;
 -			}
 +		/* Skip to destination of pointer field. */
 +		h->from_where = &h->ts[5] + h->ts[4];
 +		h->ts_remain -= 1 + h->ts[4];
 +		h->skipped = 0;
 +	} else {
 +		h->skipped++;
 +		h->ts += TS_SZ;
 +		h->priv->ts_count++;
 +		return 1;
 +	}
 +
 +	return 0;
 +}
 +
 +static int dvb_net_ule_new_ts(struct dvb_net_ule_handle *h)
 +{
 +	/* Check continuity counter. */
 +	if ((h->ts[3] & 0x0F) == h->priv->tscc)
 +		h->priv->tscc = (h->priv->tscc + 1) & 0x0F;
 +	else {
 +		/* TS discontinuity handling: */
 +		pr_warn("%lu: TS discontinuity: got %#x, expected %#x.\n",
 +			h->priv->ts_count, h->ts[3] & 0x0F,
 +			h->priv->tscc);
 +		/* Drop partly decoded SNDU, reset state, resync on PUSI. */
 +		if (h->priv->ule_skb) {
 +			dev_kfree_skb(h->priv->ule_skb);
 +			/* Prepare for next SNDU. */
 +			// reset_ule(h->priv);  moved to below.
 +			h->dev->stats.rx_errors++;
 +			h->dev->stats.rx_frame_errors++;
  		}
 +		reset_ule(h->priv);
 +		/* skip to next PUSI. */
 +		h->priv->need_pusi = 1;
 +		return 1;
 +	}
 +	/*
 +	 * If we still have an incomplete payload, but PUSI is
 +	 * set; some TS cells are missing.
 +	 * This is only possible here, if we missed exactly 16 TS
 +	 * cells (continuity counter wrap).
 +	 */
 +	if (h->ts[1] & TS_PUSI) {
 +		if (!h->priv->need_pusi) {
 +			if (!(*h->from_where < (h->ts_remain-1)) ||
 +			    *h->from_where != h->priv->ule_sndu_remain) {
 +				/*
 +				 * Pointer field is invalid.
 +				 * Drop this TS cell and any started ULE SNDU.
 +				 */
 +				pr_warn("%lu: Invalid pointer field: %u.\n",
 +					h->priv->ts_count,
 +					*h->from_where);
  
 -		if (new_ts) {
 -			/* Check continuity counter. */
 -			if ((ts[3] & 0x0F) == priv->tscc)
 -				priv->tscc = (priv->tscc + 1) & 0x0F;
 -			else {
 -				/* TS discontinuity handling: */
 -				printk(KERN_WARNING "%lu: TS discontinuity: got %#x, "
 -				       "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc);
 -				/* Drop partly decoded SNDU, reset state, resync on PUSI. */
 -				if (priv->ule_skb) {
 -					dev_kfree_skb( priv->ule_skb );
 -					/* Prepare for next SNDU. */
 -					// reset_ule(priv);  moved to below.
 -					dev->stats.rx_errors++;
 -					dev->stats.rx_frame_errors++;
 +				/*
 +				 * Drop partly decoded SNDU, reset state,
 +				 * resync on PUSI.
 +				 */
 +				if (h->priv->ule_skb) {
 +					h->error = true;
 +					dev_kfree_skb(h->priv->ule_skb);
  				}
 -				reset_ule(priv);
 -				/* skip to next PUSI. */
 -				priv->need_pusi = 1;
 -				continue;
 -			}
 -			/* If we still have an incomplete payload, but PUSI is
 -			 * set; some TS cells are missing.
 -			 * This is only possible here, if we missed exactly 16 TS
 -			 * cells (continuity counter wrap). */
 -			if (ts[1] & TS_PUSI) {
 -				if (! priv->need_pusi) {
 -					if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) {
 -						/* Pointer field is invalid.  Drop this TS cell and any started ULE SNDU. */
 -						printk(KERN_WARNING "%lu: Invalid pointer "
 -						       "field: %u.\n", priv->ts_count, *from_where);
 -
 -						/* Drop partly decoded SNDU, reset state, resync on PUSI. */
 -						if (priv->ule_skb) {
 -							error = true;
 -							dev_kfree_skb(priv->ule_skb);
 -						}
 -
 -						if (error || priv->ule_sndu_remain) {
 -							dev->stats.rx_errors++;
 -							dev->stats.rx_frame_errors++;
 -							error = false;
 -						}
 -
 -						reset_ule(priv);
 -						priv->need_pusi = 1;
 -						continue;
 -					}
 -					/* Skip pointer field (we're processing a
 -					 * packed payload). */
 -					from_where += 1;
 -					ts_remain -= 1;
 -				} else
 -					priv->need_pusi = 0;
 -
 -				if (priv->ule_sndu_remain > 183) {
 -					/* Current SNDU lacks more data than there could be available in the
 -					 * current TS cell. */
 -					dev->stats.rx_errors++;
 -					dev->stats.rx_length_errors++;
 -					printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but "
 -					       "got PUSI (pf %d, ts_remain %d).  Flushing incomplete payload.\n",
 -					       priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain);
 -					dev_kfree_skb(priv->ule_skb);
 -					/* Prepare for next SNDU. */
 -					reset_ule(priv);
 -					/* Resync: go to where pointer field points to: start of next ULE SNDU. */
 -					from_where += ts[4];
 -					ts_remain -= ts[4];
 +
 +				if (h->error || h->priv->ule_sndu_remain) {
 +					h->dev->stats.rx_errors++;
 +					h->dev->stats.rx_frame_errors++;
 +					h->error = false;
  				}
 +
 +				reset_ule(h->priv);
 +				h->priv->need_pusi = 1;
 +				return 1;
  			}
 +			/*
 +			 * Skip pointer field (we're processing a
 +			 * packed payload).
 +			 */
 +			h->from_where += 1;
 +			h->ts_remain -= 1;
 +		} else
 +			h->priv->need_pusi = 0;
 +
 +		if (h->priv->ule_sndu_remain > 183) {
 +			/*
 +			 * Current SNDU lacks more data than there
 +			 * could be available in the current TS cell.
 +			 */
 +			h->dev->stats.rx_errors++;
 +			h->dev->stats.rx_length_errors++;
 +			pr_warn("%lu: Expected %d more SNDU bytes, but got PUSI (pf %d, h->ts_remain %d).  Flushing incomplete payload.\n",
 +				h->priv->ts_count,
 +				h->priv->ule_sndu_remain,
 +				h->ts[4], h->ts_remain);
 +			dev_kfree_skb(h->priv->ule_skb);
 +			/* Prepare for next SNDU. */
 +			reset_ule(h->priv);
 +			/*
 +			 * Resync: go to where pointer field points to:
 +			 * start of next ULE SNDU.
 +			 */
 +			h->from_where += h->ts[4];
 +			h->ts_remain -= h->ts[4];
  		}
 +	}
 +	return 0;
 +}
  
 -		/* Check if new payload needs to be started. */
 -		if (priv->ule_skb == NULL) {
 -			/* Start a new payload with skb.
 -			 * Find ULE header.  It is only guaranteed that the
 -			 * length field (2 bytes) is contained in the current
 -			 * TS.
 -			 * Check ts_remain has to be >= 2 here. */
 -			if (ts_remain < 2) {
 -				printk(KERN_WARNING "Invalid payload packing: only %d "
 -				       "bytes left in TS.  Resyncing.\n", ts_remain);
 -				priv->ule_sndu_len = 0;
 -				priv->need_pusi = 1;
 -				ts += TS_SZ;
 -				continue;
 -			}
  
 -			if (! priv->ule_sndu_len) {
 -				/* Got at least two bytes, thus extrace the SNDU length. */
 -				priv->ule_sndu_len = from_where[0] << 8 | from_where[1];
 -				if (priv->ule_sndu_len & 0x8000) {
 -					/* D-Bit is set: no dest mac present. */
 -					priv->ule_sndu_len &= 0x7FFF;
 -					priv->ule_dbit = 1;
 -				} else
 -					priv->ule_dbit = 0;
 -
 -				if (priv->ule_sndu_len < 5) {
 -					printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. "
 -					       "Resyncing.\n", priv->ts_count, priv->ule_sndu_len);
 -					dev->stats.rx_errors++;
 -					dev->stats.rx_length_errors++;
 -					priv->ule_sndu_len = 0;
 -					priv->need_pusi = 1;
 -					new_ts = 1;
 -					ts += TS_SZ;
 -					priv->ts_count++;
 -					continue;
 -				}
 -				ts_remain -= 2;	/* consume the 2 bytes SNDU length. */
 -				from_where += 2;
 -			}
 +/*
 + * Start a new payload with skb.
 + * Find ULE header.  It is only guaranteed that the
 + * length field (2 bytes) is contained in the current
 + * TS.
 + * Check h.ts_remain has to be >= 2 here.
 + */
 +static int dvb_net_ule_new_payload(struct dvb_net_ule_handle *h)
 +{
 +	if (h->ts_remain < 2) {
 +		pr_warn("Invalid payload packing: only %d bytes left in TS.  Resyncing.\n",
 +			h->ts_remain);
 +		h->priv->ule_sndu_len = 0;
 +		h->priv->need_pusi = 1;
 +		h->ts += TS_SZ;
 +		return 1;
 +	}
 +
 +	if (!h->priv->ule_sndu_len) {
 +		/* Got at least two bytes, thus extrace the SNDU length. */
 +		h->priv->ule_sndu_len = h->from_where[0] << 8 |
 +					h->from_where[1];
 +		if (h->priv->ule_sndu_len & 0x8000) {
 +			/* D-Bit is set: no dest mac present. */
 +			h->priv->ule_sndu_len &= 0x7FFF;
 +			h->priv->ule_dbit = 1;
 +		} else
 +			h->priv->ule_dbit = 0;
 +
 +		if (h->priv->ule_sndu_len < 5) {
 +			pr_warn("%lu: Invalid ULE SNDU length %u. Resyncing.\n",
 +				h->priv->ts_count,
 +				h->priv->ule_sndu_len);
 +			h->dev->stats.rx_errors++;
 +			h->dev->stats.rx_length_errors++;
 +			h->priv->ule_sndu_len = 0;
 +			h->priv->need_pusi = 1;
 +			h->new_ts = 1;
 +			h->ts += TS_SZ;
 +			h->priv->ts_count++;
 +			return 1;
 +		}
 +		h->ts_remain -= 2;	/* consume the 2 bytes SNDU length. */
 +		h->from_where += 2;
 +	}
 +
 +	h->priv->ule_sndu_remain = h->priv->ule_sndu_len + 2;
 +	/*
 +	 * State of current TS:
 +	 *   h->ts_remain (remaining bytes in the current TS cell)
 +	 *   0	ule_type is not available now, we need the next TS cell
 +	 *   1	the first byte of the ule_type is present
 +	 * >=2	full ULE header present, maybe some payload data as well.
 +	 */
 +	switch (h->ts_remain) {
 +	case 1:
 +		h->priv->ule_sndu_remain--;
 +		h->priv->ule_sndu_type = h->from_where[0] << 8;
 +
 +		/* first byte of ule_type is set. */
 +		h->priv->ule_sndu_type_1 = 1;
 +		h->ts_remain -= 1;
 +		h->from_where += 1;
 +		/* fallthrough */
 +	case 0:
 +		h->new_ts = 1;
 +		h->ts += TS_SZ;
 +		h->priv->ts_count++;
 +		return 1;
 +
 +	default: /* complete ULE header is present in current TS. */
 +		/* Extract ULE type field. */
 +		if (h->priv->ule_sndu_type_1) {
 +			h->priv->ule_sndu_type_1 = 0;
 +			h->priv->ule_sndu_type |= h->from_where[0];
 +			h->from_where += 1; /* points to payload start. */
 +			h->ts_remain -= 1;
 +		} else {
 +			/* Complete type is present in new TS. */
 +			h->priv->ule_sndu_type = h->from_where[0] << 8 |
 +						 h->from_where[1];
 +			h->from_where += 2; /* points to payload start. */
 +			h->ts_remain -= 2;
 +		}
 +		break;
 +	}
 +
 +	/*
 +	 * Allocate the skb (decoder target buffer) with the correct size,
 +	 * as follows:
 +	 *
 +	 * prepare for the largest case: bridged SNDU with MAC address
 +	 * (dbit = 0).
 +	 */
 +	h->priv->ule_skb = dev_alloc_skb(h->priv->ule_sndu_len +
 +					 ETH_HLEN + ETH_ALEN);
 +	if (!h->priv->ule_skb) {
 +		pr_notice("%s: Memory squeeze, dropping packet.\n",
 +			  h->dev->name);
 +		h->dev->stats.rx_dropped++;
 +		return -1;
 +	}
 +
 +	/* This includes the CRC32 _and_ dest mac, if !dbit. */
 +	h->priv->ule_sndu_remain = h->priv->ule_sndu_len;
 +	h->priv->ule_skb->dev = h->dev;
 +	/*
 +	 * Leave space for Ethernet or bridged SNDU header
 +	 * (eth hdr plus one MAC addr).
 +	 */
 +	skb_reserve(h->priv->ule_skb, ETH_HLEN + ETH_ALEN);
 +
 +	return 0;
 +}
 +
  
 -			priv->ule_sndu_remain = priv->ule_sndu_len + 2;
 +static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h)
 +{
 +	static const u8 bc_addr[ETH_ALEN] = { [0 ... ETH_ALEN - 1] = 0xff };
 +
 +	/*
 +	 * The destination MAC address is the next data in the skb.  It comes
 +	 * before any extension headers.
 +	 *
 +	 * Check if the payload of this SNDU should be passed up the stack.
 +	 */
 +	if (h->priv->rx_mode == RX_MODE_PROMISC)
 +		return 0;
 +
 +	if (h->priv->ule_skb->data[0] & 0x01) {
 +		/* multicast or broadcast */
 +		if (!ether_addr_equal(h->priv->ule_skb->data, bc_addr)) {
 +			/* multicast */
 +			if (h->priv->rx_mode == RX_MODE_MULTI) {
 +				int i;
 +
 +				for (i = 0; i < h->priv->multi_num &&
 +				     !ether_addr_equal(h->priv->ule_skb->data,
 +						       h->priv->multi_macs[i]);
 +				     i++)
 +					;
 +				if (i == h->priv->multi_num)
 +					return 1;
 +			} else if (h->priv->rx_mode != RX_MODE_ALL_MULTI)
 +				return 1; /* no broadcast; */
  			/*
 -			 * State of current TS:
 -			 *   ts_remain (remaining bytes in the current TS cell)
 -			 *   0	ule_type is not available now, we need the next TS cell
 -			 *   1	the first byte of the ule_type is present
 -			 * >=2	full ULE header present, maybe some payload data as well.
 +			 * else:
 +			 * all multicast mode: accept all multicast packets
  			 */
 -			switch (ts_remain) {
 -				case 1:
 -					priv->ule_sndu_remain--;
 -					priv->ule_sndu_type = from_where[0] << 8;
 -					priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
 -					ts_remain -= 1; from_where += 1;
 -					/* Continue w/ next TS. */
 -				case 0:
 -					new_ts = 1;
 -					ts += TS_SZ;
 -					priv->ts_count++;
 -					continue;
 -
 -				default: /* complete ULE header is present in current TS. */
 -					/* Extract ULE type field. */
 -					if (priv->ule_sndu_type_1) {
 -						priv->ule_sndu_type_1 = 0;
 -						priv->ule_sndu_type |= from_where[0];
 -						from_where += 1; /* points to payload start. */
 -						ts_remain -= 1;
 -					} else {
 -						/* Complete type is present in new TS. */
 -						priv->ule_sndu_type = from_where[0] << 8 | from_where[1];
 -						from_where += 2; /* points to payload start. */
 -						ts_remain -= 2;
 -					}
 -					break;
 -			}
 +		}
 +		/* else: broadcast */
 +	} else if (!ether_addr_equal(h->priv->ule_skb->data, h->dev->dev_addr))
 +		return 1;
  
 -			/* Allocate the skb (decoder target buffer) with the correct size, as follows:
 -			 * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */
 -			priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN );
 -			if (priv->ule_skb == NULL) {
 -				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
 -				       dev->name);
 -				dev->stats.rx_dropped++;
 -				return;
 -			}
 +	return 0;
 +}
 +
 +
 +static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
 +				  u32 ule_crc, u32 expected_crc)
 +{
 +	u8 dest_addr[ETH_ALEN];
 +
 +	if (ule_crc != expected_crc) {
 +		pr_warn("%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
 +			h->priv->ts_count, ule_crc, expected_crc,
 +			h->priv->ule_sndu_len, h->priv->ule_sndu_type,
 +			h->ts_remain,
 +			h->ts_remain > 2 ?
 +				*(unsigned short *)h->from_where : 0);
 +
 +	#ifdef ULE_DEBUG
 +		hexdump(iov[0].iov_base, iov[0].iov_len);
 +		hexdump(iov[1].iov_base, iov[1].iov_len);
 +		hexdump(iov[2].iov_base, iov[2].iov_len);
 +
 +		if (h->ule_where == h->ule_hist) {
 +			hexdump(&h->ule_hist[98*TS_SZ], TS_SZ);
 +			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
 +		} else if (h->ule_where == &h->ule_hist[TS_SZ]) {
 +			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
 +			hexdump(h->ule_hist, TS_SZ);
 +		} else {
 +			hexdump(h->ule_where - TS_SZ - TS_SZ, TS_SZ);
 +			hexdump(h->ule_where - TS_SZ, TS_SZ);
 +		}
 +		h->ule_dump = 1;
 +	#endif
 +
 +		h->dev->stats.rx_errors++;
 +		h->dev->stats.rx_crc_errors++;
 +		dev_kfree_skb(h->priv->ule_skb);
 +
 +		return;
 +	}
 +
 +	/* CRC32 verified OK. */
 +
 +	/* CRC32 was OK, so remove it from skb. */
 +	h->priv->ule_skb->tail -= 4;
 +	h->priv->ule_skb->len -= 4;
 +
 +	if (!h->priv->ule_dbit) {
 +		if (dvb_net_ule_should_drop(h)) {
 +#ifdef ULE_DEBUG
 +			netdev_dbg(h->dev,
 +				   "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n",
 +				   h->priv->ule_skb->data, h->dev->dev_addr);
 +#endif
 +			dev_kfree_skb(h->priv->ule_skb);
 +			return;
 +		}
 +
 +		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
 +					  ETH_ALEN);
 +		skb_pull(h->priv->ule_skb, ETH_ALEN);
 +	}
 +
 +	/* Handle ULE Extension Headers. */
 +	if (h->priv->ule_sndu_type < ETH_P_802_3_MIN) {
 +		/* There is an extension header.  Handle it accordingly. */
 +		int l = handle_ule_extensions(h->priv);
 +
 +		if (l < 0) {
 +			/*
 +			 * Mandatory extension header unknown or TEST SNDU.
 +			 * Drop it.
 +			 */
 +
 +			// pr_warn("Dropping SNDU, extension headers.\n" );
 +			dev_kfree_skb(h->priv->ule_skb);
 +			return;
 +		}
 +		skb_pull(h->priv->ule_skb, l);
 +	}
 +
 +	/*
 +	 * Construct/assure correct ethernet header.
 +	 * Note: in bridged mode (h->priv->ule_bridged != 0)
 +	 * we already have the (original) ethernet
 +	 * header at the start of the payload (after
 +	 * optional dest. address and any extension
 +	 * headers).
 +	 */
 +	if (!h->priv->ule_bridged) {
 +		skb_push(h->priv->ule_skb, ETH_HLEN);
 +		h->ethh = (struct ethhdr *)h->priv->ule_skb->data;
 +		if (!h->priv->ule_dbit) {
 +			/*
 +			 * dest_addr buffer is only valid if
 +			 * h->priv->ule_dbit == 0
 +			 */
 +			memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN);
 +			eth_zero_addr(h->ethh->h_source);
 +		} else /* zeroize source and dest */
 +			memset(h->ethh, 0, ETH_ALEN * 2);
  
 -			/* This includes the CRC32 _and_ dest mac, if !dbit. */
 -			priv->ule_sndu_remain = priv->ule_sndu_len;
 -			priv->ule_skb->dev = dev;
 -			/* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */
 -			skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN );
 +		h->ethh->h_proto = htons(h->priv->ule_sndu_type);
 +	}
 +	/* else:  skb is in correct state; nothing to do. */
 +	h->priv->ule_bridged = 0;
 +
 +	/* Stuff into kernel's protocol stack. */
 +	h->priv->ule_skb->protocol = dvb_net_eth_type_trans(h->priv->ule_skb,
 +							   h->dev);
 +	/*
 +	 * If D-bit is set (i.e. destination MAC address not present),
 +	 * receive the packet anyhow.
 +	 */
 +#if 0
 +	if (h->priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
 +		h->priv->ule_skb->pkt_type = PACKET_HOST;
 +#endif
 +	h->dev->stats.rx_packets++;
 +	h->dev->stats.rx_bytes += h->priv->ule_skb->len;
 +	netif_rx(h->priv->ule_skb);
 +}
 +
 +static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
 +{
 +	int ret;
 +	struct dvb_net_ule_handle h = {
 +		.dev = dev,
 +		.buf = buf,
 +		.buf_len = buf_len,
 +		.skipped = 0L,
 +		.ts = NULL,
 +		.ts_end = NULL,
 +		.from_where = NULL,
 +		.ts_remain = 0,
 +		.how_much = 0,
 +		.new_ts = 1,
 +		.ethh = NULL,
 +		.error = false,
 +#ifdef ULE_DEBUG
 +		.ule_where = ule_hist,
 +#endif
 +	};
 +
 +	/*
 +	 * For all TS cells in current buffer.
 +	 * Appearently, we are called for every single TS cell.
 +	 */
 +	for (h.ts = h.buf, h.ts_end = h.buf + h.buf_len;
 +	     h.ts < h.ts_end; /* no incr. */) {
 +		if (h.new_ts) {
 +			/* We are about to process a new TS cell. */
 +			if (dvb_net_ule_new_ts_cell(&h))
 +				continue;
 +		}
 +
 +		/* Synchronize on PUSI, if required. */
 +		if (h.priv->need_pusi) {
 +			if (dvb_net_ule_ts_pusi(&h))
 +				continue;
 +		}
 +
 +		if (h.new_ts) {
 +			if (dvb_net_ule_new_ts(&h))
 +				continue;
 +		}
 +
 +		/* Check if new payload needs to be started. */
 +		if (h.priv->ule_skb == NULL) {
 +			ret = dvb_net_ule_new_payload(&h);
 +			if (ret < 0)
 +				return;
 +			if (ret)
 +				continue;
  		}
  
  		/* Copy data into our current skb. */
 -		how_much = min(priv->ule_sndu_remain, (int)ts_remain);
 -		memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much);
 -		priv->ule_sndu_remain -= how_much;
 -		ts_remain -= how_much;
 -		from_where += how_much;
 +		h.how_much = min(h.priv->ule_sndu_remain, (int)h.ts_remain);
 +		memcpy(skb_put(h.priv->ule_skb, h.how_much),
 +		       h.from_where, h.how_much);
 +		h.priv->ule_sndu_remain -= h.how_much;
 +		h.ts_remain -= h.how_much;
 +		h.from_where += h.how_much;
  
  		/* Check for complete payload. */
 -		if (priv->ule_sndu_remain <= 0) {
 +		if (h.priv->ule_sndu_remain <= 0) {
  			/* Check CRC32, we've got it in our skb already. */
 -			__be16 ulen = htons(priv->ule_sndu_len);
 -			__be16 utype = htons(priv->ule_sndu_type);
 +			__be16 ulen = htons(h.priv->ule_sndu_len);
 +			__be16 utype = htons(h.priv->ule_sndu_type);
  			const u8 *tail;
  			struct kvec iov[3] = {
  				{ &ulen, sizeof ulen },
  				{ &utype, sizeof utype },
 -				{ priv->ule_skb->data, priv->ule_skb->len - 4 }
 +				{ h.priv->ule_skb->data,
 +				  h.priv->ule_skb->len - 4 }
  			};
  			u32 ule_crc = ~0L, expected_crc;
 -			if (priv->ule_dbit) {
 +			if (h.priv->ule_dbit) {
  				/* Set D-bit for CRC32 verification,
  				 * if it was set originally. */
  				ulen |= htons(0x8000);
  			}
  
  			ule_crc = iov_crc32(ule_crc, iov, 3);
 -			tail = skb_tail_pointer(priv->ule_skb);
 +			tail = skb_tail_pointer(h.priv->ule_skb);
  			expected_crc = *(tail - 4) << 24 |
  				       *(tail - 3) << 16 |
  				       *(tail - 2) << 8 |
  				       *(tail - 1);
 -			if (ule_crc != expected_crc) {
 -				printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
 -				       priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0);
  
 -#ifdef ULE_DEBUG
 -				hexdump( iov[0].iov_base, iov[0].iov_len );
 -				hexdump( iov[1].iov_base, iov[1].iov_len );
 -				hexdump( iov[2].iov_base, iov[2].iov_len );
 -
 -				if (ule_where == ule_hist) {
 -					hexdump( &ule_hist[98*TS_SZ], TS_SZ );
 -					hexdump( &ule_hist[99*TS_SZ], TS_SZ );
 -				} else if (ule_where == &ule_hist[TS_SZ]) {
 -					hexdump( &ule_hist[99*TS_SZ], TS_SZ );
 -					hexdump( ule_hist, TS_SZ );
 -				} else {
 -					hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ );
 -					hexdump( ule_where - TS_SZ, TS_SZ );
 -				}
 -				ule_dump = 1;
 -#endif
 +			dvb_net_ule_check_crc(&h, ule_crc, expected_crc);
  
 -				dev->stats.rx_errors++;
 -				dev->stats.rx_crc_errors++;
 -				dev_kfree_skb(priv->ule_skb);
 -			} else {
 -				/* CRC32 verified OK. */
 -				u8 dest_addr[ETH_ALEN];
 -				static const u8 bc_addr[ETH_ALEN] =
 -					{ [ 0 ... ETH_ALEN-1] = 0xff };
 -
 -				/* CRC32 was OK. Remove it from skb. */
 -				priv->ule_skb->tail -= 4;
 -				priv->ule_skb->len -= 4;
 -
 -				if (!priv->ule_dbit) {
 -					/*
 -					 * The destination MAC address is the
 -					 * next data in the skb.  It comes
 -					 * before any extension headers.
 -					 *
 -					 * Check if the payload of this SNDU
 -					 * should be passed up the stack.
 -					 */
 -					register int drop = 0;
 -					if (priv->rx_mode != RX_MODE_PROMISC) {
 -						if (priv->ule_skb->data[0] & 0x01) {
 -							/* multicast or broadcast */
 -							if (!ether_addr_equal(priv->ule_skb->data, bc_addr)) {
 -								/* multicast */
 -								if (priv->rx_mode == RX_MODE_MULTI) {
 -									int i;
 -									for(i = 0; i < priv->multi_num &&
 -									    !ether_addr_equal(priv->ule_skb->data,
 -											      priv->multi_macs[i]); i++)
 -										;
 -									if (i == priv->multi_num)
 -										drop = 1;
 -								} else if (priv->rx_mode != RX_MODE_ALL_MULTI)
 -									drop = 1; /* no broadcast; */
 -								/* else: all multicast mode: accept all multicast packets */
 -							}
 -							/* else: broadcast */
 -						}
 -						else if (!ether_addr_equal(priv->ule_skb->data, dev->dev_addr))
 -							drop = 1;
 -						/* else: destination address matches the MAC address of our receiver device */
 -					}
 -					/* else: promiscuous mode; pass everything up the stack */
 -
 -					if (drop) {
 -#ifdef ULE_DEBUG
 -						netdev_dbg(dev, "Dropping SNDU: MAC destination address does not match: dest addr: %pM, dev addr: %pM\n",
 -							   priv->ule_skb->data, dev->dev_addr);
 -#endif
 -						dev_kfree_skb(priv->ule_skb);
 -						goto sndu_done;
 -					}
 -					else
 -					{
 -						skb_copy_from_linear_data(priv->ule_skb,
 -							      dest_addr,
 -							      ETH_ALEN);
 -						skb_pull(priv->ule_skb, ETH_ALEN);
 -					}
 -				}
 -
 -				/* Handle ULE Extension Headers. */
 -				if (priv->ule_sndu_type < ETH_P_802_3_MIN) {
 -					/* There is an extension header.  Handle it accordingly. */
 -					int l = handle_ule_extensions(priv);
 -					if (l < 0) {
 -						/* Mandatory extension header unknown or TEST SNDU.  Drop it. */
 -						// printk( KERN_WARNING "Dropping SNDU, extension headers.\n" );
 -						dev_kfree_skb(priv->ule_skb);
 -						goto sndu_done;
 -					}
 -					skb_pull(priv->ule_skb, l);
 -				}
 -
 -				/*
 -				 * Construct/assure correct ethernet header.
 -				 * Note: in bridged mode (priv->ule_bridged !=
 -				 * 0) we already have the (original) ethernet
 -				 * header at the start of the payload (after
 -				 * optional dest. address and any extension
 -				 * headers).
 -				 */
 -
 -				if (!priv->ule_bridged) {
 -					skb_push(priv->ule_skb, ETH_HLEN);
 -					ethh = (struct ethhdr *)priv->ule_skb->data;
 -					if (!priv->ule_dbit) {
 -						 /* dest_addr buffer is only valid if priv->ule_dbit == 0 */
 -						memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
 -						eth_zero_addr(ethh->h_source);
 -					}
 -					else /* zeroize source and dest */
 -						memset( ethh, 0, ETH_ALEN*2 );
 -
 -					ethh->h_proto = htons(priv->ule_sndu_type);
 -				}
 -				/* else:  skb is in correct state; nothing to do. */
 -				priv->ule_bridged = 0;
 -
 -				/* Stuff into kernel's protocol stack. */
 -				priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev);
 -				/* If D-bit is set (i.e. destination MAC address not present),
 -				 * receive the packet anyhow. */
 -				/* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST)
 -					priv->ule_skb->pkt_type = PACKET_HOST; */
 -				dev->stats.rx_packets++;
 -				dev->stats.rx_bytes += priv->ule_skb->len;
 -				netif_rx(priv->ule_skb);
 -			}
 -			sndu_done:
  			/* Prepare for next SNDU. */
 -			reset_ule(priv);
 +			reset_ule(h.priv);
  		}
  
  		/* More data in current TS (look at the bytes following the CRC32)? */
 -		if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) {
 +		if (h.ts_remain >= 2 && *((unsigned short *)h.from_where) != 0xFFFF) {
  			/* Next ULE SNDU starts right there. */
 -			new_ts = 0;
 -			priv->ule_skb = NULL;
 -			priv->ule_sndu_type_1 = 0;
 -			priv->ule_sndu_len = 0;
 -			// printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n",
 -			//	*(from_where + 0), *(from_where + 1),
 -			//	*(from_where + 2), *(from_where + 3));
 -			// printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0);
 -			// hexdump(ts, 188);
 +			h.new_ts = 0;
 +			h.priv->ule_skb = NULL;
 +			h.priv->ule_sndu_type_1 = 0;
 +			h.priv->ule_sndu_len = 0;
 +			// pr_warn("More data in current TS: [%#x %#x %#x %#x]\n",
 +			//	*(h.from_where + 0), *(h.from_where + 1),
 +			//	*(h.from_where + 2), *(h.from_where + 3));
 +			// pr_warn("h.ts @ %p, stopped @ %p:\n", h.ts, h.from_where + 0);
 +			// hexdump(h.ts, 188);
  		} else {
 -			new_ts = 1;
 -			ts += TS_SZ;
 -			priv->ts_count++;
 -			if (priv->ule_skb == NULL) {
 -				priv->need_pusi = 1;
 -				priv->ule_sndu_type_1 = 0;
 -				priv->ule_sndu_len = 0;
 +			h.new_ts = 1;
 +			h.ts += TS_SZ;
 +			h.priv->ts_count++;
 +			if (h.priv->ule_skb == NULL) {
 +				h.priv->need_pusi = 1;
 +				h.priv->ule_sndu_type_1 = 0;
 +				h.priv->ule_sndu_len = 0;
  			}
  		}
  	}	/* for all available TS cells */
@@@ -906,10 -766,10 +906,10 @@@ static int dvb_net_ts_callback(const u
  	struct net_device *dev = feed->priv;
  
  	if (buffer2)
 -		printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2);
 +		pr_warn("buffer2 not NULL: %p.\n", buffer2);
  	if (buffer1_len > 32768)
 -		printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
 -	/* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
 +		pr_warn("length > 32k: %zu.\n", buffer1_len);
 +	/* pr_info("TS callback: %u bytes, %u TS cells @ %p.\n",
  		  buffer1_len, buffer1_len / TS_SZ, buffer1); */
  	dvb_net_ule(dev, buffer1, buffer1_len);
  	return 0;
@@@ -926,7 -786,7 +926,7 @@@ static void dvb_net_sec(struct net_devi
  
  	/* note: pkt_len includes a 32bit checksum */
  	if (pkt_len < 16) {
 -		printk("%s: IP/MPE packet length = %d too small.\n",
 +		pr_warn("%s: IP/MPE packet length = %d too small.\n",
  			dev->name, pkt_len);
  		stats->rx_errors++;
  		stats->rx_length_errors++;
@@@ -964,7 -824,7 +964,7 @@@
  	 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP
  	 */
  	if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) {
 -		//printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 +		//pr_notice("%s: Memory squeeze, dropping packet.\n", dev->name);
  		stats->rx_dropped++;
  		return;
  	}
@@@ -1043,7 -903,7 +1043,7 @@@ static int dvb_net_filter_sec_set(struc
  	*secfilter=NULL;
  	ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter);
  	if (ret<0) {
 -		printk("%s: could not get filter\n", dev->name);
 +		pr_err("%s: could not get filter\n", dev->name);
  		return ret;
  	}
  
@@@ -1084,7 -944,7 +1084,7 @@@ static int dvb_net_feed_start(struct ne
  	netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
  	mutex_lock(&priv->mutex);
  	if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
 -		printk("%s: BUG %d\n", __func__, __LINE__);
 +		pr_err("%s: BUG %d\n", __func__, __LINE__);
  
  	priv->secfeed=NULL;
  	priv->secfilter=NULL;
@@@ -1095,15 -955,14 +1095,15 @@@
  		ret=demux->allocate_section_feed(demux, &priv->secfeed,
  					 dvb_net_sec_callback);
  		if (ret<0) {
 -			printk("%s: could not allocate section feed\n", dev->name);
 +			pr_err("%s: could not allocate section feed\n",
 +			       dev->name);
  			goto error;
  		}
  
 -		ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
 +		ret = priv->secfeed->set(priv->secfeed, priv->pid, 1);
  
  		if (ret<0) {
 -			printk("%s: could not set section feed\n", dev->name);
 +			pr_err("%s: could not set section feed\n", dev->name);
  			priv->demux->release_section_feed(priv->demux, priv->secfeed);
  			priv->secfeed=NULL;
  			goto error;
@@@ -1144,7 -1003,7 +1144,7 @@@
  		netdev_dbg(dev, "alloc tsfeed\n");
  		ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
  		if (ret < 0) {
 -			printk("%s: could not allocate ts feed\n", dev->name);
 +			pr_err("%s: could not allocate ts feed\n", dev->name);
  			goto error;
  		}
  
@@@ -1154,11 -1013,12 +1154,11 @@@
  					priv->pid, /* pid */
  					TS_PACKET, /* type */
  					DMX_PES_OTHER, /* pes type */
 -					32768,     /* circular buffer size */
  					timeout    /* timeout */
  					);
  
  		if (ret < 0) {
 -			printk("%s: could not set ts feed\n", dev->name);
 +			pr_err("%s: could not set ts feed\n", dev->name);
  			priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
  			priv->tsfeed = NULL;
  			goto error;
@@@ -1207,7 -1067,7 +1207,7 @@@ static int dvb_net_feed_stop(struct net
  			priv->demux->release_section_feed(priv->demux, priv->secfeed);
  			priv->secfeed = NULL;
  		} else
 -			printk("%s: no feed to stop\n", dev->name);
 +			pr_err("%s: no feed to stop\n", dev->name);
  	} else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) {
  		if (priv->tsfeed) {
  			if (priv->tsfeed->is_filtering) {
@@@ -1218,7 -1078,7 +1218,7 @@@
  			priv->tsfeed = NULL;
  		}
  		else
 -			printk("%s: no ts feed to stop\n", dev->name);
 +			pr_err("%s: no ts feed to stop\n", dev->name);
  	} else
  		ret = -EINVAL;
  	mutex_unlock(&priv->mutex);
@@@ -1338,7 -1198,6 +1338,6 @@@ static const struct net_device_ops dvb_
  	.ndo_start_xmit		= dvb_net_tx,
  	.ndo_set_rx_mode	= dvb_net_set_multicast_list,
  	.ndo_set_mac_address    = dvb_net_set_mac,
- 	.ndo_change_mtu		= eth_change_mtu,
  	.ndo_validate_addr	= eth_validate_addr,
  };
  
@@@ -1349,6 -1208,7 +1348,7 @@@ static void dvb_net_setup(struct net_de
  	dev->header_ops		= &dvb_header_ops;
  	dev->netdev_ops		= &dvb_netdev_ops;
  	dev->mtu		= 4096;
+ 	dev->max_mtu		= 4096;
  
  	dev->flags |= IFF_NOARP;
  }
@@@ -1419,7 -1279,7 +1419,7 @@@ static int dvb_net_add_if(struct dvb_ne
  		free_netdev(net);
  		return result;
  	}
 -	printk("dvb_net: created network interface %s\n", net->name);
 +	pr_info("created network interface %s\n", net->name);
  
  	return if_num;
  }
@@@ -1438,7 -1298,7 +1438,7 @@@ static int dvb_net_remove_if(struct dvb
  	dvb_net_stop(net);
  	flush_work(&priv->set_multicast_list_wq);
  	flush_work(&priv->restart_net_feed_wq);
 -	printk("dvb_net: removed network interface %s\n", net->name);
 +	pr_info("removed network interface %s\n", net->name);
  	unregister_netdev(net);
  	dvbnet->state[num]=0;
  	dvbnet->device[num] = NULL;
diff --combined drivers/net/ethernet/smsc/smsc911x.c
index 65fca9c,be09573..9179cb4
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@@ -1956,11 -1956,6 +1956,6 @@@ static void smsc911x_ethtool_getdrvinfo
  		sizeof(info->bus_info));
  }
  
- static int smsc911x_ethtool_nwayreset(struct net_device *dev)
- {
- 	return phy_start_aneg(dev->phydev);
- }
- 
  static u32 smsc911x_ethtool_getmsglevel(struct net_device *dev)
  {
  	struct smsc911x_data *pdata = netdev_priv(dev);
@@@ -2132,7 -2127,7 +2127,7 @@@ static int smsc911x_ethtool_set_eeprom(
  static const struct ethtool_ops smsc911x_ethtool_ops = {
  	.get_link = ethtool_op_get_link,
  	.get_drvinfo = smsc911x_ethtool_getdrvinfo,
- 	.nway_reset = smsc911x_ethtool_nwayreset,
+ 	.nway_reset = phy_ethtool_nway_reset,
  	.get_msglevel = smsc911x_ethtool_getmsglevel,
  	.set_msglevel = smsc911x_ethtool_setmsglevel,
  	.get_regs_len = smsc911x_ethtool_getregslen,
@@@ -2152,7 -2147,6 +2147,6 @@@ static const struct net_device_ops smsc
  	.ndo_get_stats		= smsc911x_get_stats,
  	.ndo_set_rx_mode	= smsc911x_set_multicast_list,
  	.ndo_do_ioctl		= smsc911x_do_ioctl,
- 	.ndo_change_mtu		= eth_change_mtu,
  	.ndo_validate_addr	= eth_validate_addr,
  	.ndo_set_mac_address 	= smsc911x_set_mac_address,
  #ifdef CONFIG_NET_POLL_CONTROLLER
@@@ -2584,9 -2578,6 +2578,9 @@@ static int smsc911x_suspend(struct devi
  		PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
  		PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
  
 +	pm_runtime_disable(dev);
 +	pm_runtime_set_suspended(dev);
 +
  	return 0;
  }
  
@@@ -2596,9 -2587,6 +2590,9 @@@ static int smsc911x_resume(struct devic
  	struct smsc911x_data *pdata = netdev_priv(ndev);
  	unsigned int to = 100;
  
 +	pm_runtime_enable(dev);
 +	pm_runtime_resume(dev);
 +
  	/* Note 3.11 from the datasheet:
  	 * 	"When the LAN9220 is in a power saving state, a write of any
  	 * 	 data to the BYTE_TEST register will wake-up the device."
diff --combined drivers/thermal/thermal_core.c
index 7daffc1,911fd96..641faab
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@@ -5,9 -5,22 +5,9 @@@
   *  Copyright (C) 2008 Zhang Rui <rui.zhang at intel.com>
   *  Copyright (C) 2008 Sujith Thomas <sujith.thomas at intel.com>
   *
 - *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 - *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; version 2 of the License.
 - *
 - *  This program is distributed in the hope that it will be useful, but
 - *  WITHOUT ANY WARRANTY; without even the implied warranty of
 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - *  General Public License for more details.
 - *
 - *  You should have received a copy of the GNU General Public License along
 - *  with this program; if not, write to the Free Software Foundation, Inc.,
 - *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 - *
 - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   */
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@@ -51,13 -64,6 +51,13 @@@ static atomic_t in_suspend
  
  static struct thermal_governor *def_governor;
  
 +/*
 + * Governor section: set of functions to handle thermal governors
 + *
 + * Functions to help in the life cycle of thermal governors within
 + * the thermal core and by the thermal governor code.
 + */
 +
  static struct thermal_governor *__find_governor(const char *name)
  {
  	struct thermal_governor *pos;
@@@ -136,16 -142,11 +136,16 @@@ int thermal_register_governor(struct th
  	mutex_lock(&thermal_governor_lock);
  
  	err = -EBUSY;
 -	if (__find_governor(governor->name) == NULL) {
 +	if (!__find_governor(governor->name)) {
 +		bool match_default;
 +
  		err = 0;
  		list_add(&governor->governor_list, &thermal_governor_list);
 -		if (!def_governor && !strncmp(governor->name,
 -			DEFAULT_THERMAL_GOVERNOR, THERMAL_NAME_LENGTH))
 +		match_default = !strncmp(governor->name,
 +					 DEFAULT_THERMAL_GOVERNOR,
 +					 THERMAL_NAME_LENGTH);
 +
 +		if (!def_governor && match_default)
  			def_governor = governor;
  	}
  
@@@ -187,14 -188,14 +187,14 @@@ void thermal_unregister_governor(struc
  
  	mutex_lock(&thermal_governor_lock);
  
 -	if (__find_governor(governor->name) == NULL)
 +	if (!__find_governor(governor->name))
  		goto exit;
  
  	mutex_lock(&thermal_list_lock);
  
  	list_for_each_entry(pos, &thermal_tz_list, node) {
  		if (!strncasecmp(pos->governor->name, governor->name,
 -						THERMAL_NAME_LENGTH))
 +				 THERMAL_NAME_LENGTH))
  			thermal_set_governor(pos, NULL);
  	}
  
@@@ -202,92 -203,195 +202,92 @@@
  	list_del(&governor->governor_list);
  exit:
  	mutex_unlock(&thermal_governor_lock);
 -	return;
 -}
 -
 -static int get_idr(struct idr *idr, struct mutex *lock, int *id)
 -{
 -	int ret;
 -
 -	if (lock)
 -		mutex_lock(lock);
 -	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
 -	if (lock)
 -		mutex_unlock(lock);
 -	if (unlikely(ret < 0))
 -		return ret;
 -	*id = ret;
 -	return 0;
 -}
 -
 -static void release_idr(struct idr *idr, struct mutex *lock, int id)
 -{
 -	if (lock)
 -		mutex_lock(lock);
 -	idr_remove(idr, id);
 -	if (lock)
 -		mutex_unlock(lock);
 -}
 -
 -int get_tz_trend(struct thermal_zone_device *tz, int trip)
 -{
 -	enum thermal_trend trend;
 -
 -	if (tz->emul_temperature || !tz->ops->get_trend ||
 -	    tz->ops->get_trend(tz, trip, &trend)) {
 -		if (tz->temperature > tz->last_temperature)
 -			trend = THERMAL_TREND_RAISING;
 -		else if (tz->temperature < tz->last_temperature)
 -			trend = THERMAL_TREND_DROPPING;
 -		else
 -			trend = THERMAL_TREND_STABLE;
 -	}
 -
 -	return trend;
  }
 -EXPORT_SYMBOL(get_tz_trend);
  
 -struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz,
 -			struct thermal_cooling_device *cdev, int trip)
 +int thermal_zone_device_set_policy(struct thermal_zone_device *tz,
 +				   char *policy)
  {
 -	struct thermal_instance *pos = NULL;
 -	struct thermal_instance *target_instance = NULL;
 +	struct thermal_governor *gov;
 +	int ret = -EINVAL;
  
 +	mutex_lock(&thermal_governor_lock);
  	mutex_lock(&tz->lock);
 -	mutex_lock(&cdev->lock);
  
 -	list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
 -		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 -			target_instance = pos;
 -			break;
 -		}
 -	}
 +	gov = __find_governor(strim(policy));
 +	if (!gov)
 +		goto exit;
  
 -	mutex_unlock(&cdev->lock);
 -	mutex_unlock(&tz->lock);
 +	ret = thermal_set_governor(tz, gov);
  
 -	return target_instance;
 -}
 -EXPORT_SYMBOL(get_thermal_instance);
 +exit:
 +	mutex_unlock(&tz->lock);
 +	mutex_unlock(&thermal_governor_lock);
  
 -static void print_bind_err_msg(struct thermal_zone_device *tz,
 -			struct thermal_cooling_device *cdev, int ret)
 -{
 -	dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n",
 -				tz->type, cdev->type, ret);
 +	return ret;
  }
  
 -static void __bind(struct thermal_zone_device *tz, int mask,
 -			struct thermal_cooling_device *cdev,
 -			unsigned long *limits,
 -			unsigned int weight)
 +int thermal_build_list_of_policies(char *buf)
  {
 -	int i, ret;
 +	struct thermal_governor *pos;
 +	ssize_t count = 0;
 +	ssize_t size = PAGE_SIZE;
  
 -	for (i = 0; i < tz->trips; i++) {
 -		if (mask & (1 << i)) {
 -			unsigned long upper, lower;
 +	mutex_lock(&thermal_governor_lock);
  
 -			upper = THERMAL_NO_LIMIT;
 -			lower = THERMAL_NO_LIMIT;
 -			if (limits) {
 -				lower = limits[i * 2];
 -				upper = limits[i * 2 + 1];
 -			}
 -			ret = thermal_zone_bind_cooling_device(tz, i, cdev,
 -							       upper, lower,
 -							       weight);
 -			if (ret)
 -				print_bind_err_msg(tz, cdev, ret);
 -		}
 +	list_for_each_entry(pos, &thermal_governor_list, governor_list) {
 +		size = PAGE_SIZE - count;
 +		count += scnprintf(buf + count, size, "%s ", pos->name);
  	}
 -}
 +	count += scnprintf(buf + count, size, "\n");
  
 -static void __unbind(struct thermal_zone_device *tz, int mask,
 -			struct thermal_cooling_device *cdev)
 -{
 -	int i;
 +	mutex_unlock(&thermal_governor_lock);
  
 -	for (i = 0; i < tz->trips; i++)
 -		if (mask & (1 << i))
 -			thermal_zone_unbind_cooling_device(tz, i, cdev);
 +	return count;
  }
  
 -static void bind_cdev(struct thermal_cooling_device *cdev)
 +static int __init thermal_register_governors(void)
  {
 -	int i, ret;
 -	const struct thermal_zone_params *tzp;
 -	struct thermal_zone_device *pos = NULL;
 -
 -	mutex_lock(&thermal_list_lock);
 +	int result;
  
 -	list_for_each_entry(pos, &thermal_tz_list, node) {
 -		if (!pos->tzp && !pos->ops->bind)
 -			continue;
 +	result = thermal_gov_step_wise_register();
 +	if (result)
 +		return result;
  
 -		if (pos->ops->bind) {
 -			ret = pos->ops->bind(pos, cdev);
 -			if (ret)
 -				print_bind_err_msg(pos, cdev, ret);
 -			continue;
 -		}
 +	result = thermal_gov_fair_share_register();
 +	if (result)
 +		return result;
  
 -		tzp = pos->tzp;
 -		if (!tzp || !tzp->tbp)
 -			continue;
 +	result = thermal_gov_bang_bang_register();
 +	if (result)
 +		return result;
  
 -		for (i = 0; i < tzp->num_tbps; i++) {
 -			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
 -				continue;
 -			if (tzp->tbp[i].match(pos, cdev))
 -				continue;
 -			tzp->tbp[i].cdev = cdev;
 -			__bind(pos, tzp->tbp[i].trip_mask, cdev,
 -			       tzp->tbp[i].binding_limits,
 -			       tzp->tbp[i].weight);
 -		}
 -	}
 +	result = thermal_gov_user_space_register();
 +	if (result)
 +		return result;
  
 -	mutex_unlock(&thermal_list_lock);
 +	return thermal_gov_power_allocator_register();
  }
  
 -static void bind_tz(struct thermal_zone_device *tz)
 +static void thermal_unregister_governors(void)
  {
 -	int i, ret;
 -	struct thermal_cooling_device *pos = NULL;
 -	const struct thermal_zone_params *tzp = tz->tzp;
 -
 -	if (!tzp && !tz->ops->bind)
 -		return;
 -
 -	mutex_lock(&thermal_list_lock);
 -
 -	/* If there is ops->bind, try to use ops->bind */
 -	if (tz->ops->bind) {
 -		list_for_each_entry(pos, &thermal_cdev_list, node) {
 -			ret = tz->ops->bind(tz, pos);
 -			if (ret)
 -				print_bind_err_msg(tz, pos, ret);
 -		}
 -		goto exit;
 -	}
 -
 -	if (!tzp || !tzp->tbp)
 -		goto exit;
 -
 -	list_for_each_entry(pos, &thermal_cdev_list, node) {
 -		for (i = 0; i < tzp->num_tbps; i++) {
 -			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
 -				continue;
 -			if (tzp->tbp[i].match(tz, pos))
 -				continue;
 -			tzp->tbp[i].cdev = pos;
 -			__bind(tz, tzp->tbp[i].trip_mask, pos,
 -			       tzp->tbp[i].binding_limits,
 -			       tzp->tbp[i].weight);
 -		}
 -	}
 -exit:
 -	mutex_unlock(&thermal_list_lock);
 +	thermal_gov_step_wise_unregister();
 +	thermal_gov_fair_share_unregister();
 +	thermal_gov_bang_bang_unregister();
 +	thermal_gov_user_space_unregister();
 +	thermal_gov_power_allocator_unregister();
  }
  
 +/*
 + * Zone update section: main control loop applied to each zone while monitoring
 + *
 + * in polling mode. The monitoring is done using a workqueue.
 + * Same update may be done on a zone by calling thermal_zone_device_update().
 + *
 + * An update means:
 + * - Non-critical trips will invoke the governor responsible for that zone;
 + * - Hot trips will produce a notification to userspace;
 + * - Critical trip point will cause a system shutdown.
 + */
  static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
  					    int delay)
  {
@@@ -316,15 -420,14 +316,15 @@@ static void monitor_thermal_zone(struc
  }
  
  static void handle_non_critical_trips(struct thermal_zone_device *tz,
 -			int trip, enum thermal_trip_type trip_type)
 +				      int trip,
 +				      enum thermal_trip_type trip_type)
  {
  	tz->governor ? tz->governor->throttle(tz, trip) :
  		       def_governor->throttle(tz, trip);
  }
  
  static void handle_critical_trips(struct thermal_zone_device *tz,
 -				int trip, enum thermal_trip_type trip_type)
 +				  int trip, enum thermal_trip_type trip_type)
  {
  	int trip_temp;
  
@@@ -368,6 -471,105 +368,6 @@@ static void handle_thermal_trip(struct 
  	monitor_thermal_zone(tz);
  }
  
 -/**
 - * thermal_zone_get_temp() - returns the temperature of a thermal zone
 - * @tz: a valid pointer to a struct thermal_zone_device
 - * @temp: a valid pointer to where to store the resulting temperature.
 - *
 - * When a valid thermal zone reference is passed, it will fetch its
 - * temperature and fill @temp.
 - *
 - * Return: On success returns 0, an error code otherwise
 - */
 -int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
 -{
 -	int ret = -EINVAL;
 -	int count;
 -	int crit_temp = INT_MAX;
 -	enum thermal_trip_type type;
 -
 -	if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
 -		goto exit;
 -
 -	mutex_lock(&tz->lock);
 -
 -	ret = tz->ops->get_temp(tz, temp);
 -
 -	if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
 -		for (count = 0; count < tz->trips; count++) {
 -			ret = tz->ops->get_trip_type(tz, count, &type);
 -			if (!ret && type == THERMAL_TRIP_CRITICAL) {
 -				ret = tz->ops->get_trip_temp(tz, count,
 -						&crit_temp);
 -				break;
 -			}
 -		}
 -
 -		/*
 -		 * Only allow emulating a temperature when the real temperature
 -		 * is below the critical temperature so that the emulation code
 -		 * cannot hide critical conditions.
 -		 */
 -		if (!ret && *temp < crit_temp)
 -			*temp = tz->emul_temperature;
 -	}
 - 
 -	mutex_unlock(&tz->lock);
 -exit:
 -	return ret;
 -}
 -EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
 -
 -void thermal_zone_set_trips(struct thermal_zone_device *tz)
 -{
 -	int low = -INT_MAX;
 -	int high = INT_MAX;
 -	int trip_temp, hysteresis;
 -	int i, ret;
 -
 -	mutex_lock(&tz->lock);
 -
 -	if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
 -		goto exit;
 -
 -	for (i = 0; i < tz->trips; i++) {
 -		int trip_low;
 -
 -		tz->ops->get_trip_temp(tz, i, &trip_temp);
 -		tz->ops->get_trip_hyst(tz, i, &hysteresis);
 -
 -		trip_low = trip_temp - hysteresis;
 -
 -		if (trip_low < tz->temperature && trip_low > low)
 -			low = trip_low;
 -
 -		if (trip_temp > tz->temperature && trip_temp < high)
 -			high = trip_temp;
 -	}
 -
 -	/* No need to change trip points */
 -	if (tz->prev_low_trip == low && tz->prev_high_trip == high)
 -		goto exit;
 -
 -	tz->prev_low_trip = low;
 -	tz->prev_high_trip = high;
 -
 -	dev_dbg(&tz->device,
 -		"new temperature boundaries: %d < x < %d\n", low, high);
 -
 -	/*
 -	 * Set a temperature window. When this window is left the driver
 -	 * must inform the thermal core via thermal_zone_device_update.
 -	 */
 -	ret = tz->ops->set_trips(tz, low, high);
 -	if (ret)
 -		dev_err(&tz->device, "Failed to set trips: %d\n", ret);
 -
 -exit:
 -	mutex_unlock(&tz->lock);
 -}
 -EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
 -
  static void update_temperature(struct thermal_zone_device *tz)
  {
  	int temp, ret;
@@@ -427,24 -629,6 +427,24 @@@ void thermal_zone_device_update(struct 
  }
  EXPORT_SYMBOL_GPL(thermal_zone_device_update);
  
 +/**
 + * thermal_notify_framework - Sensor drivers use this API to notify framework
 + * @tz:		thermal zone device
 + * @trip:	indicates which trip point has been crossed
 + *
 + * This function handles the trip events from sensor drivers. It starts
 + * throttling the cooling devices according to the policy configured.
 + * For CRITICAL and HOT trip points, this notifies the respective drivers,
 + * and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
 + * The throttling policy is based on the configured platform data; if no
 + * platform data is provided, this uses the step_wise throttling policy.
 + */
 +void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
 +{
 +	handle_thermal_trip(tz, trip);
 +}
 +EXPORT_SYMBOL_GPL(thermal_notify_framework);
 +
  static void thermal_zone_device_check(struct work_struct *work)
  {
  	struct thermal_zone_device *tz = container_of(work, struct
@@@ -453,12 -637,445 +453,12 @@@
  	thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
  }
  
 -/* sys I/F for thermal zone */
 -
 -#define to_thermal_zone(_dev) \
 -	container_of(_dev, struct thermal_zone_device, device)
 -
 -static ssize_t
 -type_show(struct device *dev, struct device_attribute *attr, char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -
 -	return sprintf(buf, "%s\n", tz->type);
 -}
 -
 -static ssize_t
 -temp_show(struct device *dev, struct device_attribute *attr, char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int temperature, ret;
 -
 -	ret = thermal_zone_get_temp(tz, &temperature);
 -
 -	if (ret)
 -		return ret;
 -
 -	return sprintf(buf, "%d\n", temperature);
 -}
 -
 -static ssize_t
 -mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	enum thermal_device_mode mode;
 -	int result;
 -
 -	if (!tz->ops->get_mode)
 -		return -EPERM;
 -
 -	result = tz->ops->get_mode(tz, &mode);
 -	if (result)
 -		return result;
 -
 -	return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
 -		       : "disabled");
 -}
 -
 -static ssize_t
 -mode_store(struct device *dev, struct device_attribute *attr,
 -	   const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int result;
 -
 -	if (!tz->ops->set_mode)
 -		return -EPERM;
 -
 -	if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
 -		result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
 -	else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
 -		result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
 -	else
 -		result = -EINVAL;
 -
 -	if (result)
 -		return result;
 -
 -	return count;
 -}
 -
 -static ssize_t
 -trip_point_type_show(struct device *dev, struct device_attribute *attr,
 -		     char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	enum thermal_trip_type type;
 -	int trip, result;
 -
 -	if (!tz->ops->get_trip_type)
 -		return -EPERM;
 -
 -	if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
 -		return -EINVAL;
 -
 -	result = tz->ops->get_trip_type(tz, trip, &type);
 -	if (result)
 -		return result;
 -
 -	switch (type) {
 -	case THERMAL_TRIP_CRITICAL:
 -		return sprintf(buf, "critical\n");
 -	case THERMAL_TRIP_HOT:
 -		return sprintf(buf, "hot\n");
 -	case THERMAL_TRIP_PASSIVE:
 -		return sprintf(buf, "passive\n");
 -	case THERMAL_TRIP_ACTIVE:
 -		return sprintf(buf, "active\n");
 -	default:
 -		return sprintf(buf, "unknown\n");
 -	}
 -}
 -
 -static ssize_t
 -trip_point_temp_store(struct device *dev, struct device_attribute *attr,
 -		     const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int trip, ret;
 -	int temperature;
 -
 -	if (!tz->ops->set_trip_temp)
 -		return -EPERM;
 -
 -	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
 -		return -EINVAL;
 -
 -	if (kstrtoint(buf, 10, &temperature))
 -		return -EINVAL;
 -
 -	ret = tz->ops->set_trip_temp(tz, trip, temperature);
 -	if (ret)
 -		return ret;
 -
 -	thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 -
 -	return count;
 -}
 -
 -static ssize_t
 -trip_point_temp_show(struct device *dev, struct device_attribute *attr,
 -		     char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int trip, ret;
 -	int temperature;
 -
 -	if (!tz->ops->get_trip_temp)
 -		return -EPERM;
 -
 -	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
 -		return -EINVAL;
 -
 -	ret = tz->ops->get_trip_temp(tz, trip, &temperature);
 -
 -	if (ret)
 -		return ret;
 -
 -	return sprintf(buf, "%d\n", temperature);
 -}
 -
 -static ssize_t
 -trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
 -			const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int trip, ret;
 -	int temperature;
 -
 -	if (!tz->ops->set_trip_hyst)
 -		return -EPERM;
 -
 -	if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
 -		return -EINVAL;
 -
 -	if (kstrtoint(buf, 10, &temperature))
 -		return -EINVAL;
 -
 -	/*
 -	 * We are not doing any check on the 'temperature' value
 -	 * here. The driver implementing 'set_trip_hyst' has to
 -	 * take care of this.
 -	 */
 -	ret = tz->ops->set_trip_hyst(tz, trip, temperature);
 -
 -	if (!ret)
 -		thermal_zone_set_trips(tz);
 -
 -	return ret ? ret : count;
 -}
 -
 -static ssize_t
 -trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
 -			char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int trip, ret;
 -	int temperature;
 -
 -	if (!tz->ops->get_trip_hyst)
 -		return -EPERM;
 -
 -	if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
 -		return -EINVAL;
 -
 -	ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
 -
 -	return ret ? ret : sprintf(buf, "%d\n", temperature);
 -}
 -
 -static ssize_t
 -passive_store(struct device *dev, struct device_attribute *attr,
 -		    const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	struct thermal_cooling_device *cdev = NULL;
 -	int state;
 -
 -	if (!sscanf(buf, "%d\n", &state))
 -		return -EINVAL;
 -
 -	/* sanity check: values below 1000 millicelcius don't make sense
 -	 * and can cause the system to go into a thermal heart attack
 -	 */
 -	if (state && state < 1000)
 -		return -EINVAL;
 -
 -	if (state && !tz->forced_passive) {
 -		mutex_lock(&thermal_list_lock);
 -		list_for_each_entry(cdev, &thermal_cdev_list, node) {
 -			if (!strncmp("Processor", cdev->type,
 -				     sizeof("Processor")))
 -				thermal_zone_bind_cooling_device(tz,
 -						THERMAL_TRIPS_NONE, cdev,
 -						THERMAL_NO_LIMIT,
 -						THERMAL_NO_LIMIT,
 -						THERMAL_WEIGHT_DEFAULT);
 -		}
 -		mutex_unlock(&thermal_list_lock);
 -		if (!tz->passive_delay)
 -			tz->passive_delay = 1000;
 -	} else if (!state && tz->forced_passive) {
 -		mutex_lock(&thermal_list_lock);
 -		list_for_each_entry(cdev, &thermal_cdev_list, node) {
 -			if (!strncmp("Processor", cdev->type,
 -				     sizeof("Processor")))
 -				thermal_zone_unbind_cooling_device(tz,
 -								   THERMAL_TRIPS_NONE,
 -								   cdev);
 -		}
 -		mutex_unlock(&thermal_list_lock);
 -		tz->passive_delay = 0;
 -	}
 -
 -	tz->forced_passive = state;
 -
 -	thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 -
 -	return count;
 -}
 -
 -static ssize_t
 -passive_show(struct device *dev, struct device_attribute *attr,
 -		   char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -
 -	return sprintf(buf, "%d\n", tz->forced_passive);
 -}
 -
 -static ssize_t
 -policy_store(struct device *dev, struct device_attribute *attr,
 -		    const char *buf, size_t count)
 -{
 -	int ret = -EINVAL;
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	struct thermal_governor *gov;
 -	char name[THERMAL_NAME_LENGTH];
 -
 -	snprintf(name, sizeof(name), "%s", buf);
 -
 -	mutex_lock(&thermal_governor_lock);
 -	mutex_lock(&tz->lock);
 -
 -	gov = __find_governor(strim(name));
 -	if (!gov)
 -		goto exit;
 -
 -	ret = thermal_set_governor(tz, gov);
 -	if (!ret)
 -		ret = count;
 -
 -exit:
 -	mutex_unlock(&tz->lock);
 -	mutex_unlock(&thermal_governor_lock);
 -	return ret;
 -}
 -
 -static ssize_t
 -policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -
 -	return sprintf(buf, "%s\n", tz->governor->name);
 -}
 -
 -static ssize_t
 -available_policies_show(struct device *dev, struct device_attribute *devattr,
 -			char *buf)
 -{
 -	struct thermal_governor *pos;
 -	ssize_t count = 0;
 -	ssize_t size = PAGE_SIZE;
 -
 -	mutex_lock(&thermal_governor_lock);
 -
 -	list_for_each_entry(pos, &thermal_governor_list, governor_list) {
 -		size = PAGE_SIZE - count;
 -		count += scnprintf(buf + count, size, "%s ", pos->name);
 -	}
 -	count += scnprintf(buf + count, size, "\n");
 -
 -	mutex_unlock(&thermal_governor_lock);
 -
 -	return count;
 -}
 -
 -static ssize_t
 -emul_temp_store(struct device *dev, struct device_attribute *attr,
 -		     const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	int ret = 0;
 -	int temperature;
 -
 -	if (kstrtoint(buf, 10, &temperature))
 -		return -EINVAL;
 -
 -	if (!tz->ops->set_emul_temp) {
 -		mutex_lock(&tz->lock);
 -		tz->emul_temperature = temperature;
 -		mutex_unlock(&tz->lock);
 -	} else {
 -		ret = tz->ops->set_emul_temp(tz, temperature);
 -	}
 -
 -	if (!ret)
 -		thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
 -
 -	return ret ? ret : count;
 -}
 -static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
 -
 -static ssize_t
 -sustainable_power_show(struct device *dev, struct device_attribute *devattr,
 -		       char *buf)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -
 -	if (tz->tzp)
 -		return sprintf(buf, "%u\n", tz->tzp->sustainable_power);
 -	else
 -		return -EIO;
 -}
 -
 -static ssize_t
 -sustainable_power_store(struct device *dev, struct device_attribute *devattr,
 -			const char *buf, size_t count)
 -{
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);
 -	u32 sustainable_power;
 -
 -	if (!tz->tzp)
 -		return -EIO;
 -
 -	if (kstrtou32(buf, 10, &sustainable_power))
 -		return -EINVAL;
 -
 -	tz->tzp->sustainable_power = sustainable_power;
 -
 -	return count;
 -}
 -static DEVICE_ATTR(sustainable_power, S_IWUSR | S_IRUGO, sustainable_power_show,
 -		sustainable_power_store);
 -
 -#define create_s32_tzp_attr(name)					\
 -	static ssize_t							\
 -	name##_show(struct device *dev, struct device_attribute *devattr, \
 -		char *buf)						\
 -	{								\
 -	struct thermal_zone_device *tz = to_thermal_zone(dev);		\
 -									\
 -	if (tz->tzp)							\
 -		return sprintf(buf, "%d\n", tz->tzp->name);		\
 -	else								\
 -		return -EIO;						\
 -	}								\
 -									\
 -	static ssize_t							\
 -	name##_store(struct device *dev, struct device_attribute *devattr, \
 -		const char *buf, size_t count)				\
 -	{								\
 -		struct thermal_zone_device *tz = to_thermal_zone(dev);	\
 -		s32 value;						\
 -									\
 -		if (!tz->tzp)						\
 -			return -EIO;					\
 -									\
 -		if (kstrtos32(buf, 10, &value))				\
 -			return -EINVAL;					\
 -									\
 -		tz->tzp->name = value;					\
 -									\
 -		return count;						\
 -	}								\
 -	static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, name##_show, name##_store)
 -
 -create_s32_tzp_attr(k_po);
 -create_s32_tzp_attr(k_pu);
 -create_s32_tzp_attr(k_i);
 -create_s32_tzp_attr(k_d);
 -create_s32_tzp_attr(integral_cutoff);
 -create_s32_tzp_attr(slope);
 -create_s32_tzp_attr(offset);
 -#undef create_s32_tzp_attr
 -
 -static struct device_attribute *dev_tzp_attrs[] = {
 -	&dev_attr_sustainable_power,
 -	&dev_attr_k_po,
 -	&dev_attr_k_pu,
 -	&dev_attr_k_i,
 -	&dev_attr_k_d,
 -	&dev_attr_integral_cutoff,
 -	&dev_attr_slope,
 -	&dev_attr_offset,
 -};
 -
 -static int create_tzp_attrs(struct device *dev)
 -{
 -	int i;
 -
 -	for (i = 0; i < ARRAY_SIZE(dev_tzp_attrs); i++) {
 -		int ret;
 -		struct device_attribute *dev_attr = dev_tzp_attrs[i];
 -
 -		ret = device_create_file(dev, dev_attr);
 -		if (ret)
 -			return ret;
 -	}
 -
 -	return 0;
 -}
 +/*
 + * Power actor section: interface to power actors to estimate power
 + *
 + * Set of functions used to interact to cooling devices that know
 + * how to estimate their devices power consumption.
 + */
  
  /**
   * power_actor_get_max_power() - get the maximum power that a cdev can consume
@@@ -510,13 -1127,12 +510,13 @@@ int power_actor_get_min_power(struct th
  }
  
  /**
 - * power_actor_set_power() - limit the maximum power that a cooling device can consume
 + * power_actor_set_power() - limit the maximum power a cooling device consumes
   * @cdev:	pointer to &thermal_cooling_device
   * @instance:	thermal instance to update
   * @power:	the power in milliwatts
   *
 - * Set the cooling device to consume at most @power milliwatts.
 + * Set the cooling device to consume at most @power milliwatts. The limit is
 + * expected to be a cap at the maximum power consumption.
   *
   * Return: 0 on success, -EINVAL if the cooling device does not
   * implement the power actor API or -E* for other failures.
@@@ -543,75 -1159,143 +543,75 @@@ int power_actor_set_power(struct therma
  	return 0;
  }
  
 -static DEVICE_ATTR(type, 0444, type_show, NULL);
 -static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 -static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
 -static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
 -static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store);
 -static DEVICE_ATTR(available_policies, S_IRUGO, available_policies_show, NULL);
 -
 -/* sys I/F for cooling device */
 -#define to_cooling_device(_dev)	\
 -	container_of(_dev, struct thermal_cooling_device, device)
 -
 -static ssize_t
 -thermal_cooling_device_type_show(struct device *dev,
 -				 struct device_attribute *attr, char *buf)
 +void thermal_zone_device_rebind_exception(struct thermal_zone_device *tz,
 +					  const char *cdev_type, size_t size)
  {
 -	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 +	struct thermal_cooling_device *cdev = NULL;
  
 -	return sprintf(buf, "%s\n", cdev->type);
 +	mutex_lock(&thermal_list_lock);
 +	list_for_each_entry(cdev, &thermal_cdev_list, node) {
 +		/* skip non matching cdevs */
 +		if (strncmp(cdev_type, cdev->type, size))
 +			continue;
 +
 +		/* re binding the exception matching the type pattern */
 +		thermal_zone_bind_cooling_device(tz, THERMAL_TRIPS_NONE, cdev,
 +						 THERMAL_NO_LIMIT,
 +						 THERMAL_NO_LIMIT,
 +						 THERMAL_WEIGHT_DEFAULT);
 +	}
 +	mutex_unlock(&thermal_list_lock);
  }
  
 -static ssize_t
 -thermal_cooling_device_max_state_show(struct device *dev,
 -				      struct device_attribute *attr, char *buf)
 +void thermal_zone_device_unbind_exception(struct thermal_zone_device *tz,
 +					  const char *cdev_type, size_t size)
  {
 -	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 -	unsigned long state;
 -	int ret;
 +	struct thermal_cooling_device *cdev = NULL;
  
 -	ret = cdev->ops->get_max_state(cdev, &state);
 -	if (ret)
 -		return ret;
 -	return sprintf(buf, "%ld\n", state);
 +	mutex_lock(&thermal_list_lock);
 +	list_for_each_entry(cdev, &thermal_cdev_list, node) {
 +		/* skip non matching cdevs */
 +		if (strncmp(cdev_type, cdev->type, size))
 +			continue;
 +		/* unbinding the exception matching the type pattern */
 +		thermal_zone_unbind_cooling_device(tz, THERMAL_TRIPS_NONE,
 +						   cdev);
 +	}
 +	mutex_unlock(&thermal_list_lock);
  }
  
 -static ssize_t
 -thermal_cooling_device_cur_state_show(struct device *dev,
 -				      struct device_attribute *attr, char *buf)
 +/*
 + * Device management section: cooling devices, zones devices, and binding
 + *
 + * Set of functions provided by the thermal core for:
 + * - cooling devices lifecycle: registration, unregistration,
 + *				binding, and unbinding.
 + * - thermal zone devices lifecycle: registration, unregistration,
 + *				     binding, and unbinding.
 + */
 +static int get_idr(struct idr *idr, struct mutex *lock, int *id)
  {
 -	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 -	unsigned long state;
  	int ret;
  
 -	ret = cdev->ops->get_cur_state(cdev, &state);
 -	if (ret)
 +	if (lock)
 +		mutex_lock(lock);
 +	ret = idr_alloc(idr, NULL, 0, 0, GFP_KERNEL);
 +	if (lock)
 +		mutex_unlock(lock);
 +	if (unlikely(ret < 0))
  		return ret;
 -	return sprintf(buf, "%ld\n", state);
 -}
 -
 -static ssize_t
 -thermal_cooling_device_cur_state_store(struct device *dev,
 -				       struct device_attribute *attr,
 -				       const char *buf, size_t count)
 -{
 -	struct thermal_cooling_device *cdev = to_cooling_device(dev);
 -	unsigned long state;
 -	int result;
 -
 -	if (!sscanf(buf, "%ld\n", &state))
 -		return -EINVAL;
 -
 -	if ((long)state < 0)
 -		return -EINVAL;
 -
 -	result = cdev->ops->set_cur_state(cdev, state);
 -	if (result)
 -		return result;
 -	return count;
 -}
 -
 -static struct device_attribute dev_attr_cdev_type =
 -__ATTR(type, 0444, thermal_cooling_device_type_show, NULL);
 -static DEVICE_ATTR(max_state, 0444,
 -		   thermal_cooling_device_max_state_show, NULL);
 -static DEVICE_ATTR(cur_state, 0644,
 -		   thermal_cooling_device_cur_state_show,
 -		   thermal_cooling_device_cur_state_store);
 -
 -static ssize_t
 -thermal_cooling_device_trip_point_show(struct device *dev,
 -				       struct device_attribute *attr, char *buf)
 -{
 -	struct thermal_instance *instance;
 -
 -	instance =
 -	    container_of(attr, struct thermal_instance, attr);
 -
 -	if (instance->trip == THERMAL_TRIPS_NONE)
 -		return sprintf(buf, "-1\n");
 -	else
 -		return sprintf(buf, "%d\n", instance->trip);
 -}
 -
 -static struct attribute *cooling_device_attrs[] = {
 -	&dev_attr_cdev_type.attr,
 -	&dev_attr_max_state.attr,
 -	&dev_attr_cur_state.attr,
 -	NULL,
 -};
 -
 -static const struct attribute_group cooling_device_attr_group = {
 -	.attrs = cooling_device_attrs,
 -};
 -
 -static const struct attribute_group *cooling_device_attr_groups[] = {
 -	&cooling_device_attr_group,
 -	NULL,
 -};
 -
 -static ssize_t
 -thermal_cooling_device_weight_show(struct device *dev,
 -				   struct device_attribute *attr, char *buf)
 -{
 -	struct thermal_instance *instance;
 -
 -	instance = container_of(attr, struct thermal_instance, weight_attr);
 -
 -	return sprintf(buf, "%d\n", instance->weight);
 +	*id = ret;
 +	return 0;
  }
  
 -static ssize_t
 -thermal_cooling_device_weight_store(struct device *dev,
 -				    struct device_attribute *attr,
 -				    const char *buf, size_t count)
 -{
 -	struct thermal_instance *instance;
 -	int ret, weight;
 -
 -	ret = kstrtoint(buf, 0, &weight);
 -	if (ret)
 -		return ret;
 -
 -	instance = container_of(attr, struct thermal_instance, weight_attr);
 -	instance->weight = weight;
 -
 -	return count;
 +static void release_idr(struct idr *idr, struct mutex *lock, int id)
 +{
 +	if (lock)
 +		mutex_lock(lock);
 +	idr_remove(idr, id);
 +	if (lock)
 +		mutex_unlock(lock);
  }
 -/* Device management */
  
  /**
   * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone
@@@ -674,7 -1358,8 +674,7 @@@ int thermal_zone_bind_cooling_device(st
  	if (lower > upper || upper > max_state)
  		return -EINVAL;
  
 -	dev =
 -	    kzalloc(sizeof(struct thermal_instance), GFP_KERNEL);
 +	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  	if (!dev)
  		return -ENOMEM;
  	dev->tz = tz;
@@@ -717,10 -1402,10 +717,10 @@@
  	mutex_lock(&tz->lock);
  	mutex_lock(&cdev->lock);
  	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
 -	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 -		result = -EEXIST;
 -		break;
 -	}
 +		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 +			result = -EEXIST;
 +			break;
 +		}
  	if (!result) {
  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
  		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
@@@ -800,8 -1485,8 +800,8 @@@ static void thermal_release(struct devi
  		     sizeof("thermal_zone") - 1)) {
  		tz = to_thermal_zone(dev);
  		kfree(tz);
 -	} else if(!strncmp(dev_name(dev), "cooling_device",
 -			sizeof("cooling_device") - 1)){
 +	} else if (!strncmp(dev_name(dev), "cooling_device",
 +			    sizeof("cooling_device") - 1)) {
  		cdev = to_cooling_device(dev);
  		kfree(cdev);
  	}
@@@ -812,78 -1497,6 +812,78 @@@ static struct class thermal_class = 
  	.dev_release = thermal_release,
  };
  
 +static inline
 +void print_bind_err_msg(struct thermal_zone_device *tz,
 +			struct thermal_cooling_device *cdev, int ret)
 +{
 +	dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n",
 +		tz->type, cdev->type, ret);
 +}
 +
 +static void __bind(struct thermal_zone_device *tz, int mask,
 +		   struct thermal_cooling_device *cdev,
 +		   unsigned long *limits,
 +		   unsigned int weight)
 +{
 +	int i, ret;
 +
 +	for (i = 0; i < tz->trips; i++) {
 +		if (mask & (1 << i)) {
 +			unsigned long upper, lower;
 +
 +			upper = THERMAL_NO_LIMIT;
 +			lower = THERMAL_NO_LIMIT;
 +			if (limits) {
 +				lower = limits[i * 2];
 +				upper = limits[i * 2 + 1];
 +			}
 +			ret = thermal_zone_bind_cooling_device(tz, i, cdev,
 +							       upper, lower,
 +							       weight);
 +			if (ret)
 +				print_bind_err_msg(tz, cdev, ret);
 +		}
 +	}
 +}
 +
 +static void bind_cdev(struct thermal_cooling_device *cdev)
 +{
 +	int i, ret;
 +	const struct thermal_zone_params *tzp;
 +	struct thermal_zone_device *pos = NULL;
 +
 +	mutex_lock(&thermal_list_lock);
 +
 +	list_for_each_entry(pos, &thermal_tz_list, node) {
 +		if (!pos->tzp && !pos->ops->bind)
 +			continue;
 +
 +		if (pos->ops->bind) {
 +			ret = pos->ops->bind(pos, cdev);
 +			if (ret)
 +				print_bind_err_msg(pos, cdev, ret);
 +			continue;
 +		}
 +
 +		tzp = pos->tzp;
 +		if (!tzp || !tzp->tbp)
 +			continue;
 +
 +		for (i = 0; i < tzp->num_tbps; i++) {
 +			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
 +				continue;
 +			if (tzp->tbp[i].match(pos, cdev))
 +				continue;
 +			tzp->tbp[i].cdev = cdev;
 +			__bind(pos, tzp->tbp[i].trip_mask, cdev,
 +			       tzp->tbp[i].binding_limits,
 +			       tzp->tbp[i].weight);
 +		}
 +	}
 +
 +	mutex_unlock(&thermal_list_lock);
 +}
 +
  /**
   * __thermal_cooling_device_register() - register a new thermal cooling device
   * @np:		a pointer to a device tree node.
@@@ -916,7 -1529,7 +916,7 @@@ __thermal_cooling_device_register(struc
  	    !ops->set_cur_state)
  		return ERR_PTR(-EINVAL);
  
 -	cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL);
 +	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
  	if (!cdev)
  		return ERR_PTR(-ENOMEM);
  
@@@ -933,7 -1546,7 +933,7 @@@
  	cdev->ops = ops;
  	cdev->updated = false;
  	cdev->device.class = &thermal_class;
 -	cdev->device.groups = cooling_device_attr_groups;
 +	thermal_cooling_device_setup_sysfs(cdev);
  	cdev->devdata = devdata;
  	dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
  	result = device_register(&cdev->device);
@@@ -1006,22 -1619,12 +1006,22 @@@ thermal_of_cooling_device_register(stru
  }
  EXPORT_SYMBOL_GPL(thermal_of_cooling_device_register);
  
 +static void __unbind(struct thermal_zone_device *tz, int mask,
 +		     struct thermal_cooling_device *cdev)
 +{
 +	int i;
 +
 +	for (i = 0; i < tz->trips; i++)
 +		if (mask & (1 << i))
 +			thermal_zone_unbind_cooling_device(tz, i, cdev);
 +}
 +
  /**
 - * thermal_cooling_device_unregister - removes the registered thermal cooling device
 + * thermal_cooling_device_unregister - removes a thermal cooling device
   * @cdev:	the thermal cooling device to remove.
   *
 - * thermal_cooling_device_unregister() must be called when the device is no
 - * longer needed.
 + * thermal_cooling_device_unregister() must be called when a registered
 + * thermal cooling device is no longer needed.
   */
  void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
  {
@@@ -1035,8 -1638,8 +1035,8 @@@
  
  	mutex_lock(&thermal_list_lock);
  	list_for_each_entry(pos, &thermal_cdev_list, node)
 -	    if (pos == cdev)
 -		break;
 +		if (pos == cdev)
 +			break;
  	if (pos != cdev) {
  		/* thermal cooling device not found */
  		mutex_unlock(&thermal_list_lock);
@@@ -1065,49 -1668,171 +1065,49 @@@
  
  	mutex_unlock(&thermal_list_lock);
  
 -	if (cdev->type[0])
 -		device_remove_file(&cdev->device, &dev_attr_cdev_type);
 -	device_remove_file(&cdev->device, &dev_attr_max_state);
 -	device_remove_file(&cdev->device, &dev_attr_cur_state);
 -
  	release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
  	device_unregister(&cdev->device);
 -	return;
  }
  EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
  
 -void thermal_cdev_update(struct thermal_cooling_device *cdev)
 +static void bind_tz(struct thermal_zone_device *tz)
  {
 -	struct thermal_instance *instance;
 -	unsigned long target = 0;
 +	int i, ret;
 +	struct thermal_cooling_device *pos = NULL;
 +	const struct thermal_zone_params *tzp = tz->tzp;
  
 -	mutex_lock(&cdev->lock);
 -	/* cooling device is updated*/
 -	if (cdev->updated) {
 -		mutex_unlock(&cdev->lock);
 +	if (!tzp && !tz->ops->bind)
  		return;
 -	}
 -
 -	/* Make sure cdev enters the deepest cooling state */
 -	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
 -		dev_dbg(&cdev->device, "zone%d->target=%lu\n",
 -				instance->tz->id, instance->target);
 -		if (instance->target == THERMAL_NO_TARGET)
 -			continue;
 -		if (instance->target > target)
 -			target = instance->target;
 -	}
 -	cdev->ops->set_cur_state(cdev, target);
 -	cdev->updated = true;
 -	mutex_unlock(&cdev->lock);
 -	trace_cdev_update(cdev, target);
 -	dev_dbg(&cdev->device, "set to state %lu\n", target);
 -}
 -EXPORT_SYMBOL(thermal_cdev_update);
 -
 -/**
 - * thermal_notify_framework - Sensor drivers use this API to notify framework
 - * @tz:		thermal zone device
 - * @trip:	indicates which trip point has been crossed
 - *
 - * This function handles the trip events from sensor drivers. It starts
 - * throttling the cooling devices according to the policy configured.
 - * For CRITICAL and HOT trip points, this notifies the respective drivers,
 - * and does actual throttling for other trip points i.e ACTIVE and PASSIVE.
 - * The throttling policy is based on the configured platform data; if no
 - * platform data is provided, this uses the step_wise throttling policy.
 - */
 -void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
 -{
 -	handle_thermal_trip(tz, trip);
 -}
 -EXPORT_SYMBOL_GPL(thermal_notify_framework);
 -
 -/**
 - * create_trip_attrs() - create attributes for trip points
 - * @tz:		the thermal zone device
 - * @mask:	Writeable trip point bitmap.
 - *
 - * helper function to instantiate sysfs entries for every trip
 - * point and its properties of a struct thermal_zone_device.
 - *
 - * Return: 0 on success, the proper error value otherwise.
 - */
 -static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
 -{
 -	int indx;
 -	int size = sizeof(struct thermal_attr) * tz->trips;
  
 -	tz->trip_type_attrs = kzalloc(size, GFP_KERNEL);
 -	if (!tz->trip_type_attrs)
 -		return -ENOMEM;
 -
 -	tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
 -	if (!tz->trip_temp_attrs) {
 -		kfree(tz->trip_type_attrs);
 -		return -ENOMEM;
 -	}
 +	mutex_lock(&thermal_list_lock);
  
 -	if (tz->ops->get_trip_hyst) {
 -		tz->trip_hyst_attrs = kzalloc(size, GFP_KERNEL);
 -		if (!tz->trip_hyst_attrs) {
 -			kfree(tz->trip_type_attrs);
 -			kfree(tz->trip_temp_attrs);
 -			return -ENOMEM;
 +	/* If there is ops->bind, try to use ops->bind */
 +	if (tz->ops->bind) {
 +		list_for_each_entry(pos, &thermal_cdev_list, node) {
 +			ret = tz->ops->bind(tz, pos);
 +			if (ret)
 +				print_bind_err_msg(tz, pos, ret);
  		}
 +		goto exit;
  	}
  
 +	if (!tzp || !tzp->tbp)
 +		goto exit;
  
 -	for (indx = 0; indx < tz->trips; indx++) {
 -		/* create trip type attribute */
 -		snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
 -			 "trip_point_%d_type", indx);
 -
 -		sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
 -		tz->trip_type_attrs[indx].attr.attr.name =
 -						tz->trip_type_attrs[indx].name;
 -		tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
 -		tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
 -
 -		device_create_file(&tz->device,
 -				   &tz->trip_type_attrs[indx].attr);
 -
 -		/* create trip temp attribute */
 -		snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
 -			 "trip_point_%d_temp", indx);
 -
 -		sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
 -		tz->trip_temp_attrs[indx].attr.attr.name =
 -						tz->trip_temp_attrs[indx].name;
 -		tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
 -		tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
 -		if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS) &&
 -		    mask & (1 << indx)) {
 -			tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
 -			tz->trip_temp_attrs[indx].attr.store =
 -							trip_point_temp_store;
 -		}
 -
 -		device_create_file(&tz->device,
 -				   &tz->trip_temp_attrs[indx].attr);
 -
 -		/* create Optional trip hyst attribute */
 -		if (!tz->ops->get_trip_hyst)
 -			continue;
 -		snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
 -			 "trip_point_%d_hyst", indx);
 -
 -		sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
 -		tz->trip_hyst_attrs[indx].attr.attr.name =
 -					tz->trip_hyst_attrs[indx].name;
 -		tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
 -		tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
 -		if (tz->ops->set_trip_hyst) {
 -			tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
 -			tz->trip_hyst_attrs[indx].attr.store =
 -					trip_point_hyst_store;
 +	list_for_each_entry(pos, &thermal_cdev_list, node) {
 +		for (i = 0; i < tzp->num_tbps; i++) {
 +			if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
 +				continue;
 +			if (tzp->tbp[i].match(tz, pos))
 +				continue;
 +			tzp->tbp[i].cdev = pos;
 +			__bind(tz, tzp->tbp[i].trip_mask, pos,
 +			       tzp->tbp[i].binding_limits,
 +			       tzp->tbp[i].weight);
  		}
 -
 -		device_create_file(&tz->device,
 -				   &tz->trip_hyst_attrs[indx].attr);
 -	}
 -	return 0;
 -}
 -
 -static void remove_trip_attrs(struct thermal_zone_device *tz)
 -{
 -	int indx;
 -
 -	for (indx = 0; indx < tz->trips; indx++) {
 -		device_remove_file(&tz->device,
 -				   &tz->trip_type_attrs[indx].attr);
 -		device_remove_file(&tz->device,
 -				   &tz->trip_temp_attrs[indx].attr);
 -		if (tz->ops->get_trip_hyst)
 -			device_remove_file(&tz->device,
 -				  &tz->trip_hyst_attrs[indx].attr);
  	}
 -	kfree(tz->trip_type_attrs);
 -	kfree(tz->trip_temp_attrs);
 -	kfree(tz->trip_hyst_attrs);
 +exit:
 +	mutex_unlock(&thermal_list_lock);
  }
  
  /**
@@@ -1134,22 -1859,20 +1134,22 @@@
   * in case of error, an ERR_PTR. Caller must check return value with
   * IS_ERR*() helpers.
   */
 -struct thermal_zone_device *thermal_zone_device_register(const char *type,
 -	int trips, int mask, void *devdata,
 -	struct thermal_zone_device_ops *ops,
 -	struct thermal_zone_params *tzp,
 -	int passive_delay, int polling_delay)
 +struct thermal_zone_device *
 +thermal_zone_device_register(const char *type, int trips, int mask,
 +			     void *devdata, struct thermal_zone_device_ops *ops,
 +			     struct thermal_zone_params *tzp, int passive_delay,
 +			     int polling_delay)
  {
  	struct thermal_zone_device *tz;
  	enum thermal_trip_type trip_type;
  	int trip_temp;
  	int result;
  	int count;
 -	int passive = 0;
  	struct thermal_governor *governor;
  
 +	if (!type || strlen(type) == 0)
 +		return ERR_PTR(-EINVAL);
 +
  	if (type && strlen(type) >= THERMAL_NAME_LENGTH)
  		return ERR_PTR(-EINVAL);
  
@@@ -1162,7 -1885,7 +1162,7 @@@
  	if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
  		return ERR_PTR(-EINVAL);
  
 -	tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
 +	tz = kzalloc(sizeof(*tz), GFP_KERNEL);
  	if (!tz)
  		return ERR_PTR(-ENOMEM);
  
@@@ -1175,7 -1898,7 +1175,7 @@@
  		return ERR_PTR(result);
  	}
  
 -	strlcpy(tz->type, type ? : "", sizeof(tz->type));
 +	strlcpy(tz->type, type, sizeof(tz->type));
  	tz->ops = ops;
  	tz->tzp = tzp;
  	tz->device.class = &thermal_class;
@@@ -1183,13 -1906,6 +1183,13 @@@
  	tz->trips = trips;
  	tz->passive_delay = passive_delay;
  	tz->polling_delay = polling_delay;
 +
 +	/* sys I/F */
 +	/* Add nodes that are always present via .groups */
 +	result = thermal_zone_create_device_groups(tz, mask);
 +	if (result)
 +		goto unregister;
 +
  	/* A new thermal zone needs to be updated anyway. */
  	atomic_set(&tz->need_update, 1);
  
@@@ -1201,9 -1917,32 +1201,9 @@@
  		return ERR_PTR(result);
  	}
  
 -	/* sys I/F */
 -	if (type) {
 -		result = device_create_file(&tz->device, &dev_attr_type);
 -		if (result)
 -			goto unregister;
 -	}
 -
 -	result = device_create_file(&tz->device, &dev_attr_temp);
 -	if (result)
 -		goto unregister;
 -
 -	if (ops->get_mode) {
 -		result = device_create_file(&tz->device, &dev_attr_mode);
 -		if (result)
 -			goto unregister;
 -	}
 -
 -	result = create_trip_attrs(tz, mask);
 -	if (result)
 -		goto unregister;
 -
  	for (count = 0; count < trips; count++) {
  		if (tz->ops->get_trip_type(tz, count, &trip_type))
  			set_bit(count, &tz->trips_disabled);
 -		if (trip_type == THERMAL_TRIP_PASSIVE)
 -			passive = 1;
  		if (tz->ops->get_trip_temp(tz, count, &trip_temp))
  			set_bit(count, &tz->trips_disabled);
  		/* Check for bogus trip points */
@@@ -1211,6 -1950,33 +1211,6 @@@
  			set_bit(count, &tz->trips_disabled);
  	}
  
 -	if (!passive) {
 -		result = device_create_file(&tz->device, &dev_attr_passive);
 -		if (result)
 -			goto unregister;
 -	}
 -
 -	if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) {
 -		result = device_create_file(&tz->device, &dev_attr_emul_temp);
 -		if (result)
 -			goto unregister;
 -	}
 -
 -	/* Create policy attribute */
 -	result = device_create_file(&tz->device, &dev_attr_policy);
 -	if (result)
 -		goto unregister;
 -
 -	/* Add thermal zone params */
 -	result = create_tzp_attrs(&tz->device);
 -	if (result)
 -		goto unregister;
 -
 -	/* Create available_policies attribute */
 -	result = device_create_file(&tz->device, &dev_attr_available_policies);
 -	if (result)
 -		goto unregister;
 -
  	/* Update 'this' zone's governor information */
  	mutex_lock(&thermal_governor_lock);
  
@@@ -1240,7 -2006,7 +1240,7 @@@
  	/* Bind cooling devices for this zone */
  	bind_tz(tz);
  
 -	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 +	INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
  
  	thermal_zone_device_reset(tz);
  	/* Update the new thermal zone and mark it as already updated. */
@@@ -1274,8 -2040,8 +1274,8 @@@ void thermal_zone_device_unregister(str
  
  	mutex_lock(&thermal_list_lock);
  	list_for_each_entry(pos, &thermal_tz_list, node)
 -	    if (pos == tz)
 -		break;
 +		if (pos == tz)
 +			break;
  	if (pos != tz) {
  		/* thermal zone device not found */
  		mutex_unlock(&thermal_list_lock);
@@@ -1305,10 -2071,14 +1305,10 @@@
  
  	thermal_zone_device_set_polling(tz, 0);
  
 -	if (tz->type[0])
 -		device_remove_file(&tz->device, &dev_attr_type);
 -	device_remove_file(&tz->device, &dev_attr_temp);
 -	if (tz->ops->get_mode)
 -		device_remove_file(&tz->device, &dev_attr_mode);
 -	device_remove_file(&tz->device, &dev_attr_policy);
 -	device_remove_file(&tz->device, &dev_attr_available_policies);
 -	remove_trip_attrs(tz);
 +	kfree(tz->trip_type_attrs);
 +	kfree(tz->trip_temp_attrs);
 +	kfree(tz->trip_hyst_attrs);
 +	kfree(tz->trips_attribute_group.attrs);
  	thermal_set_governor(tz, NULL);
  
  	thermal_remove_hwmon_sysfs(tz);
@@@ -1316,7 -2086,7 +1316,7 @@@
  	idr_destroy(&tz->idr);
  	mutex_destroy(&tz->lock);
  	device_unregister(&tz->device);
 -	return;
 +	kfree(tz->device.groups);
  }
  EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
  
@@@ -1358,13 -2128,43 +1358,13 @@@ exit
  }
  EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
  
 -/**
 - * thermal_zone_get_slope - return the slope attribute of the thermal zone
 - * @tz: thermal zone device with the slope attribute
 - *
 - * Return: If the thermal zone device has a slope attribute, return it, else
 - * return 1.
 - */
 -int thermal_zone_get_slope(struct thermal_zone_device *tz)
 -{
 -	if (tz && tz->tzp)
 -		return tz->tzp->slope;
 -	return 1;
 -}
 -EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
 -
 -/**
 - * thermal_zone_get_offset - return the offset attribute of the thermal zone
 - * @tz: thermal zone device with the offset attribute
 - *
 - * Return: If the thermal zone device has a offset attribute, return it, else
 - * return 0.
 - */
 -int thermal_zone_get_offset(struct thermal_zone_device *tz)
 -{
 -	if (tz && tz->tzp)
 -		return tz->tzp->offset;
 -	return 0;
 -}
 -EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
 -
  #ifdef CONFIG_NET
  static const struct genl_multicast_group thermal_event_mcgrps[] = {
  	{ .name = THERMAL_GENL_MCAST_GROUP_NAME, },
  };
  
- static struct genl_family thermal_event_genl_family = {
- 	.id = GENL_ID_GENERATE,
+ static struct genl_family thermal_event_genl_family __ro_after_init = {
+ 	.module = THIS_MODULE,
  	.name = THERMAL_GENL_FAMILY_NAME,
  	.version = THERMAL_GENL_VERSION,
  	.maxattr = THERMAL_GENL_ATTR_MAX,
@@@ -1373,7 -2173,7 +1373,7 @@@
  };
  
  int thermal_generate_netlink_event(struct thermal_zone_device *tz,
 -					enum events event)
 +				   enum events event)
  {
  	struct sk_buff *skb;
  	struct nlattr *attr;
@@@ -1435,7 -2235,7 +1435,7 @@@
  }
  EXPORT_SYMBOL_GPL(thermal_generate_netlink_event);
  
- static int genetlink_init(void)
+ static int __init genetlink_init(void)
  {
  	return genl_register_family(&thermal_event_genl_family);
  }
@@@ -1449,8 -2249,40 +1449,8 @@@ static inline int genetlink_init(void) 
  static inline void genetlink_exit(void) {}
  #endif /* !CONFIG_NET */
  
 -static int __init thermal_register_governors(void)
 -{
 -	int result;
 -
 -	result = thermal_gov_step_wise_register();
 -	if (result)
 -		return result;
 -
 -	result = thermal_gov_fair_share_register();
 -	if (result)
 -		return result;
 -
 -	result = thermal_gov_bang_bang_register();
 -	if (result)
 -		return result;
 -
 -	result = thermal_gov_user_space_register();
 -	if (result)
 -		return result;
 -
 -	return thermal_gov_power_allocator_register();
 -}
 -
 -static void thermal_unregister_governors(void)
 -{
 -	thermal_gov_step_wise_unregister();
 -	thermal_gov_fair_share_unregister();
 -	thermal_gov_bang_bang_unregister();
 -	thermal_gov_user_space_unregister();
 -	thermal_gov_power_allocator_unregister();
 -}
 -
  static int thermal_pm_notify(struct notifier_block *nb,
 -				unsigned long mode, void *_unused)
 +			     unsigned long mode, void *_unused)
  {
  	struct thermal_zone_device *tz;
  
diff --combined fs/dlm/netlink.c
index 934ab06,0643ae4..43a96c3
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@@ -16,11 -16,7 +16,7 @@@
  static uint32_t dlm_nl_seqnum;
  static uint32_t listener_nlportid;
  
- static struct genl_family family = {
- 	.id		= GENL_ID_GENERATE,
- 	.name		= DLM_GENL_NAME,
- 	.version	= DLM_GENL_VERSION,
- };
+ static struct genl_family family;
  
  static int prepare_data(u8 cmd, struct sk_buff **skbp, size_t size)
  {
@@@ -69,16 -65,24 +65,24 @@@ static int user_cmd(struct sk_buff *skb
  	return 0;
  }
  
 -static struct genl_ops dlm_nl_ops[] = {
 +static const struct genl_ops dlm_nl_ops[] = {
  	{
  		.cmd	= DLM_CMD_HELLO,
  		.doit	= user_cmd,
  	},
  };
  
+ static struct genl_family family __ro_after_init = {
+ 	.name		= DLM_GENL_NAME,
+ 	.version	= DLM_GENL_VERSION,
+ 	.ops		= dlm_nl_ops,
+ 	.n_ops		= ARRAY_SIZE(dlm_nl_ops),
+ 	.module		= THIS_MODULE,
+ };
+ 
  int __init dlm_netlink_init(void)
  {
- 	return genl_register_family_with_ops(&family, dlm_nl_ops);
+ 	return genl_register_family(&family);
  }
  
  void dlm_netlink_exit(void)
diff --combined fs/nfs/inode.c
index 75f5a9c,ce42dd0..51ed027
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@@ -634,28 -634,15 +634,28 @@@ void nfs_setattr_update_inode(struct in
  }
  EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
  
 -static void nfs_request_parent_use_readdirplus(struct dentry *dentry)
 +static void nfs_readdirplus_parent_cache_miss(struct dentry *dentry)
  {
  	struct dentry *parent;
  
 +	if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
 +		return;
  	parent = dget_parent(dentry);
  	nfs_force_use_readdirplus(d_inode(parent));
  	dput(parent);
  }
  
 +static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
 +{
 +	struct dentry *parent;
 +
 +	if (!nfs_server_capable(d_inode(dentry), NFS_CAP_READDIRPLUS))
 +		return;
 +	parent = dget_parent(dentry);
 +	nfs_advise_use_readdirplus(d_inode(parent));
 +	dput(parent);
 +}
 +
  static bool nfs_need_revalidate_inode(struct inode *inode)
  {
  	if (NFS_I(inode)->cache_validity &
@@@ -696,10 -683,10 +696,10 @@@ int nfs_getattr(struct vfsmount *mnt, s
  	if (need_atime || nfs_need_revalidate_inode(inode)) {
  		struct nfs_server *server = NFS_SERVER(inode);
  
 -		if (server->caps & NFS_CAP_READDIRPLUS)
 -			nfs_request_parent_use_readdirplus(dentry);
 +		nfs_readdirplus_parent_cache_miss(dentry);
  		err = __nfs_revalidate_inode(server, inode);
 -	}
 +	} else
 +		nfs_readdirplus_parent_cache_hit(dentry);
  	if (!err) {
  		generic_fillattr(inode, stat);
  		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
@@@ -715,7 -702,8 +715,7 @@@ EXPORT_SYMBOL_GPL(nfs_getattr)
  static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
  {
  	atomic_set(&l_ctx->count, 1);
 -	l_ctx->lockowner.l_owner = current->files;
 -	l_ctx->lockowner.l_pid = current->tgid;
 +	l_ctx->lockowner = current->files;
  	INIT_LIST_HEAD(&l_ctx->list);
  	atomic_set(&l_ctx->io_count, 0);
  }
@@@ -726,7 -714,9 +726,7 @@@ static struct nfs_lock_context *__nfs_f
  	struct nfs_lock_context *pos = head;
  
  	do {
 -		if (pos->lockowner.l_owner != current->files)
 -			continue;
 -		if (pos->lockowner.l_pid != current->tgid)
 +		if (pos->lockowner != current->files)
  			continue;
  		atomic_inc(&pos->count);
  		return pos;
@@@ -809,9 -799,7 +809,9 @@@ void nfs_close_context(struct nfs_open_
  }
  EXPORT_SYMBOL_GPL(nfs_close_context);
  
 -struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
 +struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
 +						fmode_t f_mode,
 +						struct file *filp)
  {
  	struct nfs_open_context *ctx;
  	struct rpc_cred *cred = rpc_lookup_cred();
@@@ -830,7 -818,6 +830,7 @@@
  	ctx->mode = f_mode;
  	ctx->flags = 0;
  	ctx->error = 0;
 +	ctx->flock_owner = (fl_owner_t)filp;
  	nfs_init_lock_context(&ctx->lock_context);
  	ctx->lock_context.open_context = ctx;
  	INIT_LIST_HEAD(&ctx->list);
@@@ -955,7 -942,7 +955,7 @@@ int nfs_open(struct inode *inode, struc
  {
  	struct nfs_open_context *ctx;
  
 -	ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode);
 +	ctx = alloc_nfs_open_context(file_dentry(filp), filp->f_mode, filp);
  	if (IS_ERR(ctx))
  		return PTR_ERR(ctx);
  	nfs_file_set_open_context(filp, ctx);
@@@ -1330,7 -1317,7 +1330,7 @@@ static int nfs_check_inode_attributes(s
  		invalid |= NFS_INO_INVALID_ATIME;
  
  	if (invalid != 0)
 -		nfs_set_cache_invalid(inode, invalid);
 +		nfs_set_cache_invalid(inode, invalid | NFS_INO_REVAL_FORCED);
  
  	nfsi->read_cache_jiffies = fattr->time_start;
  	return 0;
@@@ -2028,7 -2015,7 +2028,7 @@@ static void nfsiod_stop(void
  	destroy_workqueue(wq);
  }
  
- int nfs_net_id;
+ unsigned int nfs_net_id;
  EXPORT_SYMBOL_GPL(nfs_net_id);
  
  static int nfs_net_init(struct net *net)
diff --combined fs/nfsd/nfsctl.c
index be13063,2857e46..f3b2f34
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@@ -217,7 -217,7 +217,7 @@@ static const struct file_operations poo
  	.release	= nfsd_pool_stats_release,
  };
  
 -static struct file_operations reply_cache_stats_operations = {
 +static const struct file_operations reply_cache_stats_operations = {
  	.open		= nfsd_reply_cache_stats_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
@@@ -1201,7 -1201,7 +1201,7 @@@ static int create_proc_exports_entry(vo
  }
  #endif
  
- int nfsd_net_id;
+ unsigned int nfsd_net_id;
  
  static __net_init int nfsd_init_net(struct net *net)
  {
diff --combined include/linux/device.h
index 36d3a98,a00105c..94926d3
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@@ -698,6 -698,25 +698,25 @@@ static inline int devm_add_action_or_re
  	return ret;
  }
  
+ /**
+  * devm_alloc_percpu - Resource-managed alloc_percpu
+  * @dev: Device to allocate per-cpu memory for
+  * @type: Type to allocate per-cpu memory for
+  *
+  * Managed alloc_percpu. Per-cpu memory allocated with this function is
+  * automatically freed on driver detach.
+  *
+  * RETURNS:
+  * Pointer to allocated memory on success, NULL on failure.
+  */
+ #define devm_alloc_percpu(dev, type)      \
+ 	((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
+ 						      __alignof__(type)))
+ 
+ void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
+ 				   size_t align);
+ void devm_free_percpu(struct device *dev, void __percpu *pdata);
+ 
  struct device_dma_parameters {
  	/*
  	 * a low level driver may set these to teach IOMMU code about
@@@ -733,7 -752,7 +752,7 @@@
   * 		minimizes board-specific #ifdefs in drivers.
   * @driver_data: Private pointer for driver specific info.
   * @power:	For device power management.
 - * 		See Documentation/power/devices.txt for details.
 + * 		See Documentation/power/admin-guide/devices.rst for details.
   * @pm_domain:	Provide callbacks that are executed during system suspend,
   * 		hibernation, system resume and during runtime PM transitions
   * 		along with subsystem-level and driver-level callbacks.
diff --combined init/Kconfig
index 172f80e,405120b..b4f1fdc
--- a/init/Kconfig
+++ b/init/Kconfig
@@@ -1154,6 -1154,18 +1154,18 @@@ config CGROUP_PER
  
  	  Say N if unsure.
  
+ config CGROUP_BPF
+ 	bool "Support for eBPF programs attached to cgroups"
+ 	depends on BPF_SYSCALL && SOCK_CGROUP_DATA
+ 	help
+ 	  Allow attaching eBPF programs to a cgroup using the bpf(2)
+ 	  syscall command BPF_PROG_ATTACH.
+ 
+ 	  In which context these programs are accessed depends on the type
+ 	  of attachment. For instance, programs that are attached using
+ 	  BPF_CGROUP_INET_INGRESS will be executed on the ingress path of
+ 	  inet sockets.
+ 
  config CGROUP_DEBUG
  	bool "Example controller"
  	default n
@@@ -1306,7 -1318,7 +1318,7 @@@ config BLK_DEV_INITR
  	  boot loader (loadlin or lilo) and that is mounted as root
  	  before the normal boot procedure. It is typically used to
  	  load modules needed to mount the "real" root file system,
 -	  etc. See <file:Documentation/initrd.txt> for details.
 +	  etc. See <file:Documentation/admin-guide/initrd.rst> for details.
  
  	  If RAM disk support (BLK_DEV_RAM) is also included, this
  	  also enables initial RAM disk (initrd) support and adds
diff --combined net/batman-adv/translation-table.c
index 0dc85eb,447f949..30ecbfb
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@@ -56,7 -56,6 +56,6 @@@
  #include "hard-interface.h"
  #include "hash.h"
  #include "log.h"
- #include "multicast.h"
  #include "netlink.h"
  #include "originator.h"
  #include "packet.h"
@@@ -647,6 -646,7 +646,7 @@@ bool batadv_tt_local_add(struct net_dev
  	struct net *net = dev_net(soft_iface);
  	struct batadv_softif_vlan *vlan;
  	struct net_device *in_dev = NULL;
+ 	struct batadv_hard_iface *in_hardif = NULL;
  	struct hlist_head *head;
  	struct batadv_tt_orig_list_entry *orig_entry;
  	int hash_added, table_size, packet_size_max;
@@@ -658,6 -658,9 +658,9 @@@
  	if (ifindex != BATADV_NULL_IFINDEX)
  		in_dev = dev_get_by_index(net, ifindex);
  
+ 	if (in_dev)
+ 		in_hardif = batadv_hardif_get_by_netdev(in_dev);
+ 
  	tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
  
  	if (!is_multicast_ether_addr(addr))
@@@ -731,7 -734,7 +734,7 @@@
  	 */
  	tt_local->common.flags = BATADV_TT_CLIENT_NEW;
  	tt_local->common.vid = vid;
- 	if (batadv_is_wifi_netdev(in_dev))
+ 	if (batadv_is_wifi_hardif(in_hardif))
  		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
  	kref_init(&tt_local->common.refcount);
  	tt_local->last_seen = jiffies;
@@@ -791,7 -794,7 +794,7 @@@ check_roaming
  	 */
  	remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
  
- 	if (batadv_is_wifi_netdev(in_dev))
+ 	if (batadv_is_wifi_hardif(in_hardif))
  		tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
  	else
  		tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
@@@ -815,6 -818,8 +818,8 @@@
  
  	ret = true;
  out:
+ 	if (in_hardif)
+ 		batadv_hardif_put(in_hardif);
  	if (in_dev)
  		dev_put(in_dev);
  	if (tt_local)
@@@ -3282,7 -3287,7 +3287,7 @@@ static bool batadv_send_my_tt_response(
  							     &tvlv_tt_data,
  							     &tt_change,
  							     &tt_len);
 -		if (!tt_len)
 +		if (!tt_len || !tvlv_len)
  			goto unlock;
  
  		/* Copy the last orig_node's OGM buffer */
@@@ -3300,7 -3305,7 +3305,7 @@@
  							     &tvlv_tt_data,
  							     &tt_change,
  							     &tt_len);
 -		if (!tt_len)
 +		if (!tt_len || !tvlv_len)
  			goto out;
  
  		/* fill the rest of the tvlv with the real TT entries */
@@@ -3795,9 -3800,6 +3800,6 @@@ static void batadv_tt_local_commit_chan
  {
  	lockdep_assert_held(&bat_priv->tt.commit_lock);
  
- 	/* Update multicast addresses in local translation table */
- 	batadv_mcast_mla_update(bat_priv);
- 
  	if (atomic_read(&bat_priv->tt.local_changes) < 1) {
  		if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
  			batadv_tt_tvlv_container_update(bat_priv);
@@@ -3835,8 -3837,8 +3837,8 @@@ void batadv_tt_local_commit_changes(str
  bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, u8 *src, u8 *dst,
  			   unsigned short vid)
  {
- 	struct batadv_tt_local_entry *tt_local_entry = NULL;
- 	struct batadv_tt_global_entry *tt_global_entry = NULL;
+ 	struct batadv_tt_local_entry *tt_local_entry;
+ 	struct batadv_tt_global_entry *tt_global_entry;
  	struct batadv_softif_vlan *vlan;
  	bool ret = false;
  
@@@ -3845,27 -3847,24 +3847,24 @@@
  		return false;
  
  	if (!atomic_read(&vlan->ap_isolation))
- 		goto out;
+ 		goto vlan_put;
  
  	tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
  	if (!tt_local_entry)
- 		goto out;
+ 		goto vlan_put;
  
  	tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
  	if (!tt_global_entry)
- 		goto out;
+ 		goto local_entry_put;
  
- 	if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
- 		goto out;
- 
- 	ret = true;
+ 	if (_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
+ 		ret = true;
  
- out:
+ 	batadv_tt_global_entry_put(tt_global_entry);
+ local_entry_put:
+ 	batadv_tt_local_entry_put(tt_local_entry);
+ vlan_put:
  	batadv_softif_vlan_put(vlan);
- 	if (tt_global_entry)
- 		batadv_tt_global_entry_put(tt_global_entry);
- 	if (tt_local_entry)
- 		batadv_tt_local_entry_put(tt_local_entry);
  	return ret;
  }
  
diff --combined net/unix/af_unix.c
index 6f72508,1752d6b..310882f
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@@ -315,7 -315,7 +315,7 @@@ static struct sock *unix_find_socket_by
  		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
  		struct dentry *dentry = unix_sk(s)->path.dentry;
  
 -		if (dentry && d_real_inode(dentry) == i) {
 +		if (dentry && d_backing_inode(dentry) == i) {
  			sock_hold(s);
  			goto found;
  		}
@@@ -913,7 -913,7 +913,7 @@@ static struct sock *unix_find_other(str
  		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
  		if (err)
  			goto fail;
 -		inode = d_real_inode(path.dentry);
 +		inode = d_backing_inode(path.dentry);
  		err = inode_permission(inode, MAY_WRITE);
  		if (err)
  			goto put_fail;
@@@ -1040,7 -1040,7 +1040,7 @@@ static int unix_bind(struct socket *soc
  			goto out_up;
  		}
  		addr->hash = UNIX_HASH_SIZE;
 -		hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
 +		hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
  		spin_lock(&unix_table_lock);
  		u->path = path;
  		list = &unix_socket_table[hash];
@@@ -2113,8 -2113,8 +2113,8 @@@ static int unix_dgram_recvmsg(struct so
  		mutex_lock(&u->iolock);
  
  		skip = sk_peek_offset(sk, flags);
- 		skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err,
- 					      &last);
+ 		skb = __skb_try_recv_datagram(sk, flags, NULL, &peeked, &skip,
+ 					      &err, &last);
  		if (skb)
  			break;
  

-- 
LinuxNextTracking


More information about the linux-merge mailing list