mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several conflicts here. NFP driver bug fix adding nfp_netdev_is_nfp_repr() check to nfp_fl_output() needed some adjustments because the code block is in an else block now. Parallel additions to net/pkt_cls.h and net/sch_generic.h A bug fix in __tcp_retransmit_skb() conflicted with some of the rbtree changes in net-next. The tc action RCU callback fixes in 'net' had some overlap with some of the recent tcf_block reworking. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
						commit
						e1ea2f9856
					
				
					 252 changed files with 2334 additions and 2095 deletions
				
			
		| 
						 | 
					@ -14,3 +14,11 @@ Description:
 | 
				
			||||||
		Show or set the gain boost of the amp, from 0-31 range.
 | 
							Show or set the gain boost of the amp, from 0-31 range.
 | 
				
			||||||
		18 = indoors (default)
 | 
							18 = indoors (default)
 | 
				
			||||||
		14 = outdoors
 | 
							14 = outdoors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What		/sys/bus/iio/devices/iio:deviceX/noise_level_tripped
 | 
				
			||||||
 | 
					Date:		May 2017
 | 
				
			||||||
 | 
					KernelVersion:	4.13
 | 
				
			||||||
 | 
					Contact:	Matt Ranostay <matt.ranostay@konsulko.com>
 | 
				
			||||||
 | 
					Description:
 | 
				
			||||||
 | 
							When 1 the noise level is over the trip level and not reporting
 | 
				
			||||||
 | 
							valid data
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,9 @@ Description:
 | 
				
			||||||
		device, after it has been suspended at run time, from a resume
 | 
							device, after it has been suspended at run time, from a resume
 | 
				
			||||||
		request to the moment the device will be ready to process I/O,
 | 
							request to the moment the device will be ready to process I/O,
 | 
				
			||||||
		in microseconds.  If it is equal to 0, however, this means that
 | 
							in microseconds.  If it is equal to 0, however, this means that
 | 
				
			||||||
		the PM QoS resume latency may be arbitrary.
 | 
							the PM QoS resume latency may be arbitrary and the special value
 | 
				
			||||||
 | 
							"n/a" means that user space cannot accept any resume latency at
 | 
				
			||||||
 | 
							all for the given device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Not all drivers support this attribute.  If it isn't supported,
 | 
							Not all drivers support this attribute.  If it isn't supported,
 | 
				
			||||||
		it is not present.
 | 
							it is not present.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,10 @@ Optional properties:
 | 
				
			||||||
	- ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
 | 
						- ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
 | 
				
			||||||
	  value 0 - 120pF. This will require using the calibration data from
 | 
						  value 0 - 120pF. This will require using the calibration data from
 | 
				
			||||||
	  the manufacturer.
 | 
						  the manufacturer.
 | 
				
			||||||
 | 
						- ams,nflwdth: Set the noise and watchdog threshold register on
 | 
				
			||||||
 | 
						  startup. This will need to set according to the noise from the
 | 
				
			||||||
 | 
						  MCU board, and possibly the local environment. Refer to the
 | 
				
			||||||
 | 
						  datasheet for the threshold settings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,4 +31,5 @@ as3935@0 {
 | 
				
			||||||
	interrupt-parent = <&gpio1>;
 | 
						interrupt-parent = <&gpio1>;
 | 
				
			||||||
	interrupts = <16 1>;
 | 
						interrupts = <16 1>;
 | 
				
			||||||
	ams,tuning-capacitor-pf = <80>;
 | 
						ams,tuning-capacitor-pf = <80>;
 | 
				
			||||||
 | 
						ams,nflwdth = <0x44>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,7 @@ Examples:
 | 
				
			||||||
			compatible = "arm,gic-v3-its";
 | 
								compatible = "arm,gic-v3-its";
 | 
				
			||||||
			msi-controller;
 | 
								msi-controller;
 | 
				
			||||||
			#msi-cells = <1>;
 | 
								#msi-cells = <1>;
 | 
				
			||||||
			reg = <0x0 0x2c200000 0 0x200000>;
 | 
								reg = <0x0 0x2c200000 0 0x20000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,14 +124,14 @@ Examples:
 | 
				
			||||||
			compatible = "arm,gic-v3-its";
 | 
								compatible = "arm,gic-v3-its";
 | 
				
			||||||
			msi-controller;
 | 
								msi-controller;
 | 
				
			||||||
			#msi-cells = <1>;
 | 
								#msi-cells = <1>;
 | 
				
			||||||
			reg = <0x0 0x2c200000 0 0x200000>;
 | 
								reg = <0x0 0x2c200000 0 0x20000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gic-its@2c400000 {
 | 
							gic-its@2c400000 {
 | 
				
			||||||
			compatible = "arm,gic-v3-its";
 | 
								compatible = "arm,gic-v3-its";
 | 
				
			||||||
			msi-controller;
 | 
								msi-controller;
 | 
				
			||||||
			#msi-cells = <1>;
 | 
								#msi-cells = <1>;
 | 
				
			||||||
			reg = <0x0 0x2c400000 0 0x200000>;
 | 
								reg = <0x0 0x2c400000 0 0x20000>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ppi-partitions {
 | 
							ppi-partitions {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1108,14 +1108,6 @@ When kbuild executes, the following steps are followed (roughly):
 | 
				
			||||||
    ld
 | 
					    ld
 | 
				
			||||||
	Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
 | 
						Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    objcopy
 | 
					 | 
				
			||||||
	Copy binary. Uses OBJCOPYFLAGS usually specified in
 | 
					 | 
				
			||||||
	arch/$(ARCH)/Makefile.
 | 
					 | 
				
			||||||
	OBJCOPYFLAGS_$@ may be used to set additional options.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gzip
 | 
					 | 
				
			||||||
	Compress target. Use maximum compression to compress target.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Example:
 | 
						Example:
 | 
				
			||||||
		#arch/x86/boot/Makefile
 | 
							#arch/x86/boot/Makefile
 | 
				
			||||||
		LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
 | 
							LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
 | 
				
			||||||
| 
						 | 
					@ -1139,6 +1131,19 @@ When kbuild executes, the following steps are followed (roughly):
 | 
				
			||||||
	      resulting in the target file being recompiled for no
 | 
						      resulting in the target file being recompiled for no
 | 
				
			||||||
	      obvious reason.
 | 
						      obvious reason.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    objcopy
 | 
				
			||||||
 | 
						Copy binary. Uses OBJCOPYFLAGS usually specified in
 | 
				
			||||||
 | 
						arch/$(ARCH)/Makefile.
 | 
				
			||||||
 | 
						OBJCOPYFLAGS_$@ may be used to set additional options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gzip
 | 
				
			||||||
 | 
						Compress target. Use maximum compression to compress target.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Example:
 | 
				
			||||||
 | 
							#arch/x86/boot/compressed/Makefile
 | 
				
			||||||
 | 
							$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
 | 
				
			||||||
 | 
								$(call if_changed,gzip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dtc
 | 
					    dtc
 | 
				
			||||||
	Create flattened device tree blob object suitable for linking
 | 
						Create flattened device tree blob object suitable for linking
 | 
				
			||||||
	into vmlinux. Device tree blobs linked into vmlinux are placed
 | 
						into vmlinux. Device tree blobs linked into vmlinux are placed
 | 
				
			||||||
| 
						 | 
					@ -1219,7 +1224,7 @@ When kbuild executes, the following steps are followed (roughly):
 | 
				
			||||||
	that may be shared between individual architectures.
 | 
						that may be shared between individual architectures.
 | 
				
			||||||
	The recommended approach how to use a generic header file is
 | 
						The recommended approach how to use a generic header file is
 | 
				
			||||||
	to list the file in the Kbuild file.
 | 
						to list the file in the Kbuild file.
 | 
				
			||||||
	See "7.3 generic-y" for further info on syntax etc.
 | 
						See "7.2 generic-y" for further info on syntax etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--- 6.11 Post-link pass
 | 
					--- 6.11 Post-link pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1254,13 +1259,13 @@ A Kbuild file may be defined under arch/<arch>/include/uapi/asm/ and
 | 
				
			||||||
arch/<arch>/include/asm/ to list asm files coming from asm-generic.
 | 
					arch/<arch>/include/asm/ to list asm files coming from asm-generic.
 | 
				
			||||||
See subsequent chapter for the syntax of the Kbuild file.
 | 
					See subsequent chapter for the syntax of the Kbuild file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	--- 7.1 no-export-headers
 | 
					--- 7.1 no-export-headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	no-export-headers is essentially used by include/uapi/linux/Kbuild to
 | 
						no-export-headers is essentially used by include/uapi/linux/Kbuild to
 | 
				
			||||||
	avoid exporting specific headers (e.g. kvm.h) on architectures that do
 | 
						avoid exporting specific headers (e.g. kvm.h) on architectures that do
 | 
				
			||||||
	not support it. It should be avoided as much as possible.
 | 
						not support it. It should be avoided as much as possible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	--- 7.2 generic-y
 | 
					--- 7.2 generic-y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	If an architecture uses a verbatim copy of a header from
 | 
						If an architecture uses a verbatim copy of a header from
 | 
				
			||||||
	include/asm-generic then this is listed in the file
 | 
						include/asm-generic then this is listed in the file
 | 
				
			||||||
| 
						 | 
					@ -1287,7 +1292,7 @@ See subsequent chapter for the syntax of the Kbuild file.
 | 
				
			||||||
		Example: termios.h
 | 
							Example: termios.h
 | 
				
			||||||
			#include <asm-generic/termios.h>
 | 
								#include <asm-generic/termios.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	--- 7.3 generated-y
 | 
					--- 7.3 generated-y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	If an architecture generates other header files alongside generic-y
 | 
						If an architecture generates other header files alongside generic-y
 | 
				
			||||||
	wrappers, generated-y specifies them.
 | 
						wrappers, generated-y specifies them.
 | 
				
			||||||
| 
						 | 
					@ -1299,7 +1304,7 @@ See subsequent chapter for the syntax of the Kbuild file.
 | 
				
			||||||
			#arch/x86/include/asm/Kbuild
 | 
								#arch/x86/include/asm/Kbuild
 | 
				
			||||||
			generated-y += syscalls_32.h
 | 
								generated-y += syscalls_32.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	--- 7.5 mandatory-y
 | 
					--- 7.4 mandatory-y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mandatory-y is essentially used by include/uapi/asm-generic/Kbuild.asm
 | 
						mandatory-y is essentially used by include/uapi/asm-generic/Kbuild.asm
 | 
				
			||||||
	to define the minimum set of headers that must be exported in
 | 
						to define the minimum set of headers that must be exported in
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9220,7 +9220,6 @@ F:	include/linux/isicom.h
 | 
				
			||||||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
 | 
					MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
 | 
				
			||||||
M:	Bin Liu <b-liu@ti.com>
 | 
					M:	Bin Liu <b-liu@ti.com>
 | 
				
			||||||
L:	linux-usb@vger.kernel.org
 | 
					L:	linux-usb@vger.kernel.org
 | 
				
			||||||
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
 | 
					 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
F:	drivers/usb/musb/
 | 
					F:	drivers/usb/musb/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10187,7 +10186,6 @@ F:	Documentation/parport*.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PARAVIRT_OPS INTERFACE
 | 
					PARAVIRT_OPS INTERFACE
 | 
				
			||||||
M:	Juergen Gross <jgross@suse.com>
 | 
					M:	Juergen Gross <jgross@suse.com>
 | 
				
			||||||
M:	Chris Wright <chrisw@sous-sol.org>
 | 
					 | 
				
			||||||
M:	Alok Kataria <akataria@vmware.com>
 | 
					M:	Alok Kataria <akataria@vmware.com>
 | 
				
			||||||
M:	Rusty Russell <rusty@rustcorp.com.au>
 | 
					M:	Rusty Russell <rusty@rustcorp.com.au>
 | 
				
			||||||
L:	virtualization@lists.linux-foundation.org
 | 
					L:	virtualization@lists.linux-foundation.org
 | 
				
			||||||
| 
						 | 
					@ -10567,6 +10565,8 @@ M:	Peter Zijlstra <peterz@infradead.org>
 | 
				
			||||||
M:	Ingo Molnar <mingo@redhat.com>
 | 
					M:	Ingo Molnar <mingo@redhat.com>
 | 
				
			||||||
M:	Arnaldo Carvalho de Melo <acme@kernel.org>
 | 
					M:	Arnaldo Carvalho de Melo <acme@kernel.org>
 | 
				
			||||||
R:	Alexander Shishkin <alexander.shishkin@linux.intel.com>
 | 
					R:	Alexander Shishkin <alexander.shishkin@linux.intel.com>
 | 
				
			||||||
 | 
					R:	Jiri Olsa <jolsa@redhat.com>
 | 
				
			||||||
 | 
					R:	Namhyung Kim <namhyung@kernel.org>
 | 
				
			||||||
L:	linux-kernel@vger.kernel.org
 | 
					L:	linux-kernel@vger.kernel.org
 | 
				
			||||||
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
 | 
					T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile
									
									
									
									
									
								
							| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
VERSION = 4
 | 
					VERSION = 4
 | 
				
			||||||
PATCHLEVEL = 14
 | 
					PATCHLEVEL = 14
 | 
				
			||||||
SUBLEVEL = 0
 | 
					SUBLEVEL = 0
 | 
				
			||||||
EXTRAVERSION = -rc5
 | 
					EXTRAVERSION = -rc7
 | 
				
			||||||
NAME = Fearless Coyote
 | 
					NAME = Fearless Coyote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# *DOCUMENTATION*
 | 
					# *DOCUMENTATION*
 | 
				
			||||||
| 
						 | 
					@ -130,8 +130,8 @@ endif
 | 
				
			||||||
ifneq ($(KBUILD_OUTPUT),)
 | 
					ifneq ($(KBUILD_OUTPUT),)
 | 
				
			||||||
# check that the output directory actually exists
 | 
					# check that the output directory actually exists
 | 
				
			||||||
saved-output := $(KBUILD_OUTPUT)
 | 
					saved-output := $(KBUILD_OUTPUT)
 | 
				
			||||||
$(shell [ -d $(KBUILD_OUTPUT) ] || mkdir -p $(KBUILD_OUTPUT))
 | 
					KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
 | 
				
			||||||
KBUILD_OUTPUT := $(realpath $(KBUILD_OUTPUT))
 | 
													&& /bin/pwd)
 | 
				
			||||||
$(if $(KBUILD_OUTPUT),, \
 | 
					$(if $(KBUILD_OUTPUT),, \
 | 
				
			||||||
     $(error failed to create output directory "$(saved-output)"))
 | 
					     $(error failed to create output directory "$(saved-output)"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -697,11 +697,11 @@ KBUILD_CFLAGS += $(stackp-flag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(cc-name),clang)
 | 
					ifeq ($(cc-name),clang)
 | 
				
			||||||
ifneq ($(CROSS_COMPILE),)
 | 
					ifneq ($(CROSS_COMPILE),)
 | 
				
			||||||
CLANG_TARGET	:= -target $(notdir $(CROSS_COMPILE:%-=%))
 | 
					CLANG_TARGET	:= --target=$(notdir $(CROSS_COMPILE:%-=%))
 | 
				
			||||||
GCC_TOOLCHAIN	:= $(realpath $(dir $(shell which $(LD)))/..)
 | 
					GCC_TOOLCHAIN	:= $(realpath $(dir $(shell which $(LD)))/..)
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
ifneq ($(GCC_TOOLCHAIN),)
 | 
					ifneq ($(GCC_TOOLCHAIN),)
 | 
				
			||||||
CLANG_GCC_TC	:= -gcc-toolchain $(GCC_TOOLCHAIN)
 | 
					CLANG_GCC_TC	:= --gcc-toolchain=$(GCC_TOOLCHAIN)
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 | 
					KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 | 
				
			||||||
KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 | 
					KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 | 
				
			||||||
| 
						 | 
					@ -1399,7 +1399,7 @@ help:
 | 
				
			||||||
	@echo  '                    Build, install, and boot kernel before'
 | 
						@echo  '                    Build, install, and boot kernel before'
 | 
				
			||||||
	@echo  '                    running kselftest on it'
 | 
						@echo  '                    running kselftest on it'
 | 
				
			||||||
	@echo  '  kselftest-clean - Remove all generated kselftest files'
 | 
						@echo  '  kselftest-clean - Remove all generated kselftest files'
 | 
				
			||||||
	@echo  '  kselftest-merge - Merge all the config dependencies of kselftest to existed'
 | 
						@echo  '  kselftest-merge - Merge all the config dependencies of kselftest to existing'
 | 
				
			||||||
	@echo  '                    .config.'
 | 
						@echo  '                    .config.'
 | 
				
			||||||
	@echo  ''
 | 
						@echo  ''
 | 
				
			||||||
	@echo 'Userspace tools targets:'
 | 
						@echo 'Userspace tools targets:'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,10 +181,10 @@ alcor_init_irq(void)
 | 
				
			||||||
 * comes in on.  This makes interrupt processing much easier.
 | 
					 * comes in on.  This makes interrupt processing much easier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[7][5] __initdata = {
 | 
						static char irq_tab[7][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		/* note: IDSEL 17 is XLT only */
 | 
							/* note: IDSEL 17 is XLT only */
 | 
				
			||||||
		{16+13, 16+13, 16+13, 16+13, 16+13},	/* IdSel 17,  TULIP  */
 | 
							{16+13, 16+13, 16+13, 16+13, 16+13},	/* IdSel 17,  TULIP  */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,10 +173,10 @@ pc164_init_irq(void)
 | 
				
			||||||
 * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
 | 
					 * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int __init
 | 
					static inline int
 | 
				
			||||||
eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[5][5] __initdata = {
 | 
						static char irq_tab[5][5] = {
 | 
				
			||||||
		/*INT  INTA  INTB  INTC   INTD */
 | 
							/*INT  INTA  INTB  INTC   INTD */
 | 
				
			||||||
		{16+0, 16+0, 16+5,  16+9, 16+13},  /* IdSel 6,  slot 0, J25 */
 | 
							{16+0, 16+0, 16+5,  16+9, 16+13},  /* IdSel 6,  slot 0, J25 */
 | 
				
			||||||
		{16+1, 16+1, 16+6, 16+10, 16+14},  /* IdSel 7,  slot 1, J26 */
 | 
							{16+1, 16+1, 16+6, 16+10, 16+14},  /* IdSel 7,  slot 1, J26 */
 | 
				
			||||||
| 
						 | 
					@ -203,10 +203,10 @@ eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
 * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
 | 
					 * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int __init
 | 
					static inline int
 | 
				
			||||||
cabriolet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					cabriolet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[5][5] __initdata = {
 | 
						static char irq_tab[5][5] = {
 | 
				
			||||||
		/*INT   INTA  INTB  INTC   INTD */
 | 
							/*INT   INTA  INTB  INTC   INTD */
 | 
				
			||||||
		{ 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5,  slot 2, J21 */
 | 
							{ 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5,  slot 2, J21 */
 | 
				
			||||||
		{ 16+0, 16+0, 16+5,  16+9, 16+13}, /* IdSel 6,  slot 0, J19 */
 | 
							{ 16+0, 16+0, 16+5,  16+9, 16+13}, /* IdSel 6,  slot 0, J19 */
 | 
				
			||||||
| 
						 | 
					@ -287,10 +287,10 @@ cia_cab_init_pci(void)
 | 
				
			||||||
 * 
 | 
					 * 
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int __init
 | 
					static inline int
 | 
				
			||||||
alphapc164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					alphapc164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[7][5] __initdata = {
 | 
						static char irq_tab[7][5] = {
 | 
				
			||||||
		/*INT   INTA  INTB   INTC   INTD */
 | 
							/*INT   INTA  INTB   INTC   INTD */
 | 
				
			||||||
		{ 16+2, 16+2, 16+9,  16+13, 16+17}, /* IdSel  5, slot 2, J20 */
 | 
							{ 16+2, 16+2, 16+9,  16+13, 16+17}, /* IdSel  5, slot 2, J20 */
 | 
				
			||||||
		{ 16+0, 16+0, 16+7,  16+11, 16+15}, /* IdSel  6, slot 0, J29 */
 | 
							{ 16+0, 16+0, 16+7,  16+11, 16+15}, /* IdSel  6, slot 0, J29 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -356,7 +356,7 @@ clipper_init_irq(void)
 | 
				
			||||||
 *  10	 64 bit PCI option slot 3 (not bus 0)
 | 
					 *  10	 64 bit PCI option slot 3 (not bus 0)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
isa_irq_fixup(const struct pci_dev *dev, int irq)
 | 
					isa_irq_fixup(const struct pci_dev *dev, int irq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 irq8;
 | 
						u8 irq8;
 | 
				
			||||||
| 
						 | 
					@ -372,10 +372,10 @@ isa_irq_fixup(const struct pci_dev *dev, int irq)
 | 
				
			||||||
	return irq8 & 0xf;
 | 
						return irq8 & 0xf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[6][5] __initdata = {
 | 
						static char irq_tab[6][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 5 ISA Bridge */
 | 
							{    -1,    -1,    -1,    -1,    -1}, /* IdSel 5 ISA Bridge */
 | 
				
			||||||
		{ 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/
 | 
							{ 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/
 | 
				
			||||||
| 
						 | 
					@ -394,10 +394,10 @@ dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return isa_irq_fixup(dev, irq);
 | 
						return isa_irq_fixup(dev, irq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[13][5] __initdata = {
 | 
						static char irq_tab[13][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{    45,    45,    45,    45,    45}, /* IdSel 3 21143 PCI1 */
 | 
							{    45,    45,    45,    45,    45}, /* IdSel 3 21143 PCI1 */
 | 
				
			||||||
		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 4 unused */
 | 
							{    -1,    -1,    -1,    -1,    -1}, /* IdSel 4 unused */
 | 
				
			||||||
| 
						 | 
					@ -423,7 +423,7 @@ monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 | 
						return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
monet_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					monet_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pci_controller *hose = dev->sysdata;
 | 
						struct pci_controller *hose = dev->sysdata;
 | 
				
			||||||
| 
						 | 
					@ -456,10 +456,10 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
	return slot;
 | 
						return slot;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[13][5] __initdata = {
 | 
						static char irq_tab[13][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 7 ISA Bridge */
 | 
							{    -1,    -1,    -1,    -1,    -1}, /* IdSel 7 ISA Bridge */
 | 
				
			||||||
		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 8 unused */
 | 
							{    -1,    -1,    -1,    -1,    -1}, /* IdSel 8 unused */
 | 
				
			||||||
| 
						 | 
					@ -478,10 +478,10 @@ webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 | 
						return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[7][5] __initdata = {
 | 
						static char irq_tab[7][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{ 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
 | 
							{ 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
 | 
				
			||||||
		{ 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
 | 
							{ 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,10 +167,10 @@ eb64p_init_irq(void)
 | 
				
			||||||
 * comes in on.  This makes interrupt processing much easier.
 | 
					 * comes in on.  This makes interrupt processing much easier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[5][5] __initdata = {
 | 
						static char irq_tab[5][5] = {
 | 
				
			||||||
		/*INT  INTA  INTB  INTC   INTD */
 | 
							/*INT  INTA  INTB  INTC   INTD */
 | 
				
			||||||
		{16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
 | 
							{16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
 | 
				
			||||||
		{16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
 | 
							{16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ eiger_init_irq(void)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 irq_orig;
 | 
						u8 irq_orig;
 | 
				
			||||||
| 
						 | 
					@ -158,7 +158,7 @@ eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return irq_orig - 0x80;
 | 
						return irq_orig - 0x80;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
eiger_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					eiger_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pci_controller *hose = dev->sysdata;
 | 
						struct pci_controller *hose = dev->sysdata;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,10 +149,10 @@ miata_init_irq(void)
 | 
				
			||||||
 * comes in on.  This makes interrupt processing much easier.
 | 
					 * comes in on.  This makes interrupt processing much easier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        static char irq_tab[18][5] __initdata = {
 | 
					        static char irq_tab[18][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142 */
 | 
							{16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142 */
 | 
				
			||||||
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE    */
 | 
							{   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE    */
 | 
				
			||||||
| 
						 | 
					@ -196,7 +196,7 @@ miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return COMMON_TABLE_LOOKUP;
 | 
						return COMMON_TABLE_LOOKUP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
miata_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					miata_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int slot, pin = *pinp;
 | 
						int slot, pin = *pinp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,10 +145,10 @@ mikasa_init_irq(void)
 | 
				
			||||||
 * comes in on.  This makes interrupt processing much easier.
 | 
					 * comes in on.  This makes interrupt processing much easier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[8][5] __initdata = {
 | 
						static char irq_tab[8][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{16+12, 16+12, 16+12, 16+12, 16+12},	/* IdSel 17,  SCSI */
 | 
							{16+12, 16+12, 16+12, 16+12, 16+12},	/* IdSel 17,  SCSI */
 | 
				
			||||||
		{   -1,    -1,    -1,    -1,    -1},	/* IdSel 18,  PCEB */
 | 
							{   -1,    -1,    -1,    -1,    -1},	/* IdSel 18,  PCEB */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ nautilus_init_irq(void)
 | 
				
			||||||
	common_init_isa_dma();
 | 
						common_init_isa_dma();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Preserve the IRQ set up by the console.  */
 | 
						/* Preserve the IRQ set up by the console.  */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,10 +193,10 @@ noritake_init_irq(void)
 | 
				
			||||||
 * comes in on.  This makes interrupt processing much easier.
 | 
					 * comes in on.  This makes interrupt processing much easier.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[15][5] __initdata = {
 | 
						static char irq_tab[15][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		/* note: IDSELs 16, 17, and 25 are CORELLE only */
 | 
							/* note: IDSELs 16, 17, and 25 are CORELLE only */
 | 
				
			||||||
		{ 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
 | 
							{ 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
 | 
				
			||||||
| 
						 | 
					@ -221,7 +221,7 @@ noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return COMMON_TABLE_LOOKUP;
 | 
						return COMMON_TABLE_LOOKUP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
noritake_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					noritake_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int slot, pin = *pinp;
 | 
						int slot, pin = *pinp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -221,10 +221,10 @@ rawhide_init_irq(void)
 | 
				
			||||||
 * 
 | 
					 * 
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[5][5] __initdata = {
 | 
						static char irq_tab[5][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{ 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
 | 
							{ 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
 | 
				
			||||||
		{ 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
 | 
							{ 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,10 +117,10 @@ ruffian_kill_arch (int mode)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        static char irq_tab[11][5] __initdata = {
 | 
					        static char irq_tab[11][5] = {
 | 
				
			||||||
	      /*INT  INTA INTB INTC INTD */
 | 
						      /*INT  INTA INTB INTC INTD */
 | 
				
			||||||
		{-1,  -1,  -1,  -1,  -1},  /* IdSel 13,  21052	     */
 | 
							{-1,  -1,  -1,  -1,  -1},  /* IdSel 13,  21052	     */
 | 
				
			||||||
		{-1,  -1,  -1,  -1,  -1},  /* IdSel 14,  SIO	     */
 | 
							{-1,  -1,  -1,  -1,  -1},  /* IdSel 14,  SIO	     */
 | 
				
			||||||
| 
						 | 
					@ -139,7 +139,7 @@ ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return COMMON_TABLE_LOOKUP;
 | 
						return COMMON_TABLE_LOOKUP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
ruffian_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					ruffian_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int slot, pin = *pinp;
 | 
						int slot, pin = *pinp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +142,7 @@ rx164_init_irq(void)
 | 
				
			||||||
 * 
 | 
					 * 
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
| 
						 | 
					@ -156,7 +156,7 @@ rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	  { 16+1, 16+1, 16+6, 16+11, 16+16},      /* IdSel 10, slot 4 */
 | 
						  { 16+1, 16+1, 16+6, 16+11, 16+16},      /* IdSel 10, slot 4 */
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	static char irq_tab[6][5] __initdata = {
 | 
						static char irq_tab[6][5] = {
 | 
				
			||||||
	  /*INT   INTA  INTB  INTC   INTD */
 | 
						  /*INT   INTA  INTB  INTC   INTD */
 | 
				
			||||||
	  { 16+0, 16+0, 16+6, 16+11, 16+16},      /* IdSel 5,  slot 0 */
 | 
						  { 16+0, 16+0, 16+6, 16+11, 16+16},      /* IdSel 5,  slot 0 */
 | 
				
			||||||
	  { 16+1, 16+1, 16+7, 16+12, 16+17},      /* IdSel 6,  slot 1 */
 | 
						  { 16+1, 16+1, 16+7, 16+12, 16+17},      /* IdSel 6,  slot 1 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,10 +192,10 @@ sable_init_irq(void)
 | 
				
			||||||
 * with the values in the irq swizzling tables above.
 | 
					 * with the values in the irq swizzling tables above.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[9][5] __initdata = {
 | 
						static char irq_tab[9][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{ 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
 | 
							{ 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
 | 
				
			||||||
		{ 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
 | 
							{ 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
 | 
				
			||||||
| 
						 | 
					@ -374,10 +374,10 @@ lynx_init_irq(void)
 | 
				
			||||||
 * with the values in the irq swizzling tables above.
 | 
					 * with the values in the irq swizzling tables above.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[19][5] __initdata = {
 | 
						static char irq_tab[19][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 13,  PCEB   */
 | 
							{   -1,    -1,    -1,    -1,    -1},  /* IdSel 13,  PCEB   */
 | 
				
			||||||
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 14,  PPB    */
 | 
							{   -1,    -1,    -1,    -1,    -1},  /* IdSel 14,  PPB    */
 | 
				
			||||||
| 
						 | 
					@ -404,7 +404,7 @@ lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return COMMON_TABLE_LOOKUP;
 | 
						return COMMON_TABLE_LOOKUP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
lynx_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					lynx_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int slot, pin = *pinp;
 | 
						int slot, pin = *pinp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +144,7 @@ sio_fixup_irq_levels(unsigned int level_bits)
 | 
				
			||||||
	outb((level_bits >> 8) & 0xff, 0x4d1);
 | 
						outb((level_bits >> 8) & 0xff, 0x4d1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int __init
 | 
					static inline int
 | 
				
			||||||
noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -165,7 +165,7 @@ noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	 * that they use the default INTA line, if they are interrupt
 | 
						 * that they use the default INTA line, if they are interrupt
 | 
				
			||||||
	 * driven at all).
 | 
						 * driven at all).
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	static char irq_tab[][5] __initdata = {
 | 
						static char irq_tab[][5] = {
 | 
				
			||||||
		/*INT A   B   C   D */
 | 
							/*INT A   B   C   D */
 | 
				
			||||||
		{ 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */ 
 | 
							{ 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */ 
 | 
				
			||||||
		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
 | 
							{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
 | 
				
			||||||
| 
						 | 
					@ -183,10 +183,10 @@ noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return irq >= 0 ? tmp : -1;
 | 
						return irq >= 0 ? tmp : -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int __init
 | 
					static inline int
 | 
				
			||||||
p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[][5] __initdata = {
 | 
						static char irq_tab[][5] = {
 | 
				
			||||||
		/*INT A   B   C   D */
 | 
							/*INT A   B   C   D */
 | 
				
			||||||
		{ 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
 | 
							{ 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
 | 
				
			||||||
		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
 | 
							{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,10 +94,10 @@ sx164_init_irq(void)
 | 
				
			||||||
 *   9  32 bit PCI option slot 3
 | 
					 *   9  32 bit PCI option slot 3
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[5][5] __initdata = {
 | 
						static char irq_tab[5][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{ 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
 | 
							{ 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
 | 
				
			||||||
		{ 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
 | 
							{ 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,10 +155,10 @@ takara_init_irq(void)
 | 
				
			||||||
 * assign it whatever the hell IRQ we like and it doesn't matter.
 | 
					 * assign it whatever the hell IRQ we like and it doesn't matter.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[15][5] __initdata = {
 | 
						static char irq_tab[15][5] = {
 | 
				
			||||||
		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
 | 
							{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
 | 
				
			||||||
		{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
 | 
							{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
 | 
				
			||||||
		{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
 | 
							{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
 | 
				
			||||||
| 
						 | 
					@ -210,7 +210,7 @@ takara_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
	return COMMON_TABLE_LOOKUP;
 | 
						return COMMON_TABLE_LOOKUP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u8 __init
 | 
					static u8
 | 
				
			||||||
takara_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
					takara_swizzle(struct pci_dev *dev, u8 *pinp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int slot = PCI_SLOT(dev->devfn);
 | 
						int slot = PCI_SLOT(dev->devfn);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -288,10 +288,10 @@ wildfire_device_interrupt(unsigned long vector)
 | 
				
			||||||
 *   7	 64 bit PCI 1 option slot 7
 | 
					 *   7	 64 bit PCI 1 option slot 7
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init
 | 
					static int
 | 
				
			||||||
wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
					wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char irq_tab[8][5] __initdata = {
 | 
						static char irq_tab[8][5] = {
 | 
				
			||||||
		/*INT    INTA   INTB   INTC   INTD */
 | 
							/*INT    INTA   INTB   INTC   INTD */
 | 
				
			||||||
		{ -1,    -1,    -1,    -1,    -1}, /* IdSel 0 ISA Bridge */
 | 
							{ -1,    -1,    -1,    -1,    -1}, /* IdSel 0 ISA Bridge */
 | 
				
			||||||
		{ 36,    36,    36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
 | 
							{ 36,    36,    36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,14 +137,15 @@ mmcclk_ciu: mmcclk-ciu {
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * DW sdio controller has external ciu clock divider
 | 
								 * DW sdio controller has external ciu clock divider
 | 
				
			||||||
			 * controlled via register in SDIO IP. Due to its
 | 
								 * controlled via register in SDIO IP. Due to its
 | 
				
			||||||
			 * unexpected default value (it should devide by 1
 | 
								 * unexpected default value (it should divide by 1
 | 
				
			||||||
			 * but it devides by 8) SDIO IP uses wrong clock and
 | 
								 * but it divides by 8) SDIO IP uses wrong clock and
 | 
				
			||||||
			 * works unstable (see STAR 9001204800)
 | 
								 * works unstable (see STAR 9001204800)
 | 
				
			||||||
 | 
								 * We switched to the minimum possible value of the
 | 
				
			||||||
 | 
								 * divisor (div-by-2) in HSDK platform code.
 | 
				
			||||||
			 * So add temporary fix and change clock frequency
 | 
								 * So add temporary fix and change clock frequency
 | 
				
			||||||
			 * from 100000000 to 12500000 Hz until we fix dw sdio
 | 
								 * to 50000000 Hz until we fix dw sdio driver itself.
 | 
				
			||||||
			 * driver itself.
 | 
					 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			clock-frequency = <12500000>;
 | 
								clock-frequency = <50000000>;
 | 
				
			||||||
			#clock-cells = <0>;
 | 
								#clock-cells = <0>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,6 @@ CONFIG_MMC_SDHCI=y
 | 
				
			||||||
CONFIG_MMC_SDHCI_PLTFM=y
 | 
					CONFIG_MMC_SDHCI_PLTFM=y
 | 
				
			||||||
CONFIG_MMC_DW=y
 | 
					CONFIG_MMC_DW=y
 | 
				
			||||||
# CONFIG_IOMMU_SUPPORT is not set
 | 
					# CONFIG_IOMMU_SUPPORT is not set
 | 
				
			||||||
CONFIG_RESET_HSDK=y
 | 
					 | 
				
			||||||
CONFIG_EXT3_FS=y
 | 
					CONFIG_EXT3_FS=y
 | 
				
			||||||
CONFIG_VFAT_FS=y
 | 
					CONFIG_VFAT_FS=y
 | 
				
			||||||
CONFIG_TMPFS=y
 | 
					CONFIG_TMPFS=y
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,8 @@
 | 
				
			||||||
#include <linux/cpumask.h>
 | 
					#include <linux/cpumask.h>
 | 
				
			||||||
#include <linux/reboot.h>
 | 
					#include <linux/reboot.h>
 | 
				
			||||||
#include <linux/irqdomain.h>
 | 
					#include <linux/irqdomain.h>
 | 
				
			||||||
 | 
					#include <linux/export.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/processor.h>
 | 
					#include <asm/processor.h>
 | 
				
			||||||
#include <asm/setup.h>
 | 
					#include <asm/setup.h>
 | 
				
			||||||
#include <asm/mach_desc.h>
 | 
					#include <asm/mach_desc.h>
 | 
				
			||||||
| 
						 | 
					@ -30,6 +32,9 @@
 | 
				
			||||||
#ifndef CONFIG_ARC_HAS_LLSC
 | 
					#ifndef CONFIG_ARC_HAS_LLSC
 | 
				
			||||||
arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 | 
					arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 | 
				
			||||||
arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 | 
					arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(smp_atomic_ops_lock);
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(smp_bitops_lock);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct plat_smp_ops  __weak plat_smp_ops;
 | 
					struct plat_smp_ops  __weak plat_smp_ops;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,3 +8,4 @@
 | 
				
			||||||
menuconfig ARC_SOC_HSDK
 | 
					menuconfig ARC_SOC_HSDK
 | 
				
			||||||
	bool "ARC HS Development Kit SOC"
 | 
						bool "ARC HS Development Kit SOC"
 | 
				
			||||||
	select CLK_HSDK
 | 
						select CLK_HSDK
 | 
				
			||||||
 | 
						select RESET_HSDK
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,10 @@ static void __init hsdk_set_cpu_freq_1ghz(void)
 | 
				
			||||||
		pr_err("Failed to setup CPU frequency to 1GHz!");
 | 
							pr_err("Failed to setup CPU frequency to 1GHz!");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SDIO_BASE		(ARC_PERIPHERAL_BASE + 0xA000)
 | 
				
			||||||
 | 
					#define SDIO_UHS_REG_EXT	(SDIO_BASE + 0x108)
 | 
				
			||||||
 | 
					#define SDIO_UHS_REG_EXT_DIV_2	(2 << 30)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init hsdk_init_early(void)
 | 
					static void __init hsdk_init_early(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -89,6 +93,12 @@ static void __init hsdk_init_early(void)
 | 
				
			||||||
	/* Really apply settings made above */
 | 
						/* Really apply settings made above */
 | 
				
			||||||
	writel(1, (void __iomem *) CREG_PAE_UPDATE);
 | 
						writel(1, (void __iomem *) CREG_PAE_UPDATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Switch SDIO external ciu clock divider from default div-by-8 to
 | 
				
			||||||
 | 
						 * minimum possible div-by-2.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Setup CPU frequency to 1GHz.
 | 
						 * Setup CPU frequency to 1GHz.
 | 
				
			||||||
	 * TODO: remove it after smart hsdk pll driver will be introduced.
 | 
						 * TODO: remove it after smart hsdk pll driver will be introduced.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
#include <linux/bootmem.h>
 | 
					#include <linux/bootmem.h>
 | 
				
			||||||
#include <linux/gfp.h>
 | 
					#include <linux/gfp.h>
 | 
				
			||||||
#include <linux/export.h>
 | 
					#include <linux/export.h>
 | 
				
			||||||
#include <linux/rwlock.h>
 | 
					#include <linux/spinlock.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <linux/dma-mapping.h>
 | 
					#include <linux/dma-mapping.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -478,28 +478,30 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dir = iommu_tce_direction(tce);
 | 
						dir = iommu_tce_direction(tce);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						idx = srcu_read_lock(&vcpu->kvm->srcu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
 | 
						if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm,
 | 
				
			||||||
			tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL))
 | 
								tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL)) {
 | 
				
			||||||
		return H_PARAMETER;
 | 
							ret = H_PARAMETER;
 | 
				
			||||||
 | 
							goto unlock_exit;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	entry = ioba >> stt->page_shift;
 | 
						entry = ioba >> stt->page_shift;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
 | 
						list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
 | 
				
			||||||
		if (dir == DMA_NONE) {
 | 
							if (dir == DMA_NONE)
 | 
				
			||||||
			ret = kvmppc_tce_iommu_unmap(vcpu->kvm,
 | 
								ret = kvmppc_tce_iommu_unmap(vcpu->kvm,
 | 
				
			||||||
					stit->tbl, entry);
 | 
										stit->tbl, entry);
 | 
				
			||||||
		} else {
 | 
							else
 | 
				
			||||||
			idx = srcu_read_lock(&vcpu->kvm->srcu);
 | 
					 | 
				
			||||||
			ret = kvmppc_tce_iommu_map(vcpu->kvm, stit->tbl,
 | 
								ret = kvmppc_tce_iommu_map(vcpu->kvm, stit->tbl,
 | 
				
			||||||
					entry, ua, dir);
 | 
										entry, ua, dir);
 | 
				
			||||||
			srcu_read_unlock(&vcpu->kvm->srcu, idx);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ret == H_SUCCESS)
 | 
							if (ret == H_SUCCESS)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ret == H_TOO_HARD)
 | 
							if (ret == H_TOO_HARD)
 | 
				
			||||||
			return ret;
 | 
								goto unlock_exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		WARN_ON_ONCE(1);
 | 
							WARN_ON_ONCE(1);
 | 
				
			||||||
		kvmppc_clear_tce(stit->tbl, entry);
 | 
							kvmppc_clear_tce(stit->tbl, entry);
 | 
				
			||||||
| 
						 | 
					@ -507,7 +509,10 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kvmppc_tce_put(stt, entry, tce);
 | 
						kvmppc_tce_put(stt, entry, tce);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return H_SUCCESS;
 | 
					unlock_exit:
 | 
				
			||||||
 | 
						srcu_read_unlock(&vcpu->kvm->srcu, idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
 | 
					EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -989,13 +989,14 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
 | 
				
			||||||
	beq	no_xive
 | 
						beq	no_xive
 | 
				
			||||||
	ld	r11, VCPU_XIVE_SAVED_STATE(r4)
 | 
						ld	r11, VCPU_XIVE_SAVED_STATE(r4)
 | 
				
			||||||
	li	r9, TM_QW1_OS
 | 
						li	r9, TM_QW1_OS
 | 
				
			||||||
	stdcix	r11,r9,r10
 | 
					 | 
				
			||||||
	eieio
 | 
						eieio
 | 
				
			||||||
 | 
						stdcix	r11,r9,r10
 | 
				
			||||||
	lwz	r11, VCPU_XIVE_CAM_WORD(r4)
 | 
						lwz	r11, VCPU_XIVE_CAM_WORD(r4)
 | 
				
			||||||
	li	r9, TM_QW1_OS + TM_WORD2
 | 
						li	r9, TM_QW1_OS + TM_WORD2
 | 
				
			||||||
	stwcix	r11,r9,r10
 | 
						stwcix	r11,r9,r10
 | 
				
			||||||
	li	r9, 1
 | 
						li	r9, 1
 | 
				
			||||||
	stw	r9, VCPU_XIVE_PUSHED(r4)
 | 
						stw	r9, VCPU_XIVE_PUSHED(r4)
 | 
				
			||||||
 | 
						eieio
 | 
				
			||||||
no_xive:
 | 
					no_xive:
 | 
				
			||||||
#endif /* CONFIG_KVM_XICS */
 | 
					#endif /* CONFIG_KVM_XICS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1310,6 +1311,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 | 
				
			||||||
	bne	3f
 | 
						bne	3f
 | 
				
			||||||
BEGIN_FTR_SECTION
 | 
					BEGIN_FTR_SECTION
 | 
				
			||||||
	PPC_MSGSYNC
 | 
						PPC_MSGSYNC
 | 
				
			||||||
 | 
						lwsync
 | 
				
			||||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 | 
					END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 | 
				
			||||||
	lbz	r0, HSTATE_HOST_IPI(r13)
 | 
						lbz	r0, HSTATE_HOST_IPI(r13)
 | 
				
			||||||
	cmpwi	r0, 0
 | 
						cmpwi	r0, 0
 | 
				
			||||||
| 
						 | 
					@ -1400,8 +1402,8 @@ guest_exit_cont:		/* r9 = vcpu, r12 = trap, r13 = paca */
 | 
				
			||||||
	cmpldi	cr0, r10, 0
 | 
						cmpldi	cr0, r10, 0
 | 
				
			||||||
	beq	1f
 | 
						beq	1f
 | 
				
			||||||
	/* First load to pull the context, we ignore the value */
 | 
						/* First load to pull the context, we ignore the value */
 | 
				
			||||||
	lwzx	r11, r7, r10
 | 
					 | 
				
			||||||
	eieio
 | 
						eieio
 | 
				
			||||||
 | 
						lwzx	r11, r7, r10
 | 
				
			||||||
	/* Second load to recover the context state (Words 0 and 1) */
 | 
						/* Second load to recover the context state (Words 0 and 1) */
 | 
				
			||||||
	ldx	r11, r6, r10
 | 
						ldx	r11, r6, r10
 | 
				
			||||||
	b	3f
 | 
						b	3f
 | 
				
			||||||
| 
						 | 
					@ -1409,8 +1411,8 @@ guest_exit_cont:		/* r9 = vcpu, r12 = trap, r13 = paca */
 | 
				
			||||||
	cmpldi	cr0, r10, 0
 | 
						cmpldi	cr0, r10, 0
 | 
				
			||||||
	beq	1f
 | 
						beq	1f
 | 
				
			||||||
	/* First load to pull the context, we ignore the value */
 | 
						/* First load to pull the context, we ignore the value */
 | 
				
			||||||
	lwzcix	r11, r7, r10
 | 
					 | 
				
			||||||
	eieio
 | 
						eieio
 | 
				
			||||||
 | 
						lwzcix	r11, r7, r10
 | 
				
			||||||
	/* Second load to recover the context state (Words 0 and 1) */
 | 
						/* Second load to recover the context state (Words 0 and 1) */
 | 
				
			||||||
	ldcix	r11, r6, r10
 | 
						ldcix	r11, r6, r10
 | 
				
			||||||
3:	std	r11, VCPU_XIVE_SAVED_STATE(r9)
 | 
					3:	std	r11, VCPU_XIVE_SAVED_STATE(r9)
 | 
				
			||||||
| 
						 | 
					@ -1420,6 +1422,7 @@ guest_exit_cont:		/* r9 = vcpu, r12 = trap, r13 = paca */
 | 
				
			||||||
	stw	r10, VCPU_XIVE_PUSHED(r9)
 | 
						stw	r10, VCPU_XIVE_PUSHED(r9)
 | 
				
			||||||
	stb	r10, (VCPU_XIVE_SAVED_STATE+3)(r9)
 | 
						stb	r10, (VCPU_XIVE_SAVED_STATE+3)(r9)
 | 
				
			||||||
	stb	r0, (VCPU_XIVE_SAVED_STATE+4)(r9)
 | 
						stb	r0, (VCPU_XIVE_SAVED_STATE+4)(r9)
 | 
				
			||||||
 | 
						eieio
 | 
				
			||||||
1:
 | 
					1:
 | 
				
			||||||
#endif /* CONFIG_KVM_XICS */
 | 
					#endif /* CONFIG_KVM_XICS */
 | 
				
			||||||
	/* Save more register state  */
 | 
						/* Save more register state  */
 | 
				
			||||||
| 
						 | 
					@ -2788,6 +2791,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 | 
				
			||||||
	PPC_MSGCLR(6)
 | 
						PPC_MSGCLR(6)
 | 
				
			||||||
	/* see if it's a host IPI */
 | 
						/* see if it's a host IPI */
 | 
				
			||||||
	li	r3, 1
 | 
						li	r3, 1
 | 
				
			||||||
 | 
					BEGIN_FTR_SECTION
 | 
				
			||||||
 | 
						PPC_MSGSYNC
 | 
				
			||||||
 | 
						lwsync
 | 
				
			||||||
 | 
					END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 | 
				
			||||||
	lbz	r0, HSTATE_HOST_IPI(r13)
 | 
						lbz	r0, HSTATE_HOST_IPI(r13)
 | 
				
			||||||
	cmpwi	r0, 0
 | 
						cmpwi	r0, 0
 | 
				
			||||||
	bnelr
 | 
						bnelr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -644,8 +644,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	case KVM_CAP_PPC_HTM:
 | 
						case KVM_CAP_PPC_HTM:
 | 
				
			||||||
		r = cpu_has_feature(CPU_FTR_TM_COMP) &&
 | 
							r = cpu_has_feature(CPU_FTR_TM_COMP) && hv_enabled;
 | 
				
			||||||
		    is_kvmppc_hv_enabled(kvm);
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		r = 0;
 | 
							r = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -521,12 +521,15 @@ ENTRY(pgm_check_handler)
 | 
				
			||||||
	tmhh	%r8,0x0001		# test problem state bit
 | 
						tmhh	%r8,0x0001		# test problem state bit
 | 
				
			||||||
	jnz	2f			# -> fault in user space
 | 
						jnz	2f			# -> fault in user space
 | 
				
			||||||
#if IS_ENABLED(CONFIG_KVM)
 | 
					#if IS_ENABLED(CONFIG_KVM)
 | 
				
			||||||
	# cleanup critical section for sie64a
 | 
						# cleanup critical section for program checks in sie64a
 | 
				
			||||||
	lgr	%r14,%r9
 | 
						lgr	%r14,%r9
 | 
				
			||||||
	slg	%r14,BASED(.Lsie_critical_start)
 | 
						slg	%r14,BASED(.Lsie_critical_start)
 | 
				
			||||||
	clg	%r14,BASED(.Lsie_critical_length)
 | 
						clg	%r14,BASED(.Lsie_critical_length)
 | 
				
			||||||
	jhe	0f
 | 
						jhe	0f
 | 
				
			||||||
	brasl	%r14,.Lcleanup_sie
 | 
						lg	%r14,__SF_EMPTY(%r15)		# get control block pointer
 | 
				
			||||||
 | 
						ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
 | 
				
			||||||
 | 
						lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
 | 
				
			||||||
 | 
						larl	%r9,sie_exit			# skip forward to sie_exit
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
0:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
 | 
					0:	tmhh	%r8,0x4000		# PER bit set in old PSW ?
 | 
				
			||||||
	jnz	1f			# -> enabled, can't be a double fault
 | 
						jnz	1f			# -> enabled, can't be a double fault
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -808,7 +808,7 @@ apicinterrupt IRQ_WORK_VECTOR			irq_work_interrupt		smp_irq_work_interrupt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
 | 
					.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
 | 
				
			||||||
ENTRY(\sym)
 | 
					ENTRY(\sym)
 | 
				
			||||||
	UNWIND_HINT_IRET_REGS offset=8
 | 
						UNWIND_HINT_IRET_REGS offset=\has_error_code*8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Sanity check */
 | 
						/* Sanity check */
 | 
				
			||||||
	.if \shift_ist != -1 && \paranoid == 0
 | 
						.if \shift_ist != -1 && \paranoid == 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -546,9 +546,6 @@ static int bts_event_init(struct perf_event *event)
 | 
				
			||||||
	if (event->attr.type != bts_pmu.type)
 | 
						if (event->attr.type != bts_pmu.type)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (x86_add_exclusive(x86_lbr_exclusive_bts))
 | 
					 | 
				
			||||||
		return -EBUSY;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * BTS leaks kernel addresses even when CPL0 tracing is
 | 
						 * BTS leaks kernel addresses even when CPL0 tracing is
 | 
				
			||||||
	 * disabled, so disallow intel_bts driver for unprivileged
 | 
						 * disabled, so disallow intel_bts driver for unprivileged
 | 
				
			||||||
| 
						 | 
					@ -562,6 +559,9 @@ static int bts_event_init(struct perf_event *event)
 | 
				
			||||||
	    !capable(CAP_SYS_ADMIN))
 | 
						    !capable(CAP_SYS_ADMIN))
 | 
				
			||||||
		return -EACCES;
 | 
							return -EACCES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (x86_add_exclusive(x86_lbr_exclusive_bts))
 | 
				
			||||||
 | 
							return -EBUSY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = x86_reserve_hardware();
 | 
						ret = x86_reserve_hardware();
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		x86_del_exclusive(x86_lbr_exclusive_bts);
 | 
							x86_del_exclusive(x86_lbr_exclusive_bts);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,12 +82,21 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
 | 
				
			||||||
#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
 | 
					#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					static inline bool tlb_defer_switch_to_init_mm(void)
 | 
				
			||||||
 * If tlb_use_lazy_mode is true, then we try to avoid switching CR3 to point
 | 
					{
 | 
				
			||||||
 * to init_mm when we switch to a kernel thread (e.g. the idle thread).  If
 | 
						/*
 | 
				
			||||||
 * it's false, then we immediately switch CR3 when entering a kernel thread.
 | 
						 * If we have PCID, then switching to init_mm is reasonably
 | 
				
			||||||
 */
 | 
						 * fast.  If we don't have PCID, then switching to init_mm is
 | 
				
			||||||
DECLARE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
 | 
						 * quite slow, so we try to defer it in the hopes that we can
 | 
				
			||||||
 | 
						 * avoid it entirely.  The latter approach runs the risk of
 | 
				
			||||||
 | 
						 * receiving otherwise unnecessary IPIs.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * This choice is just a heuristic.  The tlb code can handle this
 | 
				
			||||||
 | 
						 * function returning true or false regardless of whether we have
 | 
				
			||||||
 | 
						 * PCID.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						return !static_cpu_has(X86_FEATURE_PCID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * 6 because 6 should be plenty and struct tlb_state will fit in
 | 
					 * 6 because 6 should be plenty and struct tlb_state will fit in
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,8 @@ static const struct pci_device_id amd_root_ids[] = {
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PCI_DEVICE_ID_AMD_CNB17H_F4     0x1704
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct pci_device_id amd_nb_misc_ids[] = {
 | 
					const struct pci_device_id amd_nb_misc_ids[] = {
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 | 
				
			||||||
| 
						 | 
					@ -37,6 +39,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
 | 
				
			||||||
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
EXPORT_SYMBOL_GPL(amd_nb_misc_ids);
 | 
					EXPORT_SYMBOL_GPL(amd_nb_misc_ids);
 | 
				
			||||||
| 
						 | 
					@ -48,6 +51,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
 | 
				
			||||||
	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
 | 
				
			||||||
 | 
						{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,11 +406,48 @@ void amd_flush_garts(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(amd_flush_garts);
 | 
					EXPORT_SYMBOL_GPL(amd_flush_garts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __fix_erratum_688(void *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#define MSR_AMD64_IC_CFG 0xC0011021
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msr_set_bit(MSR_AMD64_IC_CFG, 3);
 | 
				
			||||||
 | 
						msr_set_bit(MSR_AMD64_IC_CFG, 14);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Apply erratum 688 fix so machines without a BIOS fix work. */
 | 
				
			||||||
 | 
					static __init void fix_erratum_688(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pci_dev *F4;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (boot_cpu_data.x86 != 0x14)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!amd_northbridges.num)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						F4 = node_to_amd_nb(0)->link;
 | 
				
			||||||
 | 
						if (!F4)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pci_read_config_dword(F4, 0x164, &val))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (val & BIT(2))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						on_each_cpu(__fix_erratum_688, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static __init int init_amd_nbs(void)
 | 
					static __init int init_amd_nbs(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	amd_cache_northbridges();
 | 
						amd_cache_northbridges();
 | 
				
			||||||
	amd_cache_gart();
 | 
						amd_cache_gart();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fix_erratum_688();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -831,7 +831,6 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
 | 
				
			||||||
	} else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
 | 
						} else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
 | 
				
			||||||
		unsigned int apicid, nshared, first, last;
 | 
							unsigned int apicid, nshared, first, last;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this_leaf = this_cpu_ci->info_list + index;
 | 
					 | 
				
			||||||
		nshared = base->eax.split.num_threads_sharing + 1;
 | 
							nshared = base->eax.split.num_threads_sharing + 1;
 | 
				
			||||||
		apicid = cpu_data(cpu).apicid;
 | 
							apicid = cpu_data(cpu).apicid;
 | 
				
			||||||
		first = apicid - (apicid % nshared);
 | 
							first = apicid - (apicid % nshared);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
#include <linux/mm.h>
 | 
					#include <linux/mm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/microcode_intel.h>
 | 
					#include <asm/microcode_intel.h>
 | 
				
			||||||
 | 
					#include <asm/intel-family.h>
 | 
				
			||||||
#include <asm/processor.h>
 | 
					#include <asm/processor.h>
 | 
				
			||||||
#include <asm/tlbflush.h>
 | 
					#include <asm/tlbflush.h>
 | 
				
			||||||
#include <asm/setup.h>
 | 
					#include <asm/setup.h>
 | 
				
			||||||
| 
						 | 
					@ -918,6 +919,18 @@ static int get_ucode_fw(void *to, const void *from, size_t n)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool is_blacklisted(unsigned int cpu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cpuinfo_x86 *c = &cpu_data(cpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) {
 | 
				
			||||||
 | 
							pr_err_once("late loading on model 79 is disabled.\n");
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static enum ucode_state request_microcode_fw(int cpu, struct device *device,
 | 
					static enum ucode_state request_microcode_fw(int cpu, struct device *device,
 | 
				
			||||||
					     bool refresh_fw)
 | 
										     bool refresh_fw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -926,6 +939,9 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
 | 
				
			||||||
	const struct firmware *firmware;
 | 
						const struct firmware *firmware;
 | 
				
			||||||
	enum ucode_state ret;
 | 
						enum ucode_state ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (is_blacklisted(cpu))
 | 
				
			||||||
 | 
							return UCODE_NFOUND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sprintf(name, "intel-ucode/%02x-%02x-%02x",
 | 
						sprintf(name, "intel-ucode/%02x-%02x-%02x",
 | 
				
			||||||
		c->x86, c->x86_model, c->x86_mask);
 | 
							c->x86, c->x86_model, c->x86_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -950,6 +966,9 @@ static int get_ucode_user(void *to, const void *from, size_t n)
 | 
				
			||||||
static enum ucode_state
 | 
					static enum ucode_state
 | 
				
			||||||
request_microcode_user(int cpu, const void __user *buf, size_t size)
 | 
					request_microcode_user(int cpu, const void __user *buf, size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (is_blacklisted(cpu))
 | 
				
			||||||
 | 
							return UCODE_NFOUND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
 | 
						return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,10 +30,11 @@ static void __init i386_default_early_setup(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asmlinkage __visible void __init i386_start_kernel(void)
 | 
					asmlinkage __visible void __init i386_start_kernel(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cr4_init_shadow();
 | 
						/* Make sure IDT is set up before any exception happens */
 | 
				
			||||||
 | 
					 | 
				
			||||||
	idt_setup_early_handler();
 | 
						idt_setup_early_handler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cr4_init_shadow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sanitize_boot_params(&boot_params);
 | 
						sanitize_boot_params(&boot_params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	x86_early_init_platform_quirks();
 | 
						x86_early_init_platform_quirks();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,8 +86,8 @@ static struct orc_entry *orc_find(unsigned long ip)
 | 
				
			||||||
		idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
 | 
							idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (unlikely((idx >= lookup_num_blocks-1))) {
 | 
							if (unlikely((idx >= lookup_num_blocks-1))) {
 | 
				
			||||||
			orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%lx\n",
 | 
								orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n",
 | 
				
			||||||
				 idx, lookup_num_blocks, ip);
 | 
									 idx, lookup_num_blocks, (void *)ip);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,8 +96,8 @@ static struct orc_entry *orc_find(unsigned long ip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
 | 
							if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
 | 
				
			||||||
			     (__start_orc_unwind + stop > __stop_orc_unwind))) {
 | 
								     (__start_orc_unwind + stop > __stop_orc_unwind))) {
 | 
				
			||||||
			orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%lx\n",
 | 
								orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n",
 | 
				
			||||||
				 idx, lookup_num_blocks, start, stop, ip);
 | 
									 idx, lookup_num_blocks, start, stop, (void *)ip);
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -373,7 +373,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_REG_R10:
 | 
						case ORC_REG_R10:
 | 
				
			||||||
		if (!state->regs || !state->full_regs) {
 | 
							if (!state->regs || !state->full_regs) {
 | 
				
			||||||
			orc_warn("missing regs for base reg R10 at ip %p\n",
 | 
								orc_warn("missing regs for base reg R10 at ip %pB\n",
 | 
				
			||||||
				 (void *)state->ip);
 | 
									 (void *)state->ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -382,7 +382,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_REG_R13:
 | 
						case ORC_REG_R13:
 | 
				
			||||||
		if (!state->regs || !state->full_regs) {
 | 
							if (!state->regs || !state->full_regs) {
 | 
				
			||||||
			orc_warn("missing regs for base reg R13 at ip %p\n",
 | 
								orc_warn("missing regs for base reg R13 at ip %pB\n",
 | 
				
			||||||
				 (void *)state->ip);
 | 
									 (void *)state->ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -391,7 +391,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_REG_DI:
 | 
						case ORC_REG_DI:
 | 
				
			||||||
		if (!state->regs || !state->full_regs) {
 | 
							if (!state->regs || !state->full_regs) {
 | 
				
			||||||
			orc_warn("missing regs for base reg DI at ip %p\n",
 | 
								orc_warn("missing regs for base reg DI at ip %pB\n",
 | 
				
			||||||
				 (void *)state->ip);
 | 
									 (void *)state->ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -400,7 +400,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_REG_DX:
 | 
						case ORC_REG_DX:
 | 
				
			||||||
		if (!state->regs || !state->full_regs) {
 | 
							if (!state->regs || !state->full_regs) {
 | 
				
			||||||
			orc_warn("missing regs for base reg DX at ip %p\n",
 | 
								orc_warn("missing regs for base reg DX at ip %pB\n",
 | 
				
			||||||
				 (void *)state->ip);
 | 
									 (void *)state->ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -408,7 +408,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		orc_warn("unknown SP base reg %d for ip %p\n",
 | 
							orc_warn("unknown SP base reg %d for ip %pB\n",
 | 
				
			||||||
			 orc->sp_reg, (void *)state->ip);
 | 
								 orc->sp_reg, (void *)state->ip);
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -436,7 +436,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_TYPE_REGS:
 | 
						case ORC_TYPE_REGS:
 | 
				
			||||||
		if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) {
 | 
							if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) {
 | 
				
			||||||
			orc_warn("can't dereference registers at %p for ip %p\n",
 | 
								orc_warn("can't dereference registers at %p for ip %pB\n",
 | 
				
			||||||
				 (void *)sp, (void *)orig_ip);
 | 
									 (void *)sp, (void *)orig_ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -448,7 +448,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case ORC_TYPE_REGS_IRET:
 | 
						case ORC_TYPE_REGS_IRET:
 | 
				
			||||||
		if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) {
 | 
							if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) {
 | 
				
			||||||
			orc_warn("can't dereference iret registers at %p for ip %p\n",
 | 
								orc_warn("can't dereference iret registers at %p for ip %pB\n",
 | 
				
			||||||
				 (void *)sp, (void *)orig_ip);
 | 
									 (void *)sp, (void *)orig_ip);
 | 
				
			||||||
			goto done;
 | 
								goto done;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -465,7 +465,8 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		orc_warn("unknown .orc_unwind entry type %d\n", orc->type);
 | 
							orc_warn("unknown .orc_unwind entry type %d for ip %pB\n",
 | 
				
			||||||
 | 
								 orc->type, (void *)orig_ip);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -487,7 +488,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		orc_warn("unknown BP base reg %d for ip %p\n",
 | 
							orc_warn("unknown BP base reg %d for ip %pB\n",
 | 
				
			||||||
			 orc->bp_reg, (void *)orig_ip);
 | 
								 orc->bp_reg, (void *)orig_ip);
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -496,7 +497,7 @@ bool unwind_next_frame(struct unwind_state *state)
 | 
				
			||||||
	if (state->stack_info.type == prev_type &&
 | 
						if (state->stack_info.type == prev_type &&
 | 
				
			||||||
	    on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
 | 
						    on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
 | 
				
			||||||
	    state->sp <= prev_sp) {
 | 
						    state->sp <= prev_sp) {
 | 
				
			||||||
		orc_warn("stack going in the wrong direction? ip=%p\n",
 | 
							orc_warn("stack going in the wrong direction? ip=%pB\n",
 | 
				
			||||||
			 (void *)orig_ip);
 | 
								 (void *)orig_ip);
 | 
				
			||||||
		goto done;
 | 
							goto done;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
 | 
					atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFINE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 | 
					static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
 | 
				
			||||||
			    u16 *new_asid, bool *need_flush)
 | 
								    u16 *new_asid, bool *need_flush)
 | 
				
			||||||
| 
						 | 
					@ -147,8 +146,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 | 
				
			||||||
	this_cpu_write(cpu_tlbstate.is_lazy, false);
 | 
						this_cpu_write(cpu_tlbstate.is_lazy, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (real_prev == next) {
 | 
						if (real_prev == next) {
 | 
				
			||||||
		VM_BUG_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
 | 
							VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
 | 
				
			||||||
			  next->context.ctx_id);
 | 
								   next->context.ctx_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * We don't currently support having a real mm loaded without
 | 
							 * We don't currently support having a real mm loaded without
 | 
				
			||||||
| 
						 | 
					@ -213,6 +212,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
					 * Please ignore the name of this function.  It should be called
 | 
				
			||||||
 | 
					 * switch_to_kernel_thread().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * enter_lazy_tlb() is a hint from the scheduler that we are entering a
 | 
					 * enter_lazy_tlb() is a hint from the scheduler that we are entering a
 | 
				
			||||||
 * kernel thread or other context without an mm.  Acceptable implementations
 | 
					 * kernel thread or other context without an mm.  Acceptable implementations
 | 
				
			||||||
 * include doing nothing whatsoever, switching to init_mm, or various clever
 | 
					 * include doing nothing whatsoever, switching to init_mm, or various clever
 | 
				
			||||||
| 
						 | 
					@ -227,7 +229,7 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 | 
				
			||||||
	if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
 | 
						if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (static_branch_unlikely(&tlb_use_lazy_mode)) {
 | 
						if (tlb_defer_switch_to_init_mm()) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * There's a significant optimization that may be possible
 | 
							 * There's a significant optimization that may be possible
 | 
				
			||||||
		 * here.  We have accurate enough TLB flush tracking that we
 | 
							 * here.  We have accurate enough TLB flush tracking that we
 | 
				
			||||||
| 
						 | 
					@ -626,57 +628,3 @@ static int __init create_tlb_single_page_flush_ceiling(void)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
late_initcall(create_tlb_single_page_flush_ceiling);
 | 
					late_initcall(create_tlb_single_page_flush_ceiling);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static ssize_t tlblazy_read_file(struct file *file, char __user *user_buf,
 | 
					 | 
				
			||||||
				 size_t count, loff_t *ppos)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	char buf[2];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buf[0] = static_branch_likely(&tlb_use_lazy_mode) ? '1' : '0';
 | 
					 | 
				
			||||||
	buf[1] = '\n';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ssize_t tlblazy_write_file(struct file *file,
 | 
					 | 
				
			||||||
		 const char __user *user_buf, size_t count, loff_t *ppos)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	bool val;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (kstrtobool_from_user(user_buf, count, &val))
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (val)
 | 
					 | 
				
			||||||
		static_branch_enable(&tlb_use_lazy_mode);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		static_branch_disable(&tlb_use_lazy_mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return count;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct file_operations fops_tlblazy = {
 | 
					 | 
				
			||||||
	.read = tlblazy_read_file,
 | 
					 | 
				
			||||||
	.write = tlblazy_write_file,
 | 
					 | 
				
			||||||
	.llseek = default_llseek,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int __init init_tlb_use_lazy_mode(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (boot_cpu_has(X86_FEATURE_PCID)) {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Heuristic: with PCID on, switching to and from
 | 
					 | 
				
			||||||
		 * init_mm is reasonably fast, but remote flush IPIs
 | 
					 | 
				
			||||||
		 * as expensive as ever, so turn off lazy TLB mode.
 | 
					 | 
				
			||||||
		 *
 | 
					 | 
				
			||||||
		 * We can't do this in setup_pcid() because static keys
 | 
					 | 
				
			||||||
		 * haven't been initialized yet, and it would blow up
 | 
					 | 
				
			||||||
		 * badly.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		static_branch_disable(&tlb_use_lazy_mode);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	debugfs_create_file("tlb_use_lazy_mode", S_IRUSR | S_IWUSR,
 | 
					 | 
				
			||||||
			    arch_debugfs_dir, NULL, &fops_tlblazy);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
late_initcall(init_tlb_use_lazy_mode);
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3662,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int binder_has_thread_work(struct binder_thread *thread)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return !binder_worklist_empty(thread->proc, &thread->todo) ||
 | 
					 | 
				
			||||||
		thread->looper_need_return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int binder_put_node_cmd(struct binder_proc *proc,
 | 
					static int binder_put_node_cmd(struct binder_proc *proc,
 | 
				
			||||||
			       struct binder_thread *thread,
 | 
								       struct binder_thread *thread,
 | 
				
			||||||
			       void __user **ptrp,
 | 
								       void __user **ptrp,
 | 
				
			||||||
| 
						 | 
					@ -4297,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	binder_inner_proc_unlock(thread->proc);
 | 
						binder_inner_proc_unlock(thread->proc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (binder_has_work(thread, wait_for_proc_work))
 | 
					 | 
				
			||||||
		return POLLIN;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	poll_wait(filp, &thread->wait, wait);
 | 
						poll_wait(filp, &thread->wait, wait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (binder_has_thread_work(thread))
 | 
						if (binder_has_work(thread, wait_for_proc_work))
 | 
				
			||||||
		return POLLIN;
 | 
							return POLLIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!vma && need_mm)
 | 
						if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm))
 | 
				
			||||||
		mm = get_task_mm(alloc->tsk);
 | 
							mm = alloc->vma_vm_mm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mm) {
 | 
						if (mm) {
 | 
				
			||||||
		down_write(&mm->mmap_sem);
 | 
							down_write(&mm->mmap_sem);
 | 
				
			||||||
		vma = alloc->vma;
 | 
							vma = alloc->vma;
 | 
				
			||||||
		if (vma && mm != alloc->vma_vm_mm) {
 | 
					 | 
				
			||||||
			pr_err("%d: vma mm and task mm mismatch\n",
 | 
					 | 
				
			||||||
				alloc->pid);
 | 
					 | 
				
			||||||
			vma = NULL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!vma && need_mm) {
 | 
						if (!vma && need_mm) {
 | 
				
			||||||
| 
						 | 
					@ -565,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc,
 | 
				
			||||||
		binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
 | 
							binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
 | 
				
			||||||
				   "%d: merge free, buffer %pK do not share page with %pK or %pK\n",
 | 
									   "%d: merge free, buffer %pK do not share page with %pK or %pK\n",
 | 
				
			||||||
				   alloc->pid, buffer->data,
 | 
									   alloc->pid, buffer->data,
 | 
				
			||||||
				   prev->data, next->data);
 | 
									   prev->data, next ? next->data : NULL);
 | 
				
			||||||
		binder_update_page_range(alloc, 0, buffer_start_page(buffer),
 | 
							binder_update_page_range(alloc, 0, buffer_start_page(buffer),
 | 
				
			||||||
					 buffer_start_page(buffer) + PAGE_SIZE,
 | 
										 buffer_start_page(buffer) + PAGE_SIZE,
 | 
				
			||||||
					 NULL);
 | 
										 NULL);
 | 
				
			||||||
| 
						 | 
					@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
 | 
				
			||||||
	barrier();
 | 
						barrier();
 | 
				
			||||||
	alloc->vma = vma;
 | 
						alloc->vma = vma;
 | 
				
			||||||
	alloc->vma_vm_mm = vma->vm_mm;
 | 
						alloc->vma_vm_mm = vma->vm_mm;
 | 
				
			||||||
 | 
						mmgrab(alloc->vma_vm_mm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
 | 
				
			||||||
		vfree(alloc->buffer);
 | 
							vfree(alloc->buffer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&alloc->mutex);
 | 
						mutex_unlock(&alloc->mutex);
 | 
				
			||||||
 | 
						if (alloc->vma_vm_mm)
 | 
				
			||||||
 | 
							mmdrop(alloc->vma_vm_mm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE,
 | 
						binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE,
 | 
				
			||||||
		     "%s: %d buffers %d, pages %d\n",
 | 
							     "%s: %d buffers %d, pages %d\n",
 | 
				
			||||||
| 
						 | 
					@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
 | 
				
			||||||
void binder_alloc_vma_close(struct binder_alloc *alloc)
 | 
					void binder_alloc_vma_close(struct binder_alloc *alloc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	WRITE_ONCE(alloc->vma, NULL);
 | 
						WRITE_ONCE(alloc->vma, NULL);
 | 
				
			||||||
	WRITE_ONCE(alloc->vma_vm_mm, NULL);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
 | 
				
			||||||
	page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
 | 
						page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
 | 
				
			||||||
	vma = alloc->vma;
 | 
						vma = alloc->vma;
 | 
				
			||||||
	if (vma) {
 | 
						if (vma) {
 | 
				
			||||||
		mm = get_task_mm(alloc->tsk);
 | 
							if (!mmget_not_zero(alloc->vma_vm_mm))
 | 
				
			||||||
		if (!mm)
 | 
								goto err_mmget;
 | 
				
			||||||
			goto err_get_task_mm_failed;
 | 
							mm = alloc->vma_vm_mm;
 | 
				
			||||||
		if (!down_write_trylock(&mm->mmap_sem))
 | 
							if (!down_write_trylock(&mm->mmap_sem))
 | 
				
			||||||
			goto err_down_write_mmap_sem_failed;
 | 
								goto err_down_write_mmap_sem_failed;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_down_write_mmap_sem_failed:
 | 
					err_down_write_mmap_sem_failed:
 | 
				
			||||||
	mmput_async(mm);
 | 
						mmput_async(mm);
 | 
				
			||||||
err_get_task_mm_failed:
 | 
					err_mmget:
 | 
				
			||||||
err_page_already_freed:
 | 
					err_page_already_freed:
 | 
				
			||||||
	mutex_unlock(&alloc->mutex);
 | 
						mutex_unlock(&alloc->mutex);
 | 
				
			||||||
err_get_alloc_mutex_failed:
 | 
					err_get_alloc_mutex_failed:
 | 
				
			||||||
| 
						 | 
					@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void binder_alloc_init(struct binder_alloc *alloc)
 | 
					void binder_alloc_init(struct binder_alloc *alloc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	alloc->tsk = current->group_leader;
 | 
					 | 
				
			||||||
	alloc->pid = current->group_leader->pid;
 | 
						alloc->pid = current->group_leader->pid;
 | 
				
			||||||
	mutex_init(&alloc->mutex);
 | 
						mutex_init(&alloc->mutex);
 | 
				
			||||||
	INIT_LIST_HEAD(&alloc->buffers);
 | 
						INIT_LIST_HEAD(&alloc->buffers);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,6 @@ struct binder_lru_page {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct binder_alloc {
 | 
					struct binder_alloc {
 | 
				
			||||||
	struct mutex mutex;
 | 
						struct mutex mutex;
 | 
				
			||||||
	struct task_struct *tsk;
 | 
					 | 
				
			||||||
	struct vm_area_struct *vma;
 | 
						struct vm_area_struct *vma;
 | 
				
			||||||
	struct mm_struct *vma_vm_mm;
 | 
						struct mm_struct *vma_vm_mm;
 | 
				
			||||||
	void *buffer;
 | 
						void *buffer;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -377,7 +377,8 @@ int register_cpu(struct cpu *cpu, int num)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	per_cpu(cpu_sys_devices, num) = &cpu->dev;
 | 
						per_cpu(cpu_sys_devices, num) = &cpu->dev;
 | 
				
			||||||
	register_cpu_under_node(num, cpu_to_node(num));
 | 
						register_cpu_under_node(num, cpu_to_node(num));
 | 
				
			||||||
	dev_pm_qos_expose_latency_limit(&cpu->dev, 0);
 | 
						dev_pm_qos_expose_latency_limit(&cpu->dev,
 | 
				
			||||||
 | 
										PM_QOS_RESUME_LATENCY_NO_CONSTRAINT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,23 +14,20 @@
 | 
				
			||||||
static int dev_update_qos_constraint(struct device *dev, void *data)
 | 
					static int dev_update_qos_constraint(struct device *dev, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	s64 *constraint_ns_p = data;
 | 
						s64 *constraint_ns_p = data;
 | 
				
			||||||
	s32 constraint_ns = -1;
 | 
						s64 constraint_ns = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->power.subsys_data && dev->power.subsys_data->domain_data)
 | 
						if (dev->power.subsys_data && dev->power.subsys_data->domain_data)
 | 
				
			||||||
		constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;
 | 
							constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (constraint_ns < 0) {
 | 
						if (constraint_ns < 0)
 | 
				
			||||||
		constraint_ns = dev_pm_qos_read_value(dev);
 | 
							constraint_ns = dev_pm_qos_read_value(dev);
 | 
				
			||||||
		constraint_ns *= NSEC_PER_USEC;
 | 
					
 | 
				
			||||||
	}
 | 
						if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
	if (constraint_ns == 0)
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						constraint_ns *= NSEC_PER_USEC;
 | 
				
			||||||
	 * constraint_ns cannot be negative here, because the device has been
 | 
					
 | 
				
			||||||
	 * suspended.
 | 
						if (constraint_ns < *constraint_ns_p || *constraint_ns_p < 0)
 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0)
 | 
					 | 
				
			||||||
		*constraint_ns_p = constraint_ns;
 | 
							*constraint_ns_p = constraint_ns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -63,10 +60,14 @@ static bool default_suspend_ok(struct device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&dev->power.lock, flags);
 | 
						spin_unlock_irqrestore(&dev->power.lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (constraint_ns < 0)
 | 
						if (constraint_ns == 0)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constraint_ns *= NSEC_PER_USEC;
 | 
						if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
 | 
							constraint_ns = -1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							constraint_ns *= NSEC_PER_USEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We can walk the children without any additional locking, because
 | 
						 * We can walk the children without any additional locking, because
 | 
				
			||||||
	 * they all have been suspended at this point and their
 | 
						 * they all have been suspended at this point and their
 | 
				
			||||||
| 
						 | 
					@ -76,14 +77,19 @@ static bool default_suspend_ok(struct device *dev)
 | 
				
			||||||
		device_for_each_child(dev, &constraint_ns,
 | 
							device_for_each_child(dev, &constraint_ns,
 | 
				
			||||||
				      dev_update_qos_constraint);
 | 
									      dev_update_qos_constraint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (constraint_ns > 0) {
 | 
						if (constraint_ns < 0) {
 | 
				
			||||||
		constraint_ns -= td->suspend_latency_ns +
 | 
							/* The children have no constraints. */
 | 
				
			||||||
				td->resume_latency_ns;
 | 
							td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
 | 
				
			||||||
		if (constraint_ns == 0)
 | 
							td->cached_suspend_ok = true;
 | 
				
			||||||
			return false;
 | 
						} else {
 | 
				
			||||||
 | 
							constraint_ns -= td->suspend_latency_ns + td->resume_latency_ns;
 | 
				
			||||||
 | 
							if (constraint_ns > 0) {
 | 
				
			||||||
 | 
								td->effective_constraint_ns = constraint_ns;
 | 
				
			||||||
 | 
								td->cached_suspend_ok = true;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								td->effective_constraint_ns = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	td->effective_constraint_ns = constraint_ns;
 | 
					 | 
				
			||||||
	td->cached_suspend_ok = constraint_ns >= 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The children have been suspended already, so we don't need to take
 | 
						 * The children have been suspended already, so we don't need to take
 | 
				
			||||||
| 
						 | 
					@ -145,13 +151,14 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd,
 | 
				
			||||||
		td = &to_gpd_data(pdd)->td;
 | 
							td = &to_gpd_data(pdd)->td;
 | 
				
			||||||
		constraint_ns = td->effective_constraint_ns;
 | 
							constraint_ns = td->effective_constraint_ns;
 | 
				
			||||||
		/* default_suspend_ok() need not be called before us. */
 | 
							/* default_suspend_ok() need not be called before us. */
 | 
				
			||||||
		if (constraint_ns < 0) {
 | 
							if (constraint_ns < 0)
 | 
				
			||||||
			constraint_ns = dev_pm_qos_read_value(pdd->dev);
 | 
								constraint_ns = dev_pm_qos_read_value(pdd->dev);
 | 
				
			||||||
			constraint_ns *= NSEC_PER_USEC;
 | 
					
 | 
				
			||||||
		}
 | 
							if (constraint_ns == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
		if (constraint_ns == 0)
 | 
					 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							constraint_ns *= NSEC_PER_USEC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * constraint_ns cannot be negative here, because the device has
 | 
							 * constraint_ns cannot be negative here, because the device has
 | 
				
			||||||
		 * been suspended.
 | 
							 * been suspended.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
 | 
				
			||||||
	plist_head_init(&c->list);
 | 
						plist_head_init(&c->list);
 | 
				
			||||||
	c->target_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
 | 
						c->target_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
 | 
				
			||||||
	c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
 | 
						c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
 | 
				
			||||||
	c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE;
 | 
						c->no_constraint_value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
 | 
				
			||||||
	c->type = PM_QOS_MIN;
 | 
						c->type = PM_QOS_MIN;
 | 
				
			||||||
	c->notifiers = n;
 | 
						c->notifiers = n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,7 +253,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
 | 
				
			||||||
	    || (dev->power.request_pending
 | 
						    || (dev->power.request_pending
 | 
				
			||||||
			&& dev->power.request == RPM_REQ_RESUME))
 | 
								&& dev->power.request == RPM_REQ_RESUME))
 | 
				
			||||||
		retval = -EAGAIN;
 | 
							retval = -EAGAIN;
 | 
				
			||||||
	else if (__dev_pm_qos_read_value(dev) < 0)
 | 
						else if (__dev_pm_qos_read_value(dev) == 0)
 | 
				
			||||||
		retval = -EPERM;
 | 
							retval = -EPERM;
 | 
				
			||||||
	else if (dev->power.runtime_status == RPM_SUSPENDED)
 | 
						else if (dev->power.runtime_status == RPM_SUSPENDED)
 | 
				
			||||||
		retval = 1;
 | 
							retval = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,7 +218,14 @@ static ssize_t pm_qos_resume_latency_show(struct device *dev,
 | 
				
			||||||
					  struct device_attribute *attr,
 | 
										  struct device_attribute *attr,
 | 
				
			||||||
					  char *buf)
 | 
										  char *buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev));
 | 
						s32 value = dev_pm_qos_requested_resume_latency(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == 0)
 | 
				
			||||||
 | 
							return sprintf(buf, "n/a\n");
 | 
				
			||||||
 | 
						else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
 | 
							value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sprintf(buf, "%d\n", value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t pm_qos_resume_latency_store(struct device *dev,
 | 
					static ssize_t pm_qos_resume_latency_store(struct device *dev,
 | 
				
			||||||
| 
						 | 
					@ -228,11 +235,21 @@ static ssize_t pm_qos_resume_latency_store(struct device *dev,
 | 
				
			||||||
	s32 value;
 | 
						s32 value;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (kstrtos32(buf, 0, &value))
 | 
						if (!kstrtos32(buf, 0, &value)) {
 | 
				
			||||||
		return -EINVAL;
 | 
							/*
 | 
				
			||||||
 | 
							 * Prevent users from writing negative or "no constraint" values
 | 
				
			||||||
 | 
							 * directly.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (value < 0 || value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (value < 0)
 | 
							if (value == 0)
 | 
				
			||||||
 | 
								value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
 | 
				
			||||||
 | 
						} else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) {
 | 
				
			||||||
 | 
							value = 0;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req,
 | 
						ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req,
 | 
				
			||||||
					value);
 | 
										value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -386,6 +386,15 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Different settings for sk->sk_sndtimeo can result in different return values
 | 
				
			||||||
 | 
					 * if there is a signal pending when we enter sendmsg, because reasons?
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline int was_interrupted(int result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return result == -ERESTARTSYS || result == -EINTR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* always call with the tx_lock held */
 | 
					/* always call with the tx_lock held */
 | 
				
			||||||
static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 | 
					static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -458,7 +467,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 | 
				
			||||||
	result = sock_xmit(nbd, index, 1, &from,
 | 
						result = sock_xmit(nbd, index, 1, &from,
 | 
				
			||||||
			(type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent);
 | 
								(type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent);
 | 
				
			||||||
	if (result <= 0) {
 | 
						if (result <= 0) {
 | 
				
			||||||
		if (result == -ERESTARTSYS) {
 | 
							if (was_interrupted(result)) {
 | 
				
			||||||
			/* If we havne't sent anything we can just return BUSY,
 | 
								/* If we havne't sent anything we can just return BUSY,
 | 
				
			||||||
			 * however if we have sent something we need to make
 | 
								 * however if we have sent something we need to make
 | 
				
			||||||
			 * sure we only allow this req to be sent until we are
 | 
								 * sure we only allow this req to be sent until we are
 | 
				
			||||||
| 
						 | 
					@ -502,7 +511,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			result = sock_xmit(nbd, index, 1, &from, flags, &sent);
 | 
								result = sock_xmit(nbd, index, 1, &from, flags, &sent);
 | 
				
			||||||
			if (result <= 0) {
 | 
								if (result <= 0) {
 | 
				
			||||||
				if (result == -ERESTARTSYS) {
 | 
									if (was_interrupted(result)) {
 | 
				
			||||||
					/* We've already sent the header, we
 | 
										/* We've already sent the header, we
 | 
				
			||||||
					 * have no choice but to set pending and
 | 
										 * have no choice but to set pending and
 | 
				
			||||||
					 * return BUSY.
 | 
										 * return BUSY.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
 | 
				
			||||||
	/* Turn off the clock (and clear the event) */
 | 
						/* Turn off the clock (and clear the event) */
 | 
				
			||||||
	disable_timer(cs5535_event_clock);
 | 
						disable_timer(cs5535_event_clock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (clockevent_state_shutdown(&cs5535_clockevent))
 | 
						if (clockevent_state_detached(&cs5535_clockevent) ||
 | 
				
			||||||
 | 
						    clockevent_state_shutdown(&cs5535_clockevent))
 | 
				
			||||||
		return IRQ_HANDLED;
 | 
							return IRQ_HANDLED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear the counter */
 | 
						/* Clear the counter */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -298,8 +298,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 | 
				
			||||||
		data->needs_update = 0;
 | 
							data->needs_update = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* resume_latency is 0 means no restriction */
 | 
						if (resume_latency < latency_req &&
 | 
				
			||||||
	if (resume_latency && resume_latency < latency_req)
 | 
						    resume_latency != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
 | 
				
			||||||
		latency_req = resume_latency;
 | 
							latency_req = resume_latency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Special case when user has set very strict latency requirement */
 | 
						/* Special case when user has set very strict latency requirement */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	efi_random_get_seed(sys_table);
 | 
						efi_random_get_seed(sys_table);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!nokaslr()) {
 | 
						/* hibernation expects the runtime regions to stay in the same place */
 | 
				
			||||||
 | 
						if (!IS_ENABLED(CONFIG_HIBERNATION) && !nokaslr()) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Randomize the base of the UEFI runtime services region.
 | 
							 * Randomize the base of the UEFI runtime services region.
 | 
				
			||||||
		 * Preserve the 2 MB alignment of the region by taking a
 | 
							 * Preserve the 2 MB alignment of the region by taking a
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,6 +593,9 @@ static long efi_runtime_query_capsulecaps(unsigned long arg)
 | 
				
			||||||
	if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps)))
 | 
						if (copy_from_user(&qcaps, qcaps_user, sizeof(qcaps)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (qcaps.capsule_count == ULONG_MAX)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capsules = kcalloc(qcaps.capsule_count + 1,
 | 
						capsules = kcalloc(qcaps.capsule_count + 1,
 | 
				
			||||||
			   sizeof(efi_capsule_header_t), GFP_KERNEL);
 | 
								   sizeof(efi_capsule_header_t), GFP_KERNEL);
 | 
				
			||||||
	if (!capsules)
 | 
						if (!capsules)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,11 +225,7 @@ static int uvd_v6_0_suspend(void *handle)
 | 
				
			||||||
	if (r)
 | 
						if (r)
 | 
				
			||||||
		return r;
 | 
							return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Skip this for APU for now */
 | 
						return amdgpu_uvd_suspend(adev);
 | 
				
			||||||
	if (!(adev->flags & AMD_IS_APU))
 | 
					 | 
				
			||||||
		r = amdgpu_uvd_suspend(adev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return r;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int uvd_v6_0_resume(void *handle)
 | 
					static int uvd_v6_0_resume(void *handle)
 | 
				
			||||||
| 
						 | 
					@ -237,12 +233,10 @@ static int uvd_v6_0_resume(void *handle)
 | 
				
			||||||
	int r;
 | 
						int r;
 | 
				
			||||||
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
						struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Skip this for APU for now */
 | 
						r = amdgpu_uvd_resume(adev);
 | 
				
			||||||
	if (!(adev->flags & AMD_IS_APU)) {
 | 
						if (r)
 | 
				
			||||||
		r = amdgpu_uvd_resume(adev);
 | 
							return r;
 | 
				
			||||||
		if (r)
 | 
					
 | 
				
			||||||
			return r;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return uvd_v6_0_hw_init(adev);
 | 
						return uvd_v6_0_hw_init(adev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -830,7 +830,7 @@ uint32_t smu7_get_xclk(struct pp_hwmgr *hwmgr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t reference_clock, tmp;
 | 
						uint32_t reference_clock, tmp;
 | 
				
			||||||
	struct cgs_display_info info = {0};
 | 
						struct cgs_display_info info = {0};
 | 
				
			||||||
	struct cgs_mode_info mode_info;
 | 
						struct cgs_mode_info mode_info = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info.mode_info = &mode_info;
 | 
						info.mode_info = &mode_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3948,10 +3948,9 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
 | 
				
			||||||
	uint32_t ref_clock;
 | 
						uint32_t ref_clock;
 | 
				
			||||||
	uint32_t refresh_rate = 0;
 | 
						uint32_t refresh_rate = 0;
 | 
				
			||||||
	struct cgs_display_info info = {0};
 | 
						struct cgs_display_info info = {0};
 | 
				
			||||||
	struct cgs_mode_info mode_info;
 | 
						struct cgs_mode_info mode_info = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	info.mode_info = &mode_info;
 | 
						info.mode_info = &mode_info;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	cgs_get_active_displays_info(hwmgr->device, &info);
 | 
						cgs_get_active_displays_info(hwmgr->device, &info);
 | 
				
			||||||
	num_active_displays = info.display_count;
 | 
						num_active_displays = info.display_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3967,6 +3966,7 @@ static int smu7_program_display_gap(struct pp_hwmgr *hwmgr)
 | 
				
			||||||
	frame_time_in_us = 1000000 / refresh_rate;
 | 
						frame_time_in_us = 1000000 / refresh_rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
 | 
						pre_vbi_time_in_us = frame_time_in_us - 200 - mode_info.vblank_time_us;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->frame_time_x2 = frame_time_in_us * 2 / 100;
 | 
						data->frame_time_x2 = frame_time_in_us * 2 / 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
 | 
						display_gap2 = pre_vbi_time_in_us * (ref_clock / 100);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2723,6 +2723,9 @@ static int combine_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 | 
				
			||||||
	uint32_t per_ctx_start[CACHELINE_DWORDS] = {0};
 | 
						uint32_t per_ctx_start[CACHELINE_DWORDS] = {0};
 | 
				
			||||||
	unsigned char *bb_start_sva;
 | 
						unsigned char *bb_start_sva;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!wa_ctx->per_ctx.valid)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	per_ctx_start[0] = 0x18800001;
 | 
						per_ctx_start[0] = 0x18800001;
 | 
				
			||||||
	per_ctx_start[1] = wa_ctx->per_ctx.guest_gma;
 | 
						per_ctx_start[1] = wa_ctx->per_ctx.guest_gma;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -701,8 +701,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
 | 
				
			||||||
			CACHELINE_BYTES;
 | 
								CACHELINE_BYTES;
 | 
				
			||||||
		workload->wa_ctx.per_ctx.guest_gma =
 | 
							workload->wa_ctx.per_ctx.guest_gma =
 | 
				
			||||||
			per_ctx & PER_CTX_ADDR_MASK;
 | 
								per_ctx & PER_CTX_ADDR_MASK;
 | 
				
			||||||
 | 
							workload->wa_ctx.per_ctx.valid = per_ctx & 1;
 | 
				
			||||||
		WARN_ON(workload->wa_ctx.indirect_ctx.size && !(per_ctx & 0x1));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (emulate_schedule_in)
 | 
						if (emulate_schedule_in)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1429,18 +1429,7 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ring_timestamp_mmio_read(struct intel_vgpu *vgpu,
 | 
					static int mmio_read_from_hw(struct intel_vgpu *vgpu,
 | 
				
			||||||
		unsigned int offset, void *p_data, unsigned int bytes)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mmio_hw_access_pre(dev_priv);
 | 
					 | 
				
			||||||
	vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
 | 
					 | 
				
			||||||
	mmio_hw_access_post(dev_priv);
 | 
					 | 
				
			||||||
	return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int instdone_mmio_read(struct intel_vgpu *vgpu,
 | 
					 | 
				
			||||||
		unsigned int offset, void *p_data, unsigned int bytes)
 | 
							unsigned int offset, void *p_data, unsigned int bytes)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 | 
						struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 | 
				
			||||||
| 
						 | 
					@ -1589,6 +1578,8 @@ static int ring_reset_ctl_write(struct intel_vgpu *vgpu,
 | 
				
			||||||
	MMIO_F(prefix(BLT_RING_BASE), s, f, am, rm, d, r, w); \
 | 
						MMIO_F(prefix(BLT_RING_BASE), s, f, am, rm, d, r, w); \
 | 
				
			||||||
	MMIO_F(prefix(GEN6_BSD_RING_BASE), s, f, am, rm, d, r, w); \
 | 
						MMIO_F(prefix(GEN6_BSD_RING_BASE), s, f, am, rm, d, r, w); \
 | 
				
			||||||
	MMIO_F(prefix(VEBOX_RING_BASE), s, f, am, rm, d, r, w); \
 | 
						MMIO_F(prefix(VEBOX_RING_BASE), s, f, am, rm, d, r, w); \
 | 
				
			||||||
 | 
						if (HAS_BSD2(dev_priv)) \
 | 
				
			||||||
 | 
							MMIO_F(prefix(GEN8_BSD2_RING_BASE), s, f, am, rm, d, r, w); \
 | 
				
			||||||
} while (0)
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MMIO_RING_D(prefix, d) \
 | 
					#define MMIO_RING_D(prefix, d) \
 | 
				
			||||||
| 
						 | 
					@ -1635,10 +1626,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x6c)
 | 
					#define RING_REG(base) (base + 0x6c)
 | 
				
			||||||
	MMIO_RING_DFH(RING_REG, D_ALL, 0, instdone_mmio_read, NULL);
 | 
						MMIO_RING_DFH(RING_REG, D_ALL, 0, mmio_read_from_hw, NULL);
 | 
				
			||||||
	MMIO_DH(RING_REG(GEN8_BSD2_RING_BASE), D_ALL, instdone_mmio_read, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
	MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, instdone_mmio_read, NULL);
 | 
						MMIO_DH(GEN7_SC_INSTDONE, D_BDW_PLUS, mmio_read_from_hw, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_GM_RDR(0x2148, D_ALL, NULL, NULL);
 | 
						MMIO_GM_RDR(0x2148, D_ALL, NULL, NULL);
 | 
				
			||||||
	MMIO_GM_RDR(CCID, D_ALL, NULL, NULL);
 | 
						MMIO_GM_RDR(CCID, D_ALL, NULL, NULL);
 | 
				
			||||||
| 
						 | 
					@ -1648,7 +1638,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
	MMIO_RING_DFH(RING_TAIL, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_TAIL, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
	MMIO_RING_DFH(RING_HEAD, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_HEAD, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
	MMIO_RING_DFH(RING_CTL, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_CTL, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
	MMIO_RING_DFH(RING_ACTHD, D_ALL, F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_ACTHD, D_ALL, F_CMD_ACCESS, mmio_read_from_hw, NULL);
 | 
				
			||||||
	MMIO_RING_GM_RDR(RING_START, D_ALL, NULL, NULL);
 | 
						MMIO_RING_GM_RDR(RING_START, D_ALL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* RING MODE */
 | 
						/* RING MODE */
 | 
				
			||||||
| 
						 | 
					@ -1662,9 +1652,9 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
	MMIO_RING_DFH(RING_INSTPM, D_ALL, F_MODE_MASK | F_CMD_ACCESS,
 | 
						MMIO_RING_DFH(RING_INSTPM, D_ALL, F_MODE_MASK | F_CMD_ACCESS,
 | 
				
			||||||
			NULL, NULL);
 | 
								NULL, NULL);
 | 
				
			||||||
	MMIO_RING_DFH(RING_TIMESTAMP, D_ALL, F_CMD_ACCESS,
 | 
						MMIO_RING_DFH(RING_TIMESTAMP, D_ALL, F_CMD_ACCESS,
 | 
				
			||||||
			ring_timestamp_mmio_read, NULL);
 | 
								mmio_read_from_hw, NULL);
 | 
				
			||||||
	MMIO_RING_DFH(RING_TIMESTAMP_UDW, D_ALL, F_CMD_ACCESS,
 | 
						MMIO_RING_DFH(RING_TIMESTAMP_UDW, D_ALL, F_CMD_ACCESS,
 | 
				
			||||||
			ring_timestamp_mmio_read, NULL);
 | 
								mmio_read_from_hw, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_DFH(GEN7_GT_MODE, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_DFH(GEN7_GT_MODE, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
	MMIO_DFH(CACHE_MODE_0_GEN7, D_ALL, F_MODE_MASK | F_CMD_ACCESS,
 | 
						MMIO_DFH(CACHE_MODE_0_GEN7, D_ALL, F_MODE_MASK | F_CMD_ACCESS,
 | 
				
			||||||
| 
						 | 
					@ -2411,9 +2401,6 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
	struct drm_i915_private *dev_priv = gvt->dev_priv;
 | 
						struct drm_i915_private *dev_priv = gvt->dev_priv;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_DFH(RING_IMR(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS, NULL,
 | 
					 | 
				
			||||||
			intel_vgpu_reg_imr_handler);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MMIO_DH(GEN8_GT_IMR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_imr_handler);
 | 
						MMIO_DH(GEN8_GT_IMR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_imr_handler);
 | 
				
			||||||
	MMIO_DH(GEN8_GT_IER(0), D_BDW_PLUS, NULL, intel_vgpu_reg_ier_handler);
 | 
						MMIO_DH(GEN8_GT_IER(0), D_BDW_PLUS, NULL, intel_vgpu_reg_ier_handler);
 | 
				
			||||||
	MMIO_DH(GEN8_GT_IIR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_iir_handler);
 | 
						MMIO_DH(GEN8_GT_IIR(0), D_BDW_PLUS, NULL, intel_vgpu_reg_iir_handler);
 | 
				
			||||||
| 
						 | 
					@ -2476,68 +2463,34 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
	MMIO_DH(GEN8_MASTER_IRQ, D_BDW_PLUS, NULL,
 | 
						MMIO_DH(GEN8_MASTER_IRQ, D_BDW_PLUS, NULL,
 | 
				
			||||||
		intel_vgpu_reg_master_irq_handler);
 | 
							intel_vgpu_reg_master_irq_handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_DFH(RING_HWSTAM(GEN8_BSD2_RING_BASE), D_BDW_PLUS,
 | 
						MMIO_RING_DFH(RING_ACTHD_UDW, D_BDW_PLUS, F_CMD_ACCESS,
 | 
				
			||||||
		F_CMD_ACCESS, NULL, NULL);
 | 
							mmio_read_from_hw, NULL);
 | 
				
			||||||
	MMIO_DFH(0x1c134, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_TAIL(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS,
 | 
					 | 
				
			||||||
		NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_HEAD(GEN8_BSD2_RING_BASE),  D_BDW_PLUS,
 | 
					 | 
				
			||||||
		F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_GM_RDR(RING_START(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_CTL(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS,
 | 
					 | 
				
			||||||
		NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_ACTHD(GEN8_BSD2_RING_BASE), D_BDW_PLUS,
 | 
					 | 
				
			||||||
		F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_ACTHD_UDW(GEN8_BSD2_RING_BASE), D_BDW_PLUS,
 | 
					 | 
				
			||||||
		F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(0x1c29c, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL,
 | 
					 | 
				
			||||||
		ring_mode_mmio_write);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_MI_MODE(GEN8_BSD2_RING_BASE), D_BDW_PLUS,
 | 
					 | 
				
			||||||
		F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_INSTPM(GEN8_BSD2_RING_BASE), D_BDW_PLUS,
 | 
					 | 
				
			||||||
		F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_DFH(RING_TIMESTAMP(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS,
 | 
					 | 
				
			||||||
			ring_timestamp_mmio_read, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MMIO_RING_DFH(RING_ACTHD_UDW, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0xd0)
 | 
					#define RING_REG(base) (base + 0xd0)
 | 
				
			||||||
	MMIO_RING_F(RING_REG, 4, F_RO, 0,
 | 
						MMIO_RING_F(RING_REG, 4, F_RO, 0,
 | 
				
			||||||
		~_MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET), D_BDW_PLUS, NULL,
 | 
							~_MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET), D_BDW_PLUS, NULL,
 | 
				
			||||||
		ring_reset_ctl_write);
 | 
							ring_reset_ctl_write);
 | 
				
			||||||
	MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 4, F_RO, 0,
 | 
					 | 
				
			||||||
		~_MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET), D_BDW_PLUS, NULL,
 | 
					 | 
				
			||||||
		ring_reset_ctl_write);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x230)
 | 
					#define RING_REG(base) (base + 0x230)
 | 
				
			||||||
	MMIO_RING_DFH(RING_REG, D_BDW_PLUS, 0, NULL, elsp_mmio_write);
 | 
						MMIO_RING_DFH(RING_REG, D_BDW_PLUS, 0, NULL, elsp_mmio_write);
 | 
				
			||||||
	MMIO_DH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, elsp_mmio_write);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x234)
 | 
					#define RING_REG(base) (base + 0x234)
 | 
				
			||||||
	MMIO_RING_F(RING_REG, 8, F_RO | F_CMD_ACCESS, 0, ~0, D_BDW_PLUS,
 | 
						MMIO_RING_F(RING_REG, 8, F_RO | F_CMD_ACCESS, 0, ~0, D_BDW_PLUS,
 | 
				
			||||||
		NULL, NULL);
 | 
							NULL, NULL);
 | 
				
			||||||
	MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 4, F_RO | F_CMD_ACCESS, 0,
 | 
					 | 
				
			||||||
		~0LL, D_BDW_PLUS, NULL, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x244)
 | 
					#define RING_REG(base) (base + 0x244)
 | 
				
			||||||
	MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
	MMIO_DFH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_CMD_ACCESS,
 | 
					 | 
				
			||||||
		NULL, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x370)
 | 
					#define RING_REG(base) (base + 0x370)
 | 
				
			||||||
	MMIO_RING_F(RING_REG, 48, F_RO, 0, ~0, D_BDW_PLUS, NULL, NULL);
 | 
						MMIO_RING_F(RING_REG, 48, F_RO, 0, ~0, D_BDW_PLUS, NULL, NULL);
 | 
				
			||||||
	MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 48, F_RO, 0, ~0, D_BDW_PLUS,
 | 
					 | 
				
			||||||
			NULL, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x3a0)
 | 
					#define RING_REG(base) (base + 0x3a0)
 | 
				
			||||||
	MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_MODE_MASK, NULL, NULL);
 | 
						MMIO_RING_DFH(RING_REG, D_BDW_PLUS, F_MODE_MASK, NULL, NULL);
 | 
				
			||||||
	MMIO_DFH(RING_REG(GEN8_BSD2_RING_BASE), D_BDW_PLUS, F_MODE_MASK, NULL, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_D(PIPEMISC(PIPE_A), D_BDW_PLUS);
 | 
						MMIO_D(PIPEMISC(PIPE_A), D_BDW_PLUS);
 | 
				
			||||||
| 
						 | 
					@ -2557,11 +2510,9 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RING_REG(base) (base + 0x270)
 | 
					#define RING_REG(base) (base + 0x270)
 | 
				
			||||||
	MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL);
 | 
						MMIO_RING_F(RING_REG, 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL);
 | 
				
			||||||
	MMIO_F(RING_REG(GEN8_BSD2_RING_BASE), 32, 0, 0, 0, D_BDW_PLUS, NULL, NULL);
 | 
					 | 
				
			||||||
#undef RING_REG
 | 
					#undef RING_REG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, NULL);
 | 
						MMIO_RING_GM_RDR(RING_HWS_PGA, D_BDW_PLUS, NULL, NULL);
 | 
				
			||||||
	MMIO_GM_RDR(RING_HWS_PGA(GEN8_BSD2_RING_BASE), D_BDW_PLUS, NULL, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_DFH(HDC_CHICKEN0, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
						MMIO_DFH(HDC_CHICKEN0, D_BDW_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2849,7 +2800,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
 | 
				
			||||||
	MMIO_D(0x65f08, D_SKL | D_KBL);
 | 
						MMIO_D(0x65f08, D_SKL | D_KBL);
 | 
				
			||||||
	MMIO_D(0x320f0, D_SKL | D_KBL);
 | 
						MMIO_D(0x320f0, D_SKL | D_KBL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MMIO_DFH(_REG_VCS2_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
 | 
					 | 
				
			||||||
	MMIO_D(0x70034, D_SKL_PLUS);
 | 
						MMIO_D(0x70034, D_SKL_PLUS);
 | 
				
			||||||
	MMIO_D(0x71034, D_SKL_PLUS);
 | 
						MMIO_D(0x71034, D_SKL_PLUS);
 | 
				
			||||||
	MMIO_D(0x72034, D_SKL_PLUS);
 | 
						MMIO_D(0x72034, D_SKL_PLUS);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,9 +54,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VGT_SPRSTRIDE(pipe)	_PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B)
 | 
					#define VGT_SPRSTRIDE(pipe)	_PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _REG_VECS_EXCC		0x1A028
 | 
					 | 
				
			||||||
#define _REG_VCS2_EXCC		0x1c028
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define _REG_701C0(pipe, plane) (0x701c0 + pipe * 0x1000 + (plane - 1) * 0x100)
 | 
					#define _REG_701C0(pipe, plane) (0x701c0 + pipe * 0x1000 + (plane - 1) * 0x100)
 | 
				
			||||||
#define _REG_701C4(pipe, plane) (0x701c4 + pipe * 0x1000 + (plane - 1) * 0x100)
 | 
					#define _REG_701C4(pipe, plane) (0x701c4 + pipe * 0x1000 + (plane - 1) * 0x100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,7 @@ struct shadow_indirect_ctx {
 | 
				
			||||||
struct shadow_per_ctx {
 | 
					struct shadow_per_ctx {
 | 
				
			||||||
	unsigned long guest_gma;
 | 
						unsigned long guest_gma;
 | 
				
			||||||
	unsigned long shadow_gma;
 | 
						unsigned long shadow_gma;
 | 
				
			||||||
 | 
						unsigned valid;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct intel_shadow_wa_ctx {
 | 
					struct intel_shadow_wa_ctx {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2537,6 +2537,10 @@ static const struct file_operations fops = {
 | 
				
			||||||
	.poll		= i915_perf_poll,
 | 
						.poll		= i915_perf_poll,
 | 
				
			||||||
	.read		= i915_perf_read,
 | 
						.read		= i915_perf_read,
 | 
				
			||||||
	.unlocked_ioctl	= i915_perf_ioctl,
 | 
						.unlocked_ioctl	= i915_perf_ioctl,
 | 
				
			||||||
 | 
						/* Our ioctl have no arguments, so it's safe to use the same function
 | 
				
			||||||
 | 
						 * to handle 32bits compatibility.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						.compat_ioctl   = i915_perf_ioctl,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BUG_ON(!is_hvsock_channel(channel));
 | 
						BUG_ON(!is_hvsock_channel(channel));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	channel->rescind = true;
 | 
						/* We always get a rescind msg when a connection is closed. */
 | 
				
			||||||
 | 
						while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind))
 | 
				
			||||||
 | 
							msleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vmbus_device_unregister(channel->device_obj);
 | 
						vmbus_device_unregister(channel->device_obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
 | 
					EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -477,6 +477,11 @@ static int da9052_hwmon_probe(struct platform_device *pdev)
 | 
				
			||||||
		/* disable touchscreen features */
 | 
							/* disable touchscreen features */
 | 
				
			||||||
		da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00);
 | 
							da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Sample every 1ms */
 | 
				
			||||||
 | 
							da9052_reg_update(hwmon->da9052, DA9052_ADC_CONT_REG,
 | 
				
			||||||
 | 
										  DA9052_ADCCONT_ADCMODE,
 | 
				
			||||||
 | 
										  DA9052_ADCCONT_ADCMODE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY,
 | 
							err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY,
 | 
				
			||||||
					 "tsiready-irq", da9052_tsi_datardy_irq,
 | 
										 "tsiready-irq", da9052_tsi_datardy_irq,
 | 
				
			||||||
					 hwmon);
 | 
										 hwmon);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,14 +268,11 @@ static int tmp102_probe(struct i2c_client *client,
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tmp102->ready_time = jiffies;
 | 
						/*
 | 
				
			||||||
	if (tmp102->config_orig & TMP102_CONF_SD) {
 | 
						 * Mark that we are not ready with data until the first
 | 
				
			||||||
		/*
 | 
						 * conversion is complete
 | 
				
			||||||
		 * Mark that we are not ready with data until the first
 | 
						 */
 | 
				
			||||||
		 * conversion is complete
 | 
						tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		tmp102->ready_time += msecs_to_jiffies(CONVERSION_TIME_MS);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
 | 
						hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
 | 
				
			||||||
							 tmp102,
 | 
												 tmp102,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,6 +243,8 @@ config DA9150_GPADC
 | 
				
			||||||
config DLN2_ADC
 | 
					config DLN2_ADC
 | 
				
			||||||
	tristate "Diolan DLN-2 ADC driver support"
 | 
						tristate "Diolan DLN-2 ADC driver support"
 | 
				
			||||||
	depends on MFD_DLN2
 | 
						depends on MFD_DLN2
 | 
				
			||||||
 | 
						select IIO_BUFFER
 | 
				
			||||||
 | 
						select IIO_TRIGGERED_BUFFER
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Say yes here to build support for Diolan DLN-2 ADC.
 | 
						  Say yes here to build support for Diolan DLN-2 ADC.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,6 +225,7 @@ struct at91_adc_trigger {
 | 
				
			||||||
	char				*name;
 | 
						char				*name;
 | 
				
			||||||
	unsigned int			trgmod_value;
 | 
						unsigned int			trgmod_value;
 | 
				
			||||||
	unsigned int			edge_type;
 | 
						unsigned int			edge_type;
 | 
				
			||||||
 | 
						bool				hw_trig;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct at91_adc_state {
 | 
					struct at91_adc_state {
 | 
				
			||||||
| 
						 | 
					@ -254,16 +255,25 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
 | 
				
			||||||
		.name = "external_rising",
 | 
							.name = "external_rising",
 | 
				
			||||||
		.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
 | 
							.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
 | 
				
			||||||
		.edge_type = IRQ_TYPE_EDGE_RISING,
 | 
							.edge_type = IRQ_TYPE_EDGE_RISING,
 | 
				
			||||||
 | 
							.hw_trig = true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "external_falling",
 | 
							.name = "external_falling",
 | 
				
			||||||
		.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
 | 
							.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
 | 
				
			||||||
		.edge_type = IRQ_TYPE_EDGE_FALLING,
 | 
							.edge_type = IRQ_TYPE_EDGE_FALLING,
 | 
				
			||||||
 | 
							.hw_trig = true,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "external_any",
 | 
							.name = "external_any",
 | 
				
			||||||
		.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
 | 
							.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
 | 
				
			||||||
		.edge_type = IRQ_TYPE_EDGE_BOTH,
 | 
							.edge_type = IRQ_TYPE_EDGE_BOTH,
 | 
				
			||||||
 | 
							.hw_trig = true,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.name = "software",
 | 
				
			||||||
 | 
							.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER,
 | 
				
			||||||
 | 
							.edge_type = IRQ_TYPE_NONE,
 | 
				
			||||||
 | 
							.hw_trig = false,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -597,7 +607,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 | 
				
			||||||
	struct at91_adc_state *st;
 | 
						struct at91_adc_state *st;
 | 
				
			||||||
	struct resource	*res;
 | 
						struct resource	*res;
 | 
				
			||||||
	int ret, i;
 | 
						int ret, i;
 | 
				
			||||||
	u32 edge_type;
 | 
						u32 edge_type = IRQ_TYPE_NONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
 | 
						indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
 | 
				
			||||||
	if (!indio_dev)
 | 
						if (!indio_dev)
 | 
				
			||||||
| 
						 | 
					@ -641,14 +651,14 @@ static int at91_adc_probe(struct platform_device *pdev)
 | 
				
			||||||
	ret = of_property_read_u32(pdev->dev.of_node,
 | 
						ret = of_property_read_u32(pdev->dev.of_node,
 | 
				
			||||||
				   "atmel,trigger-edge-type", &edge_type);
 | 
									   "atmel,trigger-edge-type", &edge_type);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		dev_err(&pdev->dev,
 | 
							dev_dbg(&pdev->dev,
 | 
				
			||||||
			"invalid or missing value for atmel,trigger-edge-type\n");
 | 
								"atmel,trigger-edge-type not specified, only software trigger available\n");
 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	st->selected_trig = NULL;
 | 
						st->selected_trig = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++)
 | 
						/* find the right trigger, or no trigger at all */
 | 
				
			||||||
 | 
						for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
 | 
				
			||||||
		if (at91_adc_trigger_list[i].edge_type == edge_type) {
 | 
							if (at91_adc_trigger_list[i].edge_type == edge_type) {
 | 
				
			||||||
			st->selected_trig = &at91_adc_trigger_list[i];
 | 
								st->selected_trig = &at91_adc_trigger_list[i];
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -717,24 +727,27 @@ static int at91_adc_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	platform_set_drvdata(pdev, indio_dev);
 | 
						platform_set_drvdata(pdev, indio_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = at91_adc_buffer_init(indio_dev);
 | 
						if (st->selected_trig->hw_trig) {
 | 
				
			||||||
	if (ret < 0) {
 | 
							ret = at91_adc_buffer_init(indio_dev);
 | 
				
			||||||
		dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
 | 
							if (ret < 0) {
 | 
				
			||||||
		goto per_clk_disable_unprepare;
 | 
								dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
 | 
				
			||||||
	}
 | 
								goto per_clk_disable_unprepare;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = at91_adc_trigger_init(indio_dev);
 | 
							ret = at91_adc_trigger_init(indio_dev);
 | 
				
			||||||
	if (ret < 0) {
 | 
							if (ret < 0) {
 | 
				
			||||||
		dev_err(&pdev->dev, "couldn't setup the triggers.\n");
 | 
								dev_err(&pdev->dev, "couldn't setup the triggers.\n");
 | 
				
			||||||
		goto per_clk_disable_unprepare;
 | 
								goto per_clk_disable_unprepare;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = iio_device_register(indio_dev);
 | 
						ret = iio_device_register(indio_dev);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		goto per_clk_disable_unprepare;
 | 
							goto per_clk_disable_unprepare;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(&pdev->dev, "setting up trigger as %s\n",
 | 
						if (st->selected_trig->hw_trig)
 | 
				
			||||||
		 st->selected_trig->name);
 | 
							dev_info(&pdev->dev, "setting up trigger as %s\n",
 | 
				
			||||||
 | 
								 st->selected_trig->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_info(&pdev->dev, "version: %x\n",
 | 
						dev_info(&pdev->dev, "version: %x\n",
 | 
				
			||||||
		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
 | 
							 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
 | 
				
			||||||
				st->event_en = state;
 | 
									st->event_en = state;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				return -EINVAL;
 | 
									return -EINVAL;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -865,7 +865,6 @@ static irqreturn_t zpa2326_handle_threaded_irq(int irq, void *data)
 | 
				
			||||||
static int zpa2326_wait_oneshot_completion(const struct iio_dev   *indio_dev,
 | 
					static int zpa2326_wait_oneshot_completion(const struct iio_dev   *indio_dev,
 | 
				
			||||||
					   struct zpa2326_private *private)
 | 
										   struct zpa2326_private *private)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int          ret;
 | 
					 | 
				
			||||||
	unsigned int val;
 | 
						unsigned int val;
 | 
				
			||||||
	long     timeout;
 | 
						long     timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -887,14 +886,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev   *indio_dev,
 | 
				
			||||||
		/* Timed out. */
 | 
							/* Timed out. */
 | 
				
			||||||
		zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
 | 
							zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
 | 
				
			||||||
			     timeout);
 | 
								     timeout);
 | 
				
			||||||
		ret = -ETIME;
 | 
							return -ETIME;
 | 
				
			||||||
	} else if (timeout < 0) {
 | 
					 | 
				
			||||||
		zpa2326_warn(indio_dev,
 | 
					 | 
				
			||||||
			     "wait for one shot interrupt cancelled");
 | 
					 | 
				
			||||||
		ret = -ERESTARTSYS;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled");
 | 
				
			||||||
 | 
						return -ERESTARTSYS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int zpa2326_init_managed_irq(struct device          *parent,
 | 
					static int zpa2326_init_managed_irq(struct device          *parent,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,8 +39,12 @@
 | 
				
			||||||
#define AS3935_AFE_GAIN_MAX	0x1F
 | 
					#define AS3935_AFE_GAIN_MAX	0x1F
 | 
				
			||||||
#define AS3935_AFE_PWR_BIT	BIT(0)
 | 
					#define AS3935_AFE_PWR_BIT	BIT(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AS3935_NFLWDTH		0x01
 | 
				
			||||||
 | 
					#define AS3935_NFLWDTH_MASK	0x7f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AS3935_INT		0x03
 | 
					#define AS3935_INT		0x03
 | 
				
			||||||
#define AS3935_INT_MASK		0x0f
 | 
					#define AS3935_INT_MASK		0x0f
 | 
				
			||||||
 | 
					#define AS3935_DISTURB_INT	BIT(2)
 | 
				
			||||||
#define AS3935_EVENT_INT	BIT(3)
 | 
					#define AS3935_EVENT_INT	BIT(3)
 | 
				
			||||||
#define AS3935_NOISE_INT	BIT(0)
 | 
					#define AS3935_NOISE_INT	BIT(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +52,7 @@
 | 
				
			||||||
#define AS3935_DATA_MASK	0x3F
 | 
					#define AS3935_DATA_MASK	0x3F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AS3935_TUNE_CAP		0x08
 | 
					#define AS3935_TUNE_CAP		0x08
 | 
				
			||||||
 | 
					#define AS3935_DEFAULTS		0x3C
 | 
				
			||||||
#define AS3935_CALIBRATE	0x3D
 | 
					#define AS3935_CALIBRATE	0x3D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define AS3935_READ_DATA	BIT(14)
 | 
					#define AS3935_READ_DATA	BIT(14)
 | 
				
			||||||
| 
						 | 
					@ -62,7 +67,9 @@ struct as3935_state {
 | 
				
			||||||
	struct mutex lock;
 | 
						struct mutex lock;
 | 
				
			||||||
	struct delayed_work work;
 | 
						struct delayed_work work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned long noise_tripped;
 | 
				
			||||||
	u32 tune_cap;
 | 
						u32 tune_cap;
 | 
				
			||||||
 | 
						u32 nflwdth_reg;
 | 
				
			||||||
	u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
 | 
						u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
 | 
				
			||||||
	u8 buf[2] ____cacheline_aligned;
 | 
						u8 buf[2] ____cacheline_aligned;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -145,12 +152,29 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
 | 
				
			||||||
	return len;
 | 
						return len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static ssize_t as3935_noise_level_tripped_show(struct device *dev,
 | 
				
			||||||
 | 
										struct device_attribute *attr,
 | 
				
			||||||
 | 
										char *buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&st->lock);
 | 
				
			||||||
 | 
						ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ));
 | 
				
			||||||
 | 
						mutex_unlock(&st->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
 | 
					static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
 | 
				
			||||||
	as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
 | 
						as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO,
 | 
				
			||||||
 | 
						as3935_noise_level_tripped_show, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct attribute *as3935_attributes[] = {
 | 
					static struct attribute *as3935_attributes[] = {
 | 
				
			||||||
	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
 | 
						&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
 | 
				
			||||||
 | 
						&iio_dev_attr_noise_level_tripped.dev_attr.attr,
 | 
				
			||||||
	NULL,
 | 
						NULL,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,7 +270,11 @@ static void as3935_event_work(struct work_struct *work)
 | 
				
			||||||
	case AS3935_EVENT_INT:
 | 
						case AS3935_EVENT_INT:
 | 
				
			||||||
		iio_trigger_poll_chained(st->trig);
 | 
							iio_trigger_poll_chained(st->trig);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case AS3935_DISTURB_INT:
 | 
				
			||||||
	case AS3935_NOISE_INT:
 | 
						case AS3935_NOISE_INT:
 | 
				
			||||||
 | 
							mutex_lock(&st->lock);
 | 
				
			||||||
 | 
							st->noise_tripped = jiffies;
 | 
				
			||||||
 | 
							mutex_unlock(&st->lock);
 | 
				
			||||||
		dev_warn(&st->spi->dev, "noise level is too high\n");
 | 
							dev_warn(&st->spi->dev, "noise level is too high\n");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -269,15 +297,14 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void calibrate_as3935(struct as3935_state *st)
 | 
					static void calibrate_as3935(struct as3935_state *st)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* mask disturber interrupt bit */
 | 
						as3935_write(st, AS3935_DEFAULTS, 0x96);
 | 
				
			||||||
	as3935_write(st, AS3935_INT, BIT(5));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	as3935_write(st, AS3935_CALIBRATE, 0x96);
 | 
						as3935_write(st, AS3935_CALIBRATE, 0x96);
 | 
				
			||||||
	as3935_write(st, AS3935_TUNE_CAP,
 | 
						as3935_write(st, AS3935_TUNE_CAP,
 | 
				
			||||||
		BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
 | 
							BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mdelay(2);
 | 
						mdelay(2);
 | 
				
			||||||
	as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
 | 
						as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
 | 
				
			||||||
 | 
						as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PM_SLEEP
 | 
					#ifdef CONFIG_PM_SLEEP
 | 
				
			||||||
| 
						 | 
					@ -370,6 +397,15 @@ static int as3935_probe(struct spi_device *spi)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = of_property_read_u32(np,
 | 
				
			||||||
 | 
								"ams,nflwdth", &st->nflwdth_reg);
 | 
				
			||||||
 | 
						if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) {
 | 
				
			||||||
 | 
							dev_err(&spi->dev,
 | 
				
			||||||
 | 
								"invalid nflwdth setting of %d\n",
 | 
				
			||||||
 | 
								st->nflwdth_reg);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	indio_dev->dev.parent = &spi->dev;
 | 
						indio_dev->dev.parent = &spi->dev;
 | 
				
			||||||
	indio_dev->name = spi_get_device_id(spi)->name;
 | 
						indio_dev->name = spi_get_device_id(spi)->name;
 | 
				
			||||||
	indio_dev->channels = as3935_channels;
 | 
						indio_dev->channels = as3935_channels;
 | 
				
			||||||
| 
						 | 
					@ -384,6 +420,7 @@ static int as3935_probe(struct spi_device *spi)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	st->trig = trig;
 | 
						st->trig = trig;
 | 
				
			||||||
 | 
						st->noise_tripped = jiffies - HZ;
 | 
				
			||||||
	trig->dev.parent = indio_dev->dev.parent;
 | 
						trig->dev.parent = indio_dev->dev.parent;
 | 
				
			||||||
	iio_trigger_set_drvdata(trig, indio_dev);
 | 
						iio_trigger_set_drvdata(trig, indio_dev);
 | 
				
			||||||
	trig->ops = &iio_interrupt_trigger_ops;
 | 
						trig->ops = &iio_interrupt_trigger_ops;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,13 +175,24 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 | 
				
			||||||
	    !netlink_capable(skb, CAP_NET_ADMIN))
 | 
						    !netlink_capable(skb, CAP_NET_ADMIN))
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * LS responses overload the 0x100 (NLM_F_ROOT) flag.  Don't
 | 
				
			||||||
 | 
						 * mistakenly call the .dump() function.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (index == RDMA_NL_LS) {
 | 
				
			||||||
 | 
							if (cb_table[op].doit)
 | 
				
			||||||
 | 
								return cb_table[op].doit(skb, nlh, extack);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	/* FIXME: Convert IWCM to properly handle doit callbacks */
 | 
						/* FIXME: Convert IWCM to properly handle doit callbacks */
 | 
				
			||||||
	if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_RDMA_CM ||
 | 
						if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_RDMA_CM ||
 | 
				
			||||||
	    index == RDMA_NL_IWCM) {
 | 
						    index == RDMA_NL_IWCM) {
 | 
				
			||||||
		struct netlink_dump_control c = {
 | 
							struct netlink_dump_control c = {
 | 
				
			||||||
			.dump = cb_table[op].dump,
 | 
								.dump = cb_table[op].dump,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		return netlink_dump_start(nls, skb, nlh, &c);
 | 
							if (c.dump)
 | 
				
			||||||
 | 
								return netlink_dump_start(nls, skb, nlh, &c);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cb_table[op].doit)
 | 
						if (cb_table[op].doit)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1258,6 +1258,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
 | 
				
			||||||
	{ "ELAN0605", 0 },
 | 
						{ "ELAN0605", 0 },
 | 
				
			||||||
	{ "ELAN0609", 0 },
 | 
						{ "ELAN0609", 0 },
 | 
				
			||||||
	{ "ELAN060B", 0 },
 | 
						{ "ELAN060B", 0 },
 | 
				
			||||||
 | 
						{ "ELAN0611", 0 },
 | 
				
			||||||
	{ "ELAN1000", 0 },
 | 
						{ "ELAN1000", 0 },
 | 
				
			||||||
	{ }
 | 
						{ }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -232,9 +232,10 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
 | 
				
			||||||
	unsigned int trackstick_button = BTN_LEFT;
 | 
						unsigned int trackstick_button = BTN_LEFT;
 | 
				
			||||||
	bool button_mapped = false;
 | 
						bool button_mapped = false;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
						int button_count = min_t(u8, f30->gpioled_count, TRACKSTICK_RANGE_END);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f30->gpioled_key_map = devm_kcalloc(&fn->dev,
 | 
						f30->gpioled_key_map = devm_kcalloc(&fn->dev,
 | 
				
			||||||
					    f30->gpioled_count,
 | 
										    button_count,
 | 
				
			||||||
					    sizeof(f30->gpioled_key_map[0]),
 | 
										    sizeof(f30->gpioled_key_map[0]),
 | 
				
			||||||
					    GFP_KERNEL);
 | 
										    GFP_KERNEL);
 | 
				
			||||||
	if (!f30->gpioled_key_map) {
 | 
						if (!f30->gpioled_key_map) {
 | 
				
			||||||
| 
						 | 
					@ -242,7 +243,7 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < f30->gpioled_count; i++) {
 | 
						for (i = 0; i < button_count; i++) {
 | 
				
			||||||
		if (!rmi_f30_is_valid_button(i, f30->ctrl))
 | 
							if (!rmi_f30_is_valid_button(i, f30->ctrl))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,13 +230,17 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Walk  this report and pull out the info we need */
 | 
						/* Walk  this report and pull out the info we need */
 | 
				
			||||||
	while (i < length) {
 | 
						while (i < length) {
 | 
				
			||||||
		prefix = report[i];
 | 
							prefix = report[i++];
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Skip over prefix */
 | 
					 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Determine data size and save the data in the proper variable */
 | 
							/* Determine data size and save the data in the proper variable */
 | 
				
			||||||
		size = PREF_SIZE(prefix);
 | 
							size = (1U << PREF_SIZE(prefix)) >> 1;
 | 
				
			||||||
 | 
							if (i + size > length) {
 | 
				
			||||||
 | 
								dev_err(ddev,
 | 
				
			||||||
 | 
									"Not enough data (need %d, have %d)\n",
 | 
				
			||||||
 | 
									i + size, length);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (size) {
 | 
							switch (size) {
 | 
				
			||||||
		case 1:
 | 
							case 1:
 | 
				
			||||||
			data = report[i];
 | 
								data = report[i];
 | 
				
			||||||
| 
						 | 
					@ -244,8 +248,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
 | 
				
			||||||
		case 2:
 | 
							case 2:
 | 
				
			||||||
			data16 = get_unaligned_le16(&report[i]);
 | 
								data16 = get_unaligned_le16(&report[i]);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 3:
 | 
							case 4:
 | 
				
			||||||
			size = 4;
 | 
					 | 
				
			||||||
			data32 = get_unaligned_le32(&report[i]);
 | 
								data32 = get_unaligned_le32(&report[i]);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,10 @@ struct its_node {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ITS_ITT_ALIGN		SZ_256
 | 
					#define ITS_ITT_ALIGN		SZ_256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The maximum number of VPEID bits supported by VLPI commands */
 | 
				
			||||||
 | 
					#define ITS_MAX_VPEID_BITS	(16)
 | 
				
			||||||
 | 
					#define ITS_MAX_VPEID		(1 << (ITS_MAX_VPEID_BITS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Convert page order to size in bytes */
 | 
					/* Convert page order to size in bytes */
 | 
				
			||||||
#define PAGE_ORDER_TO_SIZE(o)	(PAGE_SIZE << (o))
 | 
					#define PAGE_ORDER_TO_SIZE(o)	(PAGE_SIZE << (o))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 | 
					static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
 | 
						its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 | 
					static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 | 
				
			||||||
| 
						 | 
					@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 | 
					static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
 | 
						its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 | 
					static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
 | 
				
			||||||
| 
						 | 
					@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
 | 
					static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
 | 
						its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
 | 
					static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
 | 
				
			||||||
| 
						 | 
					@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 | 
				
			||||||
	u64 val = its_read_baser(its, baser);
 | 
						u64 val = its_read_baser(its, baser);
 | 
				
			||||||
	u64 esz = GITS_BASER_ENTRY_SIZE(val);
 | 
						u64 esz = GITS_BASER_ENTRY_SIZE(val);
 | 
				
			||||||
	u64 type = GITS_BASER_TYPE(val);
 | 
						u64 type = GITS_BASER_TYPE(val);
 | 
				
			||||||
 | 
						u64 baser_phys, tmp;
 | 
				
			||||||
	u32 alloc_pages;
 | 
						u32 alloc_pages;
 | 
				
			||||||
	void *base;
 | 
						void *base;
 | 
				
			||||||
	u64 tmp;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
retry_alloc_baser:
 | 
					retry_alloc_baser:
 | 
				
			||||||
	alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
 | 
						alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
 | 
				
			||||||
| 
						 | 
					@ -1496,8 +1500,24 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 | 
				
			||||||
	if (!base)
 | 
						if (!base)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baser_phys = virt_to_phys(base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check if the physical address of the memory is above 48bits */
 | 
				
			||||||
 | 
						if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* 52bit PA is supported only when PageSize=64K */
 | 
				
			||||||
 | 
							if (psz != SZ_64K) {
 | 
				
			||||||
 | 
								pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
 | 
				
			||||||
 | 
								free_pages((unsigned long)base, order);
 | 
				
			||||||
 | 
								return -ENXIO;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Convert 52bit PA to 48bit field */
 | 
				
			||||||
 | 
							baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
retry_baser:
 | 
					retry_baser:
 | 
				
			||||||
	val = (virt_to_phys(base)				 |
 | 
						val = (baser_phys					 |
 | 
				
			||||||
		(type << GITS_BASER_TYPE_SHIFT)			 |
 | 
							(type << GITS_BASER_TYPE_SHIFT)			 |
 | 
				
			||||||
		((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT)	 |
 | 
							((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT)	 |
 | 
				
			||||||
		((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT)	 |
 | 
							((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT)	 |
 | 
				
			||||||
| 
						 | 
					@ -1582,13 +1602,12 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool its_parse_indirect_baser(struct its_node *its,
 | 
					static bool its_parse_indirect_baser(struct its_node *its,
 | 
				
			||||||
				     struct its_baser *baser,
 | 
									     struct its_baser *baser,
 | 
				
			||||||
				     u32 psz, u32 *order)
 | 
									     u32 psz, u32 *order, u32 ids)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 tmp = its_read_baser(its, baser);
 | 
						u64 tmp = its_read_baser(its, baser);
 | 
				
			||||||
	u64 type = GITS_BASER_TYPE(tmp);
 | 
						u64 type = GITS_BASER_TYPE(tmp);
 | 
				
			||||||
	u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
 | 
						u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
 | 
				
			||||||
	u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
 | 
						u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
 | 
				
			||||||
	u32 ids = its->device_ids;
 | 
					 | 
				
			||||||
	u32 new_order = *order;
 | 
						u32 new_order = *order;
 | 
				
			||||||
	bool indirect = false;
 | 
						bool indirect = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case GITS_BASER_TYPE_DEVICE:
 | 
							case GITS_BASER_TYPE_DEVICE:
 | 
				
			||||||
 | 
								indirect = its_parse_indirect_baser(its, baser,
 | 
				
			||||||
 | 
												    psz, &order,
 | 
				
			||||||
 | 
												    its->device_ids);
 | 
				
			||||||
		case GITS_BASER_TYPE_VCPU:
 | 
							case GITS_BASER_TYPE_VCPU:
 | 
				
			||||||
			indirect = its_parse_indirect_baser(its, baser,
 | 
								indirect = its_parse_indirect_baser(its, baser,
 | 
				
			||||||
							    psz, &order);
 | 
												    psz, &order,
 | 
				
			||||||
 | 
												    ITS_MAX_VPEID_BITS);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int its_vpe_id_alloc(void)
 | 
					static int its_vpe_id_alloc(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
 | 
						return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void its_vpe_id_free(u16 id)
 | 
					static void its_vpe_id_free(u16 id)
 | 
				
			||||||
| 
						 | 
					@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(entries != vpe_proxy.dev->nr_ites);
 | 
						BUG_ON(entries > vpe_proxy.dev->nr_ites);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	raw_spin_lock_init(&vpe_proxy.lock);
 | 
						raw_spin_lock_init(&vpe_proxy.lock);
 | 
				
			||||||
	vpe_proxy.next_victim = 0;
 | 
						vpe_proxy.next_victim = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc,
 | 
				
			||||||
	for (i = 0; i < 2; i++) {
 | 
						for (i = 0; i < 2; i++) {
 | 
				
			||||||
		ct[i].chip.irq_ack = irq_gc_ack_set_bit;
 | 
							ct[i].chip.irq_ack = irq_gc_ack_set_bit;
 | 
				
			||||||
		ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
 | 
							ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
 | 
				
			||||||
		ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack;
 | 
							ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
 | 
				
			||||||
		ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
 | 
							ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
 | 
				
			||||||
		ct[i].chip.irq_set_type = tangox_irq_set_type;
 | 
							ct[i].chip.irq_set_type = tangox_irq_set_type;
 | 
				
			||||||
		ct[i].chip.name = gc->domain->name;
 | 
							ct[i].chip.name = gc->domain->name;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -342,7 +342,7 @@ static int sun4i_can_start(struct net_device *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* enter the selected mode */
 | 
						/* enter the selected mode */
 | 
				
			||||||
	mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
 | 
						mod_reg_val = readl(priv->base + SUN4I_REG_MSEL_ADDR);
 | 
				
			||||||
	if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK)
 | 
						if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
 | 
				
			||||||
		mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE;
 | 
							mod_reg_val |= SUN4I_MSEL_LOOPBACK_MODE;
 | 
				
			||||||
	else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
 | 
						else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
 | 
				
			||||||
		mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE;
 | 
							mod_reg_val |= SUN4I_MSEL_LISTEN_ONLY_MODE;
 | 
				
			||||||
| 
						 | 
					@ -811,7 +811,6 @@ static int sun4ican_probe(struct platform_device *pdev)
 | 
				
			||||||
	priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
 | 
						priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
 | 
				
			||||||
				       CAN_CTRLMODE_LISTENONLY |
 | 
									       CAN_CTRLMODE_LISTENONLY |
 | 
				
			||||||
				       CAN_CTRLMODE_LOOPBACK |
 | 
									       CAN_CTRLMODE_LOOPBACK |
 | 
				
			||||||
				       CAN_CTRLMODE_PRESUME_ACK |
 | 
					 | 
				
			||||||
				       CAN_CTRLMODE_3_SAMPLES;
 | 
									       CAN_CTRLMODE_3_SAMPLES;
 | 
				
			||||||
	priv->base = addr;
 | 
						priv->base = addr;
 | 
				
			||||||
	priv->clk = clk;
 | 
						priv->clk = clk;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,6 +137,7 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id)
 | 
				
			||||||
#define CMD_RESET_ERROR_COUNTER		49
 | 
					#define CMD_RESET_ERROR_COUNTER		49
 | 
				
			||||||
#define CMD_TX_ACKNOWLEDGE		50
 | 
					#define CMD_TX_ACKNOWLEDGE		50
 | 
				
			||||||
#define CMD_CAN_ERROR_EVENT		51
 | 
					#define CMD_CAN_ERROR_EVENT		51
 | 
				
			||||||
 | 
					#define CMD_FLUSH_QUEUE_REPLY		68
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CMD_LEAF_USB_THROTTLE		77
 | 
					#define CMD_LEAF_USB_THROTTLE		77
 | 
				
			||||||
#define CMD_LEAF_LOG_MESSAGE		106
 | 
					#define CMD_LEAF_LOG_MESSAGE		106
 | 
				
			||||||
| 
						 | 
					@ -1301,6 +1302,11 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
 | 
				
			||||||
			goto warn;
 | 
								goto warn;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CMD_FLUSH_QUEUE_REPLY:
 | 
				
			||||||
 | 
							if (dev->family != KVASER_LEAF)
 | 
				
			||||||
 | 
								goto warn;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
warn:		dev_warn(dev->udev->dev.parent,
 | 
					warn:		dev_warn(dev->udev->dev.parent,
 | 
				
			||||||
			 "Unhandled message (%d)\n", msg->id);
 | 
								 "Unhandled message (%d)\n", msg->id);
 | 
				
			||||||
| 
						 | 
					@ -1609,7 +1615,8 @@ static int kvaser_usb_close(struct net_device *netdev)
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
 | 
							netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel))
 | 
						err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel);
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
		netdev_warn(netdev, "Cannot reset card, error %d\n", err);
 | 
							netdev_warn(netdev, "Cannot reset card, error %d\n", err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = kvaser_usb_stop_chip(priv);
 | 
						err = kvaser_usb_stop_chip(priv);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1824,11 +1824,12 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct e1000_adapter *adapter = netdev_priv(netdev);
 | 
						struct e1000_adapter *adapter = netdev_priv(netdev);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	char *p = NULL;
 | 
					 | 
				
			||||||
	const struct e1000_stats *stat = e1000_gstrings_stats;
 | 
						const struct e1000_stats *stat = e1000_gstrings_stats;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	e1000_update_stats(adapter);
 | 
						e1000_update_stats(adapter);
 | 
				
			||||||
	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
 | 
						for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++, stat++) {
 | 
				
			||||||
 | 
							char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (stat->type) {
 | 
							switch (stat->type) {
 | 
				
			||||||
		case NETDEV_STATS:
 | 
							case NETDEV_STATS:
 | 
				
			||||||
			p = (char *)netdev + stat->stat_offset;
 | 
								p = (char *)netdev + stat->stat_offset;
 | 
				
			||||||
| 
						 | 
					@ -1839,15 +1840,13 @@ static void e1000_get_ethtool_stats(struct net_device *netdev,
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
 | 
								WARN_ONCE(1, "Invalid E1000 stat type: %u index %d\n",
 | 
				
			||||||
				  stat->type, i);
 | 
									  stat->type, i);
 | 
				
			||||||
			break;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (stat->sizeof_stat == sizeof(u64))
 | 
							if (stat->sizeof_stat == sizeof(u64))
 | 
				
			||||||
			data[i] = *(u64 *)p;
 | 
								data[i] = *(u64 *)p;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			data[i] = *(u32 *)p;
 | 
								data[i] = *(u32 *)p;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		stat++;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
/* BUG_ON(i != E1000_STATS_LEN); */
 | 
					/* BUG_ON(i != E1000_STATS_LEN); */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -520,8 +520,6 @@ void e1000_down(struct e1000_adapter *adapter)
 | 
				
			||||||
	struct net_device *netdev = adapter->netdev;
 | 
						struct net_device *netdev = adapter->netdev;
 | 
				
			||||||
	u32 rctl, tctl;
 | 
						u32 rctl, tctl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	netif_carrier_off(netdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* disable receives in the hardware */
 | 
						/* disable receives in the hardware */
 | 
				
			||||||
	rctl = er32(RCTL);
 | 
						rctl = er32(RCTL);
 | 
				
			||||||
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
 | 
						ew32(RCTL, rctl & ~E1000_RCTL_EN);
 | 
				
			||||||
| 
						 | 
					@ -537,6 +535,15 @@ void e1000_down(struct e1000_adapter *adapter)
 | 
				
			||||||
	E1000_WRITE_FLUSH();
 | 
						E1000_WRITE_FLUSH();
 | 
				
			||||||
	msleep(10);
 | 
						msleep(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Set the carrier off after transmits have been disabled in the
 | 
				
			||||||
 | 
						 * hardware, to avoid race conditions with e1000_watchdog() (which
 | 
				
			||||||
 | 
						 * may be running concurrently to us, checking for the carrier
 | 
				
			||||||
 | 
						 * bit to decide whether it should enable transmits again). Such
 | 
				
			||||||
 | 
						 * a race condition would result into transmission being disabled
 | 
				
			||||||
 | 
						 * in the hardware until the next IFF_DOWN+IFF_UP cycle.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						netif_carrier_off(netdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	napi_disable(&adapter->napi);
 | 
						napi_disable(&adapter->napi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	e1000_irq_disable(adapter);
 | 
						e1000_irq_disable(adapter);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2111,6 +2111,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (unlikely(i40e_rx_is_programming_status(qword))) {
 | 
							if (unlikely(i40e_rx_is_programming_status(qword))) {
 | 
				
			||||||
			i40e_clean_programming_status(rx_ring, rx_desc, qword);
 | 
								i40e_clean_programming_status(rx_ring, rx_desc, qword);
 | 
				
			||||||
 | 
								cleaned_count++;
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
 | 
							size = (qword & I40E_RXD_QW1_LENGTH_PBUF_MASK) >>
 | 
				
			||||||
| 
						 | 
					@ -2277,7 +2278,7 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
 | 
				
			||||||
		goto enable_int;
 | 
							goto enable_int;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ITR_IS_DYNAMIC(tx_itr_setting)) {
 | 
						if (ITR_IS_DYNAMIC(rx_itr_setting)) {
 | 
				
			||||||
		rx = i40e_set_new_dynamic_itr(&q_vector->rx);
 | 
							rx = i40e_set_new_dynamic_itr(&q_vector->rx);
 | 
				
			||||||
		rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
 | 
							rxval = i40e_buildreg_itr(I40E_RX_ITR, q_vector->rx.itr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5673,7 +5673,7 @@ static int igb_tx_map(struct igb_ring *tx_ring,
 | 
				
			||||||
				       DMA_TO_DEVICE);
 | 
									       DMA_TO_DEVICE);
 | 
				
			||||||
		dma_unmap_len_set(tx_buffer, len, 0);
 | 
							dma_unmap_len_set(tx_buffer, len, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (i--)
 | 
							if (i-- == 0)
 | 
				
			||||||
			i += tx_ring->count;
 | 
								i += tx_ring->count;
 | 
				
			||||||
		tx_buffer = &tx_ring->tx_buffer_info[i];
 | 
							tx_buffer = &tx_ring->tx_buffer_info[i];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8156,29 +8156,23 @@ static int ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
dma_error:
 | 
					dma_error:
 | 
				
			||||||
	dev_err(tx_ring->dev, "TX DMA map failed\n");
 | 
						dev_err(tx_ring->dev, "TX DMA map failed\n");
 | 
				
			||||||
	tx_buffer = &tx_ring->tx_buffer_info[i];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear dma mappings for failed tx_buffer_info map */
 | 
						/* clear dma mappings for failed tx_buffer_info map */
 | 
				
			||||||
	while (tx_buffer != first) {
 | 
						for (;;) {
 | 
				
			||||||
 | 
							tx_buffer = &tx_ring->tx_buffer_info[i];
 | 
				
			||||||
		if (dma_unmap_len(tx_buffer, len))
 | 
							if (dma_unmap_len(tx_buffer, len))
 | 
				
			||||||
			dma_unmap_page(tx_ring->dev,
 | 
								dma_unmap_page(tx_ring->dev,
 | 
				
			||||||
				       dma_unmap_addr(tx_buffer, dma),
 | 
									       dma_unmap_addr(tx_buffer, dma),
 | 
				
			||||||
				       dma_unmap_len(tx_buffer, len),
 | 
									       dma_unmap_len(tx_buffer, len),
 | 
				
			||||||
				       DMA_TO_DEVICE);
 | 
									       DMA_TO_DEVICE);
 | 
				
			||||||
		dma_unmap_len_set(tx_buffer, len, 0);
 | 
							dma_unmap_len_set(tx_buffer, len, 0);
 | 
				
			||||||
 | 
							if (tx_buffer == first)
 | 
				
			||||||
		if (i--)
 | 
								break;
 | 
				
			||||||
 | 
							if (i == 0)
 | 
				
			||||||
			i += tx_ring->count;
 | 
								i += tx_ring->count;
 | 
				
			||||||
		tx_buffer = &tx_ring->tx_buffer_info[i];
 | 
							i--;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dma_unmap_len(tx_buffer, len))
 | 
					 | 
				
			||||||
		dma_unmap_single(tx_ring->dev,
 | 
					 | 
				
			||||||
				 dma_unmap_addr(tx_buffer, dma),
 | 
					 | 
				
			||||||
				 dma_unmap_len(tx_buffer, len),
 | 
					 | 
				
			||||||
				 DMA_TO_DEVICE);
 | 
					 | 
				
			||||||
	dma_unmap_len_set(tx_buffer, len, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dev_kfree_skb_any(first->skb);
 | 
						dev_kfree_skb_any(first->skb);
 | 
				
			||||||
	first->skb = NULL;
 | 
						first->skb = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1167,6 +1167,11 @@ struct mvpp2_bm_pool {
 | 
				
			||||||
	u32 port_map;
 | 
						u32 port_map;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define IS_TSO_HEADER(txq_pcpu, addr) \
 | 
				
			||||||
 | 
						((addr) >= (txq_pcpu)->tso_headers_dma && \
 | 
				
			||||||
 | 
						 (addr) < (txq_pcpu)->tso_headers_dma + \
 | 
				
			||||||
 | 
						 (txq_pcpu)->size * TSO_HEADER_SIZE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Queue modes */
 | 
					/* Queue modes */
 | 
				
			||||||
#define MVPP2_QDIST_SINGLE_MODE	0
 | 
					#define MVPP2_QDIST_SINGLE_MODE	0
 | 
				
			||||||
#define MVPP2_QDIST_MULTI_MODE	1
 | 
					#define MVPP2_QDIST_MULTI_MODE	1
 | 
				
			||||||
| 
						 | 
					@ -1534,7 +1539,7 @@ static bool mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offs,
 | 
				
			||||||
	int off = MVPP2_PRS_TCAM_DATA_BYTE(offs);
 | 
						int off = MVPP2_PRS_TCAM_DATA_BYTE(offs);
 | 
				
			||||||
	u16 tcam_data;
 | 
						u16 tcam_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tcam_data = (8 << pe->tcam.byte[off + 1]) | pe->tcam.byte[off];
 | 
						tcam_data = (pe->tcam.byte[off + 1] << 8) | pe->tcam.byte[off];
 | 
				
			||||||
	if (tcam_data != data)
 | 
						if (tcam_data != data)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
| 
						 | 
					@ -2609,8 +2614,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv)
 | 
				
			||||||
	/* place holders only - no ports */
 | 
						/* place holders only - no ports */
 | 
				
			||||||
	mvpp2_prs_mac_drop_all_set(priv, 0, false);
 | 
						mvpp2_prs_mac_drop_all_set(priv, 0, false);
 | 
				
			||||||
	mvpp2_prs_mac_promisc_set(priv, 0, false);
 | 
						mvpp2_prs_mac_promisc_set(priv, 0, false);
 | 
				
			||||||
	mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_ALL, 0, false);
 | 
						mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_ALL, false);
 | 
				
			||||||
	mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_IP6, 0, false);
 | 
						mvpp2_prs_mac_multi_set(priv, 0, MVPP2_PE_MAC_MC_IP6, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Set default entries for various types of dsa packets */
 | 
					/* Set default entries for various types of dsa packets */
 | 
				
			||||||
| 
						 | 
					@ -3391,7 +3396,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
 | 
				
			||||||
	struct mvpp2_prs_entry *pe;
 | 
						struct mvpp2_prs_entry *pe;
 | 
				
			||||||
	int tid;
 | 
						int tid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pe = kzalloc(sizeof(*pe), GFP_KERNEL);
 | 
						pe = kzalloc(sizeof(*pe), GFP_ATOMIC);
 | 
				
			||||||
	if (!pe)
 | 
						if (!pe)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
 | 
						mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
 | 
				
			||||||
| 
						 | 
					@ -3453,7 +3458,7 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
 | 
				
			||||||
		if (tid < 0)
 | 
							if (tid < 0)
 | 
				
			||||||
			return tid;
 | 
								return tid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pe = kzalloc(sizeof(*pe), GFP_KERNEL);
 | 
							pe = kzalloc(sizeof(*pe), GFP_ATOMIC);
 | 
				
			||||||
		if (!pe)
 | 
							if (!pe)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
		mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
 | 
							mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
 | 
				
			||||||
| 
						 | 
					@ -5321,8 +5326,9 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 | 
				
			||||||
		struct mvpp2_txq_pcpu_buf *tx_buf =
 | 
							struct mvpp2_txq_pcpu_buf *tx_buf =
 | 
				
			||||||
			txq_pcpu->buffs + txq_pcpu->txq_get_index;
 | 
								txq_pcpu->buffs + txq_pcpu->txq_get_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dma_unmap_single(port->dev->dev.parent, tx_buf->dma,
 | 
							if (!IS_TSO_HEADER(txq_pcpu, tx_buf->dma))
 | 
				
			||||||
				 tx_buf->size, DMA_TO_DEVICE);
 | 
								dma_unmap_single(port->dev->dev.parent, tx_buf->dma,
 | 
				
			||||||
 | 
										 tx_buf->size, DMA_TO_DEVICE);
 | 
				
			||||||
		if (tx_buf->skb)
 | 
							if (tx_buf->skb)
 | 
				
			||||||
			dev_kfree_skb_any(tx_buf->skb);
 | 
								dev_kfree_skb_any(tx_buf->skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5609,7 +5615,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		txq_pcpu->tso_headers =
 | 
							txq_pcpu->tso_headers =
 | 
				
			||||||
			dma_alloc_coherent(port->dev->dev.parent,
 | 
								dma_alloc_coherent(port->dev->dev.parent,
 | 
				
			||||||
					   MVPP2_AGGR_TXQ_SIZE * TSO_HEADER_SIZE,
 | 
										   txq_pcpu->size * TSO_HEADER_SIZE,
 | 
				
			||||||
					   &txq_pcpu->tso_headers_dma,
 | 
										   &txq_pcpu->tso_headers_dma,
 | 
				
			||||||
					   GFP_KERNEL);
 | 
										   GFP_KERNEL);
 | 
				
			||||||
		if (!txq_pcpu->tso_headers)
 | 
							if (!txq_pcpu->tso_headers)
 | 
				
			||||||
| 
						 | 
					@ -5623,7 +5629,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
 | 
				
			||||||
		kfree(txq_pcpu->buffs);
 | 
							kfree(txq_pcpu->buffs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dma_free_coherent(port->dev->dev.parent,
 | 
							dma_free_coherent(port->dev->dev.parent,
 | 
				
			||||||
				  MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE,
 | 
									  txq_pcpu->size * TSO_HEADER_SIZE,
 | 
				
			||||||
				  txq_pcpu->tso_headers,
 | 
									  txq_pcpu->tso_headers,
 | 
				
			||||||
				  txq_pcpu->tso_headers_dma);
 | 
									  txq_pcpu->tso_headers_dma);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -5647,7 +5653,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,
 | 
				
			||||||
		kfree(txq_pcpu->buffs);
 | 
							kfree(txq_pcpu->buffs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dma_free_coherent(port->dev->dev.parent,
 | 
							dma_free_coherent(port->dev->dev.parent,
 | 
				
			||||||
				  MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE,
 | 
									  txq_pcpu->size * TSO_HEADER_SIZE,
 | 
				
			||||||
				  txq_pcpu->tso_headers,
 | 
									  txq_pcpu->tso_headers,
 | 
				
			||||||
				  txq_pcpu->tso_headers_dma);
 | 
									  txq_pcpu->tso_headers_dma);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -6212,12 +6218,15 @@ static inline void
 | 
				
			||||||
tx_desc_unmap_put(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
 | 
					tx_desc_unmap_put(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
 | 
				
			||||||
		  struct mvpp2_tx_desc *desc)
 | 
							  struct mvpp2_tx_desc *desc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_addr_t buf_dma_addr =
 | 
						dma_addr_t buf_dma_addr =
 | 
				
			||||||
		mvpp2_txdesc_dma_addr_get(port, desc);
 | 
							mvpp2_txdesc_dma_addr_get(port, desc);
 | 
				
			||||||
	size_t buf_sz =
 | 
						size_t buf_sz =
 | 
				
			||||||
		mvpp2_txdesc_size_get(port, desc);
 | 
							mvpp2_txdesc_size_get(port, desc);
 | 
				
			||||||
	dma_unmap_single(port->dev->dev.parent, buf_dma_addr,
 | 
						if (!IS_TSO_HEADER(txq_pcpu, buf_dma_addr))
 | 
				
			||||||
			 buf_sz, DMA_TO_DEVICE);
 | 
							dma_unmap_single(port->dev->dev.parent, buf_dma_addr,
 | 
				
			||||||
 | 
									 buf_sz, DMA_TO_DEVICE);
 | 
				
			||||||
	mvpp2_txq_desc_put(txq);
 | 
						mvpp2_txq_desc_put(txq);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6489,7 +6498,7 @@ static int mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Finalize TX processing */
 | 
						/* Finalize TX processing */
 | 
				
			||||||
	if (txq_pcpu->count >= txq->done_pkts_coal)
 | 
						if (!port->has_tx_irqs && txq_pcpu->count >= txq->done_pkts_coal)
 | 
				
			||||||
		mvpp2_txq_done(port, txq, txq_pcpu);
 | 
							mvpp2_txq_done(port, txq, txq_pcpu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set the timer in case not all frags were processed */
 | 
						/* Set the timer in case not all frags were processed */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,35 +77,41 @@ static void add_delayed_event(struct mlx5_priv *priv,
 | 
				
			||||||
	list_add_tail(&delayed_event->list, &priv->waiting_events_list);
 | 
						list_add_tail(&delayed_event->list, &priv->waiting_events_list);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void fire_delayed_event_locked(struct mlx5_device_context *dev_ctx,
 | 
					static void delayed_event_release(struct mlx5_device_context *dev_ctx,
 | 
				
			||||||
				      struct mlx5_core_dev *dev,
 | 
									  struct mlx5_priv *priv)
 | 
				
			||||||
				      struct mlx5_priv *priv)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mlx5_core_dev *dev = container_of(priv, struct mlx5_core_dev, priv);
 | 
				
			||||||
	struct mlx5_delayed_event *de;
 | 
						struct mlx5_delayed_event *de;
 | 
				
			||||||
	struct mlx5_delayed_event *n;
 | 
						struct mlx5_delayed_event *n;
 | 
				
			||||||
 | 
						struct list_head temp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&temp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock_irq(&priv->ctx_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* stop delaying events */
 | 
					 | 
				
			||||||
	priv->is_accum_events = false;
 | 
						priv->is_accum_events = false;
 | 
				
			||||||
 | 
						list_splice_init(&priv->waiting_events_list, &temp);
 | 
				
			||||||
	/* fire all accumulated events before new event comes */
 | 
						if (!dev_ctx->context)
 | 
				
			||||||
	list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) {
 | 
							goto out;
 | 
				
			||||||
 | 
						list_for_each_entry_safe(de, n, &priv->waiting_events_list, list)
 | 
				
			||||||
		dev_ctx->intf->event(dev, dev_ctx->context, de->event, de->param);
 | 
							dev_ctx->intf->event(dev, dev_ctx->context, de->event, de->param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						spin_unlock_irq(&priv->ctx_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry_safe(de, n, &temp, list) {
 | 
				
			||||||
		list_del(&de->list);
 | 
							list_del(&de->list);
 | 
				
			||||||
		kfree(de);
 | 
							kfree(de);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cleanup_delayed_evets(struct mlx5_priv *priv)
 | 
					/* accumulating events that can come after mlx5_ib calls to
 | 
				
			||||||
 | 
					 * ib_register_device, till adding that interface to the events list.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void delayed_event_start(struct mlx5_priv *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5_delayed_event *de;
 | 
					 | 
				
			||||||
	struct mlx5_delayed_event *n;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spin_lock_irq(&priv->ctx_lock);
 | 
						spin_lock_irq(&priv->ctx_lock);
 | 
				
			||||||
	priv->is_accum_events = false;
 | 
						priv->is_accum_events = true;
 | 
				
			||||||
	list_for_each_entry_safe(de, n, &priv->waiting_events_list, list) {
 | 
					 | 
				
			||||||
		list_del(&de->list);
 | 
					 | 
				
			||||||
		kfree(de);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	spin_unlock_irq(&priv->ctx_lock);
 | 
						spin_unlock_irq(&priv->ctx_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,11 +128,8 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_ctx->intf = intf;
 | 
						dev_ctx->intf = intf;
 | 
				
			||||||
	/* accumulating events that can come after mlx5_ib calls to
 | 
					 | 
				
			||||||
	 * ib_register_device, till adding that interface to the events list.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv->is_accum_events = true;
 | 
						delayed_event_start(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_ctx->context = intf->add(dev);
 | 
						dev_ctx->context = intf->add(dev);
 | 
				
			||||||
	set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
 | 
						set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
 | 
				
			||||||
| 
						 | 
					@ -137,8 +140,6 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
 | 
				
			||||||
		spin_lock_irq(&priv->ctx_lock);
 | 
							spin_lock_irq(&priv->ctx_lock);
 | 
				
			||||||
		list_add_tail(&dev_ctx->list, &priv->ctx_list);
 | 
							list_add_tail(&dev_ctx->list, &priv->ctx_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fire_delayed_event_locked(dev_ctx, dev, priv);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 | 
					#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
 | 
				
			||||||
		if (dev_ctx->intf->pfault) {
 | 
							if (dev_ctx->intf->pfault) {
 | 
				
			||||||
			if (priv->pfault) {
 | 
								if (priv->pfault) {
 | 
				
			||||||
| 
						 | 
					@ -150,11 +151,12 @@ void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		spin_unlock_irq(&priv->ctx_lock);
 | 
							spin_unlock_irq(&priv->ctx_lock);
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		kfree(dev_ctx);
 | 
					 | 
				
			||||||
		 /* delete all accumulated events */
 | 
					 | 
				
			||||||
		cleanup_delayed_evets(priv);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delayed_event_release(dev_ctx, priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dev_ctx->context)
 | 
				
			||||||
 | 
							kfree(dev_ctx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mlx5_device_context *mlx5_get_device(struct mlx5_interface *intf,
 | 
					static struct mlx5_device_context *mlx5_get_device(struct mlx5_interface *intf,
 | 
				
			||||||
| 
						 | 
					@ -205,17 +207,21 @@ static void mlx5_attach_interface(struct mlx5_interface *intf, struct mlx5_priv
 | 
				
			||||||
	if (!dev_ctx)
 | 
						if (!dev_ctx)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delayed_event_start(priv);
 | 
				
			||||||
	if (intf->attach) {
 | 
						if (intf->attach) {
 | 
				
			||||||
		if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))
 | 
							if (test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state))
 | 
				
			||||||
			return;
 | 
								goto out;
 | 
				
			||||||
		intf->attach(dev, dev_ctx->context);
 | 
							intf->attach(dev, dev_ctx->context);
 | 
				
			||||||
		set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
 | 
							set_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
 | 
							if (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state))
 | 
				
			||||||
			return;
 | 
								goto out;
 | 
				
			||||||
		dev_ctx->context = intf->add(dev);
 | 
							dev_ctx->context = intf->add(dev);
 | 
				
			||||||
		set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
 | 
							set_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						delayed_event_release(dev_ctx, priv);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void mlx5_attach_device(struct mlx5_core_dev *dev)
 | 
					void mlx5_attach_device(struct mlx5_core_dev *dev)
 | 
				
			||||||
| 
						 | 
					@ -414,8 +420,14 @@ void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
 | 
				
			||||||
	if (priv->is_accum_events)
 | 
						if (priv->is_accum_events)
 | 
				
			||||||
		add_delayed_event(priv, dev, event, param);
 | 
							add_delayed_event(priv, dev, event, param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* After mlx5_detach_device, the dev_ctx->intf is still set and dev_ctx is
 | 
				
			||||||
 | 
						 * still in priv->ctx_list. In this case, only notify the dev_ctx if its
 | 
				
			||||||
 | 
						 * ADDED or ATTACHED bit are set.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	list_for_each_entry(dev_ctx, &priv->ctx_list, list)
 | 
						list_for_each_entry(dev_ctx, &priv->ctx_list, list)
 | 
				
			||||||
		if (dev_ctx->intf->event)
 | 
							if (dev_ctx->intf->event &&
 | 
				
			||||||
 | 
							    (test_bit(MLX5_INTERFACE_ADDED, &dev_ctx->state) ||
 | 
				
			||||||
 | 
							     test_bit(MLX5_INTERFACE_ATTACHED, &dev_ctx->state)))
 | 
				
			||||||
			dev_ctx->intf->event(dev, dev_ctx->context, event, param);
 | 
								dev_ctx->intf->event(dev, dev_ctx->context, event, param);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irqrestore(&priv->ctx_lock, flags);
 | 
						spin_unlock_irqrestore(&priv->ctx_lock, flags);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,11 @@
 | 
				
			||||||
#define MLX5E_CEE_STATE_UP    1
 | 
					#define MLX5E_CEE_STATE_UP    1
 | 
				
			||||||
#define MLX5E_CEE_STATE_DOWN  0
 | 
					#define MLX5E_CEE_STATE_DOWN  0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						MLX5E_VENDOR_TC_GROUP_NUM = 7,
 | 
				
			||||||
 | 
						MLX5E_LOWEST_PRIO_GROUP   = 0,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* If dcbx mode is non-host set the dcbx mode to host.
 | 
					/* If dcbx mode is non-host set the dcbx mode to host.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv,
 | 
					static int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv,
 | 
				
			||||||
| 
						 | 
					@ -85,6 +90,9 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5e_priv *priv = netdev_priv(netdev);
 | 
						struct mlx5e_priv *priv = netdev_priv(netdev);
 | 
				
			||||||
	struct mlx5_core_dev *mdev = priv->mdev;
 | 
						struct mlx5_core_dev *mdev = priv->mdev;
 | 
				
			||||||
 | 
						u8 tc_group[IEEE_8021QAZ_MAX_TCS];
 | 
				
			||||||
 | 
						bool is_tc_group_6_exist = false;
 | 
				
			||||||
 | 
						bool is_zero_bw_ets_tc = false;
 | 
				
			||||||
	int err = 0;
 | 
						int err = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,37 +104,64 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 | 
				
			||||||
		err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
 | 
							err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ets->ets_cap; i++) {
 | 
							err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]);
 | 
				
			||||||
 | 
							if (err)
 | 
				
			||||||
 | 
								return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = mlx5_query_port_tc_bw_alloc(mdev, i, &ets->tc_tx_bw[i]);
 | 
							err = mlx5_query_port_tc_bw_alloc(mdev, i, &ets->tc_tx_bw[i]);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			return err;
 | 
								return err;
 | 
				
			||||||
		if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC)
 | 
					
 | 
				
			||||||
			priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
 | 
							if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC &&
 | 
				
			||||||
 | 
							    tc_group[i] == (MLX5E_LOWEST_PRIO_GROUP + 1))
 | 
				
			||||||
 | 
								is_zero_bw_ets_tc = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tc_group[i] == (MLX5E_VENDOR_TC_GROUP_NUM - 1))
 | 
				
			||||||
 | 
								is_tc_group_6_exist = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Report 0% ets tc if exits*/
 | 
				
			||||||
 | 
						if (is_zero_bw_ets_tc) {
 | 
				
			||||||
 | 
							for (i = 0; i < ets->ets_cap; i++)
 | 
				
			||||||
 | 
								if (tc_group[i] == MLX5E_LOWEST_PRIO_GROUP)
 | 
				
			||||||
 | 
									ets->tc_tx_bw[i] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update tc_tsa based on fw setting*/
 | 
				
			||||||
 | 
						for (i = 0; i < ets->ets_cap; i++) {
 | 
				
			||||||
 | 
							if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC)
 | 
				
			||||||
 | 
								priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
 | 
				
			||||||
 | 
							else if (tc_group[i] == MLX5E_VENDOR_TC_GROUP_NUM &&
 | 
				
			||||||
 | 
								 !is_tc_group_6_exist)
 | 
				
			||||||
 | 
								priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa));
 | 
						memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
	MLX5E_VENDOR_TC_GROUP_NUM = 7,
 | 
					 | 
				
			||||||
	MLX5E_ETS_TC_GROUP_NUM    = 0,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc)
 | 
					static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool any_tc_mapped_to_ets = false;
 | 
						bool any_tc_mapped_to_ets = false;
 | 
				
			||||||
 | 
						bool ets_zero_bw = false;
 | 
				
			||||||
	int strict_group;
 | 
						int strict_group;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i <= max_tc; i++)
 | 
						for (i = 0; i <= max_tc; i++) {
 | 
				
			||||||
		if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS)
 | 
							if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
 | 
				
			||||||
			any_tc_mapped_to_ets = true;
 | 
								any_tc_mapped_to_ets = true;
 | 
				
			||||||
 | 
								if (!ets->tc_tx_bw[i])
 | 
				
			||||||
 | 
									ets_zero_bw = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	strict_group = any_tc_mapped_to_ets ? 1 : 0;
 | 
						/* strict group has higher priority than ets group */
 | 
				
			||||||
 | 
						strict_group = MLX5E_LOWEST_PRIO_GROUP;
 | 
				
			||||||
 | 
						if (any_tc_mapped_to_ets)
 | 
				
			||||||
 | 
							strict_group++;
 | 
				
			||||||
 | 
						if (ets_zero_bw)
 | 
				
			||||||
 | 
							strict_group++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i <= max_tc; i++) {
 | 
						for (i = 0; i <= max_tc; i++) {
 | 
				
			||||||
		switch (ets->tc_tsa[i]) {
 | 
							switch (ets->tc_tsa[i]) {
 | 
				
			||||||
| 
						 | 
					@ -137,7 +172,9 @@ static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc)
 | 
				
			||||||
			tc_group[i] = strict_group++;
 | 
								tc_group[i] = strict_group++;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case IEEE_8021QAZ_TSA_ETS:
 | 
							case IEEE_8021QAZ_TSA_ETS:
 | 
				
			||||||
			tc_group[i] = MLX5E_ETS_TC_GROUP_NUM;
 | 
								tc_group[i] = MLX5E_LOWEST_PRIO_GROUP;
 | 
				
			||||||
 | 
								if (ets->tc_tx_bw[i] && ets_zero_bw)
 | 
				
			||||||
 | 
									tc_group[i] = MLX5E_LOWEST_PRIO_GROUP + 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -146,8 +183,22 @@ static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc)
 | 
				
			||||||
static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw,
 | 
					static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw,
 | 
				
			||||||
				 u8 *tc_group, int max_tc)
 | 
									 u8 *tc_group, int max_tc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						int bw_for_ets_zero_bw_tc = 0;
 | 
				
			||||||
 | 
						int last_ets_zero_bw_tc = -1;
 | 
				
			||||||
 | 
						int num_ets_zero_bw = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i <= max_tc; i++) {
 | 
				
			||||||
 | 
							if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS &&
 | 
				
			||||||
 | 
							    !ets->tc_tx_bw[i]) {
 | 
				
			||||||
 | 
								num_ets_zero_bw++;
 | 
				
			||||||
 | 
								last_ets_zero_bw_tc = i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (num_ets_zero_bw)
 | 
				
			||||||
 | 
							bw_for_ets_zero_bw_tc = MLX5E_MAX_BW_ALLOC / num_ets_zero_bw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i <= max_tc; i++) {
 | 
						for (i = 0; i <= max_tc; i++) {
 | 
				
			||||||
		switch (ets->tc_tsa[i]) {
 | 
							switch (ets->tc_tsa[i]) {
 | 
				
			||||||
		case IEEE_8021QAZ_TSA_VENDOR:
 | 
							case IEEE_8021QAZ_TSA_VENDOR:
 | 
				
			||||||
| 
						 | 
					@ -157,12 +208,26 @@ static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw,
 | 
				
			||||||
			tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
 | 
								tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case IEEE_8021QAZ_TSA_ETS:
 | 
							case IEEE_8021QAZ_TSA_ETS:
 | 
				
			||||||
			tc_tx_bw[i] = ets->tc_tx_bw[i];
 | 
								tc_tx_bw[i] = ets->tc_tx_bw[i] ?
 | 
				
			||||||
 | 
									      ets->tc_tx_bw[i] :
 | 
				
			||||||
 | 
									      bw_for_ets_zero_bw_tc;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure the total bw for ets zero bw group is 100% */
 | 
				
			||||||
 | 
						if (last_ets_zero_bw_tc != -1)
 | 
				
			||||||
 | 
							tc_tx_bw[last_ets_zero_bw_tc] +=
 | 
				
			||||||
 | 
								MLX5E_MAX_BW_ALLOC % num_ets_zero_bw;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* If there are ETS BW 0,
 | 
				
			||||||
 | 
					 *   Set ETS group # to 1 for all ETS non zero BW tcs. Their sum must be 100%.
 | 
				
			||||||
 | 
					 *   Set group #0 to all the ETS BW 0 tcs and
 | 
				
			||||||
 | 
					 *     equally splits the 100% BW between them
 | 
				
			||||||
 | 
					 *   Report both group #0 and #1 as ETS type.
 | 
				
			||||||
 | 
					 *     All the tcs in group #0 will be reported with 0% BW.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
 | 
					int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5_core_dev *mdev = priv->mdev;
 | 
						struct mlx5_core_dev *mdev = priv->mdev;
 | 
				
			||||||
| 
						 | 
					@ -188,7 +253,6 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
 | 
						memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,17 +273,9 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Validate Bandwidth Sum */
 | 
						/* Validate Bandwidth Sum */
 | 
				
			||||||
	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 | 
						for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 | 
				
			||||||
		if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
 | 
							if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS)
 | 
				
			||||||
			if (!ets->tc_tx_bw[i]) {
 | 
					 | 
				
			||||||
				netdev_err(netdev,
 | 
					 | 
				
			||||||
					   "Failed to validate ETS: BW 0 is illegal\n");
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			bw_sum += ets->tc_tx_bw[i];
 | 
								bw_sum += ets->tc_tx_bw[i];
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bw_sum != 0 && bw_sum != 100) {
 | 
						if (bw_sum != 0 && bw_sum != 100) {
 | 
				
			||||||
		netdev_err(netdev,
 | 
							netdev_err(netdev,
 | 
				
			||||||
| 
						 | 
					@ -533,8 +589,7 @@ static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
 | 
				
			||||||
static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
 | 
					static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
 | 
				
			||||||
				      int pgid, u8 *bw_pct)
 | 
									      int pgid, u8 *bw_pct)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5e_priv *priv = netdev_priv(netdev);
 | 
						struct ieee_ets ets;
 | 
				
			||||||
	struct mlx5_core_dev *mdev = priv->mdev;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pgid >= CEE_DCBX_MAX_PGS) {
 | 
						if (pgid >= CEE_DCBX_MAX_PGS) {
 | 
				
			||||||
		netdev_err(netdev,
 | 
							netdev_err(netdev,
 | 
				
			||||||
| 
						 | 
					@ -542,8 +597,8 @@ static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mlx5_query_port_tc_bw_alloc(mdev, pgid, bw_pct))
 | 
						mlx5e_dcbnl_ieee_getets(netdev, &ets);
 | 
				
			||||||
		*bw_pct = 0;
 | 
						*bw_pct = ets.tc_tx_bw[pgid];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
 | 
					static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
 | 
				
			||||||
| 
						 | 
					@ -739,8 +794,6 @@ static void mlx5e_ets_init(struct mlx5e_priv *priv)
 | 
				
			||||||
		ets.prio_tc[i] = i;
 | 
							ets.prio_tc[i] = i;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
 | 
						/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
 | 
				
			||||||
	ets.prio_tc[0] = 1;
 | 
						ets.prio_tc[0] = 1;
 | 
				
			||||||
	ets.prio_tc[1] = 0;
 | 
						ets.prio_tc[1] = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,9 +78,11 @@ struct mlx5e_tc_flow {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mlx5e_tc_flow_parse_attr {
 | 
					struct mlx5e_tc_flow_parse_attr {
 | 
				
			||||||
 | 
						struct ip_tunnel_info tun_info;
 | 
				
			||||||
	struct mlx5_flow_spec spec;
 | 
						struct mlx5_flow_spec spec;
 | 
				
			||||||
	int num_mod_hdr_actions;
 | 
						int num_mod_hdr_actions;
 | 
				
			||||||
	void *mod_hdr_actions;
 | 
						void *mod_hdr_actions;
 | 
				
			||||||
 | 
						int mirred_ifindex;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					@ -322,6 +324,12 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
static void mlx5e_detach_encap(struct mlx5e_priv *priv,
 | 
					static void mlx5e_detach_encap(struct mlx5e_priv *priv,
 | 
				
			||||||
			       struct mlx5e_tc_flow *flow);
 | 
								       struct mlx5e_tc_flow *flow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mlx5e_attach_encap(struct mlx5e_priv *priv,
 | 
				
			||||||
 | 
								      struct ip_tunnel_info *tun_info,
 | 
				
			||||||
 | 
								      struct net_device *mirred_dev,
 | 
				
			||||||
 | 
								      struct net_device **encap_dev,
 | 
				
			||||||
 | 
								      struct mlx5e_tc_flow *flow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mlx5_flow_handle *
 | 
					static struct mlx5_flow_handle *
 | 
				
			||||||
mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 | 
					mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
		      struct mlx5e_tc_flow_parse_attr *parse_attr,
 | 
							      struct mlx5e_tc_flow_parse_attr *parse_attr,
 | 
				
			||||||
| 
						 | 
					@ -329,9 +337,27 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 | 
						struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 | 
				
			||||||
	struct mlx5_esw_flow_attr *attr = flow->esw_attr;
 | 
						struct mlx5_esw_flow_attr *attr = flow->esw_attr;
 | 
				
			||||||
	struct mlx5_flow_handle *rule;
 | 
						struct net_device *out_dev, *encap_dev = NULL;
 | 
				
			||||||
 | 
						struct mlx5_flow_handle *rule = NULL;
 | 
				
			||||||
 | 
						struct mlx5e_rep_priv *rpriv;
 | 
				
			||||||
 | 
						struct mlx5e_priv *out_priv;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) {
 | 
				
			||||||
 | 
							out_dev = __dev_get_by_index(dev_net(priv->netdev),
 | 
				
			||||||
 | 
										     attr->parse_attr->mirred_ifindex);
 | 
				
			||||||
 | 
							err = mlx5e_attach_encap(priv, &parse_attr->tun_info,
 | 
				
			||||||
 | 
										 out_dev, &encap_dev, flow);
 | 
				
			||||||
 | 
							if (err) {
 | 
				
			||||||
 | 
								rule = ERR_PTR(err);
 | 
				
			||||||
 | 
								if (err != -EAGAIN)
 | 
				
			||||||
 | 
									goto err_attach_encap;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							out_priv = netdev_priv(encap_dev);
 | 
				
			||||||
 | 
							rpriv = out_priv->ppriv;
 | 
				
			||||||
 | 
							attr->out_rep = rpriv->rep;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = mlx5_eswitch_add_vlan_action(esw, attr);
 | 
						err = mlx5_eswitch_add_vlan_action(esw, attr);
 | 
				
			||||||
	if (err) {
 | 
						if (err) {
 | 
				
			||||||
		rule = ERR_PTR(err);
 | 
							rule = ERR_PTR(err);
 | 
				
			||||||
| 
						 | 
					@ -347,10 +373,14 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr);
 | 
						/* we get here if (1) there's no error (rule being null) or when
 | 
				
			||||||
	if (IS_ERR(rule))
 | 
						 * (2) there's an encap action and we're on -EAGAIN (no valid neigh)
 | 
				
			||||||
		goto err_add_rule;
 | 
						 */
 | 
				
			||||||
 | 
						if (rule != ERR_PTR(-EAGAIN)) {
 | 
				
			||||||
 | 
							rule = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr);
 | 
				
			||||||
 | 
							if (IS_ERR(rule))
 | 
				
			||||||
 | 
								goto err_add_rule;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return rule;
 | 
						return rule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_add_rule:
 | 
					err_add_rule:
 | 
				
			||||||
| 
						 | 
					@ -361,6 +391,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
err_add_vlan:
 | 
					err_add_vlan:
 | 
				
			||||||
	if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
 | 
						if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
 | 
				
			||||||
		mlx5e_detach_encap(priv, flow);
 | 
							mlx5e_detach_encap(priv, flow);
 | 
				
			||||||
 | 
					err_attach_encap:
 | 
				
			||||||
	return rule;
 | 
						return rule;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -389,6 +420,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
 | 
				
			||||||
void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
 | 
					void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
 | 
				
			||||||
			      struct mlx5e_encap_entry *e)
 | 
								      struct mlx5e_encap_entry *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 | 
				
			||||||
 | 
						struct mlx5_esw_flow_attr *esw_attr;
 | 
				
			||||||
	struct mlx5e_tc_flow *flow;
 | 
						struct mlx5e_tc_flow *flow;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -404,10 +437,9 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
 | 
				
			||||||
	mlx5e_rep_queue_neigh_stats_work(priv);
 | 
						mlx5e_rep_queue_neigh_stats_work(priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(flow, &e->flows, encap) {
 | 
						list_for_each_entry(flow, &e->flows, encap) {
 | 
				
			||||||
		flow->esw_attr->encap_id = e->encap_id;
 | 
							esw_attr = flow->esw_attr;
 | 
				
			||||||
		flow->rule = mlx5e_tc_add_fdb_flow(priv,
 | 
							esw_attr->encap_id = e->encap_id;
 | 
				
			||||||
						   flow->esw_attr->parse_attr,
 | 
							flow->rule = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
 | 
				
			||||||
						   flow);
 | 
					 | 
				
			||||||
		if (IS_ERR(flow->rule)) {
 | 
							if (IS_ERR(flow->rule)) {
 | 
				
			||||||
			err = PTR_ERR(flow->rule);
 | 
								err = PTR_ERR(flow->rule);
 | 
				
			||||||
			mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
 | 
								mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
 | 
				
			||||||
| 
						 | 
					@ -421,15 +453,13 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
 | 
				
			||||||
void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
 | 
					void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
 | 
				
			||||||
			      struct mlx5e_encap_entry *e)
 | 
								      struct mlx5e_encap_entry *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 | 
				
			||||||
	struct mlx5e_tc_flow *flow;
 | 
						struct mlx5e_tc_flow *flow;
 | 
				
			||||||
	struct mlx5_fc *counter;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(flow, &e->flows, encap) {
 | 
						list_for_each_entry(flow, &e->flows, encap) {
 | 
				
			||||||
		if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
 | 
							if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
 | 
				
			||||||
			flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
 | 
								flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
 | 
				
			||||||
			counter = mlx5_flow_rule_counter(flow->rule);
 | 
								mlx5_eswitch_del_offloaded_rule(esw, flow->rule, flow->esw_attr);
 | 
				
			||||||
			mlx5_del_flow_rules(flow->rule);
 | 
					 | 
				
			||||||
			mlx5_fc_destroy(priv->mdev, counter);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1942,7 +1972,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (is_tcf_mirred_egress_redirect(a)) {
 | 
							if (is_tcf_mirred_egress_redirect(a)) {
 | 
				
			||||||
			int ifindex = tcf_mirred_ifindex(a);
 | 
								int ifindex = tcf_mirred_ifindex(a);
 | 
				
			||||||
			struct net_device *out_dev, *encap_dev = NULL;
 | 
								struct net_device *out_dev;
 | 
				
			||||||
			struct mlx5e_priv *out_priv;
 | 
								struct mlx5e_priv *out_priv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			out_dev = __dev_get_by_index(dev_net(priv->netdev), ifindex);
 | 
								out_dev = __dev_get_by_index(dev_net(priv->netdev), ifindex);
 | 
				
			||||||
| 
						 | 
					@ -1955,17 +1985,13 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
 | 
				
			||||||
				rpriv = out_priv->ppriv;
 | 
									rpriv = out_priv->ppriv;
 | 
				
			||||||
				attr->out_rep = rpriv->rep;
 | 
									attr->out_rep = rpriv->rep;
 | 
				
			||||||
			} else if (encap) {
 | 
								} else if (encap) {
 | 
				
			||||||
				err = mlx5e_attach_encap(priv, info,
 | 
									parse_attr->mirred_ifindex = ifindex;
 | 
				
			||||||
							 out_dev, &encap_dev, flow);
 | 
									parse_attr->tun_info = *info;
 | 
				
			||||||
				if (err && err != -EAGAIN)
 | 
									attr->parse_attr = parse_attr;
 | 
				
			||||||
					return err;
 | 
					 | 
				
			||||||
				attr->action |= MLX5_FLOW_CONTEXT_ACTION_ENCAP |
 | 
									attr->action |= MLX5_FLOW_CONTEXT_ACTION_ENCAP |
 | 
				
			||||||
					MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
 | 
										MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
 | 
				
			||||||
					MLX5_FLOW_CONTEXT_ACTION_COUNT;
 | 
										MLX5_FLOW_CONTEXT_ACTION_COUNT;
 | 
				
			||||||
				out_priv = netdev_priv(encap_dev);
 | 
									/* attr->out_rep is resolved when we handle encap */
 | 
				
			||||||
				rpriv = out_priv->ppriv;
 | 
					 | 
				
			||||||
				attr->out_rep = rpriv->rep;
 | 
					 | 
				
			||||||
				attr->parse_attr = parse_attr;
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				pr_err("devices %s %s not on same switch HW, can't offload forwarding\n",
 | 
									pr_err("devices %s %s not on same switch HW, can't offload forwarding\n",
 | 
				
			||||||
				       priv->netdev->name, out_dev->name);
 | 
									       priv->netdev->name, out_dev->name);
 | 
				
			||||||
| 
						 | 
					@ -2047,7 +2073,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
 | 
				
			||||||
	if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
 | 
						if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
 | 
				
			||||||
		err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow);
 | 
							err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow);
 | 
				
			||||||
		if (err < 0)
 | 
							if (err < 0)
 | 
				
			||||||
			goto err_handle_encap_flow;
 | 
								goto err_free;
 | 
				
			||||||
		flow->rule = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
 | 
							flow->rule = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow);
 | 
							err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow);
 | 
				
			||||||
| 
						 | 
					@ -2058,10 +2084,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (IS_ERR(flow->rule)) {
 | 
						if (IS_ERR(flow->rule)) {
 | 
				
			||||||
		err = PTR_ERR(flow->rule);
 | 
							err = PTR_ERR(flow->rule);
 | 
				
			||||||
		goto err_free;
 | 
							if (err != -EAGAIN)
 | 
				
			||||||
 | 
								goto err_free;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
 | 
						if (err != -EAGAIN)
 | 
				
			||||||
 | 
							flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = rhashtable_insert_fast(&tc->ht, &flow->node,
 | 
						err = rhashtable_insert_fast(&tc->ht, &flow->node,
 | 
				
			||||||
				     tc->ht_params);
 | 
									     tc->ht_params);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
| 
						 | 
					@ -2075,16 +2104,6 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
 | 
				
			||||||
err_del_rule:
 | 
					err_del_rule:
 | 
				
			||||||
	mlx5e_tc_del_flow(priv, flow);
 | 
						mlx5e_tc_del_flow(priv, flow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_handle_encap_flow:
 | 
					 | 
				
			||||||
	if (err == -EAGAIN) {
 | 
					 | 
				
			||||||
		err = rhashtable_insert_fast(&tc->ht, &flow->node,
 | 
					 | 
				
			||||||
					     tc->ht_params);
 | 
					 | 
				
			||||||
		if (err)
 | 
					 | 
				
			||||||
			mlx5e_tc_del_flow(priv, flow);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
err_free:
 | 
					err_free:
 | 
				
			||||||
	kvfree(parse_attr);
 | 
						kvfree(parse_attr);
 | 
				
			||||||
	kfree(flow);
 | 
						kfree(flow);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,10 +354,11 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev)
 | 
				
			||||||
void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
 | 
					void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlx5_core_health *health = &dev->priv.health;
 | 
						struct mlx5_core_health *health = &dev->priv.health;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&health->wq_lock);
 | 
						spin_lock_irqsave(&health->wq_lock, flags);
 | 
				
			||||||
	set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
 | 
						set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
 | 
				
			||||||
	spin_unlock(&health->wq_lock);
 | 
						spin_unlock_irqrestore(&health->wq_lock, flags);
 | 
				
			||||||
	cancel_delayed_work_sync(&dev->priv.health.recover_work);
 | 
						cancel_delayed_work_sync(&dev->priv.health.recover_work);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -677,6 +677,27 @@ int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group);
 | 
					EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
 | 
				
			||||||
 | 
								     u8 tc, u8 *tc_group)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 out[MLX5_ST_SZ_DW(qetc_reg)];
 | 
				
			||||||
 | 
						void *ets_tcn_conf;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
 | 
				
			||||||
 | 
						if (err)
 | 
				
			||||||
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out,
 | 
				
			||||||
 | 
									    tc_configuration[tc]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*tc_group = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
 | 
				
			||||||
 | 
								     group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(mlx5_query_port_tc_group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
 | 
					int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {0};
 | 
						u32 in[MLX5_ST_SZ_DW(qetc_reg)] = {0};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,6 +127,8 @@ nfp_fl_output(struct nfp_fl_output *output, const struct tc_action *action,
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (!switchdev_port_same_parent_id(in_dev, out_dev))
 | 
							if (!switchdev_port_same_parent_id(in_dev, out_dev))
 | 
				
			||||||
			return -EOPNOTSUPP;
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
 | 
							if (!nfp_netdev_is_nfp_repr(out_dev))
 | 
				
			||||||
 | 
								return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		output->port = cpu_to_be32(nfp_repr_get_port_id(out_dev));
 | 
							output->port = cpu_to_be32(nfp_repr_get_port_id(out_dev));
 | 
				
			||||||
		if (!output->port)
 | 
							if (!output->port)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
 | 
				
			||||||
		plat_dat->axi->axi_wr_osr_lmt--;
 | 
							plat_dat->axi->axi_wr_osr_lmt--;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (of_property_read_u32(np, "read,read-requests",
 | 
						if (of_property_read_u32(np, "snps,read-requests",
 | 
				
			||||||
				 &plat_dat->axi->axi_rd_osr_lmt)) {
 | 
									 &plat_dat->axi->axi_rd_osr_lmt)) {
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * Since the register has a reset value of 1, if property
 | 
							 * Since the register has a reset value of 1, if property
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,13 @@ static void stmmac_mtl_setup(struct platform_device *pdev,
 | 
				
			||||||
	plat->rx_queues_to_use = 1;
 | 
						plat->rx_queues_to_use = 1;
 | 
				
			||||||
	plat->tx_queues_to_use = 1;
 | 
						plat->tx_queues_to_use = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* First Queue must always be in DCB mode. As MTL_QUEUE_DCB = 1 we need
 | 
				
			||||||
 | 
						 * to always set this, otherwise Queue will be classified as AVB
 | 
				
			||||||
 | 
						 * (because MTL_QUEUE_AVB = 0).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						plat->rx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
 | 
				
			||||||
 | 
						plat->tx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
 | 
						rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
 | 
				
			||||||
	if (!rx_node)
 | 
						if (!rx_node)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,8 +197,8 @@ static int ipvtap_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap");
 | 
						err = tap_create_cdev(&ipvtap_cdev, &ipvtap_major, "ipvtap",
 | 
				
			||||||
 | 
								      THIS_MODULE);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto out1;
 | 
							goto out1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -204,8 +204,8 @@ static int macvtap_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap");
 | 
						err = tap_create_cdev(&macvtap_cdev, &macvtap_major, "macvtap",
 | 
				
			||||||
 | 
								      THIS_MODULE);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto out1;
 | 
							goto out1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -517,6 +517,10 @@ static int tap_open(struct inode *inode, struct file *file)
 | 
				
			||||||
					     &tap_proto, 0);
 | 
										     &tap_proto, 0);
 | 
				
			||||||
	if (!q)
 | 
						if (!q)
 | 
				
			||||||
		goto err;
 | 
							goto err;
 | 
				
			||||||
 | 
						if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) {
 | 
				
			||||||
 | 
							sk_free(&q->sk);
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RCU_INIT_POINTER(q->sock.wq, &q->wq);
 | 
						RCU_INIT_POINTER(q->sock.wq, &q->wq);
 | 
				
			||||||
	init_waitqueue_head(&q->wq.wait);
 | 
						init_waitqueue_head(&q->wq.wait);
 | 
				
			||||||
| 
						 | 
					@ -540,22 +544,18 @@ static int tap_open(struct inode *inode, struct file *file)
 | 
				
			||||||
	if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG))
 | 
						if ((tap->dev->features & NETIF_F_HIGHDMA) && (tap->dev->features & NETIF_F_SG))
 | 
				
			||||||
		sock_set_flag(&q->sk, SOCK_ZEROCOPY);
 | 
							sock_set_flag(&q->sk, SOCK_ZEROCOPY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = -ENOMEM;
 | 
					 | 
				
			||||||
	if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL))
 | 
					 | 
				
			||||||
		goto err_array;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = tap_set_queue(tap, file, q);
 | 
						err = tap_set_queue(tap, file, q);
 | 
				
			||||||
	if (err)
 | 
						if (err) {
 | 
				
			||||||
		goto err_queue;
 | 
							/* tap_sock_destruct() will take care of freeing skb_array */
 | 
				
			||||||
 | 
							goto err_put;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_put(tap->dev);
 | 
						dev_put(tap->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_unlock();
 | 
						rtnl_unlock();
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_queue:
 | 
					err_put:
 | 
				
			||||||
	skb_array_cleanup(&q->skb_array);
 | 
					 | 
				
			||||||
err_array:
 | 
					 | 
				
			||||||
	sock_put(&q->sk);
 | 
						sock_put(&q->sk);
 | 
				
			||||||
err:
 | 
					err:
 | 
				
			||||||
	if (tap)
 | 
						if (tap)
 | 
				
			||||||
| 
						 | 
					@ -1249,8 +1249,8 @@ static int tap_list_add(dev_t major, const char *device_name)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int tap_create_cdev(struct cdev *tap_cdev,
 | 
					int tap_create_cdev(struct cdev *tap_cdev, dev_t *tap_major,
 | 
				
			||||||
		    dev_t *tap_major, const char *device_name)
 | 
							    const char *device_name, struct module *module)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1259,6 +1259,7 @@ int tap_create_cdev(struct cdev *tap_cdev,
 | 
				
			||||||
		goto out1;
 | 
							goto out1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cdev_init(tap_cdev, &tap_fops);
 | 
						cdev_init(tap_cdev, &tap_fops);
 | 
				
			||||||
 | 
						tap_cdev->owner = module;
 | 
				
			||||||
	err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS);
 | 
						err = cdev_add(tap_cdev, *tap_major, TAP_NUM_DEVS);
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		goto out2;
 | 
							goto out2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1444,6 +1444,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 | 
				
			||||||
	buflen += SKB_DATA_ALIGN(len + pad);
 | 
						buflen += SKB_DATA_ALIGN(len + pad);
 | 
				
			||||||
	rcu_read_unlock();
 | 
						rcu_read_unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						alloc_frag->offset = ALIGN((u64)alloc_frag->offset, SMP_CACHE_BYTES);
 | 
				
			||||||
	if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL)))
 | 
						if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL)))
 | 
				
			||||||
		return ERR_PTR(-ENOMEM);
 | 
							return ERR_PTR(-ENOMEM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2253,7 +2254,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 | 
				
			||||||
		if (!dev)
 | 
							if (!dev)
 | 
				
			||||||
			return -ENOMEM;
 | 
								return -ENOMEM;
 | 
				
			||||||
		err = dev_get_valid_name(net, dev, name);
 | 
							err = dev_get_valid_name(net, dev, name);
 | 
				
			||||||
		if (err)
 | 
							if (err < 0)
 | 
				
			||||||
			goto err_free_dev;
 | 
								goto err_free_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dev_net_set(dev, net);
 | 
							dev_net_set(dev, net);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -561,6 +561,7 @@ static const struct driver_info wwan_info = {
 | 
				
			||||||
#define HP_VENDOR_ID		0x03f0
 | 
					#define HP_VENDOR_ID		0x03f0
 | 
				
			||||||
#define MICROSOFT_VENDOR_ID	0x045e
 | 
					#define MICROSOFT_VENDOR_ID	0x045e
 | 
				
			||||||
#define UBLOX_VENDOR_ID		0x1546
 | 
					#define UBLOX_VENDOR_ID		0x1546
 | 
				
			||||||
 | 
					#define TPLINK_VENDOR_ID	0x2357
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct usb_device_id	products[] = {
 | 
					static const struct usb_device_id	products[] = {
 | 
				
			||||||
/* BLACKLIST !!
 | 
					/* BLACKLIST !!
 | 
				
			||||||
| 
						 | 
					@ -813,6 +814,13 @@ static const struct usb_device_id	products[] = {
 | 
				
			||||||
	.driver_info = 0,
 | 
						.driver_info = 0,
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM,
 | 
				
			||||||
 | 
								USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
 | 
				
			||||||
 | 
						.driver_info = 0,
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* WHITELIST!!!
 | 
					/* WHITELIST!!!
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * CDC Ether uses two interfaces, not necessarily consecutive.
 | 
					 * CDC Ether uses two interfaces, not necessarily consecutive.
 | 
				
			||||||
| 
						 | 
					@ -863,6 +871,12 @@ static const struct usb_device_id	products[] = {
 | 
				
			||||||
	USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x81ba, USB_CLASS_COMM,
 | 
						USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x81ba, USB_CLASS_COMM,
 | 
				
			||||||
			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
 | 
								USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
 | 
				
			||||||
	.driver_info = (kernel_ulong_t)&wwan_info,
 | 
						.driver_info = (kernel_ulong_t)&wwan_info,
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						/* Huawei ME906 and ME909 */
 | 
				
			||||||
 | 
						USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x15c1, USB_CLASS_COMM,
 | 
				
			||||||
 | 
									      USB_CDC_SUBCLASS_ETHERNET,
 | 
				
			||||||
 | 
									      USB_CDC_PROTO_NONE),
 | 
				
			||||||
 | 
						.driver_info = (unsigned long)&wwan_info,
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
	/* ZTE modules */
 | 
						/* ZTE modules */
 | 
				
			||||||
	USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM,
 | 
						USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -615,6 +615,7 @@ enum rtl8152_flags {
 | 
				
			||||||
#define VENDOR_ID_LENOVO		0x17ef
 | 
					#define VENDOR_ID_LENOVO		0x17ef
 | 
				
			||||||
#define VENDOR_ID_LINKSYS		0x13b1
 | 
					#define VENDOR_ID_LINKSYS		0x13b1
 | 
				
			||||||
#define VENDOR_ID_NVIDIA		0x0955
 | 
					#define VENDOR_ID_NVIDIA		0x0955
 | 
				
			||||||
 | 
					#define VENDOR_ID_TPLINK		0x2357
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MCU_TYPE_PLA			0x0100
 | 
					#define MCU_TYPE_PLA			0x0100
 | 
				
			||||||
#define MCU_TYPE_USB			0x0000
 | 
					#define MCU_TYPE_USB			0x0000
 | 
				
			||||||
| 
						 | 
					@ -5319,6 +5320,7 @@ static const struct usb_device_id rtl8152_table[] = {
 | 
				
			||||||
	{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7214)},
 | 
						{REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7214)},
 | 
				
			||||||
	{REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
 | 
						{REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)},
 | 
				
			||||||
	{REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA,  0x09ff)},
 | 
						{REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA,  0x09ff)},
 | 
				
			||||||
 | 
						{REALTEK_USB_DEVICE(VENDOR_ID_TPLINK,  0x0601)},
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue