diff --git a/Documentation/ABI/testing/sysfs-ibft b/Documentation/ABI/testing/sysfs-ibft index c2b7d1154bec..cac3930bdb04 100644 --- a/Documentation/ABI/testing/sysfs-ibft +++ b/Documentation/ABI/testing/sysfs-ibft @@ -20,4 +20,4 @@ Date: November 2007 Contact: Konrad Rzeszutek Description: The /sys/firmware/ibft/ethernetX directory will contain files that expose the iSCSI Boot Firmware Table NIC data. - This can this can the IP address, MAC, and gateway of the NIC. + Usually this contains the IP address, MAC, and gateway of the NIC. diff --git a/Documentation/DocBook/media/Makefile b/Documentation/DocBook/media/Makefile index df2962d9e11e..8bf7c6191296 100644 --- a/Documentation/DocBook/media/Makefile +++ b/Documentation/DocBook/media/Makefile @@ -25,7 +25,7 @@ GENFILES := $(addprefix $(MEDIA_OBJ_DIR)/, $(MEDIA_TEMP)) PHONY += cleanmediadocs cleanmediadocs: - -@rm `find $(MEDIA_OBJ_DIR) -type l` $(GENFILES) $(OBJIMGFILES) 2>/dev/null + -@rm -f `find $(MEDIA_OBJ_DIR) -type l` $(GENFILES) $(OBJIMGFILES) 2>/dev/null $(obj)/media_api.xml: $(GENFILES) FORCE diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index 07ffc76553ba..0a2debfa68f6 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2566,6 +2566,10 @@ fields changed from _s32 to _u32. Added compound control types and &VIDIOC-QUERY-EXT-CTRL;. + + + +
V4L2 in Linux 3.18 diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 57cf5efb044d..93aa8604630e 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -324,7 +324,6 @@ tree, they need to be integration-tested. For this purpose, a special testing repository exists into which virtually all subsystem trees are pulled on an almost daily basis: http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git - http://linux.f-seidel.de/linux-next/pmwiki/ This way, the -next kernel gives a summary outlook onto what will be expected to go into the mainline kernel at the next merge period. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 482c74947de0..1fa1caa198eb 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -483,12 +483,10 @@ have been included in the discussion 14) Using Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: and Fixes: -If this patch fixes a problem reported by somebody else, consider adding a -Reported-by: tag to credit the reporter for their contribution. Please -note that this tag should not be added without the reporter's permission, -especially if the problem was not reported in a public forum. That said, -if we diligently credit our bug reporters, they will, hopefully, be -inspired to help us again in the future. +The Reported-by tag gives credit to people who find bugs and report them and it +hopefully inspires them to help us again in the future. Please note that if +the bug was reported in private, then ask for permission first before using the +Reported-by tag. A Tested-by: tag indicates that the patch has been successfully tested (in some environment) by the person named. This tag informs maintainers that diff --git a/Documentation/development-process/2.Process b/Documentation/development-process/2.Process index 2e0617936e8f..c24e156a6118 100644 --- a/Documentation/development-process/2.Process +++ b/Documentation/development-process/2.Process @@ -289,10 +289,6 @@ lists when they are assembled; they can be downloaded from: http://www.kernel.org/pub/linux/kernel/next/ -Some information about linux-next has been gathered at: - - http://linux.f-seidel.de/linux-next/pmwiki/ - Linux-next has become an integral part of the kernel development process; all patches merged during a given merge window should really have found their way into linux-next some time before the merge window opens. diff --git a/Documentation/development-process/8.Conclusion b/Documentation/development-process/8.Conclusion index 1990ab4b4949..caef69022e9c 100644 --- a/Documentation/development-process/8.Conclusion +++ b/Documentation/development-process/8.Conclusion @@ -22,10 +22,6 @@ Beyond that, a valuable resource for kernel developers is: http://kernelnewbies.org/ -Information about the linux-next tree gathers at: - - http://linux.f-seidel.de/linux-next/pmwiki/ - And, of course, one should not forget http://kernel.org/, the definitive location for kernel release information. diff --git a/Documentation/devicetree/bindings/net/smsc-lan91c111.txt b/Documentation/devicetree/bindings/net/smsc-lan91c111.txt index 0f8487b88822..e77e167593db 100644 --- a/Documentation/devicetree/bindings/net/smsc-lan91c111.txt +++ b/Documentation/devicetree/bindings/net/smsc-lan91c111.txt @@ -11,3 +11,5 @@ Optional properties: are supported on the device. Valid value for SMSC LAN91c111 are 1, 2 or 4. If it's omitted or invalid, the size would be 2 meaning 16-bit access only. +- power-gpios: GPIO to control the PWRDWN pin +- reset-gpios: GPIO to control the RESET pin diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt index 955df60a118c..d556dcb8816b 100644 --- a/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -7,10 +7,20 @@ Required properties: - clocks : the clock provider of SYS_MCLK +- VDDA-supply : the regulator provider of VDDA + +- VDDIO-supply: the regulator provider of VDDIO + +Optional properties: + +- VDDD-supply : the regulator provider of VDDD + Example: codec: sgtl5000@0a { compatible = "fsl,sgtl5000"; reg = <0x0a>; clocks = <&clks 150>; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; }; diff --git a/Documentation/devicetree/bindings/submitting-patches.txt b/Documentation/devicetree/bindings/submitting-patches.txt index 042a0273b8ba..b7ba01ad1426 100644 --- a/Documentation/devicetree/bindings/submitting-patches.txt +++ b/Documentation/devicetree/bindings/submitting-patches.txt @@ -12,6 +12,9 @@ I. For patch submitters devicetree@vger.kernel.org + 3) The Documentation/ portion of the patch should come in the series before + the code implementing the binding. + II. For kernel maintainers 1) If you aren't comfortable reviewing a given binding, reply to it and ask diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 74339c57b914..4c81a860cc2b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1264,7 +1264,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. i8042.noloop [HW] Disable the AUX Loopback command while probing for the AUX port i8042.nomux [HW] Don't check presence of an active multiplexing - controller. Default: true. + controller i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX controllers i8042.notimeout [HW] Ignore timeout condition signalled by controller @@ -1307,6 +1307,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted. .cdrom .chs .ignore_cable are additional options See Documentation/ide/ide.txt. + ide-generic.probe-mask= [HW] (E)IDE subsystem + Format: + Probe mask for legacy ISA IDE ports. Depending on + platform up to 6 ports are supported, enabled by + setting corresponding bits in the mask to 1. The + default value is 0x0, which has a special meaning. + On systems that have PCI, it triggers scanning the + PCI bus for the first and the second port, which + are then probed. On systems without PCI the value + of 0x0 enables probing the two first ports as if it + was 0x3. + ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem Claim all unknown PCI IDE storage controllers. @@ -1587,6 +1599,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. kmemleak= [KNL] Boot-time kmemleak enable/disable Valid arguments: on, off Default: on + Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y, + the default is off. kmemcheck= [X86] Boot-time kmemcheck enable/disable/one-shot mode Valid arguments: 0, 1, 2 diff --git a/Documentation/kmemleak.txt b/Documentation/kmemleak.txt index f4f033c8d856..45e777f4e41d 100644 --- a/Documentation/kmemleak.txt +++ b/Documentation/kmemleak.txt @@ -62,6 +62,10 @@ Memory may be allocated or freed before kmemleak is initialised and these actions are stored in an early log buffer. The size of this buffer is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option. +If CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF are enabled, the kmemleak is +disabled by default. Passing "kmemleak=on" on the kernel command +line enables the function. + Basic Algorithm --------------- diff --git a/Documentation/prctl/Makefile b/Documentation/prctl/Makefile index 3e3232dcb2b8..2948b7b124b9 100644 --- a/Documentation/prctl/Makefile +++ b/Documentation/prctl/Makefile @@ -1,5 +1,5 @@ # List of programs to build -hostprogs-y := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test disable-tsc-test +hostprogs-$(CONFIG_X86) := disable-tsc-ctxt-sw-stress-test disable-tsc-on-off-stress-test disable-tsc-test # Tell kbuild to always build the programs always := $(hostprogs-y) diff --git a/Documentation/ptp/testptp.mk b/Documentation/ptp/testptp.mk new file mode 100644 index 000000000000..4ef2d9755421 --- /dev/null +++ b/Documentation/ptp/testptp.mk @@ -0,0 +1,33 @@ +# PTP 1588 clock support - User space test program +# +# Copyright (C) 2010 OMICRON electronics GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +CC = $(CROSS_COMPILE)gcc +INC = -I$(KBUILD_OUTPUT)/usr/include +CFLAGS = -Wall $(INC) +LDLIBS = -lrt +PROGS = testptp + +all: $(PROGS) + +testptp: testptp.o + +clean: + rm -f testptp.o + +distclean: clean + rm -f $(PROGS) diff --git a/Documentation/vDSO/Makefile b/Documentation/vDSO/Makefile index 2b99e57207c1..ee075c3d2124 100644 --- a/Documentation/vDSO/Makefile +++ b/Documentation/vDSO/Makefile @@ -10,3 +10,6 @@ always := $(hostprogs-y) HOSTCFLAGS := -I$(objtree)/usr/include -std=gnu99 HOSTCFLAGS_vdso_standalone_test_x86.o := -fno-asynchronous-unwind-tables -fno-stack-protector HOSTLOADLIBES_vdso_standalone_test_x86 := -nostdlib +ifeq ($(CONFIG_X86_32),y) +HOSTLOADLIBES_vdso_standalone_test_x86 += -lgcc_s +endif diff --git a/Documentation/vDSO/vdso_standalone_test_x86.c b/Documentation/vDSO/vdso_standalone_test_x86.c index d46240265c50..93b0ebf8cc38 100644 --- a/Documentation/vDSO/vdso_standalone_test_x86.c +++ b/Documentation/vDSO/vdso_standalone_test_x86.c @@ -63,7 +63,7 @@ static inline void linux_exit(int code) x86_syscall3(__NR_exit, code, 0, 0); } -void to_base10(char *lastdig, uint64_t n) +void to_base10(char *lastdig, time_t n) { while (n) { *lastdig = (n % 10) + '0'; diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index bdd4bb97fff7..b64e0af9cc56 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt @@ -274,7 +274,7 @@ This command mounts a (pseudo) filesystem of type hugetlbfs on the directory /mnt/huge. Any files created on /mnt/huge uses huge pages. The uid and gid options sets the owner and group of the root of the file system. By default the uid and gid of the current process are taken. The mode option sets the -mode of root of file system to value & 0777. This value is given in octal. +mode of root of file system to value & 01777. This value is given in octal. By default the value 0755 is picked. The size option sets the maximum value of memory (huge pages) allowed for that filesystem (/mnt/huge). The size is rounded down to HPAGE_SIZE. The option nr_inodes sets the maximum number of diff --git a/MAINTAINERS b/MAINTAINERS index dab92a78d1d5..5d6136b8959e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1543,6 +1543,7 @@ F: arch/arm/mach-pxa/include/mach/z2.h ARM/ZYNQ ARCHITECTURE M: Michal Simek +R: Sören Brinkmann L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://wiki.xilinx.com T: git git://git.xilinx.com/linux-xlnx.git @@ -4312,8 +4313,10 @@ F: Documentation/blockdev/cpqarray.txt F: drivers/block/cpqarray.* HEWLETT-PACKARD SMART ARRAY RAID DRIVER (hpsa) -M: "Stephen M. Cameron" +M: Don Brace L: iss_storagedev@hp.com +L: storagedev@pmcs.com +L: linux-scsi@vger.kernel.org S: Supported F: Documentation/scsi/hpsa.txt F: drivers/scsi/hpsa*.[ch] @@ -4321,8 +4324,10 @@ F: include/linux/cciss*.h F: include/uapi/linux/cciss*.h HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) -M: Mike Miller +M: Don Brace L: iss_storagedev@hp.com +L: storagedev@pmcs.com +L: linux-scsi@vger.kernel.org S: Supported F: Documentation/blockdev/cciss.txt F: drivers/block/cciss* @@ -4608,7 +4613,7 @@ S: Supported F: drivers/crypto/nx/ IBM Power 842 compression accelerator -M: Nathan Fontenot +M: Dan Streetman S: Supported F: drivers/crypto/nx/nx-842.c F: include/linux/nx842.h @@ -7175,6 +7180,7 @@ F: drivers/crypto/picoxcell* PIN CONTROL SUBSYSTEM M: Linus Walleij +L: linux-gpio@vger.kernel.org S: Maintained F: drivers/pinctrl/ F: include/linux/pinctrl/ @@ -8479,7 +8485,6 @@ F: arch/arm/mach-s3c24xx/bast-irq.c TI DAVINCI MACHINE SUPPORT M: Sekhar Nori M: Kevin Hilman -L: davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers) T: git git://gitorious.org/linux-davinci/linux-davinci.git Q: http://patchwork.kernel.org/project/linux-davinci/list/ S: Supported @@ -8489,7 +8494,6 @@ F: drivers/i2c/busses/i2c-davinci.c TI DAVINCI SERIES MEDIA DRIVER M: Lad, Prabhakar L: linux-media@vger.kernel.org -L: davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers) W: http://linuxtv.org/ Q: http://patchwork.linuxtv.org/project/linux-media/list/ T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git @@ -9606,7 +9610,6 @@ F: drivers/staging/unisys/ UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER M: Vinayak Holikatti -M: Santosh Y L: linux-scsi@vger.kernel.org S: Supported F: Documentation/scsi/ufs.txt diff --git a/Makefile b/Makefile index 52c129725270..ffc1ce2b0345 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 3 PATCHLEVEL = 18 SUBLEVEL = 0 -EXTRAVERSION = -rc2 -NAME = Shuffling Zombie Juror +EXTRAVERSION = -rc3 +NAME = Diseased Newt # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 03dc4c1a8736..d8f6a2ec3d4e 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1187,7 +1187,7 @@ config DEBUG_UART_VIRT default 0xf1c28000 if DEBUG_SUNXI_UART0 default 0xf1c28400 if DEBUG_SUNXI_UART1 default 0xf1f02800 if DEBUG_SUNXI_R_UART - default 0xf2100000 if DEBUG_PXA_UART1 + default 0xf6200000 if DEBUG_PXA_UART1 default 0xf4090000 if ARCH_LPC32XX default 0xf4200000 if ARCH_GEMINI default 0xf7000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 739fcf29c643..bc82a12d4c2c 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -668,6 +668,8 @@ bank-width = <2>; pinctrl-names = "default"; pinctrl-0 = <ðernet_pins>; + power-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; /* gpio86 */ + reset-gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* gpio164 */ gpmc,device-width = <2>; gpmc,sync-clk-ps = <0>; gpmc,cs-on-ns = <0>; diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index f1dc7fc668f3..3487046d8a78 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -235,6 +235,7 @@ CONFIG_SPI_TEGRA20_SLINK=y CONFIG_SPI_XILINX=y CONFIG_PINCTRL_AS3722=y CONFIG_PINCTRL_PALMAS=y +CONFIG_PINCTRL_APQ8084=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_GPIO_DWAPB=y @@ -411,6 +412,7 @@ CONFIG_NVEC_POWER=y CONFIG_NVEC_PAZ00=y CONFIG_QCOM_GSBI=y CONFIG_COMMON_CLK_QCOM=y +CONFIG_APQ_MMCC_8084=y CONFIG_MSM_GCC_8660=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 16e719c268dd..b3f86670d2eb 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -86,7 +86,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y # CONFIG_INET_LRO is not set -CONFIG_IPV6=y CONFIG_NETFILTER=y CONFIG_CAN=m CONFIG_CAN_C_CAN=m @@ -112,6 +111,7 @@ CONFIG_MTD_OOPS=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_ECC_BCH=y CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_VERIFY_WRITE=y @@ -317,7 +317,7 @@ CONFIG_EXT4_FS=y CONFIG_FANOTIFY=y CONFIG_QUOTA=y CONFIG_QFMT_V2=y -CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS4_FS=m CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index d7a5855a5db8..a2956c3112f1 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig @@ -1,5 +1,6 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -11,23 +12,17 @@ CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -CONFIG_HOTPLUG=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_SOCFPGA=y -CONFIG_MACH_SOCFPGA_CYCLONE5=y CONFIG_ARM_THUMBEE=y -# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set -# CONFIG_CACHE_L2X0 is not set -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="" CONFIG_VFP=y CONFIG_NEON=y CONFIG_NET=y @@ -41,38 +36,30 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y +CONFIG_IPV6=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y CONFIG_CAN=y -CONFIG_CAN_RAW=y -CONFIG_CAN_BCM=y -CONFIG_CAN_GW=y -CONFIG_CAN_DEV=y -CONFIG_CAN_CALC_BITTIMING=y CONFIG_CAN_C_CAN=y CONFIG_CAN_C_CAN_PLATFORM=y CONFIG_CAN_DEBUG_DEVICES=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y -CONFIG_PROC_DEVICETREE=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_SRAM=y CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y CONFIG_STMMAC_ETH=y -CONFIG_MICREL_PHY=y -# CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set -CONFIG_INPUT_EVDEV=y CONFIG_DWMAC_SOCFPGA=y -CONFIG_PPS=y -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_VLAN_8021Q=y -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_GARP=y -CONFIG_IPV6=y +CONFIG_MICREL_PHY=y +CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_AMBAKMI=y CONFIG_LEGACY_PTY_COUNT=16 @@ -81,45 +68,43 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 CONFIG_SERIAL_8250_DW=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_DWAPB=y -# CONFIG_RTC_HCTOSYS is not set +CONFIG_PMBUS=y +CONFIG_SENSORS_LTC2978=y +CONFIG_SENSORS_LTC2978_REGULATOR=y CONFIG_WATCHDOG=y CONFIG_DW_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_USB=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y +CONFIG_MMC=y +CONFIG_MMC_DW=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT3_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -# CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set -CONFIG_FHANDLE=y +CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y CONFIG_NTFS_FS=y CONFIG_NTFS_RW=y CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y +CONFIG_CONFIGFS_FS=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set -CONFIG_DEBUG_INFO=y CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_DEBUG_USER=y CONFIG_XZ_DEC=y -CONFIG_I2C=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -CONFIG_I2C_CHARDEV=y -CONFIG_MMC=y -CONFIG_MMC_DW=y -CONFIG_PM=y -CONFIG_SUSPEND=y -CONFIG_MMC_UNSAFE_RESUME=y -CONFIG_USB=y -CONFIG_USB_DWC2=y -CONFIG_USB_DWC2_HOST=y -CONFIG_USB_DWC2_PLATFORM=y diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index 3aaa75cae90c..705bb7620673 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -412,6 +412,7 @@ #define __NR_seccomp (__NR_SYSCALL_BASE+383) #define __NR_getrandom (__NR_SYSCALL_BASE+384) #define __NR_memfd_create (__NR_SYSCALL_BASE+385) +#define __NR_bpf (__NR_SYSCALL_BASE+386) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 713e807621d2..2d2d6087b9b1 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -10,6 +10,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include @@ -39,10 +40,19 @@ * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c * (http://gcc.gnu.org/PR8896) and incorrect structure * initialisation in fs/jffs2/erase.c + * GCC 4.8.0-4.8.2: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58854 + * miscompiles find_get_entry(), and can result in EXT3 and EXT4 + * filesystem corruption (possibly other FS too). */ +#ifdef __GNUC__ #if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) #error Your compiler is too buggy; it is known to miscompile kernels. -#error Known good compilers: 3.3 +#error Known good compilers: 3.3, 4.x +#endif +#if GCC_VERSION >= 40800 && GCC_VERSION < 40803 +#error Your compiler is too buggy; it is known to miscompile kernels +#error and result in filesystem corruption and oopses. +#endif #endif int main(void) diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 9f899d8fdcca..e51833f8cc38 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -395,6 +395,7 @@ CALL(sys_seccomp) CALL(sys_getrandom) /* 385 */ CALL(sys_memfd_create) + CALL(sys_bpf) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h index 559c69a47731..7d11979da030 100644 --- a/arch/arm/mach-ixp4xx/include/mach/io.h +++ b/arch/arm/mach-ixp4xx/include/mach/io.h @@ -76,7 +76,7 @@ static inline void __indirect_writeb(u8 value, volatile void __iomem *p) u32 n, byte_enables, data; if (!is_pci_memory(addr)) { - __raw_writeb(value, addr); + __raw_writeb(value, p); return; } @@ -141,7 +141,7 @@ static inline unsigned char __indirect_readb(const volatile void __iomem *p) u32 n, byte_enables, data; if (!is_pci_memory(addr)) - return __raw_readb(addr); + return __raw_readb(p); n = addr % 4; byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL; diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index d22c30d3ccfa..8c58b71c2727 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -917,6 +917,10 @@ static int __init omap_device_late_idle(struct device *dev, void *data) static int __init omap_device_late_init(void) { bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); + + WARN(!of_have_populated_dt(), + "legacy booting deprecated, please update to boot with .dts\n"); + return 0; } omap_late_initcall_sync(omap_device_late_init); diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index c95346c94829..cec9d6c6442c 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -252,9 +252,6 @@ static void __init nokia_n900_legacy_init(void) platform_device_register(&omap3_rom_rng_device); } - - /* Only on some development boards */ - gpio_request_one(164, GPIOF_OUT_INIT_LOW, "smc91x reset"); } static void __init omap3_tao3530_legacy_init(void) diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h index bbf9df37ad4b..d28fe291233a 100644 --- a/arch/arm/mach-pxa/include/mach/addr-map.h +++ b/arch/arm/mach-pxa/include/mach/addr-map.h @@ -38,6 +38,11 @@ #define DMEMC_VIRT IOMEM(0xf6100000) #define DMEMC_SIZE 0x00100000 +/* + * Reserved space for low level debug virtual addresses within + * 0xf6200000..0xf6201000 + */ + /* * Internal Memory Controller (PXA27x and later) */ diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 55f9d6e0cc88..5e65ca8dea62 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -956,7 +956,7 @@ static u32 cache_id_part_number_from_dt; * @associativity: variable to return the calculated associativity in * @max_way_size: the maximum size in bytes for the cache ways */ -static void __init l2x0_cache_size_of_parse(const struct device_node *np, +static int __init l2x0_cache_size_of_parse(const struct device_node *np, u32 *aux_val, u32 *aux_mask, u32 *associativity, u32 max_way_size) @@ -974,7 +974,7 @@ static void __init l2x0_cache_size_of_parse(const struct device_node *np, of_property_read_u32(np, "cache-line-size", &line_size); if (!cache_size || !sets) - return; + return -ENODEV; /* All these l2 caches have the same line = block size actually */ if (!line_size) { @@ -1009,7 +1009,7 @@ static void __init l2x0_cache_size_of_parse(const struct device_node *np, if (way_size > max_way_size) { pr_err("L2C OF: set size %dKB is too large\n", way_size); - return; + return -EINVAL; } pr_info("L2C OF: override cache size: %d bytes (%dKB)\n", @@ -1027,7 +1027,7 @@ static void __init l2x0_cache_size_of_parse(const struct device_node *np, if (way_size_bits < 1 || way_size_bits > 6) { pr_err("L2C OF: cache way size illegal: %dKB is not mapped\n", way_size); - return; + return -EINVAL; } mask |= L2C_AUX_CTRL_WAY_SIZE_MASK; @@ -1036,6 +1036,8 @@ static void __init l2x0_cache_size_of_parse(const struct device_node *np, *aux_val &= ~mask; *aux_val |= val; *aux_mask &= ~mask; + + return 0; } static void __init l2x0_of_parse(const struct device_node *np, @@ -1046,6 +1048,7 @@ static void __init l2x0_of_parse(const struct device_node *np, u32 dirty = 0; u32 val = 0, mask = 0; u32 assoc; + int ret; of_property_read_u32(np, "arm,tag-latency", &tag); if (tag) { @@ -1068,7 +1071,10 @@ static void __init l2x0_of_parse(const struct device_node *np, val |= (dirty - 1) << L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT; } - l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_256K); + ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_256K); + if (ret) + return; + if (assoc > 8) { pr_err("l2x0 of: cache setting yield too high associativity\n"); pr_err("l2x0 of: %d calculated, max 8\n", assoc); @@ -1125,6 +1131,7 @@ static void __init l2c310_of_parse(const struct device_node *np, u32 tag[3] = { 0, 0, 0 }; u32 filter[2] = { 0, 0 }; u32 assoc; + int ret; of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag)); if (tag[0] && tag[1] && tag[2]) @@ -1152,7 +1159,10 @@ static void __init l2c310_of_parse(const struct device_node *np, l2x0_base + L310_ADDR_FILTER_START); } - l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); + ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K); + if (ret) + return; + switch (assoc) { case 16: *aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK; @@ -1164,8 +1174,8 @@ static void __init l2c310_of_parse(const struct device_node *np, *aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK; break; default: - pr_err("PL310 OF: cache setting yield illegal associativity\n"); - pr_err("PL310 OF: %d calculated, only 8 and 16 legal\n", assoc); + pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n", + assoc); break; } } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c245d903927f..e8907117861e 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1198,7 +1198,6 @@ __iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot, { return dma_common_pages_remap(pages, size, VM_ARM_DMA_CONSISTENT | VM_USERMAP, prot, caller); - return NULL; } /* diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 45aeaaca9052..e17ed00828d7 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -127,8 +127,11 @@ void *kmap_atomic_pfn(unsigned long pfn) { unsigned long vaddr; int idx, type; + struct page *page = pfn_to_page(pfn); pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); type = kmap_atomic_idx_push(); idx = type + KM_TYPE_NR * smp_processor_id(); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 92bba32d9230..9481f85c56e6 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -559,10 +559,10 @@ void __init mem_init(void) #ifdef CONFIG_MODULES " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" #endif - " .text : 0x%p" " - 0x%p" " (%4d kB)\n" - " .init : 0x%p" " - 0x%p" " (%4d kB)\n" - " .data : 0x%p" " - 0x%p" " (%4d kB)\n" - " .bss : 0x%p" " - 0x%p" " (%4d kB)\n", + " .text : 0x%p" " - 0x%p" " (%4td kB)\n" + " .init : 0x%p" " - 0x%p" " (%4td kB)\n" + " .data : 0x%p" " - 0x%p" " (%4td kB)\n" + " .bss : 0x%p" " - 0x%p" " (%4td kB)\n", MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) + (PAGE_SIZE)), diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 4ef7a54813e6..75e75d7b1702 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 354 +#define NR_syscalls 355 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index b419c6b7ac37..2c1bec9a14b6 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -359,5 +359,6 @@ #define __NR_renameat2 351 #define __NR_getrandom 352 #define __NR_memfd_create 353 +#define __NR_bpf 354 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 05b46c2b08b8..2ca219e184cd 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -374,4 +374,5 @@ ENTRY(sys_call_table) .long sys_renameat2 .long sys_getrandom .long sys_memfd_create + .long sys_bpf diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 6feded3b0c4c..a7736fa0580c 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -129,6 +129,10 @@ endmenu menu "Kernel features" +config NR_CPUS + int + default "1" + config ADVANCED_OPTIONS bool "Prompt for advanced kernel configuration options" help diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index ea4b233647c1..0a53362d5548 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h @@ -38,6 +38,6 @@ #endif /* __ASSEMBLY__ */ -#define __NR_syscalls 387 +#define __NR_syscalls 388 #endif /* _ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/include/uapi/asm/unistd.h b/arch/microblaze/include/uapi/asm/unistd.h index 1c2380bf8fe6..c712677f8a2a 100644 --- a/arch/microblaze/include/uapi/asm/unistd.h +++ b/arch/microblaze/include/uapi/asm/unistd.h @@ -402,5 +402,6 @@ #define __NR_seccomp 384 #define __NR_getrandom 385 #define __NR_memfd_create 386 +#define __NR_bpf 387 #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */ diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index de59ee1d7010..0166e890486c 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -387,3 +387,4 @@ ENTRY(sys_call_table) .long sys_seccomp .long sys_getrandom /* 385 */ .long sys_memfd_create + .long sys_bpf diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 9037914f6985..b30e41c0c033 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -660,8 +660,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, res = &hose->mem_resources[memno++]; break; } - if (res != NULL) - of_pci_range_to_resource(&range, dev, res); + if (res != NULL) { + res->name = dev->full_name; + res->flags = range.flags; + res->start = range.cpu_addr; + res->end = range.cpu_addr + range.size - 1; + res->parent = res->child = res->sibling = NULL; + } } /* If there's an ISA hole and the pci_mem_offset is -not- matching diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 623f2971ce0e..766b77d527ac 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -71,7 +71,7 @@ pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, void flush_dcache_icache_hugepage(struct page *page); -#if defined(CONFIG_PPC_MM_SLICES) || defined(CONFIG_PPC_SUBPAGE_PROT) +#if defined(CONFIG_PPC_MM_SLICES) int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len); #else diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 7d8a60068805..ce9577d693be 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -365,3 +365,4 @@ SYSCALL_SPU(renameat2) SYSCALL_SPU(seccomp) SYSCALL_SPU(getrandom) SYSCALL_SPU(memfd_create) +SYSCALL_SPU(bpf) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 4e9af3fd43e7..e0da021caa00 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define __NR_syscalls 361 +#define __NR_syscalls 362 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 0688fc06e183..f55351f2e66e 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -383,5 +383,6 @@ #define __NR_seccomp 358 #define __NR_getrandom 359 #define __NR_memfd_create 360 +#define __NR_bpf 361 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c index 0f9939e693df..5a236f082c78 100644 --- a/arch/powerpc/mm/copro_fault.c +++ b/arch/powerpc/mm/copro_fault.c @@ -99,8 +99,6 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) u64 vsid; int psize, ssize; - slb->esid = (ea & ESID_MASK) | SLB_ESID_V; - switch (REGION_ID(ea)) { case USER_REGION_ID: pr_devel("%s: 0x%llx -- USER_REGION_ID\n", __func__, ea); @@ -133,6 +131,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) vsid |= mmu_psize_defs[psize].sllp | ((ssize == MMU_SEGSIZE_1T) ? SLB_VSID_B_1T : 0); + slb->esid = (ea & (ssize == MMU_SEGSIZE_1T ? ESID_MASK_1T : ESID_MASK)) | SLB_ESID_V; slb->vsid = vsid; return 0; diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index e5236c24dc07..b9d1dfdbe5bb 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1509,11 +1509,14 @@ static int update_cpu_topology(void *data) cpu = smp_processor_id(); for (update = data; update; update = update->next) { + int new_nid = update->new_nid; if (cpu != update->cpu) continue; - unmap_cpu_from_node(update->cpu); - map_cpu_to_node(update->cpu, update->new_nid); + unmap_cpu_from_node(cpu); + map_cpu_to_node(cpu, new_nid); + set_cpu_numa_node(cpu, new_nid); + set_cpu_numa_mem(cpu, local_memory_node(new_nid)); vdso_getcpu_init(); } diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 8d7bda94d196..ded0ea1afde4 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -682,6 +682,7 @@ void slice_set_range_psize(struct mm_struct *mm, unsigned long start, slice_convert(mm, mask, psize); } +#ifdef CONFIG_HUGETLB_PAGE /* * is_hugepage_only_range() is used by generic code to verify whether * a normal mmap mapping (non hugetlbfs) is valid on a given area. @@ -726,4 +727,4 @@ int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, #endif return !slice_check_fit(mask, available); } - +#endif diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 6c8710dd90c9..dba34088da28 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -417,11 +417,6 @@ static int h_24x7_event_add(struct perf_event *event, int flags) return 0; } -static int h_24x7_event_idx(struct perf_event *event) -{ - return 0; -} - static struct pmu h_24x7_pmu = { .task_ctx_nr = perf_invalid_context, @@ -433,7 +428,6 @@ static struct pmu h_24x7_pmu = { .start = h_24x7_event_start, .stop = h_24x7_event_stop, .read = h_24x7_event_update, - .event_idx = h_24x7_event_idx, }; static int hv_24x7_init(void) diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 15fc76c93022..a051fe946c63 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -246,11 +246,6 @@ static int h_gpci_event_init(struct perf_event *event) return 0; } -static int h_gpci_event_idx(struct perf_event *event) -{ - return 0; -} - static struct pmu h_gpci_pmu = { .task_ctx_nr = perf_invalid_context, @@ -262,7 +257,6 @@ static struct pmu h_gpci_pmu = { .start = h_gpci_event_start, .stop = h_gpci_event_stop, .read = h_gpci_event_update, - .event_idx = h_gpci_event_idx, }; static int hv_gpci_init(void) diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c index dd2c285ad170..ad4b31df779a 100644 --- a/arch/powerpc/platforms/powernv/opal-lpc.c +++ b/arch/powerpc/platforms/powernv/opal-lpc.c @@ -191,7 +191,6 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf, { struct lpc_debugfs_entry *lpc = filp->private_data; u32 data, pos, len, todo; - __be32 bedata; int rc; if (!access_ok(VERIFY_WRITE, ubuf, count)) @@ -214,10 +213,9 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf, len = 2; } rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos, - &bedata, len); + &data, len); if (rc) return -ENXIO; - data = be32_to_cpu(bedata); switch(len) { case 4: rc = __put_user((u32)data, (u32 __user *)ubuf); diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index e9e2450c1fdd..feb549aa3eea 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -58,7 +58,7 @@ END_FTR_SECTION(0, 1); \ */ #define OPAL_CALL(name, token) \ - _GLOBAL(name); \ + _GLOBAL_TOC(name); \ mflr r0; \ std r0,16(r1); \ li r0,token; \ diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 08e761318c17..b878f12a9597 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1411,11 +1411,6 @@ static void cpumsf_pmu_del(struct perf_event *event, int flags) perf_pmu_enable(event->pmu); } -static int cpumsf_pmu_event_idx(struct perf_event *event) -{ - return event->hw.idx; -} - CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC, PERF_EVENT_CPUM_SF); CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG); @@ -1458,7 +1453,6 @@ static struct pmu cpumf_sampling = { .stop = cpumsf_pmu_stop, .read = cpumsf_pmu_read, - .event_idx = cpumsf_pmu_event_idx, .attr_groups = cpumsf_pmu_attr_groups, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 9139d14b9c53..538c10db3537 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -118,7 +118,7 @@ static struct plat_sci_port scif0_platform_data = { }; static struct resource scif0_resources[] = { - DEFINE_RES_MEM(0xfffffe80, 0x100), + DEFINE_RES_MEM(0xfffffe80, 0x10), DEFINE_RES_IRQ(evt2irq(0x4e0)), }; @@ -143,7 +143,7 @@ static struct plat_sci_port scif1_platform_data = { }; static struct resource scif1_resources[] = { - DEFINE_RES_MEM(0xa4000150, 0x100), + DEFINE_RES_MEM(0xa4000150, 0x10), DEFINE_RES_IRQ(evt2irq(0x900)), }; @@ -169,7 +169,7 @@ static struct plat_sci_port scif2_platform_data = { }; static struct resource scif2_resources[] = { - DEFINE_RES_MEM(0xa4000140, 0x100), + DEFINE_RES_MEM(0xa4000140, 0x10), DEFINE_RES_IRQ(evt2irq(0x880)), }; diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index c842a89b1190..46d83842eddc 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -414,8 +414,9 @@ #define __NR_seccomp 346 #define __NR_getrandom 347 #define __NR_memfd_create 348 +#define __NR_bpf 349 -#define NR_syscalls 349 +#define NR_syscalls 350 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6a873c344bc0..ad0cdf497b78 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -86,4 +86,4 @@ sys_call_table: /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr -/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create +/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index d9151b6490d8..580cde9370c9 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -87,7 +87,7 @@ sys_call_table32: /*330*/ .word compat_sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr - .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create + .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf #endif /* CONFIG_COMPAT */ @@ -166,4 +166,4 @@ sys_call_table: /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr - .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create + .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f2327e88e07c..ded8a6774ac9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -142,6 +142,10 @@ config INSTRUCTION_DECODER def_bool y depends on KPROBES || PERF_EVENTS || UPROBES +config PERF_EVENTS_INTEL_UNCORE + def_bool y + depends on PERF_EVENTS && SUP_SUP_INTEL && PCI + config OUTPUT_FORMAT string default "elf32-i386" if X86_32 diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 8ffba18395c8..ffe71228fc10 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -157,7 +157,7 @@ ENTRY(ia32_sysenter_target) * ourselves. To save a few cycles, we can check whether * NT was set instead of doing an unconditional popfq. */ - testl $X86_EFLAGS_NT,EFLAGS(%rsp) /* saved EFLAGS match cpu */ + testl $X86_EFLAGS_NT,EFLAGS-ARGOFFSET(%rsp) jnz sysenter_fix_flags sysenter_flags_fixed: diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index b436fc735aa4..a142e77693e1 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -397,7 +397,7 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, /* Don't set up the ACPI SCI because it's already set up */ if (acpi_gbl_FADT.sci_interrupt == gsi) - return gsi; + return mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC); trigger = trigger == ACPI_EDGE_SENSITIVE ? 0 : 1; polarity = polarity == ACPI_ACTIVE_HIGH ? 0 : 1; @@ -604,14 +604,18 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) { - int irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); + int irq; - if (irq >= 0) { + if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { + *irqp = gsi; + } else { + irq = mp_map_gsi_to_irq(gsi, + IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); + if (irq < 0) + return -1; *irqp = irq; - return 0; } - - return -1; + return 0; } EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 5972b108f15a..b708738d016e 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c @@ -185,8 +185,6 @@ static void apbt_setup_irq(struct apbt_dev *adev) irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT); irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); - /* APB timer irqs are set up as mp_irqs, timer is edge type */ - __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); } /* Should be called with per cpu */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 00853b254ab0..ba6cc041edb1 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1297,7 +1297,7 @@ void setup_local_APIC(void) unsigned int value, queued; int i, j, acked = 0; unsigned long long tsc = 0, ntsc; - long long max_loops = cpu_khz; + long long max_loops = cpu_khz ? cpu_khz : 1000000; if (cpu_has_tsc) rdtscll(tsc); @@ -1383,7 +1383,7 @@ void setup_local_APIC(void) break; } if (queued) { - if (cpu_has_tsc) { + if (cpu_has_tsc && cpu_khz) { rdtscll(ntsc); max_loops = (cpu_khz << 10) - (ntsc - tsc); } else diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 01d5453b5502..e27b49d7c922 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -39,9 +39,12 @@ obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o endif obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_uncore_snb.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore_snbep.o perf_event_intel_uncore_nhmex.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o + +obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += perf_event_intel_uncore.o \ + perf_event_intel_uncore_snb.o \ + perf_event_intel_uncore_snbep.o \ + perf_event_intel_uncore_nhmex.o endif diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1ef456273172..9cc6b6f25f42 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -213,12 +213,13 @@ static void intel_workarounds(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_F00F_BUG /* - * All current models of Pentium and Pentium with MMX technology CPUs + * All models of Pentium and Pentium with MMX technology CPUs * have the F0 0F bug, which lets nonprivileged users lock up the * system. Announce that the fault handler will be checking for it. + * The Quark is also family 5, but does not have the same bug. */ clear_cpu_bug(c, X86_BUG_F00F); - if (!paravirt_enabled() && c->x86 == 5) { + if (!paravirt_enabled() && c->x86 == 5 && c->x86_model < 9) { static int f00f_workaround_enabled; set_cpu_bug(c, X86_BUG_F00F); diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1b8299dd3d91..143e5f5dc855 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -243,8 +243,9 @@ static bool check_hw_exists(void) msr_fail: printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); - printk(boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR - "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new); + printk("%sFailed to access perfctr msr (MSR %x is %Lx)\n", + boot_cpu_has(X86_FEATURE_HYPERVISOR) ? KERN_INFO : KERN_ERR, + reg, val_new); return false; } @@ -444,12 +445,6 @@ int x86_pmu_hw_config(struct perf_event *event) if (event->attr.type == PERF_TYPE_RAW) event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK; - if (event->attr.sample_period && x86_pmu.limit_period) { - if (x86_pmu.limit_period(event, event->attr.sample_period) > - event->attr.sample_period) - return -EINVAL; - } - return x86_setup_perfctr(event); } @@ -987,9 +982,6 @@ int x86_perf_event_set_period(struct perf_event *event) if (left > x86_pmu.max_period) left = x86_pmu.max_period; - if (x86_pmu.limit_period) - left = x86_pmu.limit_period(event, left); - per_cpu(pmc_prev_left[idx], smp_processor_id()) = left; /* diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index d98a34d435d7..fc5eb390b368 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -445,7 +445,6 @@ struct x86_pmu { struct x86_pmu_quirk *quirks; int perfctr_second_write; bool late_ack; - unsigned (*limit_period)(struct perf_event *event, unsigned l); /* * sysfs attrs diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a73947c53b65..944bf019b74f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -220,15 +220,6 @@ static struct event_constraint intel_hsw_event_constraints[] = { EVENT_CONSTRAINT_END }; -static struct event_constraint intel_bdw_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ - FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ - FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ - INTEL_UEVENT_CONSTRAINT(0x148, 0x4), /* L1D_PEND_MISS.PENDING */ - INTEL_EVENT_CONSTRAINT(0xa3, 0x4), /* CYCLE_ACTIVITY.* */ - EVENT_CONSTRAINT_END -}; - static u64 intel_pmu_event_map(int hw_event) { return intel_perfmon_event_map[hw_event]; @@ -424,126 +415,6 @@ static __initconst const u64 snb_hw_cache_event_ids }; -static __initconst const u64 hsw_hw_cache_event_ids - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = -{ - [ C(L1D ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */ - [ C(RESULT_MISS) ] = 0x151, /* L1D.REPLACEMENT */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */ - [ C(RESULT_MISS) ] = 0x0, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x0, - }, - }, - [ C(L1I ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x280, /* ICACHE.MISSES */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x0, - }, - }, - [ C(LL ) ] = { - [ C(OP_READ) ] = { - /* OFFCORE_RESPONSE:ALL_DATA_RD|ALL_CODE_RD */ - [ C(RESULT_ACCESS) ] = 0x1b7, - /* OFFCORE_RESPONSE:ALL_DATA_RD|ALL_CODE_RD|SUPPLIER_NONE| - L3_MISS|ANY_SNOOP */ - [ C(RESULT_MISS) ] = 0x1b7, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x1b7, /* OFFCORE_RESPONSE:ALL_RFO */ - /* OFFCORE_RESPONSE:ALL_RFO|SUPPLIER_NONE|L3_MISS|ANY_SNOOP */ - [ C(RESULT_MISS) ] = 0x1b7, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x0, - }, - }, - [ C(DTLB) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */ - [ C(RESULT_MISS) ] = 0x108, /* DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */ - [ C(RESULT_MISS) ] = 0x149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x0, - }, - }, - [ C(ITLB) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x6085, /* ITLB_MISSES.STLB_HIT */ - [ C(RESULT_MISS) ] = 0x185, /* ITLB_MISSES.MISS_CAUSES_A_WALK */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - }, - [ C(BPU ) ] = { - [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0xc4, /* BR_INST_RETIRED.ALL_BRANCHES */ - [ C(RESULT_MISS) ] = 0xc5, /* BR_MISP_RETIRED.ALL_BRANCHES */ - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = -1, - [ C(RESULT_MISS) ] = -1, - }, - }, -}; - -static __initconst const u64 hsw_hw_cache_extra_regs - [PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX] = -{ - [ C(LL ) ] = { - [ C(OP_READ) ] = { - /* OFFCORE_RESPONSE:ALL_DATA_RD|ALL_CODE_RD */ - [ C(RESULT_ACCESS) ] = 0x2d5, - /* OFFCORE_RESPONSE:ALL_DATA_RD|ALL_CODE_RD|SUPPLIER_NONE| - L3_MISS|ANY_SNOOP */ - [ C(RESULT_MISS) ] = 0x3fbc0202d5ull, - }, - [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x122, /* OFFCORE_RESPONSE:ALL_RFO */ - /* OFFCORE_RESPONSE:ALL_RFO|SUPPLIER_NONE|L3_MISS|ANY_SNOOP */ - [ C(RESULT_MISS) ] = 0x3fbc020122ull, - }, - [ C(OP_PREFETCH) ] = { - [ C(RESULT_ACCESS) ] = 0x0, - [ C(RESULT_MISS) ] = 0x0, - }, - }, -}; - static __initconst const u64 westmere_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -2034,24 +1905,6 @@ hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) return c; } -/* - * Broadwell: - * The INST_RETIRED.ALL period always needs to have lowest - * 6bits cleared (BDM57). It shall not use a period smaller - * than 100 (BDM11). We combine the two to enforce - * a min-period of 128. - */ -static unsigned bdw_limit_period(struct perf_event *event, unsigned left) -{ - if ((event->hw.config & INTEL_ARCH_EVENT_MASK) == - X86_CONFIG(.event=0xc0, .umask=0x01)) { - if (left < 128) - left = 128; - left &= ~0x3fu; - } - return left; -} - PMU_FORMAT_ATTR(event, "config:0-7" ); PMU_FORMAT_ATTR(umask, "config:8-15" ); PMU_FORMAT_ATTR(edge, "config:18" ); @@ -2692,8 +2545,8 @@ __init int intel_pmu_init(void) case 69: /* 22nm Haswell ULT */ case 70: /* 22nm Haswell + GT3e (Intel Iris Pro graphics) */ x86_pmu.late_ack = true; - memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids)); - memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); + memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); + memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); intel_pmu_lbr_init_snb(); @@ -2712,28 +2565,6 @@ __init int intel_pmu_init(void) pr_cont("Haswell events, "); break; - case 61: /* 14nm Broadwell Core-M */ - x86_pmu.late_ack = true; - memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids)); - memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); - - intel_pmu_lbr_init_snb(); - - x86_pmu.event_constraints = intel_bdw_event_constraints; - x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints; - x86_pmu.extra_regs = intel_snbep_extra_regs; - x86_pmu.pebs_aliases = intel_pebs_aliases_snb; - /* all extra regs are per-cpu when HT is on */ - x86_pmu.er_flags |= ERF_HAS_RSP_1; - x86_pmu.er_flags |= ERF_NO_HT_SHARING; - - x86_pmu.hw_config = hsw_hw_config; - x86_pmu.get_event_constraints = hsw_get_event_constraints; - x86_pmu.cpu_events = hsw_events_attrs; - x86_pmu.limit_period = bdw_limit_period; - pr_cont("Broadwell events, "); - break; - default: switch (x86_pmu.version) { case 1: diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index b553ed89e5f5..344b63f18d14 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -447,15 +447,14 @@ sysenter_exit: sysenter_audit: testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) jnz syscall_trace_entry - addl $4,%esp - CFI_ADJUST_CFA_OFFSET -4 - movl %esi,4(%esp) /* 5th arg: 4th syscall arg */ - movl %edx,(%esp) /* 4th arg: 3rd syscall arg */ - /* %ecx already in %ecx 3rd arg: 2nd syscall arg */ - movl %ebx,%edx /* 2nd arg: 1st syscall arg */ - /* %eax already in %eax 1st arg: syscall number */ + /* movl PT_EAX(%esp), %eax already set, syscall number: 1st arg to audit */ + movl PT_EBX(%esp), %edx /* ebx/a0: 2nd arg to audit */ + /* movl PT_ECX(%esp), %ecx already set, a1: 3nd arg to audit */ + pushl_cfi PT_ESI(%esp) /* a3: 5th arg */ + pushl_cfi PT_EDX+4(%esp) /* a2: 4th arg */ call __audit_syscall_entry - pushl_cfi %ebx + popl_cfi %ecx /* get that remapped edx off the stack */ + popl_cfi %ecx /* get that remapped esi off the stack */ movl PT_EAX(%esp),%eax /* reload syscall number */ jmp sysenter_do_call diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 8af817105e29..e7cc5370cd2f 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -111,8 +111,7 @@ static void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<chip; - const char *name = chip->name; int i; #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) @@ -79,7 +78,7 @@ void __init init_ISA_irqs(void) legacy_pic->init(0); for (i = 0; i < nr_legacy_irqs(); i++) - irq_set_chip_and_handler_name(i, chip, handle_level_irq, name); + irq_set_chip_and_handler(i, chip, handle_level_irq); } void __init init_IRQ(void) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 235cfd39e0d7..ab08aa2276fb 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1128,7 +1128,6 @@ void __init setup_arch(char **cmdline_p) setup_real_mode(); memblock_set_current_limit(get_max_mapped()); - dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT); /* * NOTE: On x86-32, only from this point on, fixmaps are ready for use. @@ -1159,6 +1158,7 @@ void __init setup_arch(char **cmdline_p) early_acpi_boot_init(); initmem_init(); + dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT); /* * Reserve memory for crash kernel after SRAT is parsed so that it diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 2d5200e56357..4d2128ac70bd 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -102,8 +102,6 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); EXPORT_PER_CPU_SYMBOL(cpu_info); -static DEFINE_PER_CPU(struct completion, die_complete); - atomic_t init_deasserted; /* @@ -1318,6 +1316,8 @@ void cpu_disable_common(void) fixup_irqs(); } +static DEFINE_PER_CPU(struct completion, die_complete); + int native_cpu_disable(void) { int ret; diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index b6025f9e36c6..b7e50bba3bbb 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1166,14 +1166,17 @@ void __init tsc_init(void) x86_init.timers.tsc_pre_init(); - if (!cpu_has_tsc) + if (!cpu_has_tsc) { + setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); return; + } tsc_khz = x86_platform.calibrate_tsc(); cpu_khz = tsc_khz; if (!tsc_khz) { mark_tsc_unstable("could not calculate TSC khz"); + setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); return; } diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 749f9fa38254..5edf088ca51e 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -574,12 +574,14 @@ static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, case 4: ctxt->_eip = (u32)dst; break; +#ifdef CONFIG_X86_64 case 8: if ((cs_l && is_noncanonical_address(dst)) || - (!cs_l && (dst & ~(u32)-1))) + (!cs_l && (dst >> 32) != 0)) return emulate_gp(ctxt, 0); ctxt->_eip = dst; break; +#endif default: WARN(1, "unsupported eip assignment size\n"); } @@ -641,7 +643,8 @@ static bool insn_aligned(struct x86_emulate_ctxt *ctxt, unsigned size) static int __linearize(struct x86_emulate_ctxt *ctxt, struct segmented_address addr, - unsigned size, bool write, bool fetch, + unsigned *max_size, unsigned size, + bool write, bool fetch, ulong *linear) { struct desc_struct desc; @@ -652,10 +655,15 @@ static int __linearize(struct x86_emulate_ctxt *ctxt, unsigned cpl; la = seg_base(ctxt, addr.seg) + addr.ea; + *max_size = 0; switch (ctxt->mode) { case X86EMUL_MODE_PROT64: if (((signed long)la << 16) >> 16 != la) return emulate_gp(ctxt, 0); + + *max_size = min_t(u64, ~0u, (1ull << 48) - la); + if (size > *max_size) + goto bad; break; default: usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL, @@ -673,20 +681,25 @@ static int __linearize(struct x86_emulate_ctxt *ctxt, if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch && (ctxt->d & NoBigReal)) { /* la is between zero and 0xffff */ - if (la > 0xffff || (u32)(la + size - 1) > 0xffff) + if (la > 0xffff) goto bad; + *max_size = 0x10000 - la; } else if ((desc.type & 8) || !(desc.type & 4)) { /* expand-up segment */ - if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) + if (addr.ea > lim) goto bad; + *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); } else { /* expand-down segment */ - if (addr.ea <= lim || (u32)(addr.ea + size - 1) <= lim) + if (addr.ea <= lim) goto bad; lim = desc.d ? 0xffffffff : 0xffff; - if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim) + if (addr.ea > lim) goto bad; + *max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea); } + if (size > *max_size) + goto bad; cpl = ctxt->ops->cpl(ctxt); if (!(desc.type & 8)) { /* data segment */ @@ -711,9 +724,9 @@ static int __linearize(struct x86_emulate_ctxt *ctxt, return X86EMUL_CONTINUE; bad: if (addr.seg == VCPU_SREG_SS) - return emulate_ss(ctxt, sel); + return emulate_ss(ctxt, 0); else - return emulate_gp(ctxt, sel); + return emulate_gp(ctxt, 0); } static int linearize(struct x86_emulate_ctxt *ctxt, @@ -721,7 +734,8 @@ static int linearize(struct x86_emulate_ctxt *ctxt, unsigned size, bool write, ulong *linear) { - return __linearize(ctxt, addr, size, write, false, linear); + unsigned max_size; + return __linearize(ctxt, addr, &max_size, size, write, false, linear); } @@ -746,17 +760,27 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt, static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) { int rc; - unsigned size; + unsigned size, max_size; unsigned long linear; int cur_size = ctxt->fetch.end - ctxt->fetch.data; struct segmented_address addr = { .seg = VCPU_SREG_CS, .ea = ctxt->eip + cur_size }; - size = 15UL ^ cur_size; - rc = __linearize(ctxt, addr, size, false, true, &linear); + /* + * We do not know exactly how many bytes will be needed, and + * __linearize is expensive, so fetch as much as possible. We + * just have to avoid going beyond the 15 byte limit, the end + * of the segment, or the end of the page. + * + * __linearize is called with size 0 so that it does not do any + * boundary check itself. Instead, we use max_size to check + * against op_size. + */ + rc = __linearize(ctxt, addr, &max_size, 0, false, true, &linear); if (unlikely(rc != X86EMUL_CONTINUE)) return rc; + size = min_t(unsigned, 15UL ^ cur_size, max_size); size = min_t(unsigned, size, PAGE_SIZE - offset_in_page(linear)); /* @@ -766,7 +790,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) * still, we must have hit the 15-byte boundary. */ if (unlikely(size < op_size)) - return X86EMUL_UNHANDLEABLE; + return emulate_gp(ctxt, 0); + rc = ctxt->ops->fetch(ctxt, linear, ctxt->fetch.end, size, &ctxt->exception); if (unlikely(rc != X86EMUL_CONTINUE)) @@ -2012,7 +2037,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); if (rc != X86EMUL_CONTINUE) { - WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); + WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); /* assigning eip failed; restore the old cs */ ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); return rc; @@ -2109,7 +2134,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) return rc; rc = assign_eip_far(ctxt, eip, new_desc.l); if (rc != X86EMUL_CONTINUE) { - WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); + WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64); ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); } return rc; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a8b76c4c95e2..3e556c68351b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4579,7 +4579,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu) vmcs_write32(TPR_THRESHOLD, 0); } - kvm_vcpu_reload_apic_access_page(vcpu); + kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); if (vmx_vm_has_apicv(vcpu->kvm)) memset(&vmx->pi_desc, 0, sizeof(struct pi_desc)); @@ -6426,6 +6426,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) const unsigned long *fields = shadow_read_write_fields; const int num_fields = max_shadow_read_write_fields; + preempt_disable(); + vmcs_load(shadow_vmcs); for (i = 0; i < num_fields; i++) { @@ -6449,6 +6451,8 @@ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx) vmcs_clear(shadow_vmcs); vmcs_load(vmx->loaded_vmcs->vmcs); + + preempt_enable(); } static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx) diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index ae242a7c11c7..36de293caf25 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -409,7 +409,7 @@ phys_addr_t slow_virt_to_phys(void *__virt_addr) psize = page_level_size(level); pmask = page_level_mask(level); offset = virt_addr & ~pmask; - phys_addr = pte_pfn(*pte) << PAGE_SHIFT; + phys_addr = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; return (phys_addr | offset); } EXPORT_SYMBOL_GPL(slow_virt_to_phys); diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c index 3c53a90fdb18..c14ad34776c4 100644 --- a/arch/x86/platform/intel-mid/sfi.c +++ b/arch/x86/platform/intel-mid/sfi.c @@ -106,6 +106,7 @@ int __init sfi_parse_mtmr(struct sfi_table_header *table) mp_irq.dstapic = MP_APIC_ALL; mp_irq.dstirq = pentry->irq; mp_save_irq(&mp_irq); + mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC); } return 0; @@ -176,6 +177,7 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table) mp_irq.dstapic = MP_APIC_ALL; mp_irq.dstirq = pentry->irq; mp_save_irq(&mp_irq); + mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC); } return 0; } diff --git a/block/blk-merge.c b/block/blk-merge.c index ba99351c0f58..b3ac40aef46b 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio) { bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); + bool merge_not_need = bio->bi_vcnt < queue_max_segments(q); if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && - bio->bi_vcnt < queue_max_segments(q)) + merge_not_need) bio->bi_phys_segments = bio->bi_vcnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, - no_sg_merge); + no_sg_merge && merge_not_need); bio->bi_next = nxt; } diff --git a/block/elevator.c b/block/elevator.c index 24c28b659bb3..afa3b037a17c 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -229,7 +229,9 @@ int elevator_init(struct request_queue *q, char *name) } err = e->ops.elevator_init_fn(q, e); - return 0; + if (err) + elevator_put(e); + return err; } EXPORT_SYMBOL(elevator_init); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index abb2e65b24cc..1e053d911240 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -508,7 +508,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) { err = DRIVER_ERROR << 24; - goto out; + goto error; } memset(sense, 0, sizeof(sense)); @@ -517,7 +517,6 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, blk_execute_rq(q, disk, rq, 0); -out: err = rq->errors & 0xff; /* only 8 bit SCSI status */ if (err) { if (rq->sense_len && rq->sense) { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3d304ff7f095..5f9b74b9b71f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -126,6 +126,7 @@ static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ +static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ /* -------------------------------------------------------------------------- * Transaction Management @@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec) } return wakeup; } else { - /* - * There is firmware refusing to respond QR_EC when SCI_EVT - * is not set, for which case, we complete the QR_EC - * without issuing it to the firmware. - * https://bugzilla.kernel.org/show_bug.cgi?id=86211 - */ - if (!(status & ACPI_EC_FLAG_SCI) && + if (EC_FLAGS_QUERY_HANDSHAKE && + !(status & ACPI_EC_FLAG_SCI) && (t->command == ACPI_EC_COMMAND_QUERY)) { t->flags |= ACPI_EC_COMMAND_POLL; t->rdata[t->ri++] = 0x00; @@ -334,13 +330,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, pr_debug("***** Command(%s) started *****\n", acpi_ec_cmd_string(t->command)); start_transaction(ec); - spin_unlock_irqrestore(&ec->lock, tmp); - ret = ec_poll(ec); - spin_lock_irqsave(&ec->lock, tmp); if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); pr_debug("***** Event stopped *****\n"); } + spin_unlock_irqrestore(&ec->lock, tmp); + ret = ec_poll(ec); + spin_lock_irqsave(&ec->lock, tmp); pr_debug("***** Command(%s) stopped *****\n", acpi_ec_cmd_string(t->command)); ec->curr = NULL; @@ -1011,6 +1007,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) return 0; } +/* + * Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for + * which case, we complete the QR_EC without issuing it to the firmware. + * https://bugzilla.kernel.org/show_bug.cgi?id=86211 + */ +static int ec_flag_query_handshake(const struct dmi_system_id *id) +{ + pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n"); + EC_FLAGS_QUERY_HANDSHAKE = 1; + return 0; +} + /* * On some hardware it is necessary to clear events accumulated by the EC during * sleep. These ECs stop reporting GPEs until they are manually polled, if too @@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { { ec_clear_on_resume, "Samsung hardware", { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, + { + ec_flag_query_handshake, "Acer hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL}, {}, }; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d670158a26c5..0476e90b2091 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -141,6 +141,53 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, return len; } +/* + * acpi_companion_match() - Can we match via ACPI companion device + * @dev: Device in question + * + * Check if the given device has an ACPI companion and if that companion has + * a valid list of PNP IDs, and if the device is the first (primary) physical + * device associated with it. + * + * If multiple physical devices are attached to a single ACPI companion, we need + * to be careful. The usage scenario for this kind of relationship is that all + * of the physical devices in question use resources provided by the ACPI + * companion. A typical case is an MFD device where all the sub-devices share + * the parent's ACPI companion. In such cases we can only allow the primary + * (first) physical device to be matched with the help of the companion's PNP + * IDs. + * + * Additional physical devices sharing the ACPI companion can still use + * resources available from it but they will be matched normally using functions + * provided by their bus types (and analogously for their modalias). + */ +static bool acpi_companion_match(const struct device *dev) +{ + struct acpi_device *adev; + bool ret; + + adev = ACPI_COMPANION(dev); + if (!adev) + return false; + + if (list_empty(&adev->pnp.ids)) + return false; + + mutex_lock(&adev->physical_node_lock); + if (list_empty(&adev->physical_node_list)) { + ret = false; + } else { + const struct acpi_device_physical_node *node; + + node = list_first_entry(&adev->physical_node_list, + struct acpi_device_physical_node, node); + ret = node->dev == dev; + } + mutex_unlock(&adev->physical_node_lock); + + return ret; +} + /* * Creates uevent modalias field for ACPI enumerated devices. * Because the other buses does not support ACPI HIDs & CIDs. @@ -149,20 +196,14 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, */ int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) { - struct acpi_device *acpi_dev; int len; - acpi_dev = ACPI_COMPANION(dev); - if (!acpi_dev) - return -ENODEV; - - /* Fall back to bus specific way of modalias exporting */ - if (list_empty(&acpi_dev->pnp.ids)) + if (!acpi_companion_match(dev)) return -ENODEV; if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; - len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], + len = create_modalias(ACPI_COMPANION(dev), &env->buf[env->buflen - 1], sizeof(env->buf) - env->buflen); if (len <= 0) return len; @@ -179,18 +220,12 @@ EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias); */ int acpi_device_modalias(struct device *dev, char *buf, int size) { - struct acpi_device *acpi_dev; int len; - acpi_dev = ACPI_COMPANION(dev); - if (!acpi_dev) + if (!acpi_companion_match(dev)) return -ENODEV; - /* Fall back to bus specific way of modalias exporting */ - if (list_empty(&acpi_dev->pnp.ids)) - return -ENODEV; - - len = create_modalias(acpi_dev, buf, size -1); + len = create_modalias(ACPI_COMPANION(dev), buf, size -1); if (len <= 0) return len; buf[len++] = '\n'; @@ -853,6 +888,9 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, if (!ids || !handle || acpi_bus_get_device(handle, &adev)) return NULL; + if (!acpi_companion_match(dev)) + return NULL; + return __acpi_match_device(adev, ids); } EXPORT_SYMBOL_GPL(acpi_match_device); diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 473ff4892401..950fff9ce453 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -223,9 +223,10 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, #undef pr_fmt #define pr_fmt(fmt) fmt -static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev) +static int rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev) { dev_set_cma_area(dev, rmem->priv); + return 0; } static void rmem_cma_device_release(struct reserved_mem *rmem, diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 44973196d3fd..9717d5f20139 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1266,6 +1266,8 @@ int dpm_suspend_late(pm_message_t state) } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); + if (!error) + error = async_error; if (error) { suspend_stats.failed_suspend_late++; dpm_save_failed_step(SUSPEND_SUSPEND_LATE); diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 1e5ac0a79696..cd9161a8b3a1 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -275,7 +275,7 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, static const struct pci_device_id bcma_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) }, /* 0xa8d8 */ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, @@ -285,7 +285,8 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xA8DB */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ { 0, }, }; MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index d1656c2f70af..1000955ce09d 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -132,7 +132,7 @@ static bool bcma_is_core_needed_early(u16 core_id) return false; } -#ifdef CONFIG_OF +#if defined(CONFIG_OF) && defined(CONFIG_OF_ADDRESS) static struct device_node *bcma_of_find_child_device(struct platform_device *parent, struct bcma_device *core) { diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 2671a3f02f0c..8001e812018b 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -450,14 +450,10 @@ static int init_driver_queues(struct nullb *nullb) ret = setup_commands(nq); if (ret) - goto err_queue; + return ret; nullb->nr_queues++; } - return 0; -err_queue: - cleanup_queues(nullb); - return ret; } static int null_add_dev(void) @@ -507,7 +503,9 @@ static int null_add_dev(void) goto out_cleanup_queues; } blk_queue_make_request(nullb->q, null_queue_bio); - init_driver_queues(nullb); + rv = init_driver_queues(nullb); + if (rv) + goto out_cleanup_blk_queue; } else { nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node); if (!nullb->q) { @@ -516,7 +514,9 @@ static int null_add_dev(void) } blk_queue_prep_rq(nullb->q, null_rq_prep_fn); blk_queue_softirq_done(nullb->q, null_softirq_done_fn); - init_driver_queues(nullb); + rv = init_driver_queues(nullb); + if (rv) + goto out_cleanup_blk_queue; } nullb->q->queuedata = nullb; diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 0a54c588e433..27b71a0b72d0 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -342,7 +342,6 @@ struct rbd_device { struct list_head rq_queue; /* incoming rq queue */ spinlock_t lock; /* queue, flags, open_count */ - struct workqueue_struct *rq_wq; struct work_struct rq_work; struct rbd_image_header header; @@ -402,6 +401,8 @@ static struct kmem_cache *rbd_segment_name_cache; static int rbd_major; static DEFINE_IDA(rbd_dev_id_ida); +static struct workqueue_struct *rbd_wq; + /* * Default to false for now, as single-major requires >= 0.75 version of * userspace rbd utility. @@ -3452,7 +3453,7 @@ static void rbd_request_fn(struct request_queue *q) } if (queued) - queue_work(rbd_dev->rq_wq, &rbd_dev->rq_work); + queue_work(rbd_wq, &rbd_dev->rq_work); } /* @@ -3532,7 +3533,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, page_count = (u32) calc_pages_for(offset, length); pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); if (IS_ERR(pages)) - ret = PTR_ERR(pages); + return PTR_ERR(pages); ret = -ENOMEM; obj_request = rbd_obj_request_create(object_name, offset, length, @@ -5242,16 +5243,9 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); set_disk_ro(rbd_dev->disk, rbd_dev->mapping.read_only); - rbd_dev->rq_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, - rbd_dev->disk->disk_name); - if (!rbd_dev->rq_wq) { - ret = -ENOMEM; - goto err_out_mapping; - } - ret = rbd_bus_add_dev(rbd_dev); if (ret) - goto err_out_workqueue; + goto err_out_mapping; /* Everything's ready. Announce the disk to the world. */ @@ -5263,9 +5257,6 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) return ret; -err_out_workqueue: - destroy_workqueue(rbd_dev->rq_wq); - rbd_dev->rq_wq = NULL; err_out_mapping: rbd_dev_mapping_clear(rbd_dev); err_out_disk: @@ -5512,7 +5503,6 @@ static void rbd_dev_device_release(struct device *dev) { struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); - destroy_workqueue(rbd_dev->rq_wq); rbd_free_disk(rbd_dev); clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); rbd_dev_mapping_clear(rbd_dev); @@ -5716,11 +5706,21 @@ static int __init rbd_init(void) if (rc) return rc; + /* + * The number of active work items is limited by the number of + * rbd devices, so leave @max_active at default. + */ + rbd_wq = alloc_workqueue(RBD_DRV_NAME, WQ_MEM_RECLAIM, 0); + if (!rbd_wq) { + rc = -ENOMEM; + goto err_out_slab; + } + if (single_major) { rbd_major = register_blkdev(0, RBD_DRV_NAME); if (rbd_major < 0) { rc = rbd_major; - goto err_out_slab; + goto err_out_wq; } } @@ -5738,6 +5738,8 @@ static int __init rbd_init(void) err_out_blkdev: if (single_major) unregister_blkdev(rbd_major, RBD_DRV_NAME); +err_out_wq: + destroy_workqueue(rbd_wq); err_out_slab: rbd_slab_exit(); return rc; @@ -5749,6 +5751,7 @@ static void __exit rbd_exit(void) rbd_sysfs_cleanup(); if (single_major) unregister_blkdev(rbd_major, RBD_DRV_NAME); + destroy_workqueue(rbd_wq); rbd_slab_exit(); } diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 756b8ec00f16..0ebadf93b6c5 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -69,8 +69,6 @@ struct vdc_port { u8 vdisk_mtype; char disk_name[32]; - - struct vio_disk_vtoc label; }; static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) @@ -710,13 +708,6 @@ static int probe_disk(struct vdc_port *port) if (comp.err) return comp.err; - err = generic_request(port, VD_OP_GET_VTOC, - &port->label, sizeof(port->label)); - if (err < 0) { - printk(KERN_ERR PFX "VD_OP_GET_VTOC returns error %d\n", err); - return err; - } - if (vdc_version_supported(port, 1, 1)) { /* vdisk_size should be set during the handshake, if it wasn't * then the underlying disk is reserved by another system diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 0e63e8aa8279..2ad0b5bce44b 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -99,11 +99,12 @@ static ssize_t mem_used_total_show(struct device *dev, { u64 val = 0; struct zram *zram = dev_to_zram(dev); - struct zram_meta *meta = zram->meta; down_read(&zram->init_lock); - if (init_done(zram)) + if (init_done(zram)) { + struct zram_meta *meta = zram->meta; val = zs_get_total_pages(meta->mem_pool); + } up_read(&zram->init_lock); return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT); @@ -173,16 +174,17 @@ static ssize_t mem_used_max_store(struct device *dev, int err; unsigned long val; struct zram *zram = dev_to_zram(dev); - struct zram_meta *meta = zram->meta; err = kstrtoul(buf, 10, &val); if (err || val != 0) return -EINVAL; down_read(&zram->init_lock); - if (init_done(zram)) + if (init_done(zram)) { + struct zram_meta *meta = zram->meta; atomic_long_set(&zram->stats.max_used_pages, zs_get_total_pages(meta->mem_pool)); + } up_read(&zram->init_lock); return len; diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 0102dc788608..a24891b97547 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, static const struct file_operations raw_fops = { .read = new_sync_read, - .read_iter = generic_file_read_iter, + .read_iter = blkdev_read_iter, .write = new_sync_write, .write_iter = blkdev_write_iter, .fsync = blkdev_fsync, diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 2133f9d59d06..43005d4d3348 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -660,11 +660,11 @@ static bool __init arch_timer_probed(int type, const struct of_device_id *matches) { struct device_node *dn; - bool probed = false; + bool probed = true; dn = of_find_matching_node(NULL, matches); - if (dn && of_device_is_available(dn) && (arch_timers_present & type)) - probed = true; + if (dn && of_device_is_available(dn) && !(arch_timers_present & type)) + probed = false; of_node_put(dn); return probed; diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 92c162af5045..23aaf40cf37f 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -187,6 +187,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) struct device *cpu_dev; struct regulator *cpu_reg; struct clk *cpu_clk; + unsigned long min_uV = ~0, max_uV = 0; unsigned int transition_latency; int ret; @@ -206,16 +207,10 @@ static int cpufreq_init(struct cpufreq_policy *policy) /* OPPs might be populated at runtime, don't check for error here */ of_init_opp_table(cpu_dev); - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); - if (ret) { - dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); - goto out_put_node; - } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; - goto out_free_table; + goto out_put_node; } of_property_read_u32(np, "voltage-tolerance", &priv->voltage_tolerance); @@ -224,30 +219,51 @@ static int cpufreq_init(struct cpufreq_policy *policy) transition_latency = CPUFREQ_ETERNAL; if (!IS_ERR(cpu_reg)) { - struct dev_pm_opp *opp; - unsigned long min_uV, max_uV; - int i; + unsigned long opp_freq = 0; /* - * OPP is maintained in order of increasing frequency, and - * freq_table initialised from OPP is therefore sorted in the - * same order. + * Disable any OPPs where the connected regulator isn't able to + * provide the specified voltage and record minimum and maximum + * voltage levels. */ - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) - ; - rcu_read_lock(); - opp = dev_pm_opp_find_freq_exact(cpu_dev, - freq_table[0].frequency * 1000, true); - min_uV = dev_pm_opp_get_voltage(opp); - opp = dev_pm_opp_find_freq_exact(cpu_dev, - freq_table[i-1].frequency * 1000, true); - max_uV = dev_pm_opp_get_voltage(opp); - rcu_read_unlock(); + while (1) { + struct dev_pm_opp *opp; + unsigned long opp_uV, tol_uV; + + rcu_read_lock(); + opp = dev_pm_opp_find_freq_ceil(cpu_dev, &opp_freq); + if (IS_ERR(opp)) { + rcu_read_unlock(); + break; + } + opp_uV = dev_pm_opp_get_voltage(opp); + rcu_read_unlock(); + + tol_uV = opp_uV * priv->voltage_tolerance / 100; + if (regulator_is_supported_voltage(cpu_reg, opp_uV, + opp_uV + tol_uV)) { + if (opp_uV < min_uV) + min_uV = opp_uV; + if (opp_uV > max_uV) + max_uV = opp_uV; + } else { + dev_pm_opp_disable(cpu_dev, opp_freq); + } + + opp_freq++; + } + ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); if (ret > 0) transition_latency += ret * 1000; } + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); + if (ret) { + pr_err("failed to init cpufreq table: %d\n", ret); + goto out_free_priv; + } + /* * For now, just loading the cooling device; * thermal DT code takes care of matching them. @@ -277,7 +293,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = transition_latency; pd = cpufreq_get_driver_data(); - if (pd && !pd->independent_clocks) + if (!pd || !pd->independent_clocks) cpumask_setall(policy->cpus); of_node_put(np); @@ -286,9 +302,9 @@ static int cpufreq_init(struct cpufreq_policy *policy) out_cooling_unregister: cpufreq_cooling_unregister(priv->cdev); - kfree(priv); -out_free_table: dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); +out_free_priv: + kfree(priv); out_put_node: of_node_put(np); out_put_reg_clk: diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c index df6575f1430d..682288ced4ac 100644 --- a/drivers/edac/cpc925_edac.c +++ b/drivers/edac/cpc925_edac.c @@ -562,7 +562,7 @@ static void cpc925_mc_check(struct mem_ctl_info *mci) if (apiexcp & UECC_EXCP_DETECTED) { cpc925_mc_printk(mci, KERN_INFO, "DRAM UECC Fault\n"); - edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, pfn, offset, 0, csrow, -1, -1, mci->ctl_name, ""); diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index 3cda79bc8b00..ece3aef16bb1 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -226,7 +226,7 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) static void process_ce_no_info(struct mem_ctl_info *mci) { edac_dbg(3, "\n"); - edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, 0, -1, -1, -1, "e7xxx CE log register overflow", ""); } diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index 022a70273ada..aa98b136f5d0 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c @@ -242,11 +242,11 @@ static void i3200_process_error_info(struct mem_ctl_info *mci, -1, -1, "i3000 UE", ""); } else if (log & I3200_ECCERRLOG_CE) { - edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, 0, 0, eccerrlog_syndrome(log), eccerrlog_row(channel, log), -1, -1, - "i3000 UE", ""); + "i3000 CE", ""); } } } diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index 3382f6344e42..4382343a7c60 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -124,7 +124,7 @@ static int i82860_process_error_info(struct mem_ctl_info *mci, dimm->location[0], dimm->location[1], -1, "i82860 UE", ""); else - edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1, info->eap, 0, info->derrsyn, dimm->location[0], dimm->location[1], -1, "i82860 CE", ""); diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 9a0cc09e6653..e4a1490b42c2 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -260,7 +260,7 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc) * Tell the DRM core that vblank IRQs aren't going to happen for * a while. This cleans up any pending vblank events for us. */ - drm_vblank_off(dev, dcrtc->num); + drm_crtc_vblank_off(&dcrtc->crtc); /* Handle any pending flip event. */ spin_lock_irq(&dev->event_lock); @@ -289,6 +289,8 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms) armada_drm_crtc_update(dcrtc); if (dpms_blanked(dpms)) armada_drm_vblank_off(dcrtc); + else + drm_crtc_vblank_on(&dcrtc->crtc); } } @@ -526,7 +528,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, /* Wait for pending flips to complete */ wait_event(dcrtc->frame_wait, !dcrtc->frame_work); - drm_vblank_pre_modeset(crtc->dev, dcrtc->num); + drm_crtc_vblank_off(crtc); crtc->mode = *adj; @@ -617,7 +619,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, armada_drm_crtc_update(dcrtc); - drm_vblank_post_modeset(crtc->dev, dcrtc->num); + drm_crtc_vblank_on(crtc); armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms)); return 0; @@ -945,18 +947,15 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, armada_reg_queue_end(work->regs, i); /* - * Hold the old framebuffer for the work - DRM appears to drop our - * reference to the old framebuffer in drm_mode_page_flip_ioctl(). + * Ensure that we hold a reference on the new framebuffer. + * This has to match the behaviour in mode_set. */ - drm_framebuffer_reference(work->old_fb); + drm_framebuffer_reference(fb); ret = armada_drm_crtc_queue_frame_work(dcrtc, work); if (ret) { - /* - * Undo our reference above; DRM does not drop the reference - * to this object on error, so that's okay. - */ - drm_framebuffer_unreference(work->old_fb); + /* Undo our reference above */ + drm_framebuffer_unreference(fb); kfree(work); return ret; } diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index f672e6ad8afa..908e5316eac4 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -190,6 +190,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_comp; + dev->irq_enabled = true; dev->vblank_disable_allowed = 1; ret = armada_fbdev_init(dev); @@ -331,7 +332,7 @@ static struct drm_driver armada_drm_driver = { .desc = "Armada SoC DRM", .date = "20120730", .driver_features = DRIVER_GEM | DRIVER_MODESET | - DRIVER_PRIME, + DRIVER_HAVE_IRQ | DRIVER_PRIME, .ioctls = armada_ioctls, .fops = &armada_drm_fops, }; diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index cd50ece31601..6adb1e5cfb08 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -1355,13 +1355,8 @@ static void exynos_dp_unbind(struct device *dev, struct device *master, void *data) { struct exynos_drm_display *display = dev_get_drvdata(dev); - struct exynos_dp_device *dp = display->ctx; - struct drm_encoder *encoder = dp->encoder; exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); - - exynos_dp_connector_destroy(&dp->connector); - encoder->funcs->destroy(encoder); } static const struct component_ops exynos_dp_ops = { diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 8e38e9f8e542..45026e693225 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -71,13 +71,16 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) !atomic_read(&exynos_crtc->pending_flip), HZ/20)) atomic_set(&exynos_crtc->pending_flip, 0); - drm_vblank_off(crtc->dev, exynos_crtc->pipe); + drm_crtc_vblank_off(crtc); } if (manager->ops->dpms) manager->ops->dpms(manager, mode); exynos_crtc->dpms = mode; + + if (mode == DRM_MODE_DPMS_ON) + drm_crtc_vblank_on(crtc); } static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 96c87db388fb..3dc678ed9949 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -338,14 +338,10 @@ err_del_component: int exynos_dpi_remove(struct device *dev) { - struct drm_encoder *encoder = exynos_dpi_display.encoder; struct exynos_dpi *ctx = exynos_dpi_display.ctx; exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); - exynos_dpi_connector_destroy(&ctx->connector); - encoder->funcs->destroy(encoder); - if (ctx->panel) drm_panel_detach(ctx->panel); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 443a2069858a..c57466edf45b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -87,16 +87,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) plane = exynos_plane_init(dev, possible_crtcs, DRM_PLANE_TYPE_OVERLAY); - if (IS_ERR(plane)) - goto err_mode_config_cleanup; - } + if (!IS_ERR(plane)) + continue; - /* init kms poll for handling hpd */ - drm_kms_helper_poll_init(dev); - - ret = drm_vblank_init(dev, MAX_CRTC); - if (ret) + ret = PTR_ERR(plane); goto err_mode_config_cleanup; + } /* setup possible_clones. */ exynos_drm_encoder_setup(dev); @@ -106,15 +102,16 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) /* Try to bind all sub drivers. */ ret = component_bind_all(dev->dev, dev); if (ret) - goto err_cleanup_vblank; + goto err_mode_config_cleanup; + + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); + if (ret) + goto err_unbind_all; /* Probe non kms sub drivers and virtual display driver. */ ret = exynos_drm_device_subdrv_probe(dev); if (ret) - goto err_unbind_all; - - /* force connectors detection */ - drm_helper_hpd_irq_event(dev); + goto err_cleanup_vblank; /* * enable drm irq mode. @@ -133,12 +130,18 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) */ dev->vblank_disable_allowed = true; + /* init kms poll for handling hpd */ + drm_kms_helper_poll_init(dev); + + /* force connectors detection */ + drm_helper_hpd_irq_event(dev); + return 0; -err_unbind_all: - component_unbind_all(dev->dev, dev); err_cleanup_vblank: drm_vblank_cleanup(dev); +err_unbind_all: + component_unbind_all(dev->dev, dev); err_mode_config_cleanup: drm_mode_config_cleanup(dev); drm_release_iommu_mapping(dev); @@ -155,8 +158,8 @@ static int exynos_drm_unload(struct drm_device *dev) exynos_drm_fbdev_fini(dev); drm_kms_helper_poll_fini(dev); - component_unbind_all(dev->dev, dev); drm_vblank_cleanup(dev); + component_unbind_all(dev->dev, dev); drm_mode_config_cleanup(dev); drm_release_iommu_mapping(dev); @@ -191,8 +194,12 @@ static int exynos_drm_resume(struct drm_device *dev) drm_modeset_lock_all(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->funcs->dpms) - connector->funcs->dpms(connector, connector->dpms); + if (connector->funcs->dpms) { + int dpms = connector->dpms; + + connector->dpms = DRM_MODE_DPMS_OFF; + connector->funcs->dpms(connector, dpms); + } } drm_modeset_unlock_all(dev); diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index 24741d8758e8..acf7e9e39dcd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1660,13 +1660,9 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master, void *data) { struct exynos_dsi *dsi = exynos_dsi_display.ctx; - struct drm_encoder *encoder = dsi->encoder; exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF); - exynos_dsi_connector_destroy(&dsi->connector); - encoder->funcs->destroy(encoder); - mipi_dsi_host_unregister(&dsi->dsi_host); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d565207040a2..50faf913e574 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -630,7 +630,6 @@ static int vidi_remove(struct platform_device *pdev) { struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); struct vidi_context *ctx = mgr->ctx; - struct drm_encoder *encoder = ctx->encoder; if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); @@ -639,9 +638,6 @@ static int vidi_remove(struct platform_device *pdev) return -EINVAL; } - encoder->funcs->destroy(encoder); - drm_connector_cleanup(&ctx->connector); - return 0; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 7910fb37d9bb..563a19e62eb2 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2312,12 +2312,6 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) static void hdmi_unbind(struct device *dev, struct device *master, void *data) { - struct exynos_drm_display *display = get_hdmi_display(dev); - struct drm_encoder *encoder = display->encoder; - struct hdmi_context *hdata = display->ctx; - - hdmi_connector_destroy(&hdata->connector); - encoder->funcs->destroy(encoder); } static const struct component_ops hdmi_component_ops = { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c9e220963a78..f0a1a56406eb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4585,7 +4585,7 @@ static void vlv_update_cdclk(struct drm_device *dev) * BSpec erroneously claims we should aim for 4MHz, but * in fact 1MHz is the correct frequency. */ - I915_WRITE(GMBUSFREQ_VLV, dev_priv->vlv_cdclk_freq); + I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->vlv_cdclk_freq, 1000)); } /* Adjust CDclk dividers to allow high res or save power if possible */ @@ -12885,6 +12885,9 @@ static struct intel_quirk intel_quirks[] = { /* Acer C720 Chromebook (Core i3 4005U) */ { 0x0a16, 0x1025, 0x0a11, quirk_backlight_present }, + /* Apple Macbook 2,1 (Core 2 T7400) */ + { 0x27a2, 0x8086, 0x7270, quirk_backlight_present }, + /* Toshiba CB35 Chromebook (Celeron 2955U) */ { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f6a3fdd5589e..5ad45bfff3fe 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2806,6 +2806,13 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset, ssize_t ret; int i; + /* + * Sometime we just get the same incorrect byte repeated + * over the entire buffer. Doing just one throw away read + * initially seems to "solve" it. + */ + drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1); + for (i = 0; i < 3; i++) { ret = drm_dp_dpcd_read(aux, offset, buffer, size); if (ret == size) @@ -3724,9 +3731,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) } } - /* Training Pattern 3 support */ + /* Training Pattern 3 support, both source and sink */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && - intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { + intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED && + (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)) { intel_dp->use_tps3 = true; DRM_DEBUG_KMS("Displayport TPS3 supported\n"); } else @@ -4491,6 +4499,18 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; + if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { + /* + * vdd off can generate a long pulse on eDP which + * would require vdd on to handle it, and thus we + * would end up in an endless cycle of + * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..." + */ + DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", + port_name(intel_dig_port->port)); + return false; + } + DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", port_name(intel_dig_port->port), long_hpd ? "long" : "short"); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a31f1ca40c6a..f37d39d2bbbc 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3005,7 +3005,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) u32 vgt_cache_invalidation; u32 hdp_host_path_cntl, tmp; u32 disabled_rb_mask; - int i, j, num_shader_engines, ps_thread_count; + int i, j, ps_thread_count; switch (rdev->family) { case CHIP_CYPRESS: @@ -3303,8 +3303,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.tile_config |= ((gb_addr_config & 0x30000000) >> 28) << 12; - num_shader_engines = (gb_addr_config & NUM_SHADER_ENGINES(3) >> 12) + 1; - if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) { u32 efuse_straps_4; u32 efuse_straps_3; diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 1dd976f447fa..9b42001295ba 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2725,7 +2725,11 @@ int kv_dpm_init(struct radeon_device *rdev) pi->sram_end = SMC_RAM_END; - pi->enable_nb_dpm = true; + /* Enabling nb dpm on an asrock system prevents dpm from working */ + if (rdev->pdev->subsystem_vendor == 0x1849) + pi->enable_nb_dpm = false; + else + pi->enable_nb_dpm = true; pi->caps_power_containment = true; pi->caps_cac = true; @@ -2740,10 +2744,19 @@ int kv_dpm_init(struct radeon_device *rdev) pi->caps_sclk_ds = true; pi->enable_auto_thermal_throttling = true; pi->disable_nb_ps3_in_battery = false; - if (radeon_bapm == 0) + if (radeon_bapm == -1) { + /* There are stability issues reported on with + * bapm enabled on an asrock system. + */ + if (rdev->pdev->subsystem_vendor == 0x1849) + pi->bapm_enable = false; + else + pi->bapm_enable = true; + } else if (radeon_bapm == 0) { pi->bapm_enable = false; - else + } else { pi->bapm_enable = true; + } pi->voltage_drop_t = 0; pi->caps_sclk_throttle_low_notification = false; pi->caps_fps = false; /* true? */ diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 6a03624fadaa..63ccb8fa799c 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -658,12 +658,10 @@ bool radeon_get_bios(struct radeon_device *rdev) r = igp_read_bios_from_vram(rdev); if (r == false) r = radeon_read_bios(rdev); - if (r == false) { + if (r == false) r = radeon_read_disabled_bios(rdev); - } - if (r == false) { + if (r == false) r = radeon_read_platform_bios(rdev); - } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 1c893447d7cd..a3e7aed7e680 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -450,7 +450,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo kfree(parser->track); kfree(parser->relocs); kfree(parser->relocs_ptr); - kfree(parser->vm_bos); + drm_free_large(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 3d17af34afa7..2456f69efd23 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -314,7 +314,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring } /* and then save the content of the ring */ - *data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); + *data = drm_malloc_ab(size, sizeof(uint32_t)); if (!*data) { mutex_unlock(&rdev->ring_lock); return 0; @@ -356,7 +356,7 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, } radeon_ring_unlock_commit(rdev, ring, false); - kfree(data); + drm_free_large(data); return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 4532cc76a0a6..dfde266529e2 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -132,8 +132,8 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_cs_reloc *list; unsigned i, idx; - list = kmalloc_array(vm->max_pde_used + 2, - sizeof(struct radeon_cs_reloc), GFP_KERNEL); + list = drm_malloc_ab(vm->max_pde_used + 2, + sizeof(struct radeon_cs_reloc)); if (!list) return NULL; diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index a53c2e79d9cb..676e6c2ba90a 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -6256,7 +6256,7 @@ static void si_parse_pplib_clock_info(struct radeon_device *rdev, if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) && index == 0) { /* XXX disable for A0 tahiti */ - si_pi->ulv.supported = true; + si_pi->ulv.supported = false; si_pi->ulv.pl = *pl; si_pi->ulv.one_pcie_lane_in_ulv = false; si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index bfeb4b1f2acf..21e9b7f8dad0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -246,7 +246,8 @@ int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man, struct drm_hash_item *hash; int ret; - ret = drm_ht_find_item(&man->resources, user_key, &hash); + ret = drm_ht_find_item(&man->resources, user_key | (res_type << 24), + &hash); if (likely(ret != 0)) return -EINVAL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7197af157313..25f3c250fd98 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -688,7 +688,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) goto out_err0; } - if (unlikely(dev_priv->prim_bb_mem < dev_priv->vram_size)) + /* + * Limit back buffer size to VRAM size. Remove this once + * screen targets are implemented. + */ + if (dev_priv->prim_bb_mem > dev_priv->vram_size) dev_priv->prim_bb_mem = dev_priv->vram_size; mutex_unlock(&dev_priv->hw_mutex); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index d2bc2b03d4c6..941a7bc0b791 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -187,7 +187,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, * can do this since the caller in the drm core doesn't check anything * which is protected by any looks. */ - drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock_crtc(crtc); drm_modeset_lock_all(dev_priv->dev); /* A lot of the code assumes this */ @@ -252,7 +252,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ret = 0; out: drm_modeset_unlock_all(dev_priv->dev); - drm_modeset_lock(&crtc->mutex, NULL); + drm_modeset_lock_crtc(crtc); return ret; } @@ -273,7 +273,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) * can do this since the caller in the drm core doesn't check anything * which is protected by any looks. */ - drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock_crtc(crtc); drm_modeset_lock_all(dev_priv->dev); vmw_cursor_update_position(dev_priv, shown, @@ -281,7 +281,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) du->cursor_y + du->hotspot_y); drm_modeset_unlock_all(dev_priv->dev); - drm_modeset_lock(&crtc->mutex, NULL); + drm_modeset_lock_crtc(crtc); return 0; } @@ -1950,6 +1950,14 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }; int i; + u32 assumed_bpp = 2; + + /* + * If using screen objects, then assume 32-bpp because that's what the + * SVGA device is assuming + */ + if (dev_priv->sou_priv) + assumed_bpp = 4; /* Add preferred mode */ { @@ -1960,8 +1968,9 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, mode->vdisplay = du->pref_height; vmw_guess_mode_timing(mode); - if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2, - mode->vdisplay)) { + if (vmw_kms_validate_mode_vram(dev_priv, + mode->hdisplay * assumed_bpp, + mode->vdisplay)) { drm_mode_probed_add(connector, mode); } else { drm_mode_destroy(dev, mode); @@ -1983,7 +1992,8 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector, bmode->vdisplay > max_height) continue; - if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2, + if (!vmw_kms_validate_mode_vram(dev_priv, + bmode->hdisplay * assumed_bpp, bmode->vdisplay)) continue; diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 84c3cb15ccdd..8bf61d295ffd 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -946,6 +946,12 @@ static const char *keys[KEY_MAX + 1] = { [KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MAX] = "BrightnessMax", [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", + [KEY_KBDINPUTASSIST_PREV] = "KbdInputAssistPrev", + [KEY_KBDINPUTASSIST_NEXT] = "KbdInputAssistNext", + [KEY_KBDINPUTASSIST_PREVGROUP] = "KbdInputAssistPrevGroup", + [KEY_KBDINPUTASSIST_NEXTGROUP] = "KbdInputAssistNextGroup", + [KEY_KBDINPUTASSIST_ACCEPT] = "KbdInputAssistAccept", + [KEY_KBDINPUTASSIST_CANCEL] = "KbdInputAssistCancel", }; static const char *relatives[REL_MAX + 1] = { diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cd9c9e96cf0e..e23ab8b30626 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -298,6 +298,8 @@ #define USB_VENDOR_ID_ELAN 0x04f3 #define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089 +#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b +#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2df7fddbd119..725f22ca47fc 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -695,7 +695,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; case 0x5b: /* TransducerSerialNumber */ - set_bit(MSC_SERIAL, input->mscbit); + usage->type = EV_MSC; + usage->code = MSC_SERIAL; + bit = input->mscbit; + max = MSC_MAX; break; default: goto unknown; @@ -862,6 +865,13 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; case 0x28c: map_key_clear(KEY_SEND); break; + case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break; + case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break; + case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break; + case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP); break; + case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break; + case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break; + default: goto ignore; } break; diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index f3cb5b0a4345..5014bb567b29 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -71,6 +71,8 @@ static const struct hid_blacklist { { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index 1665c8e4b62b..e18bc6782256 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -71,7 +71,7 @@ int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) goto st_sensors_free_memory; } - for (i = 0; i < n * num_data_channels; i++) { + for (i = 0; i < n * byte_for_channel; i++) { if (i < n) buf[i] = rx_array[i]; else diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index bda5994ceb68..8b72cf392b34 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -1173,18 +1173,24 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, err = __mlx4_ib_create_flow(qp, flow_attr, domain, type[i], &mflow->reg_id[i]); if (err) - goto err_free; + goto err_create_flow; i++; } if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) { err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]); if (err) - goto err_free; + goto err_create_flow; + i++; } return &mflow->ibflow; +err_create_flow: + while (i) { + (void)__mlx4_ib_destroy_flow(to_mdev(qp->device)->dev, mflow->reg_id[i]); + i--; + } err_free: kfree(mflow); return ERR_PTR(err); diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 62abe2c16670..f8502bb29176 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -70,7 +70,7 @@ static int opencores_kbd_probe(struct platform_device *pdev) opencores_kbd->addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(opencores_kbd->addr)) - error = PTR_ERR(opencores_kbd->addr); + return PTR_ERR(opencores_kbd->addr); input->name = pdev->name; input->phys = "opencores-kbd/input0"; diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index c6727dda68f2..ef5e67fb567e 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -86,7 +86,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { .max_cols = 8, .max_rows = 12, .col_gpios = 0x0000ff, /* GPIO 0 - 7*/ - .row_gpios = 0x1fef00, /* GPIO 8-14, 16-20 */ + .row_gpios = 0x1f7f00, /* GPIO 8-14, 16-20 */ }, [STMPE2403] = { .auto_increment = true, diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 719410feb84b..afed8e2b2f94 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -1381,7 +1381,7 @@ static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev, pcu->ofn_reg_addr = value; mutex_unlock(&pcu->cmd_mutex); - return error ?: count; + return count; } static DEVICE_ATTR(reg_addr, S_IRUGO | S_IWUSR, diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 7b1fde93799e..ef6a9d650d69 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -194,7 +194,7 @@ static int max77693_haptic_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) { struct max77693_haptic *haptic = input_get_drvdata(dev); - uint64_t period_mag_multi; + u64 period_mag_multi; haptic->magnitude = effect->u.rumble.strong_magnitude; if (!haptic->magnitude) @@ -205,8 +205,7 @@ static int max77693_haptic_play_effect(struct input_dev *dev, void *data, * The formula to convert magnitude to pwm_duty as follows: * - pwm_duty = (magnitude * pwm_period) / MAX_MAGNITUDE(0xFFFF) */ - period_mag_multi = (int64_t)(haptic->pwm_dev->period * - haptic->magnitude); + period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude; haptic->pwm_duty = (unsigned int)(period_mag_multi >> MAX_MAGNITUDE_SHIFT); diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 735604753568..e097f1ab427f 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -55,7 +55,7 @@ static int soc_button_lookup_gpio(struct device *dev, int acpi_index) struct gpio_desc *desc; int gpio; - desc = gpiod_get_index(dev, KBUILD_MODNAME, acpi_index); + desc = gpiod_get_index(dev, KBUILD_MODNAME, acpi_index, GPIOD_ASIS); if (IS_ERR(desc)) return PTR_ERR(desc); diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 26994f6a2b2a..95a3a6e2faf6 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1536,16 +1536,9 @@ static int psmouse_reconnect(struct serio *serio) { struct psmouse *psmouse = serio_get_drvdata(serio); struct psmouse *parent = NULL; - struct serio_driver *drv = serio->drv; unsigned char type; int rc = -1; - if (!drv || !psmouse) { - psmouse_dbg(psmouse, - "reconnect request, but serio is disconnected, ignoring...\n"); - return -1; - } - mutex_lock(&psmouse_mutex); if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 38298232124f..abd494411e69 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -128,7 +128,7 @@ static void vsxxxaa_drop_bytes(struct vsxxxaa *mouse, int num) if (num >= mouse->count) { mouse->count = 0; } else { - memmove(mouse->buf, mouse->buf + num - 1, BUFLEN - num); + memmove(mouse->buf, mouse->buf + num, BUFLEN - num); mouse->count -= num; } } diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index cce69d6b9587..58781c8a8aec 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -37,7 +37,7 @@ static irqreturn_t altera_ps2_rxint(int irq, void *dev_id) { struct ps2if *ps2if = dev_id; unsigned int status; - int handled = IRQ_NONE; + irqreturn_t handled = IRQ_NONE; while ((status = readl(ps2if->base)) & 0xffff0000) { serio_interrupt(ps2if->io, status & 0xff, 0); @@ -74,7 +74,7 @@ static void altera_ps2_close(struct serio *io) { struct ps2if *ps2if = io->port_data; - writel(0, ps2if->base); /* disable rx irq */ + writel(0, ps2if->base + 4); /* disable rx irq */ } /* diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a0bcbb64d06d..faeeb1372462 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -207,17 +207,282 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { }; /* - * Some laptops do implement active multiplexing mode correctly; - * unfortunately they are in minority. + * Some Fujitsu notebooks are having trouble with touchpads if + * active multiplexing mode is activated. Luckily they don't have + * external PS/2 ports so we can safely disable it. + * ... apparently some Toshibas don't like MUX mode either and + * die horrible death on reboot. */ -static const struct dmi_system_id __initconst i8042_dmi_mux_table[] = { +static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { + { + /* Fujitsu Lifebook P7010/P7010D */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), + }, + }, + { + /* Fujitsu Lifebook P7010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), + }, + }, + { + /* Fujitsu Lifebook P5020D */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), + }, + }, + { + /* Fujitsu Lifebook S2000 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), + }, + }, + { + /* Fujitsu Lifebook S6230 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), + }, + }, + { + /* Fujitsu T70H */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), + }, + }, + { + /* Fujitsu-Siemens Lifebook T3010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), + }, + }, + { + /* Fujitsu-Siemens Lifebook E4010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), + }, + }, + { + /* Fujitsu-Siemens Amilo Pro 2010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), + }, + }, + { + /* Fujitsu-Siemens Amilo Pro 2030 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), + }, + }, { /* - * Panasonic CF-18 needs to be in MUX mode since the - * touchscreen is on serio3 and it also has touchpad. + * No data is coming from the touchscreen unless KBC + * is in legacy mode. + */ + /* Panasonic CF-29 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), + DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), + }, + }, + { + /* + * HP Pavilion DV4017EA - + * errors on MUX ports are reported without raising AUXDATA + * causing "spurious NAK" messages. */ .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), + }, + }, + { + /* + * HP Pavilion ZT1000 - + * like DV4017EA does not raise AUXERR for errors on MUX ports. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), + DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), + }, + }, + { + /* + * HP Pavilion DV4270ca - + * like DV4017EA does not raise AUXERR for errors on MUX ports. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), + }, + }, + { + /* Sharp Actius MM20 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), + DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), + }, + }, + { + /* Sony Vaio FS-115b */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), + }, + }, + { + /* + * Sony Vaio FZ-240E - + * reset and GET ID commands issued via KBD port are + * sometimes being delivered to AUX3. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), + }, + }, + { + /* + * Most (all?) VAIOs do not have external PS/2 ports nor + * they implement active multiplexing properly, and + * MUX discovery usually messes up keyboard/touchpad. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "VAIO"), + }, + }, + { + /* Amoi M636/A737 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), + }, + }, + { + /* Lenovo 3000 n100 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), + }, + }, + { + /* Acer Aspire 5710 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), + }, + }, + { + /* Gericom Bellagio */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), + }, + }, + { + /* IBM 2656 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "2656"), + }, + }, + { + /* Dell XPS M1530 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), + }, + }, + { + /* Compal HEL80I */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), + }, + }, + { + /* Dell Vostro 1510 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), + }, + }, + { + /* Acer Aspire 5536 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + }, + }, + { + /* Dell Vostro V13 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + }, + }, + { + /* Newer HP Pavilion dv4 models */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), + }, + }, + { + /* Asus X450LCP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), + }, + }, + { + /* Avatar AVIU-145A6 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), + DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), }, }, { } @@ -363,6 +628,22 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), }, }, + { + /* Fujitsu A544 laptop */ + /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), + }, + }, + { + /* Fujitsu AH544 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), + }, + }, { /* Fujitsu U574 laptop */ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ @@ -740,8 +1021,8 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_noloop_table)) i8042_noloop = true; - if (dmi_check_system(i8042_dmi_mux_table)) - i8042_nomux = false; + if (dmi_check_system(i8042_dmi_nomux_table)) + i8042_nomux = true; if (dmi_check_system(i8042_dmi_notimeout_table)) i8042_notimeout = true; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 9a97c2b10926..f5a98af3b325 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -39,7 +39,7 @@ static bool i8042_noaux; module_param_named(noaux, i8042_noaux, bool, 0); MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); -static bool i8042_nomux = true; +static bool i8042_nomux; module_param_named(nomux, i8042_nomux, bool, 0); MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index d0ef91fc87d1..b1ae77995968 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -70,11 +70,11 @@ * Documentation/input/input-programming.txt for more details. */ -static int abs_x[3] = {350, 3900, 5}; +static int abs_x[3] = {150, 4000, 5}; module_param_array(abs_x, int, NULL, 0); MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz"); -static int abs_y[3] = {320, 3750, 40}; +static int abs_y[3] = {200, 4000, 40}; module_param_array(abs_y, int, NULL, 0); MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz"); diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c index 97afee672d07..4418119cf707 100644 --- a/drivers/media/common/saa7146/saa7146_core.c +++ b/drivers/media/common/saa7146/saa7146_core.c @@ -364,6 +364,9 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent goto out; } + /* create a nice device name */ + sprintf(dev->name, "saa7146 (%d)", saa7146_num); + DEB_EE("pci:%p\n", pci); err = pci_enable_device(pci); @@ -438,9 +441,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent /* the rest + print status message */ - /* create a nice device name */ - sprintf(dev->name, "saa7146 (%d)", saa7146_num); - pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device); diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 13734b8c7917..4cb90317ff45 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1600,6 +1600,7 @@ static int dvb_register(struct cx23885_tsport *port) break; /* attach tuner */ + memset(&m88ts2022_config, 0, sizeof(m88ts2022_config)); m88ts2022_config.fe = fe0->dvb.frontend; m88ts2022_config.clock = 27000000; memset(&info, 0, sizeof(struct i2c_board_info)); @@ -1635,6 +1636,7 @@ static int dvb_register(struct cx23885_tsport *port) /* port c - terrestrial/cable */ case 2: /* attach frontend */ + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &fe0->dvb.frontend; si2168_config.ts_mode = SI2168_TS_SERIAL; @@ -1654,6 +1656,7 @@ static int dvb_register(struct cx23885_tsport *port) port->i2c_client_demod = client_demod; /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = fe0->dvb.frontend; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2157", I2C_NAME_SIZE); diff --git a/drivers/media/pci/tw68/Kconfig b/drivers/media/pci/tw68/Kconfig index 5425ba1e320d..95d5d5202048 100644 --- a/drivers/media/pci/tw68/Kconfig +++ b/drivers/media/pci/tw68/Kconfig @@ -1,7 +1,6 @@ config VIDEO_TW68 tristate "Techwell tw68x Video For Linux" depends on VIDEO_DEV && PCI && VIDEO_V4L2 - select I2C_ALGOBIT select VIDEOBUF2_DMA_SG ---help--- Support for Techwell tw68xx based frame grabber boards. diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c index a6fb48cf7aae..63f0b64057cb 100644 --- a/drivers/media/pci/tw68/tw68-core.c +++ b/drivers/media/pci/tw68/tw68-core.c @@ -306,7 +306,7 @@ static int tw68_initdev(struct pci_dev *pci_dev, /* get irq */ err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw68_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, dev); + IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index bee9074ebc13..3aac88f1d54a 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -166,7 +166,7 @@ config VIDEO_MEM2MEM_DEINTERLACE config VIDEO_SAMSUNG_S5P_G2D tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver" depends on VIDEO_DEV && VIDEO_V4L2 - depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV @@ -178,7 +178,7 @@ config VIDEO_SAMSUNG_S5P_G2D config VIDEO_SAMSUNG_S5P_JPEG tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver" depends on VIDEO_DEV && VIDEO_V4L2 - depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV @@ -189,7 +189,7 @@ config VIDEO_SAMSUNG_S5P_JPEG config VIDEO_SAMSUNG_S5P_MFC tristate "Samsung S5P MFC Video Codec" depends on VIDEO_DEV && VIDEO_V4L2 - depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on HAS_DMA select VIDEOBUF2_DMA_CONTIG default n diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index 77c951237744..b7b2e472240a 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig @@ -2,7 +2,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - depends on (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST) + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST depends on OF && COMMON_CLK help Say Y here to enable camera host interface devices for diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index b70fd996d794..aee92d908e49 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -832,6 +832,7 @@ err: return -ENXIO; } +#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) static int fimc_m2m_suspend(struct fimc_dev *fimc) { unsigned long flags; @@ -870,6 +871,7 @@ static int fimc_m2m_resume(struct fimc_dev *fimc) return 0; } +#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */ static const struct of_device_id fimc_of_match[]; diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index e525a7c8d885..6fcc7f072ace 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -893,7 +893,7 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result, unsigned long buffer, unsigned long size, struct s5p_jpeg_ctx *ctx) { - int c, components, notfound; + int c, components = 0, notfound; unsigned int height, width, word, subsampling = 0; long length; struct s5p_jpeg_buffer jpeg_buffer; @@ -2632,6 +2632,7 @@ static int s5p_jpeg_remove(struct platform_device *pdev) return 0; } +#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) static int s5p_jpeg_runtime_suspend(struct device *dev) { struct s5p_jpeg *jpeg = dev_get_drvdata(dev); @@ -2681,7 +2682,9 @@ static int s5p_jpeg_runtime_resume(struct device *dev) return 0; } +#endif /* CONFIG_PM_RUNTIME || CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM_SLEEP static int s5p_jpeg_suspend(struct device *dev) { if (pm_runtime_suspended(dev)) @@ -2697,6 +2700,7 @@ static int s5p_jpeg_resume(struct device *dev) return s5p_jpeg_runtime_resume(dev); } +#endif static const struct dev_pm_ops s5p_jpeg_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume) diff --git a/drivers/media/platform/s5p-tv/Kconfig b/drivers/media/platform/s5p-tv/Kconfig index a9d56f8936b4..beb180e71ba0 100644 --- a/drivers/media/platform/s5p-tv/Kconfig +++ b/drivers/media/platform/s5p-tv/Kconfig @@ -9,7 +9,7 @@ config VIDEO_SAMSUNG_S5P_TV bool "Samsung TV driver for S5P platform" depends on PM_RUNTIME - depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST + depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST default n ---help--- Say Y here to enable selecting the TV output devices for diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig index d71139a2ae00..c3090932f06d 100644 --- a/drivers/media/platform/vivid/Kconfig +++ b/drivers/media/platform/vivid/Kconfig @@ -1,8 +1,11 @@ config VIDEO_VIVID tristate "Virtual Video Test Driver" - depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 + depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FB select FONT_SUPPORT select FONT_8x16 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT select VIDEOBUF2_VMALLOC default n ---help--- diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c index 0c6fa53fa646..cbcd6250e7b2 100644 --- a/drivers/media/platform/vivid/vivid-tpg.c +++ b/drivers/media/platform/vivid/vivid-tpg.c @@ -136,7 +136,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w) tpg->black_line[plane] = vzalloc(max_w * pixelsz); if (!tpg->black_line[plane]) return -ENOMEM; - tpg->random_line[plane] = vzalloc(max_w * pixelsz); + tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz); if (!tpg->random_line[plane]) return -ENOMEM; } diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 6f28f6e02ea5..704397f3c106 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -1256,7 +1256,7 @@ static int fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name) fmerr("Unable to read firmware(%s) content\n", fw_name); return ret; } - fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size); + fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size); fw_data = (void *)fw_entry->data; fw_len = fw_entry->size; diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index e44c8aba6074..803a0e63d47e 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -1333,9 +1333,9 @@ static int xc5000_release(struct dvb_frontend *fe) if (priv) { cancel_delayed_work(&priv->timer_sleep); - hybrid_tuner_release_state(priv); if (priv->firmware) release_firmware(priv->firmware); + hybrid_tuner_release_state(priv); } mutex_unlock(&xc5000_list_mutex); diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 00758c83eec7..1896ab218b11 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -193,8 +193,8 @@ static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val, return af9035_wr_regs(d, reg, &val, 1); } -static int af9035_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr, - void *platform_data, struct i2c_adapter *adapter) +static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type, + u8 addr, void *platform_data, struct i2c_adapter *adapter) { int ret, num; struct state *state = d_to_priv(d); @@ -221,7 +221,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr, goto err; } - request_module(board_info.type); + request_module("%s", board_info.type); /* register I2C device */ client = i2c_new_device(adapter, &board_info); diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index d3c5f230e97a..ae917c042a52 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -630,8 +630,8 @@ error: return ret; } -static int anysee_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr, - void *platform_data) +static int anysee_add_i2c_dev(struct dvb_usb_device *d, const char *type, + u8 addr, void *platform_data) { int ret, num; struct anysee_state *state = d_to_priv(d); @@ -659,7 +659,7 @@ static int anysee_add_i2c_dev(struct dvb_usb_device *d, char *type, u8 addr, goto err; } - request_module(board_info.type); + request_module("%s", board_info.type); /* register I2C device */ client = i2c_new_device(adapter, &board_info); diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index b5e52fe7957a..901cf2b952d7 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -504,7 +504,7 @@ EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); int em28xx_audio_setup(struct em28xx *dev) { int vid1, vid2, feat, cfg; - u32 vid; + u32 vid = 0; u8 i2s_samplerates; if (dev->chip_id == CHIP_ID_EM2870 || diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 581f6dad4ca9..23f8f6afa2e0 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -712,8 +712,10 @@ static int em28xx_ir_init(struct em28xx *dev) em28xx_info("Registering input extension\n"); ir = kzalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; rc = rc_allocate_device(); - if (!ir || !rc) + if (!rc) goto error; /* record handles to ourself */ diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index 328b5ba47a0a..fd1fa412e094 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c @@ -932,7 +932,7 @@ static int hackrf_set_bandwidth(struct hackrf_dev *dev) dev->bandwidth->val = bandwidth; dev->bandwidth->cur.val = bandwidth; - dev_dbg(dev->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq); + dev_dbg(dev->dev, "bandwidth selected=%d\n", bandwidth); u16tmp = 0; u16tmp |= ((bandwidth >> 0) & 0xff) << 0; diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 68bc9615660e..9bfa041e3316 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -446,6 +446,7 @@ static int usbvision_v4l2_close(struct file *file) if (usbvision->remove_pending) { printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); + return 0; } mutex_unlock(&usbvision->v4l2_lock); @@ -1221,6 +1222,7 @@ static int usbvision_radio_close(struct file *file) if (usbvision->remove_pending) { printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); + return err_code; } mutex_unlock(&usbvision->v4l2_lock); diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 60a8e2c3631e..378ae02e593b 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -318,7 +318,6 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, stream->ctrl = probe; stream->cur_format = format; stream->cur_frame = frame; - stream->frame_size = fmt->fmt.pix.sizeimage; done: mutex_unlock(&stream->mutex); diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 9ace520bb079..df81b9c4faf1 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1143,7 +1143,7 @@ static int uvc_video_encode_data(struct uvc_streaming *stream, static void uvc_video_validate_buffer(const struct uvc_streaming *stream, struct uvc_buffer *buf) { - if (stream->frame_size != buf->bytesused && + if (stream->ctrl.dwMaxVideoFrameSize != buf->bytesused && !(stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED)) buf->error = 1; } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 6f676c29ec09..864ada740360 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -457,7 +457,6 @@ struct uvc_streaming { struct uvc_format *def_format; struct uvc_format *cur_format; struct uvc_frame *cur_frame; - size_t frame_size; /* Protect access to ctrl, cur_format, cur_frame and hardware video * probe control. diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index bf80f0f7dfb8..e02353e340dd 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c @@ -305,6 +305,15 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, /* Try to remap memory */ size = vma->vm_end - vma->vm_start; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* the "vm_pgoff" is just used in v4l2 to find the + * corresponding buffer data structure which is allocated + * earlier and it does not mean the offset from the physical + * buffer start address as usual. So set it to 0 to pass + * the sanity check in vm_iomap_memory(). + */ + vma->vm_pgoff = 0; + retval = vm_iomap_memory(vma, mem->dma_handle, size); if (retval) { dev_err(q->dev, "mmap: remap failed with error %d. ", diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c index 69506ebd4d07..c99e896604ee 100644 --- a/drivers/misc/cxl/fault.c +++ b/drivers/misc/cxl/fault.c @@ -21,60 +21,64 @@ #include "cxl.h" -static struct cxl_sste* find_free_sste(struct cxl_sste *primary_group, - bool sec_hash, - struct cxl_sste *secondary_group, - unsigned int *lru) +static bool sste_matches(struct cxl_sste *sste, struct copro_slb *slb) { - unsigned int i, entry; - struct cxl_sste *sste, *group = primary_group; - - for (i = 0; i < 2; i++) { - for (entry = 0; entry < 8; entry++) { - sste = group + entry; - if (!(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) - return sste; - } - if (!sec_hash) - break; - group = secondary_group; - } - /* Nothing free, select an entry to cast out */ - if (sec_hash && (*lru & 0x8)) - sste = secondary_group + (*lru & 0x7); - else - sste = primary_group + (*lru & 0x7); - *lru = (*lru + 1) & 0xf; - - return sste; + return ((sste->vsid_data == cpu_to_be64(slb->vsid)) && + (sste->esid_data == cpu_to_be64(slb->esid))); } -static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb) +/* + * This finds a free SSTE for the given SLB, or returns NULL if it's already in + * the segment table. + */ +static struct cxl_sste* find_free_sste(struct cxl_context *ctx, + struct copro_slb *slb) { - /* mask is the group index, we search primary and secondary here. */ - unsigned int mask = (ctx->sst_size >> 7)-1; /* SSTP0[SegTableSize] */ - bool sec_hash = 1; - struct cxl_sste *sste; + struct cxl_sste *primary, *sste, *ret = NULL; + unsigned int mask = (ctx->sst_size >> 7) - 1; /* SSTP0[SegTableSize] */ + unsigned int entry; unsigned int hash; - unsigned long flags; - - - sec_hash = !!(cxl_p1n_read(ctx->afu, CXL_PSL_SR_An) & CXL_PSL_SR_An_SC); if (slb->vsid & SLB_VSID_B_1T) hash = (slb->esid >> SID_SHIFT_1T) & mask; else /* 256M */ hash = (slb->esid >> SID_SHIFT) & mask; + primary = ctx->sstp + (hash << 3); + + for (entry = 0, sste = primary; entry < 8; entry++, sste++) { + if (!ret && !(be64_to_cpu(sste->esid_data) & SLB_ESID_V)) + ret = sste; + if (sste_matches(sste, slb)) + return NULL; + } + if (ret) + return ret; + + /* Nothing free, select an entry to cast out */ + ret = primary + ctx->sst_lru; + ctx->sst_lru = (ctx->sst_lru + 1) & 0x7; + + return ret; +} + +static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb) +{ + /* mask is the group index, we search primary and secondary here. */ + struct cxl_sste *sste; + unsigned long flags; + spin_lock_irqsave(&ctx->sste_lock, flags); - sste = find_free_sste(ctx->sstp + (hash << 3), sec_hash, - ctx->sstp + ((~hash & mask) << 3), &ctx->sst_lru); + sste = find_free_sste(ctx, slb); + if (!sste) + goto out_unlock; pr_devel("CXL Populating SST[%li]: %#llx %#llx\n", sste - ctx->sstp, slb->vsid, slb->esid); sste->vsid_data = cpu_to_be64(slb->vsid); sste->esid_data = cpu_to_be64(slb->esid); +out_unlock: spin_unlock_irqrestore(&ctx->sste_lock, flags); } diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 623286a77114..d47532e8f4f1 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -417,7 +417,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) ctx->elem->haurp = 0; /* disable */ ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1)); - sr = CXL_PSL_SR_An_SC; + sr = 0; if (ctx->master) sr |= CXL_PSL_SR_An_MP; if (mfspr(SPRN_LPCR) & LPCR_TC) @@ -508,7 +508,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr) u64 sr; int rc; - sr = CXL_PSL_SR_An_SC; + sr = 0; set_endian(sr); if (ctx->master) sr |= CXL_PSL_SR_An_MP; diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a7543ba3e190..3096f3ded3ad 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2590,6 +2590,8 @@ static void cfi_intelext_resume(struct mtd_info *mtd) /* Go to known state. Chip may have been power cycled */ if (chip->state == FL_PM_SUSPENDED) { + /* Refresh LH28F640BF Partition Config. Register */ + fixup_LH28F640BF(mtd); map_write(map, CMD(0xFF), cfi->chips[i].start); chip->oldstate = chip->state = FL_READY; wake_up(&chip->wq); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index dcda6287228d..ed827cf894e4 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -193,10 +193,10 @@ static int m25p_probe(struct spi_device *spi) { struct mtd_part_parser_data ppdata; struct flash_platform_data *data; - const struct spi_device_id *id = NULL; struct m25p *flash; struct spi_nor *nor; enum read_mode mode = SPI_NOR_NORMAL; + char *flash_name = NULL; int ret; data = dev_get_platdata(&spi->dev); @@ -236,13 +236,11 @@ static int m25p_probe(struct spi_device *spi) * If that's the case, respect "type" and ignore a "name". */ if (data && data->type) - id = spi_nor_match_id(data->type); + flash_name = data->type; + else + flash_name = spi->modalias; - /* If we didn't get name from platform, simply use "modalias". */ - if (!id) - id = spi_get_device_id(spi); - - ret = spi_nor_scan(nor, id, mode); + ret = spi_nor_scan(nor, flash_name, mode); if (ret) return ret; @@ -263,12 +261,62 @@ static int m25p_remove(struct spi_device *spi) } +/* + * XXX This needs to be kept in sync with spi_nor_ids. We can't share + * it with spi-nor, because if this is built as a module then modpost + * won't be able to read it and add appropriate aliases. + */ +static const struct spi_device_id m25p_ids[] = { + {"at25fs010"}, {"at25fs040"}, {"at25df041a"}, {"at25df321a"}, + {"at25df641"}, {"at26f004"}, {"at26df081a"}, {"at26df161a"}, + {"at26df321"}, {"at45db081d"}, + {"en25f32"}, {"en25p32"}, {"en25q32b"}, {"en25p64"}, + {"en25q64"}, {"en25qh128"}, {"en25qh256"}, + {"f25l32pa"}, + {"mr25h256"}, {"mr25h10"}, + {"gd25q32"}, {"gd25q64"}, + {"160s33b"}, {"320s33b"}, {"640s33b"}, + {"mx25l2005a"}, {"mx25l4005a"}, {"mx25l8005"}, {"mx25l1606e"}, + {"mx25l3205d"}, {"mx25l3255e"}, {"mx25l6405d"}, {"mx25l12805d"}, + {"mx25l12855e"},{"mx25l25635e"},{"mx25l25655e"},{"mx66l51235l"}, + {"mx66l1g55g"}, + {"n25q064"}, {"n25q128a11"}, {"n25q128a13"}, {"n25q256a"}, + {"n25q512a"}, {"n25q512ax3"}, {"n25q00"}, + {"pm25lv512"}, {"pm25lv010"}, {"pm25lq032"}, + {"s25sl032p"}, {"s25sl064p"}, {"s25fl256s0"}, {"s25fl256s1"}, + {"s25fl512s"}, {"s70fl01gs"}, {"s25sl12800"}, {"s25sl12801"}, + {"s25fl129p0"}, {"s25fl129p1"}, {"s25sl004a"}, {"s25sl008a"}, + {"s25sl016a"}, {"s25sl032a"}, {"s25sl064a"}, {"s25fl008k"}, + {"s25fl016k"}, {"s25fl064k"}, + {"sst25vf040b"},{"sst25vf080b"},{"sst25vf016b"},{"sst25vf032b"}, + {"sst25vf064c"},{"sst25wf512"}, {"sst25wf010"}, {"sst25wf020"}, + {"sst25wf040"}, + {"m25p05"}, {"m25p10"}, {"m25p20"}, {"m25p40"}, + {"m25p80"}, {"m25p16"}, {"m25p32"}, {"m25p64"}, + {"m25p128"}, {"n25q032"}, + {"m25p05-nonjedec"}, {"m25p10-nonjedec"}, {"m25p20-nonjedec"}, + {"m25p40-nonjedec"}, {"m25p80-nonjedec"}, {"m25p16-nonjedec"}, + {"m25p32-nonjedec"}, {"m25p64-nonjedec"}, {"m25p128-nonjedec"}, + {"m45pe10"}, {"m45pe80"}, {"m45pe16"}, + {"m25pe20"}, {"m25pe80"}, {"m25pe16"}, + {"m25px16"}, {"m25px32"}, {"m25px32-s0"}, {"m25px32-s1"}, + {"m25px64"}, + {"w25x10"}, {"w25x20"}, {"w25x40"}, {"w25x80"}, + {"w25x16"}, {"w25x32"}, {"w25q32"}, {"w25q32dw"}, + {"w25x64"}, {"w25q64"}, {"w25q128"}, {"w25q80"}, + {"w25q80bl"}, {"w25q128"}, {"w25q256"}, {"cat25c11"}, + {"cat25c03"}, {"cat25c09"}, {"cat25c17"}, {"cat25128"}, + { }, +}; +MODULE_DEVICE_TABLE(spi, m25p_ids); + + static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", .owner = THIS_MODULE, }, - .id_table = spi_nor_ids, + .id_table = m25p_ids, .probe = m25p_probe, .remove = m25p_remove, diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c index b4f61c7fc161..058531044ceb 100644 --- a/drivers/mtd/nand/omap_elm.c +++ b/drivers/mtd/nand/omap_elm.c @@ -115,7 +115,7 @@ int elm_config(struct device *dev, enum bch_ecc bch_type, if (!info) { dev_err(dev, "Unable to configure elm - device not probed?\n"); - return -ENODEV; + return -EPROBE_DEFER; } /* ELM cannot detect ECC errors for chunks > 1KB */ if (ecc_step_size > ((ELM_ECC_SIZE + 1) / 2)) { diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 8d659a2888d5..d5269a26c839 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -881,7 +881,6 @@ static int fsl_qspi_probe(struct platform_device *pdev) /* iterate the subnodes. */ for_each_available_child_of_node(dev->of_node, np) { - const struct spi_device_id *id; char modalias[40]; /* skip the holes */ @@ -909,10 +908,6 @@ static int fsl_qspi_probe(struct platform_device *pdev) if (of_modalias_node(np, modalias, sizeof(modalias)) < 0) goto map_failed; - id = spi_nor_match_id(modalias); - if (!id) - goto map_failed; - ret = of_property_read_u32(np, "spi-max-frequency", &q->clk_rate); if (ret < 0) @@ -921,7 +916,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) /* set the chip address for READID */ fsl_qspi_set_base_addr(q, nor); - ret = spi_nor_scan(nor, id, SPI_NOR_QUAD); + ret = spi_nor_scan(nor, modalias, SPI_NOR_QUAD); if (ret) goto map_failed; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index ae16aa2f6885..c51ee52386a7 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -28,6 +28,8 @@ #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) +static const struct spi_device_id *spi_nor_match_id(const char *name); + /* * Read the status register, returning its value in the location * Return the status register value. @@ -473,7 +475,7 @@ struct flash_info { * more nor chips. This current list focusses on newer chips, which * have been converging on command sets which including JEDEC ID. */ -const struct spi_device_id spi_nor_ids[] = { +static const struct spi_device_id spi_nor_ids[] = { /* Atmel -- some are (confusingly) marketed as "DataFlash" */ { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, @@ -637,7 +639,6 @@ const struct spi_device_id spi_nor_ids[] = { { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { }, }; -EXPORT_SYMBOL_GPL(spi_nor_ids); static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) { @@ -911,9 +912,9 @@ static int spi_nor_check(struct spi_nor *nor) return 0; } -int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, - enum read_mode mode) +int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) { + const struct spi_device_id *id = NULL; struct flash_info *info; struct device *dev = nor->dev; struct mtd_info *mtd = nor->mtd; @@ -925,6 +926,10 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, if (ret) return ret; + id = spi_nor_match_id(name); + if (!id) + return -ENOENT; + info = (void *)id->driver_data; if (info->jedec_id) { @@ -1113,7 +1118,7 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, } EXPORT_SYMBOL_GPL(spi_nor_scan); -const struct spi_device_id *spi_nor_match_id(char *name) +static const struct spi_device_id *spi_nor_match_id(const char *name) { const struct spi_device_id *id = spi_nor_ids; @@ -1124,7 +1129,6 @@ const struct spi_device_id *spi_nor_match_id(char *name) } return NULL; } -EXPORT_SYMBOL_GPL(spi_nor_match_id); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Huang Shijie "); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4706386b7d34..f9009be3f307 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -135,6 +135,7 @@ config MACVLAN config MACVTAP tristate "MAC-VLAN based tap driver" depends on MACVLAN + depends on INET help This adds a specialized tap character device driver that is based on the MAC-VLAN network interface, called macvtap. A macvtap device @@ -200,6 +201,7 @@ config RIONET_RX_SIZE config TUN tristate "Universal TUN/TAP device driver support" + depends on INET select CRC32 ---help--- TUN/TAP provides packet reception and transmission for user space diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index 1020a7af67cf..78d8e876f3aa 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c @@ -395,7 +395,7 @@ static int mv88e6171_get_sset_count(struct dsa_switch *ds) } struct dsa_switch_driver mv88e6171_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_DSA, + .tag_protocol = DSA_TAG_PROTO_EDSA, .priv_size = sizeof(struct mv88e6xxx_priv_state), .probe = mv88e6171_probe, .setup = mv88e6171_setup, diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 29554992215a..2349ea970255 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1465,7 +1465,7 @@ static int xgbe_set_features(struct net_device *netdev, { struct xgbe_prv_data *pdata = netdev_priv(netdev); struct xgbe_hw_if *hw_if = &pdata->hw_if; - unsigned int rxcsum, rxvlan, rxvlan_filter; + netdev_features_t rxcsum, rxvlan, rxvlan_filter; rxcsum = pdata->netdev_features & NETIF_F_RXCSUM; rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX; @@ -1598,7 +1598,8 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) struct skb_shared_hwtstamps *hwtstamps; unsigned int incomplete, error, context_next, context; unsigned int len, put_len, max_len; - int received = 0; + unsigned int received = 0; + int packet_count = 0; DBGPR("-->xgbe_rx_poll: budget=%d\n", budget); @@ -1608,7 +1609,7 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget) rdata = XGBE_GET_DESC_DATA(ring, ring->cur); packet = &ring->packet_data; - while (received < budget) { + while (packet_count < budget) { DBGPR(" cur = %d\n", ring->cur); /* First time in loop see if we need to restore state */ @@ -1662,7 +1663,7 @@ read_again: if (packet->errors) DBGPR("Error in received packet\n"); dev_kfree_skb(skb); - continue; + goto next_packet; } if (!context) { @@ -1677,7 +1678,7 @@ read_again: } dev_kfree_skb(skb); - continue; + goto next_packet; } memcpy(skb_tail_pointer(skb), rdata->skb->data, put_len); @@ -1694,7 +1695,7 @@ read_again: /* Stray Context Descriptor? */ if (!skb) - continue; + goto next_packet; /* Be sure we don't exceed the configured MTU */ max_len = netdev->mtu + ETH_HLEN; @@ -1705,7 +1706,7 @@ read_again: if (skb->len > max_len) { DBGPR("packet length exceeds configured MTU\n"); dev_kfree_skb(skb); - continue; + goto next_packet; } #ifdef XGMAC_ENABLE_RX_PKT_DUMP @@ -1739,6 +1740,9 @@ read_again: netdev->last_rx = jiffies; napi_gro_receive(&pdata->napi, skb); + +next_packet: + packet_count++; } /* Check if we need to save state before leaving */ @@ -1752,9 +1756,9 @@ read_again: rdata->state.error = error; } - DBGPR("<--xgbe_rx_poll: received = %d\n", received); + DBGPR("<--xgbe_rx_poll: packet_count = %d\n", packet_count); - return received; + return packet_count; } static int xgbe_poll(struct napi_struct *napi, int budget) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c index e6d24c210198..c22f32622fa9 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c @@ -124,20 +124,18 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *p) { struct net_device *ndev = p->ndev; u32 data; - int i; + int i = 0; xgene_enet_wr_diag_csr(p, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0); - for (i = 0; i < 10 && data != ~0U ; i++) { + do { usleep_range(100, 110); data = xgene_enet_rd_diag_csr(p, ENET_BLOCK_MEM_RDY_ADDR); - } + if (data == ~0U) + return 0; + } while (++i < 10); - if (data != ~0U) { - netdev_err(ndev, "Failed to release memory from shutdown\n"); - return -ENODEV; - } - - return 0; + netdev_err(ndev, "Failed to release memory from shutdown\n"); + return -ENODEV; } static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *p) diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index 9ae36979bdee..3a6778a667f4 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1397,6 +1397,9 @@ static void bcm_sysport_netif_start(struct net_device *dev) /* Enable NAPI */ napi_enable(&priv->napi); + /* Enable RX interrupt and TX ring full interrupt */ + intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL); + phy_start(priv->phydev); /* Enable TX interrupts for the 32 TXQs */ @@ -1499,9 +1502,6 @@ static int bcm_sysport_open(struct net_device *dev) if (ret) goto out_free_rx_ring; - /* Enable RX interrupt and TX ring full interrupt */ - intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL); - /* Turn on TDMA */ ret = tdma_enable_set(priv, 1); if (ret) @@ -1858,6 +1858,8 @@ static int bcm_sysport_resume(struct device *d) if (!netif_running(dev)) return 0; + umac_reset(priv); + /* We may have been suspended and never received a WOL event that * would turn off MPD detection, take care of that now */ @@ -1885,9 +1887,6 @@ static int bcm_sysport_resume(struct device *d) netif_device_attach(dev); - /* Enable RX interrupt and TX ring full interrupt */ - intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL); - /* RX pipe enable */ topctrl_writel(priv, 0, RX_FLUSH_CNTL); diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 23f23c97c2ad..f05fab65d78a 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -382,10 +382,8 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, if (l5_cid >= MAX_CM_SK_TBL_SZ) break; - rcu_read_lock(); if (!rcu_access_pointer(cp->ulp_ops[CNIC_ULP_L4])) { rc = -ENODEV; - rcu_read_unlock(); break; } csk = &cp->csk_tbl[l5_cid]; @@ -414,7 +412,6 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type, } } csk_put(csk); - rcu_read_unlock(); rc = 0; } } @@ -615,7 +612,7 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type) cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); mutex_lock(&cnic_lock); - if (rcu_dereference(cp->ulp_ops[ulp_type])) { + if (rcu_access_pointer(cp->ulp_ops[ulp_type])) { RCU_INIT_POINTER(cp->ulp_ops[ulp_type], NULL); cnic_put(dev); } else { diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c index 8edf0f5bd679..6fe300e316c3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c @@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev) dcb->dcb_version = FW_PORT_DCB_VER_AUTO; } +static void cxgb4_dcb_cleanup_apps(struct net_device *dev) +{ + struct port_info *pi = netdev2pinfo(dev); + struct adapter *adap = pi->adapter; + struct port_dcb_info *dcb = &pi->dcb; + struct dcb_app app; + int i, err; + + /* zero priority implies remove */ + app.priority = 0; + + for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) { + /* Check if app list is exhausted */ + if (!dcb->app_priority[i].protocolid) + break; + + app.protocol = dcb->app_priority[i].protocolid; + + if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) { + app.selector = dcb->app_priority[i].sel_field + 1; + err = dcb_ieee_setapp(dev, &app); + } else { + app.selector = !!(dcb->app_priority[i].sel_field); + err = dcb_setapp(dev, &app); + } + + if (err) { + dev_err(adap->pdev_dev, + "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n", + dcb_ver_array[dcb->dcb_version], app.selector, + app.protocol, -err); + break; + } + } +} + /* Finite State machine for Data Center Bridging. */ void cxgb4_dcb_state_fsm(struct net_device *dev, @@ -80,7 +116,6 @@ void cxgb4_dcb_state_fsm(struct net_device *dev, /* we're going to use Host DCB */ dcb->state = CXGB4_DCB_STATE_HOST; dcb->supported = CXGB4_DCBX_HOST_SUPPORT; - dcb->enabled = 1; break; } @@ -145,6 +180,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev, * state. We need to reset back to a ground state * of incomplete. */ + cxgb4_dcb_cleanup_apps(dev); cxgb4_dcb_state_init(dev); dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; dcb->supported = CXGB4_DCBX_FW_SUPPORT; @@ -349,6 +385,12 @@ static u8 cxgb4_setstate(struct net_device *dev, u8 enabled) { struct port_info *pi = netdev2pinfo(dev); + /* If DCBx is host-managed, dcb is enabled by outside lldp agents */ + if (pi->dcb.state == CXGB4_DCB_STATE_HOST) { + pi->dcb.enabled = enabled; + return 0; + } + /* Firmware doesn't provide any mechanism to control the DCB state. */ if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED)) @@ -833,11 +875,16 @@ static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id, /* Return whether IEEE Data Center Bridging has been negotiated. */ -static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev) +static inline int +cxgb4_ieee_negotiation_complete(struct net_device *dev, + enum cxgb4_dcb_fw_msgs dcb_subtype) { struct port_info *pi = netdev2pinfo(dev); struct port_dcb_info *dcb = &pi->dcb; + if (dcb_subtype && !(dcb->msgs & dcb_subtype)) + return 0; + return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED && (dcb->supported & DCB_CAP_DCBX_VER_IEEE)); } @@ -850,7 +897,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app) { int prio; - if (!cxgb4_ieee_negotiation_complete(dev)) + if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID)) return -EINVAL; if (!(app->selector && app->protocol)) return -EINVAL; @@ -872,7 +919,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app) { int ret; - if (!cxgb4_ieee_negotiation_complete(dev)) + if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID)) return -EINVAL; if (!(app->selector && app->protocol)) return -EINVAL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 3f60070f2519..8520d5529df8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -694,7 +694,11 @@ int cxgb4_dcb_enabled(const struct net_device *dev) #ifdef CONFIG_CHELSIO_T4_DCB struct port_info *pi = netdev_priv(dev); - return pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED; + if (!pi->dcb.enabled) + return 0; + + return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) || + (pi->dcb.state == CXGB4_DCB_STATE_HOST)); #else return 0; #endif @@ -6610,6 +6614,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&adapter->stats_lock); spin_lock_init(&adapter->tid_release_lock); + spin_lock_init(&adapter->win0_lock); INIT_WORK(&adapter->tid_release_task, process_tid_release_list); INIT_WORK(&adapter->db_full_task, process_db_full); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index bfa398d91826..0b42bddaf284 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2929,14 +2929,14 @@ static const struct pci_device_id cxgb4vf_pci_tbl[] = { CH_DEVICE(0x480d), /* T480-cr */ CH_DEVICE(0x480e), /* T440-lp-cr */ CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), - CH_DEVICE(0x4880), + CH_DEVICE(0x4881), + CH_DEVICE(0x4882), + CH_DEVICE(0x4883), + CH_DEVICE(0x4884), + CH_DEVICE(0x4885), + CH_DEVICE(0x4886), + CH_DEVICE(0x4887), + CH_DEVICE(0x4888), CH_DEVICE(0x5801), /* T520-cr */ CH_DEVICE(0x5802), /* T522-cr */ CH_DEVICE(0x5803), /* T540-cr */ diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c index 69dfd3c9e529..0be6850be8a2 100644 --- a/drivers/net/ethernet/cisco/enic/enic_clsf.c +++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c @@ -86,7 +86,7 @@ void enic_rfs_flw_tbl_free(struct enic *enic) int i; enic_rfs_timer_stop(enic); - spin_lock(&enic->rfs_h.lock); + spin_lock_bh(&enic->rfs_h.lock); enic->rfs_h.free = 0; for (i = 0; i < (1 << ENIC_RFS_FLW_BITSHIFT); i++) { struct hlist_head *hhead; @@ -100,7 +100,7 @@ void enic_rfs_flw_tbl_free(struct enic *enic) kfree(n); } } - spin_unlock(&enic->rfs_h.lock); + spin_unlock_bh(&enic->rfs_h.lock); } struct enic_rfs_fltr_node *htbl_fltr_search(struct enic *enic, u16 fltr_id) @@ -128,7 +128,7 @@ void enic_flow_may_expire(unsigned long data) bool res; int j; - spin_lock(&enic->rfs_h.lock); + spin_lock_bh(&enic->rfs_h.lock); for (j = 0; j < ENIC_CLSF_EXPIRE_COUNT; j++) { struct hlist_head *hhead; struct hlist_node *tmp; @@ -148,7 +148,7 @@ void enic_flow_may_expire(unsigned long data) } } } - spin_unlock(&enic->rfs_h.lock); + spin_unlock_bh(&enic->rfs_h.lock); mod_timer(&enic->rfs_h.rfs_may_expire, jiffies + HZ/4); } @@ -183,7 +183,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, return -EPROTONOSUPPORT; tbl_idx = skb_get_hash_raw(skb) & ENIC_RFS_FLW_MASK; - spin_lock(&enic->rfs_h.lock); + spin_lock_bh(&enic->rfs_h.lock); n = htbl_key_search(&enic->rfs_h.ht_head[tbl_idx], &keys); if (n) { /* entry already present */ @@ -277,7 +277,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, } ret_unlock: - spin_unlock(&enic->rfs_h.lock); + spin_unlock_bh(&enic->rfs_h.lock); return res; } diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 929bfe70080a..180e53fa628f 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1674,13 +1674,13 @@ static int enic_stop(struct net_device *netdev) enic_dev_disable(enic); - local_bh_disable(); for (i = 0; i < enic->rq_count; i++) { napi_disable(&enic->napi[i]); + local_bh_disable(); while (!enic_poll_lock_napi(&enic->rq[i])) mdelay(1); + local_bh_enable(); } - local_bh_enable(); netif_carrier_off(netdev); netif_tx_disable(netdev); diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 81b96cf87574..50a851db2852 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1581,7 +1581,8 @@ fec_enet_interrupt(int irq, void *dev_id) complete(&fep->mdio_done); } - fec_ptp_check_pps_event(fep); + if (fep->ptp_clock) + fec_ptp_check_pps_event(fep); return ret; } diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c index 3d4e08be1709..b34214e2df5f 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -341,6 +341,9 @@ static void restart(struct net_device *dev) FC(fecp, x_cntrl, FEC_TCNTRL_FDEN); /* FD disable */ } + /* Restore multicast and promiscuous settings */ + set_multicast_list(dev); + /* * Enable interrupts we wish to service. */ diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c index f30411f0701f..7a184e8816a4 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c +++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c @@ -355,6 +355,9 @@ static void restart(struct net_device *dev) if (fep->phydev->duplex) S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE); + /* Restore multicast and promiscuous settings */ + set_multicast_list(dev); + S32(sccp, scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 5f6aded512f5..24f3986cfae2 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1075,7 +1075,10 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETIF_F_HW_CSUM | NETIF_F_SG); - netdev->priv_flags |= IFF_UNICAST_FLT; + /* Do not set IFF_UNICAST_FLT for VMWare's 82545EM */ + if (hw->device_id != E1000_DEV_ID_82545EM_COPPER || + hw->subsystem_vendor_id != PCI_VENDOR_ID_VMWARE) + netdev->priv_flags |= IFF_UNICAST_FLT; adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index ed5f1c15fb0f..c3a7f4a4b775 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6151,7 +6151,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) I40E_GL_MDET_TX_PF_NUM_SHIFT; u8 vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >> I40E_GL_MDET_TX_VF_NUM_SHIFT; - u8 event = (reg & I40E_GL_MDET_TX_EVENT_SHIFT) >> + u8 event = (reg & I40E_GL_MDET_TX_EVENT_MASK) >> I40E_GL_MDET_TX_EVENT_SHIFT; u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >> I40E_GL_MDET_TX_QUEUE_SHIFT; @@ -6165,7 +6165,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) if (reg & I40E_GL_MDET_RX_VALID_MASK) { u8 func = (reg & I40E_GL_MDET_RX_FUNCTION_MASK) >> I40E_GL_MDET_RX_FUNCTION_SHIFT; - u8 event = (reg & I40E_GL_MDET_RX_EVENT_SHIFT) >> + u8 event = (reg & I40E_GL_MDET_RX_EVENT_MASK) >> I40E_GL_MDET_RX_EVENT_SHIFT; u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >> I40E_GL_MDET_RX_QUEUE_SHIFT; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index a21b14495ebd..a2d72a87cbde 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6537,6 +6537,9 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer, if (unlikely(page_to_nid(page) != numa_node_id())) return false; + if (unlikely(page->pfmemalloc)) + return false; + #if (PAGE_SIZE < 8192) /* if we are only owner of page we can reuse it */ if (unlikely(page_count(page) != 1)) @@ -6603,7 +6606,8 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring, memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long))); /* we can reuse buffer as-is, just make sure it is local */ - if (likely(page_to_nid(page) == numa_node_id())) + if (likely((page_to_nid(page) == numa_node_id()) && + !page->pfmemalloc)) return true; /* this page cannot be reused so discard it */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 3ce4a258f945..0ae038b9af90 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -342,12 +342,16 @@ static int ixgbe_set_settings(struct net_device *netdev, if (old == advertised) return err; /* this sets the link speed and restarts auto-neg */ + while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) + usleep_range(1000, 2000); + hw->mac.autotry_restart = true; err = hw->mac.ops.setup_link(hw, advertised, true); if (err) { e_info(probe, "setup link failed with code %d\n", err); hw->mac.ops.setup_link(hw, old, true); } + clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); } else { /* in this case we currently only support 10Gb/FULL */ u32 speed = ethtool_cmd_speed(ecmd); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index fec5212d4337..d2df4e3d1032 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -4321,8 +4321,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) IXGBE_CB(skb)->page_released = false; } dev_kfree_skb(skb); + rx_buffer->skb = NULL; } - rx_buffer->skb = NULL; if (rx_buffer->dma) dma_unmap_page(dev, rx_buffer->dma, ixgbe_rx_pg_size(rx_ring), diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 34c137878545..454d9fea640e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -836,8 +836,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) * whether LSO is used */ tx_desc->ctrl.srcrb_flags = priv->ctrl_flags; if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { - tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | - MLX4_WQE_CTRL_TCP_UDP_CSUM); + if (!skb->encapsulation) + tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | + MLX4_WQE_CTRL_TCP_UDP_CSUM); + else + tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM); ring->tx_csum++; } diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index a49c9d11d8a5..49290a405903 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -1026,6 +1026,7 @@ static void mlx4_free_eq(struct mlx4_dev *dev, pr_cont("\n"); } } + synchronize_irq(eq->irq); mlx4_mtt_cleanup(dev, &eq->mtt); for (i = 0; i < npages; ++i) diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index ca0f98c95105..872843179f44 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -955,6 +955,10 @@ static void mlx4_err_rule(struct mlx4_dev *dev, char *str, cur->ib.dst_gid_msk); break; + case MLX4_NET_TRANS_RULE_ID_VXLAN: + len += snprintf(buf + len, BUF_SIZE - len, + "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); + break; case MLX4_NET_TRANS_RULE_ID_IPV6: break; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index ed53291468f3..a278238a2db6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -420,6 +420,7 @@ int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq) if (err) mlx5_core_warn(dev, "failed to destroy a previously created eq: eqn %d\n", eq->eqn); + synchronize_irq(table->msix_arr[eq->irqn].vector); mlx5_buf_free(dev, &eq->buf); return err; diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index ee84a90e371c..aaf2987512b5 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -343,8 +343,6 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) unsigned short dma_flags; int i = 0; - EFX_BUG_ON_PARANOID(tx_queue->write_count > tx_queue->insert_count); - if (skb_shinfo(skb)->gso_size) return efx_enqueue_skb_tso(tx_queue, skb); @@ -1258,8 +1256,6 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, /* Find the packet protocol and sanity-check it */ state.protocol = efx_tso_check_protocol(skb); - EFX_BUG_ON_PARANOID(tx_queue->write_count > tx_queue->insert_count); - rc = tso_start(&state, efx, skb); if (rc) goto mem_err; diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 5e94d00b96b3..2c62208077fe 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -81,6 +81,7 @@ static const char version[] = #include #include #include +#include #include #include @@ -2188,6 +2189,41 @@ static const struct of_device_id smc91x_match[] = { {}, }; MODULE_DEVICE_TABLE(of, smc91x_match); + +/** + * of_try_set_control_gpio - configure a gpio if it exists + */ +static int try_toggle_control_gpio(struct device *dev, + struct gpio_desc **desc, + const char *name, int index, + int value, unsigned int nsdelay) +{ + struct gpio_desc *gpio = *desc; + int res; + + gpio = devm_gpiod_get_index(dev, name, index); + if (IS_ERR(gpio)) { + if (PTR_ERR(gpio) == -ENOENT) { + *desc = NULL; + return 0; + } + + return PTR_ERR(gpio); + } + res = gpiod_direction_output(gpio, !value); + if (res) { + dev_err(dev, "unable to toggle gpio %s: %i\n", name, res); + devm_gpiod_put(dev, gpio); + gpio = NULL; + return res; + } + if (nsdelay) + usleep_range(nsdelay, 2 * nsdelay); + gpiod_set_value_cansleep(gpio, value); + *desc = gpio; + + return 0; +} #endif /* @@ -2237,6 +2273,28 @@ static int smc_drv_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; u32 val; + /* Optional pwrdwn GPIO configured? */ + ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, + "power", 0, 0, 100); + if (ret) + return ret; + + /* + * Optional reset GPIO configured? Minimum 100 ns reset needed + * according to LAN91C96 datasheet page 14. + */ + ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, + "reset", 0, 0, 100); + if (ret) + return ret; + + /* + * Need to wait for optional EEPROM to load, max 750 us according + * to LAN91C96 datasheet page 55. + */ + if (lp->reset_gpio) + usleep_range(750, 1000); + /* Combination of IO widths supported, default to 16-bit */ if (!of_property_read_u32(np, "reg-io-width", &val)) { if (val & 1) diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h index 47dce918eb0f..2a38dacbbd27 100644 --- a/drivers/net/ethernet/smsc/smc91x.h +++ b/drivers/net/ethernet/smsc/smc91x.h @@ -298,6 +298,9 @@ struct smc_local { struct sk_buff *pending_tx_skb; struct tasklet_struct tx_task; + struct gpio_desc *power_gpio; + struct gpio_desc *reset_gpio; + /* version/revision of the SMC91x chip */ int version; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 655a23bbc451..e17a970eaf2b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -33,6 +33,7 @@ static struct stmmac_dma_cfg dma_cfg; static void stmmac_default_data(void) { memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data)); + plat_dat.bus_id = 1; plat_dat.phy_addr = 0; plat_dat.interface = PHY_INTERFACE_MODE_GMII; @@ -47,6 +48,12 @@ static void stmmac_default_data(void) dma_cfg.pbl = 32; dma_cfg.burst_len = DMA_AXI_BLEN_256; plat_dat.dma_cfg = &dma_cfg; + + /* Set default value for multicast hash bins */ + plat_dat.multicast_filter_bins = HASH_TABLE_SIZE; + + /* Set default value for unicast filter entries */ + plat_dat.unicast_filter_entries = 1; } /** diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 952e1e4764b7..d8794488f80a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -591,8 +591,8 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) if (enable) { unsigned long timeout = jiffies + HZ; - /* Disable Learn for all ports */ - for (i = 0; i < priv->data.slaves; i++) { + /* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */ + for (i = 0; i <= priv->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 1); cpsw_ale_control_set(ale, i, @@ -616,11 +616,11 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); dev_dbg(&ndev->dev, "promiscuity enabled\n"); } else { - /* Flood All Unicast Packets to Host port */ + /* Don't Flood All Unicast Packets to Host port */ cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); - /* Enable Learn for all ports */ - for (i = 0; i < priv->data.slaves; i++) { + /* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */ + for (i = 0; i <= priv->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 0); cpsw_ale_control_set(ale, i, @@ -638,12 +638,16 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ cpsw_set_promiscious(ndev, true); + cpsw_ale_set_allmulti(priv->ale, IFF_ALLMULTI); return; } else { /* Disable promiscuous mode */ cpsw_set_promiscious(ndev, false); } + /* Restore allmulti on vlans if necessary */ + cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); + /* Clear all mcast from ALE */ cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); @@ -1149,6 +1153,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) const int port = priv->host_port; u32 reg; int i; + int unreg_mcast_mask; reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : CPSW2_PORT_VLAN; @@ -1158,9 +1163,14 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) for (i = 0; i < priv->data.slaves; i++) slave_write(priv->slaves + i, vlan, reg); + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; + cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port, ALE_ALL_PORTS << port, ALE_ALL_PORTS << port, - (ALE_PORT_1 | ALE_PORT_2) << port); + unreg_mcast_mask << port); } static void cpsw_init_host_port(struct cpsw_priv *priv) @@ -1620,11 +1630,17 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, unsigned short vid) { int ret; + int unreg_mcast_mask; + + if (priv->ndev->flags & IFF_ALLMULTI) + unreg_mcast_mask = ALE_ALL_PORTS; + else + unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; ret = cpsw_ale_add_vlan(priv->ale, vid, ALE_ALL_PORTS << priv->host_port, 0, ALE_ALL_PORTS << priv->host_port, - (ALE_PORT_1 | ALE_PORT_2) << priv->host_port); + unreg_mcast_mask << priv->host_port); if (ret != 0) return ret; @@ -2006,7 +2022,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, parp = of_get_property(slave_node, "phy_id", &lenp); if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) { dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i); - return -EINVAL; + goto no_phy_slave; } mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); phyid = be32_to_cpup(parp+1); @@ -2019,6 +2035,14 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), PHY_ID_FMT, mdio->name, phyid); + slave_data->phy_if = of_get_phy_mode(slave_node); + if (slave_data->phy_if < 0) { + dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n", + i); + return slave_data->phy_if; + } + +no_phy_slave: mac_addr = of_get_mac_address(slave_node); if (mac_addr) { memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); @@ -2030,14 +2054,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, return ret; } } - - slave_data->phy_if = of_get_phy_mode(slave_node); - if (slave_data->phy_if < 0) { - dev_err(&pdev->dev, "Missing or malformed slave[%d] phy-mode property\n", - i); - return slave_data->phy_if; - } - if (data->dual_emac) { if (of_property_read_u32(slave_node, "dual_emac_res_vlan", &prop)) { diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 0579b2243bb6..3ae83879a75f 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -443,6 +443,35 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) return 0; } +void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti) +{ + u32 ale_entry[ALE_ENTRY_WORDS]; + int type, idx; + int unreg_mcast = 0; + + /* Only bother doing the work if the setting is actually changing */ + if (ale->allmulti == allmulti) + return; + + /* Remember the new setting to check against next time */ + ale->allmulti = allmulti; + + for (idx = 0; idx < ale->params.ale_entries; idx++) { + cpsw_ale_read(ale, idx, ale_entry); + type = cpsw_ale_get_entry_type(ale_entry); + if (type != ALE_TYPE_VLAN) + continue; + + unreg_mcast = cpsw_ale_get_vlan_unreg_mcast(ale_entry); + if (allmulti) + unreg_mcast |= 1; + else + unreg_mcast &= ~1; + cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast); + cpsw_ale_write(ale, idx, ale_entry); + } +} + struct ale_control_info { const char *name; int offset, port_offset; diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index 31cf43cab42e..c0d4127aa549 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h @@ -27,6 +27,7 @@ struct cpsw_ale { struct cpsw_ale_params params; struct timer_list timer; unsigned long ageout; + int allmulti; }; enum cpsw_ale_control { @@ -103,6 +104,7 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, int reg_mcast, int unreg_mcast); int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port); +void cpsw_ale_set_allmulti(struct cpsw_ale *ale, int allmulti); int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control); int cpsw_ale_control_set(struct cpsw_ale *ale, int port, diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9e17d1a91e71..78ec33f5100b 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -550,6 +550,7 @@ do_lso: do_send: /* Start filling in the page buffers with the rndis hdr */ rndis_msg->msg_len += rndis_msg_size; + packet->total_data_buflen = rndis_msg->msg_len; packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size, skb, &packet->page_buf[0]); diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 29b3bb410781..bfb0b6ec8c56 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -272,7 +272,7 @@ static void macvlan_process_broadcast(struct work_struct *w) struct sk_buff *skb; struct sk_buff_head list; - skb_queue_head_init(&list); + __skb_queue_head_init(&list); spin_lock_bh(&port->bc_queue.lock); skb_queue_splice_tail_init(&port->bc_queue, &list); @@ -1082,9 +1082,15 @@ static void macvlan_port_destroy(struct net_device *dev) { struct macvlan_port *port = macvlan_port_get_rtnl(dev); - cancel_work_sync(&port->bc_work); dev->priv_flags &= ~IFF_MACVLAN_PORT; netdev_rx_handler_unregister(dev); + + /* After this point, no packet can schedule bc_work anymore, + * but we need to cancel it and purge left skbs if any. + */ + cancel_work_sync(&port->bc_work); + __skb_queue_purge(&port->bc_queue); + kfree_rcu(port, rcu); } diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 65e2892342bd..6f226de655a4 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -65,7 +66,7 @@ static struct cdev macvtap_cdev; static const struct proto_ops macvtap_socket_ops; #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \ - NETIF_F_TSO6 | NETIF_F_UFO) + NETIF_F_TSO6) #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO) #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG) @@ -569,7 +570,11 @@ static int macvtap_skb_from_vnet_hdr(struct sk_buff *skb, gso_type = SKB_GSO_TCPV6; break; case VIRTIO_NET_HDR_GSO_UDP: + pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n", + current->comm); gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); break; default: return -EINVAL; @@ -614,8 +619,6 @@ static void macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (sinfo->gso_type & SKB_GSO_TCPV6) vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (sinfo->gso_type & SKB_GSO_UDP) - vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP; else BUG(); if (sinfo->gso_type & SKB_GSO_TCP_ECN) @@ -950,9 +953,6 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg) if (arg & TUN_F_TSO6) feature_mask |= NETIF_F_TSO6; } - - if (arg & TUN_F_UFO) - feature_mask |= NETIF_F_UFO; } /* tun/tap driver inverts the usage for TSO offloads, where @@ -963,7 +963,7 @@ static int set_offload(struct macvtap_queue *q, unsigned long arg) * When user space turns off TSO, we turn off GSO/LRO so that * user-space will not receive TSO frames. */ - if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) + if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6)) features |= RX_OFFLOADS; else features &= ~RX_OFFLOADS; @@ -1064,7 +1064,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, case TUNSETOFFLOAD: /* let the user check for future flags */ if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | - TUN_F_TSO_ECN | TUN_F_UFO)) + TUN_F_TSO_ECN)) return -EINVAL; rtnl_lock(); diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index bd37e45c89c0..225c033b08f3 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -50,10 +50,15 @@ #define MII_M1011_PHY_SCR 0x10 #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 +#define MII_M1145_PHY_EXT_SR 0x1b #define MII_M1145_PHY_EXT_CR 0x14 #define MII_M1145_RGMII_RX_DELAY 0x0080 #define MII_M1145_RGMII_TX_DELAY 0x0002 +#define MII_M1145_HWCFG_MODE_SGMII_NO_CLK 0x4 +#define MII_M1145_HWCFG_MODE_MASK 0xf +#define MII_M1145_HWCFG_FIBER_COPPER_AUTO 0x8000 + #define MII_M1111_PHY_LED_CONTROL 0x18 #define MII_M1111_PHY_LED_DIRECT 0x4100 #define MII_M1111_PHY_LED_COMBINE 0x411c @@ -676,6 +681,20 @@ static int m88e1145_config_init(struct phy_device *phydev) } } + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + int temp = phy_read(phydev, MII_M1145_PHY_EXT_SR); + if (temp < 0) + return temp; + + temp &= ~MII_M1145_HWCFG_MODE_MASK; + temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK; + temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO; + + err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp); + if (err < 0) + return err; + } + err = marvell_of_reg_init(phydev); if (err < 0) return err; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 186ce541c657..7302398f0b1f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -174,7 +175,7 @@ struct tun_struct { struct net_device *dev; netdev_features_t set_features; #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ - NETIF_F_TSO6|NETIF_F_UFO) + NETIF_F_TSO6) int vnet_hdr_sz; int sndbuf; @@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, break; } + skb_reset_network_header(skb); + if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { @@ -1149,8 +1152,20 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; break; case VIRTIO_NET_HDR_GSO_UDP: + { + static bool warned; + + if (!warned) { + warned = true; + netdev_warn(tun->dev, + "%s: using disabled UFO feature; please fix this program\n", + current->comm); + } skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + if (skb->protocol == htons(ETH_P_IPV6)) + ipv6_proxy_select_ident(skb); break; + } default: tun->dev->stats.rx_frame_errors++; kfree_skb(skb); @@ -1179,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; } - skb_reset_network_header(skb); skb_probe_transport_header(skb, 0); rxhash = skb_get_hash(skb); @@ -1251,8 +1265,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (sinfo->gso_type & SKB_GSO_TCPV6) gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (sinfo->gso_type & SKB_GSO_UDP) - gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; else { pr_err("unexpected GSO type: " "0x%x, gso_size %d, hdr_len %d\n", @@ -1762,11 +1774,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) features |= NETIF_F_TSO6; arg &= ~(TUN_F_TSO4|TUN_F_TSO6); } - - if (arg & TUN_F_UFO) { - features |= NETIF_F_UFO; - arg &= ~TUN_F_UFO; - } } /* This gives the user a way to test for new features in future by diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index be4275721039..e6338c16081a 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -937,6 +937,7 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p) { struct usbnet *dev = netdev_priv(net); struct sockaddr *addr = p; + int ret; if (netif_running(net)) return -EBUSY; @@ -946,8 +947,12 @@ static int ax88179_set_mac_addr(struct net_device *net, void *p) memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); /* Set the MAC address */ - return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, + ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN, net->dev_addr); + if (ret < 0) + return ret; + + return 0; } static const struct net_device_ops ax88179_netdev_ops = { diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 2a32d9167d3b..d3920b54a92c 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -67,6 +67,35 @@ static const u8 mbm_guid[16] = { 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a, }; +static void usbnet_cdc_update_filter(struct usbnet *dev) +{ + struct cdc_state *info = (void *) &dev->data; + struct usb_interface *intf = info->control; + + u16 cdc_filter = + USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | + USB_CDC_PACKET_TYPE_BROADCAST; + + if (dev->net->flags & IFF_PROMISC) + cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS; + + /* FIXME cdc-ether has some multicast code too, though it complains + * in routine cases. info->ether describes the multicast support. + * Implement that here, manipulating the cdc filter as needed. + */ + + usb_control_msg(dev->udev, + usb_sndctrlpipe(dev->udev, 0), + USB_CDC_SET_ETHERNET_PACKET_FILTER, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + cdc_filter, + intf->cur_altsetting->desc.bInterfaceNumber, + NULL, + 0, + USB_CTRL_SET_TIMEOUT + ); +} + /* probes control interface, claims data interface, collects the bulk * endpoints, activates data interface (if needed), maybe sets MTU. * all pure cdc, except for certain firmware workarounds, and knowing @@ -347,16 +376,8 @@ next_desc: * don't do reset all the way. So the packet filter should * be set to a sane initial value. */ - usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - USB_CDC_SET_ETHERNET_PACKET_FILTER, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, - USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | USB_CDC_PACKET_TYPE_BROADCAST, - intf->cur_altsetting->desc.bInterfaceNumber, - NULL, - 0, - USB_CTRL_SET_TIMEOUT - ); + usbnet_cdc_update_filter(dev); + return 0; bad_desc: @@ -468,10 +489,6 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf) return status; } - /* FIXME cdc-ether has some multicast code too, though it complains - * in routine cases. info->ether describes the multicast support. - * Implement that here, manipulating the cdc filter as needed. - */ return 0; } EXPORT_SYMBOL_GPL(usbnet_cdc_bind); @@ -482,6 +499,7 @@ static const struct driver_info cdc_info = { .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, .status = usbnet_cdc_status, + .set_rx_mode = usbnet_cdc_update_filter, .manage_power = usbnet_manage_power, }; @@ -491,6 +509,7 @@ static const struct driver_info wwan_info = { .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, .status = usbnet_cdc_status, + .set_rx_mode = usbnet_cdc_update_filter, .manage_power = usbnet_manage_power, }; diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e3d84c322e4e..c6554c7a8147 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1162,6 +1162,9 @@ static void intr_callback(struct urb *urb) case -ESHUTDOWN: netif_device_detach(tp->netdev); case -ENOENT: + case -EPROTO: + netif_info(tp, intr, tp->netdev, + "Stop submitting intr, status %d\n", status); return; case -EOVERFLOW: netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); @@ -2891,6 +2894,9 @@ static int rtl8152_open(struct net_device *netdev) if (res) goto out; + /* set speed to 0 to avoid autoresume try to submit rx */ + tp->speed = 0; + res = usb_autopm_get_interface(tp->intf); if (res < 0) { free_all_mem(tp); @@ -2904,6 +2910,8 @@ static int rtl8152_open(struct net_device *netdev) clear_bit(WORK_ENABLE, &tp->flags); usb_kill_urb(tp->intr_urb); cancel_delayed_work_sync(&tp->schedule); + + /* disable the tx/rx, if the workqueue has enabled them. */ if (tp->speed & LINK_STATUS) tp->rtl_ops.disable(tp); } @@ -2955,10 +2963,7 @@ static int rtl8152_close(struct net_device *netdev) * be disable when autoresume occurs, because the * netif_running() would be false. */ - if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { - rtl_runtime_suspend_enable(tp, false); - clear_bit(SELECTIVE_SUSPEND, &tp->flags); - } + rtl_runtime_suspend_enable(tp, false); tasklet_disable(&tp->tl); tp->rtl_ops.down(tp); @@ -3205,7 +3210,7 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) netif_device_detach(netdev); } - if (netif_running(netdev)) { + if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { clear_bit(WORK_ENABLE, &tp->flags); usb_kill_urb(tp->intr_urb); tasklet_disable(&tp->tl); @@ -3253,6 +3258,8 @@ static int rtl8152_resume(struct usb_interface *intf) set_bit(WORK_ENABLE, &tp->flags); } usb_submit_urb(tp->intr_urb, GFP_KERNEL); + } else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { + clear_bit(SELECTIVE_SUSPEND, &tp->flags); } mutex_unlock(&tp->control); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 20615bbd693b..3a6770a65d78 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1052,6 +1052,21 @@ static void __handle_link_change(struct usbnet *dev) clear_bit(EVENT_LINK_CHANGE, &dev->flags); } +static void usbnet_set_rx_mode(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + + usbnet_defer_kevent(dev, EVENT_SET_RX_MODE); +} + +static void __handle_set_rx_mode(struct usbnet *dev) +{ + if (dev->driver_info->set_rx_mode) + (dev->driver_info->set_rx_mode)(dev); + + clear_bit(EVENT_SET_RX_MODE, &dev->flags); +} + /* work that cannot be done in interrupt context uses keventd. * * NOTE: with 2.5 we could do more of this using completion callbacks, @@ -1157,6 +1172,10 @@ skip_reset: if (test_bit (EVENT_LINK_CHANGE, &dev->flags)) __handle_link_change(dev); + if (test_bit (EVENT_SET_RX_MODE, &dev->flags)) + __handle_set_rx_mode(dev); + + if (dev->flags) netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags); } @@ -1525,6 +1544,7 @@ static const struct net_device_ops usbnet_netdev_ops = { .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, + .ndo_set_rx_mode = usbnet_set_rx_mode, .ndo_change_mtu = usbnet_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d75256bd1a6a..ec2a8b41ed41 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -491,8 +491,17 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; break; case VIRTIO_NET_HDR_GSO_UDP: + { + static bool warned; + + if (!warned) { + warned = true; + netdev_warn(dev, + "host using disabled UFO feature; please fix it\n"); + } skb_shinfo(skb)->gso_type = SKB_GSO_UDP; break; + } case VIRTIO_NET_HDR_GSO_TCPV6: skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; break; @@ -881,8 +890,6 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; - else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) - hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP; else BUG(); if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN) @@ -1705,7 +1712,7 @@ static int virtnet_probe(struct virtio_device *vdev) dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { - dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO + dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6; } /* Individual feature bits: what can host handle? */ @@ -1715,11 +1722,9 @@ static int virtnet_probe(struct virtio_device *vdev) dev->hw_features |= NETIF_F_TSO6; if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) dev->hw_features |= NETIF_F_TSO_ECN; - if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) - dev->hw_features |= NETIF_F_UFO; if (gso) - dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO); + dev->features |= dev->hw_features & NETIF_F_ALL_TSO; /* (!csum && gso) case will be fixed by register_netdev() */ } if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) @@ -1757,8 +1762,7 @@ static int virtnet_probe(struct virtio_device *vdev) /* If we can receive ANY GSO packets, we must allocate large ones. */ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || - virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || - virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) vi->big_packets = true; if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) @@ -1952,9 +1956,9 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, - VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, + VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6, VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, - VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, + VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index e5ba6faf3281..86907e5ba6ca 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -80,6 +80,7 @@ struct reg_dmn_pair_mapping { struct ath_regulatory { char alpha2[2]; + enum nl80211_dfs_regions region; u16 country_code; u16 max_power_level; u16 current_rd; diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index c6dd7f1fed65..33b0c7aef2ea 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -368,11 +368,11 @@ void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); - if (reg->power_limit != new_txpow) { + if (reg->power_limit != new_txpow) ath9k_hw_set_txpowerlimit(ah, new_txpow, false); - /* read back in case value is clamped */ - *txpower = reg->max_power_level; - } + + /* read back in case value is clamped */ + *txpower = reg->max_power_level; } EXPORT_SYMBOL(ath9k_cmn_update_txpow); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 46f20a309b5f..5c45e787814e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -455,7 +455,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, "%2d %2x %1x %2x %2x\n", i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), - val[2] & (0x7 << (i * 3)) >> (i * 3), + (val[2] & (0x7 << (i * 3))) >> (i * 3), (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); } diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 156a944134dc..3bd030494986 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -734,6 +734,32 @@ static const struct ieee80211_iface_combination if_comb[] = { #endif }; +#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT +static void ath9k_set_mcc_capab(struct ath_softc *sc, struct ieee80211_hw *hw) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + + if (!ath9k_is_chanctx_enabled()) + return; + + hw->flags |= IEEE80211_HW_QUEUE_CONTROL; + hw->queues = ATH9K_NUM_TX_QUEUES; + hw->offchannel_tx_hw_queue = hw->queues - 1; + hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS); + hw->wiphy->iface_combinations = if_comb_multi; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi); + hw->wiphy->max_scan_ssids = 255; + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + hw->wiphy->max_remain_on_channel_duration = 10000; + hw->chanctx_data_size = sizeof(void *); + hw->extra_beacon_tailroom = + sizeof(struct ieee80211_p2p_noa_attr) + 9; + + ath_dbg(common, CHAN_CTX, "Use channel contexts\n"); +} +#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ + static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { struct ath_hw *ah = sc->sc_ah; @@ -746,7 +772,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_RC_TABLE | - IEEE80211_HW_QUEUE_CONTROL | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; if (ath9k_ps_enable) @@ -781,24 +806,6 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); } -#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT - - if (ath9k_is_chanctx_enabled()) { - hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS); - hw->wiphy->iface_combinations = if_comb_multi; - hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi); - hw->wiphy->max_scan_ssids = 255; - hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; - hw->wiphy->max_remain_on_channel_duration = 10000; - hw->chanctx_data_size = sizeof(void *); - hw->extra_beacon_tailroom = - sizeof(struct ieee80211_p2p_noa_attr) + 9; - - ath_dbg(common, CHAN_CTX, "Use channel contexts\n"); - } - -#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; @@ -808,12 +815,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; - /* allow 4 queues per channel context + - * 1 cab queue + 1 offchannel tx queue - */ - hw->queues = ATH9K_NUM_TX_QUEUES; - /* last queue for offchannel */ - hw->offchannel_tx_hw_queue = hw->queues - 1; + hw->queues = 4; hw->max_rates = 4; hw->max_listen_interval = 10; hw->max_rate_tries = 10; @@ -837,6 +839,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &common->sbands[IEEE80211_BAND_5GHZ]; +#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT + ath9k_set_mcc_capab(sc, hw); +#endif ath9k_init_wow(hw); ath9k_cmn_reload_chainmask(ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6f6a974f7fdb..30c66dfcd7a0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1162,6 +1162,9 @@ static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, { int i; + if (!ath9k_is_chanctx_enabled()) + return; + for (i = 0; i < IEEE80211_NUM_ACS; i++) vif->hw_queue[i] = i; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 493a183d0aaf..d6e54a3c88f6 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -169,7 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, if (txq->stopped && txq->pending_frames < sc->tx.txq_max_pending[q]) { - ieee80211_wake_queue(sc->hw, info->hw_queue); + if (ath9k_is_chanctx_enabled()) + ieee80211_wake_queue(sc->hw, info->hw_queue); + else + ieee80211_wake_queue(sc->hw, q); txq->stopped = false; } } @@ -2247,7 +2250,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, fi->txq = q; if (++txq->pending_frames > sc->tx.txq_max_pending[q] && !txq->stopped) { - ieee80211_stop_queue(sc->hw, info->hw_queue); + if (ath9k_is_chanctx_enabled()) + ieee80211_stop_queue(sc->hw, info->hw_queue); + else + ieee80211_stop_queue(sc->hw, q); txq->stopped = true; } } diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 415393dfb6fc..06ea6cc9e30a 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -515,6 +515,7 @@ void ath_reg_notifier_apply(struct wiphy *wiphy, if (!request) return; + reg->region = request->dfs_region; switch (request->initiator) { case NL80211_REGDOM_SET_BY_CORE: /* @@ -779,6 +780,19 @@ u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, return SD_NO_CTL; } + if (ath_regd_get_eepromRD(reg) == CTRY_DEFAULT) { + switch (reg->region) { + case NL80211_DFS_FCC: + return CTL_FCC; + case NL80211_DFS_ETSI: + return CTL_ETSI; + case NL80211_DFS_JP: + return CTL_MKK; + default: + break; + } + } + switch (band) { case IEEE80211_BAND_2GHZ: return reg->regpair->reg_2ghz_ctl; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f55f625fd06b..d20d4e6f391a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -670,7 +670,6 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci, struct brcmf_sdio_dev *sdiodev) { int i; - uint fw_len, nv_len; char end; for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) { @@ -684,25 +683,25 @@ static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci, return -ENODEV; } - fw_len = sizeof(sdiodev->fw_name) - 1; - nv_len = sizeof(sdiodev->nvram_name) - 1; /* check if firmware path is provided by module parameter */ if (brcmf_firmware_path[0] != '\0') { - strncpy(sdiodev->fw_name, brcmf_firmware_path, fw_len); - strncpy(sdiodev->nvram_name, brcmf_firmware_path, nv_len); - fw_len -= strlen(sdiodev->fw_name); - nv_len -= strlen(sdiodev->nvram_name); + strlcpy(sdiodev->fw_name, brcmf_firmware_path, + sizeof(sdiodev->fw_name)); + strlcpy(sdiodev->nvram_name, brcmf_firmware_path, + sizeof(sdiodev->nvram_name)); end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1]; if (end != '/') { - strncat(sdiodev->fw_name, "/", fw_len); - strncat(sdiodev->nvram_name, "/", nv_len); - fw_len--; - nv_len--; + strlcat(sdiodev->fw_name, "/", + sizeof(sdiodev->fw_name)); + strlcat(sdiodev->nvram_name, "/", + sizeof(sdiodev->nvram_name)); } } - strncat(sdiodev->fw_name, brcmf_fwname_data[i].bin, fw_len); - strncat(sdiodev->nvram_name, brcmf_fwname_data[i].nv, nv_len); + strlcat(sdiodev->fw_name, brcmf_fwname_data[i].bin, + sizeof(sdiodev->fw_name)); + strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv, + sizeof(sdiodev->nvram_name)); return 0; } diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2364a3c09b9e..cae692ff1013 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1095,6 +1095,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + u32 scd_queues; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -1108,18 +1109,19 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto done; } - /* - * mac80211 will not push any more frames for transmit - * until the flush is completed - */ - if (drop) { - IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (iwlagn_txfifo_flush(priv, 0)) { - IWL_ERR(priv, "flush request fail\n"); - goto done; - } + scd_queues = BIT(priv->cfg->base_params->num_of_queues) - 1; + scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | + BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); + + if (vif) + scd_queues &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); + + IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n", scd_queues); + if (iwlagn_txfifo_flush(priv, scd_queues)) { + IWL_ERR(priv, "flush request fail\n"); + goto done; } - IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); + IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n"); iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff); done: mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index e4351487ca72..d2b7234b1c73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c @@ -82,7 +82,8 @@ #define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */ #define IWL8000_FW_PRE "iwlwifi-8000" -#define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE __stringify(api) ".ucode" +#define IWL8000_MODULE_FIRMWARE(api) \ + IWL8000_FW_PRE "-" __stringify(api) ".ucode" #define NVM_HW_SECTION_NUM_FAMILY_8000 10 #define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 9eb85249e89c..d8fc548c0d6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -563,6 +563,7 @@ enum iwl_trans_state { * Set during transport allocation. * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @pm_support: set to true in start_hw if link pm is supported + * @ltr_enabled: set to true if the LTR is enabled * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. * The user should use iwl_trans_{alloc,free}_tx_cmd. * @dev_cmd_headroom: room needed for the transport's private use before the @@ -589,6 +590,7 @@ struct iwl_trans { u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size; bool pm_support; + bool ltr_enabled; /* The following fields are internal only */ struct kmem_cache *dev_cmd_pool; diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 8df2021f9856..da2ffb785194 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -303,8 +303,8 @@ static const __le64 iwl_ci_mask[][3] = { }; static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = { - cpu_to_le32(0x28412201), - cpu_to_le32(0x11118451), + cpu_to_le32(0x2e402280), + cpu_to_le32(0x7711a751), }; struct corunning_block_luts { diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c index 585c0ab4a3ec..8a1d2f33d5b7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c @@ -291,8 +291,8 @@ static const __le64 iwl_ci_mask[][3] = { }; static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = { - cpu_to_le32(0x28412201), - cpu_to_le32(0x11118451), + cpu_to_le32(0x2e402280), + cpu_to_le32(0x7711a751), }; struct corunning_block_luts { diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 27dd86395b39..2fd8ad4633e0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -68,13 +68,46 @@ /* Power Management Commands, Responses, Notifications */ +/** + * enum iwl_ltr_config_flags - masks for LTR config command flags + * @LTR_CFG_FLAG_FEATURE_ENABLE: Feature operational status + * @LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS: allow LTR change on shadow + * memory access + * @LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH: allow LTR msg send on ANY LTR + * reg change + * @LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3: allow LTR msg send on transition from + * D0 to D3 + * @LTR_CFG_FLAG_SW_SET_SHORT: fixed static short LTR register + * @LTR_CFG_FLAG_SW_SET_LONG: fixed static short LONG register + * @LTR_CFG_FLAG_DENIE_C10_ON_PD: allow going into C10 on PD + */ +enum iwl_ltr_config_flags { + LTR_CFG_FLAG_FEATURE_ENABLE = BIT(0), + LTR_CFG_FLAG_HW_DIS_ON_SHADOW_REG_ACCESS = BIT(1), + LTR_CFG_FLAG_HW_EN_SHRT_WR_THROUGH = BIT(2), + LTR_CFG_FLAG_HW_DIS_ON_D0_2_D3 = BIT(3), + LTR_CFG_FLAG_SW_SET_SHORT = BIT(4), + LTR_CFG_FLAG_SW_SET_LONG = BIT(5), + LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6), +}; + +/** + * struct iwl_ltr_config_cmd - configures the LTR + * @flags: See %enum iwl_ltr_config_flags + */ +struct iwl_ltr_config_cmd { + __le32 flags; + __le32 static_long; + __le32 static_short; +} __packed; + /* Radio LP RX Energy Threshold measured in dBm */ #define POWER_LPRX_RSSI_THRESHOLD 75 #define POWER_LPRX_RSSI_THRESHOLD_MAX 94 #define POWER_LPRX_RSSI_THRESHOLD_MIN 30 /** - * enum iwl_scan_flags - masks for power table command flags + * enum iwl_power_flags - masks for power table command flags * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off * receiver and transmitter. '0' - does not allow. * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 667a92274c87..c62575d86bcd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -157,6 +157,7 @@ enum { /* Power - legacy power table command */ POWER_TABLE_CMD = 0x77, PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78, + LTR_CONFIG = 0xee, /* Thermal Throttling*/ REPLY_THERMAL_MNG_BACKOFF = 0x7e, diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 23fd711a67e4..e0d9f19650b0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -480,6 +480,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm) /* Initialize tx backoffs to the minimal possible */ iwl_mvm_tt_tx_backoff(mvm, 0); + if (mvm->trans->ltr_enabled) { + struct iwl_ltr_config_cmd cmd = { + .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE), + }; + + WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, + sizeof(cmd), &cmd)); + } + ret = iwl_mvm_power_update_device(mvm); if (ret) goto error; diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c7a73c68bdab..585fe5b7100f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -526,7 +526,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, } if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && - !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) + !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status) && + !test_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) goto drop; /* treat non-bufferable MMPDUs as broadcast if sta is sleeping */ @@ -1734,6 +1735,13 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, if (changes & BSS_CHANGED_BEACON && iwl_mvm_mac_ctxt_beacon_changed(mvm, vif)) IWL_WARN(mvm, "Failed updating beacon data\n"); + + if (changes & BSS_CHANGED_TXPOWER) { + IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n", + bss_conf->txpower); + iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); + } + } static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, @@ -2367,14 +2375,19 @@ static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm, /* Set the node address */ memcpy(aux_roc_req.node_addr, vif->addr, ETH_ALEN); + lockdep_assert_held(&mvm->mutex); + + spin_lock_bh(&mvm->time_event_lock); + + if (WARN_ON(te_data->id == HOT_SPOT_CMD)) { + spin_unlock_bh(&mvm->time_event_lock); + return -EIO; + } + te_data->vif = vif; te_data->duration = duration; te_data->id = HOT_SPOT_CMD; - lockdep_assert_held(&mvm->mutex); - - spin_lock_bh(&mvm->time_event_lock); - list_add_tail(&te_data->list, &mvm->time_event_list); spin_unlock_bh(&mvm->time_event_lock); /* @@ -2430,22 +2443,23 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, duration, type); + mutex_lock(&mvm->mutex); + switch (vif->type) { case NL80211_IFTYPE_STATION: /* Use aux roc framework (HS20) */ ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, vif, duration); - return ret; + goto out_unlock; case NL80211_IFTYPE_P2P_DEVICE: /* handle below */ break; default: IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type); - return -EINVAL; + ret = -EINVAL; + goto out_unlock; } - mutex_lock(&mvm->mutex); - for (i = 0; i < NUM_PHY_CTX; i++) { phy_ctxt = &mvm->phy_ctxts[i]; if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 15aa298ee79c..48cb25a93591 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -336,6 +336,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(DTS_MEASUREMENT_NOTIFICATION), CMD(REPLY_THERMAL_MNG_BACKOFF), CMD(MAC_PM_POWER_TABLE), + CMD(LTR_CONFIG), CMD(BT_COEX_CI), CMD(BT_COEX_UPDATE_SW_BOOST), CMD(BT_COEX_UPDATE_CORUN_LUT), diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index cb85e63c20aa..b280d5d87127 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -459,7 +459,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, basic_ssid ? 1 : 0); cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | - TX_CMD_FLG_BT_DIS); + 3 << TX_CMD_FLG_BT_PRIO_POS); + cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); cmd->tx_cmd.rate_n_flags = diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index b7f9e61d14e2..6dfad230be5e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -305,8 +305,8 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, te_data->running = false; te_data->vif = NULL; te_data->uid = 0; + te_data->id = TE_MAX; } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) { - set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); te_data->running = true; ieee80211_ready_on_channel(mvm->hw); /* Start TE */ diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 1cb793a498ac..c6a517c771df 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -175,14 +175,10 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, /* * for data packets, rate info comes from the table inside the fw. This - * table is controlled by LINK_QUALITY commands. Exclude ctrl port - * frames like EAPOLs which should be treated as mgmt frames. This - * avoids them being sent initially in high rates which increases the - * chances for completion of the 4-Way handshake. + * table is controlled by LINK_QUALITY commands */ - if (ieee80211_is_data(fc) && sta && - !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) { + if (ieee80211_is_data(fc) && sta) { tx_cmd->initial_rate_index = 0; tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); return; diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 1393bac0025c..3781b029e54a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -174,6 +174,7 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u16 lctl; + u16 cap; /* * HW bug W/A for instability in PCIe bus L0S->L1 transition. @@ -184,16 +185,17 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans) * power savings, even without L1. */ pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl); - if (lctl & PCI_EXP_LNKCTL_ASPM_L1) { - /* L1-ASPM enabled; disable(!) L0S */ + if (lctl & PCI_EXP_LNKCTL_ASPM_L1) iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ + else iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Disabled; Enabling L0S\n"); - } trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S); + + pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_DEVCTL2, &cap); + trans->ltr_enabled = cap & PCI_EXP_DEVCTL2_LTR_EN; + dev_info(trans->dev, "L1 %sabled - LTR %sabled\n", + (lctl & PCI_EXP_LNKCTL_ASPM_L1) ? "En" : "Dis", + trans->ltr_enabled ? "En" : "Dis"); } /* @@ -428,7 +430,7 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans) ret = iwl_poll_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); - if (ret) + if (ret < 0) IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); IWL_DEBUG_INFO(trans, "stop master\n"); @@ -544,7 +546,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) msleep(25); } - IWL_DEBUG_INFO(trans, "got NIC after %d iterations\n", iter); + IWL_ERR(trans, "Couldn't prepare the card\n"); return ret; } @@ -1043,7 +1045,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); - if (ret) { + if (ret < 0) { IWL_ERR(trans, "Failed to resume the device (mac ready)\n"); return ret; } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 40057079ffb9..5ef5a0eeba50 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -196,6 +196,7 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win); del_timer_sync(&tbl->timer_context.timer); + tbl->timer_context.timer_is_set = false; spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); list_del(&tbl->list); @@ -297,6 +298,7 @@ mwifiex_flush_data(unsigned long context) (struct reorder_tmr_cnxt *) context; int start_win, seq_num; + ctx->timer_is_set = false; seq_num = mwifiex_11n_find_last_seq_num(ctx); if (seq_num < 0) @@ -385,6 +387,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, new_node->timer_context.ptr = new_node; new_node->timer_context.priv = priv; + new_node->timer_context.timer_is_set = false; init_timer(&new_node->timer_context.timer); new_node->timer_context.timer.function = mwifiex_flush_data; @@ -399,6 +402,22 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); } +static void +mwifiex_11n_rxreorder_timer_restart(struct mwifiex_rx_reorder_tbl *tbl) +{ + u32 min_flush_time; + + if (tbl->win_size >= MWIFIEX_BA_WIN_SIZE_32) + min_flush_time = MIN_FLUSH_TIMER_15_MS; + else + min_flush_time = MIN_FLUSH_TIMER_MS; + + mod_timer(&tbl->timer_context.timer, + jiffies + msecs_to_jiffies(min_flush_time * tbl->win_size)); + + tbl->timer_context.timer_is_set = true; +} + /* * This function prepares command for adding a BA request. * @@ -523,31 +542,31 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, u8 *ta, u8 pkt_type, void *payload) { struct mwifiex_rx_reorder_tbl *tbl; - int start_win, end_win, win_size; + int prev_start_win, start_win, end_win, win_size; u16 pkt_index; bool init_window_shift = false; + int ret = 0; tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); if (!tbl) { if (pkt_type != PKT_TYPE_BAR) mwifiex_11n_dispatch_pkt(priv, payload); - return 0; + return ret; } if ((pkt_type == PKT_TYPE_AMSDU) && !tbl->amsdu) { mwifiex_11n_dispatch_pkt(priv, payload); - return 0; + return ret; } start_win = tbl->start_win; + prev_start_win = start_win; win_size = tbl->win_size; end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); if (tbl->flags & RXREOR_INIT_WINDOW_SHIFT) { init_window_shift = true; tbl->flags &= ~RXREOR_INIT_WINDOW_SHIFT; } - mod_timer(&tbl->timer_context.timer, - jiffies + msecs_to_jiffies(MIN_FLUSH_TIMER_MS * win_size)); if (tbl->flags & RXREOR_FORCE_NO_DROP) { dev_dbg(priv->adapter->dev, @@ -568,11 +587,14 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) { if (seq_num >= ((start_win + TWOPOW11) & (MAX_TID_VALUE - 1)) && - seq_num < start_win) - return -1; + seq_num < start_win) { + ret = -1; + goto done; + } } else if ((seq_num < start_win) || - (seq_num > (start_win + TWOPOW11))) { - return -1; + (seq_num >= (start_win + TWOPOW11))) { + ret = -1; + goto done; } } @@ -601,8 +623,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, else pkt_index = (seq_num+MAX_TID_VALUE) - start_win; - if (tbl->rx_reorder_ptr[pkt_index]) - return -1; + if (tbl->rx_reorder_ptr[pkt_index]) { + ret = -1; + goto done; + } tbl->rx_reorder_ptr[pkt_index] = payload; } @@ -613,7 +637,11 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, */ mwifiex_11n_scan_and_dispatch(priv, tbl); - return 0; +done: + if (!tbl->timer_context.timer_is_set || + prev_start_win != tbl->start_win) + mwifiex_11n_rxreorder_timer_restart(tbl); + return ret; } /* diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 3a87bb0e3a62..63ecea89b4ab 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -21,6 +21,8 @@ #define _MWIFIEX_11N_RXREORDER_H_ #define MIN_FLUSH_TIMER_MS 50 +#define MIN_FLUSH_TIMER_15_MS 15 +#define MWIFIEX_BA_WIN_SIZE_32 32 #define PKT_TYPE_BAR 0xE7 #define MAX_TID_VALUE (2 << 11) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index e2635747d966..f55658d15c60 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -592,6 +592,7 @@ struct reorder_tmr_cnxt { struct timer_list timer; struct mwifiex_rx_reorder_tbl *ptr; struct mwifiex_private *priv; + u8 timer_is_set; }; struct mwifiex_rx_reorder_tbl { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 573897b8e878..8444313eabe2 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1111,6 +1111,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Ovislink */ { USB_DEVICE(0x1b75, 0x3071) }, { USB_DEVICE(0x1b75, 0x3072) }, + { USB_DEVICE(0x1b75, 0xa200) }, /* Para */ { USB_DEVICE(0x20b8, 0x8888) }, /* Pegatron */ diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 58ba71830886..40b6d1d006d7 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -467,7 +467,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw); /* <2> work queue */ rtlpriv->works.hw = hw; - rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0); + rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index f6179bc06086..07dae0d44abc 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1828,3 +1828,9 @@ const struct ieee80211_ops rtl_ops = { .flush = rtl_op_flush, }; EXPORT_SYMBOL_GPL(rtl_ops); + +bool rtl_btc_status_false(void) +{ + return false; +} +EXPORT_SYMBOL_GPL(rtl_btc_status_false); diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 59cd3b9dca25..624e1dc16d31 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -42,5 +42,6 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, u32 mask, u32 data); void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data); bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); +bool rtl_btc_status_false(void); #endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 667aba81246c..25daa8715219 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1796,7 +1796,8 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtl_pci_reset_trx_ring(hw); rtlpci->driver_is_goingto_unload = false; - if (rtlpriv->cfg->ops->get_btc_status()) { + if (rtlpriv->cfg->ops->get_btc_status && + rtlpriv->cfg->ops->get_btc_status()) { rtlpriv->btcoexist.btc_ops->btc_init_variables(rtlpriv); rtlpriv->btcoexist.btc_ops->btc_init_hal_vars(rtlpriv); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index a00861b26ece..29983bc96a89 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -656,7 +656,8 @@ static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, + bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *)) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -722,7 +723,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); - rtstatus = rtl_cmd_send_packet(hw, skb); + if (cmd_send_packet) + rtstatus = cmd_send_packet(hw, skb); + else + rtstatus = rtl_cmd_send_packet(hw, skb); if (rtstatus) b_dlok = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index a815bd6273da..b64ae45dc674 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -109,7 +109,9 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92c_set_fw_rsvdpagepkt + (struct ieee80211_hw *hw, + bool (*cmd_send_packet)(struct ieee80211_hw *, struct sk_buff *)); void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); void usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, void *data, u16 len); void rtl92c_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 831df101d7b7..9b660df6fd71 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -114,6 +114,8 @@ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4) #define GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr) \ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) +#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32) #define CHIP_VER_B BIT(4) #define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 8ec0f031f48a..55357d69397a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -459,7 +459,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); - rtl92c_set_fw_rsvdpagepkt(hw, 0); + rtl92c_set_fw_rsvdpagepkt(hw, NULL); _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index d86b5b566444..46ea07605eb4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -244,6 +244,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, + .get_btc_status = rtl_btc_status_false, }; static struct rtl_mod_params rtl92ce_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 2fb9c7acb76a..dc3d20b17a26 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -728,6 +728,9 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) case HW_DESC_RXPKT_LEN: ret = GET_RX_DESC_PKT_LEN(pdesc); break; + case HW_DESC_RXBUFF_ADDR: + ret = GET_RX_STATUS_DESC_BUFF_ADDR(pdesc); + break; default: RT_ASSERT(false, "ERR rxdesc :%d not process\n", desc_name); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 04aa0b5f5b3d..873363acbacf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1592,6 +1592,20 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } } +bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + /* Currently nothing happens here. + * Traffic stops after some seconds in WPA2 802.11n mode. + * Maybe because rtl8192cu chip should be set from here? + * If I understand correctly, the realtek vendor driver sends some urbs + * if its "here". + * + * This is maybe necessary: + * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb); + */ + return true; +} + void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1939,7 +1953,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) recover = true; rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); - rtl92c_set_fw_rsvdpagepkt(hw, 0); + rtl92c_set_fw_rsvdpagepkt(hw, + &usb_cmd_send_packet); _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); if (recover) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 0f7812e0c8aa..c1e33b0228c0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -104,7 +104,6 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); int rtl92c_download_fw(struct ieee80211_hw *hw); void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished); void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 7c5fbaf5fee0..e06bafee37f9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -101,6 +101,12 @@ static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw) } } +/* get bt coexist status */ +static bool rtl92cu_get_btc_status(void) +{ + return false; +} + static struct rtl_hal_ops rtl8192cu_hal_ops = { .init_sw_vars = rtl92cu_init_sw_vars, .deinit_sw_vars = rtl92cu_deinit_sw_vars, @@ -148,6 +154,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, .fill_h2c_cmd = rtl92c_fill_h2c_cmd, + .get_btc_status = rtl92cu_get_btc_status, }; static struct rtl_mod_params rtl92cu_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index edab5a5351b5..a0aba088259a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -251,6 +251,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = { .get_rfreg = rtl92d_phy_query_rf_reg, .set_rfreg = rtl92d_phy_set_rf_reg, .linked_set_reg = rtl92d_linked_set_reg, + .get_btc_status = rtl_btc_status_false, }; static struct rtl_mod_params rtl92de_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c index dfdc9b20e4ad..1a87edca2c3f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c @@ -362,7 +362,7 @@ void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, "switch case not process %x\n", variable); break; } @@ -591,7 +591,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) acm_ctrl &= (~ACMHW_BEQEN); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, "switch case not process\n"); break; } @@ -710,7 +710,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, "switch case not process %x\n", variable); break; } @@ -2424,7 +2424,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, "switch case not process\n"); enc_algo = CAM_TKIP; break; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h index 83c98674bfd3..6e7a70b43949 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -446,6 +446,8 @@ /* DWORD 6 */ #define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \ SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val) +#define GET_RX_STATUS_DESC_BUFF_ADDR(__pdesc) \ + SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32) #define SE_RX_HAL_IS_CCK_RATE(_pdesc)\ (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \ diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 1bff2a0f7600..aadba29c167a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -87,11 +87,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) static void rtl92se_fw_cb(const struct firmware *firmware, void *context) { struct ieee80211_hw *hw = context; - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); struct rt_firmware *pfirmware = NULL; - int err; RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, "Firmware callback routine entered!\n"); @@ -112,20 +109,6 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context) memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); pfirmware->sz_fw_tmpbufferlen = firmware->size; release_firmware(firmware); - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Can't register mac80211 hw\n"); - return; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - rtlpci->irq_alloc = 1; - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); - - /*init rfkill */ - rtl_init_rfkill(hw); } static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) @@ -226,8 +209,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) if (!rtlpriv->rtlhal.pfirmware) return 1; - rtlpriv->max_fw_size = RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE; - + rtlpriv->max_fw_size = RTL8190_MAX_FIRMWARE_CODE_SIZE*2 + + sizeof(struct fw_hdr); pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); /* request fw */ @@ -294,6 +277,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = { .set_bbreg = rtl92s_phy_set_bb_reg, .get_rfreg = rtl92s_phy_query_rf_reg, .set_rfreg = rtl92s_phy_set_rf_reg, + .get_btc_status = rtl_btc_status_false, }; static struct rtl_mod_params rtl92se_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index b358ebce8942..672fd3b02835 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -640,6 +640,9 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) case HW_DESC_RXPKT_LEN: ret = GET_RX_STATUS_DESC_PKT_LEN(desc); break; + case HW_DESC_RXBUFF_ADDR: + ret = GET_RX_STATUS_DESC_BUFF_ADDR(desc); + break; default: RT_ASSERT(false, "ERR rxdesc :%d not process\n", desc_name); diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c index 9786313dc62f..1e9570fa874f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c @@ -1889,15 +1889,18 @@ static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &rtlpriv->phy; u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr); - if (band != BAND_ON_2_4G && band != BAND_ON_5G) + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band); - - if (rfpath >= MAX_RF_PATH) + band = BAND_ON_2_4G; + } + if (rfpath >= MAX_RF_PATH) { RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath); - - if (txnum >= MAX_RF_PATH) + rfpath = MAX_RF_PATH - 1; + } + if (txnum >= MAX_RF_PATH) { RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum); - + txnum = MAX_RF_PATH - 1; + } rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n", diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 10cf69c4bc42..46ee956d0235 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -1117,7 +1117,18 @@ int rtl_usb_probe(struct usb_interface *intf, } rtlpriv->cfg->ops->init_sw_leds(hw); + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw.\n"); + err = -ENODEV; + goto error_out; + } + rtlpriv->mac80211.mac80211_registered = 1; + + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; + error_out: rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index d4eb8d2e9cb7..083ecc93fe5e 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -176,10 +176,11 @@ struct xenvif_queue { /* Per-queue data for xenvif */ char rx_irq_name[IRQ_NAME_SIZE]; /* DEVNAME-qN-rx */ struct xen_netif_rx_back_ring rx; struct sk_buff_head rx_queue; - RING_IDX rx_last_skb_slots; - unsigned long status; - struct timer_list rx_stalled; + unsigned int rx_queue_max; + unsigned int rx_queue_len; + unsigned long last_rx_time; + bool stalled; struct gnttab_copy grant_copy_op[MAX_GRANT_COPY_OPS]; @@ -199,18 +200,14 @@ struct xenvif_queue { /* Per-queue data for xenvif */ struct xenvif_stats stats; }; +/* Maximum number of Rx slots a to-guest packet may use, including the + * slot needed for GSO meta-data. + */ +#define XEN_NETBK_RX_SLOTS_MAX (MAX_SKB_FRAGS + 1) + enum state_bit_shift { /* This bit marks that the vif is connected */ VIF_STATUS_CONNECTED, - /* This bit signals the RX thread that queuing was stopped (in - * start_xmit), and either the timer fired or an RX interrupt came - */ - QUEUE_STATUS_RX_PURGE_EVENT, - /* This bit tells the interrupt handler that this queue was the reason - * for the carrier off, so it should kick the thread. Only queues which - * brought it down can turn on the carrier. - */ - QUEUE_STATUS_RX_STALLED }; struct xenvif { @@ -228,9 +225,6 @@ struct xenvif { u8 ip_csum:1; u8 ipv6_csum:1; - /* Internal feature information. */ - u8 can_queue:1; /* can queue packets for receiver? */ - /* Is this interface disabled? True when backend discovers * frontend is rogue. */ @@ -240,6 +234,9 @@ struct xenvif { /* Queues */ struct xenvif_queue *queues; unsigned int num_queues; /* active queues, resource allocated */ + unsigned int stalled_queues; + + spinlock_t lock; #ifdef CONFIG_DEBUG_FS struct dentry *xenvif_dbg_root; @@ -249,6 +246,14 @@ struct xenvif { struct net_device *dev; }; +struct xenvif_rx_cb { + unsigned long expires; + int meta_slots_used; + bool full_coalesce; +}; + +#define XENVIF_RX_CB(skb) ((struct xenvif_rx_cb *)(skb)->cb) + static inline struct xenbus_device *xenvif_to_xenbus_device(struct xenvif *vif) { return to_xenbus_device(vif->dev->dev.parent); @@ -272,8 +277,6 @@ void xenvif_xenbus_fini(void); int xenvif_schedulable(struct xenvif *vif); -int xenvif_must_stop_queue(struct xenvif_queue *queue); - int xenvif_queue_stopped(struct xenvif_queue *queue); void xenvif_wake_queue(struct xenvif_queue *queue); @@ -296,6 +299,8 @@ void xenvif_kick_thread(struct xenvif_queue *queue); int xenvif_dealloc_kthread(void *data); +void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb); + /* Determine whether the needed number of slots (req) are available, * and set req_event if not. */ diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index f379689dde30..895fe84011e7 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -43,6 +43,9 @@ #define XENVIF_QUEUE_LENGTH 32 #define XENVIF_NAPI_WEIGHT 64 +/* Number of bytes allowed on the internal guest Rx queue. */ +#define XENVIF_RX_QUEUE_BYTES (XEN_NETIF_RX_RING_SIZE/2 * PAGE_SIZE) + /* This function is used to set SKBTX_DEV_ZEROCOPY as well as * increasing the inflight counter. We need to increase the inflight * counter because core driver calls into xenvif_zerocopy_callback @@ -60,20 +63,11 @@ void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue) atomic_dec(&queue->inflight_packets); } -static inline void xenvif_stop_queue(struct xenvif_queue *queue) -{ - struct net_device *dev = queue->vif->dev; - - if (!queue->vif->can_queue) - return; - - netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id)); -} - int xenvif_schedulable(struct xenvif *vif) { return netif_running(vif->dev) && - test_bit(VIF_STATUS_CONNECTED, &vif->status); + test_bit(VIF_STATUS_CONNECTED, &vif->status) && + !vif->disabled; } static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id) @@ -114,16 +108,7 @@ int xenvif_poll(struct napi_struct *napi, int budget) static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id) { struct xenvif_queue *queue = dev_id; - struct netdev_queue *net_queue = - netdev_get_tx_queue(queue->vif->dev, queue->id); - /* QUEUE_STATUS_RX_PURGE_EVENT is only set if either QDisc was off OR - * the carrier went down and this queue was previously blocked - */ - if (unlikely(netif_tx_queue_stopped(net_queue) || - (!netif_carrier_ok(queue->vif->dev) && - test_bit(QUEUE_STATUS_RX_STALLED, &queue->status)))) - set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status); xenvif_kick_thread(queue); return IRQ_HANDLED; @@ -151,24 +136,13 @@ void xenvif_wake_queue(struct xenvif_queue *queue) netif_tx_wake_queue(netdev_get_tx_queue(dev, id)); } -/* Callback to wake the queue's thread and turn the carrier off on timeout */ -static void xenvif_rx_stalled(unsigned long data) -{ - struct xenvif_queue *queue = (struct xenvif_queue *)data; - - if (xenvif_queue_stopped(queue)) { - set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status); - xenvif_kick_thread(queue); - } -} - static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct xenvif *vif = netdev_priv(dev); struct xenvif_queue *queue = NULL; unsigned int num_queues = vif->num_queues; u16 index; - int min_slots_needed; + struct xenvif_rx_cb *cb; BUG_ON(skb->dev != dev); @@ -191,30 +165,10 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) !xenvif_schedulable(vif)) goto drop; - /* At best we'll need one slot for the header and one for each - * frag. - */ - min_slots_needed = 1 + skb_shinfo(skb)->nr_frags; + cb = XENVIF_RX_CB(skb); + cb->expires = jiffies + rx_drain_timeout_jiffies; - /* If the skb is GSO then we'll also need an extra slot for the - * metadata. - */ - if (skb_is_gso(skb)) - min_slots_needed++; - - /* If the skb can't possibly fit in the remaining slots - * then turn off the queue to give the ring a chance to - * drain. - */ - if (!xenvif_rx_ring_slots_available(queue, min_slots_needed)) { - queue->rx_stalled.function = xenvif_rx_stalled; - queue->rx_stalled.data = (unsigned long)queue; - xenvif_stop_queue(queue); - mod_timer(&queue->rx_stalled, - jiffies + rx_drain_timeout_jiffies); - } - - skb_queue_tail(&queue->rx_queue, skb); + xenvif_rx_queue_tail(queue, skb); xenvif_kick_thread(queue); return NETDEV_TX_OK; @@ -465,6 +419,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, vif->queues = NULL; vif->num_queues = 0; + spin_lock_init(&vif->lock); + dev->netdev_ops = &xenvif_netdev_ops; dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | @@ -508,6 +464,8 @@ int xenvif_init_queue(struct xenvif_queue *queue) init_timer(&queue->credit_timeout); queue->credit_window_start = get_jiffies_64(); + queue->rx_queue_max = XENVIF_RX_QUEUE_BYTES; + skb_queue_head_init(&queue->rx_queue); skb_queue_head_init(&queue->tx_queue); @@ -539,8 +497,6 @@ int xenvif_init_queue(struct xenvif_queue *queue) queue->grant_tx_handle[i] = NETBACK_INVALID_HANDLE; } - init_timer(&queue->rx_stalled); - return 0; } @@ -551,7 +507,6 @@ void xenvif_carrier_on(struct xenvif *vif) dev_set_mtu(vif->dev, ETH_DATA_LEN); netdev_update_features(vif->dev); set_bit(VIF_STATUS_CONNECTED, &vif->status); - netif_carrier_on(vif->dev); if (netif_running(vif->dev)) xenvif_up(vif); rtnl_unlock(); @@ -611,6 +566,8 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref, disable_irq(queue->rx_irq); } + queue->stalled = true; + task = kthread_create(xenvif_kthread_guest_rx, (void *)queue, "%s-guest-rx", queue->name); if (IS_ERR(task)) { @@ -674,7 +631,6 @@ void xenvif_disconnect(struct xenvif *vif) netif_napi_del(&queue->napi); if (queue->task) { - del_timer_sync(&queue->rx_stalled); kthread_stop(queue->task); queue->task = NULL; } diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 08f65996534c..6563f0713fc0 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -55,13 +55,20 @@ bool separate_tx_rx_irq = 1; module_param(separate_tx_rx_irq, bool, 0644); -/* When guest ring is filled up, qdisc queues the packets for us, but we have - * to timeout them, otherwise other guests' packets can get stuck there +/* The time that packets can stay on the guest Rx internal queue + * before they are dropped. */ unsigned int rx_drain_timeout_msecs = 10000; module_param(rx_drain_timeout_msecs, uint, 0444); unsigned int rx_drain_timeout_jiffies; +/* The length of time before the frontend is considered unresponsive + * because it isn't providing Rx slots. + */ +static unsigned int rx_stall_timeout_msecs = 60000; +module_param(rx_stall_timeout_msecs, uint, 0444); +static unsigned int rx_stall_timeout_jiffies; + unsigned int xenvif_max_queues; module_param_named(max_queues, xenvif_max_queues, uint, 0644); MODULE_PARM_DESC(max_queues, @@ -83,7 +90,6 @@ static void make_tx_response(struct xenvif_queue *queue, s8 st); static inline int tx_work_todo(struct xenvif_queue *queue); -static inline int rx_work_todo(struct xenvif_queue *queue); static struct xen_netif_rx_response *make_rx_response(struct xenvif_queue *queue, u16 id, @@ -163,6 +169,69 @@ bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue, int needed) return false; } +void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb) +{ + unsigned long flags; + + spin_lock_irqsave(&queue->rx_queue.lock, flags); + + __skb_queue_tail(&queue->rx_queue, skb); + + queue->rx_queue_len += skb->len; + if (queue->rx_queue_len > queue->rx_queue_max) + netif_tx_stop_queue(netdev_get_tx_queue(queue->vif->dev, queue->id)); + + spin_unlock_irqrestore(&queue->rx_queue.lock, flags); +} + +static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue) +{ + struct sk_buff *skb; + + spin_lock_irq(&queue->rx_queue.lock); + + skb = __skb_dequeue(&queue->rx_queue); + if (skb) + queue->rx_queue_len -= skb->len; + + spin_unlock_irq(&queue->rx_queue.lock); + + return skb; +} + +static void xenvif_rx_queue_maybe_wake(struct xenvif_queue *queue) +{ + spin_lock_irq(&queue->rx_queue.lock); + + if (queue->rx_queue_len < queue->rx_queue_max) + netif_tx_wake_queue(netdev_get_tx_queue(queue->vif->dev, queue->id)); + + spin_unlock_irq(&queue->rx_queue.lock); +} + + +static void xenvif_rx_queue_purge(struct xenvif_queue *queue) +{ + struct sk_buff *skb; + while ((skb = xenvif_rx_dequeue(queue)) != NULL) + kfree_skb(skb); +} + +static void xenvif_rx_queue_drop_expired(struct xenvif_queue *queue) +{ + struct sk_buff *skb; + + for(;;) { + skb = skb_peek(&queue->rx_queue); + if (!skb) + break; + if (time_before(jiffies, XENVIF_RX_CB(skb)->expires)) + break; + xenvif_rx_dequeue(queue); + kfree_skb(skb); + } +} + /* * Returns true if we should start a new receive buffer instead of * adding 'size' bytes to a buffer which currently contains 'offset' @@ -237,13 +306,6 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue, return meta; } -struct xenvif_rx_cb { - int meta_slots_used; - bool full_coalesce; -}; - -#define XENVIF_RX_CB(skb) ((struct xenvif_rx_cb *)(skb)->cb) - /* * Set up the grant operations for this fragment. If it's a flipping * interface, we also set up the unmap request from here. @@ -587,12 +649,15 @@ static void xenvif_rx_action(struct xenvif_queue *queue) skb_queue_head_init(&rxq); - while ((skb = skb_dequeue(&queue->rx_queue)) != NULL) { + while (xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX) + && (skb = xenvif_rx_dequeue(queue)) != NULL) { RING_IDX max_slots_needed; RING_IDX old_req_cons; RING_IDX ring_slots_used; int i; + queue->last_rx_time = jiffies; + /* We need a cheap worse case estimate for the number of * slots we'll use. */ @@ -634,15 +699,6 @@ static void xenvif_rx_action(struct xenvif_queue *queue) skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) max_slots_needed++; - /* If the skb may not fit then bail out now */ - if (!xenvif_rx_ring_slots_available(queue, max_slots_needed)) { - skb_queue_head(&queue->rx_queue, skb); - need_to_notify = true; - queue->rx_last_skb_slots = max_slots_needed; - break; - } else - queue->rx_last_skb_slots = 0; - old_req_cons = queue->rx.req_cons; XENVIF_RX_CB(skb)->meta_slots_used = xenvif_gop_skb(skb, &npo, queue); ring_slots_used = queue->rx.req_cons - old_req_cons; @@ -1869,12 +1925,6 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) } } -static inline int rx_work_todo(struct xenvif_queue *queue) -{ - return (!skb_queue_empty(&queue->rx_queue) && - xenvif_rx_ring_slots_available(queue, queue->rx_last_skb_slots)); -} - static inline int tx_work_todo(struct xenvif_queue *queue) { if (likely(RING_HAS_UNCONSUMED_REQUESTS(&queue->tx))) @@ -1931,92 +1981,121 @@ err: return err; } -static void xenvif_start_queue(struct xenvif_queue *queue) +static void xenvif_queue_carrier_off(struct xenvif_queue *queue) { - if (xenvif_schedulable(queue->vif)) - xenvif_wake_queue(queue); + struct xenvif *vif = queue->vif; + + queue->stalled = true; + + /* At least one queue has stalled? Disable the carrier. */ + spin_lock(&vif->lock); + if (vif->stalled_queues++ == 0) { + netdev_info(vif->dev, "Guest Rx stalled"); + netif_carrier_off(vif->dev); + } + spin_unlock(&vif->lock); } -/* Only called from the queue's thread, it handles the situation when the guest - * doesn't post enough requests on the receiving ring. - * First xenvif_start_xmit disables QDisc and start a timer, and then either the - * timer fires, or the guest send an interrupt after posting new request. If it - * is the timer, the carrier is turned off here. - * */ -static void xenvif_rx_purge_event(struct xenvif_queue *queue) +static void xenvif_queue_carrier_on(struct xenvif_queue *queue) { - /* Either the last unsuccesful skb or at least 1 slot should fit */ - int needed = queue->rx_last_skb_slots ? - queue->rx_last_skb_slots : 1; + struct xenvif *vif = queue->vif; - /* It is assumed that if the guest post new slots after this, the RX - * interrupt will set the QUEUE_STATUS_RX_PURGE_EVENT bit and wake up - * the thread again - */ - set_bit(QUEUE_STATUS_RX_STALLED, &queue->status); - if (!xenvif_rx_ring_slots_available(queue, needed)) { - rtnl_lock(); - if (netif_carrier_ok(queue->vif->dev)) { - /* Timer fired and there are still no slots. Turn off - * everything except the interrupts - */ - netif_carrier_off(queue->vif->dev); - skb_queue_purge(&queue->rx_queue); - queue->rx_last_skb_slots = 0; - if (net_ratelimit()) - netdev_err(queue->vif->dev, "Carrier off due to lack of guest response on queue %d\n", queue->id); - } else { - /* Probably an another queue already turned the carrier - * off, make sure nothing is stucked in the internal - * queue of this queue - */ - skb_queue_purge(&queue->rx_queue); - queue->rx_last_skb_slots = 0; - } - rtnl_unlock(); - } else if (!netif_carrier_ok(queue->vif->dev)) { - unsigned int num_queues = queue->vif->num_queues; - unsigned int i; - /* The carrier was down, but an interrupt kicked - * the thread again after new requests were - * posted - */ - clear_bit(QUEUE_STATUS_RX_STALLED, - &queue->status); - rtnl_lock(); - netif_carrier_on(queue->vif->dev); - netif_tx_wake_all_queues(queue->vif->dev); - rtnl_unlock(); + queue->last_rx_time = jiffies; /* Reset Rx stall detection. */ + queue->stalled = false; - for (i = 0; i < num_queues; i++) { - struct xenvif_queue *temp = &queue->vif->queues[i]; - - xenvif_napi_schedule_or_enable_events(temp); - } - if (net_ratelimit()) - netdev_err(queue->vif->dev, "Carrier on again\n"); - } else { - /* Queuing were stopped, but the guest posted - * new requests and sent an interrupt - */ - clear_bit(QUEUE_STATUS_RX_STALLED, - &queue->status); - del_timer_sync(&queue->rx_stalled); - xenvif_start_queue(queue); + /* All queues are ready? Enable the carrier. */ + spin_lock(&vif->lock); + if (--vif->stalled_queues == 0) { + netdev_info(vif->dev, "Guest Rx ready"); + netif_carrier_on(vif->dev); } + spin_unlock(&vif->lock); +} + +static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue) +{ + RING_IDX prod, cons; + + prod = queue->rx.sring->req_prod; + cons = queue->rx.req_cons; + + return !queue->stalled + && prod - cons < XEN_NETBK_RX_SLOTS_MAX + && time_after(jiffies, + queue->last_rx_time + rx_stall_timeout_jiffies); +} + +static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) +{ + RING_IDX prod, cons; + + prod = queue->rx.sring->req_prod; + cons = queue->rx.req_cons; + + return queue->stalled + && prod - cons >= XEN_NETBK_RX_SLOTS_MAX; +} + +static bool xenvif_have_rx_work(struct xenvif_queue *queue) +{ + return (!skb_queue_empty(&queue->rx_queue) + && xenvif_rx_ring_slots_available(queue, XEN_NETBK_RX_SLOTS_MAX)) + || xenvif_rx_queue_stalled(queue) + || xenvif_rx_queue_ready(queue) + || kthread_should_stop() + || queue->vif->disabled; +} + +static long xenvif_rx_queue_timeout(struct xenvif_queue *queue) +{ + struct sk_buff *skb; + long timeout; + + skb = skb_peek(&queue->rx_queue); + if (!skb) + return MAX_SCHEDULE_TIMEOUT; + + timeout = XENVIF_RX_CB(skb)->expires - jiffies; + return timeout < 0 ? 0 : timeout; +} + +/* Wait until the guest Rx thread has work. + * + * The timeout needs to be adjusted based on the current head of the + * queue (and not just the head at the beginning). In particular, if + * the queue is initially empty an infinite timeout is used and this + * needs to be reduced when a skb is queued. + * + * This cannot be done with wait_event_timeout() because it only + * calculates the timeout once. + */ +static void xenvif_wait_for_rx_work(struct xenvif_queue *queue) +{ + DEFINE_WAIT(wait); + + if (xenvif_have_rx_work(queue)) + return; + + for (;;) { + long ret; + + prepare_to_wait(&queue->wq, &wait, TASK_INTERRUPTIBLE); + if (xenvif_have_rx_work(queue)) + break; + ret = schedule_timeout(xenvif_rx_queue_timeout(queue)); + if (!ret) + break; + } + finish_wait(&queue->wq, &wait); } int xenvif_kthread_guest_rx(void *data) { struct xenvif_queue *queue = data; - struct sk_buff *skb; + struct xenvif *vif = queue->vif; - while (!kthread_should_stop()) { - wait_event_interruptible(queue->wq, - rx_work_todo(queue) || - queue->vif->disabled || - test_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status) || - kthread_should_stop()); + for (;;) { + xenvif_wait_for_rx_work(queue); if (kthread_should_stop()) break; @@ -2028,35 +2107,38 @@ int xenvif_kthread_guest_rx(void *data) * context so we defer it here, if this thread is * associated with queue 0. */ - if (unlikely(queue->vif->disabled && queue->id == 0)) { - xenvif_carrier_off(queue->vif); - } else if (unlikely(queue->vif->disabled)) { - /* kthread_stop() would be called upon this thread soon, - * be a bit proactive - */ - skb_queue_purge(&queue->rx_queue); - queue->rx_last_skb_slots = 0; - } else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT, - &queue->status))) { - xenvif_rx_purge_event(queue); - } else if (!netif_carrier_ok(queue->vif->dev)) { - /* Another queue stalled and turned the carrier off, so - * purge the internal queue of queues which were not - * blocked - */ - skb_queue_purge(&queue->rx_queue); - queue->rx_last_skb_slots = 0; + if (unlikely(vif->disabled && queue->id == 0)) { + xenvif_carrier_off(vif); + xenvif_rx_queue_purge(queue); + continue; } if (!skb_queue_empty(&queue->rx_queue)) xenvif_rx_action(queue); + /* If the guest hasn't provided any Rx slots for a + * while it's probably not responsive, drop the + * carrier so packets are dropped earlier. + */ + if (xenvif_rx_queue_stalled(queue)) + xenvif_queue_carrier_off(queue); + else if (xenvif_rx_queue_ready(queue)) + xenvif_queue_carrier_on(queue); + + /* Queued packets may have foreign pages from other + * domains. These cannot be queued indefinitely as + * this would starve guests of grant refs and transmit + * slots. + */ + xenvif_rx_queue_drop_expired(queue); + + xenvif_rx_queue_maybe_wake(queue); + cond_resched(); } /* Bin any remaining skbs */ - while ((skb = skb_dequeue(&queue->rx_queue)) != NULL) - dev_kfree_skb(skb); + xenvif_rx_queue_purge(queue); return 0; } @@ -2113,6 +2195,7 @@ static int __init netback_init(void) goto failed_init; rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs); + rx_stall_timeout_jiffies = msecs_to_jiffies(rx_stall_timeout_msecs); #ifdef CONFIG_DEBUG_FS xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL); diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 8079c31ac5e6..4e56a27f9689 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -52,6 +52,7 @@ static int xenvif_read_io_ring(struct seq_file *m, void *v) struct xenvif_queue *queue = m->private; struct xen_netif_tx_back_ring *tx_ring = &queue->tx; struct xen_netif_rx_back_ring *rx_ring = &queue->rx; + struct netdev_queue *dev_queue; if (tx_ring->sring) { struct xen_netif_tx_sring *sring = tx_ring->sring; @@ -112,6 +113,13 @@ static int xenvif_read_io_ring(struct seq_file *m, void *v) queue->credit_timeout.expires, jiffies); + dev_queue = netdev_get_tx_queue(queue->vif->dev, queue->id); + + seq_printf(m, "\nRx internal queue: len %u max %u pkts %u %s\n", + queue->rx_queue_len, queue->rx_queue_max, + skb_queue_len(&queue->rx_queue), + netif_tx_queue_stopped(dev_queue) ? "stopped" : "running"); + return 0; } @@ -703,6 +711,7 @@ static void connect(struct backend_info *be) be->vif->queues = vzalloc(requested_num_queues * sizeof(struct xenvif_queue)); be->vif->num_queues = requested_num_queues; + be->vif->stalled_queues = requested_num_queues; for (queue_index = 0; queue_index < requested_num_queues; ++queue_index) { queue = &be->vif->queues[queue_index]; @@ -873,15 +882,10 @@ static int read_xenbus_vif_flags(struct backend_info *be) if (!rx_copy) return -EOPNOTSUPP; - if (vif->dev->tx_queue_len != 0) { - if (xenbus_scanf(XBT_NIL, dev->otherend, - "feature-rx-notify", "%d", &val) < 0) - val = 0; - if (val) - vif->can_queue = 1; - else - /* Must be non-zero for pfifo_fast to work. */ - vif->dev->tx_queue_len = 1; + if (xenbus_scanf(XBT_NIL, dev->otherend, + "feature-rx-notify", "%d", &val) < 0 || val == 0) { + xenbus_dev_fatal(dev, -EINVAL, "feature-rx-notify is mandatory"); + return -EINVAL; } if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 59fb12e84e6b..dc566b38645f 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -243,23 +243,27 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node) * This function assign memory region pointed by "memory-region" device tree * property to the given device. */ -void of_reserved_mem_device_init(struct device *dev) +int of_reserved_mem_device_init(struct device *dev) { struct reserved_mem *rmem; struct device_node *np; + int ret; np = of_parse_phandle(dev->of_node, "memory-region", 0); if (!np) - return; + return -ENODEV; rmem = __find_rmem(np); of_node_put(np); if (!rmem || !rmem->ops || !rmem->ops->device_init) - return; + return -EINVAL; - rmem->ops->device_init(rmem, dev); - dev_info(dev, "assigned reserved memory node %s\n", rmem->name); + ret = rmem->ops->device_init(rmem, dev); + if (ret == 0) + dev_info(dev, "assigned reserved memory node %s\n", rmem->name); + + return ret; } /** diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 233fe8a88264..69202d1eb8fb 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -275,15 +275,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) goto err_pcie; } - /* allow the clocks to stabilize */ - usleep_range(200, 500); - /* power up core phy and enable ref clock */ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); + /* + * the async reset input need ref clock to sync internally, + * when the ref clock comes after reset, internal synced + * reset time is too short, cannot meet the requirement. + * add one ~10us delay here. + */ + udelay(10); regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); + /* allow the clocks to stabilize */ + usleep_range(200, 500); + /* Some boards don't have PCIe reset GPIO. */ if (gpio_is_valid(imx6_pcie->reset_gpio)) { gpio_set_value(imx6_pcie->reset_gpio, 0); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 3a5e7e28b874..07aa722bb12c 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -262,13 +262,6 @@ static int pciehp_probe(struct pcie_device *dev) goto err_out_none; } - if (!dev->port->subordinate) { - /* Can happen if we run out of bus numbers during probe */ - dev_err(&dev->device, - "Hotplug bridge without secondary bus, ignoring\n"); - goto err_out_none; - } - ctrl = pcie_init(dev); if (!ctrl) { dev_err(&dev->device, "Controller initialization failed\n"); diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 92b6d9ab00e4..2c6643fdc0cf 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -185,7 +185,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(modalias); -static ssize_t enabled_store(struct device *dev, struct device_attribute *attr, +static ssize_t enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); @@ -210,7 +210,7 @@ static ssize_t enabled_store(struct device *dev, struct device_attribute *attr, return result < 0 ? result : count; } -static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, +static ssize_t enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pci_dev *pdev; @@ -218,7 +218,7 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr, pdev = to_pci_dev(dev); return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt)); } -static DEVICE_ATTR_RW(enabled); +static DEVICE_ATTR_RW(enable); #ifdef CONFIG_NUMA static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr, @@ -563,7 +563,7 @@ static struct attribute *pci_dev_attrs[] = { #endif &dev_attr_dma_mask_bits.attr, &dev_attr_consistent_dma_mask_bits.attr, - &dev_attr_enabled.attr, + &dev_attr_enable.attr, &dev_attr_broken_parity_status.attr, &dev_attr_msi_bus.attr, #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c index e12e5b07f6d7..9dc38140194b 100644 --- a/drivers/pinctrl/pinctrl-baytrail.c +++ b/drivers/pinctrl/pinctrl-baytrail.c @@ -227,10 +227,14 @@ static int byt_irq_type(struct irq_data *d, unsigned type) spin_lock_irqsave(&vg->lock, flags); value = readl(reg); + WARN(value & BYT_DIRECT_IRQ_EN, + "Bad pad config for io mode, force direct_irq_en bit clearing"); + /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits * are used to indicate high and low level triggering */ - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | + BYT_TRIG_LVL); switch (type) { case IRQ_TYPE_LEVEL_HIGH: @@ -318,7 +322,7 @@ static int byt_gpio_direction_output(struct gpio_chip *chip, "Potential Error: Setting GPIO with direct_irq_en to output"); reg_val = readl(reg) | BYT_DIR_MASK; - reg_val &= ~BYT_OUTPUT_EN; + reg_val &= ~(BYT_OUTPUT_EN | BYT_INPUT_EN); if (value) writel(reg_val | BYT_LEVEL, reg); diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index e305416d7697..196a5c8838c4 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -44,7 +44,7 @@ static const int rk808_buck_config_regs[] = { }; static const struct regulator_linear_range rk808_buck_voltage_ranges[] = { - REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500), + REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500), }; static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = { diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 94ae1798d48a..6dd12ddbabc6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1320,7 +1320,7 @@ config RTC_DRV_LPC32XX config RTC_DRV_PM8XXX tristate "Qualcomm PMIC8XXX RTC" - depends on MFD_PM8XXX + depends on MFD_PM8XXX || MFD_SPMI_PMIC help If you say yes here you get support for the Qualcomm PMIC8XXX RTC. diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 314129e66d6e..92679df6d6e2 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -160,7 +160,7 @@ static int trickle_charger_of_init(struct device *dev, struct device_node *node) dev_err(dev, "bq32k: diode and resistor mismatch\n"); return -EINVAL; } - reg = 0x25; + reg = 0x45; break; default: diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 197699f358c7..5adcf111fc14 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -27,21 +27,36 @@ /* RTC_CTRL register bit fields */ #define PM8xxx_RTC_ENABLE BIT(7) -#define PM8xxx_RTC_ALARM_ENABLE BIT(1) #define PM8xxx_RTC_ALARM_CLEAR BIT(0) #define NUM_8_BIT_RTC_REGS 0x4 +/** + * struct pm8xxx_rtc_regs - describe RTC registers per PMIC versions + * @ctrl: base address of control register + * @write: base address of write register + * @read: base address of read register + * @alarm_ctrl: base address of alarm control register + * @alarm_ctrl2: base address of alarm control2 register + * @alarm_rw: base address of alarm read-write register + * @alarm_en: alarm enable mask + */ +struct pm8xxx_rtc_regs { + unsigned int ctrl; + unsigned int write; + unsigned int read; + unsigned int alarm_ctrl; + unsigned int alarm_ctrl2; + unsigned int alarm_rw; + unsigned int alarm_en; +}; + /** * struct pm8xxx_rtc - rtc driver internal structure * @rtc: rtc device for this driver. * @regmap: regmap used to access RTC registers * @allow_set_time: indicates whether writing to the RTC is allowed * @rtc_alarm_irq: rtc alarm irq number. - * @rtc_base: address of rtc control register. - * @rtc_read_base: base address of read registers. - * @rtc_write_base: base address of write registers. - * @alarm_rw_base: base address of alarm registers. * @ctrl_reg: rtc control register. * @rtc_dev: device structure. * @ctrl_reg_lock: spinlock protecting access to ctrl_reg. @@ -51,11 +66,7 @@ struct pm8xxx_rtc { struct regmap *regmap; bool allow_set_time; int rtc_alarm_irq; - int rtc_base; - int rtc_read_base; - int rtc_write_base; - int alarm_rw_base; - u8 ctrl_reg; + const struct pm8xxx_rtc_regs *regs; struct device *rtc_dev; spinlock_t ctrl_reg_lock; }; @@ -71,8 +82,10 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { int rc, i; unsigned long secs, irq_flags; - u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0; + unsigned int ctrl_reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; if (!rtc_dd->allow_set_time) return -EACCES; @@ -87,30 +100,30 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - ctrl_reg = rtc_dd->ctrl_reg; - if (ctrl_reg & PM8xxx_RTC_ALARM_ENABLE) { + rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg); + if (rc) + goto rtc_rw_fail; + + if (ctrl_reg & regs->alarm_en) { alarm_enabled = 1; - ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + ctrl_reg &= ~regs->alarm_en; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } - rtc_dd->ctrl_reg = ctrl_reg; - } else { - spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); } /* Write 0 to Byte[0] */ - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, 0); + rc = regmap_write(rtc_dd->regmap, regs->write, 0); if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; } /* Write Byte[1], Byte[2], Byte[3] */ - rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->rtc_write_base + 1, + rc = regmap_bulk_write(rtc_dd->regmap, regs->write + 1, &value[1], sizeof(value) - 1); if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); @@ -118,25 +131,23 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) } /* Write Byte[0] */ - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_write_base, value[0]); + rc = regmap_write(rtc_dd->regmap, regs->write, value[0]); if (rc) { dev_err(dev, "Write to RTC write data register failed\n"); goto rtc_rw_fail; } if (alarm_enabled) { - ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + ctrl_reg |= regs->alarm_en; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } - rtc_dd->ctrl_reg = ctrl_reg; } rtc_rw_fail: - if (alarm_enabled) - spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); + spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); return rc; } @@ -148,9 +159,9 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned long secs; unsigned int reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base, - value, sizeof(value)); + rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); if (rc) { dev_err(dev, "RTC read data register failed\n"); return rc; @@ -160,14 +171,14 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) * Read the LSB again and check if there has been a carry over. * If there is, redo the read operation. */ - rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_read_base, ®); + rc = regmap_read(rtc_dd->regmap, regs->read, ®); if (rc < 0) { dev_err(dev, "RTC read data register failed\n"); return rc; } if (unlikely(reg < value[0])) { - rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->rtc_read_base, + rc = regmap_bulk_read(rtc_dd->regmap, regs->read, value, sizeof(value)); if (rc) { dev_err(dev, "RTC read data register failed\n"); @@ -195,9 +206,11 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { int rc, i; - u8 value[NUM_8_BIT_RTC_REGS], ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS]; + unsigned int ctrl_reg; unsigned long secs, irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; rtc_tm_to_time(&alarm->time, &secs); @@ -208,28 +221,28 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - rc = regmap_bulk_write(rtc_dd->regmap, rtc_dd->alarm_rw_base, value, + rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, sizeof(value)); if (rc) { dev_err(dev, "Write to RTC ALARM register failed\n"); goto rtc_rw_fail; } - ctrl_reg = rtc_dd->ctrl_reg; + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); + if (rc) + goto rtc_rw_fail; if (alarm->enabled) - ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; + ctrl_reg |= regs->alarm_en; else - ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; + ctrl_reg &= ~regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); + dev_err(dev, "Write to RTC alarm control register failed\n"); goto rtc_rw_fail; } - rtc_dd->ctrl_reg = ctrl_reg; - dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n", alarm->time.tm_hour, alarm->time.tm_min, alarm->time.tm_sec, alarm->time.tm_mday, @@ -245,8 +258,9 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) u8 value[NUM_8_BIT_RTC_REGS]; unsigned long secs; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - rc = regmap_bulk_read(rtc_dd->regmap, rtc_dd->alarm_rw_base, value, + rc = regmap_bulk_read(rtc_dd->regmap, regs->alarm_rw, value, sizeof(value)); if (rc) { dev_err(dev, "RTC alarm time read failed\n"); @@ -276,25 +290,26 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) int rc; unsigned long irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); - u8 ctrl_reg; + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + unsigned int ctrl_reg; spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - ctrl_reg = rtc_dd->ctrl_reg; + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); + if (rc) + goto rtc_rw_fail; if (enable) - ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE; + ctrl_reg |= regs->alarm_en; else - ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; + ctrl_reg &= ~regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; } - rtc_dd->ctrl_reg = ctrl_reg; - rtc_rw_fail: spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); return rc; @@ -311,6 +326,7 @@ static const struct rtc_class_ops pm8xxx_rtc_ops = { static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) { struct pm8xxx_rtc *rtc_dd = dev_id; + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; unsigned int ctrl_reg; int rc; unsigned long irq_flags; @@ -320,48 +336,100 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id) spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); /* Clear the alarm enable bit */ - ctrl_reg = rtc_dd->ctrl_reg; - ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE; + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); + if (rc) { + spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); + goto rtc_alarm_handled; + } - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); + ctrl_reg &= ~regs->alarm_en; + + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); if (rc) { spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); dev_err(rtc_dd->rtc_dev, - "Write to RTC control register failed\n"); + "Write to alarm control register failed\n"); goto rtc_alarm_handled; } - rtc_dd->ctrl_reg = ctrl_reg; spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); /* Clear RTC alarm register */ - rc = regmap_read(rtc_dd->regmap, - rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET, - &ctrl_reg); + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg); if (rc) { dev_err(rtc_dd->rtc_dev, - "RTC Alarm control register read failed\n"); + "RTC Alarm control2 register read failed\n"); goto rtc_alarm_handled; } - ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR; - rc = regmap_write(rtc_dd->regmap, - rtc_dd->rtc_base + PM8XXX_ALARM_CTRL_OFFSET, - ctrl_reg); + ctrl_reg |= PM8xxx_RTC_ALARM_CLEAR; + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl2, ctrl_reg); if (rc) dev_err(rtc_dd->rtc_dev, - "Write to RTC Alarm control register failed\n"); + "Write to RTC Alarm control2 register failed\n"); rtc_alarm_handled: return IRQ_HANDLED; } +static int pm8xxx_rtc_enable(struct pm8xxx_rtc *rtc_dd) +{ + const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; + unsigned int ctrl_reg; + int rc; + + /* Check if the RTC is on, else turn it on */ + rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg); + if (rc) + return rc; + + if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) { + ctrl_reg |= PM8xxx_RTC_ENABLE; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); + if (rc) + return rc; + } + + return 0; +} + +static const struct pm8xxx_rtc_regs pm8921_regs = { + .ctrl = 0x11d, + .write = 0x11f, + .read = 0x123, + .alarm_rw = 0x127, + .alarm_ctrl = 0x11d, + .alarm_ctrl2 = 0x11e, + .alarm_en = BIT(1), +}; + +static const struct pm8xxx_rtc_regs pm8058_regs = { + .ctrl = 0x1e8, + .write = 0x1ea, + .read = 0x1ee, + .alarm_rw = 0x1f2, + .alarm_ctrl = 0x1e8, + .alarm_ctrl2 = 0x1e9, + .alarm_en = BIT(1), +}; + +static const struct pm8xxx_rtc_regs pm8941_regs = { + .ctrl = 0x6046, + .write = 0x6040, + .read = 0x6048, + .alarm_rw = 0x6140, + .alarm_ctrl = 0x6146, + .alarm_ctrl2 = 0x6148, + .alarm_en = BIT(7), +}; + /* * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out */ static const struct of_device_id pm8xxx_id_table[] = { - { .compatible = "qcom,pm8921-rtc", .data = (void *) 0x11D }, - { .compatible = "qcom,pm8058-rtc", .data = (void *) 0x1E8 }, + { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs }, + { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs }, + { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs }, { }, }; MODULE_DEVICE_TABLE(of, pm8xxx_id_table); @@ -369,7 +437,6 @@ MODULE_DEVICE_TABLE(of, pm8xxx_id_table); static int pm8xxx_rtc_probe(struct platform_device *pdev) { int rc; - unsigned int ctrl_reg; struct pm8xxx_rtc *rtc_dd; const struct of_device_id *match; @@ -399,33 +466,12 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) rtc_dd->allow_set_time = of_property_read_bool(pdev->dev.of_node, "allow-set-time"); - rtc_dd->rtc_base = (long) match->data; - - /* Setup RTC register addresses */ - rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET; - rtc_dd->rtc_read_base = rtc_dd->rtc_base + PM8XXX_RTC_READ_OFFSET; - rtc_dd->alarm_rw_base = rtc_dd->rtc_base + PM8XXX_ALARM_RW_OFFSET; - + rtc_dd->regs = match->data; rtc_dd->rtc_dev = &pdev->dev; - /* Check if the RTC is on, else turn it on */ - rc = regmap_read(rtc_dd->regmap, rtc_dd->rtc_base, &ctrl_reg); - if (rc) { - dev_err(&pdev->dev, "RTC control register read failed!\n"); + rc = pm8xxx_rtc_enable(rtc_dd); + if (rc) return rc; - } - - if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) { - ctrl_reg |= PM8xxx_RTC_ENABLE; - rc = regmap_write(rtc_dd->regmap, rtc_dd->rtc_base, ctrl_reg); - if (rc) { - dev_err(&pdev->dev, - "Write to RTC control register failed\n"); - return rc; - } - } - - rtc_dd->ctrl_reg = ctrl_reg; platform_set_drvdata(pdev, rtc_dd); diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a6b1252c9941..806072238c00 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -535,13 +535,15 @@ static int s3c_rtc_probe(struct platform_device *pdev) } clk_prepare_enable(info->rtc_clk); - info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); - if (IS_ERR(info->rtc_src_clk)) { - dev_err(&pdev->dev, "failed to find rtc source clock\n"); - return PTR_ERR(info->rtc_src_clk); + if (info->data->needs_src_clk) { + info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); + if (IS_ERR(info->rtc_src_clk)) { + dev_err(&pdev->dev, + "failed to find rtc source clock\n"); + return PTR_ERR(info->rtc_src_clk); + } + clk_prepare_enable(info->rtc_src_clk); } - clk_prepare_enable(info->rtc_src_clk); - /* check to see if everything is setup correctly */ if (info->data->enable) diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 54fa6e0bc1bb..674d498b46ab 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -399,6 +399,35 @@ EXPORT_SYMBOL_GPL(cxgbi_hbas_add); * If the source port is outside our allocation range, the caller is * responsible for keeping track of their port usage. */ + +static struct cxgbi_sock *find_sock_on_port(struct cxgbi_device *cdev, + unsigned char port_id) +{ + struct cxgbi_ports_map *pmap = &cdev->pmap; + unsigned int i; + unsigned int used; + + if (!pmap->max_connect || !pmap->used) + return NULL; + + spin_lock_bh(&pmap->lock); + used = pmap->used; + for (i = 0; used && i < pmap->max_connect; i++) { + struct cxgbi_sock *csk = pmap->port_csk[i]; + + if (csk) { + if (csk->port_id == port_id) { + spin_unlock_bh(&pmap->lock); + return csk; + } + used--; + } + } + spin_unlock_bh(&pmap->lock); + + return NULL; +} + static int sock_get_port(struct cxgbi_sock *csk) { struct cxgbi_device *cdev = csk->cdev; @@ -749,6 +778,7 @@ static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr) csk->daddr6.sin6_addr = daddr6->sin6_addr; csk->daddr6.sin6_port = daddr6->sin6_port; csk->daddr6.sin6_family = daddr6->sin6_family; + csk->saddr6.sin6_family = daddr6->sin6_family; csk->saddr6.sin6_addr = pref_saddr; neigh_release(n); @@ -2647,12 +2677,14 @@ int cxgbi_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, break; case ISCSI_HOST_PARAM_IPADDRESS: { - __be32 addr; - - addr = cxgbi_get_iscsi_ipv4(chba); - len = sprintf(buf, "%pI4", &addr); + struct cxgbi_sock *csk = find_sock_on_port(chba->cdev, + chba->port_id); + if (csk) { + len = sprintf(buf, "%pIS", + (struct sockaddr *)&csk->saddr); + } log_debug(1 << CXGBI_DBG_ISCSI, - "hba %s, ipv4 %pI4.\n", chba->ndev->name, &addr); + "hba %s, addr %s.\n", chba->ndev->name, buf); break; } default: diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h index 1d98fad6a0ab..2c7cb1c0c453 100644 --- a/drivers/scsi/cxgbi/libcxgbi.h +++ b/drivers/scsi/cxgbi/libcxgbi.h @@ -700,11 +700,6 @@ static inline void cxgbi_set_iscsi_ipv4(struct cxgbi_hba *chba, __be32 ipaddr) chba->ndev->name); } -static inline __be32 cxgbi_get_iscsi_ipv4(struct cxgbi_hba *chba) -{ - return chba->ipv4addr; -} - struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int); void cxgbi_device_unregister(struct cxgbi_device *); void cxgbi_device_unregister_all(unsigned int flag); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9eff8a375132..50a6e1ac8d9c 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1893,6 +1893,11 @@ static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, blk_mq_start_request(req); } + if (blk_queue_tagged(q)) + req->cmd_flags |= REQ_QUEUED; + else + req->cmd_flags &= ~REQ_QUEUED; + scsi_init_cmd_errh(cmd); cmd->scsi_done = scsi_mq_done; diff --git a/drivers/soc/versatile/soc-realview.c b/drivers/soc/versatile/soc-realview.c index cea8ea3491d2..1a07bf540fec 100644 --- a/drivers/soc/versatile/soc-realview.c +++ b/drivers/soc/versatile/soc-realview.c @@ -26,6 +26,7 @@ static const struct of_device_id realview_soc_of_match[] = { { .compatible = "arm,realview-pb11mp-soc", }, { .compatible = "arm,realview-pba8-soc", }, { .compatible = "arm,realview-pbx-soc", }, + { } }; static u32 realview_coreid; diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 729215885250..72e12bad14b9 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -669,6 +669,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) master->cleanup = dw_spi_cleanup; master->transfer_one_message = dw_spi_transfer_one_message; master->max_speed_hz = dws->max_freq; + master->dev.of_node = dev->of_node; /* Basic HW init */ spi_hw_init(dws); diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 835cdda6f4f5..c76b7d7879df 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -454,7 +454,7 @@ static int orion_spi_probe(struct platform_device *pdev) spi->master = master; of_id = of_match_device(orion_spi_of_match_table, &pdev->dev); - devdata = of_id->data; + devdata = (of_id) ? of_id->data : &orion_spi_dev_data; spi->devdata = devdata; spi->clk = devm_clk_get(&pdev->dev, NULL); diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f35f723816ea..fc2dd8441608 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1106,7 +1106,7 @@ err_rxdesc: pl022->sgt_tx.nents, DMA_TO_DEVICE); err_tx_sgmap: dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl, - pl022->sgt_tx.nents, DMA_FROM_DEVICE); + pl022->sgt_rx.nents, DMA_FROM_DEVICE); err_rx_sgmap: sg_free_table(&pl022->sgt_tx); err_alloc_tx_sg: diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index f96ea8a38d64..87bc16f491f0 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -145,6 +145,9 @@ #define RXBUSY (1 << 0) #define TXBUSY (1 << 1) +/* sclk_out: spi master internal logic in rk3x can support 50Mhz */ +#define MAX_SCLK_OUT 50000000 + enum rockchip_ssi_type { SSI_MOTO_SPI = 0, SSI_TI_SSP, @@ -325,6 +328,8 @@ static int rockchip_spi_unprepare_message(struct spi_master *master, spin_unlock_irqrestore(&rs->lock, flags); + spi_enable_chip(rs, 0); + return 0; } @@ -381,6 +386,8 @@ static int rockchip_spi_pio_transfer(struct rockchip_spi *rs) if (rs->tx) wait_for_idle(rs); + spi_enable_chip(rs, 0); + return 0; } @@ -392,8 +399,10 @@ static void rockchip_spi_dma_rxcb(void *data) spin_lock_irqsave(&rs->lock, flags); rs->state &= ~RXBUSY; - if (!(rs->state & TXBUSY)) + if (!(rs->state & TXBUSY)) { + spi_enable_chip(rs, 0); spi_finalize_current_transfer(rs->master); + } spin_unlock_irqrestore(&rs->lock, flags); } @@ -409,8 +418,10 @@ static void rockchip_spi_dma_txcb(void *data) spin_lock_irqsave(&rs->lock, flags); rs->state &= ~TXBUSY; - if (!(rs->state & RXBUSY)) + if (!(rs->state & RXBUSY)) { + spi_enable_chip(rs, 0); spi_finalize_current_transfer(rs->master); + } spin_unlock_irqrestore(&rs->lock, flags); } @@ -496,12 +507,19 @@ static void rockchip_spi_config(struct rockchip_spi *rs) dmacr |= RF_DMA_EN; } + if (WARN_ON(rs->speed > MAX_SCLK_OUT)) + rs->speed = MAX_SCLK_OUT; + + /* the minimum divsor is 2 */ + if (rs->max_freq < 2 * rs->speed) { + clk_set_rate(rs->spiclk, 2 * rs->speed); + rs->max_freq = clk_get_rate(rs->spiclk); + } + /* div doesn't support odd number */ div = max_t(u32, rs->max_freq / rs->speed, 1); div = (div + 1) & 0xfffe; - spi_enable_chip(rs, 0); - writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0); writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1); @@ -515,8 +533,6 @@ static void rockchip_spi_config(struct rockchip_spi *rs) spi_set_clk(rs, div); dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div); - - spi_enable_chip(rs, 1); } static int rockchip_spi_transfer_one( @@ -524,7 +540,7 @@ static int rockchip_spi_transfer_one( struct spi_device *spi, struct spi_transfer *xfer) { - int ret = 0; + int ret = 1; struct rockchip_spi *rs = spi_master_get_devdata(master); WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) && @@ -556,17 +572,27 @@ static int rockchip_spi_transfer_one( rs->tmode = CR0_XFM_RO; /* we need prepare dma before spi was enabled */ - if (master->can_dma && master->can_dma(master, spi, xfer)) { + if (master->can_dma && master->can_dma(master, spi, xfer)) rs->use_dma = 1; - rockchip_spi_prepare_dma(rs); - } else { + else rs->use_dma = 0; - } rockchip_spi_config(rs); - if (!rs->use_dma) + if (rs->use_dma) { + if (rs->tmode == CR0_XFM_RO) { + /* rx: dma must be prepared first */ + rockchip_spi_prepare_dma(rs); + spi_enable_chip(rs, 1); + } else { + /* tx or tr: spi must be enabled first */ + spi_enable_chip(rs, 1); + rockchip_spi_prepare_dma(rs); + } + } else { + spi_enable_chip(rs, 1); ret = rockchip_spi_pio_transfer(rs); + } return ret; } diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index e3bc23bb5883..e50039fb1474 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -82,10 +82,11 @@ struct spidev_data { struct spi_device *spi; struct list_head device_entry; - /* buffer is NULL unless this device is open (users > 0) */ + /* TX/RX buffers are NULL unless this device is open (users > 0) */ struct mutex buf_lock; unsigned users; - u8 *buffer; + u8 *tx_buffer; + u8 *rx_buffer; }; static LIST_HEAD(device_list); @@ -135,7 +136,7 @@ static inline ssize_t spidev_sync_write(struct spidev_data *spidev, size_t len) { struct spi_transfer t = { - .tx_buf = spidev->buffer, + .tx_buf = spidev->tx_buffer, .len = len, }; struct spi_message m; @@ -149,7 +150,7 @@ static inline ssize_t spidev_sync_read(struct spidev_data *spidev, size_t len) { struct spi_transfer t = { - .rx_buf = spidev->buffer, + .rx_buf = spidev->rx_buffer, .len = len, }; struct spi_message m; @@ -179,7 +180,7 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) if (status > 0) { unsigned long missing; - missing = copy_to_user(buf, spidev->buffer, status); + missing = copy_to_user(buf, spidev->rx_buffer, status); if (missing == status) status = -EFAULT; else @@ -206,7 +207,7 @@ spidev_write(struct file *filp, const char __user *buf, spidev = filp->private_data; mutex_lock(&spidev->buf_lock); - missing = copy_from_user(spidev->buffer, buf, count); + missing = copy_from_user(spidev->tx_buffer, buf, count); if (missing == 0) status = spidev_sync_write(spidev, count); else @@ -224,7 +225,7 @@ static int spidev_message(struct spidev_data *spidev, struct spi_transfer *k_tmp; struct spi_ioc_transfer *u_tmp; unsigned n, total; - u8 *buf; + u8 *tx_buf, *rx_buf; int status = -EFAULT; spi_message_init(&msg); @@ -236,7 +237,8 @@ static int spidev_message(struct spidev_data *spidev, * We walk the array of user-provided transfers, using each one * to initialize a kernel version of the same transfer. */ - buf = spidev->buffer; + tx_buf = spidev->tx_buffer; + rx_buf = spidev->rx_buffer; total = 0; for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; n; @@ -250,20 +252,21 @@ static int spidev_message(struct spidev_data *spidev, } if (u_tmp->rx_buf) { - k_tmp->rx_buf = buf; + k_tmp->rx_buf = rx_buf; if (!access_ok(VERIFY_WRITE, (u8 __user *) (uintptr_t) u_tmp->rx_buf, u_tmp->len)) goto done; } if (u_tmp->tx_buf) { - k_tmp->tx_buf = buf; - if (copy_from_user(buf, (const u8 __user *) + k_tmp->tx_buf = tx_buf; + if (copy_from_user(tx_buf, (const u8 __user *) (uintptr_t) u_tmp->tx_buf, u_tmp->len)) goto done; } - buf += k_tmp->len; + tx_buf += k_tmp->len; + rx_buf += k_tmp->len; k_tmp->cs_change = !!u_tmp->cs_change; k_tmp->tx_nbits = u_tmp->tx_nbits; @@ -290,17 +293,17 @@ static int spidev_message(struct spidev_data *spidev, goto done; /* copy any rx data out of bounce buffer */ - buf = spidev->buffer; + rx_buf = spidev->rx_buffer; for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { if (u_tmp->rx_buf) { if (__copy_to_user((u8 __user *) - (uintptr_t) u_tmp->rx_buf, buf, + (uintptr_t) u_tmp->rx_buf, rx_buf, u_tmp->len)) { status = -EFAULT; goto done; } } - buf += u_tmp->len; + rx_buf += u_tmp->len; } status = total; @@ -508,22 +511,41 @@ static int spidev_open(struct inode *inode, struct file *filp) break; } } - if (status == 0) { - if (!spidev->buffer) { - spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); - if (!spidev->buffer) { + + if (status) { + pr_debug("spidev: nothing for minor %d\n", iminor(inode)); + goto err_find_dev; + } + + if (!spidev->tx_buffer) { + spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL); + if (!spidev->tx_buffer) { dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); status = -ENOMEM; + goto err_find_dev; } } - if (status == 0) { - spidev->users++; - filp->private_data = spidev; - nonseekable_open(inode, filp); - } - } else - pr_debug("spidev: nothing for minor %d\n", iminor(inode)); + if (!spidev->rx_buffer) { + spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL); + if (!spidev->rx_buffer) { + dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); + status = -ENOMEM; + goto err_alloc_rx_buf; + } + } + + spidev->users++; + filp->private_data = spidev; + nonseekable_open(inode, filp); + + mutex_unlock(&device_list_lock); + return 0; + +err_alloc_rx_buf: + kfree(spidev->tx_buffer); + spidev->tx_buffer = NULL; +err_find_dev: mutex_unlock(&device_list_lock); return status; } @@ -542,8 +564,11 @@ static int spidev_release(struct inode *inode, struct file *filp) if (!spidev->users) { int dofree; - kfree(spidev->buffer); - spidev->buffer = NULL; + kfree(spidev->tx_buffer); + spidev->tx_buffer = NULL; + + kfree(spidev->rx_buffer); + spidev->rx_buffer = NULL; /* ... after we unbound from the underlying device? */ spin_lock_irq(&spidev->spi_lock); diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 28b93d39a94e..a673ffa34aa3 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -420,7 +420,7 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) struct logger_log *log = file_get_log(iocb->ki_filp); struct logger_entry header; struct timespec now; - size_t len, count; + size_t len, count, w_off; count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); @@ -452,11 +452,14 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) memcpy(log->buffer + log->w_off, &header, len); memcpy(log->buffer, (char *)&header + len, sizeof(header) - len); - len = min(count, log->size - log->w_off); + /* Work with a copy until we are ready to commit the whole entry */ + w_off = logger_offset(log, log->w_off + sizeof(struct logger_entry)); - if (copy_from_iter(log->buffer + log->w_off, len, from) != len) { + len = min(count, log->size - w_off); + + if (copy_from_iter(log->buffer + w_off, len, from) != len) { /* - * Note that by not updating w_off, this abandons the + * Note that by not updating log->w_off, this abandons the * portion of the new entry that *was* successfully * copied, just above. This is intentional to avoid * message corruption from missing fragments. @@ -470,7 +473,7 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from) return -EFAULT; } - log->w_off = logger_offset(log, log->w_off + count); + log->w_off = logger_offset(log, w_off + count); mutex_unlock(&log->mutex); /* wake up any blocked readers */ diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index a8bc2b567789..152f4c12ea43 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -426,6 +426,7 @@ config COMEDI_AIO_IIRO_16 config COMEDI_II_PCI20KC tristate "Intelligent Instruments PCI-20001C carrier support" + depends on HAS_IOMEM ---help--- Enable support for Intelligent Instruments PCI-20001C carrier PCI-20001, PCI-20006 and PCI-20341 @@ -667,7 +668,6 @@ config COMEDI_ADDI_APCI_2200 config COMEDI_ADDI_APCI_3120 tristate "ADDI-DATA APCI_3120/3001 support" depends on HAS_DMA - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_3120/3001 cards diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 495969f46e76..9c32f0276009 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1462,10 +1462,7 @@ static int __comedi_get_user_chanlist(struct comedi_device *dev, unsigned int *chanlist; int ret; - /* user_chanlist could be NULL for do_cmdtest ioctls */ - if (!user_chanlist) - return 0; - + cmd->chanlist = NULL; chanlist = memdup_user(user_chanlist, cmd->chanlist_len * sizeof(unsigned int)); if (IS_ERR(chanlist)) @@ -1609,13 +1606,18 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, s = &dev->subdevices[cmd.subdev]; - /* load channel/gain list */ - ret = __comedi_get_user_chanlist(dev, s, user_chanlist, &cmd); - if (ret) - return ret; + /* user_chanlist can be NULL for COMEDI_CMDTEST ioctl */ + if (user_chanlist) { + /* load channel/gain list */ + ret = __comedi_get_user_chanlist(dev, s, user_chanlist, &cmd); + if (ret) + return ret; + } ret = s->do_cmdtest(dev, s, &cmd); + kfree(cmd.chanlist); /* free kernel copy of user chanlist */ + /* restore chanlist pointer before copying back */ cmd.chanlist = (unsigned int __force *)user_chanlist; @@ -1642,7 +1644,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, */ -static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, +static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg, void *file) { int ret = 0; @@ -1679,7 +1681,7 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, This function isn't protected by the semaphore, since we already own the lock. */ -static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, +static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg, void *file) { struct comedi_subdevice *s; @@ -1714,7 +1716,7 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, nothing */ -static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, +static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg, void *file) { struct comedi_subdevice *s; @@ -1751,7 +1753,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, nothing */ -static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, +static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg, void *file) { struct comedi_subdevice *s; diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 32a19264a170..2a29b9baec0d 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1559,14 +1559,16 @@ static int mxs_lradc_probe(struct platform_device *pdev) /* Grab all IRQ sources */ for (i = 0; i < of_cfg->irq_count; i++) { lradc->irq[i] = platform_get_irq(pdev, i); - if (lradc->irq[i] < 0) - return lradc->irq[i]; + if (lradc->irq[i] < 0) { + ret = lradc->irq[i]; + goto err_clk; + } ret = devm_request_irq(dev, lradc->irq[i], mxs_lradc_handle_irq, 0, of_cfg->irq_name[i], iio); if (ret) - return ret; + goto err_clk; } lradc->vref_mv = of_cfg->vref_mv; @@ -1588,7 +1590,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) &mxs_lradc_trigger_handler, &mxs_lradc_buffer_ops); if (ret) - return ret; + goto err_clk; ret = mxs_lradc_trigger_init(iio); if (ret) @@ -1643,6 +1645,8 @@ err_dev: mxs_lradc_trigger_remove(iio); err_trig: iio_triggered_buffer_cleanup(iio); +err_clk: + clk_disable_unprepare(lradc->clk); return ret; } diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index d0c89d0457de..b6bd609c3655 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -115,6 +115,7 @@ static const struct iio_chan_spec ad5933_channels[] = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), .address = AD5933_REG_TEMP_DATA, + .scan_index = -1, .scan_type = { .sign = 's', .realbits = 14, @@ -124,9 +125,7 @@ static const struct iio_chan_spec ad5933_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .extend_name = "real_raw", - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SCALE), + .extend_name = "real", .address = AD5933_REG_REAL_DATA, .scan_index = 0, .scan_type = { @@ -138,9 +137,7 @@ static const struct iio_chan_spec ad5933_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .extend_name = "imag_raw", - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | - BIT(IIO_CHAN_INFO_SCALE), + .extend_name = "imag", .address = AD5933_REG_IMAG_DATA, .scan_index = 1, .scan_type = { @@ -749,14 +746,14 @@ static int ad5933_probe(struct i2c_client *client, indio_dev->name = id->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = ad5933_channels; - indio_dev->num_channels = 1; /* only register temp0_input */ + indio_dev->num_channels = ARRAY_SIZE(ad5933_channels); ret = ad5933_register_ring_funcs_and_init(indio_dev); if (ret) goto error_disable_reg; - /* skip temp0_input, register in0_(real|imag)_raw */ - ret = iio_buffer_register(indio_dev, &ad5933_channels[1], 2); + ret = iio_buffer_register(indio_dev, ad5933_channels, + ARRAY_SIZE(ad5933_channels)); if (ret) goto error_unreg_ring; diff --git a/drivers/staging/rtl8723au/include/rtw_eeprom.h b/drivers/staging/rtl8723au/include/rtw_eeprom.h index e5121a2a64b4..a86f36e49dd1 100644 --- a/drivers/staging/rtl8723au/include/rtw_eeprom.h +++ b/drivers/staging/rtl8723au/include/rtw_eeprom.h @@ -107,12 +107,12 @@ enum rt_customer_id }; struct eeprom_priv { + u8 mac_addr[6]; /* PermanentAddress */ u8 bautoload_fail_flag; u8 bloadfile_fail_flag; u8 bloadmac_fail_flag; /* u8 bempty; */ /* u8 sys_config; */ - u8 mac_addr[6]; /* PermanentAddress */ /* u8 config0; */ u16 channel_plan; /* u8 country_string[3]; */ diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3df5005c554d..9bdc6bd73432 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -742,7 +742,6 @@ static int ci_hdrc_remove(struct platform_device *pdev) ci_role_destroy(ci); ci_hdrc_enter_lpm(ci, true); usb_phy_shutdown(ci->transceiver); - kfree(ci->hw_bank.regmap); return 0; } diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index bf015ab3b44c..55c90c53f2d6 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -619,7 +619,7 @@ struct dwc2_hsotg { unsigned port_suspend_change:1; unsigned port_over_current_change:1; unsigned port_l1_change:1; - unsigned reserved:26; + unsigned reserved:25; } b; } flags; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 7b5856fadd93..eee87098bb8b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2561,8 +2561,10 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, hs_ep->fifo_size = val; break; } - if (i == 8) - return -ENOMEM; + if (i == 8) { + ret = -ENOMEM; + goto error; + } } /* for non control endpoints, set PID to D0 */ @@ -2579,6 +2581,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, /* enable the endpoint interrupt */ s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); +error: spin_unlock_irqrestore(&hsotg->lock, flags); return ret; } @@ -2934,9 +2937,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, spin_lock_irqsave(&hsotg->lock, flags); - if (!driver) - hsotg->driver = NULL; - + hsotg->driver = NULL; hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); @@ -3567,6 +3568,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum); /* disable power and clock */ + s3c_hsotg_phy_disable(hsotg); ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3575,8 +3577,6 @@ static int s3c_hsotg_probe(struct platform_device *pdev) goto err_ep_mem; } - s3c_hsotg_phy_disable(hsotg); - ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget); if (ret) goto err_ep_mem; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 2f537d588225..a0aa9f3da441 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -597,7 +597,7 @@ static int dwc3_omap_prepare(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); - dwc3_omap_write_irqmisc_set(omap, 0x00); + dwc3_omap_disable_irqs(omap); return 0; } @@ -605,19 +605,8 @@ static int dwc3_omap_prepare(struct device *dev) static void dwc3_omap_complete(struct device *dev) { struct dwc3_omap *omap = dev_get_drvdata(dev); - u32 reg; - reg = (USBOTGSS_IRQMISC_OEVT | - USBOTGSS_IRQMISC_DRVVBUS_RISE | - USBOTGSS_IRQMISC_CHRGVBUS_RISE | - USBOTGSS_IRQMISC_DISCHRGVBUS_RISE | - USBOTGSS_IRQMISC_IDPULLUP_RISE | - USBOTGSS_IRQMISC_DRVVBUS_FALL | - USBOTGSS_IRQMISC_CHRGVBUS_FALL | - USBOTGSS_IRQMISC_DISCHRGVBUS_FALL | - USBOTGSS_IRQMISC_IDPULLUP_FALL); - - dwc3_omap_write_irqmisc_set(omap, reg); + dwc3_omap_enable_irqs(omap); } static int dwc3_omap_suspend(struct device *dev) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 436fb08c40b8..a36cf66302fb 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -30,6 +30,7 @@ #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e +#define PCI_DEVICE_ID_INTEL_BSW 0x22B7 struct dwc3_pci { struct device *dev; @@ -181,6 +182,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, { } /* Terminating Entry */ diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index b35938777dde..711b23019d54 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -256,7 +256,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) /* stall is always issued on EP0 */ dep = dwc->eps[0]; - __dwc3_gadget_ep_set_halt(dep, 1); + __dwc3_gadget_ep_set_halt(dep, 1, false); dep->flags = DWC3_EP_ENABLED; dwc->delayed_status = false; @@ -271,7 +271,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) dwc3_ep0_out_start(dwc); } -int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) +int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) { struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; @@ -281,6 +281,20 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) return 0; } +int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) +{ + struct dwc3_ep *dep = to_dwc3_ep(ep); + struct dwc3 *dwc = dep->dwc; + unsigned long flags; + int ret; + + spin_lock_irqsave(&dwc->lock, flags); + ret = __dwc3_gadget_ep0_set_halt(ep, value); + spin_unlock_irqrestore(&dwc->lock, flags); + + return ret; +} + void dwc3_ep0_out_start(struct dwc3 *dwc) { int ret; @@ -466,7 +480,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, return -EINVAL; if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) break; - ret = __dwc3_gadget_ep_set_halt(dep, set); + ret = __dwc3_gadget_ep_set_halt(dep, set, true); if (ret) return -EINVAL; break; @@ -775,9 +789,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; - r = next_request(&ep0->request_list); - ur = &r->request; - trb = dwc->ep0_trb; status = DWC3_TRB_SIZE_TRBSTS(trb->size); @@ -790,6 +801,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, return; } + r = next_request(&ep0->request_list); + if (!r) + return; + + ur = &r->request; + length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { @@ -811,12 +828,19 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, dwc3_ep0_stall_and_restart(dwc); } else { - /* - * handle the case where we have to send a zero packet. This - * seems to be case when req.length > maxpacket. Could it be? - */ - if (r) - dwc3_gadget_giveback(ep0, r, 0); + dwc3_gadget_giveback(ep0, r, 0); + + if (IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) && + ur->length && ur->zero) { + int ret; + + dwc->ep0_next_event = DWC3_EP0_COMPLETE; + + ret = dwc3_ep0_start_trans(dwc, epnum, + dwc->ctrl_req_addr, 0, + DWC3_TRBCTL_CONTROL_DATA); + WARN_ON(ret < 0); + } } } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3818b26bfc05..546ea5431b8c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -525,12 +525,11 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, if (!usb_endpoint_xfer_isoc(desc)) return 0; - memset(&trb_link, 0, sizeof(trb_link)); - /* Link TRB for ISOC. The HWO bit is never reset */ trb_st_hw = &dep->trb_pool[0]; trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1]; + memset(trb_link, 0, sizeof(*trb_link)); trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); @@ -581,7 +580,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) /* make sure HW endpoint isn't stalled */ if (dep->flags & DWC3_EP_STALL) - __dwc3_gadget_ep_set_halt(dep, 0); + __dwc3_gadget_ep_set_halt(dep, 0, false); reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); reg &= ~DWC3_DALEPENA_EP(dep->number); @@ -1202,15 +1201,28 @@ out0: return ret; } -int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) +int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) { struct dwc3_gadget_ep_cmd_params params; struct dwc3 *dwc = dep->dwc; int ret; + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); + return -EINVAL; + } + memset(¶ms, 0x00, sizeof(params)); if (value) { + if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) || + (!list_empty(&dep->req_queued) || + !list_empty(&dep->request_list)))) { + dev_dbg(dwc->dev, "%s: pending request, cannot halt\n", + dep->name); + return -EAGAIN; + } + ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_SETSTALL, ¶ms); if (ret) @@ -1241,15 +1253,7 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) int ret; spin_lock_irqsave(&dwc->lock, flags); - - if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { - dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); - ret = -EINVAL; - goto out; - } - - ret = __dwc3_gadget_ep_set_halt(dep, value); -out: + ret = __dwc3_gadget_ep_set_halt(dep, value, false); spin_unlock_irqrestore(&dwc->lock, flags); return ret; @@ -1260,15 +1264,18 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) struct dwc3_ep *dep = to_dwc3_ep(ep); struct dwc3 *dwc = dep->dwc; unsigned long flags; + int ret; spin_lock_irqsave(&dwc->lock, flags); dep->flags |= DWC3_EP_WEDGE; - spin_unlock_irqrestore(&dwc->lock, flags); if (dep->number == 0 || dep->number == 1) - return dwc3_gadget_ep0_set_halt(ep, 1); + ret = __dwc3_gadget_ep0_set_halt(ep, 1); else - return dwc3_gadget_ep_set_halt(ep, 1); + ret = __dwc3_gadget_ep_set_halt(dep, 1, false); + spin_unlock_irqrestore(&dwc->lock, flags); + + return ret; } /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 178ad8982206..18ae3eaa8b6f 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -82,10 +82,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); void dwc3_ep0_out_start(struct dwc3 *dwc); +int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags); -int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); +int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol); /** * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 78aff1da089a..60b0f41eafc4 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -73,15 +73,23 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl, TP_PROTO(struct usb_ctrlrequest *ctrl), TP_ARGS(ctrl), TP_STRUCT__entry( - __field(struct usb_ctrlrequest *, ctrl) + __field(__u8, bRequestType) + __field(__u8, bRequest) + __field(__le16, wValue) + __field(__le16, wIndex) + __field(__le16, wLength) ), TP_fast_assign( - __entry->ctrl = ctrl; + __entry->bRequestType = ctrl->bRequestType; + __entry->bRequest = ctrl->bRequest; + __entry->wValue = ctrl->wValue; + __entry->wIndex = ctrl->wIndex; + __entry->wLength = ctrl->wLength; ), TP_printk("bRequestType %02x bRequest %02x wValue %04x wIndex %04x wLength %d", - __entry->ctrl->bRequestType, __entry->ctrl->bRequest, - le16_to_cpu(__entry->ctrl->wValue), le16_to_cpu(__entry->ctrl->wIndex), - le16_to_cpu(__entry->ctrl->wLength) + __entry->bRequestType, __entry->bRequest, + le16_to_cpu(__entry->wValue), le16_to_cpu(__entry->wIndex), + le16_to_cpu(__entry->wLength) ) ); @@ -94,15 +102,22 @@ DECLARE_EVENT_CLASS(dwc3_log_request, TP_PROTO(struct dwc3_request *req), TP_ARGS(req), TP_STRUCT__entry( + __dynamic_array(char, name, DWC3_MSG_MAX) __field(struct dwc3_request *, req) + __field(unsigned, actual) + __field(unsigned, length) + __field(int, status) ), TP_fast_assign( + snprintf(__get_str(name), DWC3_MSG_MAX, "%s", req->dep->name); __entry->req = req; + __entry->actual = req->request.actual; + __entry->length = req->request.length; + __entry->status = req->request.status; ), TP_printk("%s: req %p length %u/%u ==> %d", - __entry->req->dep->name, __entry->req, - __entry->req->request.actual, __entry->req->request.length, - __entry->req->request.status + __get_str(name), __entry->req, __entry->actual, __entry->length, + __entry->status ) ); @@ -158,17 +173,17 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, struct dwc3_gadget_ep_cmd_params *params), TP_ARGS(dep, cmd, params), TP_STRUCT__entry( - __field(struct dwc3_ep *, dep) + __dynamic_array(char, name, DWC3_MSG_MAX) __field(unsigned int, cmd) __field(struct dwc3_gadget_ep_cmd_params *, params) ), TP_fast_assign( - __entry->dep = dep; + snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); __entry->cmd = cmd; __entry->params = params; ), TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x\n", - __entry->dep->name, dwc3_gadget_ep_cmd_string(__entry->cmd), + __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), __entry->cmd, __entry->params->param0, __entry->params->param1, __entry->params->param2 ) @@ -184,16 +199,24 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), TP_ARGS(dep, trb), TP_STRUCT__entry( - __field(struct dwc3_ep *, dep) + __dynamic_array(char, name, DWC3_MSG_MAX) __field(struct dwc3_trb *, trb) + __field(u32, bpl) + __field(u32, bph) + __field(u32, size) + __field(u32, ctrl) ), TP_fast_assign( - __entry->dep = dep; + snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); __entry->trb = trb; + __entry->bpl = trb->bpl; + __entry->bph = trb->bph; + __entry->size = trb->size; + __entry->ctrl = trb->ctrl; ), TP_printk("%s: trb %p bph %08x bpl %08x size %08x ctrl %08x\n", - __entry->dep->name, __entry->trb, __entry->trb->bph, - __entry->trb->bpl, __entry->trb->size, __entry->trb->ctrl + __get_str(name), __entry->trb, __entry->bph, __entry->bpl, + __entry->size, __entry->ctrl ) ); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a8c18df171c3..f6a51fddd5b5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -560,7 +560,7 @@ static int bos_desc(struct usb_composite_dev *cdev) usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; - usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT); + usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | USB_BESL_SUPPORT); /* * The Superspeed USB Capability descriptor shall be implemented by all diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 6da4685490ef..aad8165e98ef 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -433,12 +433,12 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) dev_vdbg(&cdev->gadget->dev, "reset acm control interface %d\n", intf); usb_ep_disable(acm->notify); - } else { - dev_vdbg(&cdev->gadget->dev, - "init acm ctrl interface %d\n", intf); + } + + if (!acm->notify->desc) if (config_ep_by_speed(cdev->gadget, f, acm->notify)) return -EINVAL; - } + usb_ep_enable(acm->notify); acm->notify->driver_data = acm; diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index 4d8b236ea608..c9e90de5bdd9 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -325,7 +325,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - usb_free_all_descriptors(f); if (eem->port.out_ep) eem->port.out_ep->driver_data = NULL; if (eem->port.in_ep) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 7c6771d027a2..63314ede7ba6 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -647,15 +647,26 @@ static void ffs_user_copy_worker(struct work_struct *work) if (io_data->read && ret > 0) { int i; size_t pos = 0; + + /* + * Since req->length may be bigger than io_data->len (after + * being rounded up to maxpacketsize), we may end up with more + * data then user space has space for. + */ + ret = min_t(int, ret, io_data->len); + use_mm(io_data->mm); for (i = 0; i < io_data->nr_segs; i++) { + size_t len = min_t(size_t, ret - pos, + io_data->iovec[i].iov_len); + if (!len) + break; if (unlikely(copy_to_user(io_data->iovec[i].iov_base, - &io_data->buf[pos], - io_data->iovec[i].iov_len))) { + &io_data->buf[pos], len))) { ret = -EFAULT; break; } - pos += io_data->iovec[i].iov_len; + pos += len; } unuse_mm(io_data->mm); } @@ -687,7 +698,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) struct ffs_epfile *epfile = file->private_data; struct ffs_ep *ep; char *data = NULL; - ssize_t ret, data_len; + ssize_t ret, data_len = -EINVAL; int halt; /* Are we still active? */ @@ -787,13 +798,30 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) /* Fire the request */ struct usb_request *req; + /* + * Sanity Check: even though data_len can't be used + * uninitialized at the time I write this comment, some + * compilers complain about this situation. + * In order to keep the code clean from warnings, data_len is + * being initialized to -EINVAL during its declaration, which + * means we can't rely on compiler anymore to warn no future + * changes won't result in data_len being used uninitialized. + * For such reason, we're adding this redundant sanity check + * here. + */ + if (unlikely(data_len == -EINVAL)) { + WARN(1, "%s: data_len == -EINVAL\n", __func__); + ret = -EINVAL; + goto error_lock; + } + if (io_data->aio) { req = usb_ep_alloc_request(ep->ep, GFP_KERNEL); if (unlikely(!req)) goto error_lock; req->buf = data; - req->length = io_data->len; + req->length = data_len; io_data->buf = data; io_data->ep = ep->ep; @@ -815,7 +843,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) req = ep->req; req->buf = data; - req->length = io_data->len; + req->length = data_len; req->context = &done; req->complete = ffs_epfile_io_complete; @@ -2663,8 +2691,6 @@ static inline struct f_fs_opts *ffs_do_functionfs_bind(struct usb_function *f, func->conf = c; func->gadget = c->cdev->gadget; - ffs_data_get(func->ffs); - /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index a95290a1289f..59ab62c92b66 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -621,12 +621,14 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) dev = MKDEV(major, hidg->minor); status = cdev_add(&hidg->cdev, dev, 1); if (status) - goto fail; + goto fail_free_descs; device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor); return 0; +fail_free_descs: + usb_free_all_descriptors(f); fail: ERROR(f->config->cdev, "hidg_bind FAILED\n"); if (hidg->req != NULL) { @@ -635,7 +637,6 @@ fail: usb_ep_free_request(hidg->in_ep, hidg->req); } - usb_free_all_descriptors(f); return status; } diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index bf04389137e6..298b46112b1a 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -253,22 +253,13 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion? */ if (ep == loop->out_ep) { - /* loop this OUT packet back IN to the host */ req->zero = (req->actual < req->length); req->length = req->actual; - status = usb_ep_queue(loop->in_ep, req, GFP_ATOMIC); - if (status == 0) - return; - - /* "should never get here" */ - ERROR(cdev, "can't loop %s to %s: %d\n", - ep->name, loop->in_ep->name, - status); } /* queue the buffer for some later OUT packet */ req->length = buflen; - status = usb_ep_queue(loop->out_ep, req, GFP_ATOMIC); + status = usb_ep_queue(ep, req, GFP_ATOMIC); if (status == 0) return; @@ -308,60 +299,66 @@ static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) return alloc_ep_req(ep, len, buflen); } -static int -enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) +static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop, + struct usb_ep *ep) { - int result = 0; - struct usb_ep *ep; struct usb_request *req; unsigned i; + int result; - /* one endpoint writes data back IN to the host */ - ep = loop->in_ep; - result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); - if (result) - return result; - result = usb_ep_enable(ep); - if (result < 0) - return result; - ep->driver_data = loop; - - /* one endpoint just reads OUT packets */ - ep = loop->out_ep; + /* + * one endpoint writes data back IN to the host while another endpoint + * just reads OUT packets + */ result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); if (result) goto fail0; - result = usb_ep_enable(ep); - if (result < 0) { -fail0: - ep = loop->in_ep; - usb_ep_disable(ep); - ep->driver_data = NULL; - return result; - } + if (result < 0) + goto fail0; ep->driver_data = loop; - /* allocate a bunch of read buffers and queue them all at once. + /* + * allocate a bunch of read buffers and queue them all at once. * we buffer at most 'qlen' transfers; fewer if any need more * than 'buflen' bytes each. */ for (i = 0; i < qlen && result == 0; i++) { req = lb_alloc_ep_req(ep, 0); - if (req) { - req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); - if (result) - ERROR(cdev, "%s queue req --> %d\n", - ep->name, result); - } else { - usb_ep_disable(ep); - ep->driver_data = NULL; - result = -ENOMEM; - goto fail0; + if (!req) + goto fail1; + + req->complete = loopback_complete; + result = usb_ep_queue(ep, req, GFP_ATOMIC); + if (result) { + ERROR(cdev, "%s queue req --> %d\n", + ep->name, result); + goto fail1; } } + return 0; + +fail1: + usb_ep_disable(ep); + +fail0: + return result; +} + +static int +enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) +{ + int result = 0; + + result = enable_endpoint(cdev, loop, loop->in_ep); + if (result) + return result; + + result = enable_endpoint(cdev, loop, loop->out_ep); + if (result) + return result; + DBG(cdev, "%s enabled\n", loop->function.name); return result; } diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 146f48cc65d7..16361b0a8b46 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1461,7 +1461,6 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - usb_free_all_descriptors(f); if (ncm->notify_req) { kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index 5f40080c92cc..a1b79c53499c 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -35,6 +35,7 @@ struct f_obex { struct gserial port; u8 ctrl_id; u8 data_id; + u8 cur_alt; u8 port_num; u8 can_activate; }; @@ -235,6 +236,8 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else goto fail; + obex->cur_alt = alt; + return 0; fail: @@ -245,10 +248,7 @@ static int obex_get_alt(struct usb_function *f, unsigned intf) { struct f_obex *obex = func_to_obex(f); - if (intf == obex->ctrl_id) - return 0; - - return obex->port.in->driver_data ? 1 : 0; + return obex->cur_alt; } static void obex_disable(struct usb_function *f) @@ -397,7 +397,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - usb_free_all_descriptors(f); /* we might as well release our claims on endpoints */ if (obex->port.out) obex->port.out->driver_data = NULL; diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index b9cfc1571d71..1ec8b7ffdccd 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -570,8 +570,8 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f) err_req: for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); -err: usb_free_all_descriptors(f); +err: if (fp->out_ep) fp->out_ep->driver_data = NULL; if (fp->in_ep) diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index ddb09dc6d1f2..f13fc6a58565 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -802,8 +802,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (rndis->manufacturer && rndis->vendorID && rndis_set_param_vendor(rndis->config, rndis->vendorID, - rndis->manufacturer)) - goto fail; + rndis->manufacturer)) { + status = -EINVAL; + goto fail_free_descs; + } /* NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code @@ -817,10 +819,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis->notify->name); return 0; +fail_free_descs: + usb_free_all_descriptors(f); fail: kfree(f->os_desc_table); f->os_desc_n = 0; - usb_free_all_descriptors(f); if (rndis->notify_req) { kfree(rndis->notify_req->buf); diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 1ea8baf33333..e3dfa675ff06 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -380,7 +380,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - usb_free_all_descriptors(f); /* we might as well release our claims on endpoints */ if (geth->port.out_ep) geth->port.out_ep->driver_data = NULL; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index a5a27a504d67..33e16658e5cf 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -512,6 +512,11 @@ static int snd_uac2_remove(struct platform_device *pdev) return 0; } +static void snd_uac2_release(struct device *dev) +{ + dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); +} + static int alsa_uac2_init(struct audio_dev *agdev) { struct snd_uac2_chip *uac2 = &agdev->uac2; @@ -523,6 +528,7 @@ static int alsa_uac2_init(struct audio_dev *agdev) uac2->pdev.id = 0; uac2->pdev.name = uac2_name; + uac2->pdev.dev.release = snd_uac2_release; /* Register snd_uac2 driver */ err = platform_driver_register(&uac2->pdrv); @@ -772,6 +778,7 @@ struct usb_endpoint_descriptor fs_epout_desc = { .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .wMaxPacketSize = cpu_to_le16(1023), .bInterval = 1, }; @@ -780,6 +787,7 @@ struct usb_endpoint_descriptor hs_epout_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .wMaxPacketSize = cpu_to_le16(1024), .bInterval = 4, }; @@ -847,6 +855,7 @@ struct usb_endpoint_descriptor fs_epin_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .wMaxPacketSize = cpu_to_le16(1023), .bInterval = 1, }; @@ -855,6 +864,7 @@ struct usb_endpoint_descriptor hs_epin_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .wMaxPacketSize = cpu_to_le16(1024), .bInterval = 4, }; @@ -947,6 +957,9 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep) struct snd_uac2_chip *uac2 = prm->uac2; int i; + if (!prm->ep_enabled) + return; + prm->ep_enabled = false; for (i = 0; i < USB_XFERS; i++) { @@ -1071,7 +1084,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); if (!prm->rbuf) { prm->max_psize = 0; - goto err; + goto err_free_descs; } prm = &agdev->uac2.p_prm; @@ -1079,17 +1092,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); if (!prm->rbuf) { prm->max_psize = 0; - goto err; + goto err_free_descs; } ret = alsa_uac2_init(agdev); if (ret) - goto err; + goto err_free_descs; return 0; + +err_free_descs: + usb_free_all_descriptors(fn); err: kfree(agdev->uac2.p_prm.rbuf); kfree(agdev->uac2.c_prm.rbuf); - usb_free_all_descriptors(fn); if (agdev->in_ep) agdev->in_ep->driver_data = NULL; if (agdev->out_ep) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index e126439e4b65..945b3bd2ca98 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -279,27 +279,41 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface) else if (interface != uvc->streaming_intf) return -EINVAL; else - return uvc->state == UVC_STATE_STREAMING ? 1 : 0; + return uvc->video.ep->driver_data ? 1 : 0; } static int uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) { struct uvc_device *uvc = to_uvc(f); + struct usb_composite_dev *cdev = f->config->cdev; struct v4l2_event v4l2_event; struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; int ret; - INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); + INFO(cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); if (interface == uvc->control_intf) { if (alt) return -EINVAL; + if (uvc->control_ep->driver_data) { + INFO(cdev, "reset UVC Control\n"); + usb_ep_disable(uvc->control_ep); + uvc->control_ep->driver_data = NULL; + } + + if (!uvc->control_ep->desc) + if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep)) + return -EINVAL; + + usb_ep_enable(uvc->control_ep); + uvc->control_ep->driver_data = uvc; + if (uvc->state == UVC_STATE_DISCONNECTED) { memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_CONNECT; - uvc_event->speed = f->config->cdev->gadget->speed; + uvc_event->speed = cdev->gadget->speed; v4l2_event_queue(uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_CONNECTED; @@ -321,8 +335,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (uvc->state != UVC_STATE_STREAMING) return 0; - if (uvc->video.ep) + if (uvc->video.ep) { usb_ep_disable(uvc->video.ep); + uvc->video.ep->driver_data = NULL; + } memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMOFF; @@ -335,14 +351,22 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (uvc->state != UVC_STATE_CONNECTED) return 0; - if (uvc->video.ep) { - ret = config_ep_by_speed(f->config->cdev->gadget, - &(uvc->func), uvc->video.ep); - if (ret) - return ret; - usb_ep_enable(uvc->video.ep); + if (!uvc->video.ep) + return -EINVAL; + + if (uvc->video.ep->driver_data) { + INFO(cdev, "reset UVC\n"); + usb_ep_disable(uvc->video.ep); + uvc->video.ep->driver_data = NULL; } + ret = config_ep_by_speed(f->config->cdev->gadget, + &(uvc->func), uvc->video.ep); + if (ret) + return ret; + usb_ep_enable(uvc->video.ep); + uvc->video.ep->driver_data = uvc; + memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; v4l2_event_queue(uvc->vdev, &v4l2_event); @@ -366,6 +390,16 @@ uvc_function_disable(struct usb_function *f) v4l2_event_queue(uvc->vdev, &v4l2_event); uvc->state = UVC_STATE_DISCONNECTED; + + if (uvc->video.ep->driver_data) { + usb_ep_disable(uvc->video.ep); + uvc->video.ep->driver_data = NULL; + } + + if (uvc->control_ep->driver_data) { + usb_ep_disable(uvc->control_ep); + uvc->control_ep->driver_data = NULL; + } } /* -------------------------------------------------------------------------- diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index c3e1f27dbbef..9cb86bc1a9a5 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -352,7 +352,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable) if (!enable) { for (i = 0; i < UVC_NUM_REQUESTS; ++i) - usb_ep_dequeue(video->ep, video->req[i]); + if (video->req[i]) + usb_ep_dequeue(video->ep, video->req[i]); uvc_video_free_requests(video); uvcg_queue_enable(&video->queue, 0); diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 3ea287b0e448..217365d35a25 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -357,6 +357,7 @@ config USB_EG20T config USB_GADGET_XILINX tristate "Xilinx USB Driver" + depends on HAS_DMA depends on OF || COMPILE_TEST help USB peripheral controller driver for Xilinx USB2 device. diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f107bb60a5ab..f2054659f25b 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -507,6 +507,11 @@ static ssize_t usb_udc_softconn_store(struct device *dev, { struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + if (!udc->driver) { + dev_err(dev, "soft-connect without a gadget driver\n"); + return -EOPNOTSUPP; + } + if (sysfs_streq(buf, "connect")) { usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index acdfb3e68a90..5a9b977fbc19 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -209,7 +209,8 @@ static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) } } - if (!list_empty(&controller->early_tx_list)) { + if (!list_empty(&controller->early_tx_list) && + !hrtimer_is_queued(&controller->early_tx)) { ret = HRTIMER_RESTART; hrtimer_forward_now(&controller->early_tx, ktime_set(0, 20 * NSEC_PER_USEC)); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 154bcf1b5dfa..48bc09e7b83b 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -868,9 +868,15 @@ static int dsps_suspend(struct device *dev) struct dsps_glue *glue = dev_get_drvdata(dev); const struct dsps_musb_wrapper *wrp = glue->wrp; struct musb *musb = platform_get_drvdata(glue->musb); - void __iomem *mbase = musb->ctrl_base; + void __iomem *mbase; del_timer_sync(&glue->timer); + + if (!musb) + /* This can happen if the musb device is in -EPROBE_DEFER */ + return 0; + + mbase = musb->ctrl_base; glue->context.control = dsps_readl(mbase, wrp->control); glue->context.epintr = dsps_readl(mbase, wrp->epintr_set); glue->context.coreintr = dsps_readl(mbase, wrp->coreintr_set); @@ -887,8 +893,12 @@ static int dsps_resume(struct device *dev) struct dsps_glue *glue = dev_get_drvdata(dev); const struct dsps_musb_wrapper *wrp = glue->wrp; struct musb *musb = platform_get_drvdata(glue->musb); - void __iomem *mbase = musb->ctrl_base; + void __iomem *mbase; + if (!musb) + return 0; + + mbase = musb->ctrl_base; dsps_writel(mbase, wrp->control, glue->context.control); dsps_writel(mbase, wrp->epintr_set, glue->context.epintr); dsps_writel(mbase, wrp->coreintr_set, glue->context.coreintr); @@ -896,7 +906,9 @@ static int dsps_resume(struct device *dev) dsps_writel(mbase, wrp->mode, glue->context.mode); dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode); dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode); - setup_timer(&glue->timer, otg_timer, (unsigned long) musb); + if (musb->xceiv->state == OTG_STATE_B_IDLE && + musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) + mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); return 0; } diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index eca1747ca8c7..cfd009dc4018 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -155,6 +155,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ + { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dc72b924c399..0dad8ce5a609 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -140,6 +140,7 @@ static struct ftdi_sio_quirk ftdi_8u2232c_quirk = { * /sys/bus/usb-serial/drivers/ftdi_sio/new_id and send a patch or report. */ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(FTDI_VID, FTDI_BRICK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, @@ -661,6 +662,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5937b2d242f2..6786b705ccf6 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -30,6 +30,12 @@ /*** third-party PIDs (using FTDI_VID) ***/ +/* + * Certain versions of the official Windows FTDI driver reprogrammed + * counterfeit FTDI devices to PID 0. Support these devices anyway. + */ +#define FTDI_BRICK_PID 0x0000 + #define FTDI_LUMEL_PD12_PID 0x6002 /* @@ -143,8 +149,12 @@ * Xsens Technologies BV products (http://www.xsens.com). */ #define XSENS_VID 0x2639 -#define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ +#define XSENS_AWINDA_STATION_PID 0x0101 +#define XSENS_AWINDA_DONGLE_PID 0x0102 #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ +#define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ + +/* Xsens devices using FTDI VID */ #define XSENS_CONVERTER_0_PID 0xD388 /* Xsens USB converter */ #define XSENS_CONVERTER_1_PID 0xD389 /* Xsens Wireless Receiver */ #define XSENS_CONVERTER_2_PID 0xD38A diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 078f9ed419c8..3d2bd65df0fc 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -414,8 +414,6 @@ static int kobil_tiocmset(struct tty_struct *tty, int result; int dtr = 0; int rts = 0; - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; /* FIXME: locking ? */ priv = usb_get_serial_port_data(port); @@ -425,11 +423,6 @@ static int kobil_tiocmset(struct tty_struct *tty, return -EINVAL; } - /* allocate memory for transfer buffer */ - transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOMEM; - if (set & TIOCM_RTS) rts = 1; if (set & TIOCM_DTR) @@ -469,7 +462,6 @@ static int kobil_tiocmset(struct tty_struct *tty, KOBIL_TIMEOUT); } dev_dbg(dev, "%s - Send set_status_line URB returns: %i\n", __func__, result); - kfree(transfer_buffer); return (result < 0) ? result : 0; } @@ -530,8 +522,6 @@ static int kobil_ioctl(struct tty_struct *tty, { struct usb_serial_port *port = tty->driver_data; struct kobil_private *priv = usb_get_serial_port_data(port); - unsigned char *transfer_buffer; - int transfer_buffer_length = 8; int result; if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || @@ -541,10 +531,6 @@ static int kobil_ioctl(struct tty_struct *tty, switch (cmd) { case TCFLSH: - transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOBUFS; - result = usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0), SUSBCRequest_Misc, @@ -559,7 +545,6 @@ static int kobil_ioctl(struct tty_struct *tty, dev_dbg(&port->dev, "%s - Send reset_all_queues (FLUSH) URB returns: %i\n", __func__, result); - kfree(transfer_buffer); return (result < 0) ? -EIO: 0; default: return -ENOIOCTLCMD; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d1a3f6044c8a..7a4c21b4f676 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -269,6 +269,7 @@ static void option_instat_callback(struct urb *urb); #define TELIT_PRODUCT_DE910_DUAL 0x1010 #define TELIT_PRODUCT_UE910_V2 0x1012 #define TELIT_PRODUCT_LE920 0x1200 +#define TELIT_PRODUCT_LE910 0x1201 /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 @@ -362,6 +363,7 @@ static void option_instat_callback(struct urb *urb); /* Haier products */ #define HAIER_VENDOR_ID 0x201e +#define HAIER_PRODUCT_CE81B 0x10f8 #define HAIER_PRODUCT_CE100 0x2009 /* Cinterion (formerly Siemens) products */ @@ -589,6 +591,11 @@ static const struct option_blacklist_info zte_1255_blacklist = { .reserved = BIT(3) | BIT(4), }; +static const struct option_blacklist_info telit_le910_blacklist = { + .sendsetup = BIT(0), + .reserved = BIT(1) | BIT(2), +}; + static const struct option_blacklist_info telit_le920_blacklist = { .sendsetup = BIT(0), .reserved = BIT(1) | BIT(5), @@ -1138,6 +1145,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), + .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ @@ -1621,6 +1630,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, + { USB_DEVICE_AND_INTERFACE_INFO(HAIER_VENDOR_ID, HAIER_PRODUCT_CE81B, 0xff, 0xff, 0xff) }, /* Pirelli */ { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2, 0xff) }, diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 57b1d44acbfe..eb976ee3a02f 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -448,8 +448,10 @@ static int __init fb_console_setup(char *this_opt) return 1; while ((options = strsep(&this_opt, ",")) != NULL) { - if (!strncmp(options, "font:", 5)) + if (!strncmp(options, "font:", 5)) { strlcpy(fontname, options + 5, sizeof(fontname)); + continue; + } if (!strncmp(options, "scrollback:", 11)) { options += 11; @@ -457,13 +459,9 @@ static int __init fb_console_setup(char *this_opt) fbcon_softback_size = simple_strtoul(options, &options, 0); if (*options == 'k' || *options == 'K') { fbcon_softback_size *= 1024; - options++; } - if (*options != ',') - return 1; - options++; - } else - return 1; + } + continue; } if (!strncmp(options, "map:", 4)) { @@ -478,8 +476,7 @@ static int __init fb_console_setup(char *this_opt) fbcon_map_override(); } - - return 1; + continue; } if (!strncmp(options, "vc:", 3)) { @@ -491,7 +488,8 @@ static int __init fb_console_setup(char *this_opt) if (*options++ == '-') last_fb_vc = simple_strtoul(options, &options, 10) - 1; fbcon_is_default = 0; - } + continue; + } if (!strncmp(options, "rotate:", 7)) { options += 7; @@ -499,6 +497,7 @@ static int __init fb_console_setup(char *this_opt) initial_rotation = simple_strtoul(options, &options, 0); if (initial_rotation > 3) initial_rotation = 0; + continue; } } return 1; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 6e6aa704fe84..517f565b65d7 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -56,7 +56,7 @@ static int cursor_size_lastfrom; static int cursor_size_lastto; static u32 vgacon_xres; static u32 vgacon_yres; -static struct vgastate state; +static struct vgastate vgastate; #define BLANK 0x0020 @@ -400,7 +400,7 @@ static const char *vgacon_startup(void) vga_video_num_lines = screen_info.orig_video_lines; vga_video_num_columns = screen_info.orig_video_cols; - state.vgabase = NULL; + vgastate.vgabase = NULL; if (screen_info.orig_video_mode == 7) { /* Monochrome display */ @@ -851,12 +851,12 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table) { int i, j; - vga_w(state.vgabase, VGA_PEL_MSK, 0xff); + vga_w(vgastate.vgabase, VGA_PEL_MSK, 0xff); for (i = j = 0; i < 16; i++) { - vga_w(state.vgabase, VGA_PEL_IW, table[i]); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); - vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_IW, table[i]); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); + vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); } } @@ -1008,7 +1008,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) switch (blank) { case 0: /* Unblank */ if (vga_vesa_blanked) { - vga_vesa_unblank(&state); + vga_vesa_unblank(&vgastate); vga_vesa_blanked = 0; } if (vga_palette_blanked) { @@ -1022,7 +1022,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) case 1: /* Normal blanking */ case -1: /* Obsolete */ if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { - vga_pal_blank(&state); + vga_pal_blank(&vgastate); vga_palette_blanked = 1; return 0; } @@ -1034,7 +1034,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch) return 1; default: /* VESA blanking */ if (vga_video_type == VIDEO_TYPE_VGAC) { - vga_vesa_blank(&state, blank - 1); + vga_vesa_blank(&vgastate, blank - 1); vga_vesa_blanked = blank; } return 0; @@ -1280,7 +1280,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne (charcount != 256 && charcount != 512)) return -EINVAL; - rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); + rc = vgacon_do_font_op(&vgastate, font->data, 1, charcount == 512); if (rc) return rc; @@ -1299,7 +1299,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) font->charcount = vga_512_chars ? 512 : 256; if (!font->data) return 0; - return vgacon_do_font_op(&state, font->data, 0, vga_512_chars); + return vgacon_do_font_op(&vgastate, font->data, 0, vga_512_chars); } #else diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 3bf403150a2d..9ec81d46fc57 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -27,7 +27,6 @@ #include #include