Merge "msm: adsprpc: Fix array index underflow problem"
diff --git a/.gitignore b/.gitignore
index 4105cfb..667f544 100644
--- a/.gitignore
+++ b/.gitignore
@@ -118,3 +118,8 @@
# fetched Android config fragments
kernel/configs/android-*.cfg
+
+#
+#Ignoring Android.bp link file
+#
+Android.bp
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 4341e3a..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-cc_binary_host {
- name: "unifdef",
- srcs: ["scripts/unifdef.c"],
- sanitize: {
- never: true,
- }
-}
-
-gensrcs {
- name: "qseecom-kernel-includes",
-
- // move to out/ as root for header generation because of scripts/unifdef
- // storage - at the expense of extra ../ references
- cmd: "pushd out && mkdir -p scripts && rm -f scripts/unifdef && ln -s ../../$(location unifdef) scripts/unifdef && ../$(location scripts/headers_install.sh) `dirname ../$(out)` ../ $(in) && popd",
-
- tools: ["unifdef"],
- tool_files: ["scripts/headers_install.sh"],
- export_include_dirs: ["include/uapi"],
- srcs: ["include/uapi/linux/qseecom.h"],
- output_extension: "h",
-}
-
-cc_library_headers {
- name: "qseecom-kernel-headers",
- generated_headers: ["qseecom-kernel-includes"],
- export_generated_headers: ["qseecom-kernel-includes"],
-}
diff --git a/Androidbp b/Androidbp
new file mode 100644
index 0000000..1fd921a
--- /dev/null
+++ b/Androidbp
@@ -0,0 +1,45 @@
+cc_binary_host {
+ name: "unifdef",
+ srcs: ["scripts/unifdef.c"],
+ sanitize: {
+ never: true,
+ },
+}
+
+genrule {
+ name: "gen-headers_install.sh",
+ srcs: ["scripts/headers_install.sh"],
+ tools: ["unifdef"],
+ out: ["headers_install.sh"],
+ cmd: "sed 's+scripts/unifdef+$(location unifdef)+g' $(in) > $(out)",
+}
+
+cc_prebuilt_binary {
+ name: "headers_install.sh",
+ device_supported: false,
+ host_supported: true,
+ srcs: [":gen-headers_install.sh"],
+}
+
+// Use the following for verbose output from kernel_headers.py.
+// kernel_headers_verbose = "--verbose "
+// Use the following for minimal output from kernel_headers.py.
+kernel_headers_verbose = ""
+
+build = ["gen_headers_arm.bp", "gen_headers_arm64.bp"]
+
+cc_library_headers {
+ name: "qti_kernel_headers",
+ arch: {
+ arm: {
+ generated_headers: ["qti_generate_kernel_headers_arm"],
+ export_generated_headers: ["qti_generate_kernel_headers_arm"],
+ },
+ arm64: {
+ generated_headers: ["qti_generate_kernel_headers_arm64"],
+ export_generated_headers: ["qti_generate_kernel_headers_arm64"],
+ },
+ },
+ vendor: true,
+ recovery_available: true,
+}
diff --git a/Documentation/devicetree/bindings/drm/msm/sde-dp.txt b/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
index ada2eab..66a668f 100644
--- a/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
+++ b/Documentation/devicetree/bindings/drm/msm/sde-dp.txt
@@ -67,6 +67,7 @@
within DP AUX, while the remaining entries indicate the
programmable values.
- qcom,max-pclk-frequency-khz: An integer specifying the max. pixel clock in KHz supported by Display Port.
+- qcom,yuv-support: A boolean specifying if any YUV formats are supported by Display Port.
- qcom,dp-usbpd-detection: Phandle for the PMI regulator node for USB PHY PD detection.
- qcom,<type>-supply-entries: A node that lists the elements of the supply used by the a particular "type" of DSI module. The module "types"
can be "core", "ctrl", and "phy". Within the same type,
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
index df873d1..2aaae21 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt
@@ -110,6 +110,13 @@
Usage: required
Definition: See soc/fsl/qman.txt and soc/fsl/bman.txt
+- fsl,erratum-a050385
+ Usage: optional
+ Value type: boolean
+ Definition: A boolean property. Indicates the presence of the
+ erratum A050385 which indicates that DMA transactions that are
+ split can result in a FMan lock.
+
=============================================================================
FMan MURAM Node
diff --git a/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt b/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
index 4ef8d7a..a6b0cdd 100644
--- a/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/gdsc-regulator.txt
@@ -72,7 +72,9 @@
- qcom,en-rest-wait-val: Input value for EN_REST_WAIT controls state transition
delay after receiving ack signal (gds_enr_ack) from the
longest en_rest power switch chain.
-
+ - qcom,skip-disable-before-sw-enable: Presence denotes a hardware requirement
+ to leave the GDSC on that has been
+ enabled by an entity external to HLOS.
Example:
gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
compatible = "qcom,gdsc";
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 534ef89..7acf1f4 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -2152,8 +2152,11 @@
should comply with the wsa nodes configurations.
- qcom,wsa-aux-dev-prefix: This property contains list of wsa codec prefixes.
- qcom,tdm-i2s-switch-enable: For chipsets where tdm mics are controlled by
- switch, drive corresponding gpio to output high
- to enable switch.
+ switch, drive corresponding gpio to output high
+ to enable switch.
+- qcom,pdm-i2s-switch-enable: For chipsets where pdm mics are controlled by
+ switch, drive corresponding gpio to output high
+ to enable switch.
Example:
sound {
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index bdd025c..85ed345 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -596,3 +596,10 @@
[mandatory]
->rename() has an added flags argument. Any flags not handled by the
filesystem should result in EINVAL being returned.
+--
+[mandatory]
+
+ [should've been added in 2016] stale comment in finish_open()
+ nonwithstanding, failure exits in ->atomic_open() instances should
+ *NOT* fput() the file, no matter what. Everything is handled by the
+ caller.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 9b9c479..e988247 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -44,11 +44,10 @@
--- 6.11 Post-link pass
=== 7 Kbuild syntax for exported headers
- --- 7.1 header-y
- --- 7.2 genhdr-y
- --- 7.3 destination-y
- --- 7.4 generic-y
- --- 7.5 generated-y
+ --- 7.1 no-export-headers-y
+ --- 7.2 generic-y
+ --- 7.3 generated-y
+ --- 7.4 mandatory-y
=== 8 Kbuild Variables
=== 9 Makefile language
@@ -1236,7 +1235,7 @@
that may be shared between individual architectures.
The recommended approach how to use a generic header file is
to list the file in the Kbuild file.
- See "7.4 generic-y" for further info on syntax etc.
+ See "7.2 generic-y" for further info on syntax etc.
--- 6.11 Post-link pass
@@ -1263,53 +1262,21 @@
- drop include of compiler.h
- drop all sections that are kernel internal (guarded by ifdef __KERNEL__)
-Each relevant directory contains a file name "Kbuild" which specifies the
-headers to be exported.
+All headers under include/uapi/, include/generated/uapi/,
+arch/<arch>/include/uapi/ and arch/<arch>/include/generated/uapi/
+are exported.
+
+A Kbuild file may be defined under arch/<arch>/include/uapi/asm/ and
+arch/<arch>/include/asm/ to list asm files coming from asm-generic.
See subsequent chapter for the syntax of the Kbuild file.
- --- 7.1 header-y
+ --- 7.1 no-export-headers
- header-y specifies header files to be exported.
+ no-export-headers is essentially used by include/uapi/linux/Kbuild to
+ avoid exporting specific headers (e.g. kvm.h) on architectures that do
+ not support it. It should be avoided as much as possible.
- Example:
- #include/linux/Kbuild
- header-y += usb/
- header-y += aio_abi.h
-
- The convention is to list one file per line and
- preferably in alphabetic order.
-
- header-y also specifies which subdirectories to visit.
- A subdirectory is identified by a trailing '/' which
- can be seen in the example above for the usb subdirectory.
-
- Subdirectories are visited before their parent directories.
-
- --- 7.2 genhdr-y
-
- genhdr-y specifies generated files to be exported.
- Generated files are special as they need to be looked
- up in another directory when doing 'make O=...' builds.
-
- Example:
- #include/linux/Kbuild
- genhdr-y += version.h
-
- --- 7.3 destination-y
-
- When an architecture has a set of exported headers that needs to be
- exported to a different directory destination-y is used.
- destination-y specifies the destination directory for all exported
- headers in the file where it is present.
-
- Example:
- #arch/xtensa/platforms/s6105/include/platform/Kbuild
- destination-y := include/linux
-
- In the example above all exported headers in the Kbuild file
- will be located in the directory "include/linux" when exported.
-
- --- 7.4 generic-y
+ --- 7.2 generic-y
If an architecture uses a verbatim copy of a header from
include/asm-generic then this is listed in the file
@@ -1336,11 +1303,10 @@
Example: termios.h
#include <asm-generic/termios.h>
- --- 7.5 generated-y
+ --- 7.3 generated-y
If an architecture generates other header files alongside generic-y
- wrappers, and not included in genhdr-y, then generated-y specifies
- them.
+ wrappers, generated-y specifies them.
This prevents them being treated as stale asm-generic wrappers and
removed.
@@ -1349,6 +1315,15 @@
#arch/x86/include/asm/Kbuild
generated-y += syscalls_32.h
+ --- 7.4 mandatory-y
+
+ mandatory-y is essentially used by include/uapi/asm-generic/Kbuild.asm
+ to define the minimun set of headers that must be exported in
+ include/asm.
+
+ The convention is to list one subdir per line and
+ preferably in alphabetic order.
+
=== 8 Kbuild Variables
The top Makefile exports the following variables:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4738e7f..cf76646 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -336,6 +336,10 @@
dynamic table installation which will install SSDT
tables to /sys/firmware/acpi/tables/dynamic.
+ acpi_no_watchdog [HW,ACPI,WDT]
+ Ignore the ACPI-based watchdog interface (WDAT) and let
+ a native driver control the watchdog device instead.
+
acpi_rsdp= [ACPI,EFI,KEXEC]
Pass the RSDP address to the kernel, mostly used
on machines running EFI runtime service to boot the
diff --git a/MAINTAINERS b/MAINTAINERS
index 01e7290..9bb64d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8606,6 +8606,12 @@
F: Documentation/scsi/NinjaSCSI.txt
F: drivers/scsi/nsp32*
+NINTENDO HID DRIVER
+M: Daniel J. Ogorchock <djogorchock@gmail.com>
+L: linux-input@vger.kernel.org
+S: Maintained
+F: drivers/hid/hid-nintendo*
+
NIOS2 ARCHITECTURE
M: Ley Foon Tan <lftan@altera.com>
L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
diff --git a/Makefile b/Makefile
index 8b259a1..efba893 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
-SUBLEVEL = 213
+SUBLEVEL = 218
EXTRAVERSION =
NAME = Roaring Lionus
@@ -1300,7 +1300,7 @@
export INSTALL_HDR_PATH = $(objtree)/usr
# If we do an all arch process set dst to asm-$(hdr-arch)
-hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm)
+hdr-dst = $(if $(KBUILD_HEADERS), dst=include/arch-$(hdr-arch), dst=include)
PHONY += archheaders
archheaders:
@@ -1321,7 +1321,7 @@
$(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/uapi/asm/Kbuild),, \
$(error Headers not exportable for the $(SRCARCH) architecture))
$(Q)$(MAKE) $(hdr-inst)=include/uapi
- $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst)
+ $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi $(hdr-dst)
$(Q)$(MAKE) $(hdr-inst)=techpack
PHONY += headers_check_all
@@ -1331,7 +1331,7 @@
PHONY += headers_check
headers_check: headers_install
$(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
- $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/asm $(hdr-dst) HDRCHECK=1
+ $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi $(hdr-dst) HDRCHECK=1
$(Q)$(MAKE) $(hdr-inst)=techpack HDRCHECK=1
# ---------------------------------------------------------------------------
diff --git a/arch/alpha/include/uapi/asm/Kbuild b/arch/alpha/include/uapi/asm/Kbuild
index d96f2ef..b15bf6b 100644
--- a/arch/alpha/include/uapi/asm/Kbuild
+++ b/arch/alpha/include/uapi/asm/Kbuild
@@ -1,43 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += a.out.h
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += compiler.h
-header-y += console.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += fpu.h
-header-y += gentrap.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += pal.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += reg.h
-header-y += regdef.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += sysinfo.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index d6c1bbc..15698b3 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -63,6 +63,7 @@
interrupt-names = "macirq";
phy-mode = "rgmii";
snps,pbl = < 32 >;
+ snps,multicast-filter-bins = <256>;
clocks = <&apbclk>;
clock-names = "stmmaceth";
max-speed = <100>;
diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h
index b29f1a9..07c8e1a 100644
--- a/arch/arc/include/asm/linkage.h
+++ b/arch/arc/include/asm/linkage.h
@@ -14,6 +14,8 @@
#ifdef __ASSEMBLY__
#define ASM_NL ` /* use '`' to mark new line in macro */
+#define __ALIGN .align 4
+#define __ALIGN_STR __stringify(__ALIGN)
/* annotation for data we want in DCCM - if enabled in .config */
.macro ARCFP_DATA nm
diff --git a/arch/arc/include/uapi/asm/Kbuild b/arch/arc/include/uapi/asm/Kbuild
index f50d02d..b15bf6b 100644
--- a/arch/arc/include/uapi/asm/Kbuild
+++ b/arch/arc/include/uapi/asm/Kbuild
@@ -1,5 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += elf.h
-header-y += page.h
-header-y += cachectl.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8f70fb1..76b0f41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2130,7 +2130,7 @@
config KEXEC
bool "Kexec system call (EXPERIMENTAL)"
depends on (!SMP || PM_SLEEP_SMP)
- depends on !CPU_V7M
+ depends on MMU
select KEXEC_CORE
help
kexec is a system call that implements the ability to shutdown your
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9117e86..963a879 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -328,8 +328,11 @@
boot := arch/arm/boot
+archheaders:
+ $(Q)$(MAKE) $(build)=arch/arm/tools uapi
+
archprepare:
- $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
+ $(Q)$(MAKE) $(build)=arch/arm/tools kapi
# Convert bzImage to zImage
bzImage: zImage
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index a1a9280..204ba77 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -123,6 +123,7 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x0 0xc0000000>;
+ dma-ranges = <0x80000000 0x0 0x80000000 0x80000000>;
ti,hwmods = "l3_main_1", "l3_main_2";
reg = <0x0 0x44000000 0x0 0x1000000>,
<0x0 0x45000000 0x0 0x1000>;
@@ -282,6 +283,7 @@
device_type = "pci";
ranges = <0x81000000 0 0 0x03000 0 0x00010000
0x82000000 0 0x20013000 0x13000 0 0xffed000>;
+ dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>;
bus-range = <0x00 0xff>;
#interrupt-cells = <1>;
num-lanes = <1>;
@@ -319,6 +321,7 @@
device_type = "pci";
ranges = <0x81000000 0 0 0x03000 0 0x00010000
0x82000000 0 0x30013000 0x13000 0 0xffed000>;
+ dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>;
bus-range = <0x00 0xff>;
#interrupt-cells = <1>;
num-lanes = <1>;
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 27133c3..0de4ba6 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -505,7 +505,7 @@
};
mdio0: mdio@2d24000 {
- compatible = "fsl,etsec2-mdio";
+ compatible = "gianfar";
device_type = "mdio";
#address-cells = <1>;
#size-cells = <0>;
@@ -513,7 +513,7 @@
};
mdio1: mdio@2d64000 {
- compatible = "fsl,etsec2-mdio";
+ compatible = "gianfar";
device_type = "mdio";
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 1d1d8e9..a76266f 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -131,6 +131,7 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0 0 0xc0000000>;
+ dma-ranges = <0x80000000 0x0 0x80000000 0x80000000>;
ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
reg = <0 0x44000000 0 0x2000>,
<0 0x44800000 0 0x3000>,
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
index a14ad6f..e1f520d4 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
@@ -19,6 +19,16 @@
compatible = "qcom,sa415m-ccard",
"qcom,sdxpoorwills", "qcom,ccard";
qcom,board-id = <25 1>, <25 0x101>;
+
+ qcom_gadget {
+ compatible = "qcom,usb-gadget";
+ qcom,vid = <0x05c6>;
+
+ composition1 {
+ qcom,pid = <0x9105>;
+ qcom,composition = "diag.diag,gsi.dpl";
+ };
+ };
};
&usb {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
index 29db2d4..cc091b1 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
@@ -30,11 +30,6 @@
};
composition2 {
- qcom,pid = <0x9105>;
- qcom,composition = "diag.diag,gsi.dpl";
- };
-
- composition3 {
qcom,pid = <0x9107>;
qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet.v2x,gsi.ecm,gsi.dpl";
};
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dts b/arch/arm/boot/dts/qcom/sa415m-ccard.dts
index a0212fc..65c5761 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dts
@@ -19,4 +19,14 @@
compatible = "qcom,sa415m-ccard",
"qcom,sdxpoorwills", "qcom,ccard";
qcom,board-id = <25 0>, <25 0x100>;
+
+ qcom_gadget {
+ compatible = "qcom,usb-gadget";
+ qcom,vid = <0x05c6>;
+
+ composition1 {
+ qcom,pid = <0x90dc>;
+ qcom,composition = "diag.diag,cser.dun.0,gsi.rmnet,gsi.dpl,qdss.qdss";
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
index 0cbc9e3..619a601 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
@@ -20,6 +20,16 @@
compatible = "qcom,sa415m-ttp",
"qcom,sdxpoorwills", "qcom,ttp";
qcom,board-id = <30 0x101>;
+
+ qcom_gadget {
+ compatible = "qcom,usb-gadget";
+ qcom,vid = <0x05c6>;
+
+ composition1 {
+ qcom,pid = <0x9105>;
+ qcom,composition = "diag.diag,gsi.dpl";
+ };
+ };
};
&mss_mem {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
index 1e4c7231..a907069 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
@@ -20,6 +20,21 @@
compatible = "qcom,sa415m-ttp",
"qcom,sdxpoorwills", "qcom,ttp";
qcom,board-id = <30 0x102>;
+
+ qcom_gadget {
+ compatible = "qcom,usb-gadget";
+ qcom,vid = <0x05c6>;
+
+ composition1 {
+ qcom,pid = <0x9103>;
+ qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet,gsi.rmnet.v2x,ecm.ecm,gsi.dpl";
+ };
+
+ composition2 {
+ qcom,pid = <0x9107>;
+ qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet.v2x,gsi.ecm,gsi.dpl";
+ };
+ };
};
&blsp1_uart2b_hs {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dts b/arch/arm/boot/dts/qcom/sa415m-ttp.dts
index d83eb68..578c43c 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dts
@@ -20,6 +20,16 @@
compatible = "qcom,sa415m-ttp",
"qcom,sdxpoorwills", "qcom,ttp";
qcom,board-id = <30 0x100>;
+
+ qcom_gadget {
+ compatible = "qcom,usb-gadget";
+ qcom,vid = <0x05c6>;
+
+ composition1 {
+ qcom,pid = <0x90dc>;
+ qcom,composition = "diag.diag,cser.dun.0,gsi.rmnet,gsi.dpl,qdss.qdss";
+ };
+ };
};
&blsp1_uart2b_hs {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
index 484d29e..ce5ba93 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
@@ -1771,7 +1771,7 @@
&pmxpoorwills_gpios {
a2b_cdc_sel {
a2b_cdc_sel_default: a2b_cdc_sel_default {
- pins = "gpio1";
+ pins = "gpio5";
power-source = <1>;
output-high;
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index e9c35d3..2c6e485 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -1172,7 +1172,7 @@
reg-names = "wdt-base";
interrupts = <1 3 0>, <1 2 0>;
qcom,bark-time = <11000>;
- qcom,pet-time = <10000>;
+ qcom,pet-time = <9360>;
};
qcom_rng: qrng@793000{
@@ -1390,7 +1390,7 @@
"eth_rgmii_clk", "eth_slave_ahb_clk";
qcom,phy-intr-redirect = <&tlmm 84 GPIO_ACTIVE_LOW>;
qcom,phy-reset = <&tlmm 85 GPIO_ACTIVE_LOW>;
- qcom,phy-reset-delay-msecs = <10>;
+ qcom,phy-reset-delay-msecs = <11 70>;
vreg_rgmii-supply = <&vreg_rgmii>;
vreg_emac_phy-supply = <&vreg_emac_phy>;
vreg_rgmii_io_pads-supply = <&vreg_rgmii_io_pads>;
diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index b9bbcce..6c6d489 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -67,6 +67,14 @@
<0xf0000100 0x100>;
};
+ timer@f0000200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0xf0000200 0x100>;
+ interrupts = <GIC_PPI 11
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+ clocks = <&cpg_clocks R8A7779_CLK_ZS>;
+ };
+
timer@f0000600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xf0000600 0x20>;
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 4c84d33..33c0d26 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -1109,49 +1109,49 @@
usart0_clk: usart0_clk {
#clock-cells = <0>;
reg = <12>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
usart1_clk: usart1_clk {
#clock-cells = <0>;
reg = <13>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
usart2_clk: usart2_clk {
#clock-cells = <0>;
reg = <14>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
usart3_clk: usart3_clk {
#clock-cells = <0>;
reg = <15>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
uart0_clk: uart0_clk {
#clock-cells = <0>;
reg = <16>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
twi0_clk: twi0_clk {
reg = <18>;
#clock-cells = <0>;
- atmel,clk-output-range = <0 16625000>;
+ atmel,clk-output-range = <0 41500000>;
};
twi1_clk: twi1_clk {
#clock-cells = <0>;
reg = <19>;
- atmel,clk-output-range = <0 16625000>;
+ atmel,clk-output-range = <0 41500000>;
};
twi2_clk: twi2_clk {
#clock-cells = <0>;
reg = <20>;
- atmel,clk-output-range = <0 16625000>;
+ atmel,clk-output-range = <0 41500000>;
};
mci0_clk: mci0_clk {
@@ -1167,19 +1167,19 @@
spi0_clk: spi0_clk {
#clock-cells = <0>;
reg = <24>;
- atmel,clk-output-range = <0 133000000>;
+ atmel,clk-output-range = <0 166000000>;
};
spi1_clk: spi1_clk {
#clock-cells = <0>;
reg = <25>;
- atmel,clk-output-range = <0 133000000>;
+ atmel,clk-output-range = <0 166000000>;
};
tcb0_clk: tcb0_clk {
#clock-cells = <0>;
reg = <26>;
- atmel,clk-output-range = <0 133000000>;
+ atmel,clk-output-range = <0 166000000>;
};
pwm_clk: pwm_clk {
@@ -1190,7 +1190,7 @@
adc_clk: adc_clk {
#clock-cells = <0>;
reg = <29>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
dma0_clk: dma0_clk {
@@ -1221,13 +1221,13 @@
ssc0_clk: ssc0_clk {
#clock-cells = <0>;
reg = <38>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
ssc1_clk: ssc1_clk {
#clock-cells = <0>;
reg = <39>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
sha_clk: sha_clk {
diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi
index c5a3772..0fac79f 100644
--- a/arch/arm/boot/dts/sama5d3_can.dtsi
+++ b/arch/arm/boot/dts/sama5d3_can.dtsi
@@ -37,13 +37,13 @@
can0_clk: can0_clk {
#clock-cells = <0>;
reg = <40>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
can1_clk: can1_clk {
#clock-cells = <0>;
reg = <41>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi
index 801f974..b80dbc4 100644
--- a/arch/arm/boot/dts/sama5d3_tcb1.dtsi
+++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi
@@ -23,6 +23,7 @@
tcb1_clk: tcb1_clk {
#clock-cells = <0>;
reg = <27>;
+ atmel,clk-output-range = <0 166000000>;
};
};
};
diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi
index 2511d74..71818c7 100644
--- a/arch/arm/boot/dts/sama5d3_uart.dtsi
+++ b/arch/arm/boot/dts/sama5d3_uart.dtsi
@@ -42,13 +42,13 @@
uart0_clk: uart0_clk {
#clock-cells = <0>;
reg = <16>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
uart1_clk: uart1_clk {
#clock-cells = <0>;
reg = <17>;
- atmel,clk-output-range = <0 66000000>;
+ atmel,clk-output-range = <0 83000000>;
};
};
};
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 96e2d66..f80c84a 100755
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -10,6 +10,8 @@
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_RCU_EXPERT=y
CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_NOCB_CPU=y
+CONFIG_RCU_NOCB_CPU_ALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
@@ -55,6 +57,7 @@
CONFIG_SCHED_MC=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
CONFIG_ARM_MODULE_PLTS=y
CONFIG_CMA=y
CONFIG_ZSMALLOC=y
@@ -87,6 +90,7 @@
CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
CONFIG_INET_DIAG_DESTROY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
@@ -116,12 +120,13 @@
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
-CONFIG_NETFILTER_XT_TARGET_CT=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
@@ -187,8 +192,11 @@
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
@@ -203,12 +211,12 @@
CONFIG_DNS_RESOLVER=y
CONFIG_RMNET_DATA=y
CONFIG_RMNET_DATA_FC=y
-CONFIG_RMNET_DATA_DEBUG_PKT=y
CONFIG_BT=y
CONFIG_MSM_BT_POWER=y
CONFIG_CFG80211=y
CONFIG_CFG80211_INTERNAL_REGDB=y
CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
CONFIG_IPC_ROUTER=y
CONFIG_IPC_ROUTER_SECURITY=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
@@ -219,12 +227,18 @@
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_HDCP_QSEECOM=y
CONFIG_QSEECOM=y
+CONFIG_UID_SYS_STATS=y
CONFIG_MEMORY_STATE_TIME=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
@@ -257,7 +271,9 @@
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_MATRIX=y
+# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
@@ -267,8 +283,10 @@
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_STMVL53L0X=y
CONFIG_INPUT_UINPUT=y
-# CONFIG_VT is not set
+CONFIG_INPUT_GPIO=y
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
CONFIG_DIAG_CHAR=y
@@ -284,7 +302,6 @@
CONFIG_SPI_SPIDEV=y
CONFIG_SLIMBUS_MSM_NGD=y
CONFIG_SPMI=y
-CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
CONFIG_PINCTRL_MSM8909=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_GPIO_SYSFS=y
@@ -308,6 +325,7 @@
CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_THERMAL_TSENS=y
CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_QTI_THERMAL_LIMITS_DCVS=y
CONFIG_QTI_QMI_COOLING_DEVICE=y
CONFIG_REGULATOR_COOLING_DEVICE=y
CONFIG_MFD_QCOM_RPM=y
@@ -344,35 +362,44 @@
CONFIG_RADIO_IRIS_TRANSPORT=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
+CONFIG_FB_VIRTUAL=y
CONFIG_FB_MSM=y
CONFIG_FB_MSM_MDSS=y
CONFIG_FB_MSM_MDSS_WRITEBACK=y
CONFIG_FB_MSM_MDSS_SPI_PANEL=y
CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y
CONFIG_FB_MSM_MDSS_MDP3=y
-CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_SOC=y
CONFIG_UHID=y
CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
+CONFIG_HID_ELECOM=y
CONFIG_HID_EZKEY=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
-CONFIG_USB=y
+CONFIG_HID_MULTITOUCH=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_ACM=y
CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CP210X=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -380,13 +407,18 @@
CONFIG_USB_CI13XXX_MSM=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_RMNET_BAM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_MTP=y
+CONFIG_USB_CONFIGFS_F_PTP=y
CONFIG_USB_CONFIGFS_UEVENT=y
CONFIG_USB_CONFIGFS_F_DIAG=y
CONFIG_USB_CONFIGFS_F_CDEV=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_RING_BUFFER=y
CONFIG_MMC_PARANOID_SD_INIT=y
CONFIG_MMC_CLKGATE=y
CONFIG_MMC_BLOCK_MINORS=32
@@ -396,6 +428,7 @@
CONFIG_MMC_SDHCI_MSM=y
CONFIG_LEDS_CLASS_FLASH=y
CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_MSM_GPIO_FLASH=y
CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_RTC_CLASS=y
@@ -409,6 +442,8 @@
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ION=y
CONFIG_ION_MSM=y
+CONFIG_IPA=y
+CONFIG_RMNET_IPA=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_REVID=y
@@ -431,18 +466,22 @@
CONFIG_QCOM_EARLY_RANDOM=y
CONFIG_MSM_SMEM=y
CONFIG_MSM_SMD=y
-CONFIG_MSM_SMD_DEBUG=y
+CONFIG_MSM_GLINK=y
CONFIG_MSM_TZ_SMMU=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_MSM_GLINK_SPI_XPRT=y
CONFIG_TRACER_PKT=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
CONFIG_MSM_PIL_SSR_GENERIC=y
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_EVENT_TIMER=y
-CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_MEM_SHARE_QMI_SERVICE=y
CONFIG_MSM_BAM_DMUX=y
@@ -461,31 +500,45 @@
CONFIG_ANDROID_BINDER_IPC_32BIT=y
CONFIG_STM=y
CONFIG_SENSORS_SSC=y
-CONFIG_MSM_TZ_LOG=y
-CONFIG_EXT4_FS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_FANOTIFY=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_ECRYPT_FS=y
+CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_SDCARD_FS=y
CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_INFO=y
CONFIG_FRAME_WARN=2048
-CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_WQ_WATCHDOG=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_PANIC_ON_SCHED_BUG=y
CONFIG_PANIC_ON_RT_THROTTLING=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_STACKTRACE=y
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_SET_MODULE_RONX=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_QCOM_RTB=y
+CONFIG_QCOM_RTB_SEPARATE_CPUS=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_LKDTM=y
+CONFIG_MEMTEST=y
+CONFIG_PANIC_ON_DATA_CORRUPTION=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_CORESIGHT=y
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY=y
CONFIG_LSM_MMAP_MIN_ADDR=4096
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index f8f04b9..a006bff 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -437,6 +437,7 @@
CONFIG_MMC_SDHCI_MSM=y
CONFIG_LEDS_CLASS_FLASH=y
CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_MSM_GPIO_FLASH=y
CONFIG_LEDS_QPNP_VIBRATOR=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/sa415m-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig
index 192094e..da5078c 100644
--- a/arch/arm/configs/sa415m-perf_defconfig
+++ b/arch/arm/configs/sa415m-perf_defconfig
@@ -230,7 +230,6 @@
CONFIG_CLD_HL_SDIO_CORE=y
CONFIG_CLD_LL_CORE=y
CONFIG_CNSS_UTILS=y
-CONFIG_CNSS_GENL=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig
index 96e21cc..b3f392e 100644
--- a/arch/arm/configs/sa415m_defconfig
+++ b/arch/arm/configs/sa415m_defconfig
@@ -231,7 +231,6 @@
CONFIG_CLD_HL_SDIO_CORE=y
CONFIG_CLD_LL_CORE=y
CONFIG_CNSS_UTILS=y
-CONFIG_CNSS_GENL=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/arm/configs/sdm429-bg-perf_defconfig b/arch/arm/configs/sdm429-bg-perf_defconfig
index bbb4c4e..db981b6 100644
--- a/arch/arm/configs/sdm429-bg-perf_defconfig
+++ b/arch/arm/configs/sdm429-bg-perf_defconfig
@@ -353,35 +353,9 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF_V2=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
CONFIG_MSM_VIDC_3X_V4L2=y
CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_ADSP_SHMEM=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
@@ -436,6 +410,8 @@
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
@@ -493,7 +469,6 @@
CONFIG_ICNSS=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_EVENT_TIMER=y
-CONFIG_MSM_AVTIMER=y
CONFIG_MSM_PM=y
CONFIG_QCOM_DCC=y
CONFIG_QTI_RPM_STATS_LOG=y
diff --git a/arch/arm/configs/sdm429-bg_defconfig b/arch/arm/configs/sdm429-bg_defconfig
index 6c345f7..36d92e7 100644
--- a/arch/arm/configs/sdm429-bg_defconfig
+++ b/arch/arm/configs/sdm429-bg_defconfig
@@ -360,35 +360,9 @@
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF_V2=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
CONFIG_MSM_VIDC_3X_V4L2=y
CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_ADSP_SHMEM=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
@@ -444,6 +418,8 @@
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
CONFIG_LEDS_QPNP_HAPTICS=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
@@ -507,7 +483,6 @@
CONFIG_MSM_PIL_MSS_QDSP6V5=y
CONFIG_MSM_PERFORMANCE=y
CONFIG_MSM_EVENT_TIMER=y
-CONFIG_MSM_AVTIMER=y
CONFIG_MSM_PM=y
CONFIG_QCOM_DCC=y
CONFIG_QTI_RPM_STATS_LOG=y
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index bd12b98..d690fef 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -37,3 +37,6 @@
generic-y += termios.h
generic-y += timex.h
generic-y += trace_clock.h
+
+generated-y += mach-types.h
+generated-y += unistd-nr.h
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
deleted file mode 100644
index 948178c..0000000
--- a/arch/arm/include/asm/mach-types.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <generated/mach-types.h>
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index ada0d29..076090d 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -14,12 +14,7 @@
#define __ASM_ARM_UNISTD_H
#include <uapi/asm/unistd.h>
-
-/*
- * This may need to be greater than __NR_last_syscall+1 in order to
- * account for the padding in the syscall table
- */
-#define __NR_syscalls (400)
+#include <asm/unistd-nr.h>
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
@@ -52,4 +47,23 @@
#define __IGNORE_fadvise64_64
#define __IGNORE_migrate_pages
+#ifdef __ARM_EABI__
+/*
+ * The following syscalls are obsolete and no longer available for EABI:
+ * __NR_time
+ * __NR_umount
+ * __NR_stime
+ * __NR_alarm
+ * __NR_utime
+ * __NR_getrlimit
+ * __NR_select
+ * __NR_readdir
+ * __NR_mmap
+ * __NR_socketcall
+ * __NR_syscall
+ * __NR_ipc
+ */
+#define __IGNORE_getrlimit
+#endif
+
#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index a1c05f9..424935e 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -1,20 +1,6 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += auxvec.h
-header-y += byteorder.h
-header-y += fcntl.h
-header-y += hwcap.h
-header-y += ioctls.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += perf_regs.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += signal.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += unistd.h
+generated-y += unistd-common.h
+generated-y += unistd-oabi.h
+generated-y += unistd-eabi.h
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/uapi/asm/types.h
similarity index 93%
rename from arch/arm/include/asm/types.h
rename to arch/arm/include/uapi/asm/types.h
index a53cdb8..9435a42 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/uapi/asm/types.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_TYPES_H
-#define _ASM_TYPES_H
+#ifndef _UAPI_ASM_TYPES_H
+#define _UAPI_ASM_TYPES_H
#include <asm-generic/int-ll64.h>
@@ -37,4 +37,4 @@
#define __UINTPTR_TYPE__ unsigned long
#endif
-#endif /* _ASM_TYPES_H */
+#endif /* _UAPI_ASM_TYPES_H */
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index d67def5..63ff7aa 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -17,414 +17,15 @@
#if defined(__thumb__) || defined(__ARM_EABI__)
#define __NR_SYSCALL_BASE 0
+#include <asm/unistd-eabi.h>
#else
#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#include <asm/unistd-oabi.h>
#endif
-/*
- * This file contains the system call numbers.
- */
+#include <asm/unistd-common.h>
+#define __NR_sync_file_range2 __NR_arm_sync_file_range
-#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
-#define __NR_exit (__NR_SYSCALL_BASE+ 1)
-#define __NR_fork (__NR_SYSCALL_BASE+ 2)
-#define __NR_read (__NR_SYSCALL_BASE+ 3)
-#define __NR_write (__NR_SYSCALL_BASE+ 4)
-#define __NR_open (__NR_SYSCALL_BASE+ 5)
-#define __NR_close (__NR_SYSCALL_BASE+ 6)
- /* 7 was sys_waitpid */
-#define __NR_creat (__NR_SYSCALL_BASE+ 8)
-#define __NR_link (__NR_SYSCALL_BASE+ 9)
-#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
-#define __NR_execve (__NR_SYSCALL_BASE+ 11)
-#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
-#define __NR_time (__NR_SYSCALL_BASE+ 13)
-#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
-#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
-#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
- /* 17 was sys_break */
- /* 18 was sys_stat */
-#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
-#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
-#define __NR_mount (__NR_SYSCALL_BASE+ 21)
-#define __NR_umount (__NR_SYSCALL_BASE+ 22)
-#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
-#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
-#define __NR_stime (__NR_SYSCALL_BASE+ 25)
-#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
-#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
- /* 28 was sys_fstat */
-#define __NR_pause (__NR_SYSCALL_BASE+ 29)
-#define __NR_utime (__NR_SYSCALL_BASE+ 30)
- /* 31 was sys_stty */
- /* 32 was sys_gtty */
-#define __NR_access (__NR_SYSCALL_BASE+ 33)
-#define __NR_nice (__NR_SYSCALL_BASE+ 34)
- /* 35 was sys_ftime */
-#define __NR_sync (__NR_SYSCALL_BASE+ 36)
-#define __NR_kill (__NR_SYSCALL_BASE+ 37)
-#define __NR_rename (__NR_SYSCALL_BASE+ 38)
-#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
-#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
-#define __NR_dup (__NR_SYSCALL_BASE+ 41)
-#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
-#define __NR_times (__NR_SYSCALL_BASE+ 43)
- /* 44 was sys_prof */
-#define __NR_brk (__NR_SYSCALL_BASE+ 45)
-#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
-#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
- /* 48 was sys_signal */
-#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
-#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
-#define __NR_acct (__NR_SYSCALL_BASE+ 51)
-#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
- /* 53 was sys_lock */
-#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
-#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
- /* 56 was sys_mpx */
-#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
- /* 58 was sys_ulimit */
- /* 59 was sys_olduname */
-#define __NR_umask (__NR_SYSCALL_BASE+ 60)
-#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
-#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
-#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
-#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
-#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
-#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
-#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
- /* 68 was sys_sgetmask */
- /* 69 was sys_ssetmask */
-#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
-#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
-#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
-#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
-#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
-#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
-#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
-#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
-#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
-#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
-#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
-#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
-#define __NR_select (__NR_SYSCALL_BASE+ 82)
-#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
- /* 84 was sys_lstat */
-#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
-#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
-#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
-#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
-#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
-#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
-#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
-#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
-#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
-#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
-#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
-#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
-#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
- /* 98 was sys_profil */
-#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
-#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
- /* 101 was sys_ioperm */
-#define __NR_socketcall (__NR_SYSCALL_BASE+102)
-#define __NR_syslog (__NR_SYSCALL_BASE+103)
-#define __NR_setitimer (__NR_SYSCALL_BASE+104)
-#define __NR_getitimer (__NR_SYSCALL_BASE+105)
-#define __NR_stat (__NR_SYSCALL_BASE+106)
-#define __NR_lstat (__NR_SYSCALL_BASE+107)
-#define __NR_fstat (__NR_SYSCALL_BASE+108)
- /* 109 was sys_uname */
- /* 110 was sys_iopl */
-#define __NR_vhangup (__NR_SYSCALL_BASE+111)
- /* 112 was sys_idle */
-#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
-#define __NR_wait4 (__NR_SYSCALL_BASE+114)
-#define __NR_swapoff (__NR_SYSCALL_BASE+115)
-#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
-#define __NR_ipc (__NR_SYSCALL_BASE+117)
-#define __NR_fsync (__NR_SYSCALL_BASE+118)
-#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
-#define __NR_clone (__NR_SYSCALL_BASE+120)
-#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
-#define __NR_uname (__NR_SYSCALL_BASE+122)
- /* 123 was sys_modify_ldt */
-#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
-#define __NR_mprotect (__NR_SYSCALL_BASE+125)
-#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
- /* 127 was sys_create_module */
-#define __NR_init_module (__NR_SYSCALL_BASE+128)
-#define __NR_delete_module (__NR_SYSCALL_BASE+129)
- /* 130 was sys_get_kernel_syms */
-#define __NR_quotactl (__NR_SYSCALL_BASE+131)
-#define __NR_getpgid (__NR_SYSCALL_BASE+132)
-#define __NR_fchdir (__NR_SYSCALL_BASE+133)
-#define __NR_bdflush (__NR_SYSCALL_BASE+134)
-#define __NR_sysfs (__NR_SYSCALL_BASE+135)
-#define __NR_personality (__NR_SYSCALL_BASE+136)
- /* 137 was sys_afs_syscall */
-#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
-#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
-#define __NR__llseek (__NR_SYSCALL_BASE+140)
-#define __NR_getdents (__NR_SYSCALL_BASE+141)
-#define __NR__newselect (__NR_SYSCALL_BASE+142)
-#define __NR_flock (__NR_SYSCALL_BASE+143)
-#define __NR_msync (__NR_SYSCALL_BASE+144)
-#define __NR_readv (__NR_SYSCALL_BASE+145)
-#define __NR_writev (__NR_SYSCALL_BASE+146)
-#define __NR_getsid (__NR_SYSCALL_BASE+147)
-#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
-#define __NR__sysctl (__NR_SYSCALL_BASE+149)
-#define __NR_mlock (__NR_SYSCALL_BASE+150)
-#define __NR_munlock (__NR_SYSCALL_BASE+151)
-#define __NR_mlockall (__NR_SYSCALL_BASE+152)
-#define __NR_munlockall (__NR_SYSCALL_BASE+153)
-#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
-#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
-#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
-#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
-#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
-#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
-#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
-#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
-#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
-#define __NR_mremap (__NR_SYSCALL_BASE+163)
-#define __NR_setresuid (__NR_SYSCALL_BASE+164)
-#define __NR_getresuid (__NR_SYSCALL_BASE+165)
- /* 166 was sys_vm86 */
- /* 167 was sys_query_module */
-#define __NR_poll (__NR_SYSCALL_BASE+168)
-#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
-#define __NR_setresgid (__NR_SYSCALL_BASE+170)
-#define __NR_getresgid (__NR_SYSCALL_BASE+171)
-#define __NR_prctl (__NR_SYSCALL_BASE+172)
-#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
-#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
-#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
-#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
-#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
-#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
-#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
-#define __NR_pread64 (__NR_SYSCALL_BASE+180)
-#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
-#define __NR_chown (__NR_SYSCALL_BASE+182)
-#define __NR_getcwd (__NR_SYSCALL_BASE+183)
-#define __NR_capget (__NR_SYSCALL_BASE+184)
-#define __NR_capset (__NR_SYSCALL_BASE+185)
-#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
-#define __NR_sendfile (__NR_SYSCALL_BASE+187)
- /* 188 reserved */
- /* 189 reserved */
-#define __NR_vfork (__NR_SYSCALL_BASE+190)
-#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
-#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
-#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
-#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
-#define __NR_stat64 (__NR_SYSCALL_BASE+195)
-#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
-#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
-#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
-#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
-#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
-#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
-#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
-#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
-#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
-#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
-#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
-#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
-#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
-#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
-#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
-#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
-#define __NR_chown32 (__NR_SYSCALL_BASE+212)
-#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
-#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
-#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
-#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
-#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
-#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
-#define __NR_mincore (__NR_SYSCALL_BASE+219)
-#define __NR_madvise (__NR_SYSCALL_BASE+220)
-#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
- /* 222 for tux */
- /* 223 is unused */
-#define __NR_gettid (__NR_SYSCALL_BASE+224)
-#define __NR_readahead (__NR_SYSCALL_BASE+225)
-#define __NR_setxattr (__NR_SYSCALL_BASE+226)
-#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
-#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
-#define __NR_getxattr (__NR_SYSCALL_BASE+229)
-#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
-#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
-#define __NR_listxattr (__NR_SYSCALL_BASE+232)
-#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
-#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
-#define __NR_removexattr (__NR_SYSCALL_BASE+235)
-#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
-#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
-#define __NR_tkill (__NR_SYSCALL_BASE+238)
-#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
-#define __NR_futex (__NR_SYSCALL_BASE+240)
-#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
-#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
-#define __NR_io_setup (__NR_SYSCALL_BASE+243)
-#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
-#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
-#define __NR_io_submit (__NR_SYSCALL_BASE+246)
-#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
-#define __NR_exit_group (__NR_SYSCALL_BASE+248)
-#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
-#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
-#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
-#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
-#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
- /* 254 for set_thread_area */
- /* 255 for get_thread_area */
-#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
-#define __NR_timer_create (__NR_SYSCALL_BASE+257)
-#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
-#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
-#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
-#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
-#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
-#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
-#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
-#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
-#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
-#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
-#define __NR_tgkill (__NR_SYSCALL_BASE+268)
-#define __NR_utimes (__NR_SYSCALL_BASE+269)
-#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
-#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
-#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
-#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
-#define __NR_mq_open (__NR_SYSCALL_BASE+274)
-#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
-#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
-#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
-#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
-#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
-#define __NR_waitid (__NR_SYSCALL_BASE+280)
-#define __NR_socket (__NR_SYSCALL_BASE+281)
-#define __NR_bind (__NR_SYSCALL_BASE+282)
-#define __NR_connect (__NR_SYSCALL_BASE+283)
-#define __NR_listen (__NR_SYSCALL_BASE+284)
-#define __NR_accept (__NR_SYSCALL_BASE+285)
-#define __NR_getsockname (__NR_SYSCALL_BASE+286)
-#define __NR_getpeername (__NR_SYSCALL_BASE+287)
-#define __NR_socketpair (__NR_SYSCALL_BASE+288)
-#define __NR_send (__NR_SYSCALL_BASE+289)
-#define __NR_sendto (__NR_SYSCALL_BASE+290)
-#define __NR_recv (__NR_SYSCALL_BASE+291)
-#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
-#define __NR_shutdown (__NR_SYSCALL_BASE+293)
-#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
-#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
-#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
-#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
-#define __NR_semop (__NR_SYSCALL_BASE+298)
-#define __NR_semget (__NR_SYSCALL_BASE+299)
-#define __NR_semctl (__NR_SYSCALL_BASE+300)
-#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
-#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
-#define __NR_msgget (__NR_SYSCALL_BASE+303)
-#define __NR_msgctl (__NR_SYSCALL_BASE+304)
-#define __NR_shmat (__NR_SYSCALL_BASE+305)
-#define __NR_shmdt (__NR_SYSCALL_BASE+306)
-#define __NR_shmget (__NR_SYSCALL_BASE+307)
-#define __NR_shmctl (__NR_SYSCALL_BASE+308)
-#define __NR_add_key (__NR_SYSCALL_BASE+309)
-#define __NR_request_key (__NR_SYSCALL_BASE+310)
-#define __NR_keyctl (__NR_SYSCALL_BASE+311)
-#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
-#define __NR_vserver (__NR_SYSCALL_BASE+313)
-#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
-#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
-#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
-#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
-#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
-#define __NR_mbind (__NR_SYSCALL_BASE+319)
-#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
-#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
-#define __NR_openat (__NR_SYSCALL_BASE+322)
-#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
-#define __NR_mknodat (__NR_SYSCALL_BASE+324)
-#define __NR_fchownat (__NR_SYSCALL_BASE+325)
-#define __NR_futimesat (__NR_SYSCALL_BASE+326)
-#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
-#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
-#define __NR_renameat (__NR_SYSCALL_BASE+329)
-#define __NR_linkat (__NR_SYSCALL_BASE+330)
-#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
-#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
-#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
-#define __NR_faccessat (__NR_SYSCALL_BASE+334)
-#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
-#define __NR_ppoll (__NR_SYSCALL_BASE+336)
-#define __NR_unshare (__NR_SYSCALL_BASE+337)
-#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
-#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
-#define __NR_splice (__NR_SYSCALL_BASE+340)
-#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
-#define __NR_sync_file_range2 __NR_arm_sync_file_range
-#define __NR_tee (__NR_SYSCALL_BASE+342)
-#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
-#define __NR_move_pages (__NR_SYSCALL_BASE+344)
-#define __NR_getcpu (__NR_SYSCALL_BASE+345)
-#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
-#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
-#define __NR_utimensat (__NR_SYSCALL_BASE+348)
-#define __NR_signalfd (__NR_SYSCALL_BASE+349)
-#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
-#define __NR_eventfd (__NR_SYSCALL_BASE+351)
-#define __NR_fallocate (__NR_SYSCALL_BASE+352)
-#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
-#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
-#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
-#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
-#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
-#define __NR_dup3 (__NR_SYSCALL_BASE+358)
-#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
-#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
-#define __NR_preadv (__NR_SYSCALL_BASE+361)
-#define __NR_pwritev (__NR_SYSCALL_BASE+362)
-#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
-#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
-#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
-#define __NR_accept4 (__NR_SYSCALL_BASE+366)
-#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
-#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
-#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
-#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
-#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
-#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
-#define __NR_syncfs (__NR_SYSCALL_BASE+373)
-#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
-#define __NR_setns (__NR_SYSCALL_BASE+375)
-#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
-#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
-#define __NR_kcmp (__NR_SYSCALL_BASE+378)
-#define __NR_finit_module (__NR_SYSCALL_BASE+379)
-#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
-#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
-#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
-#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)
-#define __NR_execveat (__NR_SYSCALL_BASE+387)
-#define __NR_userfaultfd (__NR_SYSCALL_BASE+388)
-#define __NR_membarrier (__NR_SYSCALL_BASE+389)
-#define __NR_mlock2 (__NR_SYSCALL_BASE+390)
-#define __NR_copy_file_range (__NR_SYSCALL_BASE+391)
-#define __NR_preadv2 (__NR_SYSCALL_BASE+392)
-#define __NR_pwritev2 (__NR_SYSCALL_BASE+393)
-#define __NR_pkey_mprotect (__NR_SYSCALL_BASE+394)
-#define __NR_pkey_alloc (__NR_SYSCALL_BASE+395)
-#define __NR_pkey_free (__NR_SYSCALL_BASE+396)
-#define __NR_pidfd_send_signal (__NR_SYSCALL_BASE+424)
-#define __NR_pidfd_open (__NR_SYSCALL_BASE+434)
/*
* The following SWIs are ARM private.
@@ -436,24 +37,4 @@
#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
-/*
- * The following syscalls are obsolete and no longer available for EABI.
- */
-#if !defined(__KERNEL__)
-#if defined(__ARM_EABI__)
-#undef __NR_time
-#undef __NR_umount
-#undef __NR_stime
-#undef __NR_alarm
-#undef __NR_utime
-#undef __NR_getrlimit
-#undef __NR_select
-#undef __NR_readdir
-#undef __NR_mmap
-#undef __NR_socketcall
-#undef __NR_syscall
-#undef __NR_ipc
-#endif
-#endif
-
#endif /* _UAPI__ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
deleted file mode 100644
index 4585cdf..0000000
--- a/arch/arm/kernel/calls.S
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * linux/arch/arm/kernel/calls.S
- *
- * Copyright (C) 1995-2005 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file is included thrice in entry-common.S
- */
-/* 0 */ CALL(sys_restart_syscall)
- CALL(sys_exit)
- CALL(sys_fork)
- CALL(sys_read)
- CALL(sys_write)
-/* 5 */ CALL(sys_open)
- CALL(sys_close)
- CALL(sys_ni_syscall) /* was sys_waitpid */
- CALL(sys_creat)
- CALL(sys_link)
-/* 10 */ CALL(sys_unlink)
- CALL(sys_execve)
- CALL(sys_chdir)
- CALL(OBSOLETE(sys_time)) /* used by libc4 */
- CALL(sys_mknod)
-/* 15 */ CALL(sys_chmod)
- CALL(sys_lchown16)
- CALL(sys_ni_syscall) /* was sys_break */
- CALL(sys_ni_syscall) /* was sys_stat */
- CALL(sys_lseek)
-/* 20 */ CALL(sys_getpid)
- CALL(sys_mount)
- CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
- CALL(sys_setuid16)
- CALL(sys_getuid16)
-/* 25 */ CALL(OBSOLETE(sys_stime))
- CALL(sys_ptrace)
- CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
- CALL(sys_ni_syscall) /* was sys_fstat */
- CALL(sys_pause)
-/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
- CALL(sys_ni_syscall) /* was sys_stty */
- CALL(sys_ni_syscall) /* was sys_getty */
- CALL(sys_access)
- CALL(sys_nice)
-/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
- CALL(sys_sync)
- CALL(sys_kill)
- CALL(sys_rename)
- CALL(sys_mkdir)
-/* 40 */ CALL(sys_rmdir)
- CALL(sys_dup)
- CALL(sys_pipe)
- CALL(sys_times)
- CALL(sys_ni_syscall) /* was sys_prof */
-/* 45 */ CALL(sys_brk)
- CALL(sys_setgid16)
- CALL(sys_getgid16)
- CALL(sys_ni_syscall) /* was sys_signal */
- CALL(sys_geteuid16)
-/* 50 */ CALL(sys_getegid16)
- CALL(sys_acct)
- CALL(sys_umount)
- CALL(sys_ni_syscall) /* was sys_lock */
- CALL(sys_ioctl)
-/* 55 */ CALL(sys_fcntl)
- CALL(sys_ni_syscall) /* was sys_mpx */
- CALL(sys_setpgid)
- CALL(sys_ni_syscall) /* was sys_ulimit */
- CALL(sys_ni_syscall) /* was sys_olduname */
-/* 60 */ CALL(sys_umask)
- CALL(sys_chroot)
- CALL(sys_ustat)
- CALL(sys_dup2)
- CALL(sys_getppid)
-/* 65 */ CALL(sys_getpgrp)
- CALL(sys_setsid)
- CALL(sys_sigaction)
- CALL(sys_ni_syscall) /* was sys_sgetmask */
- CALL(sys_ni_syscall) /* was sys_ssetmask */
-/* 70 */ CALL(sys_setreuid16)
- CALL(sys_setregid16)
- CALL(sys_sigsuspend)
- CALL(sys_sigpending)
- CALL(sys_sethostname)
-/* 75 */ CALL(sys_setrlimit)
- CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
- CALL(sys_getrusage)
- CALL(sys_gettimeofday)
- CALL(sys_settimeofday)
-/* 80 */ CALL(sys_getgroups16)
- CALL(sys_setgroups16)
- CALL(OBSOLETE(sys_old_select)) /* used by libc4 */
- CALL(sys_symlink)
- CALL(sys_ni_syscall) /* was sys_lstat */
-/* 85 */ CALL(sys_readlink)
- CALL(sys_uselib)
- CALL(sys_swapon)
- CALL(sys_reboot)
- CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
-/* 90 */ CALL(OBSOLETE(sys_old_mmap)) /* used by libc4 */
- CALL(sys_munmap)
- CALL(sys_truncate)
- CALL(sys_ftruncate)
- CALL(sys_fchmod)
-/* 95 */ CALL(sys_fchown16)
- CALL(sys_getpriority)
- CALL(sys_setpriority)
- CALL(sys_ni_syscall) /* was sys_profil */
- CALL(sys_statfs)
-/* 100 */ CALL(sys_fstatfs)
- CALL(sys_ni_syscall) /* sys_ioperm */
- CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
- CALL(sys_syslog)
- CALL(sys_setitimer)
-/* 105 */ CALL(sys_getitimer)
- CALL(sys_newstat)
- CALL(sys_newlstat)
- CALL(sys_newfstat)
- CALL(sys_ni_syscall) /* was sys_uname */
-/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
- CALL(sys_vhangup)
- CALL(sys_ni_syscall)
- CALL(OBSOLETE(sys_syscall)) /* call a syscall */
- CALL(sys_wait4)
-/* 115 */ CALL(sys_swapoff)
- CALL(sys_sysinfo)
- CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
- CALL(sys_fsync)
- CALL(sys_sigreturn_wrapper)
-/* 120 */ CALL(sys_clone)
- CALL(sys_setdomainname)
- CALL(sys_newuname)
- CALL(sys_ni_syscall) /* modify_ldt */
- CALL(sys_adjtimex)
-/* 125 */ CALL(sys_mprotect)
- CALL(sys_sigprocmask)
- CALL(sys_ni_syscall) /* was sys_create_module */
- CALL(sys_init_module)
- CALL(sys_delete_module)
-/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
- CALL(sys_quotactl)
- CALL(sys_getpgid)
- CALL(sys_fchdir)
- CALL(sys_bdflush)
-/* 135 */ CALL(sys_sysfs)
- CALL(sys_personality)
- CALL(sys_ni_syscall) /* reserved for afs_syscall */
- CALL(sys_setfsuid16)
- CALL(sys_setfsgid16)
-/* 140 */ CALL(sys_llseek)
- CALL(sys_getdents)
- CALL(sys_select)
- CALL(sys_flock)
- CALL(sys_msync)
-/* 145 */ CALL(sys_readv)
- CALL(sys_writev)
- CALL(sys_getsid)
- CALL(sys_fdatasync)
- CALL(sys_sysctl)
-/* 150 */ CALL(sys_mlock)
- CALL(sys_munlock)
- CALL(sys_mlockall)
- CALL(sys_munlockall)
- CALL(sys_sched_setparam)
-/* 155 */ CALL(sys_sched_getparam)
- CALL(sys_sched_setscheduler)
- CALL(sys_sched_getscheduler)
- CALL(sys_sched_yield)
- CALL(sys_sched_get_priority_max)
-/* 160 */ CALL(sys_sched_get_priority_min)
- CALL(sys_sched_rr_get_interval)
- CALL(sys_nanosleep)
- CALL(sys_mremap)
- CALL(sys_setresuid16)
-/* 165 */ CALL(sys_getresuid16)
- CALL(sys_ni_syscall) /* vm86 */
- CALL(sys_ni_syscall) /* was sys_query_module */
- CALL(sys_poll)
- CALL(sys_ni_syscall) /* was nfsservctl */
-/* 170 */ CALL(sys_setresgid16)
- CALL(sys_getresgid16)
- CALL(sys_prctl)
- CALL(sys_rt_sigreturn_wrapper)
- CALL(sys_rt_sigaction)
-/* 175 */ CALL(sys_rt_sigprocmask)
- CALL(sys_rt_sigpending)
- CALL(sys_rt_sigtimedwait)
- CALL(sys_rt_sigqueueinfo)
- CALL(sys_rt_sigsuspend)
-/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
- CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
- CALL(sys_chown16)
- CALL(sys_getcwd)
- CALL(sys_capget)
-/* 185 */ CALL(sys_capset)
- CALL(sys_sigaltstack)
- CALL(sys_sendfile)
- CALL(sys_ni_syscall) /* getpmsg */
- CALL(sys_ni_syscall) /* putpmsg */
-/* 190 */ CALL(sys_vfork)
- CALL(sys_getrlimit)
- CALL(sys_mmap2)
- CALL(ABI(sys_truncate64, sys_oabi_truncate64))
- CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
-/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
- CALL(ABI(sys_lstat64, sys_oabi_lstat64))
- CALL(ABI(sys_fstat64, sys_oabi_fstat64))
- CALL(sys_lchown)
- CALL(sys_getuid)
-/* 200 */ CALL(sys_getgid)
- CALL(sys_geteuid)
- CALL(sys_getegid)
- CALL(sys_setreuid)
- CALL(sys_setregid)
-/* 205 */ CALL(sys_getgroups)
- CALL(sys_setgroups)
- CALL(sys_fchown)
- CALL(sys_setresuid)
- CALL(sys_getresuid)
-/* 210 */ CALL(sys_setresgid)
- CALL(sys_getresgid)
- CALL(sys_chown)
- CALL(sys_setuid)
- CALL(sys_setgid)
-/* 215 */ CALL(sys_setfsuid)
- CALL(sys_setfsgid)
- CALL(sys_getdents64)
- CALL(sys_pivot_root)
- CALL(sys_mincore)
-/* 220 */ CALL(sys_madvise)
- CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
- CALL(sys_ni_syscall) /* TUX */
- CALL(sys_ni_syscall)
- CALL(sys_gettid)
-/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
- CALL(sys_setxattr)
- CALL(sys_lsetxattr)
- CALL(sys_fsetxattr)
- CALL(sys_getxattr)
-/* 230 */ CALL(sys_lgetxattr)
- CALL(sys_fgetxattr)
- CALL(sys_listxattr)
- CALL(sys_llistxattr)
- CALL(sys_flistxattr)
-/* 235 */ CALL(sys_removexattr)
- CALL(sys_lremovexattr)
- CALL(sys_fremovexattr)
- CALL(sys_tkill)
- CALL(sys_sendfile64)
-/* 240 */ CALL(sys_futex)
- CALL(sys_sched_setaffinity)
- CALL(sys_sched_getaffinity)
- CALL(sys_io_setup)
- CALL(sys_io_destroy)
-/* 245 */ CALL(sys_io_getevents)
- CALL(sys_io_submit)
- CALL(sys_io_cancel)
- CALL(sys_exit_group)
- CALL(sys_lookup_dcookie)
-/* 250 */ CALL(sys_epoll_create)
- CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
- CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
- CALL(sys_remap_file_pages)
- CALL(sys_ni_syscall) /* sys_set_thread_area */
-/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
- CALL(sys_set_tid_address)
- CALL(sys_timer_create)
- CALL(sys_timer_settime)
- CALL(sys_timer_gettime)
-/* 260 */ CALL(sys_timer_getoverrun)
- CALL(sys_timer_delete)
- CALL(sys_clock_settime)
- CALL(sys_clock_gettime)
- CALL(sys_clock_getres)
-/* 265 */ CALL(sys_clock_nanosleep)
- CALL(sys_statfs64_wrapper)
- CALL(sys_fstatfs64_wrapper)
- CALL(sys_tgkill)
- CALL(sys_utimes)
-/* 270 */ CALL(sys_arm_fadvise64_64)
- CALL(sys_pciconfig_iobase)
- CALL(sys_pciconfig_read)
- CALL(sys_pciconfig_write)
- CALL(sys_mq_open)
-/* 275 */ CALL(sys_mq_unlink)
- CALL(sys_mq_timedsend)
- CALL(sys_mq_timedreceive)
- CALL(sys_mq_notify)
- CALL(sys_mq_getsetattr)
-/* 280 */ CALL(sys_waitid)
- CALL(sys_socket)
- CALL(ABI(sys_bind, sys_oabi_bind))
- CALL(ABI(sys_connect, sys_oabi_connect))
- CALL(sys_listen)
-/* 285 */ CALL(sys_accept)
- CALL(sys_getsockname)
- CALL(sys_getpeername)
- CALL(sys_socketpair)
- CALL(sys_send)
-/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
- CALL(sys_recv)
- CALL(sys_recvfrom)
- CALL(sys_shutdown)
- CALL(sys_setsockopt)
-/* 295 */ CALL(sys_getsockopt)
- CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
- CALL(sys_recvmsg)
- CALL(ABI(sys_semop, sys_oabi_semop))
- CALL(sys_semget)
-/* 300 */ CALL(sys_semctl)
- CALL(sys_msgsnd)
- CALL(sys_msgrcv)
- CALL(sys_msgget)
- CALL(sys_msgctl)
-/* 305 */ CALL(sys_shmat)
- CALL(sys_shmdt)
- CALL(sys_shmget)
- CALL(sys_shmctl)
- CALL(sys_add_key)
-/* 310 */ CALL(sys_request_key)
- CALL(sys_keyctl)
- CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
-/* vserver */ CALL(sys_ni_syscall)
- CALL(sys_ioprio_set)
-/* 315 */ CALL(sys_ioprio_get)
- CALL(sys_inotify_init)
- CALL(sys_inotify_add_watch)
- CALL(sys_inotify_rm_watch)
- CALL(sys_mbind)
-/* 320 */ CALL(sys_get_mempolicy)
- CALL(sys_set_mempolicy)
- CALL(sys_openat)
- CALL(sys_mkdirat)
- CALL(sys_mknodat)
-/* 325 */ CALL(sys_fchownat)
- CALL(sys_futimesat)
- CALL(ABI(sys_fstatat64, sys_oabi_fstatat64))
- CALL(sys_unlinkat)
- CALL(sys_renameat)
-/* 330 */ CALL(sys_linkat)
- CALL(sys_symlinkat)
- CALL(sys_readlinkat)
- CALL(sys_fchmodat)
- CALL(sys_faccessat)
-/* 335 */ CALL(sys_pselect6)
- CALL(sys_ppoll)
- CALL(sys_unshare)
- CALL(sys_set_robust_list)
- CALL(sys_get_robust_list)
-/* 340 */ CALL(sys_splice)
- CALL(sys_sync_file_range2)
- CALL(sys_tee)
- CALL(sys_vmsplice)
- CALL(sys_move_pages)
-/* 345 */ CALL(sys_getcpu)
- CALL(sys_epoll_pwait)
- CALL(sys_kexec_load)
- CALL(sys_utimensat)
- CALL(sys_signalfd)
-/* 350 */ CALL(sys_timerfd_create)
- CALL(sys_eventfd)
- CALL(sys_fallocate)
- CALL(sys_timerfd_settime)
- CALL(sys_timerfd_gettime)
-/* 355 */ CALL(sys_signalfd4)
- CALL(sys_eventfd2)
- CALL(sys_epoll_create1)
- CALL(sys_dup3)
- CALL(sys_pipe2)
-/* 360 */ CALL(sys_inotify_init1)
- CALL(sys_preadv)
- CALL(sys_pwritev)
- CALL(sys_rt_tgsigqueueinfo)
- CALL(sys_perf_event_open)
-/* 365 */ CALL(sys_recvmmsg)
- CALL(sys_accept4)
- CALL(sys_fanotify_init)
- CALL(sys_fanotify_mark)
- CALL(sys_prlimit64)
-/* 370 */ CALL(sys_name_to_handle_at)
- CALL(sys_open_by_handle_at)
- CALL(sys_clock_adjtime)
- CALL(sys_syncfs)
- CALL(sys_sendmmsg)
-/* 375 */ CALL(sys_setns)
- CALL(sys_process_vm_readv)
- CALL(sys_process_vm_writev)
- CALL(sys_kcmp)
- CALL(sys_finit_module)
-/* 380 */ CALL(sys_sched_setattr)
- CALL(sys_sched_getattr)
- CALL(sys_renameat2)
- CALL(sys_seccomp)
- CALL(sys_getrandom)
-/* 385 */ CALL(sys_memfd_create)
- CALL(sys_bpf)
- CALL(sys_execveat)
- CALL(sys_userfaultfd)
- CALL(sys_membarrier)
-/* 390 */ CALL(sys_mlock2)
- CALL(sys_copy_file_range)
- CALL(sys_preadv2)
- CALL(sys_pwritev2)
- CALL(sys_pkey_mprotect)
-/* 395 */ CALL(sys_pkey_alloc)
- CALL(sys_pkey_free)
- CALL(sys_pidfd_send_signal)
- CALL(sys_pidfd_open)
-#ifndef syscalls_counted
-.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
-#define syscalls_counted
-#endif
-.rept syscalls_padding
- CALL(sys_ni_syscall)
-.endr
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 8d6c751..3b5af1c 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -13,6 +13,11 @@
#include <asm/ftrace.h>
#include <asm/unwind.h>
#include <asm/memory.h>
+#ifdef CONFIG_AEABI
+#include <asm/unistd-oabi.h>
+#endif
+
+ .equ NR_syscalls, __NR_syscalls
#ifdef CONFIG_NEED_RET_TO_USER
#include <mach/entry-macro.S>
@@ -132,21 +137,6 @@
b ret_slow_syscall
ENDPROC(ret_from_fork)
- .equ NR_syscalls,0
-#define CALL(x) .equ NR_syscalls,NR_syscalls+1
-#include "calls.S"
-
-/*
- * Ensure that the system call table is equal to __NR_syscalls,
- * which is the value the rest of the system sees
- */
-.ifne NR_syscalls - __NR_syscalls
-.error "__NR_syscalls is not equal to the size of the syscall table"
-.endif
-
-#undef CALL
-#define CALL(x) .long x
-
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
@@ -294,22 +284,48 @@
#endif
.ltorg
+ .macro syscall_table_start, sym
+ .equ __sys_nr, 0
+ .type \sym, #object
+ENTRY(\sym)
+ .endm
+
+ .macro syscall, nr, func
+ .ifgt __sys_nr - \nr
+ .error "Duplicated/unorded system call entry"
+ .endif
+ .rept \nr - __sys_nr
+ .long sys_ni_syscall
+ .endr
+ .long \func
+ .equ __sys_nr, \nr + 1
+ .endm
+
+ .macro syscall_table_end, sym
+ .ifgt __sys_nr - __NR_syscalls
+ .error "System call table too big"
+ .endif
+ .rept __NR_syscalls - __sys_nr
+ .long sys_ni_syscall
+ .endr
+ .size \sym, . - \sym
+ .endm
+
+#define NATIVE(nr, func) syscall nr, func
+
/*
* This is the syscall table declaration for native ABI syscalls.
* With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
*/
-#define ABI(native, compat) native
+ syscall_table_start sys_call_table
+#define COMPAT(nr, native, compat) syscall nr, native
#ifdef CONFIG_AEABI
-#define OBSOLETE(syscall) sys_ni_syscall
+#include <calls-eabi.S>
#else
-#define OBSOLETE(syscall) syscall
+#include <calls-oabi.S>
#endif
-
- .type sys_call_table, #object
-ENTRY(sys_call_table)
-#include "calls.S"
-#undef ABI
-#undef OBSOLETE
+#undef COMPAT
+ syscall_table_end sys_call_table
/*============================================================================
* Special system call wrappers
@@ -414,14 +430,10 @@
* Let's declare a second syscall table for old ABI binaries
* using the compatibility syscall entries.
*/
-#define ABI(native, compat) compat
-#define OBSOLETE(syscall) syscall
-
- .type sys_oabi_call_table, #object
-ENTRY(sys_oabi_call_table)
-#include "calls.S"
-#undef ABI
-#undef OBSOLETE
+ syscall_table_start sys_oabi_call_table
+#define COMPAT(nr, native, compat) syscall nr, compat
+#include <calls-oabi.S>
+ syscall_table_end sys_oabi_call_table
#endif
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 8904397..bf6e45d 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -86,6 +86,8 @@
*/
np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
if (!np)
+ np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer");
+ if (!np)
goto out_put;
if (of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 6709a8d..f1e34f1 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -100,7 +100,7 @@
ENDPROC(arm_copy_from_user)
- .pushsection .fixup,"ax"
+ .pushsection .text.fixup,"ax"
.align 0
copy_abort_preamble
ldmfd sp!, {r1, r2, r3}
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index cab1289..3a40148 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -86,6 +86,8 @@
obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
endif
+AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
+obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c4436d9..a3f6885 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -112,17 +112,17 @@
int imx_cpu_kill(unsigned int cpu);
#ifdef CONFIG_SUSPEND
-void v7_cpu_resume(void);
void imx53_suspend(void __iomem *ocram_vbase);
extern const u32 imx53_suspend_sz;
void imx6_suspend(void __iomem *ocram_vbase);
#else
-static inline void v7_cpu_resume(void) {}
static inline void imx53_suspend(void __iomem *ocram_vbase) {}
static const u32 imx53_suspend_sz;
static inline void imx6_suspend(void __iomem *ocram_vbase) {}
#endif
+void v7_cpu_resume(void);
+
void imx6_pm_ccm_init(const char *ccm_compat);
void imx6q_pm_init(void);
void imx6dl_pm_init(void);
diff --git a/arch/arm/mach-imx/resume-imx6.S b/arch/arm/mach-imx/resume-imx6.S
new file mode 100644
index 0000000..5bd1ba7
--- /dev/null
+++ b/arch/arm/mach-imx/resume-imx6.S
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "hardware.h"
+
+/*
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
+ */
+
+ENTRY(v7_cpu_resume)
+ bl v7_invalidate_l1
+#ifdef CONFIG_CACHE_L2X0
+ bl l2c310_early_resume
+#endif
+ b cpu_resume
+ENDPROC(v7_cpu_resume)
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index 76ee2ce..7d84b61 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -333,17 +333,3 @@
ret lr
ENDPROC(imx6_suspend)
-
-/*
- * The following code must assume it is running from physical address
- * where absolute virtual addresses to the data section have to be
- * turned into relative ones.
- */
-
-ENTRY(v7_cpu_resume)
- bl v7_invalidate_l1
-#ifdef CONFIG_CACHE_L2X0
- bl l2c310_early_resume
-#endif
- b cpu_resume
-ENDPROC(v7_cpu_resume)
diff --git a/arch/arm/mach-qcom/board-sdm429.c b/arch/arm/mach-qcom/board-sdm429.c
index 3638c37..64c1c06 100644
--- a/arch/arm/mach-qcom/board-sdm429.c
+++ b/arch/arm/mach-qcom/board-sdm429.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
"qcom,sdm429",
"qcom,sda429",
"qcom,sdm429w",
+ "qcom,sda429w",
NULL
};
diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S
index 16e5ff0..91b3f06 100644
--- a/arch/arm/mach-tegra/sleep-tegra30.S
+++ b/arch/arm/mach-tegra/sleep-tegra30.S
@@ -382,6 +382,14 @@
pll_locked r1, r0, CLK_RESET_PLLC_BASE
pll_locked r1, r0, CLK_RESET_PLLX_BASE
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
+ cmp r1, #TEGRA30
+ beq 1f
+ ldr r1, [r0, #CLK_RESET_PLLP_BASE]
+ bic r1, r1, #(1<<31) @ disable PllP bypass
+ str r1, [r0, #CLK_RESET_PLLP_BASE]
+1:
+
mov32 r7, TEGRA_TMRUS_BASE
ldr r1, [r7]
add r1, r1, #LOCK_DELAY
@@ -641,7 +649,10 @@
str r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
/* disable PLLP, PLLA, PLLC and PLLX */
+ tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
+ cmp r1, #TEGRA30
ldr r0, [r5, #CLK_RESET_PLLP_BASE]
+ orrne r0, r0, #(1 << 31) @ enable PllP bypass on fast cluster
bic r0, r0, #(1 << 30)
str r0, [r5, #CLK_RESET_PLLP_BASE]
ldr r0, [r5, #CLK_RESET_PLLA_BASE]
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
index 6e4cd18..92eb5c3 100644
--- a/arch/arm/tools/Makefile
+++ b/arch/arm/tools/Makefile
@@ -4,10 +4,76 @@
# Copyright (C) 2001 Russell King
#
+gen := arch/$(ARCH)/include/generated
+kapi := $(gen)/asm
+uapi := $(gen)/uapi/asm
+syshdr := $(srctree)/$(src)/syscallhdr.sh
+sysnr := $(srctree)/$(src)/syscallnr.sh
+systbl := $(srctree)/$(src)/syscalltbl.sh
+syscall := $(srctree)/$(src)/syscall.tbl
+
+gen-y := $(gen)/calls-oabi.S
+gen-y += $(gen)/calls-eabi.S
+kapi-hdrs-y := $(kapi)/unistd-nr.h
+kapi-hdrs-y += $(kapi)/mach-types.h
+uapi-hdrs-y := $(uapi)/unistd-common.h
+uapi-hdrs-y += $(uapi)/unistd-oabi.h
+uapi-hdrs-y += $(uapi)/unistd-eabi.h
+
+targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
+
+PHONY += kapi uapi
+
+kapi: $(kapi-hdrs-y) $(gen-y)
+
+uapi: $(uapi-hdrs-y)
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(kapi)' ] || mkdir -p '$(kapi)') \
+ $(shell [ -d '$(uapi)' ] || mkdir -p '$(uapi)')
+
quiet_cmd_gen_mach = GEN $@
cmd_gen_mach = mkdir -p $(dir $@) && \
$(AWK) -f $(filter-out $(PHONY),$^) > $@ || \
{ rm -f $@; /bin/false; }
-include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types FORCE
+$(kapi)/mach-types.h: $(src)/gen-mach-types $(src)/mach-types FORCE
$(call if_changed,gen_mach)
+
+quiet_cmd_syshdr = SYSHDR $@
+ cmd_syshdr = $(CONFIG_SHELL) '$(syshdr)' '$<' '$@' \
+ '$(syshdr_abi_$(basetarget))' \
+ '$(syshdr_pfx_$(basetarget))' \
+ '__NR_SYSCALL_BASE'
+
+quiet_cmd_systbl = SYSTBL $@
+ cmd_systbl = $(CONFIG_SHELL) '$(systbl)' '$<' '$@' \
+ '$(systbl_abi_$(basetarget))'
+
+quiet_cmd_sysnr = SYSNR $@
+ cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@' \
+ '$(syshdr_abi_$(basetarget))'
+
+syshdr_abi_unistd-common := common
+$(uapi)/unistd-common.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+syshdr_abi_unistd-oabi := oabi
+$(uapi)/unistd-oabi.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+syshdr_abi_unistd-eabi := eabi
+$(uapi)/unistd-eabi.h: $(syscall) $(syshdr) FORCE
+ $(call if_changed,syshdr)
+
+sysnr_abi_unistd-nr := common,oabi,eabi,compat
+$(kapi)/unistd-nr.h: $(syscall) $(sysnr) FORCE
+ $(call if_changed,sysnr)
+
+systbl_abi_calls-oabi := common,oabi
+$(gen)/calls-oabi.S: $(syscall) $(systbl) FORCE
+ $(call if_changed,systbl)
+
+systbl_abi_calls-eabi := common,eabi
+$(gen)/calls-eabi.S: $(syscall) $(systbl) FORCE
+ $(call if_changed,systbl)
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
new file mode 100644
index 0000000..98c6dd9
--- /dev/null
+++ b/arch/arm/tools/syscall.tbl
@@ -0,0 +1,415 @@
+#
+# Linux system call numbers and entry vectors
+#
+# The format is:
+# <num> <abi> <name> [<entry point> [<oabi compat entry point>]]
+#
+# Where abi is:
+# common - for system calls shared between oabi and eabi (may have compat)
+# oabi - for oabi-only system calls (may have compat)
+# eabi - for eabi-only system calls
+#
+# For each syscall number, "common" is mutually exclusive with oabi and eabi
+#
+0 common restart_syscall sys_restart_syscall
+1 common exit sys_exit
+2 common fork sys_fork
+3 common read sys_read
+4 common write sys_write
+5 common open sys_open
+6 common close sys_close
+# 7 was sys_waitpid
+8 common creat sys_creat
+9 common link sys_link
+10 common unlink sys_unlink
+11 common execve sys_execve
+12 common chdir sys_chdir
+13 oabi time sys_time
+14 common mknod sys_mknod
+15 common chmod sys_chmod
+16 common lchown sys_lchown16
+# 17 was sys_break
+# 18 was sys_stat
+19 common lseek sys_lseek
+20 common getpid sys_getpid
+21 common mount sys_mount
+22 oabi umount sys_oldumount
+23 common setuid sys_setuid16
+24 common getuid sys_getuid16
+25 oabi stime sys_stime
+26 common ptrace sys_ptrace
+27 oabi alarm sys_alarm
+# 28 was sys_fstat
+29 common pause sys_pause
+30 oabi utime sys_utime
+# 31 was sys_stty
+# 32 was sys_gtty
+33 common access sys_access
+34 common nice sys_nice
+# 35 was sys_ftime
+36 common sync sys_sync
+37 common kill sys_kill
+38 common rename sys_rename
+39 common mkdir sys_mkdir
+40 common rmdir sys_rmdir
+41 common dup sys_dup
+42 common pipe sys_pipe
+43 common times sys_times
+# 44 was sys_prof
+45 common brk sys_brk
+46 common setgid sys_setgid16
+47 common getgid sys_getgid16
+# 48 was sys_signal
+49 common geteuid sys_geteuid16
+50 common getegid sys_getegid16
+51 common acct sys_acct
+52 common umount2 sys_umount
+# 53 was sys_lock
+54 common ioctl sys_ioctl
+55 common fcntl sys_fcntl
+# 56 was sys_mpx
+57 common setpgid sys_setpgid
+# 58 was sys_ulimit
+# 59 was sys_olduname
+60 common umask sys_umask
+61 common chroot sys_chroot
+62 common ustat sys_ustat
+63 common dup2 sys_dup2
+64 common getppid sys_getppid
+65 common getpgrp sys_getpgrp
+66 common setsid sys_setsid
+67 common sigaction sys_sigaction
+# 68 was sys_sgetmask
+# 69 was sys_ssetmask
+70 common setreuid sys_setreuid16
+71 common setregid sys_setregid16
+72 common sigsuspend sys_sigsuspend
+73 common sigpending sys_sigpending
+74 common sethostname sys_sethostname
+75 common setrlimit sys_setrlimit
+# Back compat 2GB limited rlimit
+76 oabi getrlimit sys_old_getrlimit
+77 common getrusage sys_getrusage
+78 common gettimeofday sys_gettimeofday
+79 common settimeofday sys_settimeofday
+80 common getgroups sys_getgroups16
+81 common setgroups sys_setgroups16
+82 oabi select sys_old_select
+83 common symlink sys_symlink
+# 84 was sys_lstat
+85 common readlink sys_readlink
+86 common uselib sys_uselib
+87 common swapon sys_swapon
+88 common reboot sys_reboot
+89 oabi readdir sys_old_readdir
+90 oabi mmap sys_old_mmap
+91 common munmap sys_munmap
+92 common truncate sys_truncate
+93 common ftruncate sys_ftruncate
+94 common fchmod sys_fchmod
+95 common fchown sys_fchown16
+96 common getpriority sys_getpriority
+97 common setpriority sys_setpriority
+# 98 was sys_profil
+99 common statfs sys_statfs
+100 common fstatfs sys_fstatfs
+# 101 was sys_ioperm
+102 oabi socketcall sys_socketcall sys_oabi_socketcall
+103 common syslog sys_syslog
+104 common setitimer sys_setitimer
+105 common getitimer sys_getitimer
+106 common stat sys_newstat
+107 common lstat sys_newlstat
+108 common fstat sys_newfstat
+# 109 was sys_uname
+# 110 was sys_iopl
+111 common vhangup sys_vhangup
+# 112 was sys_idle
+# syscall to call a syscall!
+113 oabi syscall sys_syscall
+114 common wait4 sys_wait4
+115 common swapoff sys_swapoff
+116 common sysinfo sys_sysinfo
+117 oabi ipc sys_ipc sys_oabi_ipc
+118 common fsync sys_fsync
+119 common sigreturn sys_sigreturn_wrapper
+120 common clone sys_clone
+121 common setdomainname sys_setdomainname
+122 common uname sys_newuname
+# 123 was sys_modify_ldt
+124 common adjtimex sys_adjtimex
+125 common mprotect sys_mprotect
+126 common sigprocmask sys_sigprocmask
+# 127 was sys_create_module
+128 common init_module sys_init_module
+129 common delete_module sys_delete_module
+# 130 was sys_get_kernel_syms
+131 common quotactl sys_quotactl
+132 common getpgid sys_getpgid
+133 common fchdir sys_fchdir
+134 common bdflush sys_bdflush
+135 common sysfs sys_sysfs
+136 common personality sys_personality
+# 137 was sys_afs_syscall
+138 common setfsuid sys_setfsuid16
+139 common setfsgid sys_setfsgid16
+140 common _llseek sys_llseek
+141 common getdents sys_getdents
+142 common _newselect sys_select
+143 common flock sys_flock
+144 common msync sys_msync
+145 common readv sys_readv
+146 common writev sys_writev
+147 common getsid sys_getsid
+148 common fdatasync sys_fdatasync
+149 common _sysctl sys_sysctl
+150 common mlock sys_mlock
+151 common munlock sys_munlock
+152 common mlockall sys_mlockall
+153 common munlockall sys_munlockall
+154 common sched_setparam sys_sched_setparam
+155 common sched_getparam sys_sched_getparam
+156 common sched_setscheduler sys_sched_setscheduler
+157 common sched_getscheduler sys_sched_getscheduler
+158 common sched_yield sys_sched_yield
+159 common sched_get_priority_max sys_sched_get_priority_max
+160 common sched_get_priority_min sys_sched_get_priority_min
+161 common sched_rr_get_interval sys_sched_rr_get_interval
+162 common nanosleep sys_nanosleep
+163 common mremap sys_mremap
+164 common setresuid sys_setresuid16
+165 common getresuid sys_getresuid16
+# 166 was sys_vm86
+# 167 was sys_query_module
+168 common poll sys_poll
+169 common nfsservctl
+170 common setresgid sys_setresgid16
+171 common getresgid sys_getresgid16
+172 common prctl sys_prctl
+173 common rt_sigreturn sys_rt_sigreturn_wrapper
+174 common rt_sigaction sys_rt_sigaction
+175 common rt_sigprocmask sys_rt_sigprocmask
+176 common rt_sigpending sys_rt_sigpending
+177 common rt_sigtimedwait sys_rt_sigtimedwait
+178 common rt_sigqueueinfo sys_rt_sigqueueinfo
+179 common rt_sigsuspend sys_rt_sigsuspend
+180 common pread64 sys_pread64 sys_oabi_pread64
+181 common pwrite64 sys_pwrite64 sys_oabi_pwrite64
+182 common chown sys_chown16
+183 common getcwd sys_getcwd
+184 common capget sys_capget
+185 common capset sys_capset
+186 common sigaltstack sys_sigaltstack
+187 common sendfile sys_sendfile
+# 188 reserved
+# 189 reserved
+190 common vfork sys_vfork
+# SuS compliant getrlimit
+191 common ugetrlimit sys_getrlimit
+192 common mmap2 sys_mmap2
+193 common truncate64 sys_truncate64 sys_oabi_truncate64
+194 common ftruncate64 sys_ftruncate64 sys_oabi_ftruncate64
+195 common stat64 sys_stat64 sys_oabi_stat64
+196 common lstat64 sys_lstat64 sys_oabi_lstat64
+197 common fstat64 sys_fstat64 sys_oabi_fstat64
+198 common lchown32 sys_lchown
+199 common getuid32 sys_getuid
+200 common getgid32 sys_getgid
+201 common geteuid32 sys_geteuid
+202 common getegid32 sys_getegid
+203 common setreuid32 sys_setreuid
+204 common setregid32 sys_setregid
+205 common getgroups32 sys_getgroups
+206 common setgroups32 sys_setgroups
+207 common fchown32 sys_fchown
+208 common setresuid32 sys_setresuid
+209 common getresuid32 sys_getresuid
+210 common setresgid32 sys_setresgid
+211 common getresgid32 sys_getresgid
+212 common chown32 sys_chown
+213 common setuid32 sys_setuid
+214 common setgid32 sys_setgid
+215 common setfsuid32 sys_setfsuid
+216 common setfsgid32 sys_setfsgid
+217 common getdents64 sys_getdents64
+218 common pivot_root sys_pivot_root
+219 common mincore sys_mincore
+220 common madvise sys_madvise
+221 common fcntl64 sys_fcntl64 sys_oabi_fcntl64
+# 222 for tux
+# 223 is unused
+224 common gettid sys_gettid
+225 common readahead sys_readahead sys_oabi_readahead
+226 common setxattr sys_setxattr
+227 common lsetxattr sys_lsetxattr
+228 common fsetxattr sys_fsetxattr
+229 common getxattr sys_getxattr
+230 common lgetxattr sys_lgetxattr
+231 common fgetxattr sys_fgetxattr
+232 common listxattr sys_listxattr
+233 common llistxattr sys_llistxattr
+234 common flistxattr sys_flistxattr
+235 common removexattr sys_removexattr
+236 common lremovexattr sys_lremovexattr
+237 common fremovexattr sys_fremovexattr
+238 common tkill sys_tkill
+239 common sendfile64 sys_sendfile64
+240 common futex sys_futex
+241 common sched_setaffinity sys_sched_setaffinity
+242 common sched_getaffinity sys_sched_getaffinity
+243 common io_setup sys_io_setup
+244 common io_destroy sys_io_destroy
+245 common io_getevents sys_io_getevents
+246 common io_submit sys_io_submit
+247 common io_cancel sys_io_cancel
+248 common exit_group sys_exit_group
+249 common lookup_dcookie sys_lookup_dcookie
+250 common epoll_create sys_epoll_create
+251 common epoll_ctl sys_epoll_ctl sys_oabi_epoll_ctl
+252 common epoll_wait sys_epoll_wait sys_oabi_epoll_wait
+253 common remap_file_pages sys_remap_file_pages
+# 254 for set_thread_area
+# 255 for get_thread_area
+256 common set_tid_address sys_set_tid_address
+257 common timer_create sys_timer_create
+258 common timer_settime sys_timer_settime
+259 common timer_gettime sys_timer_gettime
+260 common timer_getoverrun sys_timer_getoverrun
+261 common timer_delete sys_timer_delete
+262 common clock_settime sys_clock_settime
+263 common clock_gettime sys_clock_gettime
+264 common clock_getres sys_clock_getres
+265 common clock_nanosleep sys_clock_nanosleep
+266 common statfs64 sys_statfs64_wrapper
+267 common fstatfs64 sys_fstatfs64_wrapper
+268 common tgkill sys_tgkill
+269 common utimes sys_utimes
+270 common arm_fadvise64_64 sys_arm_fadvise64_64
+271 common pciconfig_iobase sys_pciconfig_iobase
+272 common pciconfig_read sys_pciconfig_read
+273 common pciconfig_write sys_pciconfig_write
+274 common mq_open sys_mq_open
+275 common mq_unlink sys_mq_unlink
+276 common mq_timedsend sys_mq_timedsend
+277 common mq_timedreceive sys_mq_timedreceive
+278 common mq_notify sys_mq_notify
+279 common mq_getsetattr sys_mq_getsetattr
+280 common waitid sys_waitid
+281 common socket sys_socket
+282 common bind sys_bind sys_oabi_bind
+283 common connect sys_connect sys_oabi_connect
+284 common listen sys_listen
+285 common accept sys_accept
+286 common getsockname sys_getsockname
+287 common getpeername sys_getpeername
+288 common socketpair sys_socketpair
+289 common send sys_send
+290 common sendto sys_sendto sys_oabi_sendto
+291 common recv sys_recv
+292 common recvfrom sys_recvfrom
+293 common shutdown sys_shutdown
+294 common setsockopt sys_setsockopt
+295 common getsockopt sys_getsockopt
+296 common sendmsg sys_sendmsg sys_oabi_sendmsg
+297 common recvmsg sys_recvmsg
+298 common semop sys_semop sys_oabi_semop
+299 common semget sys_semget
+300 common semctl sys_semctl
+301 common msgsnd sys_msgsnd
+302 common msgrcv sys_msgrcv
+303 common msgget sys_msgget
+304 common msgctl sys_msgctl
+305 common shmat sys_shmat
+306 common shmdt sys_shmdt
+307 common shmget sys_shmget
+308 common shmctl sys_shmctl
+309 common add_key sys_add_key
+310 common request_key sys_request_key
+311 common keyctl sys_keyctl
+312 common semtimedop sys_semtimedop sys_oabi_semtimedop
+313 common vserver
+314 common ioprio_set sys_ioprio_set
+315 common ioprio_get sys_ioprio_get
+316 common inotify_init sys_inotify_init
+317 common inotify_add_watch sys_inotify_add_watch
+318 common inotify_rm_watch sys_inotify_rm_watch
+319 common mbind sys_mbind
+320 common get_mempolicy sys_get_mempolicy
+321 common set_mempolicy sys_set_mempolicy
+322 common openat sys_openat
+323 common mkdirat sys_mkdirat
+324 common mknodat sys_mknodat
+325 common fchownat sys_fchownat
+326 common futimesat sys_futimesat
+327 common fstatat64 sys_fstatat64 sys_oabi_fstatat64
+328 common unlinkat sys_unlinkat
+329 common renameat sys_renameat
+330 common linkat sys_linkat
+331 common symlinkat sys_symlinkat
+332 common readlinkat sys_readlinkat
+333 common fchmodat sys_fchmodat
+334 common faccessat sys_faccessat
+335 common pselect6 sys_pselect6
+336 common ppoll sys_ppoll
+337 common unshare sys_unshare
+338 common set_robust_list sys_set_robust_list
+339 common get_robust_list sys_get_robust_list
+340 common splice sys_splice
+341 common arm_sync_file_range sys_sync_file_range2
+342 common tee sys_tee
+343 common vmsplice sys_vmsplice
+344 common move_pages sys_move_pages
+345 common getcpu sys_getcpu
+346 common epoll_pwait sys_epoll_pwait
+347 common kexec_load sys_kexec_load
+348 common utimensat sys_utimensat
+349 common signalfd sys_signalfd
+350 common timerfd_create sys_timerfd_create
+351 common eventfd sys_eventfd
+352 common fallocate sys_fallocate
+353 common timerfd_settime sys_timerfd_settime
+354 common timerfd_gettime sys_timerfd_gettime
+355 common signalfd4 sys_signalfd4
+356 common eventfd2 sys_eventfd2
+357 common epoll_create1 sys_epoll_create1
+358 common dup3 sys_dup3
+359 common pipe2 sys_pipe2
+360 common inotify_init1 sys_inotify_init1
+361 common preadv sys_preadv
+362 common pwritev sys_pwritev
+363 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
+364 common perf_event_open sys_perf_event_open
+365 common recvmmsg sys_recvmmsg
+366 common accept4 sys_accept4
+367 common fanotify_init sys_fanotify_init
+368 common fanotify_mark sys_fanotify_mark
+369 common prlimit64 sys_prlimit64
+370 common name_to_handle_at sys_name_to_handle_at
+371 common open_by_handle_at sys_open_by_handle_at
+372 common clock_adjtime sys_clock_adjtime
+373 common syncfs sys_syncfs
+374 common sendmmsg sys_sendmmsg
+375 common setns sys_setns
+376 common process_vm_readv sys_process_vm_readv
+377 common process_vm_writev sys_process_vm_writev
+378 common kcmp sys_kcmp
+379 common finit_module sys_finit_module
+380 common sched_setattr sys_sched_setattr
+381 common sched_getattr sys_sched_getattr
+382 common renameat2 sys_renameat2
+383 common seccomp sys_seccomp
+384 common getrandom sys_getrandom
+385 common memfd_create sys_memfd_create
+386 common bpf sys_bpf
+387 common execveat sys_execveat
+388 common userfaultfd sys_userfaultfd
+389 common membarrier sys_membarrier
+390 common mlock2 sys_mlock2
+391 common copy_file_range sys_copy_file_range
+392 common preadv2 sys_preadv2
+393 common pwritev2 sys_pwritev2
+394 common pkey_mprotect sys_pkey_mprotect
+395 common pkey_alloc sys_pkey_alloc
+396 common pkey_free sys_pkey_free
+424 common pidfd_send_signal sys_pidfd_send_signal
+434 common pidfd_open sys_pidfd_open
diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh
new file mode 100644
index 0000000..72d4b2e
--- /dev/null
+++ b/arch/arm/tools/syscallhdr.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+prefix="$4"
+offset="$5"
+
+fileguard=_ASM_ARM_`basename "$out" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
+if echo $out | grep -q uapi; then
+ fileguard="_UAPI$fileguard"
+fi
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
+ echo "#ifndef ${fileguard}"
+ echo "#define ${fileguard} 1"
+ echo ""
+
+ while read nr abi name entry ; do
+ if [ -z "$offset" ]; then
+ echo "#define __NR_${prefix}${name} $nr"
+ else
+ echo "#define __NR_${prefix}${name} ($offset + $nr)"
+ fi
+ done
+
+ echo ""
+ echo "#endif /* ${fileguard} */"
+) > "$out"
diff --git a/arch/arm/tools/syscallnr.sh b/arch/arm/tools/syscallnr.sh
new file mode 100644
index 0000000..d297129
--- /dev/null
+++ b/arch/arm/tools/syscallnr.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+align=1
+
+fileguard=_ASM_ARM_`basename "$out" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
+
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | tail -n1 | (
+ echo "#ifndef ${fileguard}
+#define ${fileguard} 1
+
+/*
+ * This needs to be greater than __NR_last_syscall+1 in order to account
+ * for the padding in the syscall table.
+ */
+"
+
+ while read nr abi name entry; do
+ nr=$(($nr + 1))
+ while [ "$(($nr / (256 * $align) ))" -gt 0 ]; do
+ align=$(( $align * 4 ))
+ done
+ nr=$(( ($nr + $align - 1) & ~($align - 1) ))
+ echo "/* aligned to $align */"
+ echo "#define __NR_syscalls $nr"
+ done
+
+ echo ""
+ echo "#endif /* ${fileguard} */"
+) > "$out"
diff --git a/arch/arm/tools/syscalltbl.sh b/arch/arm/tools/syscalltbl.sh
new file mode 100644
index 0000000..5ca8345
--- /dev/null
+++ b/arch/arm/tools/syscalltbl.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+in="$1"
+out="$2"
+my_abis=`echo "($3)" | tr ',' '|'`
+
+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
+ while read nr abi name entry compat; do
+ if [ "$abi" = "eabi" -a -n "$compat" ]; then
+ echo "$in: error: a compat entry for an EABI syscall ($name) makes no sense" >&2
+ exit 1
+ fi
+
+ if [ -n "$entry" ]; then
+ if [ -z "$compat" ]; then
+ echo "NATIVE($nr, $entry)"
+ else
+ echo "COMPAT($nr, $entry, $compat)"
+ fi
+ fi
+ done
+) > "$out"
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index f6df01c..0dde749 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -401,9 +401,11 @@
sda429-spyro-qrd-dvt-overlay.dtbo \
sdm429-spyro-qrd-wdp-overlay.dtbo \
sdm429-bg-wtp-overlay.dtbo \
+ sdm429-bg-dvt2-wtp-overlay.dtbo \
sdm429-bg-wdp-overlay.dtbo \
sda429-bg-wdp-overlay.dtbo \
- sda429-bg-wtp-overlay.dtbo
+ sda429-bg-wtp-overlay.dtbo \
+ sda429-bg-dvt2-wtp-overlay.dtbo
msm8940-mtp-overlay.dtbo-base := msm8940-pmi8950.dtb \
msm8940-pmi8937.dtb \
@@ -523,6 +525,8 @@
sdm429-spyro-qrd-wdp-overlay.dtbo-base := sdm429-spyro-wdp.dtb
sdm429-bg-wtp-overlay.dtbo-base := sdm429-bg-wtp.dtb
sda429-bg-wtp-overlay.dtbo-base := sda429-bg-wtp.dtb
+sdm429-bg-dvt2-wtp-overlay.dtbo-base := sdm429-bg-dvt2-wtp.dtb
+sda429-bg-dvt2-wtp-overlay.dtbo-base := sda429-bg-dvt2-wtp.dtb
sdm429-bg-wdp-overlay.dtbo-base := sdm429-bg-wdp.dtb
sda429-bg-wdp-overlay.dtbo-base := sda429-bg-wdp.dtb
else
@@ -608,6 +612,8 @@
sdw2500-apq8009w-wtp.dtb \
sdw2500-msm8909w-wtp.dtb \
msm8905-qrd-skub_qseev4.dtb \
+ msm8905-qrd-skub.dtb \
+ msm8905-qrd-sku3.dtb \
msm8909-mtp.dtb \
msm8909-1gb-mtp.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
index 763aa9b..26ce607 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
@@ -59,16 +59,25 @@
&soc {
ext_codec: sound-9335 {
compatible = "qcom,apq8009-audio-i2s-codec";
- qcom,model = "apq8009-tashalite-snd-card-tdm";
qcom,audio-routing =
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
"MADINPUT", "MCLK",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
"SpkrLeft IN", "SPK1 OUT",
"SpkrRight IN", "SPK2 OUT";
- qcom,tdm-i2s-switch-enable = <&msm_gpio 88 0>;
+ qcom,pdm-i2s-switch-enable = <&msm_gpio 88 0>;
qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
qcom,quat-mi2s-gpios = <&cdc_quat_tdm_gpios>;
};
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
index 5664d3e..ad33fe1 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,7 +25,6 @@
#global-interrupts = <2>;
qcom,regulator-names = "vdd";
vdd-supply = <&gpu_cx_gdsc>;
- qcom,deferred-regulator-disable-delay = <80>;
interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/qcom/msm-pm8909.dtsi b/arch/arm64/boot/dts/qcom/msm-pm8909.dtsi
index 5b44204..87330d6 100644
--- a/arch/arm64/boot/dts/qcom/msm-pm8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-pm8909.dtsi
@@ -81,33 +81,14 @@
};
pm8909_gpios: gpios {
- compatible = "qcom,qpnp-pin";
- spmi-dev-container;
+ compatible = "qcom,spmi-gpio";
+ reg = <0xc000 0x400>;
+ interrupts = <0x0 0xc1 0 IRQ_TYPE_NONE>,
+ <0x0 0xc3 0 IRQ_TYPE_NONE>;
+ interrupt-names = "pm8909_gpio2", "pm8909_gpio4";
gpio-controller;
#gpio-cells = <2>;
- #address-cells = <1>;
- #size-cells = <1>;
- label = "pm8909-gpio";
-
- gpio@c000 {
- reg = <0xc000 0x100>;
- qcom,pin-num = <1>;
- };
-
- gpio@c100 {
- reg = <0xc100 0x100>;
- qcom,pin-num = <2>;
- };
-
- gpio@c200 {
- reg = <0xc200 0x100>;
- qcom,pin-num = <3>;
- };
-
- gpio@c300 {
- reg = <0xc300 0x100>;
- qcom,pin-num = <4>;
- };
+ qcom,gpios-disallowed = <1 3>;
};
pm8909_vadc: vadc@3100 {
diff --git a/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi b/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
index c13c031..d662415 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
@@ -17,8 +17,17 @@
qcom,pin-func = <2>;
label = "SY7807_pins";
SY7807_default: en_default {
- drive-strength = <2>;
- bias-pull-down;
+ mux {
+ pins = "gpio32";
+ function = "gpio";
+ };
+
+ configs {
+ pins = "gpio32";
+ drive-strength = <0x2>;
+ bias-pull-down;
+ };
+
};
};
};
@@ -28,7 +37,7 @@
compatible = "qcom,leds-gpio-flash";
status = "okay";
pinctrl-names = "flash_default";
- pinctrl-0 = <&SY7807_default>;
+ pinctrl-0 = <&SY7807_default &flash_en_default>;
qcom,flash-en = <&pm8909_gpios 4 0>;
qcom,flash-now = <&msm_gpio 32 0>;
clocks = <&clock_gcc clk_gcc_camss_gp1_clk>,
diff --git a/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi b/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
index e3d390f..467b448 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
@@ -283,3 +283,12 @@
pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
};
+
+&mdss_dsi {
+ vdda-supply = <&pm8909_l2>;
+ vddio-supply = <&pm8909_l6>;
+ qcom,mdss_dsi_ctrl0@1ac8000 {
+ vdd-supply = <&pm8909_l17>;
+ vddio-supply = <&pm8909_l6>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
index 1ac0640..8a72765 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
@@ -514,12 +514,24 @@
&pm8909_gpios {
/* GPIO 2 (NFC_CLK_REQ) */
- gpio@c100 {
- qcom,mode = <0>;
- qcom,vin-sel = <1>;
- qcom,src-sel = <0>;
- qcom,master-en = <1>;
- status = "okay";
+ nfc-clk {
+ nfc_clk_default: nfc_clk_default {
+ pins = "gpio2";
+ function = "normal";
+ input-enable;
+ power-source = <1>;
+ };
+ };
+
+ /* GPIO 4 (FLASH ENABLE GPIO CONFIG) */
+ flash_en {
+ flash_en_default: flash_en_default{
+ pins = "gpio4";
+ function = "normal";
+ input-disable;
+ output-enable;
+ status = "okay";
+ };
};
};
@@ -538,7 +550,8 @@
interrupts = <21 0>;
interrupt-names = "nfc_irq";
pinctrl-names = "nfc_active", "nfc_suspend";
- pinctrl-0 = <&nfc_int_active &nfc_disable_active>;
+ pinctrl-0 = <&nfc_int_active &nfc_disable_active
+ &nfc_clk_default>;
pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>;
clocks = <&clock_rpm clk_bb_clk2_pin>;
clock-names = "ref_clk";
@@ -572,3 +585,12 @@
&pm8909_conga_analog {
status = "disabled";
};
+
+&mdss_dsi {
+ vdda-supply = <&pm8909_l2>;
+ vddio-supply = <&pm8909_l6>;
+ qcom,mdss_dsi_ctrl0@1ac8000 {
+ vdd-supply = <&pm8909_l17>;
+ vddio-supply = <&pm8909_l6>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8909-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..85b3505
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8909-camera-sensor-mtp.dtsi
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2014-2017, 2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+&soc {
+};
+
+&i2c_3 {
+
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x3>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8909_l8>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-type = <0>;
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2900000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@6c{
+ cell-index = <0>;
+ reg = <0x6c>;
+ qcom,eeprom-name = "sunny_ov8858_q8v19w";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <4>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0 1 1>;
+ qcom,mem0 = <0 0x0 2 0 1 0>;
+ qcom,page1 = <1 0x3d84 2 0xc0 1 1>;
+ qcom,poll1 = <0 0x0 2 0 1 1>;
+ qcom,mem1 = <0 0x3d00 2 0 1 0>;
+ qcom,page2 = <1 0x3d88 2 0x7010 2 1>;
+ qcom,poll2 = <0 0x0 2 0 1 1>;
+ qcom,mem2 = <0 0x3d00 2 0 1 0>;
+ qcom,page3 = <1 0x3d8A 2 0x7184 2 1>;
+ qcom,pageen3 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll3 = <0 0x0 2 0 1 1>;
+ qcom,mem3 = <373 0x7010 2 0 1 1>;
+
+ cam_vdig-supply = <&pm8909_l2>;
+ cam_vana-supply = <&pm8909_l17>;
+ cam_vio-supply = <&pm8909_l6>;
+ cam_vaf-supply = <&pm8909_l8>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ qcom,enable_pinctrl;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;
+ gpios = <&msm_gpio 26 0>,
+ <&msm_gpio 35 0>,
+ <&msm_gpio 34 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,cam-power-seq-type = "sensor_vreg",
+ "sensor_gpio", "sensor_gpio",
+ "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vaf",
+ "sensor_gpio_reset",
+ "sensor_gpio_standby",
+ "sensor_cam_mclk" ;
+ qcom,cam-power-seq-cfg-val = <1 1 1 23880000>;
+ qcom,cam-power-seq-delay = <1 10 10 5>;
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ led_flash0: qcom,led-flash@60 {
+ cell-index = <0>;
+ reg = <0x60>;
+ qcom,slave-id = <0x60 0x00 0x0011>;
+ compatible = "qcom,led-flash";
+ label = "adp1660";
+ qcom,flash-type = <1>;
+ qcom,gpio-no-mux = <0>;
+ qcom,enable_pinctrl;
+ pinctrl-names = "cam_flash_default", "cam_flash_suspend";
+ pinctrl-0 = <&cam_sensor_flash_default>;
+ pinctrl-1 = <&cam_sensor_flash_sleep>;
+ gpios = <&msm_gpio 31 0>,
+ <&msm_gpio 32 0>,
+ <&msm_gpio 36 0>;
+ qcom,gpio-flash-en = <0>;
+ qcom,gpio-flash-now = <1>;
+ qcom,gpio-flash-rst = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <0 0 0>;
+ qcom,gpio-req-tbl-label = "FLASH_EN",
+ "FLASH_NOW", "FLASH_RST";
+ qcom,cci-master = <0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x2>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <90>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ cam_vdig-supply = <&pm8909_l2>;
+ cam_vana-supply = <&pm8909_l17>;
+ cam_vio-supply = <&pm8909_l6>;
+ cam_vaf-supply = <&pm8909_l8>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-type = <0 1 0 0>;
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2850000 2900000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;
+ gpios = <&msm_gpio 26 0>,
+ <&msm_gpio 35 0>,
+ <&msm_gpio 34 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET1",
+ "CAM_STANDBY";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom_camera1: qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ cam_vana-supply = <&pm8909_l17>;
+ cam_vio-supply = <&pm8909_l6>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <1 0>;
+ qcom,cam-vreg-min-voltage = <0 2850000>;
+ qcom,cam-vreg-max-voltage = <0 2850000>;
+ qcom,cam-vreg-op-mode = <0 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep>;
+ gpios = <&msm_gpio 27 0>,
+ <&msm_gpio 28 0>,
+ <&msm_gpio 33 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY";
+ qcom,cci-master = <0>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
index 5b4fd6d..591d30d 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
@@ -13,6 +13,7 @@
#include "msm8909.dtsi"
#include "msm8909-pinctrl.dtsi"
#include "msm8909-regulator.dtsi"
+#include "msm8909-camera-sensor-mtp.dtsi"
&soc {
/*
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pm8909-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pm8909-mtp.dtsi
index b67b712..09d351c 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-pm8909-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-pm8909-mtp.dtsi
@@ -113,7 +113,157 @@
};
&audio_codec_mtp {
+ compatible = "qcom,msm8952-audio-codec";
+ qcom,model = "msm8909-snd-card";
+ reg = <0x7702000 0x4>,
+ <0x7702004 0x4>,
+ <0x7702008 0x4>;
+ reg-names = "csr_gp_io_mux_mic_ctl",
+ "csr_gp_io_mux_spkr_ctl",
+ "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel";
+ qcom,msm-snd-card-id = <0>;
+ qcom,msm-codec-type = "internal";
+ qcom,msm-ext-pa = "primary";
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-hs-micbias-type = "internal";
+ qcom,msm-micbias1-ext-cap;
qcom,msm-micbias2-ext-cap;
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "SPK_RX_BIAS", "MCLK",
+ "INT_LDO_H", "MCLK",
+ "MIC BIAS External", "Handset Mic",
+ "MIC BIAS Internal2", "Headset Mic",
+ "MIC BIAS External", "Secondary Mic",
+ "AMIC1", "MIC BIAS External",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External";
+
+ qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
+ qcom,cdc-us-euro-gpios = <&cdc_us_euro_gpios>;
+
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>,
+ <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&pcm_noirq>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2",
+ "msm-voip-dsp", "msm-pcm-voice",
+ "msm-pcm-loopback", "msm-compress-dsp",
+ "msm-pcm-hostless", "msm-pcm-afe",
+ "msm-lsm-client", "msm-pcm-routing",
+ "msm-pcm-dsp-noirq";
+ asoc-cpu = <&dai_pri_auxpcm>, <&dai_hdmi>,
+ <&dai_mi2s0>, <&dai_mi2s1>,
+ <&dai_mi2s2>, <&dai_mi2s3>,
+ <&dai_mi2s4>, <&dai_mi2s5>,
+ <&sb_0_rx>, <&sb_0_tx>,
+ <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_3_rx>, <&sb_3_tx>,
+ <&sb_4_rx>, <&sb_4_tx>,
+ <&bt_sco_rx>, <&bt_sco_tx>,
+ <&bt_a2dp_rx>, <&int_fm_rx>, <&int_fm_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>,
+ <&afe_proxy_rx>, <&afe_proxy_tx>,
+ <&incall_record_rx>, <&incall_record_tx>,
+ <&incall_music_rx>, <&incall_music_2_rx>;
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-hdmi.8",
+ "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6",
+ "msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385",
+ "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+ "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+ "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289",
+ "msm-dai-q6-dev.12290",
+ "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770";
+ asoc-codec = <&stub_codec>, <&msm_digital_codec>,
+ <&pmic_analog_codec>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
+ "analog-codec";
+};
+
+&pm8909_1 {
+ pmic_analog_codec: analog-codec@f100 {
+ status = "okay";
+ compatible = "qcom,pmic-analog-codec";
+ reg = <0xf000 0x200>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts =
+ <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names =
+ "spk_cnp_int",
+ "spk_clip_int",
+ "spk_ocp_int",
+ "ins_rem_det1",
+ "but_rel_det",
+ "but_press_det",
+ "ins_rem_det",
+ "mbhc_int",
+ "ear_ocp_int",
+ "hphr_ocp_int",
+ "hphl_ocp_det",
+ "ear_cnp_int",
+ "hphr_cnp_int",
+ "hphl_cnp_int";
+
+ cdc-vdda-cp-supply = <&pm8909_s2>;
+ qcom,cdc-vdda-cp-voltage = <1800000 2200000>;
+ qcom,cdc-vdda-cp-current = <500000>;
+
+ cdc-vdda-h-supply = <&pm8909_l5>;
+ qcom,cdc-vdda-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdda-h-current = <5000>;
+
+ cdc-vdd-px-supply = <&pm8909_l5>;
+ qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-px-current = <5000>;
+
+ cdc-vdd-pa-supply = <&pm8909_s2>;
+ qcom,cdc-vdd-pa-voltage = <1800000 2200000>;
+ qcom,cdc-vdd-pa-current = <260000>;
+
+ cdc-vdd-mic-bias-supply = <&pm8909_l13>;
+ qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
+ qcom,cdc-vdd-mic-bias-current = <5000>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+
+ qcom,cdc-static-supplies =
+ "cdc-vdda-h",
+ "cdc-vdd-px",
+ "cdc-vdd-pa",
+ "cdc-vdda-cp";
+
+ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+
+ msm_digital_codec: msm-dig-codec@f000 {
+ compatible = "qcom,msm-digital-codec";
+ reg = <0x771c000 0x100>;
+ };
+ };
};
&spk_vreg {
@@ -121,12 +271,11 @@
};
&pm8909_conga_dig {
- cdc-vdd-spkdrv-supply = <&spk_vreg>;
- qcom,cdc-vdd-spkdrv-voltage = <5000000 5000000>;
- qcom,cdc-vdd-spkdrv-current = <20000>;
- qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias",
- "cdc-vdd-spkdrv";
- qcom,subsys-name = "modem";
+ status = "disabled";
+};
+
+&pm8909_conga_analog {
+ status = "disabled";
};
&wcnss {
@@ -163,3 +312,34 @@
qcom,mdss-dsi-pwm-gpio = <&pm8909_mpps 4 0>;
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
};
+
+&soc {
+ qcom,msm-audio-apr {
+ compatible = "qcom,msm-audio-apr";
+ msm_audio_apr_dummy {
+ compatible = "qcom,msm-audio-apr-dummy";
+ };
+ };
+
+ qcom,avtimer@c0a300c {
+ compatible = "qcom,avtimer";
+ reg = <0x0c0a300c 0x4>,
+ <0x0c0a3010 0x4>;
+ reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
+ qcom,clk-div = <27>;
+ };
+
+ cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_pdm_lines_act>;
+ pinctrl-1 = <&cdc_pdm_lines_sus>;
+ };
+
+ cdc_us_euro_gpios: msm_cdc_pinctrl_us_euro {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cross_conn_det_act>;
+ pinctrl-1 = <&cross_conn_det_sus>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
index 8c8f175..8d643eb 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-coresight.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016, 2018, 2020, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -987,28 +987,30 @@
};
/* Venus CTI */
- cti_video_cpu0: cti@6134000 {
+ cti_video_cpu0: cti@6035000 {
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x6134000 0x1000>;
+ reg = <0x6035000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-video-cpu0";
+ status = "disabled";
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "apb_pclk";
};
/* Pronto CTI */
- cti_wcn_cpu0: cti@6139000 {
+ cti_wcn_cpu0: cti@6039000 {
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b966>;
- reg = <0x6139000 0x1000>;
+ reg = <0x6039000 0x1000>;
reg-names = "cti-base";
coresight-name = "coresight-cti-wcn-cpu0";
+ status = "disabled";
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "apb_pclk";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
index f82b68d..5dc808f 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018,2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -76,7 +76,7 @@
qcom,highest-bank-bit = <14>;
- qcom,snapshot-size = <1048576>; //bytes
+ qcom,snapshot-size = <0x200000>; //bytes
clocks = <&clock_gcc_gfx clk_gcc_oxili_gfx3d_clk>,
<&clock_gcc_gfx clk_gcc_oxili_ahb_clk>,
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts
new file mode 100644
index 0000000..eb9d5d4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA429 BG DVT2 WTP Overlay";
+ compatible = "qcom,sdm429w-qrd", "qcom,sda429w", "qcom,qrd";
+ qcom,msm-id = <437 0x0>;
+ qcom,board-id = <0x00010b 0xA>;
+ qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x1F00000>;
+};
+
+&adsp_fw_mem {
+ reg = <0x0 0x88700000 0x0 0x1500000>;
+};
+
+&wcnss_fw_mem {
+ reg = <0x0 0x89c00000 0x0 0x700000>;
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>;
+ /delete-property/ vdd-supply;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_te_active>;
+ pinctrl-1 = <&mdss_te_suspend>;
+ vddio-supply = <&L11A>;
+ qcom,platform-enable-gpio = <&pm660_gpios 12 0>;
+};
+
+&dsi_pm660_panel_pwr_supply {
+ /delete-node/ qcom,panel-supply-entry@0;
+};
+
+&usb_otg {
+ HSUSB_3p3-supply = <&L16A>;
+};
+
+&msm_dig_codec {
+ cdc-vdd-digital-supply = <&pm660_l11>;
+};
+
+&ext_smart_pa {
+ dvdd-supply = <&pm660_l11>;
+};
+
+&firmware {
+ android {
+ fstab {
+ system {
+ status = "disabled";
+ };
+ };
+ };
+};
+
+&msm_gpu {
+ qcom,initial-pwrlevel = <0>;
+ qcom,gpu-pwrlevels {
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <320000000>;
+ qcom,bus-freq = <2>;
+ qcom,bus-min = <2>;
+ qcom,bus-max = <2>;
+ };
+ qcom,gpu-pwrlevel@1{
+ reg = <1>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+};
+
+&msm_cpufreq {
+ qcom,cpufreq-table =
+ < 960000 >,
+ < 1305600 >,
+ < 1497600 >,
+ < 1708800 >;
+};
+
+&cpubw {
+ qcom,bw-tbl =
+ < 1611 /* 211.2 MHz */ >, /*Low SVS*/
+ < 2929 /* 384 MHz */ >, /* SVS */
+ < 5053 /* 662.4 MHz */ >, /* SVS+ */
+ < 5712 /* 748.8 MHz */ >; /* NOM */
+};
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts
new file mode 100644
index 0000000..859ca55
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 - 2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "sdm429-spyro.dtsi"
+#include "sdm429w-bg-pm660.dtsi"
+#include "sdm429-bg-memory.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA429 BG DVT2 WTP";
+ compatible = "qcom,sdm429w-qrd", "qcom,sda429w", "qcom,qrd";
+ qcom,msm-id = <437 0x0>;
+ qcom,board-id = <0x00010b 0xA>;
+ qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&msm_gpu {
+ /delete-property/qcom,enable-ca-jump;
+ /delete-property/qcom,ca-busy-penalty;
+ /delete-property/qcom,ca-target-pwrlevel;
+
+ qcom,gpu-pwrlevels {
+ /delete-node/qcom,gpu-pwrlevel@2;
+ /delete-node/qcom,gpu-pwrlevel@3;
+ /delete-node/qcom,gpu-pwrlevel@4;
+ /delete-node/qcom,gpu-pwrlevel@5;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-wdp-overlay.dts
index c34e945..8c021377 100644
--- a/arch/arm64/boot/dts/qcom/sda429-bg-wdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-wdp-overlay.dts
@@ -15,6 +15,7 @@
/plugin/;
#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDA429 QRD Spyro BG WDP Overlay";
@@ -24,125 +25,16 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
-&soc {
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x1F00000>;
+};
- qcom,blackghost {
- compatible = "qcom,pil-blackghost";
- qcom,pil-force-shutdown;
- qcom,firmware-name = "bg-wear";
- /* GPIO inputs from blackghost */
- qcom,bg2ap-status-gpio = <&tlmm 44 0>;
- qcom,bg2ap-errfatal-gpio = <&tlmm 72 0>;
- /* GPIO output to blackghost */
- qcom,ap2bg-status-gpio = <&tlmm 61 0>;
- qcom,ap2bg-errfatal-gpio = <&tlmm 62 0>;
- };
+&adsp_fw_mem {
+ reg = <0x0 0x88700000 0x0 0x1500000>;
+};
- qcom,msm-ssc-sensors {
- compatible = "qcom,msm-ssc-sensors";
- };
-
- qcom,glink-bgcom-xprt-bg {
- compatible = "qcom,glink-bgcom-xprt";
- label = "bg";
- qcom,qos-config = <&glink_qos_bg>;
- qcom,ramp-time = <0x10>,
- <0x20>,
- <0x30>,
- <0x40>;
- };
-
- glink_qos_bg: qcom,glink-qos-config-bg {
- compatible = "qcom,glink-qos-config";
- qcom,flow-info = <0x80 0x0>,
- <0x70 0x1>,
- <0x60 0x2>,
- <0x50 0x3>;
- qcom,mtu-size = <0x800>;
- qcom,tput-stats-cycle = <0xa>;
- };
-
- qcom,glink_pkt {
- compatible = "qcom,glinkpkt";
-
- qcom,glinkpkt-bg-daemon {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
- };
-
- qcom,glinkpkt-bg-daemon-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon-ctl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon_ctrl";
- };
-
- qcom,glinkpkt-bg-display-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
- };
-
- qcom,glinkpkt-bg-display-data {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-data";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
- };
-
- qcom,glinkpkt-bg-rsb-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "RSB_CTRL";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
- };
-
- qcom,glinkpkt-bg-sso-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "sso-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
- };
-
- qcom,glinkpkt-bg-buzzer-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "buzzer-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
- };
- };
-
- spi_3: spi@78b7000 { /* BLSP1 QUP3*/
- status = "ok";
- qcom,bg-spi {
- compatible = "qcom,bg-spi";
- reg = <0>;
- spi-max-frequency = <16000000>;
- interrupt-parent = <&tlmm>;
- qcom,irq-gpio = <&tlmm 43 1>;
- };
- };
-
- i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
- status = "disabled";
- };
-
- qcom,bg-rsb {
- compatible = "qcom,bg-rsb";
- vdd-ldo1-supply = <&pm660_l11>;
- qcom,bg-rsb-gpio = <&tlmm 40 1>;
- qcom,rsb-use-msm-gpio;
- };
-
- qcom,bg-daemon {
- compatible = "qcom,bg-daemon";
- qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
- ssr-reg1-supply = <&pm660_l3>;
- ssr-reg2-supply = <&pm660_l9>;
- };
+&wcnss_fw_mem {
+ reg = <0x0 0x89c00000 0x0 0x700000>;
};
&usb_otg {
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
index 39c1847..e8c11bb 100644
--- a/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-wtp-overlay.dts
@@ -15,6 +15,7 @@
/plugin/;
#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDA429 QRD BG WTP Overlay";
@@ -24,125 +25,16 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
-&soc {
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x1F00000>;
+};
- qcom,blackghost {
- compatible = "qcom,pil-blackghost";
- qcom,pil-force-shutdown;
- qcom,firmware-name = "bg-wear";
- /* GPIO inputs from blackghost */
- qcom,bg2ap-status-gpio = <&tlmm 44 0>;
- qcom,bg2ap-errfatal-gpio = <&tlmm 72 0>;
- /* GPIO output to blackghost */
- qcom,ap2bg-status-gpio = <&tlmm 61 0>;
- qcom,ap2bg-errfatal-gpio = <&tlmm 62 0>;
- };
+&adsp_fw_mem {
+ reg = <0x0 0x88700000 0x0 0x1500000>;
+};
- qcom,msm-ssc-sensors {
- compatible = "qcom,msm-ssc-sensors";
- };
-
- qcom,glink-bgcom-xprt-bg {
- compatible = "qcom,glink-bgcom-xprt";
- label = "bg";
- qcom,qos-config = <&glink_qos_bg>;
- qcom,ramp-time = <0x10>,
- <0x20>,
- <0x30>,
- <0x40>;
- };
-
- glink_qos_bg: qcom,glink-qos-config-bg {
- compatible = "qcom,glink-qos-config";
- qcom,flow-info = <0x80 0x0>,
- <0x70 0x1>,
- <0x60 0x2>,
- <0x50 0x3>;
- qcom,mtu-size = <0x800>;
- qcom,tput-stats-cycle = <0xa>;
- };
-
- qcom,glink_pkt {
- compatible = "qcom,glinkpkt";
-
- qcom,glinkpkt-bg-daemon {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
- };
-
- qcom,glinkpkt-bg-daemon-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon-ctl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon_ctrl";
- };
-
- qcom,glinkpkt-bg-display-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
- };
-
- qcom,glinkpkt-bg-display-data {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-data";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
- };
-
- qcom,glinkpkt-bg-rsb-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "RSB_CTRL";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
- };
-
- qcom,glinkpkt-bg-sso-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "sso-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
- };
-
- qcom,glinkpkt-bg-buzzer-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "buzzer-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
- };
- };
-
- spi_3: spi@78b7000 { /* BLSP1 QUP3*/
- status = "ok";
- qcom,bg-spi {
- compatible = "qcom,bg-spi";
- reg = <0>;
- spi-max-frequency = <16000000>;
- interrupt-parent = <&tlmm>;
- qcom,irq-gpio = <&tlmm 43 1>;
- };
- };
-
- i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
- status = "disabled";
- };
-
- qcom,bg-rsb {
- compatible = "qcom,bg-rsb";
- vdd-ldo1-supply = <&pm660_l11>;
- qcom,bg-rsb-gpio = <&tlmm 40 1>;
- qcom,rsb-use-msm-gpio;
- };
-
- qcom,bg-daemon {
- compatible = "qcom,bg-daemon";
- qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
- ssr-reg1-supply = <&pm660_l3>;
- ssr-reg2-supply = <&pm660_l9>;
- };
+&wcnss_fw_mem {
+ reg = <0x0 0x89c00000 0x0 0x700000>;
};
&mdss_dsi0 {
diff --git a/arch/arm64/boot/dts/qcom/sda429-spyro-qrd-dvt-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-spyro-qrd-dvt-overlay.dts
index 46fe9d5..2bab608 100644
--- a/arch/arm64/boot/dts/qcom/sda429-spyro-qrd-dvt-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sda429-spyro-qrd-dvt-overlay.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,18 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
+&modem_mem {
+ reg = <0x0 0x86800000 0x0 0x1F00000>;
+};
+
+&adsp_fw_mem {
+ reg = <0x0 0x88700000 0x0 0x1500000>;
+};
+
+&wcnss_fw_mem {
+ reg = <0x0 0x89c00000 0x0 0x700000>;
+};
+
&usb_otg {
HSUSB_3p3-supply = <&L16A>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts
new file mode 100644
index 0000000..b2f9204
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM429 BG DVT2 WTP Overlay";
+ compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
+ qcom,msm-id = <416 0x0>;
+ qcom,board-id = <0x00010b 0xA>;
+ qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>;
+ /delete-property/ vdd-supply;
+ vddio-supply = <&L11A>;
+ pinctrl-names = "mdss_default", "mdss_sleep";
+ pinctrl-0 = <&mdss_te_active>;
+ pinctrl-1 = <&mdss_te_suspend>;
+ qcom,platform-enable-gpio = <&pm660_gpios 12 0>;
+};
+
+&dsi_pm660_panel_pwr_supply {
+ /delete-node/ qcom,panel-supply-entry@0;
+};
+
+&usb_otg {
+ HSUSB_3p3-supply = <&L16A>;
+};
+
+&msm_dig_codec {
+ cdc-vdd-digital-supply = <&pm660_l11>;
+};
+
+&ext_smart_pa {
+ dvdd-supply = <&pm660_l11>;
+};
+
+&firmware {
+ android {
+ fstab {
+ system {
+ status = "disabled";
+ };
+ };
+ };
+};
+
+&msm_gpu {
+ qcom,initial-pwrlevel = <0>;
+ qcom,gpu-pwrlevels {
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <320000000>;
+ qcom,bus-freq = <2>;
+ qcom,bus-min = <2>;
+ qcom,bus-max = <2>;
+ };
+ qcom,gpu-pwrlevel@1{
+ reg = <1>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+};
+
+&msm_cpufreq {
+ qcom,cpufreq-table =
+ < 960000 >,
+ < 1305600 >,
+ < 1497600 >,
+ < 1708800 >;
+};
+&cpubw {
+ qcom,bw-tbl =
+ < 1611 /* 211.2 MHz */ >, /*Low SVS*/
+ < 2929 /* 384 MHz */ >, /* SVS */
+ < 5053 /* 662.4 MHz */ >, /* SVS+ */
+ < 5712 /* 748.8 MHz */ >; /* NOM */
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts
new file mode 100644
index 0000000..894986f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 - 2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+#include "sdm429-spyro.dtsi"
+#include "sdm429w-bg-pm660.dtsi"
+#include "sdm429-bg-memory.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM429 BG DVT2 WTP";
+ compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
+ qcom,msm-id = <416 0x0>;
+ qcom,board-id = <0x00010b 0xA>;
+ qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&msm_gpu {
+ /delete-property/qcom,enable-ca-jump;
+ /delete-property/qcom,ca-busy-penalty;
+ /delete-property/qcom,ca-target-pwrlevel;
+
+ qcom,gpu-pwrlevels {
+ /delete-node/qcom,gpu-pwrlevel@2;
+ /delete-node/qcom,gpu-pwrlevel@3;
+ /delete-node/qcom,gpu-pwrlevel@4;
+ /delete-node/qcom,gpu-pwrlevel@5;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
index 70bc00a..b91f161 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
@@ -22,7 +22,8 @@
model = "Qualcomm Technologies, Inc. SDM429 BG IOT WTP";
compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
qcom,msm-id = <416 0x0>;
- qcom,board-id = <0x00010b 8>;
+ qcom,board-id = <0x00010b 8>,
+ <0x00010b 0xA>;
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi b/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi
new file mode 100644
index 0000000..44bc91c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-soc.dtsi
@@ -0,0 +1,132 @@
+/* Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+&soc {
+
+ qcom,blackghost {
+ compatible = "qcom,pil-blackghost";
+ qcom,pil-force-shutdown;
+ qcom,firmware-name = "bg-wear";
+ /* GPIO inputs from blackghost */
+ qcom,bg2ap-status-gpio = <&tlmm 44 0>;
+ qcom,bg2ap-errfatal-gpio = <&tlmm 72 0>;
+ /* GPIO output to blackghost */
+ qcom,ap2bg-status-gpio = <&tlmm 61 0>;
+ qcom,ap2bg-errfatal-gpio = <&tlmm 62 0>;
+ };
+
+ qcom,msm-ssc-sensors {
+ compatible = "qcom,msm-ssc-sensors";
+ };
+
+ qcom,glink-bgcom-xprt-bg {
+ compatible = "qcom,glink-bgcom-xprt";
+ label = "bg";
+ qcom,qos-config = <&glink_qos_bg>;
+ qcom,ramp-time = <0x10>,
+ <0x20>,
+ <0x30>,
+ <0x40>;
+ };
+
+ glink_qos_bg: qcom,glink-qos-config-bg {
+ compatible = "qcom,glink-qos-config";
+ qcom,flow-info = <0x80 0x0>,
+ <0x70 0x1>,
+ <0x60 0x2>,
+ <0x50 0x3>;
+ qcom,mtu-size = <0x800>;
+ qcom,tput-stats-cycle = <0xa>;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-bg-daemon {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+ };
+
+ qcom,glinkpkt-bg-daemon-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "bg-daemon-ctl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+ };
+
+ qcom,glinkpkt-bg-display-data {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "display-data";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+ };
+
+ qcom,glinkpkt-bg-rsb-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "RSB_CTRL";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+ };
+
+ qcom,glinkpkt-bg-sso-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "sso-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
+ };
+
+ qcom,glinkpkt-bg-buzzer-ctrl {
+ qcom,glinkpkt-transport = "bgcom";
+ qcom,glinkpkt-edge = "bg";
+ qcom,glinkpkt-ch-name = "buzzer-ctrl";
+ qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
+ };
+ };
+
+ spi_3: spi@78b7000 { /* BLSP1 QUP3*/
+ status = "ok";
+ qcom,bg-spi {
+ compatible = "qcom,bg-spi";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ interrupt-parent = <&tlmm>;
+ qcom,irq-gpio = <&tlmm 43 1>;
+ };
+ };
+
+ i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
+ status = "disabled";
+ };
+
+ qcom,bg-rsb {
+ compatible = "qcom,bg-rsb";
+ vdd-ldo1-supply = <&pm660_l11>;
+ qcom,bg-rsb-gpio = <&tlmm 40 1>;
+ qcom,rsb-use-msm-gpio;
+ };
+
+ qcom,bg-daemon {
+ compatible = "qcom,bg-daemon";
+ qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+ ssr-reg1-supply = <&pm660_l3>;
+ ssr-reg2-supply = <&pm660_l9>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
index 2a4a02d2..b92688c 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-wdp-overlay.dts
@@ -15,6 +15,7 @@
/plugin/;
#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM429 QRD BG WDP Overlay";
@@ -24,127 +25,6 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
-&soc {
-
- qcom,blackghost {
- compatible = "qcom,pil-blackghost";
- qcom,pil-force-shutdown;
- qcom,firmware-name = "bg-wear";
- /* GPIO inputs from blackghost */
- qcom,bg2ap-status-gpio = <&tlmm 44 0>;
- qcom,bg2ap-errfatal-gpio = <&tlmm 72 0>;
- /* GPIO output to blackghost */
- qcom,ap2bg-status-gpio = <&tlmm 61 0>;
- qcom,ap2bg-errfatal-gpio = <&tlmm 62 0>;
- };
-
- qcom,msm-ssc-sensors {
- compatible = "qcom,msm-ssc-sensors";
- };
-
- qcom,glink-bgcom-xprt-bg {
- compatible = "qcom,glink-bgcom-xprt";
- label = "bg";
- qcom,qos-config = <&glink_qos_bg>;
- qcom,ramp-time = <0x10>,
- <0x20>,
- <0x30>,
- <0x40>;
- };
-
- glink_qos_bg: qcom,glink-qos-config-bg {
- compatible = "qcom,glink-qos-config";
- qcom,flow-info = <0x80 0x0>,
- <0x70 0x1>,
- <0x60 0x2>,
- <0x50 0x3>;
- qcom,mtu-size = <0x800>;
- qcom,tput-stats-cycle = <0xa>;
- };
-
- qcom,glink_pkt {
- compatible = "qcom,glinkpkt";
-
- qcom,glinkpkt-bg-daemon {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
- };
-
- qcom,glinkpkt-bg-daemon-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon-ctl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon_ctrl";
- };
-
- qcom,glinkpkt-bg-display-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
- };
-
- qcom,glinkpkt-bg-display-data {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-data";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
- };
-
- qcom,glinkpkt-bg-rsb-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "RSB_CTRL";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
- };
-
- qcom,glinkpkt-bg-sso-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "sso-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
- };
-
- qcom,glinkpkt-bg-buzzer-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "buzzer-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
- };
- };
-
- spi_3: spi@78b7000 { /*BLSP1 QUP3*/
- status = "ok";
- qcom,bg-spi {
- compatible = "qcom,bg-spi";
- reg = <0>;
- spi-max-frequency = <16000000>;
- interrupt-parent = <&tlmm>;
- qcom,irq-gpio = <&tlmm 43 1>;
- };
- };
-
- i2c_3: i2c@78b8000 { /* BLSP1 QUP3 */
- status = "disabled";
- };
-
- qcom,bg-rsb {
- compatible = "qcom,bg-rsb";
- vdd-ldo1-supply = <&pm660_l11>;
- qcom,bg-rsb-gpio = <&tlmm 40 1>;
- qcom,rsb-use-msm-gpio;
- };
-
- qcom,bg-daemon {
- compatible = "qcom,bg-daemon";
- qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
- ssr-reg1-supply = <&pm660_l3>;
- ssr-reg2-supply = <&pm660_l9>;
- };
-};
-
&usb_otg {
HSUSB_3p3-supply = <&L16A>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-wtp-overlay.dts
index a0ea543..d91e397 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-bg-wtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-wtp-overlay.dts
@@ -15,7 +15,7 @@
/plugin/;
#include "sdm429-spyro-qrd-evt.dtsi"
-
+#include "sdm429-bg-soc.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM429 QRD BG WTP Overlay";
compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
@@ -24,127 +24,6 @@
qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
};
-&soc {
-
- qcom,blackghost {
- compatible = "qcom,pil-blackghost";
- qcom,pil-force-shutdown;
- qcom,firmware-name = "bg-wear";
- /* GPIO inputs from blackghost */
- qcom,bg2ap-status-gpio = <&tlmm 44 0>;
- qcom,bg2ap-errfatal-gpio = <&tlmm 72 0>;
- /* GPIO output to blackghost */
- qcom,ap2bg-status-gpio = <&tlmm 61 0>;
- qcom,ap2bg-errfatal-gpio = <&tlmm 62 0>;
- };
-
- qcom,msm-ssc-sensors {
- compatible = "qcom,msm-ssc-sensors";
- };
-
- qcom,glink-bgcom-xprt-bg {
- compatible = "qcom,glink-bgcom-xprt";
- label = "bg";
- qcom,qos-config = <&glink_qos_bg>;
- qcom,ramp-time = <0x10>,
- <0x20>,
- <0x30>,
- <0x40>;
- };
-
- glink_qos_bg: qcom,glink-qos-config-bg {
- compatible = "qcom,glink-qos-config";
- qcom,flow-info = <0x80 0x0>,
- <0x70 0x1>,
- <0x60 0x2>,
- <0x50 0x3>;
- qcom,mtu-size = <0x800>;
- qcom,tput-stats-cycle = <0xa>;
- };
-
- qcom,glink_pkt {
- compatible = "qcom,glinkpkt";
-
- qcom,glinkpkt-bg-daemon {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
- };
-
- qcom,glinkpkt-bg-daemon-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "bg-daemon-ctl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon_ctrl";
- };
-
- qcom,glinkpkt-bg-display-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
- };
-
- qcom,glinkpkt-bg-display-data {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "display-data";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
- };
-
- qcom,glinkpkt-bg-rsb-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "RSB_CTRL";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
- };
-
- qcom,glinkpkt-bg-sso-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "sso-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_sso_ctrl";
- };
-
- qcom,glinkpkt-bg-buzzer-ctrl {
- qcom,glinkpkt-transport = "bgcom";
- qcom,glinkpkt-edge = "bg";
- qcom,glinkpkt-ch-name = "buzzer-ctrl";
- qcom,glinkpkt-dev-name = "glink_pkt_bg_buzzer_ctrl";
- };
- };
-
- spi_3: spi@78b7000 { /* BLSP1 QUP3*/
- status = "ok";
- qcom,bg-spi {
- compatible = "qcom,bg-spi";
- reg = <0>;
- spi-max-frequency = <16000000>;
- interrupt-parent = <&tlmm>;
- qcom,irq-gpio = <&tlmm 43 1>;
- };
- };
-
- i2c_3: i2c@78b7000 { /* BLSP1 QUP3 */
- status = "disabled";
- };
-
- qcom,bg-rsb {
- compatible = "qcom,bg-rsb";
- vdd-ldo1-supply = <&pm660_l11>;
- qcom,bg-rsb-gpio = <&tlmm 40 1>;
- qcom,rsb-use-msm-gpio;
- };
-
- qcom,bg-daemon {
- compatible = "qcom,bg-daemon";
- qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
- ssr-reg1-supply = <&pm660_l3>;
- ssr-reg2-supply = <&pm660_l9>;
- };
-};
-
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>;
/delete-property/ vdd-supply;
diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
index 567389a..1f25e56 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -486,6 +486,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 0>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -520,6 +521,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 1>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -554,6 +556,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 2>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -588,6 +591,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 3>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -622,6 +626,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 4>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -656,6 +661,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 5>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -690,6 +696,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 6>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -724,6 +731,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 7>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -758,6 +766,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 8>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -792,6 +801,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 9>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -826,6 +836,7 @@
polling-delay = <0>;
thermal-governor = "low_limits_floor";
thermal-sensors = <&tsens0 10>;
+ wake-capable-sensor;
tracks-low;
trips {
@@ -892,6 +903,7 @@
polling-delay = <0>;
thermal-sensors = <&pm660_adc_tm 0x51>;
thermal-governor = "step_wise";
+ wake-capable-sensor;
trips {
quiet_batt_439_trip1: quiet-batt-trip1 {
diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi
index 004011c..d993dc2 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-spyro.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019,2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,7 +33,7 @@
"/dev/block/platform/soc/7824900.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,avb";
status = "ok";
};
system {
@@ -42,7 +42,7 @@
"/dev/block/platform/soc/7824900.sdhci/by-name/system";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait";
+ fsmgr_flags = "wait,avb";
status = "ok";
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429w-bg-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm429w-bg-pm660.dtsi
index bb73889..f453259 100644
--- a/arch/arm64/boot/dts/qcom/sdm429w-bg-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429w-bg-pm660.dtsi
@@ -29,7 +29,3 @@
&pm660_fg {
qcom,fg-disable-in-twm;
};
-
-&pm660_haptics {
- qcom,haptics-ext-pin-twm;
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
index a6535ac..8aaaebb 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -402,10 +402,10 @@
};
/* 9282 CCI0 */
- qcom,cam-sensor@2 {
- cell-index = <2>;
+ qcom,cam-sensor@4 {
+ cell-index = <4>;
compatible = "qcom,cam-sensor";
- reg = <0x02>;
+ reg = <0x04>;
csiphy-sd-index = <2>;
sensor-position-roll = <270>;
sensor-position-pitch = <0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index d7b1b06..5990f9b 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -3004,6 +3004,7 @@
parent-supply = <&pm660l_s2_level>;
domain-addr = <&gpu_gx_domain_addr>;
sw-reset = <&gpu_gx_sw_reset>;
+ qcom,skip-disable-before-sw-enable;
qcom,reset-aon-logic;
status = "ok";
};
diff --git a/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi b/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
index 40aceac..16ed764 100644
--- a/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
@@ -518,3 +518,17 @@
&cdc_pdm_gpios {
status = "disabled";
};
+
+&lcdb_ldo_vreg {
+ regulator-min-microvolt = <5700000>;
+ regulator-max-microvolt = <5700000>;
+};
+
+&lcdb_ncp_vreg {
+ regulator-min-microvolt = <5700000>;
+ regulator-max-microvolt = <5700000>;
+};
+
+&pm660_pdphy {
+ qcom,sxr1130-sxr-dp-sink;
+};
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index 7e842dc..b7205c2 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -29,13 +29,16 @@
void __init apply_alternatives_all(void);
void apply_alternatives(void *start, size_t length);
-#define ALTINSTR_ENTRY(feature,cb) \
+#define ALTINSTR_ENTRY(feature) \
" .word 661b - .\n" /* label */ \
- " .if " __stringify(cb) " == 0\n" \
" .word 663f - .\n" /* new instruction */ \
- " .else\n" \
+ " .hword " __stringify(feature) "\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* source len */ \
+ " .byte 664f-663f\n" /* replacement len */
+
+#define ALTINSTR_ENTRY_CB(feature, cb) \
+ " .word 661b - .\n" /* label */ \
" .word " __stringify(cb) "- .\n" /* callback */ \
- " .endif\n" \
" .hword " __stringify(feature) "\n" /* feature bit */ \
" .byte 662b-661b\n" /* source len */ \
" .byte 664f-663f\n" /* replacement len */
@@ -56,15 +59,14 @@
*
* Alternatives with callbacks do not generate replacement instructions.
*/
-#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \
+#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
".if "__stringify(cfg_enabled)" == 1\n" \
"661:\n\t" \
oldinstr "\n" \
"662:\n" \
".pushsection .altinstructions,\"a\"\n" \
- ALTINSTR_ENTRY(feature,cb) \
+ ALTINSTR_ENTRY(feature) \
".popsection\n" \
- " .if " __stringify(cb) " == 0\n" \
".pushsection .altinstr_replacement, \"a\"\n" \
"663:\n\t" \
newinstr "\n" \
@@ -72,17 +74,25 @@
".popsection\n\t" \
".org . - (664b-663b) + (662b-661b)\n\t" \
".org . - (662b-661b) + (664b-663b)\n" \
- ".else\n\t" \
+ ".endif\n"
+
+#define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb) \
+ ".if "__stringify(cfg_enabled)" == 1\n" \
+ "661:\n\t" \
+ oldinstr "\n" \
+ "662:\n" \
+ ".pushsection .altinstructions,\"a\"\n" \
+ ALTINSTR_ENTRY_CB(feature, cb) \
+ ".popsection\n" \
"663:\n\t" \
"664:\n\t" \
- ".endif\n" \
".endif\n"
#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
- __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
+ __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))
#define ALTERNATIVE_CB(oldinstr, cb) \
- __ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
+ __ALTERNATIVE_CFG_CB(oldinstr, ARM64_CB_PATCH, 1, cb)
#else
#include <asm/assembler.h>
@@ -205,7 +215,7 @@
.macro user_alt, label, oldinstr, newinstr, cond
9999: alternative_insn "\oldinstr", "\newinstr", \cond
- _ASM_EXTABLE 9999b, \label
+ _asm_extable 9999b, \label
.endm
/*
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index 825b0fe..13a97aa 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -2,21 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += kvm_para.h
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += fcntl.h
-header-y += hwcap.h
-header-y += kvm_para.h
-header-y += perf_regs.h
-header-y += param.h
-header-y += ptrace.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += stat.h
-header-y += statfs.h
-header-y += ucontext.h
-header-y += unistd.h
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
old mode 100644
new mode 100755
index a91fbc4..b6d3274
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1014,11 +1014,29 @@
}
#endif
+/*
+ * The number of CPUs online, not counting this CPU (which may not be
+ * fully online and so not counted in num_online_cpus()).
+ */
+static inline unsigned int num_other_online_cpus(void)
+{
+ unsigned int this_cpu_online = cpu_online(smp_processor_id());
+
+ return num_online_cpus() - this_cpu_online;
+}
+
+static inline unsigned int num_other_active_cpus(void)
+{
+ unsigned int this_cpu_active = cpu_active(smp_processor_id());
+
+ return num_active_cpus() - this_cpu_active;
+}
+
void smp_send_stop(void)
{
unsigned long timeout;
- if (num_online_cpus() > 1) {
+ if (num_other_online_cpus()) {
cpumask_t mask;
cpumask_copy(&mask, cpu_online_mask);
@@ -1032,10 +1050,11 @@
/* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC;
- while (num_active_cpus() > 1 && timeout--)
+
+ while (num_other_active_cpus() && timeout--)
udelay(1);
- if (num_active_cpus() > 1)
+ if (num_other_active_cpus())
pr_warning("SMP: failed to stop secondary CPUs %*pbl\n",
cpumask_pr_args(cpu_online_mask));
}
diff --git a/arch/blackfin/include/uapi/asm/Kbuild b/arch/blackfin/include/uapi/asm/Kbuild
index 0bd28f7..b15bf6b 100644
--- a/arch/blackfin/include/uapi/asm/Kbuild
+++ b/arch/blackfin/include/uapi/asm/Kbuild
@@ -1,19 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += bfin_sport.h
-header-y += byteorder.h
-header-y += cachectl.h
-header-y += fcntl.h
-header-y += fixed_code.h
-header-y += ioctls.h
-header-y += kvm_para.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += stat.h
-header-y += swab.h
-header-y += unistd.h
diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild
index e9bc2b2..13a97aa 100644
--- a/arch/c6x/include/uapi/asm/Kbuild
+++ b/arch/c6x/include/uapi/asm/Kbuild
@@ -2,11 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += kvm_para.h
-
-header-y += byteorder.h
-header-y += kvm_para.h
-header-y += ptrace.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += swab.h
-header-y += unistd.h
diff --git a/arch/cris/include/uapi/arch-v10/arch/Kbuild b/arch/cris/include/uapi/arch-v10/arch/Kbuild
deleted file mode 100644
index 9048c87..0000000
--- a/arch/cris/include/uapi/arch-v10/arch/Kbuild
+++ /dev/null
@@ -1,5 +0,0 @@
-# UAPI Header export list
-header-y += sv_addr.agh
-header-y += sv_addr_ag.h
-header-y += svinto.h
-header-y += user.h
diff --git a/arch/cris/include/uapi/arch-v32/arch/Kbuild b/arch/cris/include/uapi/arch-v32/arch/Kbuild
deleted file mode 100644
index 59efffd..0000000
--- a/arch/cris/include/uapi/arch-v32/arch/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += cryptocop.h
-header-y += user.h
diff --git a/arch/cris/include/uapi/asm/Kbuild b/arch/cris/include/uapi/asm/Kbuild
index d5564a0..b15bf6b 100644
--- a/arch/cris/include/uapi/asm/Kbuild
+++ b/arch/cris/include/uapi/asm/Kbuild
@@ -1,44 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += ../arch-v10/arch/
-header-y += ../arch-v32/arch/
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += elf.h
-header-y += elf_v10.h
-header-y += elf_v32.h
-header-y += errno.h
-header-y += ethernet.h
-header-y += etraxgpio.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += ptrace_v10.h
-header-y += ptrace_v32.h
-header-y += resource.h
-header-y += rs485.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += sync_serial.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/frv/include/uapi/asm/Kbuild b/arch/frv/include/uapi/asm/Kbuild
index 42a2b33..b15bf6b 100644
--- a/arch/frv/include/uapi/asm/Kbuild
+++ b/arch/frv/include/uapi/asm/Kbuild
@@ -1,35 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += registers.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/h8300/include/uapi/asm/Kbuild b/arch/h8300/include/uapi/asm/Kbuild
index fb6101a..b15bf6b 100644
--- a/arch/h8300/include/uapi/asm/Kbuild
+++ b/arch/h8300/include/uapi/asm/Kbuild
@@ -1,30 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += siginfo.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index db8ddab..f3b1ceb 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -1,6 +1,3 @@
-
-header-y += ucontext.h
-
generic-y += auxvec.h
generic-y += barrier.h
generic-y += bug.h
diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild
index c31706c..b15bf6b 100644
--- a/arch/hexagon/include/uapi/asm/Kbuild
+++ b/arch/hexagon/include/uapi/asm/Kbuild
@@ -1,15 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += kvm_para.h
-header-y += param.h
-header-y += ptrace.h
-header-y += registers.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += signal.h
-header-y += swab.h
-header-y += unistd.h
-header-y += user.h
diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild
index 891002b..13a97aa 100644
--- a/arch/ia64/include/uapi/asm/Kbuild
+++ b/arch/ia64/include/uapi/asm/Kbuild
@@ -2,48 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += kvm_para.h
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += break.h
-header-y += byteorder.h
-header-y += cmpxchg.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += fpu.h
-header-y += gcc_intrin.h
-header-y += ia64regs.h
-header-y += intel_intrin.h
-header-y += intrinsics.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += perfmon.h
-header-y += perfmon_default_smpl.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += ptrace_offsets.h
-header-y += resource.h
-header-y += rse.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
-header-y += ustack.h
diff --git a/arch/m32r/include/uapi/asm/Kbuild b/arch/m32r/include/uapi/asm/Kbuild
index 43937a6..b15bf6b 100644
--- a/arch/m32r/include/uapi/asm/Kbuild
+++ b/arch/m32r/include/uapi/asm/Kbuild
@@ -1,33 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/m68k/include/uapi/asm/Kbuild b/arch/m68k/include/uapi/asm/Kbuild
index 6a2d257..6436807 100644
--- a/arch/m68k/include/uapi/asm/Kbuild
+++ b/arch/m68k/include/uapi/asm/Kbuild
@@ -9,27 +9,3 @@
generic-y += sockios.h
generic-y += termbits.h
generic-y += termios.h
-
-header-y += a.out.h
-header-y += bootinfo.h
-header-y += bootinfo-amiga.h
-header-y += bootinfo-apollo.h
-header-y += bootinfo-atari.h
-header-y += bootinfo-hp300.h
-header-y += bootinfo-mac.h
-header-y += bootinfo-q40.h
-header-y += bootinfo-vme.h
-header-y += byteorder.h
-header-y += cachectl.h
-header-y += fcntl.h
-header-y += ioctls.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += signal.h
-header-y += stat.h
-header-y += swab.h
-header-y += unistd.h
diff --git a/arch/metag/include/uapi/asm/Kbuild b/arch/metag/include/uapi/asm/Kbuild
index ab78be2..b29731e 100644
--- a/arch/metag/include/uapi/asm/Kbuild
+++ b/arch/metag/include/uapi/asm/Kbuild
@@ -1,14 +1,6 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += byteorder.h
-header-y += ech.h
-header-y += ptrace.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += swab.h
-header-y += unistd.h
-
generic-y += mman.h
generic-y += resource.h
generic-y += setup.h
diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild
index 1aac99f..2178c78 100644
--- a/arch/microblaze/include/uapi/asm/Kbuild
+++ b/arch/microblaze/include/uapi/asm/Kbuild
@@ -2,35 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += types.h
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += elf.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += unistd.h
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 0bde47e..dcba538 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -92,7 +92,8 @@
#define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size) \
do { \
int align = ~(cache_line_length - 1); \
- end = min(start + cache_size, end); \
+ if (start < UINT_MAX - cache_size) \
+ end = min(start + cache_size, end); \
start &= align; \
} while (0)
diff --git a/arch/mips/include/uapi/asm/Kbuild b/arch/mips/include/uapi/asm/Kbuild
index f2cf414..a0266fe 100644
--- a/arch/mips/include/uapi/asm/Kbuild
+++ b/arch/mips/include/uapi/asm/Kbuild
@@ -2,40 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += ipcbuf.h
-
-header-y += auxvec.h
-header-y += bitfield.h
-header-y += bitsperlong.h
-header-y += break.h
-header-y += byteorder.h
-header-y += cachectl.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += inst.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += sgidefs.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += sysmips.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 544ea21..b2683ac 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -134,7 +134,7 @@
{
list_del(&v->list);
if (v->load_addr)
- release_progmem(v);
+ release_progmem(v->load_addr);
kfree(v);
}
diff --git a/arch/mips/loongson64/loongson-3/platform.c b/arch/mips/loongson64/loongson-3/platform.c
index 25a97cc..0db4cc3 100644
--- a/arch/mips/loongson64/loongson-3/platform.c
+++ b/arch/mips/loongson64/loongson-3/platform.c
@@ -31,6 +31,9 @@
continue;
pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
pdev->name = loongson_sysconf.sensors[i].name;
pdev->id = loongson_sysconf.sensors[i].id;
pdev->dev.platform_data = &loongson_sysconf.sensors[i];
diff --git a/arch/mn10300/include/uapi/asm/Kbuild b/arch/mn10300/include/uapi/asm/Kbuild
index 040178c..b15bf6b 100644
--- a/arch/mn10300/include/uapi/asm/Kbuild
+++ b/arch/mn10300/include/uapi/asm/Kbuild
@@ -1,34 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/nios2/include/uapi/asm/Kbuild b/arch/nios2/include/uapi/asm/Kbuild
index e0bb972..0c74c3c 100644
--- a/arch/nios2/include/uapi/asm/Kbuild
+++ b/arch/nios2/include/uapi/asm/Kbuild
@@ -1,5 +1,4 @@
+# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += elf.h
-
generic-y += ucontext.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 2832f03..5619157 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -1,6 +1,3 @@
-
-header-y += ucontext.h
-
generic-y += atomic.h
generic-y += auxvec.h
generic-y += barrier.h
diff --git a/arch/openrisc/include/uapi/asm/Kbuild b/arch/openrisc/include/uapi/asm/Kbuild
index 80761eb..b15bf6b 100644
--- a/arch/openrisc/include/uapi/asm/Kbuild
+++ b/arch/openrisc/include/uapi/asm/Kbuild
@@ -1,10 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += byteorder.h
-header-y += elf.h
-header-y += kvm_para.h
-header-y += param.h
-header-y += ptrace.h
-header-y += sigcontext.h
-header-y += unistd.h
diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild
index 348356c..3971c60 100644
--- a/arch/parisc/include/uapi/asm/Kbuild
+++ b/arch/parisc/include/uapi/asm/Kbuild
@@ -2,31 +2,3 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += resource.h
-
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += pdc.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 062b006..a4632af 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -86,6 +86,7 @@
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select OF
+ select OF_DMA_DEFAULT_COHERENT if !NOT_COHERENT_CACHE
select OF_EARLY_FLATTREE
select OF_RESERVED_MEM
select HAVE_FTRACE_MCOUNT_RECORD
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 9d3bd4c..1c4354f 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -232,7 +232,7 @@
dpath = 8; /* 64 bits */
/* get address pins (rows) */
- val = SDRAM0_READ(DDR0_42);
+ val = SDRAM0_READ(DDR0_42);
row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
if (row > max_row)
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild
index dab3717..b15bf6b 100644
--- a/arch/powerpc/include/uapi/asm/Kbuild
+++ b/arch/powerpc/include/uapi/asm/Kbuild
@@ -1,47 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += bootx.h
-header-y += byteorder.h
-header-y += cputable.h
-header-y += eeh.h
-header-y += elf.h
-header-y += epapr_hcalls.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += nvram.h
-header-y += opal-prd.h
-header-y += param.h
-header-y += perf_event.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ps3fb.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += spu_info.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += tm.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 7471ed4..514e04b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2199,11 +2199,13 @@
* oprofile_cpu_type already has a value, then we are
* possibly overriding a real PVR with a logical one,
* and, in that case, keep the current value for
- * oprofile_cpu_type.
+ * oprofile_cpu_type. Futhermore, let's ensure that the
+ * fix for the PMAO bug is enabled on compatibility mode.
*/
if (old.oprofile_cpu_type != NULL) {
t->oprofile_cpu_type = old.oprofile_cpu_type;
t->oprofile_type = old.oprofile_type;
+ t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG;
}
}
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 620e08d..adac3de 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -520,12 +520,6 @@
pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0);
edev->pdev = NULL;
-
- /*
- * We have to set the VF PE number to invalid one, which is
- * required to plug the VF successfully.
- */
- pdn->pe_number = IODA_INVALID_PE;
#endif
if (rmv_data)
list_add(&edev->rmv_list, &rmv_data->edev_list);
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 5926934..c8f1b78 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -271,9 +271,22 @@
continue;
#ifdef CONFIG_EEH
- /* Release EEH device for the VF */
+ /*
+ * Release EEH state for this VF. The PCI core
+ * has already torn down the pci_dev for this VF, but
+ * we're responsible to removing the eeh_dev since it
+ * has the same lifetime as the pci_dn that spawned it.
+ */
edev = pdn_to_eeh_dev(pdn);
if (edev) {
+ /*
+ * We allocate pci_dn's for the totalvfs count,
+ * but only only the vfs that were activated
+ * have a configured PE.
+ */
+ if (edev->pe)
+ eeh_rmv_from_parent_pe(edev);
+
pdn->edev = NULL;
kfree(edev);
}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 50d3650..c205104 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -315,6 +315,12 @@
*(.branch_lt)
}
+#ifdef CONFIG_DEBUG_INFO_BTF
+ .BTF : AT(ADDR(.BTF) - LOAD_OFFSET) {
+ *(.BTF)
+ }
+#endif
+
.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
*(.opd)
}
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index e840f94..5cf1392 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1766,7 +1766,7 @@
mutex_unlock(&kvm->lock);
if (!vcore)
- goto free_vcpu;
+ goto uninit_vcpu;
spin_lock(&vcore->lock);
++vcore->num_threads;
@@ -1782,6 +1782,8 @@
return vcpu;
+uninit_vcpu:
+ kvm_vcpu_uninit(vcpu);
free_vcpu:
kmem_cache_free(kvm_vcpu_cache, vcpu);
out:
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index e0d88d0..8172021 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1482,10 +1482,12 @@
err = kvmppc_mmu_init(vcpu);
if (err < 0)
- goto uninit_vcpu;
+ goto free_shared_page;
return vcpu;
+free_shared_page:
+ free_page((unsigned long)vcpu->arch.shared);
uninit_vcpu:
kvm_vcpu_uninit(vcpu);
free_shadow_vcpu:
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3ec673b..b787a66 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1524,6 +1524,10 @@
/* Reserve PE for each VF */
for (vf_index = 0; vf_index < num_vfs; vf_index++) {
+ int vf_devfn = pci_iov_virtfn_devfn(pdev, vf_index);
+ int vf_bus = pci_iov_virtfn_bus(pdev, vf_index);
+ struct pci_dn *vf_pdn;
+
if (pdn->m64_single_mode)
pe_num = pdn->pe_num_map[vf_index];
else
@@ -1536,13 +1540,11 @@
pe->pbus = NULL;
pe->parent_dev = pdev;
pe->mve_number = -1;
- pe->rid = (pci_iov_virtfn_bus(pdev, vf_index) << 8) |
- pci_iov_virtfn_devfn(pdev, vf_index);
+ pe->rid = (vf_bus << 8) | vf_devfn;
pe_info(pe, "VF %04d:%02d:%02d.%d associated with PE#%d\n",
hose->global_number, pdev->bus->number,
- PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)),
- PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)), pe_num);
+ PCI_SLOT(vf_devfn), PCI_FUNC(vf_devfn), pe_num);
if (pnv_ioda_configure_pe(phb, pe)) {
/* XXX What do we do here ? */
@@ -1556,6 +1558,15 @@
list_add_tail(&pe->list, &phb->ioda.pe_list);
mutex_unlock(&phb->ioda.pe_list_mutex);
+ /* associate this pe to it's pdn */
+ list_for_each_entry(vf_pdn, &pdn->parent->child_list, list) {
+ if (vf_pdn->busno == vf_bus &&
+ vf_pdn->devfn == vf_devfn) {
+ vf_pdn->pe_number = pe_num;
+ break;
+ }
+ }
+
pnv_pci_ioda2_setup_dma_pe(phb, pe);
}
}
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 00dbf1e8..2ed7627 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -856,16 +856,12 @@
struct pnv_phb *phb = hose->private_data;
#ifdef CONFIG_PCI_IOV
struct pnv_ioda_pe *pe;
- struct pci_dn *pdn;
/* Fix the VF pdn PE number */
if (pdev->is_virtfn) {
- pdn = pci_get_pdn(pdev);
- WARN_ON(pdn->pe_number != IODA_INVALID_PE);
list_for_each_entry(pe, &phb->ioda.pe_list, list) {
if (pe->rid == ((pdev->bus->number << 8) |
(pdev->devfn & 0xff))) {
- pdn->pe_number = pe->pe_number;
pe->pdev = pdev;
break;
}
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 6c12b02..eee45b9 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -398,8 +398,10 @@
for (i = 0; i < scns_per_block; i++) {
pfn = PFN_DOWN(phys_addr);
- if (!pfn_present(pfn))
+ if (!pfn_present(pfn)) {
+ phys_addr += MIN_MEMORY_BLOCK_SIZE;
continue;
+ }
rc &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
phys_addr += MIN_MEMORY_BLOCK_SIZE;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 0024e45..c0f094c 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -167,10 +167,10 @@
return be64_to_cpu(*tcep);
}
-static void tce_free_pSeriesLP(struct iommu_table*, long, long);
+static void tce_free_pSeriesLP(unsigned long liobn, long, long);
static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long);
-static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
+static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift,
long npages, unsigned long uaddr,
enum dma_data_direction direction,
unsigned long attrs)
@@ -181,25 +181,25 @@
int ret = 0;
long tcenum_start = tcenum, npages_start = npages;
- rpn = __pa(uaddr) >> TCE_SHIFT;
+ rpn = __pa(uaddr) >> tceshift;
proto_tce = TCE_PCI_READ;
if (direction != DMA_TO_DEVICE)
proto_tce |= TCE_PCI_WRITE;
while (npages--) {
- tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
- rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
+ tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
+ rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
ret = (int)rc;
- tce_free_pSeriesLP(tbl, tcenum_start,
+ tce_free_pSeriesLP(liobn, tcenum_start,
(npages_start - (npages + 1)));
break;
}
if (rc && printk_ratelimit()) {
printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
- printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
+ printk("\tindex = 0x%llx\n", (u64)liobn);
printk("\ttcenum = 0x%llx\n", (u64)tcenum);
printk("\ttce val = 0x%llx\n", tce );
dump_stack();
@@ -228,7 +228,8 @@
unsigned long flags;
if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
- return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+ return tce_build_pSeriesLP(tbl->it_index, tcenum,
+ tbl->it_page_shift, npages, uaddr,
direction, attrs);
}
@@ -244,8 +245,9 @@
/* If allocation fails, fall back to the loop implementation */
if (!tcep) {
local_irq_restore(flags);
- return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
- direction, attrs);
+ return tce_build_pSeriesLP(tbl->it_index, tcenum,
+ tbl->it_page_shift,
+ npages, uaddr, direction, attrs);
}
__this_cpu_write(tce_page, tcep);
}
@@ -296,16 +298,16 @@
return ret;
}
-static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
+static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
{
u64 rc;
while (npages--) {
- rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
+ rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);
if (rc && printk_ratelimit()) {
printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
- printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
+ printk("\tindex = 0x%llx\n", (u64)liobn);
printk("\ttcenum = 0x%llx\n", (u64)tcenum);
dump_stack();
}
@@ -320,7 +322,7 @@
u64 rc;
if (!firmware_has_feature(FW_FEATURE_MULTITCE))
- return tce_free_pSeriesLP(tbl, tcenum, npages);
+ return tce_free_pSeriesLP(tbl->it_index, tcenum, npages);
rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
@@ -435,6 +437,19 @@
u64 rc = 0;
long l, limit;
+ if (!firmware_has_feature(FW_FEATURE_MULTITCE)) {
+ unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
+ unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
+ be64_to_cpu(maprange->dma_base);
+ unsigned long tcenum = dmastart >> tceshift;
+ unsigned long npages = num_pfn << PAGE_SHIFT >> tceshift;
+ void *uaddr = __va(start_pfn << PAGE_SHIFT);
+
+ return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
+ tcenum, tceshift, npages, (unsigned long) uaddr,
+ DMA_BIDIRECTIONAL, 0);
+ }
+
local_irq_disable(); /* to protect tcep and the page behind it */
tcep = __this_cpu_read(tce_page);
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 69b8a41..e094c0c 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -35,7 +35,7 @@
static inline void storage_key_init_range(unsigned long start, unsigned long end)
{
- if (PAGE_DEFAULT_KEY)
+ if (PAGE_DEFAULT_KEY != 0)
__storage_key_init_range(start, end);
}
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index 0bb08f3..f133024 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -146,7 +146,7 @@
static inline unsigned long long get_tod_clock(void)
{
- unsigned char clk[STORE_CLOCK_EXT_SIZE];
+ char clk[STORE_CLOCK_EXT_SIZE];
get_tod_clock_ext(clk);
return *((unsigned long long *)&clk[1]);
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild
index cc44b09..baebb3d 100644
--- a/arch/s390/include/uapi/asm/Kbuild
+++ b/arch/s390/include/uapi/asm/Kbuild
@@ -1,53 +1,3 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += chpid.h
-header-y += chsc.h
-header-y += clp.h
-header-y += cmb.h
-header-y += dasd.h
-header-y += debug.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm.h
-header-y += kvm_para.h
-header-y += kvm_perf.h
-header-y += kvm_virtio.h
-header-y += mman.h
-header-y += monwriter.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += qeth.h
-header-y += resource.h
-header-y += schid.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += sclp_ctl.h
-header-y += sie.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += tape390.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
-header-y += virtio-ccw.h
-header-y += vtoc.h
-header-y += zcrypt.h
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index be75e8e..802a4de 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -24,6 +24,12 @@
#define STACK_PTREGS (STACK_FRAME_OVERHEAD)
#define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS)
#define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW)
+#ifdef __PACK_STACK
+/* allocate just enough for r14, r15 and backchain */
+#define TRACED_FUNC_FRAME_SIZE 24
+#else
+#define TRACED_FUNC_FRAME_SIZE STACK_FRAME_OVERHEAD
+#endif
ENTRY(_mcount)
BR_EX %r14
@@ -37,9 +43,16 @@
#ifndef CC_USING_HOTPATCH
aghi %r0,MCOUNT_RETURN_FIXUP
#endif
- aghi %r15,-STACK_FRAME_SIZE
+ # allocate stack frame for ftrace_caller to contain traced function
+ aghi %r15,-TRACED_FUNC_FRAME_SIZE
stg %r1,__SF_BACKCHAIN(%r15)
+ stg %r0,(__SF_GPRS+8*8)(%r15)
+ stg %r15,(__SF_GPRS+9*8)(%r15)
+ # allocate pt_regs and stack frame for ftrace_trace_function
+ aghi %r15,-STACK_FRAME_SIZE
stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
+ aghi %r1,-TRACED_FUNC_FRAME_SIZE
+ stg %r1,__SF_BACKCHAIN(%r15)
stg %r0,(STACK_PTREGS_PSW+8)(%r15)
stmg %r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15)
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index a05218f..c70aceb 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -1,7 +1,4 @@
-header-y +=
-
-
generic-y += barrier.h
generic-y += clkdev.h
generic-y += cputime.h
diff --git a/arch/score/include/uapi/asm/Kbuild b/arch/score/include/uapi/asm/Kbuild
index 040178c..b15bf6b 100644
--- a/arch/score/include/uapi/asm/Kbuild
+++ b/arch/score/include/uapi/asm/Kbuild
@@ -1,34 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7269.h b/arch/sh/include/cpu-sh2a/cpu/sh7269.h
index 2a0ca87..e4caddd 100644
--- a/arch/sh/include/cpu-sh2a/cpu/sh7269.h
+++ b/arch/sh/include/cpu-sh2a/cpu/sh7269.h
@@ -79,8 +79,15 @@
GPIO_FN_WDTOVF,
/* CAN */
- GPIO_FN_CTX1, GPIO_FN_CRX1, GPIO_FN_CTX0, GPIO_FN_CTX0_CTX1,
- GPIO_FN_CRX0, GPIO_FN_CRX0_CRX1, GPIO_FN_CRX0_CRX1_CRX2,
+ GPIO_FN_CTX2, GPIO_FN_CRX2,
+ GPIO_FN_CTX1, GPIO_FN_CRX1,
+ GPIO_FN_CTX0, GPIO_FN_CRX0,
+ GPIO_FN_CTX0_CTX1, GPIO_FN_CRX0_CRX1,
+ GPIO_FN_CTX0_CTX1_CTX2, GPIO_FN_CRX0_CRX1_CRX2,
+ GPIO_FN_CTX2_PJ21, GPIO_FN_CRX2_PJ20,
+ GPIO_FN_CTX1_PJ23, GPIO_FN_CRX1_PJ22,
+ GPIO_FN_CTX0_CTX1_PJ23, GPIO_FN_CRX0_CRX1_PJ22,
+ GPIO_FN_CTX0_CTX1_CTX2_PJ21, GPIO_FN_CRX0_CRX1_CRX2_PJ20,
/* DMAC */
GPIO_FN_TEND0, GPIO_FN_DACK0, GPIO_FN_DREQ0,
diff --git a/arch/sh/include/uapi/asm/Kbuild b/arch/sh/include/uapi/asm/Kbuild
index 60613ae..b15bf6b 100644
--- a/arch/sh/include/uapi/asm/Kbuild
+++ b/arch/sh/include/uapi/asm/Kbuild
@@ -1,25 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += byteorder.h
-header-y += cachectl.h
-header-y += cpu-features.h
-header-y += hw_breakpoint.h
-header-y += ioctls.h
-header-y += posix_types.h
-header-y += posix_types_32.h
-header-y += posix_types_64.h
-header-y += ptrace.h
-header-y += ptrace_32.h
-header-y += ptrace_64.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += signal.h
-header-y += sockios.h
-header-y += stat.h
-header-y += swab.h
-header-y += types.h
-header-y += unistd.h
-header-y += unistd_32.h
-header-y += unistd_64.h
diff --git a/arch/sparc/include/uapi/asm/Kbuild b/arch/sparc/include/uapi/asm/Kbuild
index b5843ee..b15bf6b 100644
--- a/arch/sparc/include/uapi/asm/Kbuild
+++ b/arch/sparc/include/uapi/asm/Kbuild
@@ -1,50 +1,2 @@
# UAPI Header export list
-# User exported sparc header files
-
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += apc.h
-header-y += asi.h
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += display7seg.h
-header-y += envctrl.h
-header-y += errno.h
-header-y += fbio.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += jsflash.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += openpromio.h
-header-y += param.h
-header-y += perfctr.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += psr.h
-header-y += psrcompat.h
-header-y += pstate.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += traps.h
-header-y += uctx.h
-header-y += unistd.h
-header-y += utrap.h
-header-y += watchdog.h
diff --git a/arch/sparc/include/uapi/asm/ipcbuf.h b/arch/sparc/include/uapi/asm/ipcbuf.h
index 66013b4..58da9c4 100644
--- a/arch/sparc/include/uapi/asm/ipcbuf.h
+++ b/arch/sparc/include/uapi/asm/ipcbuf.h
@@ -14,19 +14,19 @@
struct ipc64_perm
{
- __kernel_key_t key;
- __kernel_uid_t uid;
- __kernel_gid_t gid;
- __kernel_uid_t cuid;
- __kernel_gid_t cgid;
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
#ifndef __arch64__
- unsigned short __pad0;
+ unsigned short __pad0;
#endif
- __kernel_mode_t mode;
- unsigned short __pad1;
- unsigned short seq;
- unsigned long long __unused1;
- unsigned long long __unused2;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned long long __unused1;
+ unsigned long long __unused2;
};
#endif /* __SPARC_IPCBUF_H */
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 572db68..385d6d0 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -151,12 +151,14 @@
}
PERCPU_SECTION(SMP_CACHE_BYTES)
-#ifdef CONFIG_JUMP_LABEL
. = ALIGN(PAGE_SIZE);
.exit.text : {
EXIT_TEXT
}
-#endif
+
+ .exit.data : {
+ EXIT_DATA
+ }
. = ALIGN(PAGE_SIZE);
__init_end = .;
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index ba35c41..bf3e654 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -1,6 +1,3 @@
-
-header-y += ../arch/
-
generic-y += bug.h
generic-y += bugs.h
generic-y += clkdev.h
diff --git a/arch/tile/include/uapi/arch/Kbuild b/arch/tile/include/uapi/arch/Kbuild
deleted file mode 100644
index 97dfbec..0000000
--- a/arch/tile/include/uapi/arch/Kbuild
+++ /dev/null
@@ -1,17 +0,0 @@
-# UAPI Header export list
-header-y += abi.h
-header-y += chip.h
-header-y += chip_tilegx.h
-header-y += chip_tilepro.h
-header-y += icache.h
-header-y += interrupts.h
-header-y += interrupts_32.h
-header-y += interrupts_64.h
-header-y += opcode.h
-header-y += opcode_tilegx.h
-header-y += opcode_tilepro.h
-header-y += sim.h
-header-y += sim_def.h
-header-y += spr_def.h
-header-y += spr_def_32.h
-header-y += spr_def_64.h
diff --git a/arch/tile/include/uapi/asm/Kbuild b/arch/tile/include/uapi/asm/Kbuild
index c20db8e..0c74c3c 100644
--- a/arch/tile/include/uapi/asm/Kbuild
+++ b/arch/tile/include/uapi/asm/Kbuild
@@ -1,21 +1,4 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += cachectl.h
-header-y += hardwall.h
-header-y += kvm_para.h
-header-y += mman.h
-header-y += ptrace.h
-header-y += setup.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += stat.h
-header-y += swab.h
-header-y += ucontext.h
-header-y += unistd.h
-
generic-y += ucontext.h
diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild
index 0514d7a..13a97aa 100644
--- a/arch/unicore32/include/uapi/asm/Kbuild
+++ b/arch/unicore32/include/uapi/asm/Kbuild
@@ -1,10 +1,4 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-header-y += byteorder.h
-header-y += kvm_para.h
-header-y += ptrace.h
-header-y += sigcontext.h
-header-y += unistd.h
-
generic-y += kvm_para.h
diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c
index 3f9d1a8..50c1f77 100644
--- a/arch/x86/entry/vdso/vdso32-setup.c
+++ b/arch/x86/entry/vdso/vdso32-setup.c
@@ -10,6 +10,7 @@
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/mm_types.h>
+#include <linux/elf.h>
#include <asm/processor.h>
#include <asm/vdso.h>
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index 00b56cc..836b7e4 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -239,6 +239,7 @@
[PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
[PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0964,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x0287,
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index c16c99b..6bfb9a6 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -185,20 +185,18 @@
/*
* NB and Last level cache counters (MSRs) are shared across all cores
- * that share the same NB / Last level cache. Interrupts can be directed
- * to a single target core, however, event counts generated by processes
- * running on other cores cannot be masked out. So we do not support
- * sampling and per-thread events.
+ * that share the same NB / Last level cache. On family 16h and below,
+ * Interrupts can be directed to a single target core, however, event
+ * counts generated by processes running on other cores cannot be masked
+ * out. So we do not support sampling and per-thread events via
+ * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts:
*/
- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
- return -EINVAL;
/* NB and Last level cache counters do not have usr/os/guest/host bits */
if (event->attr.exclude_user || event->attr.exclude_kernel ||
event->attr.exclude_host || event->attr.exclude_guest)
return -EINVAL;
- /* and we do not enable counter overflow interrupts */
hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB;
hwc->idx = -1;
@@ -275,6 +273,7 @@
.start = amd_uncore_start,
.stop = amd_uncore_stop,
.read = amd_uncore_read,
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
};
static struct pmu amd_llc_pmu = {
@@ -287,6 +286,7 @@
.start = amd_uncore_start,
.stop = amd_uncore_stop,
.read = amd_uncore_read,
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
};
static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index ad31c01..f562ddb 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1326,6 +1326,8 @@
old = ((s64)(prev_raw_count << shift) >> shift);
local64_add(new - old + count * period, &event->count);
+ local64_set(&hwc->period_left, -new);
+
perf_event_update_userpage(event);
return 0;
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index ccc4420..fb457ba 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -305,6 +305,7 @@
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
+#define X86_FEATURE_RDPID (16*32+ 22) /* RDPID instruction */
/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index e728699..3a01996 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -89,8 +89,13 @@
* works on all CPUs. This is volatile so that it orders
* correctly wrt barrier() and to keep gcc from cleverly
* hoisting it out of the calling function.
+ *
+ * If RDPID is available, use it.
*/
- asm volatile ("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
+ alternative_io ("lsl %[p],%[seg]",
+ ".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */
+ X86_FEATURE_RDPID,
+ [p] "=a" (p), [seg] "r" (__PER_CPU_SEG));
return p;
}
diff --git a/arch/x86/include/uapi/asm/Kbuild b/arch/x86/include/uapi/asm/Kbuild
index 1c532b3..da1489c 100644
--- a/arch/x86/include/uapi/asm/Kbuild
+++ b/arch/x86/include/uapi/asm/Kbuild
@@ -1,64 +1,6 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-genhdr-y += unistd_32.h
-genhdr-y += unistd_64.h
-genhdr-y += unistd_x32.h
-header-y += a.out.h
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += boot.h
-header-y += bootparam.h
-header-y += byteorder.h
-header-y += debugreg.h
-header-y += e820.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += hw_breakpoint.h
-header-y += hyperv.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += ist.h
-header-y += kvm.h
-header-y += kvm_para.h
-header-y += kvm_perf.h
-header-y += ldt.h
-header-y += mce.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += msr.h
-header-y += mtrr.h
-header-y += param.h
-header-y += perf_regs.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += posix_types_32.h
-header-y += posix_types_64.h
-header-y += posix_types_x32.h
-header-y += prctl.h
-header-y += processor-flags.h
-header-y += ptrace-abi.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += sigcontext32.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += svm.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
-header-y += vm86.h
-header-y += vmx.h
-header-y += vsyscall.h
+generated-y += unistd_32.h
+generated-y += unistd_64.h
+generated-y += unistd_x32.h
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 477df97..f490a4f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -388,7 +388,7 @@
* cpuid bit to be set. We need to ensure that we
* update that bit in this CPU's "cpu_info".
*/
- get_cpu_cap(c);
+ set_cpu_cap(c, X86_FEATURE_OSPKE);
}
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 2a473cd..775d5f0 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -846,9 +846,12 @@
.store = store,
};
+static void threshold_block_release(struct kobject *kobj);
+
static struct kobj_type threshold_ktype = {
.sysfs_ops = &threshold_ops,
.default_attrs = default_attrs,
+ .release = threshold_block_release,
};
static const char *get_name(unsigned int bank, struct threshold_block *b)
@@ -879,8 +882,9 @@
return buf_mcatype;
}
-static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
- unsigned int block, u32 address)
+static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb,
+ unsigned int bank, unsigned int block,
+ u32 address)
{
struct threshold_block *b = NULL;
u32 low, high;
@@ -924,16 +928,12 @@
INIT_LIST_HEAD(&b->miscj);
- if (per_cpu(threshold_banks, cpu)[bank]->blocks) {
- list_add(&b->miscj,
- &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj);
- } else {
- per_cpu(threshold_banks, cpu)[bank]->blocks = b;
- }
+ if (tb->blocks)
+ list_add(&b->miscj, &tb->blocks->miscj);
+ else
+ tb->blocks = b;
- err = kobject_init_and_add(&b->kobj, &threshold_ktype,
- per_cpu(threshold_banks, cpu)[bank]->kobj,
- get_name(bank, b));
+ err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b));
if (err)
goto out_free;
recurse:
@@ -941,7 +941,7 @@
if (!address)
return 0;
- err = allocate_threshold_blocks(cpu, bank, block, address);
+ err = allocate_threshold_blocks(cpu, tb, bank, block, address);
if (err)
goto out_free;
@@ -1026,8 +1026,6 @@
goto out_free;
}
- per_cpu(threshold_banks, cpu)[bank] = b;
-
if (is_shared_bank(bank)) {
atomic_set(&b->cpus, 1);
@@ -1038,9 +1036,13 @@
}
}
- err = allocate_threshold_blocks(cpu, bank, 0, msr_ops.misc(bank));
- if (!err)
- goto out;
+ err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank));
+ if (err)
+ goto out_free;
+
+ per_cpu(threshold_banks, cpu)[bank] = b;
+
+ return 0;
out_free:
kfree(b);
@@ -1074,8 +1076,12 @@
return err;
}
-static void deallocate_threshold_block(unsigned int cpu,
- unsigned int bank)
+static void threshold_block_release(struct kobject *kobj)
+{
+ kfree(to_block(kobj));
+}
+
+static void deallocate_threshold_block(unsigned int cpu, unsigned int bank)
{
struct threshold_block *pos = NULL;
struct threshold_block *tmp = NULL;
@@ -1085,13 +1091,11 @@
return;
list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) {
- kobject_put(&pos->kobj);
list_del(&pos->miscj);
- kfree(pos);
+ kobject_put(&pos->kobj);
}
- kfree(per_cpu(threshold_banks, cpu)[bank]->blocks);
- per_cpu(threshold_banks, cpu)[bank]->blocks = NULL;
+ kobject_put(&head->blocks->kobj);
}
static void __threshold_remove_blocks(struct threshold_bank *b)
diff --git a/arch/x86/kernel/cpu/tsx.c b/arch/x86/kernel/cpu/tsx.c
index 3e20d32..032509a 100644
--- a/arch/x86/kernel/cpu/tsx.c
+++ b/arch/x86/kernel/cpu/tsx.c
@@ -115,11 +115,12 @@
tsx_disable();
/*
- * tsx_disable() will change the state of the
- * RTM CPUID bit. Clear it here since it is now
- * expected to be not set.
+ * tsx_disable() will change the state of the RTM and HLE CPUID
+ * bits. Clear them here since they are now expected to be not
+ * set.
*/
setup_clear_cpu_cap(X86_FEATURE_RTM);
+ setup_clear_cpu_cap(X86_FEATURE_HLE);
} else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {
/*
@@ -131,10 +132,10 @@
tsx_enable();
/*
- * tsx_enable() will change the state of the
- * RTM CPUID bit. Force it here since it is now
- * expected to be set.
+ * tsx_enable() will change the state of the RTM and HLE CPUID
+ * bits. Force them here since they are now expected to be set.
*/
setup_force_cpu_cap(X86_FEATURE_RTM);
+ setup_force_cpu_cap(X86_FEATURE_HLE);
}
}
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c
index 85195d4..f321534 100644
--- a/arch/x86/kernel/sysfb_simplefb.c
+++ b/arch/x86/kernel/sysfb_simplefb.c
@@ -94,11 +94,11 @@
if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
size <<= 16;
length = mode->height * mode->stride;
- length = PAGE_ALIGN(length);
if (length > size) {
printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n");
return -EINVAL;
}
+ length = PAGE_ALIGN(length);
/* setup IORESOURCE_MEM as framebuffer memory */
memset(&res, 0, sizeof(res));
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 242ad06..c57dab0 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -279,13 +279,18 @@
{
switch (func) {
case 0:
- entry->eax = 1; /* only one leaf currently */
+ entry->eax = 7;
++*nent;
break;
case 1:
entry->ecx = F(MOVBE);
++*nent;
break;
+ case 7:
+ entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+ if (index == 0)
+ entry->ecx = F(RDPID);
+ ++*nent;
default:
break;
}
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 660c35f..da3cd73 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -21,6 +21,7 @@
*/
#include <linux/kvm_host.h>
+#include <linux/nospec.h>
#include "kvm_cache_regs.h"
#include <asm/kvm_emulate.h>
#include <linux/stringify.h>
@@ -3530,6 +3531,16 @@
return X86EMUL_CONTINUE;
}
+static int em_rdpid(struct x86_emulate_ctxt *ctxt)
+{
+ u64 tsc_aux = 0;
+
+ if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux))
+ return emulate_gp(ctxt, 0);
+ ctxt->dst.val = tsc_aux;
+ return X86EMUL_CONTINUE;
+}
+
static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
{
u64 tsc = 0;
@@ -4390,10 +4401,20 @@
F(DstMem | SrcImmByte | Lock | PageTable, em_btc),
};
+/*
+ * The "memory" destination is actually always a register, since we come
+ * from the register case of group9.
+ */
+static const struct gprefix pfx_0f_c7_7 = {
+ N, N, N, II(DstMem | ModRM | Op3264 | EmulateOnUD, em_rdpid, rdtscp),
+};
+
+
static const struct group_dual group9 = { {
N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
}, {
- N, N, N, N, N, N, N, N,
+ N, N, N, N, N, N, N,
+ GP(0, &pfx_0f_c7_7),
} };
static const struct opcode group11[] = {
@@ -5001,6 +5022,7 @@
ctxt->fetch.ptr = ctxt->fetch.data;
ctxt->fetch.end = ctxt->fetch.data + insn_len;
ctxt->opcode_len = 1;
+ ctxt->intercept = x86_intercept_none;
if (insn_len > 0)
memcpy(ctxt->fetch.data, insn, insn_len);
else {
@@ -5053,16 +5075,28 @@
ctxt->ad_bytes = def_ad_bytes ^ 6;
break;
case 0x26: /* ES override */
+ has_seg_override = true;
+ ctxt->seg_override = VCPU_SREG_ES;
+ break;
case 0x2e: /* CS override */
+ has_seg_override = true;
+ ctxt->seg_override = VCPU_SREG_CS;
+ break;
case 0x36: /* SS override */
+ has_seg_override = true;
+ ctxt->seg_override = VCPU_SREG_SS;
+ break;
case 0x3e: /* DS override */
has_seg_override = true;
- ctxt->seg_override = (ctxt->b >> 3) & 3;
+ ctxt->seg_override = VCPU_SREG_DS;
break;
case 0x64: /* FS override */
+ has_seg_override = true;
+ ctxt->seg_override = VCPU_SREG_FS;
+ break;
case 0x65: /* GS override */
has_seg_override = true;
- ctxt->seg_override = ctxt->b & 7;
+ ctxt->seg_override = VCPU_SREG_GS;
break;
case 0x40 ... 0x4f: /* REX */
if (mode != X86EMUL_MODE_PROT64)
@@ -5146,10 +5180,15 @@
}
break;
case Escape:
- if (ctxt->modrm > 0xbf)
- opcode = opcode.u.esc->high[ctxt->modrm - 0xc0];
- else
+ if (ctxt->modrm > 0xbf) {
+ size_t size = ARRAY_SIZE(opcode.u.esc->high);
+ u32 index = array_index_nospec(
+ ctxt->modrm - 0xc0, size);
+
+ opcode = opcode.u.esc->high[index];
+ } else {
opcode = opcode.u.esc->op[(ctxt->modrm >> 3) & 7];
+ }
break;
case InstrDual:
if ((ctxt->modrm >> 6) == 3)
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 42b1c83..5e837c9 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -28,6 +28,7 @@
#include <linux/kvm_host.h>
#include <linux/highmem.h>
+#include <linux/nospec.h>
#include <asm/apicdef.h>
#include <trace/events/kvm.h>
@@ -719,11 +720,12 @@
u32 index, u64 *pdata)
{
struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+ size_t size = ARRAY_SIZE(hv->hv_crash_param);
- if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+ if (WARN_ON_ONCE(index >= size))
return -EINVAL;
- *pdata = hv->hv_crash_param[index];
+ *pdata = hv->hv_crash_param[array_index_nospec(index, size)];
return 0;
}
@@ -762,11 +764,12 @@
u32 index, u64 data)
{
struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+ size_t size = ARRAY_SIZE(hv->hv_crash_param);
- if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+ if (WARN_ON_ONCE(index >= size))
return -EINVAL;
- hv->hv_crash_param[index] = data;
+ hv->hv_crash_param[array_index_nospec(index, size)] = data;
return 0;
}
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
index 5f810bb..aa34b16 100644
--- a/arch/x86/kvm/ioapic.c
+++ b/arch/x86/kvm/ioapic.c
@@ -36,6 +36,7 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/export.h>
+#include <linux/nospec.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/current.h>
@@ -73,13 +74,14 @@
default:
{
u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
- u64 redir_content;
+ u64 redir_content = ~0ULL;
- if (redir_index < IOAPIC_NUM_PINS)
- redir_content =
- ioapic->redirtbl[redir_index].bits;
- else
- redir_content = ~0ULL;
+ if (redir_index < IOAPIC_NUM_PINS) {
+ u32 index = array_index_nospec(
+ redir_index, IOAPIC_NUM_PINS);
+
+ redir_content = ioapic->redirtbl[index].bits;
+ }
result = (ioapic->ioregsel & 0x1) ?
(redir_content >> 32) & 0xffffffff :
@@ -299,6 +301,7 @@
ioapic_debug("change redir index %x val %x\n", index, val);
if (index >= IOAPIC_NUM_PINS)
return;
+ index = array_index_nospec(index, IOAPIC_NUM_PINS);
e = &ioapic->redirtbl[index];
mask_before = e->fields.mask;
/* Preserve read-only fields */
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 6c01916..cf8b3c1 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -436,7 +436,7 @@
kvm_set_msi_irq(vcpu->kvm, entry, &irq);
- if (irq.level && kvm_apic_match_dest(vcpu, NULL, 0,
+ if (irq.trig_mode && kvm_apic_match_dest(vcpu, NULL, 0,
irq.dest_id, irq.dest_mode))
__set_bit(irq.vector, ioapic_handled_vectors);
}
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index cf32533..3988e26 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -28,6 +28,7 @@
#include <linux/export.h>
#include <linux/math64.h>
#include <linux/slab.h>
+#include <linux/nospec.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/page.h>
@@ -531,9 +532,11 @@
static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu)
{
u8 val;
- if (pv_eoi_get_user(vcpu, &val) < 0)
+ if (pv_eoi_get_user(vcpu, &val) < 0) {
apic_debug("Can't read EOI MSR value: 0x%llx\n",
(unsigned long long)vcpu->arch.pv_eoi.msr_val);
+ return false;
+ }
return val & 0x1;
}
@@ -1587,15 +1590,20 @@
case APIC_LVTTHMR:
case APIC_LVTPC:
case APIC_LVT1:
- case APIC_LVTERR:
+ case APIC_LVTERR: {
/* TODO: Check vector */
+ size_t size;
+ u32 index;
+
if (!kvm_apic_sw_enabled(apic))
val |= APIC_LVT_MASKED;
-
- val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
+ size = ARRAY_SIZE(apic_lvt_mask);
+ index = array_index_nospec(
+ (reg - APIC_LVTT) >> 4, size);
+ val &= apic_lvt_mask[index];
kvm_lapic_set_reg(apic, reg, val);
-
break;
+ }
case APIC_LVTT:
if (!kvm_apic_sw_enabled(apic))
diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
index 0149ac59..3e30164 100644
--- a/arch/x86/kvm/mtrr.c
+++ b/arch/x86/kvm/mtrr.c
@@ -17,6 +17,7 @@
*/
#include <linux/kvm_host.h>
+#include <linux/nospec.h>
#include <asm/mtrr.h>
#include "cpuid.h"
@@ -202,11 +203,15 @@
break;
case MSR_MTRRfix16K_80000 ... MSR_MTRRfix16K_A0000:
*seg = 1;
- *unit = msr - MSR_MTRRfix16K_80000;
+ *unit = array_index_nospec(
+ msr - MSR_MTRRfix16K_80000,
+ MSR_MTRRfix16K_A0000 - MSR_MTRRfix16K_80000 + 1);
break;
case MSR_MTRRfix4K_C0000 ... MSR_MTRRfix4K_F8000:
*seg = 2;
- *unit = msr - MSR_MTRRfix4K_C0000;
+ *unit = array_index_nospec(
+ msr - MSR_MTRRfix4K_C0000,
+ MSR_MTRRfix4K_F8000 - MSR_MTRRfix4K_C0000 + 1);
break;
default:
return false;
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index f96e1f9..fbf3d25 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -1,6 +1,8 @@
#ifndef __KVM_X86_PMU_H
#define __KVM_X86_PMU_H
+#include <linux/nospec.h>
+
#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu)
#define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu))
#define pmc_to_pmu(pmc) (&(pmc)->vcpu->arch.pmu)
@@ -80,8 +82,12 @@
static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu *pmu, u32 msr,
u32 base)
{
- if (msr >= base && msr < base + pmu->nr_arch_gp_counters)
- return &pmu->gp_counters[msr - base];
+ if (msr >= base && msr < base + pmu->nr_arch_gp_counters) {
+ u32 index = array_index_nospec(msr - base,
+ pmu->nr_arch_gp_counters);
+
+ return &pmu->gp_counters[index];
+ }
return NULL;
}
@@ -91,8 +97,12 @@
{
int base = MSR_CORE_PERF_FIXED_CTR0;
- if (msr >= base && msr < base + pmu->nr_arch_fixed_counters)
- return &pmu->fixed_counters[msr - base];
+ if (msr >= base && msr < base + pmu->nr_arch_fixed_counters) {
+ u32 index = array_index_nospec(msr - base,
+ pmu->nr_arch_fixed_counters);
+
+ return &pmu->fixed_counters[index];
+ }
return NULL;
}
diff --git a/arch/x86/kvm/pmu_intel.c b/arch/x86/kvm/pmu_intel.c
index 2729131..84ae4dd 100644
--- a/arch/x86/kvm/pmu_intel.c
+++ b/arch/x86/kvm/pmu_intel.c
@@ -87,10 +87,14 @@
static unsigned intel_find_fixed_event(int idx)
{
- if (idx >= ARRAY_SIZE(fixed_pmc_events))
+ u32 event;
+ size_t size = ARRAY_SIZE(fixed_pmc_events);
+
+ if (idx >= size)
return PERF_COUNT_HW_MAX;
- return intel_arch_events[fixed_pmc_events[idx]].event_type;
+ event = fixed_pmc_events[array_index_nospec(idx, size)];
+ return intel_arch_events[event].event_type;
}
/* check if a PMC is enabled by comparing it with globl_ctrl bits. */
@@ -131,15 +135,19 @@
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
bool fixed = idx & (1u << 30);
struct kvm_pmc *counters;
+ unsigned int num_counters;
idx &= ~(3u << 30);
- if (!fixed && idx >= pmu->nr_arch_gp_counters)
+ if (fixed) {
+ counters = pmu->fixed_counters;
+ num_counters = pmu->nr_arch_fixed_counters;
+ } else {
+ counters = pmu->gp_counters;
+ num_counters = pmu->nr_arch_gp_counters;
+ }
+ if (idx >= num_counters)
return NULL;
- if (fixed && idx >= pmu->nr_arch_fixed_counters)
- return NULL;
- counters = fixed ? pmu->fixed_counters : pmu->gp_counters;
-
- return &counters[idx];
+ return &counters[array_index_nospec(idx, num_counters)];
}
static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 8e78252..69cadb9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4641,6 +4641,26 @@
(ss.selector & SEGMENT_RPL_MASK));
}
+static bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu,
+ unsigned int port, int size);
+static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
+ struct vmcs12 *vmcs12)
+{
+ unsigned long exit_qualification;
+ unsigned short port;
+ int size;
+
+ if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
+ return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
+
+ exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
+
+ port = exit_qualification >> 16;
+ size = (exit_qualification & 7) + 1;
+
+ return nested_vmx_check_io_bitmaps(vcpu, port, size);
+}
+
/*
* Check if guest state is valid. Returns true if valid, false if
* not.
@@ -6544,8 +6564,8 @@
return 1;
}
else
- return x86_emulate_instruction(vcpu, gpa, EMULTYPE_SKIP,
- NULL, 0) == EMULATE_DONE;
+ return emulate_instruction(vcpu, EMULTYPE_SKIP) ==
+ EMULATE_DONE;
}
ret = kvm_mmu_page_fault(vcpu, gpa, PFERR_RSVD_MASK, NULL, 0);
@@ -7653,8 +7673,10 @@
/* _system ok, as nested_vmx_check_permission verified cpl=0 */
if (kvm_write_guest_virt_system(vcpu, gva, &field_value,
(is_long_mode(vcpu) ? 8 : 4),
- &e))
+ &e)) {
kvm_inject_page_fault(vcpu, &e);
+ return 1;
+ }
}
nested_vmx_succeed(vcpu);
@@ -8024,23 +8046,17 @@
static const int kvm_vmx_max_exit_handlers =
ARRAY_SIZE(kvm_vmx_exit_handlers);
-static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
- struct vmcs12 *vmcs12)
+/*
+ * Return true if an IO instruction with the specified port and size should cause
+ * a VM-exit into L1.
+ */
+bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
+ int size)
{
- unsigned long exit_qualification;
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
gpa_t bitmap, last_bitmap;
- unsigned int port;
- int size;
u8 b;
- if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
- return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING);
-
- exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
-
- port = exit_qualification >> 16;
- size = (exit_qualification & 7) + 1;
-
last_bitmap = (gpa_t)-1;
b = -1;
@@ -11332,11 +11348,71 @@
to_vmx(vcpu)->nested.sync_shadow_vmcs = true;
}
+static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
+ struct x86_instruction_info *info)
+{
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+ unsigned short port;
+ bool intercept;
+ int size;
+
+ if (info->intercept == x86_intercept_in ||
+ info->intercept == x86_intercept_ins) {
+ port = info->src_val;
+ size = info->dst_bytes;
+ } else {
+ port = info->dst_val;
+ size = info->src_bytes;
+ }
+
+ /*
+ * If the 'use IO bitmaps' VM-execution control is 0, IO instruction
+ * VM-exits depend on the 'unconditional IO exiting' VM-execution
+ * control.
+ *
+ * Otherwise, IO instruction VM-exits are controlled by the IO bitmaps.
+ */
+ if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
+ intercept = nested_cpu_has(vmcs12,
+ CPU_BASED_UNCOND_IO_EXITING);
+ else
+ intercept = nested_vmx_check_io_bitmaps(vcpu, port, size);
+
+ return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
+}
+
static int vmx_check_intercept(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info,
enum x86_intercept_stage stage)
{
- return X86EMUL_CONTINUE;
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+ struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
+
+ switch (info->intercept) {
+ /*
+ * RDPID causes #UD if disabled through secondary execution controls.
+ * Because it is marked as EmulateOnUD, we need to intercept it here.
+ */
+ case x86_intercept_rdtscp:
+ if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
+ ctxt->exception.vector = UD_VECTOR;
+ ctxt->exception.error_code_valid = false;
+ return X86EMUL_PROPAGATE_FAULT;
+ }
+ break;
+
+ case x86_intercept_in:
+ case x86_intercept_ins:
+ case x86_intercept_out:
+ case x86_intercept_outs:
+ return vmx_check_intercept_io(vcpu, info);
+
+ /* TODO: check more intercepts... */
+ default:
+ break;
+ }
+
+ return X86EMUL_UNHANDLEABLE;
}
#ifdef CONFIG_X86_64
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c9c5333..43aabd7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -54,6 +54,7 @@
#include <linux/pvclock_gtod.h>
#include <linux/kvm_irqfd.h>
#include <linux/irqbypass.h>
+#include <linux/nospec.h>
#include <trace/events/kvm.h>
#include <asm/debugreg.h>
@@ -889,9 +890,11 @@
static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
{
+ size_t size = ARRAY_SIZE(vcpu->arch.db);
+
switch (dr) {
case 0 ... 3:
- vcpu->arch.db[dr] = val;
+ vcpu->arch.db[array_index_nospec(dr, size)] = val;
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
vcpu->arch.eff_db[dr] = val;
break;
@@ -928,9 +931,11 @@
int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
{
+ size_t size = ARRAY_SIZE(vcpu->arch.db);
+
switch (dr) {
case 0 ... 3:
- *val = vcpu->arch.db[dr];
+ *val = vcpu->arch.db[array_index_nospec(dr, size)];
break;
case 4:
/* fall through */
@@ -2125,7 +2130,10 @@
default:
if (msr >= MSR_IA32_MC0_CTL &&
msr < MSR_IA32_MCx_CTL(bank_num)) {
- u32 offset = msr - MSR_IA32_MC0_CTL;
+ u32 offset = array_index_nospec(
+ msr - MSR_IA32_MC0_CTL,
+ MSR_IA32_MCx_CTL(bank_num) - MSR_IA32_MC0_CTL);
+
/* only 0 or all 1s can be written to IA32_MCi_CTL
* some Linux kernels though clear bit 10 in bank 4 to
* workaround a BIOS/GART TBL issue on AMD K8s, ignore
@@ -2493,7 +2501,10 @@
default:
if (msr >= MSR_IA32_MC0_CTL &&
msr < MSR_IA32_MCx_CTL(bank_num)) {
- u32 offset = msr - MSR_IA32_MC0_CTL;
+ u32 offset = array_index_nospec(
+ msr - MSR_IA32_MC0_CTL,
+ MSR_IA32_MCx_CTL(bank_num) - MSR_IA32_MC0_CTL);
+
data = vcpu->arch.mce_banks[offset];
break;
}
@@ -6121,14 +6132,12 @@
/* Set the present bit. */
mask |= 1ull;
-#ifdef CONFIG_X86_64
/*
* If reserved bit is not supported, clear the present bit to disable
* mmio page fault.
*/
if (maxphyaddr == 52)
mask &= ~1ull;
-#endif
kvm_mmu_set_mmio_spte_mask(mask);
}
@@ -7798,7 +7807,7 @@
kvm_mmu_unload(vcpu);
vcpu_put(vcpu);
- kvm_x86_ops->vcpu_free(vcpu);
+ kvm_arch_vcpu_free(vcpu);
}
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 0f7eb4f..82e105b 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -909,7 +909,7 @@
GrpTable: Grp3_2
0: TEST Ev,Iz
-1:
+1: TEST Ev,Iz
2: NOT Ev
3: NEG Ev
4: MUL rAX,Ev
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 4b52d00..fc841d9 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -285,7 +285,7 @@
return pmd_k;
}
-void vmalloc_sync_all(void)
+static void vmalloc_sync(void)
{
unsigned long address;
@@ -312,6 +312,16 @@
}
}
+void vmalloc_sync_mappings(void)
+{
+ vmalloc_sync();
+}
+
+void vmalloc_sync_unmappings(void)
+{
+ vmalloc_sync();
+}
+
/*
* 32-bit:
*
@@ -406,11 +416,23 @@
#else /* CONFIG_X86_64: */
-void vmalloc_sync_all(void)
+void vmalloc_sync_mappings(void)
{
+ /*
+ * 64-bit mappings might allocate new p4d/pud pages
+ * that need to be propagated to all tasks' PGDs.
+ */
sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END, 0);
}
+void vmalloc_sync_unmappings(void)
+{
+ /*
+ * Unmappings never allocate or free p4d/pud pages.
+ * No work is required here.
+ */
+}
+
/*
* 64-bit:
*
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index b6669d3..f08abdf 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -478,7 +478,6 @@
efi_char16_t *c16;
char vendor[100] = "unknown";
int i = 0;
- void *tmp;
#ifdef CONFIG_X86_32
if (boot_params.efi_info.efi_systab_hi ||
@@ -503,14 +502,16 @@
/*
* Show what we know for posterity
*/
- c16 = tmp = early_memremap(efi.systab->fw_vendor, 2);
+ c16 = early_memremap_ro(efi.systab->fw_vendor,
+ sizeof(vendor) * sizeof(efi_char16_t));
if (c16) {
- for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i)
- vendor[i] = *c16++;
+ for (i = 0; i < sizeof(vendor) - 1 && c16[i]; ++i)
+ vendor[i] = c16[i];
vendor[i] = '\0';
- } else
+ early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
+ } else {
pr_err("Could not map the firmware vendor!\n");
- early_memunmap(tmp, 2);
+ }
pr_info("EFI v%u.%.02u by %s\n",
efi.systab->hdr.revision >> 16,
diff --git a/arch/xtensa/include/uapi/asm/Kbuild b/arch/xtensa/include/uapi/asm/Kbuild
index 56aad54..b15bf6b 100644
--- a/arch/xtensa/include/uapi/asm/Kbuild
+++ b/arch/xtensa/include/uapi/asm/Kbuild
@@ -1,25 +1,2 @@
# UAPI Header export list
include include/uapi/asm-generic/Kbuild.asm
-
-header-y += auxvec.h
-header-y += byteorder.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += swab.h
-header-y += termbits.h
-header-y += types.h
-header-y += unistd.h
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 5c098ff..9e5b243 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -652,11 +652,9 @@
void crypto_drop_spawn(struct crypto_spawn *spawn)
{
- if (!spawn->alg)
- return;
-
down_write(&crypto_alg_sem);
- list_del(&spawn->list);
+ if (spawn->alg)
+ list_del(&spawn->list);
up_write(&crypto_alg_sem);
}
EXPORT_SYMBOL_GPL(crypto_drop_spawn);
@@ -664,22 +662,16 @@
static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
{
struct crypto_alg *alg;
- struct crypto_alg *alg2;
down_read(&crypto_alg_sem);
alg = spawn->alg;
- alg2 = alg;
- if (alg2)
- alg2 = crypto_mod_get(alg2);
+ if (alg && !crypto_mod_get(alg)) {
+ alg->cra_flags |= CRYPTO_ALG_DYING;
+ alg = NULL;
+ }
up_read(&crypto_alg_sem);
- if (!alg2) {
- if (alg)
- crypto_shoot_alg(alg);
- return ERR_PTR(-EAGAIN);
- }
-
- return alg;
+ return alg ?: ERR_PTR(-EAGAIN);
}
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index aaf2f81..b28f45a 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -538,7 +538,7 @@
lock_sock(sk);
tx_nents = skcipher_all_sg_nents(ctx);
sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
- if (unlikely(!sreq->tsg))
+ if (unlikely(ZERO_OR_NULL_PTR(sreq->tsg)))
goto unlock;
sg_init_table(sreq->tsg, tx_nents);
memcpy(iv, ctx->iv, ivsize);
diff --git a/crypto/api.c b/crypto/api.c
index f12d6b9..b47796b 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -356,13 +356,12 @@
return len;
}
-void crypto_shoot_alg(struct crypto_alg *alg)
+static void crypto_shoot_alg(struct crypto_alg *alg)
{
down_write(&crypto_alg_sem);
alg->cra_flags |= CRYPTO_ALG_DYING;
up_write(&crypto_alg_sem);
}
-EXPORT_SYMBOL_GPL(crypto_shoot_alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask)
diff --git a/crypto/internal.h b/crypto/internal.h
index 7eefcdb..6184c42 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -87,7 +87,6 @@
void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
struct crypto_alg *nalg);
void crypto_remove_final(struct list_head *list);
-void crypto_shoot_alg(struct crypto_alg *alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask);
void *crypto_create_tfm(struct crypto_alg *alg,
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 1348541..8508257 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -130,7 +130,6 @@
struct padata_priv *padata = pcrypt_request_padata(preq);
padata->info = err;
- req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
padata_do_serial(padata);
}
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
index 396e358..4296f49 100644
--- a/drivers/acpi/acpi_watchdog.c
+++ b/drivers/acpi/acpi_watchdog.c
@@ -58,12 +58,14 @@
}
#endif
+static bool acpi_no_watchdog;
+
static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
{
const struct acpi_table_wdat *wdat = NULL;
acpi_status status;
- if (acpi_disabled)
+ if (acpi_disabled || acpi_no_watchdog)
return NULL;
status = acpi_get_table(ACPI_SIG_WDAT, 0,
@@ -91,6 +93,14 @@
}
EXPORT_SYMBOL_GPL(acpi_has_watchdog);
+/* ACPI watchdog can be disabled on boot command line */
+static int __init disable_acpi_watchdog(char *str)
+{
+ acpi_no_watchdog = true;
+ return 1;
+}
+__setup("acpi_no_watchdog", disable_acpi_watchdog);
+
void __init acpi_watchdog_init(void)
{
const struct acpi_wdat_entry *entries;
@@ -129,12 +139,11 @@
gas = &entries[i].register_region;
res.start = gas->address;
+ res.end = res.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1;
if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
res.flags = IORESOURCE_MEM;
- res.end = res.start + ALIGN(gas->access_width, 4) - 1;
} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
res.flags = IORESOURCE_IO;
- res.end = res.start + gas->access_width - 1;
} else {
pr_warn("Unsupported address space: %u\n",
gas->space_id);
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index 6a4b603..10bbf6c 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -272,7 +272,7 @@
* FUNCTION: acpi_ds_get_field_names
*
* PARAMETERS: info - create_field info structure
- * ` walk_state - Current method state
+ * walk_state - Current method state
* arg - First parser arg for the field name list
*
* RETURN: Status
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index fd34040..9c41d21 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -440,6 +440,27 @@
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
walk_state));
+ /*
+ * Disassembler: handle create field operators here.
+ *
+ * create_buffer_field is a deferred op that is typically processed in load
+ * pass 2. However, disassembly of control method contents walk the parse
+ * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed
+ * in a later walk. This is a problem when there is a control method that
+ * has the same name as the AML_CREATE object. In this case, any use of the
+ * name segment will be detected as a method call rather than a reference
+ * to a buffer field.
+ *
+ * This earlier creation during disassembly solves this issue by inserting
+ * the named object in the ACPI namespace so that references to this name
+ * would be a name string rather than a method call.
+ */
+ if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) &&
+ (walk_state->op_info->flags & AML_CREATE)) {
+ status = acpi_ds_create_buffer_field(op, walk_state);
+ return_ACPI_STATUS(status);
+ }
+
/* We are only interested in opcodes that have an associated name */
if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index a6e3c8d..acb4e75 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -234,7 +234,7 @@
* New allocation must be visible in all pgd before it can be found by
* an NMI allocating from the pool.
*/
- vmalloc_sync_all();
+ vmalloc_sync_mappings();
return gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1);
}
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 5408a29..89e6204 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -86,6 +86,7 @@
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void ahci_remove_one(struct pci_dev *dev);
+static void ahci_shutdown_one(struct pci_dev *dev);
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -582,6 +583,7 @@
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
.remove = ahci_remove_one,
+ .shutdown = ahci_shutdown_one,
.driver = {
.pm = &ahci_pci_pm_ops,
},
@@ -1775,6 +1777,11 @@
return 0;
}
+static void ahci_shutdown_one(struct pci_dev *pdev)
+{
+ ata_pci_shutdown_one(pdev);
+}
+
static void ahci_remove_one(struct pci_dev *pdev)
{
pm_runtime_get_noresume(&pdev->dev);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b1582f1..ba0cffb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6580,6 +6580,26 @@
ata_host_detach(host);
}
+void ata_pci_shutdown_one(struct pci_dev *pdev)
+{
+ struct ata_host *host = pci_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ ap->pflags |= ATA_PFLAG_FROZEN;
+
+ /* Disable port interrupts */
+ if (ap->ops->freeze)
+ ap->ops->freeze(ap);
+
+ /* Stop the port DMA engines */
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+ }
+}
+
/* move to PCI subsystem */
int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
{
@@ -7200,6 +7220,7 @@
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
+EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
#ifdef CONFIG_PM
EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index a7baf3c..fc4b762 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -362,7 +362,10 @@
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __func__, drv->name, dev_name(dev));
- WARN_ON(!list_empty(&dev->devres_head));
+ if (!list_empty(&dev->devres_head)) {
+ dev_crit(dev, "Resources present before probing\n");
+ return -EBUSY;
+ }
re_probe:
dev->driver = drv;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f90b1b9..bef299e 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -28,6 +28,7 @@
#include <linux/limits.h>
#include <linux/property.h>
#include <linux/kmemleak.h>
+#include <linux/types.h>
#include "base.h"
#include "power/power.h"
@@ -68,7 +69,7 @@
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
{
- int i;
+ u32 i;
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
@@ -153,7 +154,7 @@
unsigned int type,
const char *name)
{
- int i;
+ u32 i;
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
@@ -350,7 +351,8 @@
*/
int platform_device_add(struct platform_device *pdev)
{
- int i, ret;
+ u32 i;
+ int ret;
if (!pdev)
return -EINVAL;
@@ -416,7 +418,7 @@
pdev->id = PLATFORM_DEVID_AUTO;
}
- while (--i >= 0) {
+ while (i--) {
struct resource *r = &pdev->resource[i];
if (r->parent)
release_resource(r);
@@ -437,7 +439,7 @@
*/
void platform_device_del(struct platform_device *pdev)
{
- int i;
+ u32 i;
if (pdev) {
device_remove_properties(&pdev->dev);
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 0c76d40..7e35574 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -581,6 +581,25 @@
return kobj;
}
+static inline void brd_check_and_reset_par(void)
+{
+ if (unlikely(!max_part))
+ max_part = 1;
+
+ /*
+ * make sure 'max_part' can be divided exactly by (1U << MINORBITS),
+ * otherwise, it is possiable to get same dev_t when adding partitions.
+ */
+ if ((1U << MINORBITS) % max_part != 0)
+ max_part = 1UL << fls(max_part);
+
+ if (max_part > DISK_MAX_PARTS) {
+ pr_info("brd: max_part can't be larger than %d, reset max_part = %d.\n",
+ DISK_MAX_PARTS, DISK_MAX_PARTS);
+ max_part = DISK_MAX_PARTS;
+ }
+}
+
static int __init brd_init(void)
{
struct brd_device *brd, *next;
@@ -604,8 +623,7 @@
if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
return -EIO;
- if (unlikely(!max_part))
- max_part = 1;
+ brd_check_and_reset_par();
for (i = 0; i < rd_nr; i++) {
brd = brd_alloc(i);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index ece4f70..4496e7a 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -848,14 +848,17 @@
/* selects the fdc and drive, and enables the fdc's input/dma. */
static void set_fdc(int drive)
{
+ unsigned int new_fdc = fdc;
+
if (drive >= 0 && drive < N_DRIVE) {
- fdc = FDC(drive);
+ new_fdc = FDC(drive);
current_drive = drive;
}
- if (fdc != 1 && fdc != 0) {
+ if (new_fdc >= N_FDC) {
pr_info("bad fdc value\n");
return;
}
+ fdc = new_fdc;
set_dor(fdc, ~0, 8);
#if N_FDC > 1
set_dor(1 - fdc, ~8, 0);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 44ef1d6..f287eec 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -215,10 +215,12 @@
err = __virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
if (err) {
virtqueue_kick(vblk->vqs[qid].vq);
- blk_mq_stop_hw_queue(hctx);
+ /* Don't stop the queue if -ENOMEM: we may have failed to
+ * bounce the buffer due to global resource outage.
+ */
+ if (err == -ENOSPC)
+ blk_mq_stop_hw_queue(hctx);
spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
- /* Out of mem doesn't actually happen, since we fall back
- * to direct descriptors */
if (err == -ENOMEM || err == -ENOSPC)
return BLK_MQ_RQ_QUEUE_BUSY;
return BLK_MQ_RQ_QUEUE_ERROR;
diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c
index 66cb2a9..1b81eb8 100644
--- a/drivers/bus/mhi/core/mhi_main.c
+++ b/drivers/bus/mhi/core/mhi_main.c
@@ -1285,6 +1285,10 @@
local_rp->ptr, local_rp->dword[0], local_rp->dword[1]);
chan = MHI_TRE_GET_EV_CHID(local_rp);
+ if (chan >= mhi_cntrl->max_chan) {
+ MHI_ERR("invalid channel id %u\n", chan);
+ continue;
+ }
mhi_chan = &mhi_cntrl->mhi_chan[chan];
if (likely(type == MHI_PKT_TYPE_TX_EVENT)) {
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index b3d3cd6..2d23442 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -3514,11 +3514,8 @@
static int fastrpc_device_open(struct inode *inode, struct file *filp)
{
int err = 0;
- struct dentry *debugfs_file;
struct fastrpc_file *fl = NULL;
struct fastrpc_apps *me = &gfa;
- char strpid[PID_SIZE];
- int buf_size = 0;
/*
* Indicates the device node opened
@@ -3536,13 +3533,6 @@
VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
if (err)
return err;
- snprintf(strpid, PID_SIZE, "%d", current->pid);
- buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
- fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
- snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
- current->comm, "_", current->pid);
- debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
- debugfs_root, fl, &debugfs_fops);
context_list_ctor(&fl->clst);
spin_lock_init(&fl->hlock);
@@ -3552,14 +3542,11 @@
INIT_HLIST_HEAD(&fl->remote_bufs);
INIT_HLIST_NODE(&fl->hn);
fl->sessionid = 0;
- fl->tgid = current->tgid;
fl->apps = me;
fl->mode = FASTRPC_MODE_SERIAL;
fl->cid = -1;
fl->dev_minor = dev_minor;
fl->init_mem = NULL;
- if (debugfs_file != NULL)
- fl->debugfs_file = debugfs_file;
fl->qos_request = 0;
fl->refcount = 0;
filp->private_data = fl;
@@ -3572,6 +3559,29 @@
return 0;
}
+static int fastrpc_set_process_info(struct fastrpc_file *fl)
+{
+ int err = 0, buf_size = 0;
+ char strpid[PID_SIZE];
+
+ fl->tgid = current->tgid;
+ snprintf(strpid, PID_SIZE, "%d", current->pid);
+ buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
+ fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
+ if (!fl->debug_buf) {
+ err = -ENOMEM;
+ return err;
+ }
+ snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
+ current->comm, "_", current->pid);
+ fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
+ debugfs_root, fl, &debugfs_fops);
+ if (!fl->debugfs_file)
+ pr_warn("Error: %s: %s: failed to create debugfs file %s\n",
+ current->comm, __func__, fl->debug_buf);
+ return err;
+}
+
static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
{
int err = 0;
@@ -3580,6 +3590,9 @@
VERIFY(err, fl != NULL);
if (err)
goto bail;
+ err = fastrpc_set_process_info(fl);
+ if (err)
+ goto bail;
if (fl->cid == -1) {
cid = *info;
VERIFY(err, cid < NUM_CHANNELS);
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 996b9ae1..a4ef9a6 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -746,10 +746,14 @@
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
msg = ssif_info->curr_msg;
if (msg) {
+ if (data) {
+ if (len > IPMI_MAX_MSG_LENGTH)
+ len = IPMI_MAX_MSG_LENGTH;
+ memcpy(msg->rsp, data, len);
+ } else {
+ len = 0;
+ }
msg->rsp_size = len;
- if (msg->rsp_size > IPMI_MAX_MSG_LENGTH)
- msg->rsp_size = IPMI_MAX_MSG_LENGTH;
- memcpy(msg->rsp, data, msg->rsp_size);
ssif_info->curr_msg = NULL;
}
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 514c0ad..8d07b3c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -554,7 +554,7 @@
pll->inited = true;
}
-static int clk_fabia_pll_enable(struct clk_hw *hw)
+static int pll_is_enabled(struct clk_hw *hw, u32 mask)
{
int ret;
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -564,6 +564,24 @@
if (ret)
return ret;
+ return !!(val & mask);
+}
+
+static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
+{
+ return pll_is_enabled(hw, PLL_LOCK_DET);
+}
+
+static int clk_fabia_pll_enable(struct clk_hw *hw)
+{
+ int ret;
+ struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+ u32 val, opmode_val, off = pll->offset;
+
+ ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+ if (ret)
+ return ret;
+
/* If in FSM mode, just vote for it */
if (val & PLL_VOTE_FSM_ENA) {
ret = clk_enable_regmap(hw);
@@ -572,6 +590,14 @@
return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
}
+ ret = regmap_read(pll->clkr.regmap, off + FABIA_OPMODE, &opmode_val);
+ if (ret)
+ return ret;
+
+ /* Skip If PLL is already running */
+ if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL))
+ return 0;
+
if (unlikely(!pll->inited))
clk_fabia_pll_configure(pll, pll->clkr.regmap, pll->config);
@@ -751,6 +777,7 @@
const struct clk_ops clk_fabia_pll_ops = {
.enable = clk_fabia_pll_enable,
.disable = clk_fabia_pll_disable,
+ .is_enabled = clk_alpha_pll_is_enabled,
.recalc_rate = clk_fabia_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_fabia_pll_set_rate,
@@ -761,6 +788,7 @@
const struct clk_ops clk_fabia_fixed_pll_ops = {
.enable = clk_fabia_pll_enable,
.disable = clk_fabia_pll_disable,
+ .is_enabled = clk_alpha_pll_is_enabled,
.recalc_rate = clk_fabia_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.list_registers = clk_fabia_pll_list_registers,
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 9d99f0c..f603a3f 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1,5 +1,7 @@
/*
- * Copyright (c) 2013, 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2018, 2020,
+ *
+ * The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -248,6 +250,7 @@
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f_curr;
u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
+ unsigned long recalc_rate;
if (rcg->flags & DFS_ENABLE_RCG)
return rcg->current_freq;
@@ -285,7 +288,16 @@
hid_div &= mask;
}
- return clk_rcg2_calc_rate(parent_rate, m, n, mode, hid_div);
+ recalc_rate = clk_rcg2_calc_rate(parent_rate, m, n, mode, hid_div);
+
+ /*
+ * Check the case when the RCG has been initialized to a non-CXO
+ * frequency.
+ */
+ if (rcg->enable_safe_config && !rcg->current_freq)
+ rcg->current_freq = recalc_rate;
+
+ return recalc_rate;
}
static int _freq_tbl_determine_rate(struct clk_hw *hw,
@@ -306,6 +318,9 @@
clk_flags = clk_hw_get_flags(hw);
p = clk_hw_get_parent_by_index(hw, index);
+ if (!p)
+ return -EINVAL;
+
if (clk_flags & CLK_SET_RATE_PARENT) {
if (f->pre_div) {
if (!rate)
diff --git a/drivers/clk/qcom/gcc-sdxpoorwills.c b/drivers/clk/qcom/gcc-sdxpoorwills.c
index 6732ebe..98a1ecd 100644
--- a/drivers/clk/qcom/gcc-sdxpoorwills.c
+++ b/drivers/clk/qcom/gcc-sdxpoorwills.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -714,12 +714,24 @@
},
};
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+ F(144000, P_BI_TCXO, 16, 3, 25),
+ F(400000, P_BI_TCXO, 12, 1, 4),
+ F(19200000, P_BI_TCXO, 1, 0, 0),
+ F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3),
+ F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+ F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+ F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+ F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+ { }
+};
+
static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
.cmd_rcgr = 0xf00c,
.mnd_width = 8,
.hid_width = 5,
.parent_map = gcc_parent_map_0,
- .freq_tbl = ftbl_gcc_gp1_clk_src,
+ .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc1_apps_clk_src",
.parent_names = gcc_parent_names_0,
diff --git a/drivers/clk/qcom/gdsc-regulator.c b/drivers/clk/qcom/gdsc-regulator.c
index 15a93cd..1ffb341 100644
--- a/drivers/clk/qcom/gdsc-regulator.c
+++ b/drivers/clk/qcom/gdsc-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -92,6 +92,7 @@
int root_clk_idx;
u32 gds_timeout;
u32 flags;
+ bool skip_disable_before_enable;
};
enum gdscr_status {
@@ -379,6 +380,7 @@
clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);
sc->is_gdsc_enabled = true;
+ sc->skip_disable_before_enable = false;
mutex_unlock(&gdsc_seq_lock);
@@ -391,6 +393,16 @@
uint32_t regval;
int i, ret = 0;
+ /*
+ * Protect GDSC against late_init disabling when the GDSC is enabled
+ * by an entity outside external to HLOS.
+ */
+ if (sc->skip_disable_before_enable) {
+ dev_dbg(&rdev->dev, "Skip Disabling: %s\n", sc->rdesc.name);
+ sc->skip_disable_before_enable = false;
+ return 0;
+ }
+
mutex_lock(&gdsc_seq_lock);
if (sc->force_root_en)
@@ -827,6 +839,9 @@
clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
}
+ sc->skip_disable_before_enable = of_property_read_bool(
+ pdev->dev.of_node, "qcom,skip-disable-before-sw-enable");
+
reg_config.dev = &pdev->dev;
reg_config.init_data = init_data;
reg_config.driver_data = sc;
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 4ce4e7f..d9c1f22 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -797,7 +797,11 @@
GATE("vcp", "clk_m", 29, 0, tegra_clk_vcp, 0),
GATE("apbdma", "clk_m", 34, 0, tegra_clk_apbdma, 0),
GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
- GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0),
+ /*
+ * Critical for RAM re-repair operation, which must occur on resume
+ * from LP1 system suspend and as part of CCPLEX cluster switching.
+ */
+ GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL),
GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0),
GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index e3d40a8..915253b 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -87,7 +87,6 @@
struct atmel_aes_caps {
bool has_dualbuff;
bool has_cfb64;
- bool has_ctr32;
bool has_gcm;
u32 max_burst_size;
};
@@ -923,8 +922,9 @@
struct atmel_aes_ctr_ctx *ctx = atmel_aes_ctr_ctx_cast(dd->ctx);
struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq);
struct scatterlist *src, *dst;
- u32 ctr, blocks;
size_t datalen;
+ u32 ctr;
+ u16 blocks, start, end;
bool use_dma, fragmented = false;
/* Check for transfer completion. */
@@ -936,27 +936,17 @@
datalen = req->nbytes - ctx->offset;
blocks = DIV_ROUND_UP(datalen, AES_BLOCK_SIZE);
ctr = be32_to_cpu(ctx->iv[3]);
- if (dd->caps.has_ctr32) {
- /* Check 32bit counter overflow. */
- u32 start = ctr;
- u32 end = start + blocks - 1;
- if (end < start) {
- ctr |= 0xffffffff;
- datalen = AES_BLOCK_SIZE * -start;
- fragmented = true;
- }
- } else {
- /* Check 16bit counter overflow. */
- u16 start = ctr & 0xffff;
- u16 end = start + (u16)blocks - 1;
+ /* Check 16bit counter overflow. */
+ start = ctr & 0xffff;
+ end = start + blocks - 1;
- if (blocks >> 16 || end < start) {
- ctr |= 0xffff;
- datalen = AES_BLOCK_SIZE * (0x10000-start);
- fragmented = true;
- }
+ if (blocks >> 16 || end < start) {
+ ctr |= 0xffff;
+ datalen = AES_BLOCK_SIZE * (0x10000 - start);
+ fragmented = true;
}
+
use_dma = (datalen >= ATMEL_AES_DMA_THRESHOLD);
/* Jump to offset. */
@@ -1926,7 +1916,6 @@
{
dd->caps.has_dualbuff = 0;
dd->caps.has_cfb64 = 0;
- dd->caps.has_ctr32 = 0;
dd->caps.has_gcm = 0;
dd->caps.max_burst_size = 1;
@@ -1935,14 +1924,12 @@
case 0x500:
dd->caps.has_dualbuff = 1;
dd->caps.has_cfb64 = 1;
- dd->caps.has_ctr32 = 1;
dd->caps.has_gcm = 1;
dd->caps.max_burst_size = 4;
break;
case 0x200:
dd->caps.has_dualbuff = 1;
dd->caps.has_cfb64 = 1;
- dd->caps.has_ctr32 = 1;
dd->caps.has_gcm = 1;
dd->caps.max_burst_size = 4;
break;
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 1ef5382..e80523b 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,7 +1,7 @@
/*
* QTI Crypto Engine driver.
*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -4680,7 +4680,7 @@
pce_dev->intr_cadence = 0;
atomic_set(&pce_dev->bunch_cmd_seq, 0);
atomic_set(&pce_dev->last_intr_seq, 0);
- pce_dev->cadence_flag = ~pce_dev->cadence_flag;
+ pce_dev->cadence_flag = !pce_dev->cadence_flag;
}
}
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index db1d3d8..d410562 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1,7 +1,7 @@
/*
* QTI CE device driver.
*
- * Copyright (c) 2010-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1808,10 +1808,11 @@
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
- sizeof(struct qcedev_sha_op_req)))
+ sizeof(struct qcedev_sha_op_req))) {
err = -EFAULT;
goto exit_free_qcedev_areq;
}
+ }
break;
case QCEDEV_IOCTL_SHA_FINAL_REQ:
@@ -1900,10 +1901,11 @@
handle->sha_ctxt.diglen);
mutex_unlock(&hash_access_lock);
if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
- sizeof(struct qcedev_sha_op_req)))
+ sizeof(struct qcedev_sha_op_req))) {
err = -EFAULT;
goto exit_free_qcedev_areq;
}
+ }
break;
case QCEDEV_IOCTL_MAP_BUF_REQ:
@@ -1918,6 +1920,11 @@
goto exit_free_qcedev_areq;
}
+ if (map_buf.num_fds > QCEDEV_MAX_BUFFERS) {
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
+ }
+
for (i = 0; i < map_buf.num_fds; i++) {
err = qcedev_check_and_map_buffer(handle,
map_buf.fd[i],
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
index 4757609..b3ea6d6 100644
--- a/drivers/crypto/picoxcell_crypto.c
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -1632,6 +1632,11 @@
return false;
}
+static void spacc_tasklet_kill(void *data)
+{
+ tasklet_kill(data);
+}
+
static int spacc_probe(struct platform_device *pdev)
{
int i, err, ret = -EINVAL;
@@ -1674,6 +1679,14 @@
return -ENXIO;
}
+ tasklet_init(&engine->complete, spacc_spacc_complete,
+ (unsigned long)engine);
+
+ ret = devm_add_action(&pdev->dev, spacc_tasklet_kill,
+ &engine->complete);
+ if (ret)
+ return ret;
+
if (devm_request_irq(&pdev->dev, irq->start, spacc_spacc_irq, 0,
engine->name, engine)) {
dev_err(engine->dev, "failed to request IRQ\n");
@@ -1736,8 +1749,6 @@
INIT_LIST_HEAD(&engine->completed);
INIT_LIST_HEAD(&engine->in_progress);
engine->in_flight = 0;
- tasklet_init(&engine->complete, spacc_spacc_complete,
- (unsigned long)engine);
platform_set_drvdata(pdev, engine);
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 3a2239c..a806ee7 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -202,7 +202,8 @@
config ARM_RK3399_DMC_DEVFREQ
tristate "ARM RK3399 DMC DEVFREQ Driver"
- depends on ARCH_ROCKCHIP
+ depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \
+ (COMPILE_TEST && HAVE_ARM_SMCCC)
select DEVFREQ_EVENT_ROCKCHIP_DFI
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select PM_DEVFREQ_EVENT
diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
index cd94980..8851bc4 100644
--- a/drivers/devfreq/event/Kconfig
+++ b/drivers/devfreq/event/Kconfig
@@ -33,7 +33,7 @@
config DEVFREQ_EVENT_ROCKCHIP_DFI
tristate "ROCKCHIP DFI DEVFREQ event Driver"
- depends on ARCH_ROCKCHIP
+ depends on ARCH_ROCKCHIP || COMPILE_TEST
help
This add the devfreq-event driver for Rockchip SoC. It provides DFI
(DDR Monitor Module) driver to count ddr load.
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 6d7d2d5..f0932f2 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -1944,8 +1944,6 @@
return;
}
- spin_lock(&cohc->lock);
-
/*
* When we reach this point, at least one queue item
* should have been moved over from cohc->queue to
@@ -1966,8 +1964,6 @@
if (coh901318_queue_start(cohc) == NULL)
cohc->busy = 0;
- spin_unlock(&cohc->lock);
-
/*
* This tasklet will remove items from cohc->active
* and thus terminates them.
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 22f7f0c..4eaf92b 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -288,7 +288,7 @@
/* Do not allocate if desc are waiting for ack */
list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) {
- if (async_tx_test_ack(&dma_desc->txd)) {
+ if (async_tx_test_ack(&dma_desc->txd) && !dma_desc->cb_count) {
list_del(&dma_desc->node);
spin_unlock_irqrestore(&tdc->lock, flags);
dma_desc->txd.flags = 0;
@@ -755,10 +755,6 @@
bool was_busy;
spin_lock_irqsave(&tdc->lock, flags);
- if (list_empty(&tdc->pending_sg_req)) {
- spin_unlock_irqrestore(&tdc->lock, flags);
- return 0;
- }
if (!tdc->busy)
goto skip_dma_stop;
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 3e626fd..1c65f5ac 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -139,13 +139,16 @@
efivar_attr_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
+ unsigned long size = sizeof(var->Data);
char *str = buf;
+ int ret;
if (!entry || !buf)
return -EINVAL;
- var->DataSize = 1024;
- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
+ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
+ var->DataSize = size;
+ if (ret)
return -EIO;
if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
@@ -172,13 +175,16 @@
efivar_size_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
+ unsigned long size = sizeof(var->Data);
char *str = buf;
+ int ret;
if (!entry || !buf)
return -EINVAL;
- var->DataSize = 1024;
- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
+ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
+ var->DataSize = size;
+ if (ret)
return -EIO;
str += sprintf(str, "0x%lx\n", var->DataSize);
@@ -189,12 +195,15 @@
efivar_data_read(struct efivar_entry *entry, char *buf)
{
struct efi_variable *var = &entry->var;
+ unsigned long size = sizeof(var->Data);
+ int ret;
if (!entry || !buf)
return -EINVAL;
- var->DataSize = 1024;
- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
+ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data);
+ var->DataSize = size;
+ if (ret)
return -EIO;
memcpy(buf, var->Data, var->DataSize);
@@ -263,6 +272,9 @@
u8 *data;
int err;
+ if (!entry || !buf)
+ return -EINVAL;
+
if (is_compat()) {
struct compat_efi_variable *compat;
@@ -314,14 +326,16 @@
{
struct efi_variable *var = &entry->var;
struct compat_efi_variable *compat;
+ unsigned long datasize = sizeof(var->Data);
size_t size;
+ int ret;
if (!entry || !buf)
return 0;
- var->DataSize = 1024;
- if (efivar_entry_get(entry, &entry->var.Attributes,
- &entry->var.DataSize, entry->var.Data))
+ ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data);
+ var->DataSize = datasize;
+ if (ret)
return -EIO;
if (is_compat()) {
diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
index 7847dd3..036a78b 100644
--- a/drivers/gpio/gpio-grgpio.c
+++ b/drivers/gpio/gpio-grgpio.c
@@ -259,17 +259,16 @@
lirq->irq = irq;
uirq = &priv->uirqs[lirq->index];
if (uirq->refcnt == 0) {
+ spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
dev_name(priv->dev), priv);
if (ret) {
dev_err(priv->dev,
"Could not request underlying irq %d\n",
uirq->uirq);
-
- spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
-
return ret;
}
+ spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
}
uirq->refcnt++;
@@ -315,8 +314,11 @@
if (index >= 0) {
uirq = &priv->uirqs[lirq->index];
uirq->refcnt--;
- if (uirq->refcnt == 0)
+ if (uirq->refcnt == 0) {
+ spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
free_irq(uirq->uirq, priv);
+ return;
+ }
}
spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 26afdff..0c2ed125 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -336,17 +336,9 @@
path_size += le16_to_cpu(path->usSize);
if (device_support & le16_to_cpu(path->usDeviceTag)) {
- uint8_t con_obj_id, con_obj_num, con_obj_type;
-
- con_obj_id =
+ uint8_t con_obj_id =
(le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK)
>> OBJECT_ID_SHIFT;
- con_obj_num =
- (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK)
- >> ENUM_ID_SHIFT;
- con_obj_type =
- (le16_to_cpu(path->usConnObjectId) &
- OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
/* Skip TV/CV support */
if ((le16_to_cpu(path->usDeviceTag) ==
@@ -371,15 +363,7 @@
router.ddc_valid = false;
router.cd_valid = false;
for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) {
- uint8_t grph_obj_id, grph_obj_num, grph_obj_type;
-
- grph_obj_id =
- (le16_to_cpu(path->usGraphicObjIds[j]) &
- OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
- grph_obj_num =
- (le16_to_cpu(path->usGraphicObjIds[j]) &
- ENUM_ID_MASK) >> ENUM_ID_SHIFT;
- grph_obj_type =
+ uint8_t grph_obj_type =
(le16_to_cpu(path->usGraphicObjIds[j]) &
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 9b17a66..aa54a6a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -81,7 +81,11 @@
struct videomode vm;
unsigned long prate;
unsigned int cfg;
- int div;
+ int div, ret;
+
+ ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk);
+ if (ret)
+ return;
vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay;
vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end;
@@ -140,6 +144,8 @@
ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
cfg);
+
+ clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
}
static bool atmel_hlcdc_crtc_mode_fixup(struct drm_crtc *c,
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 17aedaa..e05dda9 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -980,20 +980,9 @@
static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
{
struct drm_dp_mst_port *rport = NULL;
-
mutex_lock(&mgr->lock);
- /*
- * Port may or may not be 'valid' but we don't care about that when
- * destroying the port and we are guaranteed that the port pointer
- * will be valid until we've finished
- */
- if (current_work() == &mgr->destroy_connector_work) {
- kref_get(&port->kref);
- rport = port;
- } else if (mgr->mst_primary) {
- rport = drm_dp_mst_get_port_ref_locked(mgr->mst_primary,
- port);
- }
+ if (mgr->mst_primary)
+ rport = drm_dp_mst_get_port_ref_locked(mgr->mst_primary, port);
mutex_unlock(&mgr->lock);
return rport;
}
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 811316c..0a8fc78 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2960,7 +2960,7 @@
*
* Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
*/
-static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
+u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
{
u8 vic;
@@ -2982,6 +2982,7 @@
}
return 0;
}
+EXPORT_SYMBOL(drm_match_hdmi_mode);
static bool drm_valid_hdmi_vic(u8 vic)
{
@@ -3081,6 +3082,7 @@
if (!newmode)
return NULL;
+ newmode->vic_id = vic;
newmode->vrefresh = 0;
return newmode;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index e07cb1f..2b6c04a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1775,8 +1775,9 @@
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies),
dsi->supplies);
if (ret) {
- dev_info(dev, "failed to get regulators: %d\n", ret);
- return -EPROBE_DEFER;
+ if (ret != -EPROBE_DEFER)
+ dev_info(dev, "failed to get regulators: %d\n", ret);
+ return ret;
}
dsi->clks = devm_kzalloc(dev,
@@ -1789,9 +1790,10 @@
dsi->clks[i] = devm_clk_get(dev, clk_names[i]);
if (IS_ERR(dsi->clks[i])) {
if (strcmp(clk_names[i], "sclk_mipi") == 0) {
- strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME);
- i--;
- continue;
+ dsi->clks[i] = devm_clk_get(dev,
+ OLD_SCLK_MIPI_CLK_NAME);
+ if (!IS_ERR(dsi->clks[i]))
+ continue;
}
dev_info(dev, "failed to get the clock: %s\n",
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 3a44e70..d224fc1 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -516,6 +516,7 @@
container_of(helper, struct psb_fbdev, psb_fb_helper);
struct drm_device *dev = psb_fbdev->psb_fb_helper.dev;
struct drm_psb_private *dev_priv = dev->dev_private;
+ unsigned int fb_size;
int bytespp;
bytespp = sizes->surface_bpp / 8;
@@ -525,8 +526,11 @@
/* If the mode will not fit in 32bit then switch to 16bit to get
a console on full resolution. The X mode setting server will
allocate its own 32bit GEM framebuffer */
- if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height >
- dev_priv->vram_stolen_size) {
+ fb_size = ALIGN(sizes->surface_width * bytespp, 64) *
+ sizes->surface_height;
+ fb_size = ALIGN(fb_size, PAGE_SIZE);
+
+ if (fb_size > dev_priv->vram_stolen_size) {
sizes->surface_bpp = 16;
sizes->surface_depth = 16;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 01a21dd..1ed60da 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -306,6 +306,7 @@
static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
{
struct drm_device *drm = mtk_crtc->base.dev;
+ struct drm_crtc *crtc = &mtk_crtc->base;
int i;
DRM_DEBUG_DRIVER("%s\n", __func__);
@@ -327,6 +328,13 @@
mtk_disp_mutex_unprepare(mtk_crtc->mutex);
pm_runtime_put(drm->dev);
+
+ if (crtc->state->event && !crtc->state->active) {
+ spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irq(&crtc->dev->event_lock);
+ }
}
static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 5396a35..94392d3 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@
#include "dp_catalog.h"
#include "dp_reg.h"
+#include "msm_kms.h"
#define DP_GET_MSB(x) (x >> 8)
#define DP_GET_LSB(x) (x & 0xff)
@@ -394,7 +395,8 @@
return dp_read(catalog, io_data, DP_HDCP_STATUS);
}
-static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
+static void dp_catalog_panel_setup_hdr_infoframe_sdp(
+ struct dp_catalog_panel *panel)
{
struct dp_catalog_private *catalog;
struct drm_msm_ext_hdr_metadata *hdr;
@@ -501,7 +503,7 @@
DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
-static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
+static void dp_catalog_panel_setup_hdr_vsc_sdp(struct dp_catalog_panel *panel)
{
struct dp_catalog_private *catalog;
struct dp_io_data *io_data;
@@ -627,8 +629,8 @@
cfg2 |= BIT(15) | BIT(16);
dp_write(catalog, io_data, MMSS_DP_SDP_CFG2, cfg2);
- dp_catalog_panel_setup_vsc_sdp(panel);
- dp_catalog_panel_setup_infoframe_sdp(panel);
+ dp_catalog_panel_setup_hdr_vsc_sdp(panel);
+ dp_catalog_panel_setup_hdr_infoframe_sdp(panel);
/* indicates presence of VSC (BIT(6) of MISC1) */
misc |= BIT(14);
@@ -772,6 +774,7 @@
catalog = dp_catalog_get_priv(ctrl);
io_data = catalog->io.dp_link;
+ misc_val = cc;
misc_val |= (tb << 5);
misc_val |= BIT(0); /* Configure clock to synchronous mode */
@@ -780,7 +783,7 @@
}
static void dp_catalog_ctrl_config_msa(struct dp_catalog_ctrl *ctrl,
- u32 rate, u32 stream_rate_khz)
+ u32 rate, u32 stream_rate_khz, u32 out_format)
{
u32 pixel_m, pixel_n;
u32 mvid, nvid;
@@ -815,6 +818,9 @@
pr_debug("rate = %d\n", rate);
+ if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ mvid *= 2;
+
if (link_rate_hbr2 == rate)
nvid *= 2;
@@ -1319,6 +1325,158 @@
return ret;
}
+static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
+{
+ struct dp_catalog_private *catalog;
+ struct dp_io_data *io_data;
+ u32 header, parity, data;
+ u8 bpc, off = 0;
+ u8 buf[SZ_128];
+
+ if (!panel) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ catalog = dp_catalog_get_priv(panel);
+ io_data = catalog->io.dp_link;
+
+ /* HEADER BYTE 1 */
+ header = panel->vsc_sdp_data.vsc_header_byte1;
+ parity = dp_header_get_parity(header);
+ data = ((header << HEADER_BYTE_1_BIT)
+ | (parity << PARITY_BYTE_1_BIT));
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_0, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ /* HEADER BYTE 2 */
+ header = panel->vsc_sdp_data.vsc_header_byte2;
+ parity = dp_header_get_parity(header);
+ data = ((header << HEADER_BYTE_2_BIT)
+ | (parity << PARITY_BYTE_2_BIT));
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_1, data);
+
+ /* HEADER BYTE 3 */
+ header = panel->vsc_sdp_data.vsc_header_byte3;
+ parity = dp_header_get_parity(header);
+ data = ((header << HEADER_BYTE_3_BIT)
+ | (parity << PARITY_BYTE_3_BIT));
+ data |= dp_read(catalog, io_data, MMSS_DP_GENERIC0_1);
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_1, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ data = 0;
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_2, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_3, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_4, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_5, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ switch (panel->vsc_sdp_data.bpc) {
+ case 10:
+ bpc = BIT(1);
+ break;
+ case 8:
+ default:
+ bpc = BIT(0);
+ break;
+ }
+
+ data = (panel->vsc_sdp_data.colorimetry & 0xF) |
+ ((panel->vsc_sdp_data.pixel_encoding & 0xF) << 4) |
+ (bpc << 8) |
+ ((panel->vsc_sdp_data.dynamic_range & 0x1) << 15) |
+ ((panel->vsc_sdp_data.content_type & 0x7) << 16);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_6, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ data = 0;
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_7, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_8, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ dp_write(catalog, io_data, MMSS_DP_GENERIC0_9, data);
+ memcpy(buf + off, &data, sizeof(data));
+ off += sizeof(data);
+
+ print_hex_dump(KERN_DEBUG, "[drm-dp] VSC: ",
+ DUMP_PREFIX_NONE, 16, 4, buf, off, false);
+}
+
+static void dp_catalog_panel_config_vsc_sdp(struct dp_catalog_panel *panel,
+ bool en)
+{
+ struct dp_catalog_private *catalog;
+ struct dp_io_data *io_data;
+ u32 cfg, cfg2, misc;
+
+ if (!panel) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ catalog = dp_catalog_get_priv(panel);
+ io_data = catalog->io.dp_link;
+
+ cfg = dp_read(catalog, io_data, MMSS_DP_SDP_CFG);
+ cfg2 = dp_read(catalog, io_data, MMSS_DP_SDP_CFG2);
+ misc = dp_read(catalog, io_data, DP_MISC1_MISC0);
+
+ if (en) {
+ /* GEN0_SDP_EN */
+ cfg |= BIT(17);
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG, cfg);
+
+ /* GENERIC0_SDPSIZE */
+ cfg2 |= BIT(16);
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG2, cfg2);
+
+ dp_catalog_panel_setup_vsc_sdp(panel);
+
+ /* indicates presence of VSC (BIT(6) of MISC1) */
+ misc |= BIT(14);
+
+ pr_debug("Enabled\n");
+ } else {
+ /* GEN0_SDP_EN */
+ cfg &= ~BIT(17);
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG, cfg);
+
+ /* GENERIC0_SDPSIZE */
+ cfg2 &= ~BIT(16);
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG2, cfg2);
+
+ /* switch back to MSA */
+ misc &= ~BIT(14);
+
+ pr_debug("Disabled\n");
+ }
+
+ pr_debug("misc settings = 0x%x\n", misc);
+ dp_write(catalog, io_data, DP_MISC1_MISC0, misc);
+
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG3, 0x01);
+ dp_write(catalog, io_data, MMSS_DP_SDP_CFG3, 0x00);
+}
+
/* panel related catalog functions */
static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel *panel)
{
@@ -1762,6 +1920,7 @@
.config_hdr = dp_catalog_panel_config_hdr,
.tpg_config = dp_catalog_panel_tpg_cfg,
.config_spd = dp_catalog_panel_config_spd,
+ .config_vsc_sdp = dp_catalog_panel_config_vsc_sdp,
};
if (!dev || !parser) {
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h
index dbcbd8b..12dce42 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -64,6 +64,22 @@
struct drm_msm_ext_hdr_metadata hdr_meta;
};
+struct dp_catalog_vsc_sdp_data {
+ u32 vsc_header_byte0;
+ u32 vsc_header_byte1;
+ u32 vsc_header_byte2;
+ u32 vsc_header_byte3;
+
+ u32 bpc;
+
+ u32 version;
+ u32 length;
+ u32 pixel_encoding;
+ u32 colorimetry;
+ u32 dynamic_range;
+ u32 content_type;
+};
+
struct dp_catalog_aux {
u32 data;
u32 isr;
@@ -94,7 +110,7 @@
void (*mainlink_ctrl)(struct dp_catalog_ctrl *ctrl, bool enable);
void (*config_misc)(struct dp_catalog_ctrl *ctrl, u32 cc, u32 tb);
void (*config_msa)(struct dp_catalog_ctrl *ctrl, u32 rate,
- u32 stream_rate_khz);
+ u32 stream_rate_khz, u32 out_format);
void (*set_pattern)(struct dp_catalog_ctrl *ctrl, u32 pattern);
void (*reset)(struct dp_catalog_ctrl *ctrl);
void (*usb_reset)(struct dp_catalog_ctrl *ctrl, bool flip);
@@ -159,6 +175,7 @@
u8 *spd_vendor_name;
u8 *spd_product_description;
+ struct dp_catalog_vsc_sdp_data vsc_sdp_data;
struct dp_catalog_hdr_data hdr_data;
/* TPG */
@@ -174,6 +191,7 @@
void (*config_hdr)(struct dp_catalog_panel *panel, bool en);
void (*tpg_config)(struct dp_catalog_panel *panel, bool enable);
void (*config_spd)(struct dp_catalog_panel *panel);
+ void (*config_vsc_sdp)(struct dp_catalog_panel *panel, bool en);
};
struct dp_catalog {
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index befbc5c..365fefc 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
#include <linux/completion.h>
#include <linux/delay.h>
+#include "msm_kms.h"
#include "dp_ctrl.h"
#define DP_KHZ_TO_HZ 1000
@@ -149,9 +150,16 @@
{
u32 config = 0, tbd;
u8 *dpcd = ctrl->panel->dpcd;
+ u32 out_format = ctrl->panel->pinfo.out_format;
config |= (2 << 13); /* Default-> LSCLK DIV: 1/4 LCLK */
- config |= (0 << 11); /* RGB */
+
+ if (out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ config |= (1 << 11); /* YUV420 */
+ else if (out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422)
+ config |= (2 << 11); /* YUV422 */
+ else
+ config |= (0 << 11); /* RGB */
/* Scrambler reset enable */
if (dpcd[DP_EDP_CONFIGURATION_CAP] & DP_ALTERNATE_SCRAMBLER_RESET_CAP)
@@ -178,6 +186,25 @@
ctrl->catalog->config_ctrl(ctrl->catalog, config);
}
+static void dp_ctrl_misc_ctrl(struct dp_ctrl_private *ctrl)
+{
+ u32 out_format = ctrl->panel->pinfo.out_format;
+ u32 yres = ctrl->panel->pinfo.v_active;
+ u32 cc, tb;
+
+ tb = ctrl->link->get_test_bits_depth(ctrl->link,
+ ctrl->panel->pinfo.bpp);
+ cc = ctrl->link->get_colorimetry_config(ctrl->link);
+ if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422) {
+ cc |= (0x01 << 1); /* Set 4:2:2 Pixel Encoding */
+ cc |= BIT(3); /* Set YCbCr Colorimetry */
+ if (yres >= 720)
+ cc |= BIT(4); /* Set BT709 */
+ }
+
+ ctrl->catalog->config_misc(ctrl->catalog, cc, tb);
+}
+
/**
* dp_ctrl_configure_source_params() - configures DP transmitter source params
* @ctrl: Display Port Driver data
@@ -187,17 +214,13 @@
*/
static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)
{
- u32 cc, tb;
ctrl->catalog->lane_mapping(ctrl->catalog);
ctrl->catalog->mainlink_ctrl(ctrl->catalog, true);
dp_ctrl_config_ctrl(ctrl);
+ dp_ctrl_misc_ctrl(ctrl);
- tb = ctrl->link->get_test_bits_depth(ctrl->link,
- ctrl->panel->pinfo.bpp);
- cc = ctrl->link->get_colorimetry_config(ctrl->link);
- ctrl->catalog->config_misc(ctrl->catalog, cc, tb);
ctrl->panel->timing_cfg(ctrl->panel);
}
@@ -251,7 +274,8 @@
{
u32 const multiplier = 1000000;
u64 pclk, lclk;
- u8 bpp, ln_cnt;
+ u32 bpp;
+ u8 ln_cnt;
int run_idx = 0;
u32 lwidth, h_blank;
u32 fifo_empty = 0;
@@ -309,6 +333,8 @@
int min_hblank_tmp = 0;
bool extra_req_bytes_is_neg = false;
struct dp_panel_info *pinfo = &ctrl->panel->pinfo;
+ int div = 0;
+ u32 out_format = pinfo->out_format;
u8 dp_brute_force = 1;
u64 brute_force_threshold = 10;
@@ -317,10 +343,26 @@
ln_cnt = ctrl->link->link_params.lane_count;
bpp = pinfo->bpp;
- lwidth = pinfo->h_active;
- h_blank = pinfo->h_back_porch + pinfo->h_front_porch +
- pinfo->h_sync_width;
- pclk = pinfo->pixel_clk_khz * 1000;
+ if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422) {
+ switch (pinfo->bpp) {
+ case 24:
+ bpp = 16;
+ break;
+ case 30:
+ bpp = 20;
+ break;
+ default:
+ bpp = 16;
+ break;
+ };
+ } else if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) {
+ div = 1;
+ }
+
+ lwidth = pinfo->h_active >> div;
+ h_blank = (pinfo->h_back_porch + pinfo->h_front_porch +
+ pinfo->h_sync_width) >> div;
+ pclk = (pinfo->pixel_clk_khz * 1000) >> div;
boundary_moderation_en = 0;
upper_bdry_cnt = 0;
@@ -1201,7 +1243,7 @@
ctrl->dp_ctrl.push_idle(&ctrl->dp_ctrl);
ctrl->dp_ctrl.reset(&ctrl->dp_ctrl);
- ctrl->pixel_rate = ctrl->panel->pinfo.pixel_clk_khz;
+ ctrl->pixel_rate = ctrl->panel->get_pixel_clk(ctrl->panel);
do {
if (ret == -EAGAIN) {
@@ -1229,7 +1271,9 @@
ctrl->catalog->config_msa(ctrl->catalog,
drm_dp_bw_code_to_link_rate(
- ctrl->link->link_params.bw_code), ctrl->pixel_rate);
+ ctrl->link->link_params.bw_code),
+ ctrl->pixel_rate,
+ ctrl->panel->pinfo.out_format);
reinit_completion(&ctrl->idle_comp);
@@ -1374,7 +1418,7 @@
drm_dp_link_rate_to_bw_code(rate);
ctrl->link->link_params.lane_count =
ctrl->panel->link_info.num_lanes;
- ctrl->pixel_rate = ctrl->panel->pinfo.pixel_clk_khz;
+ ctrl->pixel_rate = ctrl->panel->get_pixel_clk(ctrl->panel);
}
pr_debug("bw_code=%d, lane_count=%d, pixel_rate=%d\n",
@@ -1395,7 +1439,8 @@
while (--link_train_max_retries && !atomic_read(&ctrl->aborted)) {
ctrl->catalog->config_msa(ctrl->catalog,
drm_dp_bw_code_to_link_rate(
- ctrl->link->link_params.bw_code), ctrl->pixel_rate);
+ ctrl->link->link_params.bw_code),
+ ctrl->pixel_rate, ctrl->panel->pinfo.out_format);
rc = dp_ctrl_setup_main_link(ctrl, true);
if (!rc)
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c
index d023f64..386c56c 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -533,9 +533,10 @@
mutex_lock(&connector->dev->mode_config.mutex);
list_for_each_entry(mode, &connector->modes, head) {
ret = snprintf(buf + len, max_size,
- "%s %d %d %d %d %d 0x%x\n",
- mode->name, mode->vrefresh, mode->picture_aspect_ratio,
- mode->htotal, mode->vtotal, mode->clock, mode->flags);
+ "%d %s %d %d %d %d %d 0x%x\n",
+ mode->vic_id, mode->name, mode->vrefresh,
+ mode->picture_aspect_ratio, mode->htotal, mode->vtotal,
+ mode->clock, mode->flags);
if (dp_debug_check_buffer_overflow(ret, &max_size, &len))
break;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index 9ae0482..9bf732b 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -522,6 +522,7 @@
dp->panel->handle_sink_request(dp->panel);
dp->dp_display.max_pclk_khz = dp->parser->max_pclk_khz;
+ dp->dp_display.yuv_support = dp->parser->yuv_support;
notify:
dp_display_send_hpd_notification(dp, true);
@@ -1023,6 +1024,8 @@
{
const u32 num_components = 3, default_bpp = 24;
struct dp_display_private *dp;
+ u32 pixel_clk_khz = 0;
+ u32 rate_ratio = RGB_24BPP_TMDS_CHAR_RATE_RATIO;
if (!dp_display) {
pr_err("invalid input\n");
@@ -1031,13 +1034,43 @@
dp = container_of(dp_display, struct dp_display_private, dp_display);
mutex_lock(&dp->session_lock);
- mode->timing.bpp =
- dp_display->connector->display_info.bpc * num_components;
+ if (mode->timing.out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) {
+ mode->timing.bpp =
+ dp_display->connector->display_info.y420_bpc *
+ num_components;
+ rate_ratio = YUV420_24BPP_TMDS_CHAR_RATE_RATIO;
+ } else {
+ mode->timing.bpp =
+ dp_display->connector->display_info.bpc *
+ num_components;
+ }
+
+ pixel_clk_khz = mode->timing.pixel_clk_khz / rate_ratio;
+
if (!mode->timing.bpp)
mode->timing.bpp = default_bpp;
mode->timing.bpp = dp->panel->get_mode_bpp(dp->panel,
- mode->timing.bpp, mode->timing.pixel_clk_khz);
+ mode->timing.bpp, pixel_clk_khz);
+
+ /* Refactor bits per pixel for YUV422 format */
+ if (mode->timing.out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422) {
+ switch (mode->timing.bpp) {
+ case 18:
+ mode->timing.bpp = 24;
+ break;
+ case 24:
+ mode->timing.bpp = 30;
+ break;
+ case 30:
+ mode->timing.bpp = 36;
+ break;
+ default:
+ mode->timing.bpp = 30;
+ break;
+ };
+ pr_debug("YCC422 bpp = %d\n", mode->timing.bpp);
+ }
dp->panel->pinfo = mode->timing;
dp->panel->init(dp->panel);
@@ -1287,12 +1320,14 @@
return 0;
}
-static int dp_display_validate_mode(struct dp_display *dp, u32 mode_pclk_khz)
+static int dp_display_get_dc_support(struct dp_display *dp,
+ u32 mode_pclk_khz, u32 out_format, bool dc_enable)
{
- const u32 num_components = 3, default_bpp = 24;
struct dp_display_private *dp_display;
struct drm_dp_link *link_info;
- u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
+ u32 mode_rate_khz = 0, supported_rate_khz = 0;
+ u32 default_bpp = 24, max_supported_bpp = 30;
+ u32 rate_ratio = RGB_24BPP_TMDS_CHAR_RATE_RATIO;
if (!dp || !mode_pclk_khz || !dp->connector) {
pr_err("invalid params\n");
@@ -1302,7 +1337,51 @@
dp_display = container_of(dp, struct dp_display_private, dp_display);
link_info = &dp_display->panel->link_info;
- mode_bpp = dp->connector->display_info.bpc * num_components;
+ if (out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ rate_ratio = YUV420_24BPP_TMDS_CHAR_RATE_RATIO;
+
+ mode_pclk_khz /= rate_ratio;
+
+ mode_rate_khz = mode_pclk_khz * default_bpp;
+ if (dc_enable)
+ mode_rate_khz = mode_pclk_khz * max_supported_bpp;
+
+ supported_rate_khz = link_info->num_lanes * link_info->rate * 8;
+
+ if (mode_rate_khz > supported_rate_khz)
+ return false;
+
+ return true;
+}
+
+static int dp_display_validate_mode(struct dp_display *dp,
+ u32 mode_pclk_khz, u32 flags)
+{
+ const u32 num_components = 3, default_bpp = 24;
+ struct dp_display_private *dp_display;
+ struct drm_dp_link *link_info;
+ u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
+
+ if (!dp || !dp->connector) {
+ pr_err("invalid params\n");
+ return -EINVAL;
+ }
+
+ if (!mode_pclk_khz) {
+ pr_err("invalid mode_pclk_khz\n");
+ return -EINVAL;
+ }
+
+ dp_display = container_of(dp, struct dp_display_private, dp_display);
+ link_info = &dp_display->panel->link_info;
+
+ if ((flags & SDE_DRM_MODE_FLAG_FMT_MASK) ==
+ DRM_MODE_FLAG_SUPPORTS_YUV420)
+ mode_bpp =
+ dp->connector->display_info.y420_bpc * num_components;
+ else
+ mode_bpp = dp->connector->display_info.bpc * num_components;
+
if (!mode_bpp)
mode_bpp = default_bpp;
@@ -1356,6 +1435,42 @@
return rc;
}
+static int dp_display_get_display_type(struct dp_display *dp_display,
+ const char **display_type)
+{
+ struct dp_display_private *dp;
+
+ if (!dp_display || !display_type) {
+ pr_err("invalid input\n");
+ return -EINVAL;
+ }
+
+ dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+ *display_type = dp->parser->display_type;
+
+ if (!strcmp(*display_type, "primary"))
+ dp_display->is_primary = true;
+ else
+ dp_display->is_primary = false;
+
+ return 0;
+}
+
+static bool dp_display_vsc_sdp_supported(struct dp_display *dp_display)
+{
+ struct dp_display_private *dp;
+
+ if (!dp_display) {
+ pr_err("invalid input\n");
+ return 0;
+ }
+
+ dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+ return dp->panel->vsc_sdp_supported(dp->panel);
+}
+
static int dp_display_create_workqueue(struct dp_display_private *dp)
{
dp->wq = create_singlethread_workqueue("drm_dp");
@@ -1412,6 +1527,7 @@
g_dp_display->set_mode = dp_display_set_mode;
g_dp_display->validate_mode = dp_display_validate_mode;
g_dp_display->get_modes = dp_display_get_modes;
+ g_dp_display->get_dc_support = dp_display_get_dc_support;
g_dp_display->prepare = dp_display_prepare;
g_dp_display->unprepare = dp_display_unprepare;
g_dp_display->request_irq = dp_request_irq;
@@ -1419,6 +1535,8 @@
g_dp_display->post_open = dp_display_post_open;
g_dp_display->post_init = dp_display_post_init;
g_dp_display->config_hdr = dp_display_config_hdr;
+ g_dp_display->get_display_type = dp_display_get_display_type;
+ g_dp_display->vsc_sdp_supported = dp_display_vsc_sdp_supported;
rc = component_add(&pdev->dev, &dp_display_comp_ops);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h
index 6b83368..3229987 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -25,7 +25,9 @@
struct dp_bridge *bridge;
struct drm_connector *connector;
bool is_connected;
+ bool is_primary;
u32 max_pclk_khz;
+ bool yuv_support;
int (*enable)(struct dp_display *dp_display);
int (*post_enable)(struct dp_display *dp_display);
@@ -35,9 +37,12 @@
int (*set_mode)(struct dp_display *dp_display,
struct dp_display_mode *mode);
- int (*validate_mode)(struct dp_display *dp_display, u32 mode_pclk_khz);
+ int (*validate_mode)(struct dp_display *dp_display,
+ u32 mode_pclk_khz, u32 flags);
int (*get_modes)(struct dp_display *dp_display,
struct dp_display_mode *dp_mode);
+ int (*get_dc_support)(struct dp_display *dp_display,
+ u32 mode_pclk_khz, u32 out_format, bool dc_enable);
int (*prepare)(struct dp_display *dp_display);
int (*unprepare)(struct dp_display *dp_display);
int (*request_irq)(struct dp_display *dp_display);
@@ -46,11 +51,15 @@
int (*config_hdr)(struct dp_display *dp_display,
struct drm_msm_ext_hdr_metadata *hdr_meta);
void (*post_init)(struct dp_display *dp_display);
+ int (*get_display_type)(struct dp_display *dp_display,
+ const char **display_type);
+ bool (*vsc_sdp_supported)(struct dp_display *dp_display);
};
int dp_display_get_num_of_displays(void);
int dp_display_get_displays(void **displays, int count);
bool dp_connector_mode_needs_full_range(void *display);
+bool dp_connector_mode_is_cea_mode(void *display);
enum sde_csc_type dp_connector_get_csc_type(struct drm_connector *conn,
void *data);
#endif /* _DP_DISPLAY_H_ */
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index fdd40a7..442179f 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -31,11 +31,82 @@
HDR_ENABLE
};
+static int get_sink_dc_support(struct dp_display *dp,
+ struct drm_display_mode *mode)
+{
+ int dc_format = 0;
+ struct drm_connector *connector = dp->connector;
+
+ if ((mode->flags & DRM_MODE_FLAG_SUPPORTS_YUV420) &&
+ (connector->display_info.edid_hdmi_dc_modes
+ & DRM_EDID_YCBCR420_DC_30))
+ if (dp->get_dc_support(dp, mode->clock,
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420, true))
+ dc_format |= MSM_MODE_FLAG_YUV420_DC_ENABLE;
+
+ if ((mode->flags & DRM_MODE_FLAG_SUPPORTS_RGB) &&
+ (connector->display_info.edid_hdmi_dc_modes
+ & DRM_EDID_HDMI_DC_30))
+ if (dp->get_dc_support(dp, mode->clock,
+ MSM_MODE_FLAG_COLOR_FORMAT_RGB444, true))
+ dc_format |= MSM_MODE_FLAG_RGB444_DC_ENABLE;
+
+ if ((mode->flags & DRM_MODE_FLAG_SUPPORTS_YUV422) &&
+ (connector->display_info.edid_hdmi_dc_modes
+ & DRM_EDID_HDMI_DC_30))
+ if (dp->get_dc_support(dp, mode->clock,
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422, false))
+ dc_format |= MSM_MODE_FLAG_YUV422_DC_ENABLE;
+
+ return dc_format;
+}
+
+static u32 choose_best_format(struct dp_display *dp,
+ struct drm_display_mode *mode)
+{
+ /*
+ * choose priority:
+ * 1. DC + RGB
+ * 2. DC + YUV422
+ * 3. DC + YUV420
+ * 4. RGB
+ * 5. YUV420
+ */
+ int dc_format;
+
+ dc_format = get_sink_dc_support(dp, mode);
+ if (dc_format & MSM_MODE_FLAG_RGB444_DC_ENABLE)
+ return (MSM_MODE_FLAG_COLOR_FORMAT_RGB444
+ | MSM_MODE_FLAG_RGB444_DC_ENABLE);
+ else if (dc_format & MSM_MODE_FLAG_YUV422_DC_ENABLE)
+ return (MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422
+ | MSM_MODE_FLAG_YUV422_DC_ENABLE);
+ else if (dc_format & MSM_MODE_FLAG_YUV420_DC_ENABLE)
+ return (MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420
+ | MSM_MODE_FLAG_YUV420_DC_ENABLE);
+ else if (mode->flags & DRM_MODE_FLAG_SUPPORTS_RGB)
+ return MSM_MODE_FLAG_COLOR_FORMAT_RGB444;
+ else if (mode->flags & DRM_MODE_FLAG_SUPPORTS_YUV420)
+ return MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420;
+
+ pr_err("Can't get available best display format\n");
+
+ return MSM_MODE_FLAG_COLOR_FORMAT_RGB444;
+}
+
static void convert_to_dp_mode(const struct drm_display_mode *drm_mode,
struct dp_display_mode *dp_mode, struct dp_display *dp)
{
memset(dp_mode, 0, sizeof(*dp_mode));
+ dp_mode->timing.out_format = MSM_MODE_FLAG_COLOR_FORMAT_RGB444;
+ if (drm_mode->private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422)
+ dp_mode->timing.out_format =
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422;
+ else if (drm_mode->private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ dp_mode->timing.out_format =
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420;
+
dp_mode->timing.h_active = drm_mode->hdisplay;
dp_mode->timing.h_back_porch = drm_mode->htotal - drm_mode->hsync_end;
dp_mode->timing.h_sync_width = drm_mode->htotal -
@@ -61,6 +132,10 @@
dp_mode->timing.h_active_low =
!!(drm_mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+ dp_mode->flags = drm_mode->flags;
+
+ dp_mode->timing.par = drm_mode->picture_aspect_ratio;
}
static void convert_to_drm_mode(const struct dp_display_mode *dp_mode,
@@ -99,6 +174,9 @@
flags |= DRM_MODE_FLAG_PVSYNC;
drm_mode->flags = flags;
+ drm_mode->flags |= (dp_mode->flags & SDE_DRM_MODE_FLAG_FMT_MASK);
+
+ drm_mode->picture_aspect_ratio = dp_mode->timing.par;
drm_mode->type = 0x48;
drm_mode_set_name(drm_mode);
@@ -153,6 +231,7 @@
bridge->id, rc);
dp->unprepare(dp);
}
+
}
static void dp_bridge_enable(struct drm_bridge *drm_bridge)
@@ -272,6 +351,15 @@
convert_to_dp_mode(mode, &dp_mode, dp);
convert_to_drm_mode(&dp_mode, adjusted_mode);
+
+ /* Clear the private flags before assigning new one */
+ adjusted_mode->private_flags = 0;
+
+ adjusted_mode->private_flags |=
+ choose_best_format(dp, adjusted_mode);
+ SDE_DEBUG("Adjusted mode private flags: 0x%x\n",
+ adjusted_mode->private_flags);
+
end:
return ret;
}
@@ -355,6 +443,7 @@
info->num_of_h_tiles = 1;
info->h_tile_instance[0] = 0;
info->is_connected = display->is_connected;
+ info->is_primary = display->is_primary;
info->capabilities = MSM_DISPLAY_CAP_VID_MODE | MSM_DISPLAY_CAP_EDID |
MSM_DISPLAY_CAP_HOT_PLUG;
@@ -389,6 +478,45 @@
return false;
}
+bool dp_connector_mode_is_cea_mode(void *data)
+{
+ struct dp_display *display = data;
+ struct dp_bridge *bridge;
+ struct dp_display_mode *mode;
+ struct drm_display_mode drm_mode;
+ struct dp_panel_info *timing;
+ bool is_ce_mode = false;
+
+ if (!display) {
+ pr_err("invalid input\n");
+ return false;
+ }
+
+ bridge = display->bridge;
+ if (!bridge) {
+ pr_err("invalid bridge data\n");
+ return false;
+ }
+
+ mode = &bridge->dp_mode;
+ timing = &mode->timing;
+
+ if (timing->h_active == 640 &&
+ timing->v_active == 480)
+ is_ce_mode = false;
+
+ convert_to_drm_mode(mode, &drm_mode);
+ drm_mode.flags &= ~SDE_DRM_MODE_FLAG_FMT_MASK;
+
+ if (drm_match_cea_mode(&drm_mode) || drm_match_hdmi_mode(&drm_mode))
+ is_ce_mode = true;
+
+ pr_debug("%s: %s : %s video format\n", __func__,
+ drm_mode.name, is_ce_mode ? "CE" : "IT");
+
+ return is_ce_mode;
+}
+
enum sde_csc_type dp_connector_get_csc_type(struct drm_connector *conn,
void *data)
{
@@ -415,10 +543,10 @@
return SDE_CSC_RGB2YUV_2020L;
else if (dp_connector_mode_needs_full_range(data)
|| conn->yuv_qs)
- return SDE_CSC_RGB2YUV_601FR;
+ return SDE_CSC_RGB2YUV_709FR;
error:
- return SDE_CSC_RGB2YUV_601L;
+ return SDE_CSC_RGB2YUV_709L;
}
enum drm_connector_status dp_connector_detect(struct drm_connector *conn,
@@ -513,6 +641,19 @@
return rc;
}
+int dp_connnector_set_info_blob(struct drm_connector *connector,
+ void *info, void *display, struct msm_mode_info *mode_info)
+{
+ struct dp_display *dp_display = display;
+ const char *display_type = NULL;
+
+ dp_display->get_display_type(dp_display, &display_type);
+ sde_kms_info_add_keystr(info,
+ "display type", display_type);
+
+ return 0;
+}
+
int dp_drm_bridge_init(void *data, struct drm_encoder *encoder)
{
int rc = 0;
@@ -574,6 +715,8 @@
{
struct dp_display *dp_disp;
struct dp_debug *debug;
+ u32 pclk = 0;
+ u32 rate_ratio = RGB_24BPP_TMDS_CHAR_RATE_RATIO;
if (!mode || !display) {
pr_err("invalid params\n");
@@ -585,7 +728,34 @@
mode->vrefresh = drm_mode_vrefresh(mode);
- if (mode->clock > dp_disp->max_pclk_khz)
+ if (!dp_disp->yuv_support) {
+ mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_YUV420;
+ mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_YUV422;
+ }
+
+ if (!dp_disp->vsc_sdp_supported(dp_disp))
+ mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_YUV420;
+
+ if (!(mode->flags & SDE_DRM_MODE_FLAG_FMT_MASK))
+ return MODE_BAD;
+
+ if ((mode->flags & SDE_DRM_MODE_FLAG_FMT_MASK) ==
+ DRM_MODE_FLAG_SUPPORTS_YUV420) {
+ rate_ratio = YUV420_24BPP_TMDS_CHAR_RATE_RATIO;
+ } else if ((mode->flags & DRM_MODE_FLAG_SUPPORTS_RGB) &&
+ (mode->flags & DRM_MODE_FLAG_SUPPORTS_YUV420)) {
+ if (mode->clock > dp_disp->max_pclk_khz) {
+ /* Clear RGB and YUV422 support flags */
+ mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_RGB;
+ mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_YUV422;
+ /* Only YUV420 format is now supported */
+ rate_ratio = YUV420_24BPP_TMDS_CHAR_RATE_RATIO;
+ }
+ }
+
+ pclk = mode->clock / rate_ratio;
+
+ if (pclk > dp_disp->max_pclk_khz)
return MODE_BAD;
if (debug->debug_en && (mode->hdisplay != debug->hdisplay ||
@@ -594,5 +764,5 @@
mode->picture_aspect_ratio != debug->aspect_ratio))
return MODE_BAD;
- return dp_disp->validate_mode(dp_disp, mode->clock);
+ return dp_disp->validate_mode(dp_disp, pclk, mode->flags);
}
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 3ca10c2..4181472 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -99,6 +99,17 @@
*/
void dp_connector_post_open(void *display);
+/**
+ * dp_conn_set_info_blob - callback to perform info blob initialization
+ * @connector: Pointer to drm connector structure
+ * @info: Pointer to sde connector info structure
+ * @display: Pointer to private display handle
+ * @mode_info: Pointer to mode info structure
+ * Returns: Zero on success
+ */
+int dp_connnector_set_info_blob(struct drm_connector *connector,
+ void *info, void *display, struct msm_mode_info *mode_info);
+
int dp_drm_bridge_init(void *display,
struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 7132699..5379823 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
+#include "msm_kms.h"
#include "dp_panel.h"
#define DP_PANEL_DEFAULT_BPP 24
@@ -43,6 +44,17 @@
ITU_R_BT_2020_RGB,
};
+enum dp_panel_hdr_yuv_colorimetry {
+ ITU_R_BT_601,
+ ITU_R_BT_709,
+ xvYCC_601,
+ xvYCC_709,
+ sYCC_601,
+ ADOBE_YCC_601,
+ ITU_R_BT_2020_YcCBcCRc,
+ ITU_R_BT_2020_YCBCR,
+};
+
enum dp_panel_hdr_dynamic_range {
VESA,
CEA,
@@ -537,6 +549,50 @@
panel->catalog->tpg_config(catalog, true);
}
+static int dp_panel_setup_vsc_sdp(struct dp_panel *dp_panel)
+{
+ struct dp_catalog_panel *catalog;
+ struct dp_panel_private *panel;
+ struct dp_panel_info *pinfo;
+ int rc = 0;
+
+ if (!dp_panel) {
+ pr_err("invalid input\n");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+ catalog = panel->catalog;
+ pinfo = &panel->dp_panel.pinfo;
+
+ memset(&catalog->vsc_sdp_data, 0, sizeof(catalog->vsc_sdp_data));
+
+ if (pinfo->out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) {
+ catalog->vsc_sdp_data.vsc_header_byte0 = 0x00;
+ catalog->vsc_sdp_data.vsc_header_byte1 = 0x07;
+ catalog->vsc_sdp_data.vsc_header_byte2 = 0x05;
+ catalog->vsc_sdp_data.vsc_header_byte3 = 0x13;
+
+ /* VSC SDP Payload for DB16 */
+ catalog->vsc_sdp_data.pixel_encoding = YCbCr420;
+ catalog->vsc_sdp_data.colorimetry = ITU_R_BT_709;
+
+ /* VSC SDP Payload for DB17 */
+ catalog->vsc_sdp_data.dynamic_range = CEA;
+
+ /* VSC SDP Payload for DB18 */
+ catalog->vsc_sdp_data.content_type = GRAPHICS;
+
+ catalog->vsc_sdp_data.bpc = pinfo->bpp / 3;
+
+ if (panel->catalog->config_vsc_sdp)
+ panel->catalog->config_vsc_sdp(catalog, true);
+ }
+end:
+ return rc;
+}
+
static int dp_panel_timing_cfg(struct dp_panel *dp_panel)
{
int rc = 0;
@@ -596,11 +652,37 @@
catalog->dp_active = data;
panel->catalog->timing_cfg(catalog);
+ dp_panel_setup_vsc_sdp(dp_panel);
panel->panel_on = true;
end:
return rc;
}
+static u32 dp_panel_get_pixel_clk(struct dp_panel *dp_panel)
+{
+ struct dp_panel_private *panel;
+ struct dp_panel_info *pinfo;
+ u32 pixel_clk_khz = 0;
+ u32 rate_ratio = RGB_24BPP_TMDS_CHAR_RATE_RATIO;
+
+ if (!dp_panel) {
+ pr_err("invalid input\n");
+ return 0;
+ }
+
+ panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+ pinfo = &panel->dp_panel.pinfo;
+
+ pixel_clk_khz = pinfo->pixel_clk_khz;
+
+ if (pinfo->out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ rate_ratio = YUV420_24BPP_TMDS_CHAR_RATE_RATIO;
+
+ pixel_clk_khz /= rate_ratio;
+
+ return pixel_clk_khz;
+}
+
static int dp_panel_edid_register(struct dp_panel_private *panel)
{
int rc = 0;
@@ -619,6 +701,16 @@
sde_edid_deinit((void **)&panel->dp_panel.edid_ctrl);
}
+static inline char *get_out_format(u32 out_format)
+{
+ if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420)
+ return "Y420";
+ else if (out_format == MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422)
+ return "Y422";
+ else
+ return "RGB";
+}
+
static int dp_panel_init_panel_info(struct dp_panel *dp_panel)
{
int rc = 0;
@@ -648,6 +740,7 @@
pinfo->v_front_porch,
pinfo->v_sync_width);
pr_info("pixel clock (KHz)=(%d)\n", pinfo->pixel_clk_khz);
+ pr_info("%s\n", get_out_format(pinfo->out_format));
pr_info("bpp = %d\n", pinfo->bpp);
pr_info("active low (h|v)=(%d|%d)\n", pinfo->h_active_low,
pinfo->v_active_low);
@@ -705,6 +798,20 @@
return min_link_rate_khz;
}
+static bool dp_panel_vsc_sdp_supported(struct dp_panel *dp_panel)
+{
+ struct dp_panel_private *panel;
+
+ if (!dp_panel) {
+ pr_err("invalid input\n");
+ return false;
+ }
+
+ panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+ return panel->major >= 1 && panel->minor >= 3 && panel->vsc_supported;
+}
+
static bool dp_panel_hdr_supported(struct dp_panel *dp_panel)
{
struct dp_panel_private *panel;
@@ -726,6 +833,7 @@
int rc = 0;
struct dp_panel_private *panel;
struct dp_catalog_hdr_data *hdr;
+ struct dp_panel_info *pinfo;
if (!dp_panel) {
pr_err("invalid input\n");
@@ -735,6 +843,7 @@
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
hdr = &panel->catalog->hdr_data;
+ pinfo = &panel->dp_panel.pinfo;
/* use cached meta data in case meta data not provided */
if (!hdr_meta) {
@@ -762,8 +871,16 @@
hdr->vscext_header_byte3 = 0x13 << 2;
/* VSC SDP Payload for DB16 */
- hdr->pixel_encoding = RGB;
- hdr->colorimetry = ITU_R_BT_2020_RGB;
+ if (pinfo->out_format & MSM_MODE_FLAG_COLOR_FORMAT_RGB444) {
+ hdr->pixel_encoding = RGB;
+ hdr->colorimetry = ITU_R_BT_2020_RGB;
+ } else if (pinfo->out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422) {
+ hdr->pixel_encoding = YCbCr422;
+ hdr->colorimetry = ITU_R_BT_2020_YCBCR;
+ } else if (pinfo->out_format & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) {
+ hdr->pixel_encoding = YCbCr420;
+ hdr->colorimetry = ITU_R_BT_2020_YCBCR;
+ }
/* VSC SDP Payload for DB17 */
hdr->dynamic_range = CEA;
@@ -781,8 +898,11 @@
else
memset(&hdr->hdr_meta, 0, sizeof(hdr->hdr_meta));
cached:
- if (panel->panel_on)
+ if (panel->panel_on) {
panel->catalog->config_hdr(panel->catalog, panel->hdr_state);
+ if (panel->hdr_state == HDR_DISABLED)
+ dp_panel_setup_vsc_sdp(dp_panel);
+ }
end:
return rc;
}
@@ -856,6 +976,8 @@
dp_panel->spd_config = dp_panel_spd_config;
dp_panel->setup_hdr = dp_panel_setup_hdr;
dp_panel->hdr_supported = dp_panel_hdr_supported;
+ dp_panel->vsc_sdp_supported = dp_panel_vsc_sdp_supported;
+ dp_panel->get_pixel_clk = dp_panel_get_pixel_clk;
dp_panel_edid_register(panel);
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h b/drivers/gpu/drm/msm/dp/dp_panel.h
index 6c2e186..1a87a96 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -28,6 +28,7 @@
DP_LANE_COUNT_4 = 4,
};
+
#define DP_MAX_DOWNSTREAM_PORTS 0x10
struct dp_panel_info {
@@ -45,11 +46,14 @@
u32 refresh_rate;
u32 pixel_clk_khz;
u32 bpp;
+ u32 out_format;
+ enum hdmi_picture_aspect par;
};
struct dp_display_mode {
struct dp_panel_info timing;
u32 capabilities;
+ u32 flags;
};
struct dp_panel_in {
@@ -94,6 +98,8 @@
void (*tpg_config)(struct dp_panel *dp_panel, bool enable);
int (*spd_config)(struct dp_panel *dp_panel);
bool (*hdr_supported)(struct dp_panel *dp_panel);
+ bool (*vsc_sdp_supported)(struct dp_panel *dp_panel);
+ u32 (*get_pixel_clk)(struct dp_panel *dp_panel);
};
/**
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index 0174ea10..09fa4fd 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -157,6 +157,14 @@
if (rc)
parser->max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ;
+ parser->yuv_support = of_property_read_bool(of_node,
+ "qcom,yuv-support");
+
+ parser->display_type = of_get_property(of_node,
+ "qcom,display-type", NULL);
+ if (!parser->display_type)
+ parser->display_type = "unknown";
+
return 0;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index a768ca3..a32a8ec 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -161,6 +161,7 @@
* @pinctrl: pin-control related data
* @ctrl_resouce: controller's register address realated data
* @disp_data: controller's display related data
+ * @display_type: display type as defined in device tree.
* @parse: function to be called by client to parse device tree.
* @get_io: function to be called by client to get io data.
* @get_io_buf: function to be called by client to get io buffers.
@@ -177,6 +178,9 @@
u8 l_map[4];
struct dp_aux_cfg aux_cfg[AUX_CFG_LEN];
u32 max_pclk_khz;
+ bool yuv_support;
+
+ const char *display_type;
int (*parse)(struct dp_parser *parser);
struct dp_io_data *(*get_io)(struct dp_parser *parser, char *name);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 1a29b0e..e2584cd 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -252,6 +252,103 @@
return rc;
}
+static int dsi_panel_exd_gpio_request(struct dsi_panel *panel)
+{
+ int rc = 0;
+ struct dsi_panel_exd_config *e_config = &panel->exd_config;
+
+ if (!e_config->display_1p8_en && !e_config->led_5v_en &&
+ !e_config->led_en1 && !e_config->led_en2 &&
+ !e_config->oenab && !e_config->selab &&
+ !e_config->switch_power)
+ return 0;
+
+ if (gpio_is_valid(e_config->display_1p8_en)) {
+ rc = gpio_request(e_config->display_1p8_en, "display_1p8_en");
+ if (rc) {
+ pr_err("request for display_1p8_en failed, rc=%d\n",
+ rc);
+ goto error;
+ }
+ }
+
+ if (gpio_is_valid(e_config->led_5v_en)) {
+ rc = gpio_request(e_config->led_5v_en, "led_5v_en");
+ if (rc) {
+ pr_err("request for led_5v_en failed, rc=%d\n",
+ rc);
+ goto error_release_1p8;
+ }
+ }
+
+ if (gpio_is_valid(e_config->led_en1)) {
+ rc = gpio_request(e_config->led_en1, "led_en1");
+ if (rc) {
+ pr_err("request for led_en1 failed, rc=%d\n",
+ rc);
+ goto error_release_5v;
+ }
+ }
+
+ if (gpio_is_valid(e_config->led_en2)) {
+ rc = gpio_request(e_config->led_en2, "led_en2");
+ if (rc) {
+ pr_err("request for led_en2 failed, rc=%d\n",
+ rc);
+ goto error_release_led;
+ }
+ }
+
+ if (gpio_is_valid(e_config->oenab)) {
+ rc = gpio_request(e_config->oenab, "oenab");
+ if (rc) {
+ pr_err("request for oenab failed, rc=%d\n",
+ rc);
+ goto error_release_led2;
+ }
+ }
+
+ if (gpio_is_valid(e_config->selab)) {
+ rc = gpio_request(e_config->selab, "selab");
+ if (rc) {
+ pr_err("request for selab failed, rc=%d\n",
+ rc);
+ goto error_release_oenab;
+ }
+ }
+
+ if (gpio_is_valid(e_config->switch_power)) {
+ rc = gpio_request(e_config->switch_power, "switch_power");
+ if (rc) {
+ pr_err("request for switch_power failed, rc=%d\n",
+ rc);
+ goto error_release_selab;
+ }
+ }
+ return rc;
+
+error_release_selab:
+ if (gpio_is_valid(e_config->selab))
+ gpio_free(e_config->selab);
+error_release_oenab:
+ if (gpio_is_valid(e_config->oenab))
+ gpio_free(e_config->oenab);
+error_release_led2:
+ if (gpio_is_valid(e_config->led_en2))
+ gpio_free(e_config->led_en2);
+error_release_led:
+ if (gpio_is_valid(e_config->led_en1))
+ gpio_free(e_config->led_en1);
+error_release_5v:
+ if (gpio_is_valid(e_config->led_5v_en))
+ gpio_free(e_config->led_5v_en);
+error_release_1p8:
+ if (gpio_is_valid(e_config->display_1p8_en))
+ gpio_free(e_config->display_1p8_en);
+error:
+ return rc;
+}
+
static int dsi_panel_gpio_request(struct dsi_panel *panel)
{
int rc = 0;
@@ -303,6 +400,34 @@
return rc;
}
+static int dsi_panel_exd_gpio_release(struct dsi_panel *panel)
+{
+ struct dsi_panel_exd_config *e_config = &panel->exd_config;
+
+ if (!e_config->display_1p8_en && !e_config->led_5v_en &&
+ !e_config->led_en1 && !e_config->led_en2 &&
+ !e_config->oenab && !e_config->selab &&
+ !e_config->switch_power)
+ return 0;
+
+ if (gpio_is_valid(e_config->display_1p8_en))
+ gpio_free(e_config->display_1p8_en);
+ if (gpio_is_valid(e_config->led_5v_en))
+ gpio_free(e_config->led_5v_en);
+ if (gpio_is_valid(e_config->led_en1))
+ gpio_free(e_config->led_en1);
+ if (gpio_is_valid(e_config->led_en2))
+ gpio_free(e_config->led_en2);
+ if (gpio_is_valid(e_config->oenab))
+ gpio_free(e_config->oenab);
+ if (gpio_is_valid(e_config->selab))
+ gpio_free(e_config->selab);
+ if (gpio_is_valid(e_config->switch_power))
+ gpio_free(e_config->switch_power);
+
+ return 0;
+}
+
static int dsi_panel_gpio_release(struct dsi_panel *panel)
{
int rc = 0;
@@ -426,6 +551,110 @@
return rc;
}
+static int dsi_panel_exd_enable(struct dsi_panel *panel)
+{
+ int rc = 0;
+ struct dsi_panel_exd_config *e_config = &panel->exd_config;
+
+ if (!e_config->display_1p8_en && !e_config->led_5v_en &&
+ !e_config->led_en1 && !e_config->led_en2 &&
+ !e_config->oenab && !e_config->selab &&
+ !e_config->switch_power)
+ return 0;
+
+ if (gpio_is_valid(e_config->display_1p8_en)) {
+ rc = gpio_direction_output(e_config->display_1p8_en, 0);
+ if (rc) {
+ pr_err("unable to set dir for disp_1p8_en rc:%d\n",
+ rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->display_1p8_en, 1);
+ }
+
+ if (gpio_is_valid(e_config->switch_power)) {
+ rc = gpio_direction_output(e_config->switch_power, 0);
+ if (rc) {
+ pr_err("unable to set dir for switch_power rc:%d\n",
+ rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->switch_power, 1);
+ }
+
+ if (gpio_is_valid(e_config->led_5v_en)) {
+ rc = gpio_direction_output(e_config->led_5v_en, 0);
+ if (rc) {
+ pr_err("unable to set dir for led_5v_en rc:%d\n", rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->led_5v_en, 1);
+ }
+
+ if (gpio_is_valid(e_config->led_en1)) {
+ rc = gpio_direction_output(e_config->led_en1, 0);
+ if (rc) {
+ pr_err("unable to set dir for led_en1 rc:%d\n", rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->led_en1, 1);
+ }
+
+ if (gpio_is_valid(e_config->led_en2)) {
+ rc = gpio_direction_output(e_config->led_en2, 0);
+ if (rc) {
+ pr_err("unable to set dir for led_en2 rc:%d\n", rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->led_en2, 1);
+ }
+
+ if (gpio_is_valid(e_config->oenab)) {
+ rc = gpio_direction_output(e_config->oenab, 0);
+ if (rc) {
+ pr_err("unable to set dir for oenab rc:%d\n", rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->oenab, 0);
+ }
+
+ if (gpio_is_valid(e_config->selab)) {
+ rc = gpio_direction_output(e_config->selab, 0);
+ if (rc) {
+ pr_err("unable to set dir for selab rc:%d\n", rc);
+ goto exit;
+ }
+ gpio_set_value(e_config->selab, 1);
+ }
+exit:
+ return rc;
+}
+
+static void dsi_panel_exd_disable(struct dsi_panel *panel)
+{
+ struct dsi_panel_exd_config *e_config = &panel->exd_config;
+
+ if (!e_config->display_1p8_en && !e_config->led_5v_en &&
+ !e_config->led_en1 && !e_config->led_en2 &&
+ !e_config->oenab && !e_config->selab &&
+ !e_config->switch_power)
+ return;
+
+ if (gpio_is_valid(e_config->display_1p8_en))
+ gpio_set_value(e_config->display_1p8_en, 0);
+ if (gpio_is_valid(e_config->led_5v_en))
+ gpio_set_value(e_config->led_5v_en, 0);
+ if (gpio_is_valid(e_config->led_en1))
+ gpio_set_value(e_config->led_en1, 0);
+ if (gpio_is_valid(e_config->led_en2))
+ gpio_set_value(e_config->led_en2, 0);
+ if (gpio_is_valid(e_config->oenab))
+ gpio_set_value(e_config->oenab, 1);
+ if (gpio_is_valid(e_config->selab))
+ gpio_set_value(e_config->selab, 0);
+ if (gpio_is_valid(e_config->switch_power))
+ gpio_set_value(e_config->switch_power, 0);
+}
static int dsi_panel_power_on(struct dsi_panel *panel)
{
@@ -449,6 +678,13 @@
goto error_disable_gpio;
}
+ rc = dsi_panel_exd_enable(panel);
+ if (rc) {
+ pr_err("[%s] failed to reset panel, rc=%d\n", panel->name, rc);
+ dsi_panel_exd_disable(panel);
+ goto error_disable_gpio;
+ }
+
goto exit;
error_disable_gpio:
@@ -471,6 +707,8 @@
{
int rc = 0;
+ dsi_panel_exd_disable(panel);
+
if (gpio_is_valid(panel->reset_config.disp_en_gpio))
gpio_set_value(panel->reset_config.disp_en_gpio, 0);
@@ -1887,6 +2125,63 @@
return rc;
}
+static int dsi_panel_exd_parse_gpios(struct dsi_panel *panel,
+ struct device_node *of_node)
+{
+ int rc = 0;
+ struct dsi_panel_exd_config *e_config = &panel->exd_config;
+
+ e_config->display_1p8_en = of_get_named_gpio(of_node,
+ "qcom,1p8-en-gpio", 0);
+ if (!e_config->display_1p8_en) {
+ pr_debug("%s qcom,display-1p8-en-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->led_5v_en = of_get_named_gpio(of_node,
+ "qcom,led-5v-en-gpio", 0);
+ if (!e_config->led_5v_en) {
+ pr_debug("%s qcom,led-5v-en-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->led_en1 = of_get_named_gpio(of_node,
+ "qcom,led-driver-en1-gpio", 0);
+ if (!e_config->led_en1) {
+ pr_debug("%s qcom,led-driver-en1-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->led_en2 = of_get_named_gpio(of_node,
+ "qcom,led-driver-en2-gpio", 0);
+ if (!e_config->led_en2) {
+ pr_debug("%s qcom,led-driver-en2-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->oenab = of_get_named_gpio(of_node,
+ "qcom,oenab-gpio", 0);
+ if (!e_config->oenab) {
+ pr_debug("%s qcom,oenab-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->selab = of_get_named_gpio(of_node,
+ "qcom,selab-gpio", 0);
+ if (!e_config->selab) {
+ pr_debug("%s qcom,selab-gpio not found\n", __func__);
+ return -EINVAL;
+ }
+
+ e_config->switch_power = of_get_named_gpio(of_node,
+ "qcom,switch-power-gpio", 0);
+ if (!e_config->switch_power) {
+ pr_debug("%s qcom,switch_power not found\n", __func__);
+ return -EINVAL;
+ }
+ return rc;
+}
+
static int dsi_panel_parse_gpios(struct dsi_panel *panel,
struct device_node *of_node)
{
@@ -1942,6 +2237,12 @@
panel->reset_config.mode_sel_state = MODE_SEL_DUAL_PORT;
}
+ /* Extended display panel gpios parsed */
+ rc = dsi_panel_exd_parse_gpios(panel, of_node);
+ if (rc && rc != -EINVAL)
+ pr_err("[%s] failed to parse gpios, rc=%d\n",
+ panel->name, rc);
+
/* TODO: release memory */
rc = dsi_panel_parse_reset_sequence(panel, of_node);
if (rc) {
@@ -3105,8 +3406,17 @@
goto error_gpio_release;
}
+ rc = dsi_panel_exd_gpio_request(panel);
+ if (rc) {
+ pr_err("[%s] failed to request gpios, rc=%d\n", panel->name,
+ rc);
+ goto error_exd_gpio_release;
+ }
+
goto exit;
+error_exd_gpio_release:
+ (void)dsi_panel_exd_gpio_release(panel);
error_gpio_release:
(void)dsi_panel_gpio_release(panel);
error_pinctrl_deinit:
@@ -3142,6 +3452,11 @@
pr_err("[%s] failed to release gpios, rc=%d\n", panel->name,
rc);
+ rc = dsi_panel_exd_gpio_release(panel);
+ if (rc)
+ pr_err("[%s] failed to release gpios, rc=%d\n", panel->name,
+ rc);
+
rc = dsi_panel_pinctrl_deinit(panel);
if (rc)
pr_err("[%s] failed to deinit gpios, rc=%d\n", panel->name,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
index ab8ccee..8702375 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -161,6 +161,17 @@
DSI_PANEL_TYPE_MAX,
};
+/* Extended Panel config for panels with additional gpios */
+struct dsi_panel_exd_config {
+ int display_1p8_en;
+ int led_5v_en;
+ int switch_power;
+ int led_en1;
+ int led_en2;
+ int oenab;
+ int selab;
+};
+
struct dsi_panel {
const char *name;
enum dsi_panel_type type;
@@ -204,6 +215,8 @@
enum dsi_dms_mode dms_mode;
bool sync_broadcast_en;
+
+ struct dsi_panel_exd_config exd_config;
};
static inline bool dsi_panel_ulps_feature_enabled(struct dsi_panel *panel)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c8d1f19..d46b9e7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -306,7 +306,7 @@
return num;
}
-static int dsi_mgr_connector_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
int id = dsi_mgr_connector_get_id(connector);
@@ -438,6 +438,7 @@
struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
struct mipi_dsi_host *host = msm_dsi->host;
struct drm_panel *panel = msm_dsi->panel;
+ struct msm_dsi_pll *src_pll;
bool is_dual_dsi = IS_DUAL_DSI();
int ret;
@@ -471,6 +472,10 @@
id, ret);
}
+ /* Save PLL status if it is a clock source */
+ src_pll = msm_dsi_phy_get_pll(msm_dsi->phy);
+ msm_dsi_pll_save_state(src_pll);
+
ret = msm_dsi_host_power_off(host);
if (ret)
pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
old mode 100644
new mode 100755
index c564a09..1c058db
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -526,6 +526,14 @@
if (ret)
goto fail;
+ if (!dev->dma_parms) {
+ dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms),
+ GFP_KERNEL);
+ if (!dev->dma_parms)
+ return -ENOMEM;
+ }
+ dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
switch (get_mdp_ver(pdev)) {
case KMS_MDP4:
kms = mdp4_kms_init(ddev);
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 25523b0..828e0f6 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -26,6 +26,9 @@
#define MAX_PLANE 4
+#define RGB_24BPP_TMDS_CHAR_RATE_RATIO 1
+#define YUV420_24BPP_TMDS_CHAR_RATE_RATIO 2
+
/**
* Device Private DRM Mode Flags
* drm_mode->private_flags
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 2d2f352..9ef04a8 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -768,6 +768,28 @@
return c_conn->ops.mode_needs_full_range(c_conn->display);
}
+bool sde_connector_mode_is_cea_mode(struct drm_connector *connector)
+{
+ struct sde_connector *c_conn;
+
+ if (!connector) {
+ SDE_ERROR("invalid argument\n");
+ return false;
+ }
+
+ c_conn = to_sde_connector(connector);
+
+ if (!c_conn->display) {
+ SDE_ERROR("invalid argument\n");
+ return false;
+ }
+
+ if (!c_conn->ops.mode_is_cea_mode)
+ return false;
+
+ return c_conn->ops.mode_is_cea_mode(c_conn->display);
+}
+
static void sde_connector_destroy(struct drm_connector *connector)
{
struct sde_connector *c_conn;
@@ -1999,6 +2021,9 @@
sde_kms_info_add_keystr(info, "mode_name", mode->name);
+ sde_kms_info_add_keyint(info, "VIC",
+ mode->vic_id);
+
sde_kms_info_add_keyint(info, "bit_clk_rate",
mode_info.clk_rate);
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 2543822..3fb4531 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -192,6 +192,14 @@
bool (*mode_needs_full_range)(void *display);
/**
+ * mode_is_cea_mode - is this mode a CE video format
+ * or IT video format.
+ * @display: Pointer to private display structure
+ * Returns: true or false based on CE or IT video format
+ */
+ bool (*mode_is_cea_mode)(void *display);
+
+ /**
* clk_ctrl - perform clk enable/disable on the connector
* @handle: Pointer to clk handle
* @type: Type of clks
@@ -728,6 +736,14 @@
bool sde_connector_mode_needs_full_range(struct drm_connector *connector);
/**
+ * sde_connector_mode_is_cea_mode - query if this mode is
+ * CE or IT video format
+ * @connector: Pointer to drm connector object
+ * Returns: true OR false based on CE or IT video format mode
+ */
+bool sde_connector_mode_is_cea_mode(struct drm_connector *connector);
+
+/**
* sde_connector_get_csc_type - query csc type
* to be used for the connector
* @connector: Pointer to drm connector object
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 0956c01..3e625fe 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -234,6 +234,30 @@
{ 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
{ 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
},
+
+ [SDE_CSC_RGB2RGB_L] = {
+ {
+ TO_S15D16(0x01b7), TO_S15D16(0x0000), TO_S15D16(0x0000),
+ TO_S15D16(0x0000), TO_S15D16(0x01b7), TO_S15D16(0x0000),
+ TO_S15D16(0x0000), TO_S15D16(0x0000), TO_S15D16(0x01b7),
+ },
+ { 0x0, 0x0, 0x0,},
+ { 0x0040, 0x0040, 0x0040,},
+ { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
+ { 0x40, 0x3ac, 0x40, 0x3ac, 0x40, 0x3ac,},
+ },
+
+ [SDE_CSC_RGB2RGB_FR] = {
+ {
+ TO_S15D16(0x0200), TO_S15D16(0x0000), TO_S15D16(0x0000),
+ TO_S15D16(0x0000), TO_S15D16(0x0200), TO_S15D16(0x0000),
+ TO_S15D16(0x0000), TO_S15D16(0x0000), TO_S15D16(0x0200),
+ },
+ { 0x0, 0x0, 0x0,},
+ { 0x0, 0x0, 0x0,},
+ { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
+ { 0x0, 0x3ff, 0x0, 0x3ff, 0x0, 0x3ff,},
+ }
};
/**
@@ -4198,8 +4222,10 @@
phys = sde_enc->phys_encs[i];
if (phys) {
mode = &phys->cached_mode;
- mode_is_yuv = (mode->private_flags &
- MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420);
+ mode_is_yuv = ((mode->private_flags &
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR420) ||
+ (mode->private_flags &
+ MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422));
}
/**
* Check the CSC matrix type to which the
@@ -5269,7 +5295,8 @@
}
sde_enc = to_sde_encoder_virt(encoder);
- if (!SDE_FORMAT_IS_YUV(format)) {
+ if ((output_type == CDM_CDWN_OUTPUT_WB) &&
+ !SDE_FORMAT_IS_YUV(format)) {
SDE_DEBUG_ENC(sde_enc, "[cdm_disable fmt:%x]\n",
format->base.pixel_format);
@@ -5329,13 +5356,21 @@
*/
if (output_type == CDM_CDWN_OUTPUT_HDMI) {
- if (connector && connector->yuv_qs)
- csc_type = SDE_CSC_RGB2YUV_709FR;
- else if (connector &&
- sde_connector_mode_needs_full_range(connector))
- csc_type = SDE_CSC_RGB2YUV_709FR;
- else
- csc_type = SDE_CSC_RGB2YUV_709L;
+ if (SDE_FORMAT_IS_YUV(format)) {
+ if (connector && connector->yuv_qs)
+ csc_type = SDE_CSC_RGB2YUV_709FR;
+ else if (connector &&
+ sde_connector_mode_needs_full_range(connector))
+ csc_type = SDE_CSC_RGB2YUV_709FR;
+ else
+ csc_type = SDE_CSC_RGB2YUV_709L;
+ } else if (connector &&
+ sde_connector_mode_is_cea_mode(connector)) {
+ csc_type = SDE_CSC_RGB2RGB_L;
+ } else {
+ csc_type = SDE_CSC_RGB2RGB_FR;
+ }
+
} else if (output_type == CDM_CDWN_OUTPUT_WB) {
csc_type = SDE_CSC_RGB2YUV_601L;
}
@@ -5368,3 +5403,21 @@
}
}
}
+
+void sde_encoder_phys_destroy_cdm(struct sde_encoder_phys *phys_enc)
+{
+ struct drm_encoder *encoder = phys_enc->parent;
+ struct sde_encoder_virt *sde_enc = NULL;
+ struct sde_hw_cdm *hw_cdm = phys_enc->hw_cdm;
+
+ if (!encoder) {
+ SDE_ERROR("invalid encoder\n");
+ return;
+ }
+ sde_enc = to_sde_encoder_virt(encoder);
+
+ SDE_DEBUG_ENC(sde_enc, "[cdm_disable]\n");
+
+ if (hw_cdm && hw_cdm->ops.disable)
+ hw_cdm->ops.disable(hw_cdm);
+}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index b1547ab..d5e9f4a 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -498,6 +498,8 @@
const struct sde_format *format, u32 output_type,
struct sde_rect *roi);
+void sde_encoder_phys_destroy_cdm(struct sde_encoder_phys *phys_enc);
+
/**
* sde_encoder_helper_trigger_flush - control flush helper function
* This helper function may be optionally specified by physical
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index a1c3bfa..bd0868b 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -794,6 +794,8 @@
fmt = sde_get_sde_format(DRM_FORMAT_YUV420);
else if (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_YCBCR422)
fmt = sde_get_sde_format(DRM_FORMAT_NV61);
+ else if (mode.private_flags & MSM_MODE_FLAG_COLOR_FORMAT_RGB444)
+ fmt = sde_get_sde_format(DRM_FORMAT_RGB888);
if (fmt) {
struct sde_rect hdmi_roi;
@@ -830,6 +832,7 @@
}
vid_enc = to_sde_encoder_phys_vid(phys_enc);
+ sde_encoder_phys_destroy_cdm(phys_enc);
SDE_DEBUG_VIDENC(vid_enc, "\n");
kfree(vid_enc);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_cdm.c b/drivers/gpu/drm/msm/sde/sde_hw_cdm.c
index a223e77..86661983 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_cdm.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_cdm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -226,21 +226,29 @@
u32 opmode = 0;
u32 csc = 0;
- if (!SDE_FORMAT_IS_YUV(fmt))
+ if ((cdm->output_type == CDM_CDWN_OUTPUT_WB) &&
+ !SDE_FORMAT_IS_YUV(fmt))
return -EINVAL;
if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) {
if (fmt->chroma_sample == SDE_CHROMA_H1V2)
return -EINVAL; /*unsupported format */
- opmode = BIT(0);
- opmode |= (fmt->chroma_sample << 1);
+ if (fmt->chroma_sample == SDE_CHROMA_RGB) {
+ opmode = 0;
+ } else {
+ opmode = BIT(0);
+ opmode |= (fmt->chroma_sample << 1);
+ }
cdm_cfg.intf_en = true;
} else {
opmode = 0;
cdm_cfg.wb_en = true;
}
- csc |= BIT(2);
+ if (fmt->chroma_sample == SDE_CHROMA_RGB)
+ csc &= ~BIT(2);
+ else
+ csc |= BIT(2);
csc &= ~BIT(1);
csc |= BIT(0);
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
index 322613d..db84ba4 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_mdss.h
@@ -400,6 +400,8 @@
SDE_CSC_RGB2YUV_709FR,
SDE_CSC_RGB2YUV_2020L,
SDE_CSC_RGB2YUV_2020FR,
+ SDE_CSC_RGB2RGB_L,
+ SDE_CSC_RGB2RGB_FR,
SDE_MAX_CSC
};
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 1b59ac7..df4eaec 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1306,6 +1306,7 @@
.get_panel_vfp = NULL,
};
static const struct sde_connector_ops dp_ops = {
+ .set_info_blob = dp_connnector_set_info_blob,
.post_init = dp_connector_post_init,
.detect = dp_connector_detect,
.get_modes = dp_connector_get_modes,
@@ -1319,6 +1320,7 @@
.cont_splash_config = NULL,
.get_panel_vfp = NULL,
.mode_needs_full_range = dp_connector_mode_needs_full_range,
+ .mode_is_cea_mode = dp_connector_mode_is_cea_mode,
.get_csc_type = dp_connector_get_csc_type,
};
static const struct sde_connector_ops ext_bridge_ops = {
diff --git a/drivers/gpu/drm/msm/sde_edid_parser.c b/drivers/gpu/drm/msm/sde_edid_parser.c
index 89b5e3e..11051b5 100644
--- a/drivers/gpu/drm/msm/sde_edid_parser.c
+++ b/drivers/gpu/drm/msm/sde_edid_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -369,34 +369,6 @@
else
SDE_EDID_DEBUG("YCbCr420 CMDB is not present\n");
- /*
- * As per HDMI 2.0 spec, a sink supporting any modes
- * requiring more than 340Mhz clock rate should support
- * SCDC as well. This is required because we need the SCDC
- * channel to set the TMDS clock ratio. However in cases
- * where the TV publishes such a mode in its list of modes
- * but does not have SCDC support as per HDMI HFVSDB block
- * remove RGB mode support from the flags. Currently, in
- * the list of modes not having deep color support only RGB
- * modes shall requre a clock of 340Mhz and above such as the
- * 4K@60fps case. All other modes shall be YUV.
- * Deep color case is handled separately while choosing the
- * best mode in the _sde_hdmi_choose_best_format API where
- * we enable deep color only if it satisfies both source and
- * sink requirements. However, that API assumes that at least
- * RGB mode is supported on the mode. Hence, it would be better
- * to remove the format support flags while parsing the EDID
- * itself if it doesn't satisfy the HDMI spec requirement.
- */
-
- list_for_each_entry(mode, &connector->probed_modes, head) {
- if ((mode->clock > MIN_SCRAMBLER_REQ_RATE) &&
- !connector->scdc_present) {
- mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_RGB;
- mode->flags &= ~DRM_MODE_FLAG_SUPPORTS_YUV422;
- }
- }
-
SDE_EDID_DEBUG("%s -\n", __func__);
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 4bb9ab8..78e521d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -158,7 +158,7 @@
fence = list_entry(fctx->pending.next, typeof(*fence), head);
chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
- if (nouveau_fence_update(fence->channel, fctx))
+ if (nouveau_fence_update(chan, fctx))
ret = NVIF_NOTIFY_DROP;
}
spin_unlock_irqrestore(&fctx->lock, flags);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
index 9d90d8b..f5a8db1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
@@ -72,6 +72,8 @@
if (debug > subdev->debug)
return;
+ if (!mthd)
+ return;
for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) {
u32 base = chan->head * mthd->addr;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
index de8b806..7618b2e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
@@ -143,23 +143,24 @@
nent = (fuc.size / sizeof(struct gk20a_fw_av));
- pack = vzalloc((sizeof(*pack) * max_classes) +
- (sizeof(*init) * (nent + 1)));
+ pack = vzalloc((sizeof(*pack) * (max_classes + 1)) +
+ (sizeof(*init) * (nent + max_classes + 1)));
if (!pack) {
ret = -ENOMEM;
goto end;
}
- init = (void *)(pack + max_classes);
+ init = (void *)(pack + max_classes + 1);
- for (i = 0; i < nent; i++) {
- struct gf100_gr_init *ent = &init[i];
+ for (i = 0; i < nent; i++, init++) {
struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i];
u32 class = av->addr & 0xffff;
u32 addr = (av->addr & 0xffff0000) >> 14;
if (prevclass != class) {
- pack[classidx].init = ent;
+ if (prevclass) /* Add terminator to the method list. */
+ init++;
+ pack[classidx].init = init;
pack[classidx].type = class;
prevclass = class;
if (++classidx >= max_classes) {
@@ -169,10 +170,10 @@
}
}
- ent->addr = addr;
- ent->data = av->data;
- ent->count = 1;
- ent->pitch = 1;
+ init->addr = addr;
+ init->data = av->data;
+ init->count = 1;
+ init->pitch = 1;
}
*ppack = pack;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 8b6f8aa..432ad7d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -110,6 +110,8 @@
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
+ msleep(10);
+
WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
(NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
index 1f013d4..0c7c300 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
@@ -210,8 +210,10 @@
cres->hash.key = user_key | (res_type << 24);
ret = drm_ht_insert_item(&man->resources, &cres->hash);
- if (unlikely(ret != 0))
+ if (unlikely(ret != 0)) {
+ kfree(cres);
goto out_invalid_key;
+ }
cres->state = VMW_CMDBUF_RES_ADD;
cres->res = vmw_resource_reference(res);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 76e0e25..a499b2c 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1296,6 +1296,11 @@
if (size == 0)
goto done;
+ if (size > device->snapshot_memory.size) {
+ SNAPSHOT_ERR_NOMEM(device, "OBJS");
+ goto done;
+ }
+
snapshot->mempool = vmalloc(size);
ptr = snapshot->mempool;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index ce9e55e..7e49239 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -573,6 +573,17 @@
To compile this driver as a module, choose M here: the
module will be called hid-multitouch.
+config HID_NINTENDO
+ tristate "Nintendo Joy-Con and Pro Controller support"
+ depends on HID
+ help
+ Adds support for the Nintendo Switch Joy-Cons and Pro Controller.
+ All controllers support bluetooth, and the Pro Controller also supports
+ its USB mode.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hid-nintendo.
+
config HID_NTRIG
tristate "N-Trig touch screen"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a11278bf..538716e 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -61,6 +61,7 @@
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o
+obj-$(CONFIG_HID_NINTENDO) += hid-nintendo.o
obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
obj-$(CONFIG_HID_ORTEK) += hid-ortek.o
obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 6d76e96..0a3efa7 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -341,7 +341,8 @@
unsigned long **bit, int *max)
{
if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
- usage->hid == (HID_UP_MSVENDOR | 0x0003)) {
+ usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
+ usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
/* The fn key on Apple USB keyboards */
set_bit(EV_REP, hi->input->evbit);
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 2ac7811..4f3706e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1547,7 +1547,9 @@
rsize = ((report->size - 1) >> 3) + 1;
- if (rsize > HID_MAX_BUFFER_SIZE)
+ if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)
+ rsize = HID_MAX_BUFFER_SIZE - 1;
+ else if (rsize > HID_MAX_BUFFER_SIZE)
rsize = HID_MAX_BUFFER_SIZE;
if (csize < rsize) {
@@ -2060,6 +2062,16 @@
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
+#if IS_ENABLED(CONFIG_HID_NINTENDO)
+ { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_PROCON) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_PROCON) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_JOYCONL) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_JOYCONR) },
+#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 36d69ee..3df4364 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -778,6 +778,9 @@
#define USB_VENDOR_ID_NINTENDO 0x057e
#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
#define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330
+#define USB_DEVICE_ID_NINTENDO_JOYCONL 0x2006
+#define USB_DEVICE_ID_NINTENDO_JOYCONR 0x2007
+#define USB_DEVICE_ID_NINTENDO_PROCON 0x2009
#define USB_VENDOR_ID_NOVATEK 0x0603
#define USB_DEVICE_ID_NOVATEK_PCT 0x0600
diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
new file mode 100644
index 0000000..3695b96
--- /dev/null
+++ b/drivers/hid/hid-nintendo.c
@@ -0,0 +1,820 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * HID driver for Nintendo Switch Joy-Cons and Pro Controllers
+ *
+ * Copyright (c) 2019 Daniel J. Ogorchock <djogorchock@gmail.com>
+ *
+ * The following resources/projects were referenced for this driver:
+ * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering
+ * https://gitlab.com/pjranki/joycon-linux-kernel (Peter Rankin)
+ * https://github.com/FrotBot/SwitchProConLinuxUSB
+ * https://github.com/MTCKC/ProconXInput
+ * hid-wiimote kernel hid driver
+ * hid-logitech-hidpp driver
+ *
+ * This driver supports the Nintendo Switch Joy-Cons and Pro Controllers. The
+ * Pro Controllers can either be used over USB or Bluetooth.
+ *
+ * The driver will retrieve the factory calibration info from the controllers,
+ * so little to no user calibration should be required.
+ *
+ */
+
+#include "hid-ids.h"
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+/*
+ * Reference the url below for the following HID report defines:
+ * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering
+ */
+
+/* Output Reports */
+static const u8 JC_OUTPUT_RUMBLE_AND_SUBCMD = 0x01;
+static const u8 JC_OUTPUT_FW_UPDATE_PKT = 0x03;
+static const u8 JC_OUTPUT_RUMBLE_ONLY = 0x10;
+static const u8 JC_OUTPUT_MCU_DATA = 0x11;
+static const u8 JC_OUTPUT_USB_CMD = 0x80;
+
+/* Subcommand IDs */
+static const u8 JC_SUBCMD_STATE /*= 0x00*/;
+static const u8 JC_SUBCMD_MANUAL_BT_PAIRING = 0x01;
+static const u8 JC_SUBCMD_REQ_DEV_INFO = 0x02;
+static const u8 JC_SUBCMD_SET_REPORT_MODE = 0x03;
+static const u8 JC_SUBCMD_TRIGGERS_ELAPSED = 0x04;
+static const u8 JC_SUBCMD_GET_PAGE_LIST_STATE = 0x05;
+static const u8 JC_SUBCMD_SET_HCI_STATE = 0x06;
+static const u8 JC_SUBCMD_RESET_PAIRING_INFO = 0x07;
+static const u8 JC_SUBCMD_LOW_POWER_MODE = 0x08;
+static const u8 JC_SUBCMD_SPI_FLASH_READ = 0x10;
+static const u8 JC_SUBCMD_SPI_FLASH_WRITE = 0x11;
+static const u8 JC_SUBCMD_RESET_MCU = 0x20;
+static const u8 JC_SUBCMD_SET_MCU_CONFIG = 0x21;
+static const u8 JC_SUBCMD_SET_MCU_STATE = 0x22;
+static const u8 JC_SUBCMD_SET_PLAYER_LIGHTS = 0x30;
+static const u8 JC_SUBCMD_GET_PLAYER_LIGHTS = 0x31;
+static const u8 JC_SUBCMD_SET_HOME_LIGHT = 0x38;
+static const u8 JC_SUBCMD_ENABLE_IMU = 0x40;
+static const u8 JC_SUBCMD_SET_IMU_SENSITIVITY = 0x41;
+static const u8 JC_SUBCMD_WRITE_IMU_REG = 0x42;
+static const u8 JC_SUBCMD_READ_IMU_REG = 0x43;
+static const u8 JC_SUBCMD_ENABLE_VIBRATION = 0x48;
+static const u8 JC_SUBCMD_GET_REGULATED_VOLTAGE = 0x50;
+
+/* Input Reports */
+static const u8 JC_INPUT_BUTTON_EVENT = 0x3F;
+static const u8 JC_INPUT_SUBCMD_REPLY = 0x21;
+static const u8 JC_INPUT_IMU_DATA = 0x30;
+static const u8 JC_INPUT_MCU_DATA = 0x31;
+static const u8 JC_INPUT_USB_RESPONSE = 0x81;
+
+/* Feature Reports */
+static const u8 JC_FEATURE_LAST_SUBCMD = 0x02;
+static const u8 JC_FEATURE_OTA_FW_UPGRADE = 0x70;
+static const u8 JC_FEATURE_SETUP_MEM_READ = 0x71;
+static const u8 JC_FEATURE_MEM_READ = 0x72;
+static const u8 JC_FEATURE_ERASE_MEM_SECTOR = 0x73;
+static const u8 JC_FEATURE_MEM_WRITE = 0x74;
+static const u8 JC_FEATURE_LAUNCH = 0x75;
+
+/* USB Commands */
+static const u8 JC_USB_CMD_CONN_STATUS = 0x01;
+static const u8 JC_USB_CMD_HANDSHAKE = 0x02;
+static const u8 JC_USB_CMD_BAUDRATE_3M = 0x03;
+static const u8 JC_USB_CMD_NO_TIMEOUT = 0x04;
+static const u8 JC_USB_CMD_EN_TIMEOUT = 0x05;
+static const u8 JC_USB_RESET = 0x06;
+static const u8 JC_USB_PRE_HANDSHAKE = 0x91;
+static const u8 JC_USB_SEND_UART = 0x92;
+
+/* SPI storage addresses of factory calibration data */
+static const u16 JC_CAL_DATA_START = 0x603d;
+static const u16 JC_CAL_DATA_END = 0x604e;
+#define JC_CAL_DATA_SIZE (JC_CAL_DATA_END - JC_CAL_DATA_START + 1)
+
+
+/* The raw analog joystick values will be mapped in terms of this magnitude */
+static const u16 JC_MAX_STICK_MAG = 32767;
+static const u16 JC_STICK_FUZZ = 250;
+static const u16 JC_STICK_FLAT = 500;
+
+/* States for controller state machine */
+enum joycon_ctlr_state {
+ JOYCON_CTLR_STATE_INIT,
+ JOYCON_CTLR_STATE_READ,
+};
+
+struct joycon_stick_cal {
+ s32 max;
+ s32 min;
+ s32 center;
+};
+
+/*
+ * All the controller's button values are stored in a u32.
+ * They can be accessed with bitwise ANDs.
+ */
+static const u32 JC_BTN_Y = BIT(0);
+static const u32 JC_BTN_X = BIT(1);
+static const u32 JC_BTN_B = BIT(2);
+static const u32 JC_BTN_A = BIT(3);
+static const u32 JC_BTN_SR_R = BIT(4);
+static const u32 JC_BTN_SL_R = BIT(5);
+static const u32 JC_BTN_R = BIT(6);
+static const u32 JC_BTN_ZR = BIT(7);
+static const u32 JC_BTN_MINUS = BIT(8);
+static const u32 JC_BTN_PLUS = BIT(9);
+static const u32 JC_BTN_RSTICK = BIT(10);
+static const u32 JC_BTN_LSTICK = BIT(11);
+static const u32 JC_BTN_HOME = BIT(12);
+static const u32 JC_BTN_CAP = BIT(13); /* capture button */
+static const u32 JC_BTN_DOWN = BIT(16);
+static const u32 JC_BTN_UP = BIT(17);
+static const u32 JC_BTN_RIGHT = BIT(18);
+static const u32 JC_BTN_LEFT = BIT(19);
+static const u32 JC_BTN_SR_L = BIT(20);
+static const u32 JC_BTN_SL_L = BIT(21);
+static const u32 JC_BTN_L = BIT(22);
+static const u32 JC_BTN_ZL = BIT(23);
+
+enum joycon_msg_type {
+ JOYCON_MSG_TYPE_NONE,
+ JOYCON_MSG_TYPE_USB,
+ JOYCON_MSG_TYPE_SUBCMD,
+};
+
+struct joycon_subcmd_request {
+ u8 output_id; /* must be 0x01 for subcommand, 0x10 for rumble only */
+ u8 packet_num; /* incremented every send */
+ u8 rumble_data[8];
+ u8 subcmd_id;
+ u8 data[0]; /* length depends on the subcommand */
+} __packed;
+
+struct joycon_subcmd_reply {
+ u8 ack; /* MSB 1 for ACK, 0 for NACK */
+ u8 id; /* id of requested subcmd */
+ u8 data[0]; /* will be at most 35 bytes */
+} __packed;
+
+struct joycon_input_report {
+ u8 id;
+ u8 timer;
+ u8 bat_con; /* battery and connection info */
+ u8 button_status[3];
+ u8 left_stick[3];
+ u8 right_stick[3];
+ u8 vibrator_report;
+
+ /*
+ * If support for firmware updates, gyroscope data, and/or NFC/IR
+ * are added in the future, this can be swapped for a union.
+ */
+ struct joycon_subcmd_reply reply;
+} __packed;
+
+#define JC_MAX_RESP_SIZE (sizeof(struct joycon_input_report) + 35)
+
+/* Each physical controller is associated with a joycon_ctlr struct */
+struct joycon_ctlr {
+ struct hid_device *hdev;
+ struct input_dev *input;
+ enum joycon_ctlr_state ctlr_state;
+
+ /* The following members are used for synchronous sends/receives */
+ enum joycon_msg_type msg_type;
+ u8 subcmd_num;
+ struct mutex output_mutex;
+ u8 input_buf[JC_MAX_RESP_SIZE];
+ wait_queue_head_t wait;
+ bool received_resp;
+ u8 usb_ack_match;
+ u8 subcmd_ack_match;
+
+ /* factory calibration data */
+ struct joycon_stick_cal left_stick_cal_x;
+ struct joycon_stick_cal left_stick_cal_y;
+ struct joycon_stick_cal right_stick_cal_x;
+ struct joycon_stick_cal right_stick_cal_y;
+
+};
+
+static int __joycon_hid_send(struct hid_device *hdev, u8 *data, size_t len)
+{
+ u8 *buf;
+ int ret;
+
+ buf = kmemdup(data, len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ ret = hid_hw_output_report(hdev, buf, len);
+ kfree(buf);
+ if (ret < 0)
+ hid_dbg(hdev, "Failed to send output report ret=%d\n", ret);
+ return ret;
+}
+
+static int joycon_hid_send_sync(struct joycon_ctlr *ctlr, u8 *data, size_t len)
+{
+ int ret;
+
+ ret = __joycon_hid_send(ctlr->hdev, data, len);
+ if (ret < 0) {
+ memset(ctlr->input_buf, 0, JC_MAX_RESP_SIZE);
+ return ret;
+ }
+
+ if (!wait_event_timeout(ctlr->wait, ctlr->received_resp, HZ)) {
+ hid_dbg(ctlr->hdev, "synchronous send/receive timed out\n");
+ memset(ctlr->input_buf, 0, JC_MAX_RESP_SIZE);
+ return -ETIMEDOUT;
+ }
+
+ ctlr->received_resp = false;
+ return 0;
+}
+
+static int joycon_send_usb(struct joycon_ctlr *ctlr, u8 cmd)
+{
+ int ret;
+ u8 buf[2] = {JC_OUTPUT_USB_CMD};
+
+ buf[1] = cmd;
+ ctlr->usb_ack_match = cmd;
+ ctlr->msg_type = JOYCON_MSG_TYPE_USB;
+ ret = joycon_hid_send_sync(ctlr, buf, sizeof(buf));
+ if (ret)
+ hid_dbg(ctlr->hdev, "send usb command failed; ret=%d\n", ret);
+ return ret;
+}
+
+static int joycon_send_subcmd(struct joycon_ctlr *ctlr,
+ struct joycon_subcmd_request *subcmd,
+ size_t data_len)
+{
+ int ret;
+
+ subcmd->output_id = JC_OUTPUT_RUMBLE_AND_SUBCMD;
+ subcmd->packet_num = ctlr->subcmd_num;
+ if (++ctlr->subcmd_num > 0xF)
+ ctlr->subcmd_num = 0;
+ ctlr->subcmd_ack_match = subcmd->subcmd_id;
+ ctlr->msg_type = JOYCON_MSG_TYPE_SUBCMD;
+
+ ret = joycon_hid_send_sync(ctlr, (u8 *)subcmd,
+ sizeof(*subcmd) + data_len);
+ if (ret < 0)
+ hid_dbg(ctlr->hdev, "send subcommand failed; ret=%d\n", ret);
+ else
+ ret = 0;
+ return ret;
+}
+
+/* Supply nibbles for flash and on. Ones correspond to active */
+static int joycon_set_player_leds(struct joycon_ctlr *ctlr, u8 flash, u8 on)
+{
+ struct joycon_subcmd_request *req;
+ u8 buffer[sizeof(*req) + 1] = { 0 };
+
+ req = (struct joycon_subcmd_request *)buffer;
+ req->subcmd_id = JC_SUBCMD_SET_PLAYER_LIGHTS;
+ req->data[0] = (flash << 4) | on;
+
+ hid_dbg(ctlr->hdev, "setting player leds\n");
+ return joycon_send_subcmd(ctlr, req, 1);
+}
+
+static const u16 DFLT_STICK_CAL_CEN = 2000;
+static const u16 DFLT_STICK_CAL_MAX = 3500;
+static const u16 DFLT_STICK_CAL_MIN = 500;
+static int joycon_request_calibration(struct joycon_ctlr *ctlr)
+{
+ struct joycon_subcmd_request *req;
+ u8 buffer[sizeof(*req) + 5] = { 0 };
+ struct joycon_input_report *report;
+ struct joycon_stick_cal *cal_x;
+ struct joycon_stick_cal *cal_y;
+ s32 x_max_above;
+ s32 x_min_below;
+ s32 y_max_above;
+ s32 y_min_below;
+ u8 *data;
+ u8 *raw_cal;
+ int ret;
+
+ req = (struct joycon_subcmd_request *)buffer;
+ req->subcmd_id = JC_SUBCMD_SPI_FLASH_READ;
+ data = req->data;
+ data[0] = 0xFF & JC_CAL_DATA_START;
+ data[1] = 0xFF & (JC_CAL_DATA_START >> 8);
+ data[2] = 0xFF & (JC_CAL_DATA_START >> 16);
+ data[3] = 0xFF & (JC_CAL_DATA_START >> 24);
+ data[4] = JC_CAL_DATA_SIZE;
+
+ hid_dbg(ctlr->hdev, "requesting cal data\n");
+ ret = joycon_send_subcmd(ctlr, req, 5);
+ if (ret) {
+ hid_warn(ctlr->hdev,
+ "Failed to read stick cal, using defaults; ret=%d\n",
+ ret);
+
+ ctlr->left_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+ ctlr->left_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+ ctlr->left_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+
+ ctlr->left_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+ ctlr->left_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+ ctlr->left_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+
+ ctlr->right_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+ ctlr->right_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+ ctlr->right_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+
+ ctlr->right_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+ ctlr->right_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+ ctlr->right_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+
+ return ret;
+ }
+
+ report = (struct joycon_input_report *)ctlr->input_buf;
+ raw_cal = &report->reply.data[5];
+
+ /* left stick calibration parsing */
+ cal_x = &ctlr->left_stick_cal_x;
+ cal_y = &ctlr->left_stick_cal_y;
+
+ x_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 0), 0, 12);
+ y_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 1), 4, 12);
+ cal_x->center = hid_field_extract(ctlr->hdev, (raw_cal + 3), 0, 12);
+ cal_y->center = hid_field_extract(ctlr->hdev, (raw_cal + 4), 4, 12);
+ x_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 6), 0, 12);
+ y_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 7), 4, 12);
+ cal_x->max = cal_x->center + x_max_above;
+ cal_x->min = cal_x->center - x_min_below;
+ cal_y->max = cal_y->center + y_max_above;
+ cal_y->min = cal_y->center - y_min_below;
+
+ /* right stick calibration parsing */
+ raw_cal += 9;
+ cal_x = &ctlr->right_stick_cal_x;
+ cal_y = &ctlr->right_stick_cal_y;
+
+ cal_x->center = hid_field_extract(ctlr->hdev, (raw_cal + 0), 0, 12);
+ cal_y->center = hid_field_extract(ctlr->hdev, (raw_cal + 1), 4, 12);
+ x_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 3), 0, 12);
+ y_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 4), 4, 12);
+ x_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 6), 0, 12);
+ y_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 7), 4, 12);
+ cal_x->max = cal_x->center + x_max_above;
+ cal_x->min = cal_x->center - x_min_below;
+ cal_y->max = cal_y->center + y_max_above;
+ cal_y->min = cal_y->center - y_min_below;
+
+ hid_dbg(ctlr->hdev, "calibration:\n"
+ "l_x_c=%d l_x_max=%d l_x_min=%d\n"
+ "l_y_c=%d l_y_max=%d l_y_min=%d\n"
+ "r_x_c=%d r_x_max=%d r_x_min=%d\n"
+ "r_y_c=%d r_y_max=%d r_y_min=%d\n",
+ ctlr->left_stick_cal_x.center,
+ ctlr->left_stick_cal_x.max,
+ ctlr->left_stick_cal_x.min,
+ ctlr->left_stick_cal_y.center,
+ ctlr->left_stick_cal_y.max,
+ ctlr->left_stick_cal_y.min,
+ ctlr->right_stick_cal_x.center,
+ ctlr->right_stick_cal_x.max,
+ ctlr->right_stick_cal_x.min,
+ ctlr->right_stick_cal_y.center,
+ ctlr->right_stick_cal_y.max,
+ ctlr->right_stick_cal_y.min);
+
+ return 0;
+}
+
+static int joycon_set_report_mode(struct joycon_ctlr *ctlr)
+{
+ struct joycon_subcmd_request *req;
+ u8 buffer[sizeof(*req) + 1] = { 0 };
+
+ req = (struct joycon_subcmd_request *)buffer;
+ req->subcmd_id = JC_SUBCMD_SET_REPORT_MODE;
+ req->data[0] = 0x30; /* standard, full report mode */
+
+ hid_dbg(ctlr->hdev, "setting controller report mode\n");
+ return joycon_send_subcmd(ctlr, req, 1);
+}
+
+static s32 joycon_map_stick_val(struct joycon_stick_cal *cal, s32 val)
+{
+ s32 center = cal->center;
+ s32 min = cal->min;
+ s32 max = cal->max;
+ s32 new_val;
+
+ if (val > center) {
+ new_val = (val - center) * JC_MAX_STICK_MAG;
+ new_val /= (max - center);
+ } else {
+ new_val = (center - val) * -JC_MAX_STICK_MAG;
+ new_val /= (center - min);
+ }
+ new_val = clamp(new_val, (s32)-JC_MAX_STICK_MAG, (s32)JC_MAX_STICK_MAG);
+ return new_val;
+}
+
+static void joycon_parse_report(struct joycon_ctlr *ctlr,
+ struct joycon_input_report *rep)
+{
+ struct input_dev *dev = ctlr->input;
+ u32 btns;
+ u32 id = ctlr->hdev->product;
+
+ btns = hid_field_extract(ctlr->hdev, rep->button_status, 0, 24);
+
+ if (id != USB_DEVICE_ID_NINTENDO_JOYCONR) {
+ u16 raw_x;
+ u16 raw_y;
+ s32 x;
+ s32 y;
+
+ /* get raw stick values */
+ raw_x = hid_field_extract(ctlr->hdev, rep->left_stick, 0, 12);
+ raw_y = hid_field_extract(ctlr->hdev,
+ rep->left_stick + 1, 4, 12);
+ /* map the stick values */
+ x = joycon_map_stick_val(&ctlr->left_stick_cal_x, raw_x);
+ y = -joycon_map_stick_val(&ctlr->left_stick_cal_y, raw_y);
+ /* report sticks */
+ input_report_abs(dev, ABS_X, x);
+ input_report_abs(dev, ABS_Y, y);
+
+ /* report buttons */
+ input_report_key(dev, BTN_TL, btns & JC_BTN_L);
+ input_report_key(dev, BTN_TL2, btns & JC_BTN_ZL);
+ if (id != USB_DEVICE_ID_NINTENDO_PROCON) {
+ /* Report the S buttons as the non-existent triggers */
+ input_report_key(dev, BTN_TR, btns & JC_BTN_SL_L);
+ input_report_key(dev, BTN_TR2, btns & JC_BTN_SR_L);
+ }
+ input_report_key(dev, BTN_SELECT, btns & JC_BTN_MINUS);
+ input_report_key(dev, BTN_THUMBL, btns & JC_BTN_LSTICK);
+ input_report_key(dev, BTN_Z, btns & JC_BTN_CAP);
+ input_report_key(dev, BTN_DPAD_DOWN, btns & JC_BTN_DOWN);
+ input_report_key(dev, BTN_DPAD_UP, btns & JC_BTN_UP);
+ input_report_key(dev, BTN_DPAD_RIGHT, btns & JC_BTN_RIGHT);
+ input_report_key(dev, BTN_DPAD_LEFT, btns & JC_BTN_LEFT);
+ }
+ if (id != USB_DEVICE_ID_NINTENDO_JOYCONL) {
+ u16 raw_x;
+ u16 raw_y;
+ s32 x;
+ s32 y;
+
+ /* get raw stick values */
+ raw_x = hid_field_extract(ctlr->hdev, rep->right_stick, 0, 12);
+ raw_y = hid_field_extract(ctlr->hdev,
+ rep->right_stick + 1, 4, 12);
+ /* map stick values */
+ x = joycon_map_stick_val(&ctlr->right_stick_cal_x, raw_x);
+ y = -joycon_map_stick_val(&ctlr->right_stick_cal_y, raw_y);
+ /* report sticks */
+ input_report_abs(dev, ABS_RX, x);
+ input_report_abs(dev, ABS_RY, y);
+
+ /* report buttons */
+ input_report_key(dev, BTN_TR, btns & JC_BTN_R);
+ input_report_key(dev, BTN_TR2, btns & JC_BTN_ZR);
+ if (id != USB_DEVICE_ID_NINTENDO_PROCON) {
+ /* Report the S buttons as the non-existent triggers */
+ input_report_key(dev, BTN_TL, btns & JC_BTN_SL_R);
+ input_report_key(dev, BTN_TL2, btns & JC_BTN_SR_R);
+ }
+ input_report_key(dev, BTN_START, btns & JC_BTN_PLUS);
+ input_report_key(dev, BTN_THUMBR, btns & JC_BTN_RSTICK);
+ input_report_key(dev, BTN_MODE, btns & JC_BTN_HOME);
+ input_report_key(dev, BTN_WEST, btns & JC_BTN_Y);
+ input_report_key(dev, BTN_NORTH, btns & JC_BTN_X);
+ input_report_key(dev, BTN_EAST, btns & JC_BTN_A);
+ input_report_key(dev, BTN_SOUTH, btns & JC_BTN_B);
+ }
+
+ input_sync(dev);
+}
+
+
+static const unsigned int joycon_button_inputs_l[] = {
+ BTN_SELECT, BTN_Z, BTN_THUMBL,
+ BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT,
+ BTN_TL, BTN_TL2,
+ 0 /* 0 signals end of array */
+};
+
+static const unsigned int joycon_button_inputs_r[] = {
+ BTN_START, BTN_MODE, BTN_THUMBR,
+ BTN_SOUTH, BTN_EAST, BTN_NORTH, BTN_WEST,
+ BTN_TR, BTN_TR2,
+ 0 /* 0 signals end of array */
+};
+
+static DEFINE_MUTEX(joycon_input_num_mutex);
+static int joycon_input_create(struct joycon_ctlr *ctlr)
+{
+ struct hid_device *hdev;
+ static int input_num = 1;
+ const char *name;
+ int ret;
+ int i;
+
+ hdev = ctlr->hdev;
+
+ switch (hdev->product) {
+ case USB_DEVICE_ID_NINTENDO_PROCON:
+ name = "Nintendo Switch Pro Controller";
+ break;
+ case USB_DEVICE_ID_NINTENDO_JOYCONL:
+ name = "Nintendo Switch Left Joy-Con";
+ break;
+ case USB_DEVICE_ID_NINTENDO_JOYCONR:
+ name = "Nintendo Switch Right Joy-Con";
+ break;
+ default: /* Should be impossible */
+ hid_err(hdev, "Invalid hid product\n");
+ return -EINVAL;
+ }
+
+ ctlr->input = devm_input_allocate_device(&hdev->dev);
+ if (!ctlr->input)
+ return -ENOMEM;
+ ctlr->input->id.bustype = hdev->bus;
+ ctlr->input->id.vendor = hdev->vendor;
+ ctlr->input->id.product = hdev->product;
+ ctlr->input->id.version = hdev->version;
+ ctlr->input->name = name;
+ input_set_drvdata(ctlr->input, ctlr);
+
+
+ /* set up sticks */
+ if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONR) {
+ input_set_abs_params(ctlr->input, ABS_X,
+ -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
+ JC_STICK_FUZZ, JC_STICK_FLAT);
+ input_set_abs_params(ctlr->input, ABS_Y,
+ -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
+ JC_STICK_FUZZ, JC_STICK_FLAT);
+ }
+ if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONL) {
+ input_set_abs_params(ctlr->input, ABS_RX,
+ -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
+ JC_STICK_FUZZ, JC_STICK_FLAT);
+ input_set_abs_params(ctlr->input, ABS_RY,
+ -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG,
+ JC_STICK_FUZZ, JC_STICK_FLAT);
+ }
+
+ /* set up buttons */
+ if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONR) {
+ for (i = 0; joycon_button_inputs_l[i] > 0; i++)
+ input_set_capability(ctlr->input, EV_KEY,
+ joycon_button_inputs_l[i]);
+ }
+ if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONL) {
+ for (i = 0; joycon_button_inputs_r[i] > 0; i++)
+ input_set_capability(ctlr->input, EV_KEY,
+ joycon_button_inputs_r[i]);
+ }
+
+ ret = input_register_device(ctlr->input);
+ if (ret)
+ return ret;
+
+ /* Set the default controller player leds based on controller number */
+ mutex_lock(&joycon_input_num_mutex);
+ mutex_lock(&ctlr->output_mutex);
+ ret = joycon_set_player_leds(ctlr, 0, 0xF >> (4 - input_num));
+ if (ret)
+ hid_warn(ctlr->hdev, "Failed to set leds; ret=%d\n", ret);
+ mutex_unlock(&ctlr->output_mutex);
+ if (++input_num > 4)
+ input_num = 1;
+ mutex_unlock(&joycon_input_num_mutex);
+
+ return 0;
+}
+
+/* Common handler for parsing inputs */
+static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data,
+ int size)
+{
+ int ret = 0;
+
+ if (data[0] == JC_INPUT_SUBCMD_REPLY || data[0] == JC_INPUT_IMU_DATA ||
+ data[0] == JC_INPUT_MCU_DATA) {
+ if (size >= 12) /* make sure it contains the input report */
+ joycon_parse_report(ctlr,
+ (struct joycon_input_report *)data);
+ }
+
+ return ret;
+}
+
+static int joycon_ctlr_handle_event(struct joycon_ctlr *ctlr, u8 *data,
+ int size)
+{
+ int ret = 0;
+ bool match = false;
+ struct joycon_input_report *report;
+
+ if (unlikely(mutex_is_locked(&ctlr->output_mutex)) &&
+ ctlr->msg_type != JOYCON_MSG_TYPE_NONE) {
+ switch (ctlr->msg_type) {
+ case JOYCON_MSG_TYPE_USB:
+ if (size < 2)
+ break;
+ if (data[0] == JC_INPUT_USB_RESPONSE &&
+ data[1] == ctlr->usb_ack_match)
+ match = true;
+ break;
+ case JOYCON_MSG_TYPE_SUBCMD:
+ if (size < sizeof(struct joycon_input_report) ||
+ data[0] != JC_INPUT_SUBCMD_REPLY)
+ break;
+ report = (struct joycon_input_report *)data;
+ if (report->reply.id == ctlr->subcmd_ack_match)
+ match = true;
+ break;
+ default:
+ break;
+ }
+
+ if (match) {
+ memcpy(ctlr->input_buf, data,
+ min(size, (int)JC_MAX_RESP_SIZE));
+ ctlr->msg_type = JOYCON_MSG_TYPE_NONE;
+ ctlr->received_resp = true;
+ wake_up(&ctlr->wait);
+
+ /* This message has been handled */
+ return 1;
+ }
+ }
+
+ if (ctlr->ctlr_state == JOYCON_CTLR_STATE_READ)
+ ret = joycon_ctlr_read_handler(ctlr, data, size);
+
+ return ret;
+}
+
+static int nintendo_hid_event(struct hid_device *hdev,
+ struct hid_report *report, u8 *raw_data, int size)
+{
+ struct joycon_ctlr *ctlr = hid_get_drvdata(hdev);
+
+ if (size < 1)
+ return -EINVAL;
+
+ return joycon_ctlr_handle_event(ctlr, raw_data, size);
+}
+
+static int nintendo_hid_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ int ret;
+ struct joycon_ctlr *ctlr;
+
+ hid_dbg(hdev, "probe - start\n");
+
+ ctlr = devm_kzalloc(&hdev->dev, sizeof(*ctlr), GFP_KERNEL);
+ if (!ctlr) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ctlr->hdev = hdev;
+ ctlr->ctlr_state = JOYCON_CTLR_STATE_INIT;
+ hid_set_drvdata(hdev, ctlr);
+ mutex_init(&ctlr->output_mutex);
+ init_waitqueue_head(&ctlr->wait);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "HID parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+ if (ret) {
+ hid_err(hdev, "HW start failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_open(hdev);
+ if (ret) {
+ hid_err(hdev, "cannot start hardware I/O\n");
+ goto err_stop;
+ }
+
+ hid_device_io_start(hdev);
+
+ /* Initialize the controller */
+ mutex_lock(&ctlr->output_mutex);
+ /* if handshake command fails, assume ble pro controller */
+ if (hdev->product == USB_DEVICE_ID_NINTENDO_PROCON &&
+ !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE)) {
+ hid_dbg(hdev, "detected USB controller\n");
+ /* set baudrate for improved latency */
+ ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M);
+ if (ret) {
+ hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret);
+ goto err_mutex;
+ }
+ /* handshake */
+ ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE);
+ if (ret) {
+ hid_err(hdev, "Failed handshake; ret=%d\n", ret);
+ goto err_mutex;
+ }
+ /*
+ * Set no timeout (to keep controller in USB mode).
+ * This doesn't send a response, so ignore the timeout.
+ */
+ joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT);
+ }
+
+ /* get controller calibration data, and parse it */
+ ret = joycon_request_calibration(ctlr);
+ if (ret) {
+ /*
+ * We can function with default calibration, but it may be
+ * inaccurate. Provide a warning, and continue on.
+ */
+ hid_warn(hdev, "Analog stick positions may be inaccurate\n");
+ }
+
+ /* Set the reporting mode to 0x30, which is the full report mode */
+ ret = joycon_set_report_mode(ctlr);
+ if (ret) {
+ hid_err(hdev, "Failed to set report mode; ret=%d\n", ret);
+ goto err_mutex;
+ }
+
+ mutex_unlock(&ctlr->output_mutex);
+
+ ret = joycon_input_create(ctlr);
+ if (ret) {
+ hid_err(hdev, "Failed to create input device; ret=%d\n", ret);
+ goto err_close;
+ }
+
+ ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;
+
+ hid_dbg(hdev, "probe - success\n");
+ return 0;
+
+err_mutex:
+ mutex_unlock(&ctlr->output_mutex);
+err_close:
+ hid_hw_close(hdev);
+err_stop:
+ hid_hw_stop(hdev);
+err:
+ hid_err(hdev, "probe - fail = %d\n", ret);
+ return ret;
+}
+
+static void nintendo_hid_remove(struct hid_device *hdev)
+{
+ hid_dbg(hdev, "remove\n");
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id nintendo_hid_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_PROCON) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_PROCON) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_JOYCONL) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
+ USB_DEVICE_ID_NINTENDO_JOYCONR) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, nintendo_hid_devices);
+
+static struct hid_driver nintendo_hid_driver = {
+ .name = "nintendo",
+ .id_table = nintendo_hid_devices,
+ .probe = nintendo_hid_probe,
+ .remove = nintendo_hid_remove,
+ .raw_event = nintendo_hid_event,
+};
+module_hid_driver(nintendo_hid_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel J. Ogorchock <djogorchock@gmail.com>");
+MODULE_DESCRIPTION("Driver for Nintendo Switch Controllers");
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
index 10af858..9505237 100644
--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -342,6 +342,14 @@
.driver_data = (void *)&sipodev_desc
},
{
+ .ident = "Trekstor SURFBOOK E11B",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"),
+ },
+ .driver_data = (void *)&sipodev_desc
+ },
+ {
.ident = "Direkt-Tek DTLAPY116-2",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"),
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 8903ea0..dbdd265 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -962,9 +962,9 @@
hiddev->exist = 0;
if (hiddev->open) {
- mutex_unlock(&hiddev->existancelock);
usbhid_close(hiddev->hid);
wake_up_interruptible(&hiddev->wait);
+ mutex_unlock(&hiddev->existancelock);
} else {
mutex_unlock(&hiddev->existancelock);
kfree(hiddev);
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index 5929e12..d9923d6 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -426,7 +426,7 @@
return 0x95;
break;
}
- return -ENODEV;
+ return 0;
}
/* Provide labels for sysfs */
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 58b789c..94eea2a 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -89,8 +89,8 @@
#define LTC_POLL_TIMEOUT 100 /* in milli-seconds */
-#define LTC_NOT_BUSY BIT(5)
-#define LTC_NOT_PENDING BIT(4)
+#define LTC_NOT_BUSY BIT(6)
+#define LTC_NOT_PENDING BIT(5)
/*
* LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which
diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c
index 7bdd1bf..73713b2 100644
--- a/drivers/hwtracing/intel_th/msu.c
+++ b/drivers/hwtracing/intel_th/msu.c
@@ -497,7 +497,7 @@
lockdep_assert_held(&msc->buf_mutex);
if (msc->mode > MSC_MODE_MULTI)
- return -ENOTSUPP;
+ return -EINVAL;
if (msc->mode == MSC_MODE_MULTI)
msc_buffer_clear_hw_header(msc);
@@ -948,7 +948,7 @@
} else if (msc->mode == MSC_MODE_MULTI) {
ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins);
} else {
- ret = -ENOTSUPP;
+ ret = -EINVAL;
}
if (!ret) {
@@ -1171,7 +1171,7 @@
if (ret >= 0)
*ppos = iter->offset;
} else {
- ret = -ENOTSUPP;
+ ret = -EINVAL;
}
put_count:
diff --git a/drivers/i2c/busses/i2c-hix5hd2.c b/drivers/i2c/busses/i2c-hix5hd2.c
index ae7f318..75c8bbb 100644
--- a/drivers/i2c/busses/i2c-hix5hd2.c
+++ b/drivers/i2c/busses/i2c-hix5hd2.c
@@ -498,6 +498,7 @@
i2c_del_adapter(&priv->adap);
pm_runtime_disable(priv->dev);
pm_runtime_set_suspended(priv->dev);
+ clk_disable_unprepare(priv->clk);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
index 30132c3..41ca9ff 100644
--- a/drivers/i2c/busses/i2c-jz4780.c
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -82,25 +82,6 @@
#define JZ4780_I2C_STA_TFNF BIT(1)
#define JZ4780_I2C_STA_ACT BIT(0)
-static const char * const jz4780_i2c_abrt_src[] = {
- "ABRT_7B_ADDR_NOACK",
- "ABRT_10ADDR1_NOACK",
- "ABRT_10ADDR2_NOACK",
- "ABRT_XDATA_NOACK",
- "ABRT_GCALL_NOACK",
- "ABRT_GCALL_READ",
- "ABRT_HS_ACKD",
- "SBYTE_ACKDET",
- "ABRT_HS_NORSTRT",
- "SBYTE_NORSTRT",
- "ABRT_10B_RD_NORSTRT",
- "ABRT_MASTER_DIS",
- "ARB_LOST",
- "SLVFLUSH_TXFIFO",
- "SLV_ARBLOST",
- "SLVRD_INTX",
-};
-
#define JZ4780_I2C_INTST_IGC BIT(11)
#define JZ4780_I2C_INTST_ISTT BIT(10)
#define JZ4780_I2C_INTST_ISTP BIT(9)
@@ -538,21 +519,8 @@
static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src)
{
- int i;
-
- dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src);
- dev_err(&i2c->adap.dev, "device addr=%x\n",
- jz4780_i2c_readw(i2c, JZ4780_I2C_TAR));
- dev_err(&i2c->adap.dev, "send cmd count:%d %d\n",
- i2c->cmd, i2c->cmd_buf[i2c->cmd]);
- dev_err(&i2c->adap.dev, "receive data count:%d %d\n",
- i2c->cmd, i2c->data_buf[i2c->cmd]);
-
- for (i = 0; i < 16; i++) {
- if (src & BIT(i))
- dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n",
- i, jz4780_i2c_abrt_src[i]);
- }
+ dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n",
+ src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]);
}
static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index b127ed6..9dde839 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -65,6 +65,9 @@
struct ide_timing t;
u8 arttim = 0;
+ if (drive->dn >= ARRAY_SIZE(drwtim_regs))
+ return;
+
ide_timing_compute(drive, mode, &t, T, 0);
/*
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index a97affc..0f57d45 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -114,6 +114,9 @@
struct pci_dev *dev = to_pci_dev(hwif->dev);
const u8 pio = drive->pio_mode - XFER_PIO_0;
+ if (drive->dn >= ARRAY_SIZE(drive_pci))
+ return;
+
pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
if (svwks_csb_check(dev)) {
@@ -140,6 +143,9 @@
u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0;
+ if (drive->dn >= ARRAY_SIZE(drive_pci2))
+ return;
+
pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
pci_read_config_byte(dev, 0x54, &ultra_enable);
diff --git a/drivers/iio/imu/inv_mpu/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
index bf1b9c4..be6fa48 100644
--- a/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu/inv_mpu_ring.c
@@ -303,6 +303,7 @@
{
if (false == st->acc_buffer_inv_samples)
return;
+ mutex_lock(&st->acc_sensor_buff);
st->timestamp.tv64 = t;
if (ktime_to_timespec(st->timestamp).tv_sec
< st->max_buffer_time) {
@@ -328,13 +329,14 @@
st->acc_bufsample_cnt);
st->acc_buffer_inv_samples = false;
}
+ mutex_unlock(&st->acc_sensor_buff);
}
static void store_gyro_boot_sample(struct inv_mpu_state *st, u64 t,
s16 x, s16 y, s16 z)
{
-
if (false == st->gyro_buffer_inv_samples)
return;
+ mutex_lock(&st->gyro_sensor_buff);
st->timestamp.tv64 = t;
if (ktime_to_timespec(st->timestamp).tv_sec
< st->max_buffer_time) {
@@ -360,6 +362,7 @@
st->gyro_bufsample_cnt);
st->gyro_buffer_inv_samples = false;
}
+ mutex_unlock(&st->gyro_sensor_buff);
}
#else
static void store_acc_boot_sample(struct inv_mpu_state *st, u64 t,
@@ -383,9 +386,7 @@
memcpy(&buf[2], &d[0], sizeof(d[0]));
for (j = 0; j < 2; j++)
memcpy(&buf[4 + j * 2], &d[j + 1], sizeof(d[j]));
- mutex_lock(&st->gyro_sensor_buff);
store_gyro_boot_sample(st, t, d[0], d[1], d[2]);
- mutex_unlock(&st->gyro_sensor_buff);
iio_push_to_buffers(indio_dev, buf);
inv_push_timestamp(indio_dev, t);
@@ -476,9 +477,7 @@
for (j = 0; j < 2; j++)
memcpy(&buf[4 + j * 2], &d[j + 1],
sizeof(d[j]));
- mutex_lock(&st->acc_sensor_buff);
store_acc_boot_sample(st, t, d[0], d[1], d[2]);
- mutex_unlock(&st->acc_sensor_buff);
iio_push_to_buffers(indio_dev, buf);
inv_push_timestamp(indio_dev, t);
st->sensor_l[ii].counter = 0;
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
index c3ea68b..39a99a2 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
@@ -181,7 +181,6 @@
u16 watermark;
u8 batch_mask;
u8 batch_addr;
- struct mutex sensor_buff;
#ifdef CONFIG_ENABLE_ASM_ACC_GYRO_BUFFERING
bool read_boot_sample;
int bufsample_cnt;
@@ -192,6 +191,7 @@
int max_buffer_time;
struct input_dev *buf_dev;
int report_evt_cnt;
+ struct mutex sensor_buff;
#endif
};
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
index f1da1e4..623d434 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
@@ -203,6 +203,7 @@
if (false == sensor->buffer_asm_samples)
return;
+ mutex_lock(&sensor->sensor_buff);
sensor->timestamp = (ktime_t)tsample;
x = iio_buf[1]<<8|iio_buf[0];
y = iio_buf[3]<<8|iio_buf[2];
@@ -225,6 +226,7 @@
sensor->id, sensor->bufsample_cnt);
sensor->buffer_asm_samples = false;
}
+ mutex_unlock(&sensor->sensor_buff);
}
#else
static void store_acc_gyro_boot_sample(struct st_asm330lhh_sensor *sensor,
@@ -330,17 +332,15 @@
}
memcpy(iio_buf, ptr, ST_ASM330LHH_SAMPLE_SIZE);
- hw->tsample = min_t(s64,
- hw->ts,
- hw->tsample);
-
+ if ((i + (3*ST_ASM330LHH_FIFO_SAMPLE_SIZE)) >
+ word_len) {
+ hw->tsample = hw->ts;
+ }
iio_push_to_buffers_with_timestamp(iio_dev,
iio_buf,
hw->tsample);
- mutex_lock(&sensor->sensor_buff);
store_acc_gyro_boot_sample(sensor,
iio_buf, hw->tsample);
- mutex_unlock(&sensor->sensor_buff);
}
}
read_len += word_len;
@@ -538,6 +538,8 @@
bool irq_active_low;
int i, err;
+ if (!irq_get_irq_data(hw->irq))
+ return -EINVAL;
irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
if (irq_type == IRQF_TRIGGER_NONE)
irq_type = IRQF_TRIGGER_HIGH;
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index dd3fcd1..752237f 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -477,7 +477,7 @@
* We read all axes and discard all but one, for optimized
* reading, use the triggered buffer.
*/
- *val = le16_to_cpu(hw_values[chan->address]);
+ *val = (s16)le16_to_cpu(hw_values[chan->address]);
ret = IIO_VAL_INT;
}
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 1baa25e..f7d23c1 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -141,7 +141,7 @@
if (ib_nl_is_good_ip_resp(nlh))
ib_nl_process_good_ip_rsep(nlh);
- return skb->len;
+ return 0;
}
static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 71c7c4c..304429f 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -1073,6 +1073,7 @@
/* Sharing an ib_cm_id with different handlers is not
* supported */
spin_unlock_irqrestore(&cm.lock, flags);
+ ib_destroy_cm_id(cm_id);
return ERR_PTR(-EINVAL);
}
atomic_inc(&cm_id_priv->refcount);
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 5495e22..1f71c30 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -137,8 +137,10 @@
{
struct list_head *e, *tmp;
- list_for_each_safe(e, tmp, &cm_id_priv->work_free_list)
+ list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) {
+ list_del(e);
kfree(list_entry(e, struct iwcm_work, free_list));
+ }
}
static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 5879a06..1c45972 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -848,7 +848,7 @@
}
settimeout_out:
- return skb->len;
+ return 0;
}
static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh)
@@ -920,7 +920,7 @@
}
resp_out:
- return skb->len;
+ return 0;
}
static void free_sm_ah(struct kref *kref)
diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c
index 79e6309..262c18b 100644
--- a/drivers/infiniband/hw/mlx5/gsi.c
+++ b/drivers/infiniband/hw/mlx5/gsi.c
@@ -507,8 +507,7 @@
ret = ib_post_send(tx_qp, &cur_wr.wr, bad_wr);
if (ret) {
/* Undo the effect of adding the outstanding wr */
- gsi->outstanding_pi = (gsi->outstanding_pi - 1) %
- gsi->cap.max_send_wr;
+ gsi->outstanding_pi--;
goto err;
}
spin_unlock_irqrestore(&gsi->lock, flags);
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
index 47003d2..dee3853 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -422,7 +422,7 @@
struct list_head pending_mmaps;
spinlock_t mmap_offset_lock; /* guard mmap_offset */
- int mmap_offset;
+ u64 mmap_offset;
struct rxe_port port;
struct list_head list;
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 0d2ab9a..02a5e2d 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -2555,6 +2555,17 @@
}
}
+static void
+isert_wait4cmds(struct iscsi_conn *conn)
+{
+ isert_info("iscsi_conn %p\n", conn);
+
+ if (conn->sess) {
+ target_sess_cmd_list_set_waiting(conn->sess->se_sess);
+ target_wait_for_sess_cmds(conn->sess->se_sess);
+ }
+}
+
/**
* isert_put_unsol_pending_cmds() - Drop commands waiting for
* unsolicitate dataout
@@ -2602,6 +2613,7 @@
ib_drain_qp(isert_conn->qp);
isert_put_unsol_pending_cmds(conn);
+ isert_wait4cmds(conn);
isert_wait4logout(isert_conn);
queue_work(isert_release_wq, &isert_conn->release_work);
diff --git a/drivers/input/misc/qti-haptics.c b/drivers/input/misc/qti-haptics.c
index 27ce7cf..a2c8e76 100644
--- a/drivers/input/misc/qti-haptics.c
+++ b/drivers/input/misc/qti-haptics.c
@@ -254,6 +254,11 @@
static int wf_repeat[8] = {1, 2, 4, 8, 16, 32, 64, 128};
static int wf_s_repeat[4] = {1, 2, 4, 8};
+static int twm_sys_enable;
+module_param_named(
+ haptics_twm, twm_sys_enable, int, 0600
+);
+
static inline bool is_secure(u8 addr)
{
return ((addr & 0xFF) > 0xD0);
@@ -2028,6 +2033,7 @@
{
struct qti_hap_chip *chip = dev_get_drvdata(&pdev->dev);
int rc;
+ bool enable_haptics_twm;
dev_dbg(chip->dev, "Shutdown!\n");
@@ -2043,7 +2049,9 @@
chip->vdd_enabled = false;
}
- if (chip->twm_state == PMIC_TWM_ENABLE && chip->haptics_ext_pin_twm) {
+ enable_haptics_twm = chip->haptics_ext_pin_twm && twm_sys_enable;
+
+ if (chip->twm_state == PMIC_TWM_ENABLE && enable_haptics_twm) {
rc = qti_haptics_twm_config(chip);
if (rc < 0)
pr_err("Haptics TWM config failed rc=%d\n", rc);
diff --git a/drivers/input/sensors/smi130/smi130_acc.c b/drivers/input/sensors/smi130/smi130_acc.c
index 4bffe51..3a667a0 100644
--- a/drivers/input/sensors/smi130/smi130_acc.c
+++ b/drivers/input/sensors/smi130/smi130_acc.c
@@ -6967,6 +6967,7 @@
{
if (false == client_data->acc_buffer_smi130_samples)
return;
+ mutex_lock(&client_data->acc_sensor_buff);
if (ts.tv_sec < client_data->max_buffer_time) {
if (client_data->acc_bufsample_cnt < SMI_ACC_MAXSAMPLE) {
client_data->smi130_acc_samplist[client_data->
@@ -6989,6 +6990,7 @@
smi130_acc_set_mode(client_data->smi130_acc_client,
SMI_ACC2X2_MODE_SUSPEND, 1);
}
+ mutex_unlock(&client_data->acc_sensor_buff);
}
#else
static void store_acc_boot_sample(struct smi130_acc_data *client_data,
@@ -7145,9 +7147,7 @@
smi130_acc->value = acc;
mutex_unlock(&smi130_acc->value_mutex);
}
- mutex_lock(&smi130_acc->acc_sensor_buff);
store_acc_boot_sample(smi130_acc, acc.x, acc.y, acc.z, ts);
- mutex_unlock(&smi130_acc->acc_sensor_buff);
smi130_set_cpu_idle_state(false);
return IRQ_HANDLED;
diff --git a/drivers/input/sensors/smi130/smi130_gyro_driver.c b/drivers/input/sensors/smi130/smi130_gyro_driver.c
index d8252fb..61b5933 100644
--- a/drivers/input/sensors/smi130/smi130_gyro_driver.c
+++ b/drivers/input/sensors/smi130/smi130_gyro_driver.c
@@ -1743,6 +1743,7 @@
{
if (false == client_data->gyro_buffer_smi130_samples)
return;
+ mutex_lock(&client_data->gyro_sensor_buff);
if (ts.tv_sec < client_data->max_buffer_time) {
if (client_data->gyro_bufsample_cnt < SMI_GYRO_MAXSAMPLE) {
client_data->smi130_gyro_samplist[client_data->
@@ -1766,6 +1767,7 @@
smi130_gyro_delay(5);
}
}
+ mutex_unlock(&client_data->gyro_sensor_buff);
}
#else
static void store_gyro_boot_sample(struct smi_gyro_client_data *client_data,
@@ -1918,10 +1920,8 @@
input_event(client_data->input, EV_MSC,
MSC_SCAN, gyro_data.dataz);
input_sync(client_data->input);
- mutex_lock(&client_data->gyro_sensor_buff);
store_gyro_boot_sample(client_data, gyro_data.datax,
gyro_data.datay, gyro_data.dataz, ts);
- mutex_unlock(&client_data->gyro_sensor_buff);
return IRQ_HANDLED;
}
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
index f501b5c..cd78249 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
@@ -1835,15 +1835,15 @@
*/
if (test_item > 0 && test_item < 5)
range_check = 0;
- dad->cmcp_test_items = test_item;
- dad->cmcp_range_check = range_check;
- dad->cmcp_force_calibrate = force_calibrate;
- parade_debug(dev, DEBUG_LEVEL_2,
- "%s: Item: %s, Range check: %s, Force calibrate: %s.\n",
- __func__,
- cmcp_test_case_array[test_item],
- cmcp_test_range_check_array[range_check],
- cmcp_test_force_cal_array[force_calibrate]);
+ dad->cmcp_test_items = test_item;
+ dad->cmcp_range_check = range_check;
+ dad->cmcp_force_calibrate = force_calibrate;
+ parade_debug(dev, DEBUG_LEVEL_2,
+ "%s: Item: %s, Range check: %s, Force calibrate: %s.\n",
+ __func__,
+ cmcp_test_case_array[test_item],
+ cmcp_test_range_check_array[range_check],
+ cmcp_test_force_cal_array[force_calibrate]);
error:
mutex_unlock(&dad->sysfs_lock);
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 28466e3..22c8d20 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -887,6 +887,7 @@
{
const struct edt_i2c_chip_data *chip_data;
struct edt_ft5x06_ts_data *tsdata;
+ u8 buf[2] = { 0xfc, 0x00 };
struct input_dev *input;
unsigned long irq_flags;
int error;
@@ -956,6 +957,12 @@
return error;
}
+ /*
+ * Dummy read access. EP0700MLP1 returns bogus data on the first
+ * register read access and ignores writes.
+ */
+ edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
+
edt_ft5x06_ts_set_regs(tsdata);
edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
edt_ft5x06_ts_get_parameters(tsdata);
diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index a99fb5c..1f5b6b5 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -441,7 +441,7 @@
return 0;
}
-static bool raydium_i2c_boot_trigger(struct i2c_client *client)
+static int raydium_i2c_boot_trigger(struct i2c_client *client)
{
static const u8 cmd[7][6] = {
{ 0x08, 0x0C, 0x09, 0x00, 0x50, 0xD7 },
@@ -469,7 +469,7 @@
return 0;
}
-static bool raydium_i2c_fw_trigger(struct i2c_client *client)
+static int raydium_i2c_fw_trigger(struct i2c_client *client)
{
static const u8 cmd[5][11] = {
{ 0, 0x09, 0x71, 0x0C, 0x09, 0x00, 0x50, 0xD7, 0, 0, 0 },
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 7bd9858..48d3820 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1103,7 +1103,8 @@
}
arm_smmu_sync_ste_for_sid(smmu, sid);
- dst[0] = cpu_to_le64(val);
+ /* See comment in arm_smmu_write_ctx_desc() */
+ WRITE_ONCE(dst[0], cpu_to_le64(val));
arm_smmu_sync_ste_for_sid(smmu, sid);
/* It's likely that we'll want to use the new STE soon */
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index d51734e..977070c 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -39,6 +39,7 @@
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/iommu.h>
+#include <linux/limits.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
@@ -138,6 +139,13 @@
BUG_ON(dev->is_virtfn);
+ /*
+ * Ignore devices that have a domain number higher than what can
+ * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
+ */
+ if (pci_domain_nr(dev->bus) > U16_MAX)
+ return NULL;
+
/* Only generate path[] for device addition event */
if (event == BUS_NOTIFY_ADD_DEVICE)
for (tmp = dev; tmp; tmp = tmp->bus->self)
@@ -450,12 +458,13 @@
/* Check for NUL termination within the designated length */
if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
+ pr_warn(FW_BUG
"Your BIOS is broken; ANDD object name is not NUL-terminated\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
return -EINVAL;
}
pr_info("ANDD device: %x name: %s\n", andd->device_number,
@@ -481,14 +490,14 @@
return 0;
}
}
- WARN_TAINT(
- 1, TAINT_FIRMWARE_WORKAROUND,
+ pr_warn(FW_BUG
"Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
- drhd->reg_base_addr,
+ rhsa->base_address,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
return 0;
}
@@ -834,14 +843,14 @@
static void warn_invalid_dmar(u64 addr, const char *message)
{
- WARN_TAINT_ONCE(
- 1, TAINT_FIRMWARE_WORKAROUND,
+ pr_warn_once(FW_BUG
"Your BIOS is broken; DMAR reported at address %llx%s!\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
addr, message,
dmi_get_system_info(DMI_BIOS_VENDOR),
dmi_get_system_info(DMI_BIOS_VERSION),
dmi_get_system_info(DMI_PRODUCT_VERSION));
+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
}
static int __ref
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 5c6e0a9f..593a4bf 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4085,10 +4085,11 @@
/* we know that the this iommu should be at offset 0xa000 from vtbar */
drhd = dmar_find_matched_drhd_unit(pdev);
- if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
- TAINT_FIRMWARE_WORKAROUND,
- "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
+ if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) {
+ pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n");
+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ }
}
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
@@ -5192,8 +5193,10 @@
u64 phys = 0;
pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
- if (pte)
- phys = dma_pte_addr(pte);
+ if (pte && dma_pte_present(pte))
+ phys = dma_pte_addr(pte) +
+ (iova & (BIT_MASK(level_to_offset_bits(level) +
+ VTD_PAGE_SHIFT) - 1));
return phys;
}
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0c0cd27..d1efbb8 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -365,7 +365,7 @@
struct its_cmd_desc *desc)
{
its_encode_cmd(cmd, GITS_CMD_INVALL);
- its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id);
+ its_encode_collection(cmd, desc->its_invall_cmd.col->col_id);
its_fixup_cmd(cmd);
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index f28e9ed..19215ce 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1637,6 +1637,7 @@
struct redist_region *redist_regs;
u32 nr_redist_regions;
bool single_redist;
+ int enabled_rdists;
u32 maint_irq;
int maint_irq_mode;
phys_addr_t vcpu_base;
@@ -1731,8 +1732,10 @@
* If GICC is enabled and has valid gicr base address, then it means
* GICR base is presented via GICC
*/
- if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
+ if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
+ acpi_data.enabled_rdists++;
return 0;
+ }
/*
* It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1762,8 +1765,10 @@
count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
gic_acpi_match_gicc, 0);
- if (count > 0)
+ if (count > 0) {
acpi_data.single_redist = true;
+ count = acpi_data.enabled_rdists;
+ }
return count;
}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f931a2c..c42c846 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -705,6 +705,15 @@
variable brightness. It also supports outputting the Avdd supply for
AMOLED displays.
+config LEDS_MSM_GPIO_FLASH
+ tristate "Support for GPIO Flash LEDs"
+ help
+ This driver supports the leds functionality of GPIO Flash LED. It
+ includes flash mode and torch mode.
+
+ To compile this driver as a module, choose M here: the module will
+ be called leds-gpio-flash.
+
config LEDS_QPNP_HAPTICS
tristate "Haptics support for QPNP PMIC"
depends on LEDS_CLASS && MFD_SPMI_PMIC
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 31d29f0..e53ef7e 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -61,6 +61,7 @@
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
+obj-$(CONFIG_LEDS_MSM_GPIO_FLASH) += leds-msm-gpio-flash.o
obj-$(CONFIG_LEDS_QTI_TRI_LED) += leds-qti-tri-led.o
obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
diff --git a/drivers/leds/leds-msm-gpio-flash.c b/drivers/leds/leds-msm-gpio-flash.c
new file mode 100644
index 0000000..6a5332e
--- /dev/null
+++ b/drivers/leds/leds-msm-gpio-flash.c
@@ -0,0 +1,516 @@
+/* Copyright (c) 2013-2014, 2017, 2020, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/list.h>
+#include <linux/clk/msm-clk.h>
+#include <linux/clk/msm-clk-provider.h>
+#include <linux/pinctrl/consumer.h>
+
+/* #define CONFIG_GPIO_FLASH_DEBUG */
+#undef CDBG
+#ifdef CONFIG_GPIO_FLASH_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+#define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
+#define LED_TRIGGER_DEFAULT "none"
+
+#define GPIO_OUT_LOW (0 << 1)
+#define GPIO_OUT_HIGH (1 << 1)
+
+#define DUTY_CYCLE_BASE 100
+
+enum msm_flash_seq_type_t {
+ FLASH_EN,
+ FLASH_NOW,
+};
+
+enum msm_flash_gpio_type_t {
+ NORMAL_GPIO,
+ CLK_GPIO,
+};
+
+struct msm_flash_ctrl_seq {
+ enum msm_flash_seq_type_t seq_type;
+ uint8_t flash_on_val;
+ uint8_t torch_on_val;
+};
+
+struct led_gpio_flash_data {
+ int flash_en;
+ int flash_now;
+ struct clk *flash_en_clk;
+ struct clk *flash_now_clk;
+ int brightness;
+ atomic_t clk_enabled[2];
+ uint32_t clk_freq[2];
+ uint32_t duty_cycle[2];
+ enum msm_flash_gpio_type_t gpio_type[2];
+ struct led_classdev cdev;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *gpio_state_default;
+ struct msm_flash_ctrl_seq ctrl_seq[2];
+};
+
+static const struct of_device_id led_gpio_flash_of_match[] = {
+ {.compatible = LED_GPIO_FLASH_DRIVER_NAME,},
+ {},
+};
+
+static void led_gpio_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ int rc = 0;
+ int brightness = value;
+ int flash_en = 0;
+ int flash_now = 0;
+ struct led_gpio_flash_data *flash_led =
+ container_of(led_cdev, struct led_gpio_flash_data, cdev);
+
+ if (brightness > LED_HALF) {
+ flash_en =
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val;
+ flash_now =
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val;
+ } else if (brightness > LED_OFF) {
+ flash_en =
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val;
+ flash_now =
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val;
+ } else {
+ flash_en = 0;
+ flash_now = 0;
+ }
+
+ CDBG("%s:flash_en=%d, flash_now=%d\n", __func__, flash_en, flash_now);
+
+ if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
+ rc = gpio_direction_output(flash_led->flash_en, flash_en);
+ } else {
+ if (flash_en == GPIO_OUT_HIGH &&
+ !atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
+ rc = clk_prepare_enable(flash_led->flash_en_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 1);
+ } else if (flash_en == GPIO_OUT_LOW &&
+ atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
+ clk_disable_unprepare(flash_led->flash_en_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
+ }
+ }
+
+ if (rc) {
+ pr_err("%s: Failed to set flash en.\n", __func__);
+ return;
+ }
+
+ if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
+ rc = gpio_direction_output(flash_led->flash_now, flash_now);
+ } else {
+ if (flash_now == GPIO_OUT_HIGH &&
+ !atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
+ rc = clk_prepare_enable(flash_led->flash_now_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 1);
+ } else if (flash_now == GPIO_OUT_LOW &&
+ atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
+ clk_disable_unprepare(flash_led->flash_now_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
+ }
+ }
+
+ if (rc) {
+ pr_err("%s: Failed to set flash now.\n", __func__);
+ return;
+ }
+
+ flash_led->brightness = brightness;
+}
+
+static enum led_brightness led_gpio_brightness_get(struct led_classdev
+ *led_cdev)
+{
+ struct led_gpio_flash_data *flash_led =
+ container_of(led_cdev, struct led_gpio_flash_data, cdev);
+ return flash_led->brightness;
+}
+
+static int led_gpio_get_dt_data(struct device *dev,
+ struct led_gpio_flash_data *flash_led)
+{
+ int rc = 0;
+ int i = 0;
+ const char *temp_str = NULL;
+ const char *seq_name = NULL;
+ uint32_t array_flash_seq[2];
+ uint32_t array_torch_seq[2];
+ struct device_node *node = dev->of_node;
+
+ flash_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
+ rc = of_property_read_string(node, "linux,default-trigger",
+ &temp_str);
+ if (!rc)
+ flash_led->cdev.default_trigger = temp_str;
+
+ rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
+ if (rc) {
+ pr_err("Failed to read linux name. rc = %d\n", rc);
+ return rc;
+ }
+
+ /* Configure the gpio type as NORMAL_GPIO by default,
+ * the gpio type should be CLK_GPIO if the frequency
+ * is not 0.
+ */
+ flash_led->gpio_type[FLASH_EN] = NORMAL_GPIO;
+ flash_led->gpio_type[FLASH_NOW] = NORMAL_GPIO;
+ rc = of_property_read_u32_array(node, "qcom,clk-freq",
+ flash_led->clk_freq, 2);
+ if (!rc) {
+ if (flash_led->clk_freq[FLASH_EN])
+ flash_led->gpio_type[FLASH_EN] = CLK_GPIO;
+
+ if (flash_led->clk_freq[FLASH_NOW])
+ flash_led->gpio_type[FLASH_NOW] = CLK_GPIO;
+ }
+
+ if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
+ flash_led->flash_en =
+ of_get_named_gpio(node, "qcom,flash-en", 0);
+ if (flash_led->flash_en < 0) {
+ pr_err("Read flash-en property failed. rc = %d\n",
+ flash_led->flash_en);
+ return -EINVAL;
+ }
+ rc = gpio_request(flash_led->flash_en, "FLASH_EN");
+ if (rc) {
+ pr_err("%s: Failed to request gpio %d,rc = %d\n",
+ __func__, flash_led->flash_en, rc);
+ return rc;
+ }
+ } else {
+ flash_led->flash_en_clk =
+ devm_clk_get(dev, "flash_en_clk");
+ if (IS_ERR(flash_led->flash_en_clk)) {
+ pr_err("Failed to get flash-en clk.\n");
+ return -EINVAL;
+ }
+
+ flash_led->clk_freq[FLASH_EN] =
+ clk_round_rate(flash_led->flash_en_clk,
+ flash_led->clk_freq[FLASH_EN]);
+ rc = clk_set_rate(flash_led->flash_en_clk,
+ flash_led->clk_freq[FLASH_EN]);
+ if (rc) {
+ pr_err("%s: Failed to set rate for flash en.\n",
+ __func__);
+ return rc;
+ }
+ }
+
+ if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
+ flash_led->flash_now =
+ of_get_named_gpio(node, "qcom,flash-now", 0);
+ if (flash_led->flash_now < 0) {
+ pr_err("Read flash-now property failed. rc = %d\n",
+ flash_led->flash_now);
+ return -EINVAL;
+ }
+ rc = gpio_request(flash_led->flash_now, "FLASH_NOW");
+ if (rc) {
+ pr_err("%s: Failed to request gpio %d,rc = %d\n",
+ __func__, flash_led->flash_now, rc);
+ return rc;
+ }
+ } else {
+ flash_led->flash_now_clk =
+ devm_clk_get(dev, "flash_now_clk");
+ if (IS_ERR(flash_led->flash_now_clk)) {
+ pr_err("Failed to get flash-now clk.\n");
+ return -EINVAL;
+ }
+
+ flash_led->clk_freq[FLASH_NOW] =
+ clk_round_rate(flash_led->flash_now_clk,
+ flash_led->clk_freq[FLASH_NOW]);
+ rc = clk_set_rate(flash_led->flash_now_clk,
+ flash_led->clk_freq[FLASH_NOW]);
+ if (rc) {
+ pr_err("%s: Failed to set rate for flash now.\n",
+ __func__);
+ return rc;
+ }
+ }
+
+ /* Configure the duty cycle if need. */
+ if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO ||
+ flash_led->gpio_type[FLASH_NOW] == CLK_GPIO) {
+ rc = of_property_read_u32_array(node, "qcom,duty-cycle",
+ flash_led->duty_cycle, 2);
+ if (!rc &&
+ flash_led->duty_cycle[FLASH_EN] >= DUTY_CYCLE_BASE &&
+ flash_led->duty_cycle[FLASH_NOW] >= DUTY_CYCLE_BASE) {
+ pr_err("%s: the duty cycle value is invalid.\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+ /* Based on clk protocol, only RCG clks support duty cycle
+ * configuration, so if the used clk doesn't support set duty
+ * cycle, we use the clk's parent rcg clk to configure the
+ * duty cycle.
+ */
+ if (flash_led->duty_cycle[FLASH_EN]) {
+ struct clk *flash_en_duty_cycle_clk = NULL;
+
+ flash_en_duty_cycle_clk = devm_clk_get(dev,
+ "flash_en_duty_cycle_clk");
+ if (!IS_ERR(flash_en_duty_cycle_clk)) {
+ rc = clk_set_duty_cycle(flash_en_duty_cycle_clk,
+ flash_led->duty_cycle[FLASH_EN],
+ DUTY_CYCLE_BASE);
+ clk_put(flash_en_duty_cycle_clk);
+ } else {
+ rc = clk_set_duty_cycle(flash_led->flash_en_clk,
+ flash_led->duty_cycle[FLASH_EN],
+ DUTY_CYCLE_BASE);
+ }
+
+ if (rc) {
+ pr_err("Failed to set duty cycle for flash en.\n");
+ return rc;
+ }
+ }
+
+ if (flash_led->duty_cycle[FLASH_NOW]) {
+ struct clk *flash_now_duty_cycle_clk = NULL;
+
+ flash_now_duty_cycle_clk = devm_clk_get(dev,
+ "flash_now_duty_cycle_clk");
+ if (!IS_ERR(flash_now_duty_cycle_clk)) {
+ rc = clk_set_duty_cycle(flash_now_duty_cycle_clk,
+ flash_led->duty_cycle[FLASH_NOW],
+ DUTY_CYCLE_BASE);
+ clk_put(flash_now_duty_cycle_clk);
+ } else {
+ rc = clk_set_duty_cycle(flash_led->flash_now_clk,
+ flash_led->duty_cycle[FLASH_NOW],
+ DUTY_CYCLE_BASE);
+ }
+
+ if (rc) {
+ pr_err("Failed to set duty cycle for flash now.\n");
+ return rc;
+ }
+ }
+
+ rc = of_property_read_u32_array(node, "qcom,flash-seq-val",
+ array_flash_seq, 2);
+ if (rc < 0) {
+ pr_err("Failed to get flash op seq, rc = %d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32_array(node, "qcom,torch-seq-val",
+ array_torch_seq, 2);
+ if (rc < 0) {
+ pr_err("Failed to get torch op seq, rc = %d\n", rc);
+ return rc;
+ }
+
+ pr_debug("%s: seq: flash: %d, %d torch:%d, %d\n", __func__,
+ array_flash_seq[0], array_flash_seq[1],
+ array_torch_seq[0], array_torch_seq[1]);
+
+ for (i = 0; i < 2; i++) {
+ rc = of_property_read_string_index(node,
+ "qcom,op-seq", i,
+ &seq_name);
+ CDBG("%s seq_name[%d] = %s\n", __func__, i,
+ seq_name);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ return rc;
+ }
+
+ if (!strcmp(seq_name, "flash_en")) {
+ flash_led->ctrl_seq[FLASH_EN].seq_type =
+ FLASH_EN;
+ CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+ i, flash_led->ctrl_seq[FLASH_EN].seq_type);
+ if (array_flash_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val =
+ GPIO_OUT_HIGH;
+
+ if (array_torch_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val =
+ GPIO_OUT_HIGH;
+ } else if (!strcmp(seq_name, "flash_now")) {
+ flash_led->ctrl_seq[FLASH_NOW].seq_type =
+ FLASH_NOW;
+ CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+ i, flash_led->ctrl_seq[FLASH_NOW].seq_type);
+ if (array_flash_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
+ GPIO_OUT_HIGH;
+
+ if (array_torch_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
+ GPIO_OUT_HIGH;
+ }
+ }
+
+ return rc;
+}
+
+static int led_gpio_flash_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ struct led_gpio_flash_data *flash_led = NULL;
+
+ flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
+ GFP_KERNEL);
+ if (flash_led == NULL)
+ return -ENOMEM;
+
+ flash_led->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(flash_led->pinctrl)) {
+ pr_err("%s:failed to get pinctrl\n", __func__);
+ rc = PTR_ERR(flash_led->pinctrl);
+ goto error;
+ }
+
+ flash_led->gpio_state_default = pinctrl_lookup_state(flash_led->pinctrl,
+ "flash_default");
+ if (IS_ERR(flash_led->gpio_state_default)) {
+ pr_err("%s:can not get active pinstate\n", __func__);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ rc = pinctrl_select_state(flash_led->pinctrl,
+ flash_led->gpio_state_default);
+ if (rc) {
+ pr_err("%s:set state failed!\n", __func__);
+ goto error;
+ }
+
+ rc = led_gpio_get_dt_data(&pdev->dev, flash_led);
+ if (rc) {
+ pr_err("%s: get device tree data failed.\n",
+ __func__);
+ goto error;
+ }
+
+ /* Add these atomic variables to make sure clk is disabled
+ * just after the clk has been enabled.
+ */
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
+
+ platform_set_drvdata(pdev, flash_led);
+ flash_led->cdev.max_brightness = LED_FULL;
+ flash_led->cdev.brightness_set = led_gpio_brightness_set;
+ flash_led->cdev.brightness_get = led_gpio_brightness_get;
+
+ rc = led_classdev_register(&pdev->dev, &flash_led->cdev);
+ if (rc) {
+ pr_err("%s: Failed to register led dev. rc = %d\n",
+ __func__, rc);
+ goto error;
+ }
+ pr_err("%s:probe successfully!\n", __func__);
+ return 0;
+
+error:
+ if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO &&
+ IS_ERR(flash_led->flash_en_clk))
+ devm_clk_put(&pdev->dev, flash_led->flash_en_clk);
+ else if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO &&
+ flash_led->flash_en)
+ gpio_free(flash_led->flash_en);
+
+ if (flash_led->gpio_type[FLASH_NOW] == CLK_GPIO &&
+ IS_ERR(flash_led->flash_now_clk))
+ devm_clk_put(&pdev->dev, flash_led->flash_now_clk);
+ else if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO &&
+ flash_led->flash_now)
+ gpio_free(flash_led->flash_now);
+
+ if (IS_ERR(flash_led->pinctrl))
+ devm_pinctrl_put(flash_led->pinctrl);
+
+ devm_kfree(&pdev->dev, flash_led);
+ return rc;
+}
+
+static int led_gpio_flash_remove(struct platform_device *pdev)
+{
+ struct led_gpio_flash_data *flash_led =
+ (struct led_gpio_flash_data *)platform_get_drvdata(pdev);
+ if (IS_ERR(flash_led->pinctrl))
+ devm_pinctrl_put(flash_led->pinctrl);
+ led_classdev_unregister(&flash_led->cdev);
+ devm_kfree(&pdev->dev, flash_led);
+ return 0;
+}
+
+static struct platform_driver led_gpio_flash_driver = {
+ .probe = led_gpio_flash_probe,
+ .remove = led_gpio_flash_remove,
+ .driver = {
+ .name = LED_GPIO_FLASH_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = led_gpio_flash_of_match,
+ }
+};
+
+static int __init led_gpio_flash_init(void)
+{
+ return platform_driver_register(&led_gpio_flash_driver);
+}
+
+static void __exit led_gpio_flash_exit(void)
+{
+ return platform_driver_unregister(&led_gpio_flash_driver);
+}
+
+late_initcall(led_gpio_flash_init);
+module_exit(led_gpio_flash_exit);
+
+MODULE_DESCRIPTION("QTI GPIO LEDs driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("leds:leds-msm-gpio-flash");
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h
index b935839..f483041 100644
--- a/drivers/md/bcache/bset.h
+++ b/drivers/md/bcache/bset.h
@@ -380,7 +380,8 @@
/* Bkey utility code */
-#define bset_bkey_last(i) bkey_idx((struct bkey *) (i)->d, (i)->keys)
+#define bset_bkey_last(i) bkey_idx((struct bkey *) (i)->d, \
+ (unsigned int)(i)->keys)
static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned idx)
{
diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c
index 4e7f6c0..b45f0b2 100644
--- a/drivers/md/dm-bow.c
+++ b/drivers/md/dm-bow.c
@@ -792,6 +792,7 @@
*/
original_type = br->type;
sector0 = backup_br->sector;
+ bc->trims_total -= range_size(backup_br);
if (backup_br->type == TRIMMED)
list_del(&backup_br->trimmed_list);
backup_br->type = br->type == SECTOR0_CURRENT ? SECTOR0_CURRENT
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index f3993a4..4dac4bb 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -2192,8 +2192,8 @@
static void stop_worker(struct cache *cache)
{
- cancel_delayed_work(&cache->waker);
- flush_workqueue(cache->wq);
+ cancel_delayed_work_sync(&cache->waker);
+ drain_workqueue(cache->wq);
}
static void requeue_deferred_cells(struct cache *cache)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
old mode 100644
new mode 100755
index a2d2ac2..e96c32d
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1464,7 +1464,6 @@
* - must do so here (in alloc_dev callchain) before queue is used
*/
md->queue->queuedata = md;
- md->queue->backing_dev_info->congested_data = md;
}
void dm_init_normal_md_queue(struct mapped_device *md)
@@ -1475,6 +1474,7 @@
/*
* Initialize aspects of queue that aren't relevant for blk-mq
*/
+ md->queue->backing_dev_info->congested_data = md;
md->queue->backing_dev_info->congested_fn = dm_any_congested;
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
}
@@ -1562,6 +1562,12 @@
goto bad;
dm_init_md_queue(md);
+ /*
+ * default to bio-based required ->make_request_fn until DM
+ * table is loaded and md->type established. If request-based
+ * table is loaded: blk-mq will override accordingly.
+ */
+ blk_queue_make_request(md->queue, dm_make_request);
md->disk = alloc_disk_node(1, numa_node_id);
if (!md->disk)
@@ -1860,7 +1866,6 @@
case DM_TYPE_BIO_BASED:
case DM_TYPE_DAX_BIO_BASED:
dm_init_normal_md_queue(md);
- blk_queue_make_request(md->queue, dm_make_request);
/*
* DM handles splitting bios as needed. Free the bio_split bioset
* since it won't be used (saves 1 process per bio-based DM device).
diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c
index 306d2e4..22729fd 100644
--- a/drivers/md/persistent-data/dm-space-map-common.c
+++ b/drivers/md/persistent-data/dm-space-map-common.c
@@ -382,6 +382,33 @@
return -ENOSPC;
}
+int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll,
+ dm_block_t begin, dm_block_t end, dm_block_t *b)
+{
+ int r;
+ uint32_t count;
+
+ do {
+ r = sm_ll_find_free_block(new_ll, begin, new_ll->nr_blocks, b);
+ if (r)
+ break;
+
+ /* double check this block wasn't used in the old transaction */
+ if (*b >= old_ll->nr_blocks)
+ count = 0;
+ else {
+ r = sm_ll_lookup(old_ll, *b, &count);
+ if (r)
+ break;
+
+ if (count)
+ begin = *b + 1;
+ }
+ } while (count);
+
+ return r;
+}
+
static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b,
int (*mutator)(void *context, uint32_t old, uint32_t *new),
void *context, enum allocation_event *ev)
diff --git a/drivers/md/persistent-data/dm-space-map-common.h b/drivers/md/persistent-data/dm-space-map-common.h
index b3078d5..8de63ce 100644
--- a/drivers/md/persistent-data/dm-space-map-common.h
+++ b/drivers/md/persistent-data/dm-space-map-common.h
@@ -109,6 +109,8 @@
int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result);
int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
dm_block_t end, dm_block_t *result);
+int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll,
+ dm_block_t begin, dm_block_t end, dm_block_t *result);
int sm_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count, enum allocation_event *ev);
int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev);
int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev);
diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c
index 32adf6b..bf4c5e2 100644
--- a/drivers/md/persistent-data/dm-space-map-disk.c
+++ b/drivers/md/persistent-data/dm-space-map-disk.c
@@ -167,8 +167,10 @@
enum allocation_event ev;
struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
- /* FIXME: we should loop round a couple of times */
- r = sm_ll_find_free_block(&smd->old_ll, smd->begin, smd->old_ll.nr_blocks, b);
+ /*
+ * Any block we allocate has to be free in both the old and current ll.
+ */
+ r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b);
if (r)
return r;
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
index 1d29771..967d8f2 100644
--- a/drivers/md/persistent-data/dm-space-map-metadata.c
+++ b/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -447,7 +447,10 @@
enum allocation_event ev;
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
- r = sm_ll_find_free_block(&smm->old_ll, smm->begin, smm->old_ll.nr_blocks, b);
+ /*
+ * Any block we allocate has to be free in both the old and current ll.
+ */
+ r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b);
if (r)
return r;
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 58eb62f..a018a76 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -423,10 +423,12 @@
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
{
+ struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
if (code->index > 0)
return -EINVAL;
- code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ code->code = mt9v032->format.code;
return 0;
}
@@ -434,7 +436,11 @@
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
{
- if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+ struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
+ if (fse->index >= 3)
+ return -EINVAL;
+ if (mt9v032->format.code != fse->code)
return -EINVAL;
fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index);
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 98fe080..a506ff4 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1419,6 +1419,7 @@
spin_unlock_bh(&ctx->lock);
atomic_set(&ctx_isp->process_bubble, 0);
+ atomic_set(&ctx_isp->bubble_sof_count, 0);
if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
/* if active and wait list are empty, return */
spin_lock_bh(&ctx->lock);
@@ -1686,6 +1687,7 @@
notify.req_id = req->request_id;
notify.error = CRM_KMD_ERR_BUBBLE;
ctx->ctx_crm_intf->notify_err(¬ify);
+ atomic_set(&ctx_isp->process_bubble, 1);
CAM_DBG(CAM_ISP, "Notify CRM about Bubble frame %lld",
ctx_isp->frame_id);
} else {
@@ -1741,8 +1743,20 @@
ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
+ atomic_inc(&ctx_isp->bubble_sof_count);
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
+
+ if (atomic_read(&ctx_isp->process_bubble) &&
+ (!list_empty(&ctx->active_req_list)) &&
+ (atomic_read(&ctx_isp->bubble_sof_count) <
+ CAM_ISP_CTX_BUBBLE_SOF_COUNT_MAX)) {
+ CAM_INFO(CAM_ISP,
+ "Processing bubble, bubble_sof_count :%u",
+ atomic_read(&ctx_isp->bubble_sof_count));
+ goto end;
+ }
+
/*
* Signal all active requests with error and move the all the active
* requests to free list
@@ -1762,8 +1776,11 @@
}
list_add_tail(&req->list, &ctx->free_req_list);
ctx_isp->active_req_cnt--;
+ atomic_set(&ctx_isp->bubble_sof_count, 0);
}
+ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
+end:
/* notify reqmgr with sof signal */
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
notify.link_hdl = ctx->link_hdl;
@@ -1786,8 +1803,6 @@
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
- ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
-
CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated);
@@ -2462,6 +2477,7 @@
start_isp.start_only = false;
atomic_set(&ctx_isp->process_bubble, 0);
+ atomic_set(&ctx_isp->bubble_sof_count, 0);
ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
@@ -2598,6 +2614,7 @@
ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
atomic_set(&ctx_isp->process_bubble, 0);
+ atomic_set(&ctx_isp->bubble_sof_count, 0);
CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u",
ctx->state, ctx->ctx_id);
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
index f96e6bd..c1cd00f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,6 +33,11 @@
*/
#define CAM_ISP_CTX_CFG_MAX 22
+/* Maximum allowed sof count in rdi only bubble state
+ * till buf_done is received for bubble req_id.
+ */
+#define CAM_ISP_CTX_BUBBLE_SOF_COUNT_MAX 3
+
/*
* Maximum entries in state monitoring array for error logging
*/
@@ -161,6 +166,8 @@
* @cam_isp_ctx_state_monitor: State monitoring array
* @rdi_only_context: Get context type information.
* true, if context is rdi only context
+ * @bubble_sof_count: Atomic variable to check if ctx has any sof's
+ * while processing bubble
*
*/
struct cam_isp_context {
@@ -186,6 +193,7 @@
struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
bool rdi_only_context;
+ atomic_t bubble_sof_count;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
index 78dd64c..3c4d6df 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -196,11 +196,12 @@
if (rc)
CAM_ERR(CAM_ISP, "CPAS0 unregistration failed rc=%d", rc);
- if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+ if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
rc = cam_cpas_unregister_client(soc_private->cpas_handle[1]);
if (rc)
CAM_ERR(CAM_ISP, "CPAS1 unregistration failed rc=%d",
rc);
+ }
rc = cam_vfe_release_platform_resource(soc_info);
if (rc < 0)
@@ -245,7 +246,7 @@
goto end;
}
- if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+ if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
rc = cam_cpas_start(soc_private->cpas_handle[1], &ahb_vote,
&axi_vote);
if (rc) {
@@ -253,6 +254,7 @@
rc = -EFAULT;
goto end;
}
+ }
rc = cam_soc_util_enable_platform_resource(soc_info, true,
CAM_TURBO_VOTE, true);
@@ -344,12 +346,13 @@
return rc;
}
- if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+ if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
rc = cam_cpas_stop(soc_private->cpas_handle[1]);
if (rc) {
CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
return rc;
}
+ }
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
index 185e060..e9998a7 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -450,13 +450,13 @@
break;
case CAM_FORMAT_NV21:
case CAM_FORMAT_NV12:
- if (plane_index < CAM_PACKET_MAX_PLANES)
- kmd_plane_size = plane_stride * slice_height;
+ if (plane_index < CAM_PACKET_MAX_PLANES)
+ kmd_plane_size = plane_stride * slice_height;
break;
case CAM_FORMAT_PD10:
- if (plane_index < CAM_PACKET_MAX_PLANES)
- kmd_plane_size = plane_stride * slice_height;
- break;
+ if (plane_index < CAM_PACKET_MAX_PLANES)
+ kmd_plane_size = plane_stride * slice_height;
+ break;
case CAM_FORMAT_UBWC_NV12:
case CAM_FORMAT_UBWC_NV12_4R:
case CAM_FORMAT_UBWC_TP10:
diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c
index b7892f3..5c4c3f0 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-hw.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c
@@ -14,8 +14,8 @@
#define MAX_SRC_WIDTH 2048
/* Reset & boot poll config */
-#define POLL_RST_MAX 50
-#define POLL_RST_DELAY_MS 20
+#define POLL_RST_MAX 500
+#define POLL_RST_DELAY_MS 2
enum bdisp_target_plan {
BDISP_RGB,
@@ -382,7 +382,7 @@
for (i = 0; i < POLL_RST_MAX; i++) {
if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE)
break;
- msleep(POLL_RST_DELAY_MS);
+ udelay(POLL_RST_DELAY_MS * 1000);
}
if (i == POLL_RST_MAX)
dev_err(bdisp->dev, "Reset timeout\n");
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 2547039..246795c 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -430,7 +430,7 @@
int ret, pipein, pipeout;
struct usb_host_interface *idesc;
- idesc = intf->altsetting;
+ idesc = intf->cur_altsetting;
if (idesc->desc.bNumEndpoints < 2)
return -ENODEV;
diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c
index 78809bb..a93fc18 100644
--- a/drivers/media/usb/b2c2/flexcop-usb.c
+++ b/drivers/media/usb/b2c2/flexcop-usb.c
@@ -511,6 +511,9 @@
return ret;
}
+ if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
switch (fc_usb->udev->speed) {
case USB_SPEED_LOW:
err("cannot handle USB speed because it is too slow.");
@@ -544,9 +547,6 @@
struct flexcop_device *fc = NULL;
int ret;
- if (intf->cur_altsetting->desc.bNumEndpoints < 1)
- return -ENODEV;
-
if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
err("out of memory\n");
return -ENOMEM;
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 563f690..4a5ea74 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -812,7 +812,7 @@
/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
- if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)
+ if (intf->cur_altsetting->desc.bNumEndpoints < rc_ep + 1)
return -ENODEV;
purb = usb_alloc_urb(0, GFP_KERNEL);
@@ -832,7 +832,7 @@
* Some devices like the Hauppauge NovaTD model 52009 use an interrupt
* endpoint, while others use a bulk one.
*/
- e = &intf->altsetting[0].endpoint[rc_ep].desc;
+ e = &intf->cur_altsetting->endpoint[rc_ep].desc;
if (usb_endpoint_dir_in(e)) {
if (usb_endpoint_xfer_bulk(e)) {
pipe = usb_rcvbulkpipe(d->udev, rc_ep);
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index 7ac3890..25871bc 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -3482,6 +3482,11 @@
return;
}
+ if (alt->desc.bNumEndpoints < 1) {
+ sd->gspca_dev.usb_err = -ENODEV;
+ return;
+ }
+
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
@@ -3607,6 +3612,11 @@
return;
}
+ if (alt->desc.bNumEndpoints < 1) {
+ sd->gspca_dev.usb_err = -ENODEV;
+ return;
+ }
+
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
index 6ac93d8..7d25552 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
@@ -293,6 +293,9 @@
return -EIO;
}
+ if (alt->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
if (err < 0)
@@ -317,11 +320,21 @@
static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
{
+ struct usb_interface_cache *intfc;
struct usb_host_interface *alt;
struct sd *sd = (struct sd *) gspca_dev;
+ intfc = gspca_dev->dev->actconfig->intf_cache[0];
+
+ if (intfc->num_altsetting < 2)
+ return -ENODEV;
+
+ alt = &intfc->altsetting[1];
+
+ if (alt->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
alt->endpoint[0].desc.wMaxPacketSize =
cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
@@ -334,6 +347,10 @@
struct usb_host_interface *alt;
struct sd *sd = (struct sd *) gspca_dev;
+ /*
+ * Existence of altsetting and endpoint was verified in
+ * stv06xx_isoc_init()
+ */
alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
index 8d785ed..cc88c059 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
@@ -198,6 +198,10 @@
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt)
return -ENODEV;
+
+ if (alt->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
/* If we don't have enough bandwidth use a lower framerate */
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index d5ed9d3..2a555b0 100644
--- a/drivers/media/usb/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -1455,6 +1455,9 @@
return -EIO;
}
+ if (alt->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
}
@@ -2638,6 +2641,7 @@
static int sd_isoc_init(struct gspca_dev *gspca_dev)
{
+ struct usb_interface_cache *intfc;
struct usb_host_interface *alt;
int max_packet_size;
@@ -2653,8 +2657,17 @@
break;
}
+ intfc = gspca_dev->dev->actconfig->intf_cache[0];
+
+ if (intfc->num_altsetting < 2)
+ return -ENODEV;
+
+ alt = &intfc->altsetting[1];
+
+ if (alt->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
- alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
return 0;
@@ -2677,6 +2690,9 @@
break;
}
+ /*
+ * Existence of altsetting and endpoint was verified in sd_isoc_init()
+ */
alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
if (packet_size <= min_packet_size)
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
index e56a49a..d8ce7d7 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -56,7 +56,7 @@
ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, index, NULL, 0, 0);
+ value, index, NULL, 0, USB_CTRL_GET_TIMEOUT);
if (ret < 0)
return ret;
}
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index d5347a2..94acf7c 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1411,6 +1411,11 @@
break;
if (forward == prev)
continue;
+ if (forward->chain.next || forward->chain.prev) {
+ uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+ "entity %d already in chain.\n", forward->id);
+ return -EINVAL;
+ }
switch (UVC_ENTITY_TYPE(forward)) {
case UVC_VC_EXTENSION_UNIT:
@@ -1492,6 +1497,13 @@
return -1;
}
+ if (term->chain.next || term->chain.prev) {
+ uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+ "entity %d already in chain.\n",
+ term->id);
+ return -EINVAL;
+ }
+
if (uvc_trace_param & UVC_TRACE_PROBE)
printk(" %d", term->id);
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index b6189a4..025822b 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -352,8 +352,11 @@
BUG_ON(dma->sglen);
if (dma->pages) {
- for (i = 0; i < dma->nr_pages; i++)
+ for (i = 0; i < dma->nr_pages; i++) {
+ if (dma->direction == DMA_FROM_DEVICE)
+ set_page_dirty_lock(dma->pages[i]);
put_page(dma->pages[i]);
+ }
kfree(dma->pages);
dma->pages = NULL;
}
diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
index 8f873866..86aab32 100644
--- a/drivers/mfd/da9062-core.c
+++ b/drivers/mfd/da9062-core.c
@@ -142,7 +142,7 @@
.name = "da9062-watchdog",
.num_resources = ARRAY_SIZE(da9062_wdt_resources),
.resources = da9062_wdt_resources,
- .of_compatible = "dlg,da9062-wdt",
+ .of_compatible = "dlg,da9062-watchdog",
},
{
.name = "da9062-thermal",
diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c
index 704e189..95d0f2d 100644
--- a/drivers/mfd/dln2.c
+++ b/drivers/mfd/dln2.c
@@ -729,6 +729,8 @@
const struct usb_device_id *usb_id)
{
struct usb_host_interface *hostif = interface->cur_altsetting;
+ struct usb_endpoint_descriptor *epin;
+ struct usb_endpoint_descriptor *epout;
struct device *dev = &interface->dev;
struct dln2_dev *dln2;
int ret;
@@ -738,12 +740,19 @@
hostif->desc.bNumEndpoints < 2)
return -ENODEV;
+ epin = &hostif->endpoint[0].desc;
+ epout = &hostif->endpoint[1].desc;
+ if (!usb_endpoint_is_bulk_out(epout))
+ return -ENODEV;
+ if (!usb_endpoint_is_bulk_in(epin))
+ return -ENODEV;
+
dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
if (!dln2)
return -ENOMEM;
- dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
- dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
+ dln2->ep_out = epout->bEndpointAddress;
+ dln2->ep_in = epin->bEndpointAddress;
dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
dln2->interface = interface;
usb_set_intfdata(interface, dln2);
diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c
index ee94080..dd20c3e 100644
--- a/drivers/mfd/rn5t618.c
+++ b/drivers/mfd/rn5t618.c
@@ -32,6 +32,7 @@
case RN5T618_WATCHDOGCNT:
case RN5T618_DCIRQ:
case RN5T618_ILIMDATAH ... RN5T618_AIN0DATAL:
+ case RN5T618_ADCCNT3:
case RN5T618_IR_ADC1 ... RN5T618_IR_ADC3:
case RN5T618_IR_GPR:
case RN5T618_IR_GPF:
diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c
index 494e263..b7ee804 100644
--- a/drivers/misc/altera-stapl/altera.c
+++ b/drivers/misc/altera-stapl/altera.c
@@ -2126,8 +2126,8 @@
return status;
}
-static int altera_get_note(u8 *p, s32 program_size,
- s32 *offset, char *key, char *value, int length)
+static int altera_get_note(u8 *p, s32 program_size, s32 *offset,
+ char *key, char *value, int keylen, int vallen)
/*
* Gets key and value of NOTE fields in the JBC file.
* Can be called in two modes: if offset pointer is NULL,
@@ -2184,7 +2184,7 @@
&p[note_table + (8 * i) + 4])];
if (value != NULL)
- strlcpy(value, value_ptr, length);
+ strlcpy(value, value_ptr, vallen);
}
}
@@ -2203,13 +2203,13 @@
strlcpy(key, &p[note_strings +
get_unaligned_be32(
&p[note_table + (8 * i)])],
- length);
+ keylen);
if (value != NULL)
strlcpy(value, &p[note_strings +
get_unaligned_be32(
&p[note_table + (8 * i) + 4])],
- length);
+ vallen);
*offset = i + 1;
}
@@ -2463,7 +2463,7 @@
__func__, (format_version == 2) ? "Jam STAPL" :
"pre-standardized Jam 1.1");
while (altera_get_note((u8 *)fw->data, fw->size,
- &offset, key, value, 256) == 0)
+ &offset, key, value, 32, 256) == 0)
printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
__func__, key, value);
}
diff --git a/drivers/misc/qcom-xr-smrtvwr-misc.c b/drivers/misc/qcom-xr-smrtvwr-misc.c
index fc8796f..fe3cdc8 100644
--- a/drivers/misc/qcom-xr-smrtvwr-misc.c
+++ b/drivers/misc/qcom-xr-smrtvwr-misc.c
@@ -32,7 +32,6 @@
struct regulator *reg1, *reg2, *reg3;
int dp3p3_en_gpio = 142;
int wcd_en_gpio = 93;
- int switch_gpio = 112;
int rgb_tck_oe_en_gpio = 108;
reg1 = devm_regulator_get(&pdev->dev, "pm660l_l6");
@@ -91,19 +90,6 @@
gpio_set_value(wcd_en_gpio, 1);
msleep(20);
- rc = gpio_request(switch_gpio, "1p8_en_gpio");
- if (rc) {
- pr_err("%s 1p8_switch_gpio request failed\n", __func__);
- goto gpio_switch_fail;
- }
- rc = gpio_direction_output(switch_gpio, 0);
- if (rc) {
- pr_err("%s 1p8_switch_gpio direction failed\n", __func__);
- goto gpio_switch_fail;
- }
- gpio_set_value(switch_gpio, 1);
- msleep(20);
-
rc = gpio_request(rgb_tck_oe_en_gpio, "rgb_tck_oe_en_gpio");
if (rc) {
pr_err("%s rgb_tck_oe_en_gpio request failed\n", __func__);
@@ -122,8 +108,6 @@
gpio_oe_en_fail:
gpio_free(rgb_tck_oe_en_gpio);
-gpio_switch_fail:
- gpio_free(switch_gpio);
gpiowcd_fail:
gpio_free(wcd_en_gpio);
gpio3p3_fail:
diff --git a/drivers/misc/tusb1064.c b/drivers/misc/tusb1064.c
index 234e21a..b9f40e9 100644
--- a/drivers/misc/tusb1064.c
+++ b/drivers/misc/tusb1064.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/delay.h>
+#include "tusb1064.h"
struct tusb1064 {
struct device *dev;
@@ -80,21 +81,23 @@
return 0;
}
-void tusb1064_flip(bool flip)
+void tusb1064_usb_event(bool flip)
{
if (pdata) {
if (flip) {
- pr_debug("%s flipping the switch\n", __func__);
- /*AUXn->SBU2, AUXp->SBU1*/
- tusb1064_write(pdata->i2c_client, 0x13, 0x2F);
+ if (standalone_mode)
+ tusb1064_write(pdata->i2c_client, 0x0A, 0x05);
+ else
+ tusb1064_write(pdata->i2c_client, 0x0A, 0x06);
} else {
- pr_debug("%s not flipping the switch\n", __func__);
- /*AUXn->SBU2, AUXp->SBU1*/
- tusb1064_write(pdata->i2c_client, 0x13, 0x1F);
+ if (standalone_mode)
+ tusb1064_write(pdata->i2c_client, 0x0A, 0x01);
+ else
+ tusb1064_write(pdata->i2c_client, 0x0A, 0x02);
}
}
}
-EXPORT_SYMBOL(tusb1064_flip);
+EXPORT_SYMBOL(tusb1064_usb_event);
static int tusb1064_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -140,19 +143,6 @@
goto fail;
pr_debug("%s setting SBU1 to AUXN, SBU2 to AUXP\n", __func__);
- /*AUXn->SBU2, AUXp->SBU1 */
- if (tusb1064_write(pdata->i2c_client, 0x13, 0x1F) < 0)
- goto fail;
- //tusb1064_write(pdata, 0x13, 0x01);//AUXn->SBU1, AUXp->SBU2
-
- /*Enable 4-lane DP */
- if (tusb1064_write(pdata->i2c_client, 0x10, 0x55) < 0)
- goto fail;
- /*Enable 4-lane DP */
- if (tusb1064_write(pdata->i2c_client, 0x11, 0x55) < 0)
- goto fail;
- //pr_err("setting SBU1 to AUXp and SBU2 to AUXN\n");
- //tusb1064_write(pdata, 0x13, 0x8F);//Enable 4-lane DP
}
tusb1064_read(pdata->i2c_client, 0x0A, buf, 2);
tusb1064_read(pdata->i2c_client, 0x13, buf, 2);
diff --git a/drivers/misc/tusb1064.h b/drivers/misc/tusb1064.h
new file mode 100644
index 0000000..effecdc
--- /dev/null
+++ b/drivers/misc/tusb1064.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __TUSB1064_H_
+#define __TUSB1064_H_
+
+void tusb1064_usb_event(bool flip);
+
+#endif /* __TUSB1064_H_ */
diff --git a/drivers/misc/vxr7200.c b/drivers/misc/vxr7200.c
index ad1c82c..7388ade 100644
--- a/drivers/misc/vxr7200.c
+++ b/drivers/misc/vxr7200.c
@@ -41,10 +41,8 @@
u32 led_drive_en1;
u32 led_drive_en2;
u32 display_1v8_en;
- u32 mipi_sw_1v8_en;
+ u32 mipi_switch_1v8_en;
u32 display_res1;
- u32 selab_gpio;
- u32 oenab_gpio;
bool gpioInit;
struct i2c_client *i2c_client;
@@ -104,6 +102,7 @@
goto error;
}
gpio_set_value(gpio, 1);
+ msleep(20);
pr_debug("%s vxr7200 gpio:%d set to high\n", __func__, gpio);
} else {
ret = gpio_direction_output(gpio, 1);
@@ -112,6 +111,7 @@
goto error;
}
gpio_set_value(gpio, 0);
+ msleep(20);
pr_debug("%s vxr7200 gpio:%d set to low\n", __func__, gpio);
}
return 0;
@@ -128,62 +128,54 @@
rc = turnGpio(pdata, pdata->vxr_3v3_en, "vxr_3v3_en", turnOn);
if (rc)
goto gpio1Fail;
- rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
- if (rc)
- goto gpio2Fail;
- rc = turnGpio(pdata, pdata->led_drive_en1,
- "led_drive_en1", turnOn);
- if (rc)
- goto gpio3Fail;
- rc = turnGpio(pdata, pdata->led_drive_en2,
- "led_drive_en2", turnOn);
- if (rc)
- goto gpio4Fail;
- rc = turnGpio(pdata, pdata->display_1v8_en,
- "disp_1v8_en", turnOn);
- if (rc)
- goto gpio5Fail;
- pdata->mipi_sw_1v8_en += 1100;
- rc = turnGpio(pdata, pdata->mipi_sw_1v8_en,
- "mipi_sw1v8_en", turnOn);
- if (rc)
- goto gpio6Fail;
+
rc = turnGpio(pdata, pdata->display_res1,
"display_res1", turnOn);
if (rc)
+ goto gpio2Fail;
+
+ rc = turnGpio(pdata, pdata->display_1v8_en,
+ "disp_1v8_en", turnOn);
+ if (rc)
+ goto gpio3Fail;
+
+ rc = turnGpio(pdata, pdata->mipi_switch_1v8_en,
+ "mipi_switch_1v8_en", turnOn);
+ if (rc)
+ goto gpio4Fail;
+
+ rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
+ if (rc)
+ goto gpio5Fail;
+
+ rc = turnGpio(pdata, pdata->led_drive_en1,
+ "led_drive_en1", turnOn);
+ if (rc)
+ goto gpio6Fail;
+
+ rc = turnGpio(pdata, pdata->led_drive_en2,
+ "led_drive_en2", turnOn);
+ if (rc)
goto gpio7Fail;
}
+ return;
gpio7Fail:
- gpio_free(pdata->display_res1);
-gpio6Fail:
- gpio_free(pdata->mipi_sw_1v8_en);
-gpio5Fail:
- gpio_free(pdata->display_1v8_en);
-gpio4Fail:
gpio_free(pdata->led_drive_en2);
-gpio3Fail:
+gpio6Fail:
gpio_free(pdata->led_drive_en1);
-gpio2Fail:
+gpio5Fail:
gpio_free(pdata->led_5v_en);
+gpio4Fail:
+ gpio_free(pdata->mipi_switch_1v8_en);
+gpio3Fail:
+ gpio_free(pdata->display_1v8_en);
+gpio2Fail:
+ gpio_free(pdata->display_res1);
gpio1Fail:
gpio_free(pdata->vxr_3v3_en);
}
-static void vxr7200_free_gpios(struct vxr7200 *pdata)
-{
- if (pdata) {
- gpio_free(pdata->vxr_3v3_en);
- gpio_free(pdata->led_5v_en);
- gpio_free(pdata->led_drive_en1);
- gpio_free(pdata->led_drive_en2);
- gpio_free(pdata->display_1v8_en);
- gpio_free(pdata->mipi_sw_1v8_en);
- gpio_free(pdata->display_res1);
- }
-}
-
-
static int vxr7200_parse_dt(struct device *dev,
struct vxr7200 *pdata)
{
@@ -225,10 +217,10 @@
rc = -EINVAL;
}
- pdata->mipi_sw_1v8_en =
+ pdata->mipi_switch_1v8_en =
of_get_named_gpio(np, "qcom,switch-power-gpio", 0);
- if (!gpio_is_valid(pdata->mipi_sw_1v8_en)) {
- pr_err("mipi_sw_1v8_en gpio not specified\n");
+ if (!gpio_is_valid(pdata->mipi_switch_1v8_en)) {
+ pr_err("mipi_switch_1v8_en gpio not specified\n");
rc = -EINVAL;
}
@@ -242,39 +234,15 @@
if (!rc)
vxr7200_set_gpios(pdata, true);
- pdata->selab_gpio = of_get_named_gpio(np, "qcom,selab-gpio", 0);
- if (!gpio_is_valid(pdata->selab_gpio)) {
- pr_err("selab_gpio gpio not specified\n");
- rc = -EINVAL;
- goto gpio_selab_fail;
- } else
- turnGpio(pdata, pdata->selab_gpio, "selab_gpio", 0);
-
- pdata->oenab_gpio = of_get_named_gpio(np, "qcom,oenab-gpio", 0);
- if (!gpio_is_valid(pdata->oenab_gpio)) {
- pr_err("oenab_gpio gpio not specified\n");
- rc = -EINVAL;
- goto gpio_oenab_fail;
- } else
- turnGpio(pdata, pdata->oenab_gpio, "oenab_gpio", 0);
-
if (!pdata->gpioInit)
pdata->gpioInit = true;
return rc;
-
-gpio_oenab_fail:
- gpio_free(pdata->oenab_gpio);
-gpio_selab_fail:
- gpio_free(pdata->selab_gpio);
- vxr7200_free_gpios(pdata);
- return rc;
}
static void vxr7200_display_pwr_enable_vregs(struct vxr7200 *pdata)
{
int rc = 0;
-
pdata->vddio = devm_regulator_get(pdata->dev, "pm660_l11");
rc = PTR_RET(pdata->vddio);
if (rc) {
@@ -286,12 +254,8 @@
pr_err("Load setting failed for vddio %s\n", __func__);
goto vddio_fail;
}
- rc = regulator_set_voltage(pdata->vddio, 1800000, 1800000);
- if (rc) {
- pr_err("Set voltage(vddio) fail, rc=%d %s\n", rc, __func__);
- goto vddio_fail;
- }
rc = regulator_enable(pdata->vddio);
+ msleep(20);
if (rc) {
pr_err("enable failed for vddio, rc=%d %s\n", rc, __func__);
goto vddio_fail;
@@ -308,16 +272,12 @@
pr_err("Load Setting failed for lab %s\n", __func__);
goto lab_fail;
}
- rc = regulator_set_voltage(pdata->lab, 4600000, 6000000);
- if (rc) {
- pr_err("Set voltage(lab) fail, rc=%d %s\n", rc, __func__);
- goto lab_fail;
- }
rc = regulator_enable(pdata->lab);
if (rc) {
pr_err("enable failed for lab, rc=%d %s\n", rc, __func__);
goto lab_fail;
}
+ msleep(20);
pdata->ibb = devm_regulator_get(pdata->dev, "lcdb_ncp");
rc = PTR_RET(pdata->ibb);
@@ -330,16 +290,12 @@
pr_err("Load Setting failed for ibb %s\n", __func__);
goto ibb_fail;
}
- rc = regulator_set_voltage(pdata->ibb, 4600000, 6000000);
- if (rc) {
- pr_err("Set voltage(ibb) fail, rc=%d %s\n", rc, __func__);
- goto ibb_fail;
- }
rc = regulator_enable(pdata->ibb);
if (rc) {
pr_err("enable failed for ibb, rc=%d %s\n", rc, __func__);
goto ibb_fail;
}
+ msleep(20);
return;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index c2df68e..279d5da 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1157,17 +1157,22 @@
* SPI protocol. Another is that when chipselect is released while
* the card returns BUSY status, the clock must issue several cycles
* with chipselect high before the card will stop driving its output.
+ *
+ * SPI_CS_HIGH means "asserted" here. In some cases like when using
+ * GPIOs for chip select, SPI_CS_HIGH is set but this will be logically
+ * inverted by gpiolib, so if we want to ascertain to drive it high
+ * we should toggle the default with an XOR as we do here.
*/
- host->spi->mode |= SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
if (spi_setup(host->spi) != 0) {
/* Just warn; most cards work without it. */
dev_warn(&host->spi->dev,
"can't change chip-select polarity\n");
- host->spi->mode &= ~SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
} else {
mmc_spi_readbytes(host, 18);
- host->spi->mode &= ~SPI_CS_HIGH;
+ host->spi->mode ^= SPI_CS_HIGH;
if (spi_setup(host->spi) != 0) {
/* Wot, we can't get the same setup we had before? */
dev_err(&host->spi->dev,
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
index 7f7af31..c354711 100644
--- a/drivers/mmc/host/sdhci-of-at91.c
+++ b/drivers/mmc/host/sdhci-of-at91.c
@@ -126,7 +126,8 @@
{
sdhci_reset(host, mask);
- if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ if ((host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ || mmc_gpio_get_cd(host->mmc) >= 0)
sdhci_at91_set_force_card_detect(host);
}
@@ -354,8 +355,11 @@
* detection procedure using the SDMCC_CD signal is bypassed.
* This bit is reset when a software reset for all command is performed
* so we need to implement our own reset function to set back this bit.
+ *
+ * WA: SAMA5D2 doesn't drive CMD if using CD GPIO line.
*/
- if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ if ((host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ || mmc_gpio_get_cd(host->mmc) >= 0)
sdhci_at91_set_force_card_detect(host);
pm_runtime_put_autosuspend(&pdev->dev);
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index b44c8d3..e7b177c 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -73,7 +73,7 @@
return 0;
for (pnum = 0; pnum < ubi->peb_count; pnum++) {
- if (test_bit(pnum, seen) && ubi->lookuptbl[pnum]) {
+ if (!test_bit(pnum, seen) && ubi->lookuptbl[pnum]) {
ubi_err(ubi, "self-check failed for PEB %d, fastmap didn't see it", pnum);
ret = -EINVAL;
}
@@ -1127,7 +1127,7 @@
struct rb_node *tmp_rb;
int ret, i, j, free_peb_count, used_peb_count, vol_count;
int scrub_peb_count, erase_peb_count;
- unsigned long *seen_pebs = NULL;
+ unsigned long *seen_pebs;
fm_raw = ubi->fm_buf;
memset(ubi->fm_buf, 0, ubi->fm_size);
@@ -1141,7 +1141,7 @@
dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID);
if (!dvbuf) {
ret = -ENOMEM;
- goto out_kfree;
+ goto out_free_avbuf;
}
avhdr = ubi_get_vid_hdr(avbuf);
@@ -1150,7 +1150,7 @@
seen_pebs = init_seen(ubi);
if (IS_ERR(seen_pebs)) {
ret = PTR_ERR(seen_pebs);
- goto out_kfree;
+ goto out_free_dvbuf;
}
spin_lock(&ubi->volumes_lock);
@@ -1318,7 +1318,7 @@
ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf);
if (ret) {
ubi_err(ubi, "unable to write vid_hdr to fastmap SB!");
- goto out_kfree;
+ goto out_free_seen;
}
for (i = 0; i < new_fm->used_blocks; i++) {
@@ -1340,7 +1340,7 @@
if (ret) {
ubi_err(ubi, "unable to write vid_hdr to PEB %i!",
new_fm->e[i]->pnum);
- goto out_kfree;
+ goto out_free_seen;
}
}
@@ -1350,7 +1350,7 @@
if (ret) {
ubi_err(ubi, "unable to write fastmap to PEB %i!",
new_fm->e[i]->pnum);
- goto out_kfree;
+ goto out_free_seen;
}
}
@@ -1360,10 +1360,13 @@
ret = self_check_seen(ubi, seen_pebs);
dbg_bld("fastmap written!");
-out_kfree:
- ubi_free_vid_buf(avbuf);
- ubi_free_vid_buf(dvbuf);
+out_free_seen:
free_seen(seen_pebs);
+out_free_dvbuf:
+ ubi_free_vid_buf(dvbuf);
+out_free_avbuf:
+ ubi_free_vid_buf(avbuf);
+
out:
return ret;
}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 91d8a48..1f8fbd7 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -71,11 +71,6 @@
};
#pragma pack()
-static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb)
-{
- return (struct arp_pkt *)skb_network_header(skb);
-}
-
/* Forward declaration */
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
bool strict_match);
@@ -574,10 +569,11 @@
spin_unlock(&bond->mode_lock);
}
-static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
+static struct slave *rlb_choose_channel(struct sk_buff *skb,
+ struct bonding *bond,
+ const struct arp_pkt *arp)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- struct arp_pkt *arp = arp_pkt(skb);
struct slave *assigned_slave, *curr_active_slave;
struct rlb_client_info *client_info;
u32 hash_index = 0;
@@ -674,8 +670,12 @@
*/
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
{
- struct arp_pkt *arp = arp_pkt(skb);
struct slave *tx_slave = NULL;
+ struct arp_pkt *arp;
+
+ if (!pskb_network_may_pull(skb, sizeof(*arp)))
+ return NULL;
+ arp = (struct arp_pkt *)skb_network_header(skb);
/* Don't modify or load balance ARPs that do not originate locally
* (e.g.,arrive via a bridge).
@@ -685,7 +685,7 @@
if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected rx channel */
- tx_slave = rlb_choose_channel(skb, bond);
+ tx_slave = rlb_choose_channel(skb, bond, arp);
if (tx_slave)
ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr);
netdev_dbg(bond->dev, "Server sent ARP Reply packet\n");
@@ -695,7 +695,7 @@
* When the arp reply is received the entry will be updated
* with the correct unicast address of the client.
*/
- rlb_choose_channel(skb, bond);
+ rlb_choose_channel(skb, bond, arp);
/* The ARP reply packets must be delayed so that
* they can cancel out the influence of the ARP request.
@@ -1371,26 +1371,31 @@
bool do_tx_balance = true;
u32 hash_index = 0;
const u8 *hash_start = NULL;
- struct ipv6hdr *ip6hdr;
skb_reset_mac_header(skb);
eth_data = eth_hdr(skb);
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
- const struct iphdr *iph = ip_hdr(skb);
+ const struct iphdr *iph;
if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) ||
- (iph->daddr == ip_bcast) ||
- (iph->protocol == IPPROTO_IGMP)) {
+ (!pskb_network_may_pull(skb, sizeof(*iph)))) {
+ do_tx_balance = false;
+ break;
+ }
+ iph = ip_hdr(skb);
+ if (iph->daddr == ip_bcast || iph->protocol == IPPROTO_IGMP) {
do_tx_balance = false;
break;
}
hash_start = (char *)&(iph->daddr);
hash_size = sizeof(iph->daddr);
- }
break;
- case ETH_P_IPV6:
+ }
+ case ETH_P_IPV6: {
+ const struct ipv6hdr *ip6hdr;
+
/* IPv6 doesn't really use broadcast mac address, but leave
* that here just in case.
*/
@@ -1407,7 +1412,11 @@
break;
}
- /* Additianally, DAD probes should not be tx-balanced as that
+ if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) {
+ do_tx_balance = false;
+ break;
+ }
+ /* Additionally, DAD probes should not be tx-balanced as that
* will lead to false positives for duplicate addresses and
* prevent address configuration from working.
*/
@@ -1417,17 +1426,26 @@
break;
}
- hash_start = (char *)&(ipv6_hdr(skb)->daddr);
- hash_size = sizeof(ipv6_hdr(skb)->daddr);
+ hash_start = (char *)&ip6hdr->daddr;
+ hash_size = sizeof(ip6hdr->daddr);
break;
- case ETH_P_IPX:
- if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) {
+ }
+ case ETH_P_IPX: {
+ const struct ipxhdr *ipxhdr;
+
+ if (pskb_network_may_pull(skb, sizeof(*ipxhdr))) {
+ do_tx_balance = false;
+ break;
+ }
+ ipxhdr = (struct ipxhdr *)skb_network_header(skb);
+
+ if (ipxhdr->ipx_checksum != IPX_NO_CHECKSUM) {
/* something is wrong with this packet */
do_tx_balance = false;
break;
}
- if (ipx_hdr(skb)->ipx_type != IPX_TYPE_NCP) {
+ if (ipxhdr->ipx_type != IPX_TYPE_NCP) {
/* The only protocol worth balancing in
* this family since it has an "ARP" like
* mechanism
@@ -1436,9 +1454,11 @@
break;
}
+ eth_data = eth_hdr(skb);
hash_start = (char *)eth_data->h_dest;
hash_size = ETH_ALEN;
break;
+ }
case ETH_P_ARP:
do_tx_balance = false;
if (bond_info->rlb_enabled)
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 453a2ea..94b37c6 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -621,7 +621,10 @@
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
slc_free_netdev(sl->dev);
+ /* do not call free_netdev before rtnl_unlock */
+ rtnl_unlock();
free_netdev(sl->dev);
+ return err;
err_exit:
rtnl_unlock();
diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c
index fdc6188..d8c1048 100644
--- a/drivers/net/can/spi/qti-can.c
+++ b/drivers/net/can/spi/qti-can.c
@@ -46,8 +46,8 @@
#define DRIVER_MODE_AMB 2
#define QUERY_FIRMWARE_TIMEOUT_MS 300
#define EUPGRADE 140
-#define TIME_OFFSET_MAX_THD 5
-#define TIME_OFFSET_MIN_THD -5
+#define TIME_OFFSET_MAX_THD 30
+#define TIME_OFFSET_MIN_THD -30
struct qti_can {
struct net_device **netdev;
@@ -326,7 +326,7 @@
if (ts_offset_corrected > 0) {
if (disp_disc_cntr == 1) {
dev_info(&priv_data->spidev->dev,
- "No of buff frames discarded is %lld\n",
+ "No of buff frames discarded is %d\n",
buff_frames_disc_cntr);
disp_disc_cntr = 0;
}
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
index 912dc09..905911f 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -199,6 +199,11 @@
static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *queue,
u16 command_id, bool capture)
{
+ if (unlikely(!queue->comp_ctx)) {
+ pr_err("Completion context is NULL\n");
+ return NULL;
+ }
+
if (unlikely(command_id >= queue->q_depth)) {
pr_err("command id is larger than the queue size. cmd_id: %u queue size %d\n",
command_id, queue->q_depth);
@@ -839,6 +844,24 @@
0);
}
+static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev)
+{
+ struct ena_admin_feature_rss_flow_hash_control *hash_key =
+ (ena_dev->rss).hash_key;
+
+ netdev_rss_key_fill(&hash_key->key, sizeof(hash_key->key));
+ /* The key is stored in the device in u32 array
+ * as well as the API requires the key to be passed in this
+ * format. Thus the size of our array should be divided by 4
+ */
+ hash_key->keys_num = sizeof(hash_key->key) / sizeof(u32);
+}
+
+int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev)
+{
+ return ena_dev->rss.hash_func;
+}
+
static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev)
{
struct ena_rss *rss = &ena_dev->rss;
@@ -2034,15 +2057,16 @@
switch (func) {
case ENA_ADMIN_TOEPLITZ:
- if (key_len > sizeof(hash_key->key)) {
- pr_err("key len (%hu) is bigger than the max supported (%zu)\n",
- key_len, sizeof(hash_key->key));
- return -EINVAL;
+ if (key) {
+ if (key_len != sizeof(hash_key->key)) {
+ pr_err("key len (%hu) doesn't equal the supported size (%zu)\n",
+ key_len, sizeof(hash_key->key));
+ return -EINVAL;
+ }
+ memcpy(hash_key->key, key, key_len);
+ rss->hash_init_val = init_val;
+ hash_key->keys_num = key_len >> 2;
}
-
- memcpy(hash_key->key, key, key_len);
- rss->hash_init_val = init_val;
- hash_key->keys_num = key_len >> 2;
break;
case ENA_ADMIN_CRC32:
rss->hash_init_val = init_val;
@@ -2079,7 +2103,11 @@
if (unlikely(rc))
return rc;
- rss->hash_func = get_resp.u.flow_hash_func.selected_func;
+ /* ffs() returns 1 in case the lsb is set */
+ rss->hash_func = ffs(get_resp.u.flow_hash_func.selected_func);
+ if (rss->hash_func)
+ rss->hash_func--;
+
if (func)
*func = rss->hash_func;
@@ -2366,6 +2394,8 @@
if (unlikely(rc))
goto err_hash_key;
+ ena_com_hash_key_fill_default_key(ena_dev);
+
rc = ena_com_hash_ctrl_init(ena_dev);
if (unlikely(rc))
goto err_hash_ctrl;
diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h
index 509d7b8..98b2ad2 100644
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -41,6 +41,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
+#include <linux/netdevice.h>
#include "ena_common_defs.h"
#include "ena_admin_defs.h"
@@ -622,6 +623,14 @@
*/
void ena_com_rss_destroy(struct ena_com_dev *ena_dev);
+/* ena_com_get_current_hash_function - Get RSS hash function
+ * @ena_dev: ENA communication layer struct
+ *
+ * Return the current hash function.
+ * @return: 0 or one of the ena_admin_hash_functions values.
+ */
+int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev);
+
/* ena_com_fill_hash_function - Fill RSS hash function
* @ena_dev: ENA communication layer struct
* @func: The hash function (Toeplitz or crc)
diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
index 06fd061..0ef0a7b 100644
--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
@@ -651,6 +651,28 @@
return ENA_HASH_KEY_SIZE;
}
+static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir)
+{
+ struct ena_com_dev *ena_dev = adapter->ena_dev;
+ int i, rc;
+
+ if (!indir)
+ return 0;
+
+ rc = ena_com_indirect_table_get(ena_dev, indir);
+ if (rc)
+ return rc;
+
+ /* Our internal representation of the indices is: even indices
+ * for Tx and uneven indices for Rx. We need to convert the Rx
+ * indices to be consecutive
+ */
+ for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++)
+ indir[i] = ENA_IO_RXQ_IDX_TO_COMBINED_IDX(indir[i]);
+
+ return rc;
+}
+
static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
u8 *hfunc)
{
@@ -659,11 +681,25 @@
u8 func;
int rc;
- rc = ena_com_indirect_table_get(adapter->ena_dev, indir);
+ rc = ena_indirection_table_get(adapter, indir);
if (rc)
return rc;
+ /* We call this function in order to check if the device
+ * supports getting/setting the hash function.
+ */
rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key);
+
+ if (rc) {
+ if (rc == -EOPNOTSUPP) {
+ key = NULL;
+ hfunc = NULL;
+ rc = 0;
+ }
+
+ return rc;
+ }
+
if (rc)
return rc;
@@ -715,6 +751,9 @@
}
switch (hfunc) {
+ case ETH_RSS_HASH_NO_CHANGE:
+ func = ena_com_get_current_hash_function(ena_dev);
+ break;
case ETH_RSS_HASH_TOP:
func = ENA_ADMIN_TOEPLITZ;
break;
@@ -819,6 +858,7 @@
.get_channels = ena_get_channels,
.get_tunable = ena_get_tunable,
.set_tunable = ena_set_tunable,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void ena_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
index 008f2d5..326c2e1 100644
--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
@@ -110,6 +110,8 @@
#define ENA_IO_TXQ_IDX(q) (2 * (q))
#define ENA_IO_RXQ_IDX(q) (2 * (q) + 1)
+#define ENA_IO_TXQ_IDX_TO_COMBINED_IDX(q) ((q) / 2)
+#define ENA_IO_RXQ_IDX_TO_COMBINED_IDX(q) (((q) - 1) / 2)
#define ENA_MGMNT_IRQ_IDX 0
#define ENA_IO_IRQ_FIRST_IDX 1
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index de4b5d2..17c0783 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1711,7 +1711,7 @@
int ret;
ndev = alloc_etherdev_mqs(sizeof(struct xgene_enet_pdata),
- XGENE_NUM_RX_RING, XGENE_NUM_TX_RING);
+ XGENE_NUM_TX_RING, XGENE_NUM_RX_RING);
if (!ndev)
return -ENOMEM;
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index e3b41af..6519dd3 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1983,6 +1983,9 @@
umac_reset(priv);
+ /* Disable the UniMAC RX/TX */
+ umac_enable_set(priv, CMD_RX_EN | CMD_TX_EN, 0);
+
/* We may have been suspended and never received a WOL event that
* would turn off MPD detection, take care of that now
*/
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index fbe3c2c..736e550 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -6439,13 +6439,13 @@
return -EINVAL;
if (netif_running(dev))
- bnxt_close_nic(bp, false, false);
+ bnxt_close_nic(bp, true, false);
dev->mtu = new_mtu;
bnxt_set_ring_params(bp);
if (netif_running(dev))
- return bnxt_open_nic(bp, false, false);
+ return bnxt_open_nic(bp, true, false);
return 0;
}
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index b73d9ba..96290b8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1806,10 +1806,10 @@
}
netif_carrier_off(netdev);
- netif_tx_disable(netdev);
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
for (i = 0; i < enic->wq_count; i++)
napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
+ netif_tx_disable(netdev);
if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
enic_dev_del_station_addr(enic);
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 8ed0fd8..74cb9b3 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -2225,15 +2225,16 @@
if (cr6set)
dmfe_cr6_user_set = cr6set;
- switch(mode) {
- case DMFE_10MHF:
+ switch (mode) {
+ case DMFE_10MHF:
case DMFE_100MHF:
case DMFE_10MFD:
case DMFE_100MFD:
case DMFE_1M_HPNA:
dmfe_media_mode = mode;
break;
- default:dmfe_media_mode = DMFE_AUTO;
+ default:
+ dmfe_media_mode = DMFE_AUTO;
break;
}
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index e750b5d..5f79e27 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -1813,8 +1813,8 @@
if (cr6set)
uli526x_cr6_user_set = cr6set;
- switch (mode) {
- case ULI526X_10MHF:
+ switch (mode) {
+ case ULI526X_10MHF:
case ULI526X_100MHF:
case ULI526X_10MFD:
case ULI526X_100MFD:
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 1b07c62..8df3239 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2470,15 +2470,15 @@
return -EINVAL;
}
- cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr);
+ cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs);
if (cycle > 0xFFFF) {
pr_err("Rx coalesced usec exceed hardware limitation\n");
return -EINVAL;
}
- cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr);
+ cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs);
if (cycle > 0xFFFF) {
- pr_err("Rx coalesced usec exceed hardware limitation\n");
+ pr_err("Tx coalesced usec exceed hardware limitation\n");
return -EINVAL;
}
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 60bd1b3..b665d27 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2688,13 +2688,17 @@
skb_dirtytx = tx_queue->skb_dirtytx;
while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
+ bool do_tstamp;
+
+ do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+ priv->hwts_tx_en;
frags = skb_shinfo(skb)->nr_frags;
/* When time stamping, one additional TxBD must be freed.
* Also, we need to dma_unmap_single() the TxPAL.
*/
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
+ if (unlikely(do_tstamp))
nr_txbds = frags + 2;
else
nr_txbds = frags + 1;
@@ -2708,7 +2712,7 @@
(lstatus & BD_LENGTH_MASK))
break;
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+ if (unlikely(do_tstamp)) {
next = next_txbd(bdp, base, tx_ring_size);
buflen = be16_to_cpu(next->length) +
GMAC_FCB_LEN + GMAC_TXPAL_LEN;
@@ -2718,7 +2722,7 @@
dma_unmap_single(priv->dev, be32_to_cpu(bdp->bufPtr),
buflen, DMA_TO_DEVICE);
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+ if (unlikely(do_tstamp)) {
struct skb_shared_hwtstamps shhwtstamps;
u64 *ns = (u64 *)(((uintptr_t)skb->data + 0x10) &
~0x7UL);
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index f2904af..bb6bc849 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2690,10 +2690,9 @@
/* For the case where the last mvneta_poll did not process all
* RX packets
*/
- rx_queue = fls(((cause_rx_tx >> 8) & 0xff));
-
cause_rx_tx |= port->cause_rx_tx;
+ rx_queue = fls(((cause_rx_tx >> 8) & 0xff));
if (rx_queue) {
rx_queue = rx_queue - 1;
if (pp->bm_priv)
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 8dc1f02..bebddb8 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -475,21 +475,47 @@
*/
/**
- * ks_rdreg8 - read 8 bit register from device
+ * ks_check_endian - Check whether endianness of the bus is correct
* @ks : The chip information
- * @offset: The register address
*
- * Read a 8bit register from the chip, returning the result
+ * The KS8851-16MLL EESK pin allows selecting the endianness of the 16bit
+ * bus. To maintain optimum performance, the bus endianness should be set
+ * such that it matches the endianness of the CPU.
*/
-static u8 ks_rdreg8(struct ks_net *ks, int offset)
+
+static int ks_check_endian(struct ks_net *ks)
{
- u16 data;
- u8 shift_bit = offset & 0x03;
- u8 shift_data = (offset & 1) << 3;
- ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit);
- iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
- data = ioread16(ks->hw_addr);
- return (u8)(data >> shift_data);
+ u16 cider;
+
+ /*
+ * Read CIDER register first, however read it the "wrong" way around.
+ * If the endian strap on the KS8851-16MLL in incorrect and the chip
+ * is operating in different endianness than the CPU, then the meaning
+ * of BE[3:0] byte-enable bits is also swapped such that:
+ * BE[3,2,1,0] becomes BE[1,0,3,2]
+ *
+ * Luckily for us, the byte-enable bits are the top four MSbits of
+ * the address register and the CIDER register is at offset 0xc0.
+ * Hence, by reading address 0xc0c0, which is not impacted by endian
+ * swapping, we assert either BE[3:2] or BE[1:0] while reading the
+ * CIDER register.
+ *
+ * If the bus configuration is correct, reading 0xc0c0 asserts
+ * BE[3:2] and this read returns 0x0000, because to read register
+ * with bottom two LSbits of address set to 0, BE[1:0] must be
+ * asserted.
+ *
+ * If the bus configuration is NOT correct, reading 0xc0c0 asserts
+ * BE[1:0] and this read returns non-zero 0x8872 value.
+ */
+ iowrite16(BE3 | BE2 | KS_CIDER, ks->hw_addr_cmd);
+ cider = ioread16(ks->hw_addr);
+ if (!cider)
+ return 0;
+
+ netdev_err(ks->netdev, "incorrect EESK endian strap setting\n");
+
+ return -EINVAL;
}
/**
@@ -508,22 +534,6 @@
}
/**
- * ks_wrreg8 - write 8bit register value to chip
- * @ks: The chip information
- * @offset: The register address
- * @value: The value to write
- *
- */
-static void ks_wrreg8(struct ks_net *ks, int offset, u8 value)
-{
- u8 shift_bit = (offset & 0x03);
- u16 value_write = (u16)(value << ((offset & 1) << 3));
- ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit);
- iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
- iowrite16(value_write, ks->hw_addr);
-}
-
-/**
* ks_wrreg16 - write 16bit register value to chip
* @ks: The chip information
* @offset: The register address
@@ -642,8 +652,7 @@
u16 reg_data = 0;
/* Regardless of bus width, 8 bit read should always work.*/
- reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF;
- reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8;
+ reg_data = ks_rdreg16(ks, KS_CCR);
/* addr/data bus are multiplexed */
ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
@@ -747,7 +756,7 @@
/* 1. set sudo DMA mode */
ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
- ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
/* 2. read prepend data */
/**
@@ -764,7 +773,7 @@
ks_inblk(ks, buf, ALIGN(len, 4));
/* 4. reset sudo DMA Mode */
- ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
}
/**
@@ -866,14 +875,17 @@
{
struct net_device *netdev = pw;
struct ks_net *ks = netdev_priv(netdev);
+ unsigned long flags;
u16 status;
+ spin_lock_irqsave(&ks->statelock, flags);
/*this should be the first in IRQ handler */
ks_save_cmd_reg(ks);
status = ks_rdreg16(ks, KS_ISR);
if (unlikely(!status)) {
ks_restore_cmd_reg(ks);
+ spin_unlock_irqrestore(&ks->statelock, flags);
return IRQ_NONE;
}
@@ -899,6 +911,7 @@
ks->netdev->stats.rx_over_errors++;
/* this should be the last in IRQ handler*/
ks_restore_cmd_reg(ks);
+ spin_unlock_irqrestore(&ks->statelock, flags);
return IRQ_HANDLED;
}
@@ -968,6 +981,7 @@
/* shutdown RX/TX QMU */
ks_disable_qmu(ks);
+ ks_disable_int(ks);
/* set powermode to soft power down to save power */
ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
@@ -997,13 +1011,13 @@
ks->txh.txw[1] = cpu_to_le16(len);
/* 1. set sudo-DMA mode */
- ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
+ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
/* 2. write status/lenth info */
ks_outblk(ks, ks->txh.txw, 4);
/* 3. write pkt data */
ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4));
/* 4. reset sudo-DMA mode */
- ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
+ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
/* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
/* 6. wait until TXQCR_METFE is auto-cleared */
@@ -1024,10 +1038,9 @@
{
netdev_tx_t retv = NETDEV_TX_OK;
struct ks_net *ks = netdev_priv(netdev);
+ unsigned long flags;
- disable_irq(netdev->irq);
- ks_disable_int(ks);
- spin_lock(&ks->statelock);
+ spin_lock_irqsave(&ks->statelock, flags);
/* Extra space are required:
* 4 byte for alignment, 4 for status/length, 4 for CRC
@@ -1041,9 +1054,7 @@
dev_kfree_skb(skb);
} else
retv = NETDEV_TX_BUSY;
- spin_unlock(&ks->statelock);
- ks_enable_int(ks);
- enable_irq(netdev->irq);
+ spin_unlock_irqrestore(&ks->statelock, flags);
return retv;
}
@@ -1568,6 +1579,10 @@
goto err_free;
}
+ err = ks_check_endian(ks);
+ if (err)
+ goto err_free;
+
netdev->irq = platform_get_irq(pdev, 0);
if ((int)netdev->irq < 0) {
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index ea44a24..11dd7c8 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -2313,7 +2313,7 @@
if (!str || !*str)
return -EINVAL;
while ((opt = strsep(&str, ",")) != NULL) {
- if (!strncmp(opt, "eee_timer:", 6)) {
+ if (!strncmp(opt, "eee_timer:", 10)) {
if (kstrtoint(opt + 10, 0, &eee_timer))
goto err;
}
diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index 323b3ac..d0cf971 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -948,7 +948,7 @@
if (lp->ctl_rspeed != 100)
my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
- if (!lp->ctl_rfduplx)
+ if (!lp->ctl_rfduplx)
my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
/* Update our Auto-Neg Advertisement Register */
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 5077c69..a9e8a73 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -784,11 +784,13 @@
{
int i;
- gtp->addr_hash = kmalloc(sizeof(struct hlist_head) * hsize, GFP_KERNEL);
+ gtp->addr_hash = kmalloc(sizeof(struct hlist_head) * hsize,
+ GFP_KERNEL | __GFP_NOWARN);
if (gtp->addr_hash == NULL)
return -ENOMEM;
- gtp->tid_hash = kmalloc(sizeof(struct hlist_head) * hsize, GFP_KERNEL);
+ gtp->tid_hash = kmalloc(sizeof(struct hlist_head) * hsize,
+ GFP_KERNEL | __GFP_NOWARN);
if (gtp->tid_hash == NULL)
goto err1;
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index c747ab6..6c0982a 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -251,6 +251,7 @@
} else {
kfree_skb(skb);
}
+ cond_resched();
}
}
@@ -443,19 +444,21 @@
struct ethhdr *ethh = eth_hdr(skb);
int ret = NET_XMIT_DROP;
- /* In this mode we dont care about multicast and broadcast traffic */
- if (is_multicast_ether_addr(ethh->h_dest)) {
- pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n",
- ntohs(skb->protocol));
- kfree_skb(skb);
- goto out;
- }
-
/* The ipvlan is a pseudo-L2 device, so the packets that we receive
* will have L2; which need to discarded and processed further
* in the net-ns of the main-device.
*/
if (skb_mac_header_was_set(skb)) {
+ /* In this mode we dont care about
+ * multicast and broadcast traffic */
+ if (is_multicast_ether_addr(ethh->h_dest)) {
+ pr_debug_ratelimited(
+ "Dropped {multi|broad}cast of type=[%x]\n",
+ ntohs(skb->protocol));
+ kfree_skb(skb);
+ goto out;
+ }
+
skb_pull(skb, sizeof(*ethh));
skb->mac_header = (typeof(skb->mac_header))~0U;
skb_reset_network_header(skb);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 72fb55c..72f37e5 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -217,7 +217,6 @@
static int ipvlan_open(struct net_device *dev)
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
- struct net_device *phy_dev = ipvlan->phy_dev;
struct ipvl_addr *addr;
if (ipvlan->port->mode == IPVLAN_MODE_L3 ||
@@ -229,7 +228,7 @@
list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_add(ipvlan, addr);
- return dev_uc_add(phy_dev, phy_dev->dev_addr);
+ return 0;
}
static int ipvlan_stop(struct net_device *dev)
@@ -241,8 +240,6 @@
dev_uc_unsync(phy_dev, dev);
dev_mc_unsync(phy_dev, dev);
- dev_uc_del(phy_dev, phy_dev->dev_addr);
-
list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_del(addr);
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index a48ed08..da8bf32 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -19,6 +19,7 @@
#include <net/genetlink.h>
#include <net/sock.h>
#include <net/gro_cells.h>
+#include <linux/if_arp.h>
#include <uapi/linux/if_macsec.h>
@@ -2871,6 +2872,11 @@
dev_uc_sync(real_dev, dev);
}
+static sci_t dev_to_sci(struct net_device *dev, __be16 port)
+{
+ return make_sci(dev->dev_addr, port);
+}
+
static int macsec_set_mac_address(struct net_device *dev, void *p)
{
struct macsec_dev *macsec = macsec_priv(dev);
@@ -2892,6 +2898,7 @@
out:
ether_addr_copy(dev->dev_addr, addr->sa_data);
+ macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES);
return 0;
}
@@ -2976,6 +2983,7 @@
static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
[IFLA_MACSEC_SCI] = { .type = NLA_U64 },
+ [IFLA_MACSEC_PORT] = { .type = NLA_U16 },
[IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 },
[IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 },
[IFLA_MACSEC_WINDOW] = { .type = NLA_U32 },
@@ -3160,11 +3168,6 @@
return false;
}
-static sci_t dev_to_sci(struct net_device *dev, __be16 port)
-{
- return make_sci(dev->dev_addr, port);
-}
-
static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
{
struct macsec_dev *macsec = macsec_priv(dev);
@@ -3217,6 +3220,8 @@
real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
if (!real_dev)
return -ENODEV;
+ if (real_dev->type != ARPHRD_ETHER)
+ return -EINVAL;
dev->priv_flags |= IFF_MACSEC;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index e2b3d3c..2948816 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -309,6 +309,8 @@
if (src)
dev_put(src->dev);
kfree_skb(skb);
+
+ cond_resched();
}
}
diff --git a/drivers/net/phy/mdio-bcm-iproc.c b/drivers/net/phy/mdio-bcm-iproc.c
index 46fe1ae..51ce3ea 100644
--- a/drivers/net/phy/mdio-bcm-iproc.c
+++ b/drivers/net/phy/mdio-bcm-iproc.c
@@ -188,6 +188,23 @@
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+int iproc_mdio_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iproc_mdio_priv *priv = platform_get_drvdata(pdev);
+
+ /* restore the mii clock configuration */
+ iproc_mdio_config_clk(priv->base);
+
+ return 0;
+}
+
+static const struct dev_pm_ops iproc_mdio_pm_ops = {
+ .resume = iproc_mdio_resume
+};
+#endif /* CONFIG_PM_SLEEP */
+
static const struct of_device_id iproc_mdio_of_match[] = {
{ .compatible = "brcm,iproc-mdio", },
{ /* sentinel */ },
@@ -198,6 +215,9 @@
.driver = {
.name = "iproc-mdio",
.of_match_table = iproc_mdio_of_match,
+#ifdef CONFIG_PM_SLEEP
+ .pm = &iproc_mdio_pm_ops,
+#endif
},
.probe = iproc_mdio_probe,
.remove = iproc_mdio_remove,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 487d037..2f55873 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -80,7 +80,7 @@
static DEFINE_MUTEX(phy_fixup_lock);
#ifdef CONFIG_PM
-static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend)
+static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{
struct device_driver *drv = phydev->mdio.dev.driver;
struct phy_driver *phydrv = to_phy_driver(drv);
@@ -92,11 +92,10 @@
/* PHY not attached? May suspend if the PHY has not already been
* suspended as part of a prior call to phy_disconnect() ->
* phy_detach() -> phy_suspend() because the parent netdev might be the
- * MDIO bus driver and clock gated at this point. Also may resume if
- * PHY is not attached.
+ * MDIO bus driver and clock gated at this point.
*/
if (!netdev)
- return suspend ? !phydev->suspended : phydev->suspended;
+ goto out;
/* Don't suspend PHY if the attached netdev parent may wakeup.
* The parent may point to a PCI device, as in tg3 driver.
@@ -111,7 +110,8 @@
if (device_may_wakeup(&netdev->dev))
return false;
- return true;
+out:
+ return !phydev->suspended;
}
static int mdio_bus_phy_suspend(struct device *dev)
@@ -126,9 +126,11 @@
if (phydev->attached_dev && phydev->adjust_link)
phy_stop_machine(phydev);
- if (!mdio_bus_phy_may_suspend(phydev, true))
+ if (!mdio_bus_phy_may_suspend(phydev))
return 0;
+ phydev->suspended_by_mdio_bus = true;
+
return phy_suspend(phydev);
}
@@ -137,9 +139,11 @@
struct phy_device *phydev = to_phy_device(dev);
int ret;
- if (!mdio_bus_phy_may_suspend(phydev, false))
+ if (!phydev->suspended_by_mdio_bus)
goto no_resume;
+ phydev->suspended_by_mdio_bus = false;
+
ret = phy_resume(phydev);
if (ret < 0)
return ret;
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c
index 6d8e06e0..a27ecd6 100644
--- a/drivers/net/ppp/ppp_async.c
+++ b/drivers/net/ppp/ppp_async.c
@@ -878,15 +878,15 @@
skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
if (!skb)
goto nomem;
- ap->rpkt = skb;
- }
- if (skb->len == 0) {
- /* Try to get the payload 4-byte aligned.
- * This should match the
- * PPP_ALLSTATIONS/PPP_UI/compressed tests in
- * process_input_packet, but we do not have
- * enough chars here to test buf[1] and buf[2].
- */
+ ap->rpkt = skb;
+ }
+ if (skb->len == 0) {
+ /* Try to get the payload 4-byte aligned.
+ * This should match the
+ * PPP_ALLSTATIONS/PPP_UI/compressed tests in
+ * process_input_packet, but we do not have
+ * enough chars here to test buf[1] and buf[2].
+ */
if (buf[0] != PPP_ALLSTATIONS)
skb_reserve(skb, 2 + (buf[0] & 1));
}
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
index ddceed3..a516470 100644
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -232,7 +232,7 @@
register struct cstate *cs = lcs->next;
register unsigned long deltaS, deltaA;
register short changes = 0;
- int hlen;
+ int nlen, hlen;
unsigned char new_seq[16];
register unsigned char *cp = new_seq;
struct iphdr *ip;
@@ -248,6 +248,8 @@
return isize;
ip = (struct iphdr *) icp;
+ if (ip->version != 4 || ip->ihl < 5)
+ return isize;
/* Bail if this packet isn't TCP, or is an IP fragment */
if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) {
@@ -258,10 +260,14 @@
comp->sls_o_tcp++;
return isize;
}
- /* Extract TCP header */
+ nlen = ip->ihl * 4;
+ if (isize < nlen + sizeof(*th))
+ return isize;
- th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4);
- hlen = ip->ihl*4 + th->doff*4;
+ th = (struct tcphdr *)(icp + nlen);
+ if (th->doff < sizeof(struct tcphdr) / 4)
+ return isize;
+ hlen = nlen + th->doff * 4;
/* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or
* some other control bit is set). Also uncompressible if
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index 2af09c3..cc84112 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -868,7 +868,6 @@
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
sl_free_netdev(sl->dev);
- free_netdev(sl->dev);
err_exit:
rtnl_unlock();
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index fd2573c..d0c18e3 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2216,6 +2216,8 @@
[TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG },
[TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 },
[TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY },
+ [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 },
+ [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 },
};
static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 134c59c..fbd8ffe 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1106,6 +1106,13 @@
}
}
+static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile)
+{
+ struct sock *sk = tfile->socket.sk;
+
+ return (tun->dev->flags & IFF_UP) && sock_writeable(sk);
+}
+
/* Character device part */
/* Poll */
@@ -1128,10 +1135,14 @@
if (!skb_array_empty(&tfile->tx_array))
mask |= POLLIN | POLLRDNORM;
- if (tun->dev->flags & IFF_UP &&
- (sock_writeable(sk) ||
- (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
- sock_writeable(sk))))
+ /* Make sure SOCKWQ_ASYNC_NOSPACE is set if not writable to
+ * guarantee EPOLLOUT to be raised by either here or
+ * tun_sock_write_space(). Then process could get notification
+ * after it writes to a down device and meets -EIO.
+ */
+ if (tun_sock_writeable(tun, tfile) ||
+ (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+ tun_sock_writeable(tun, tfile)))
mask |= POLLOUT | POLLWRNORM;
if (tun->dev->reg_state != NETREG_REGISTERED)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index de7b431..97f6b81 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -951,6 +951,7 @@
{QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */
{QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */
{QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */
+ {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */
{QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
{QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ba7cfc0..6e74965 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3423,7 +3423,10 @@
if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
AUTOLOAD_DONE)
break;
+
msleep(20);
+ if (test_bit(RTL8152_UNPLUG, &tp->flags))
+ break;
}
for (i = 0; i < 500; i++) {
@@ -3447,7 +3450,10 @@
ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK;
if (ocp_data == PHY_STAT_LAN_ON)
break;
+
msleep(20);
+ if (test_bit(RTL8152_UNPLUG, &tp->flags))
+ break;
}
usb_disable_lpm(tp->udev);
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 987bb1d..bc4542d 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2354,10 +2354,19 @@
/* Setup stats when device is created */
static int vxlan_init(struct net_device *dev)
{
+ struct vxlan_dev *vxlan = netdev_priv(dev);
+ int err;
+
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!dev->tstats)
return -ENOMEM;
+ err = gro_cells_init(&vxlan->gro_cells, dev);
+ if (err) {
+ free_percpu(dev->tstats);
+ return err;
+ }
+
return 0;
}
@@ -2623,8 +2632,6 @@
vxlan->dev = dev;
- gro_cells_init(&vxlan->gro_cells, dev);
-
for (h = 0; h < FDB_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
}
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index af85a1b..87bf05a 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -209,6 +209,11 @@
ret = -ENOMEM;
goto free_riptr;
}
+ if (riptr != (u16)riptr || tiptr != (u16)tiptr) {
+ dev_err(priv->dev, "MURAM allocation out of addressable range\n");
+ ret = -ENOMEM;
+ goto free_tiptr;
+ }
/* Set RIPTR, TIPTR */
iowrite16be(riptr, &priv->ucc_pram->riptr);
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index e7bbdb7..97968e6 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -261,7 +261,7 @@
struct hss_plat_info *plat;
buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS];
struct desc *desc_tab; /* coherent */
- u32 desc_tab_phys;
+ dma_addr_t desc_tab_phys;
unsigned int id;
unsigned int clock_type, clock_rate, loopback;
unsigned int initialized, carrier;
@@ -861,7 +861,7 @@
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
- memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
+ memcpy_swab32(mem, (u32 *)((uintptr_t)skb->data & ~3), bytes / 4);
dev_kfree_skb(skb);
#endif
diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c
index 83770d2..9da8bd7 100644
--- a/drivers/net/wireless/broadcom/b43legacy/main.c
+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
@@ -1304,8 +1304,9 @@
}
/* Interrupt handler bottom-half */
-static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
+static void b43legacy_interrupt_tasklet(unsigned long data)
{
+ struct b43legacy_wldev *dev = (struct b43legacy_wldev *)data;
u32 reason;
u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
u32 merged_dma_reason = 0;
@@ -3775,7 +3776,7 @@
b43legacy_set_status(wldev, B43legacy_STAT_UNINIT);
wldev->bad_frames_preempt = modparam_bad_frames_preempt;
tasklet_init(&wldev->isr_tasklet,
- (void (*)(unsigned long))b43legacy_interrupt_tasklet,
+ b43legacy_interrupt_tasklet,
(unsigned long)wldev);
if (modparam_pio)
wldev->__using_pio = true;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index de52d82..998a4bd 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1921,6 +1921,7 @@
BRCMF_SDIO_FT_NORMAL)) {
rd->len = 0;
brcmu_pkt_buf_free_skb(pkt);
+ continue;
}
bus->sdcnt.rx_readahead_cnt++;
if (rd->len != roundup(rd_new.len, 16)) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index 05df9d8..31727f3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -438,6 +438,7 @@
usb_free_urb(req->urb);
list_del(q->next);
}
+ kfree(reqs);
return NULL;
}
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index bfa542c..86c84b1 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -3220,8 +3220,9 @@
}
}
-static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
+static void ipw2100_irq_tasklet(unsigned long data)
{
+ struct ipw2100_priv *priv = (struct ipw2100_priv *)data;
struct net_device *dev = priv->net_dev;
unsigned long flags;
u32 inta, tmp;
@@ -6029,7 +6030,7 @@
spin_unlock_irqrestore(&priv->low_lock, flags);
}
-static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
+static void ipw2100_irq_tasklet(unsigned long data);
static const struct net_device_ops ipw2100_netdev_ops = {
.ndo_open = ipw2100_open,
@@ -6158,7 +6159,7 @@
INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
INIT_DELAYED_WORK(&priv->scan_event, ipw2100_scan_event);
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ tasklet_init(&priv->irq_tasklet,
ipw2100_irq_tasklet, (unsigned long)priv);
/* NOTE: We do not start the deferred work for status checks yet */
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index bfd6861..48edb2b 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -1968,8 +1968,9 @@
wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
}
-static void ipw_irq_tasklet(struct ipw_priv *priv)
+static void ipw_irq_tasklet(unsigned long data)
{
+ struct ipw_priv *priv = (struct ipw_priv *)data;
u32 inta, inta_mask, handled = 0;
unsigned long flags;
int rc = 0;
@@ -10705,7 +10706,7 @@
INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
#endif /* CONFIG_IPW2200_QOS */
- tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ tasklet_init(&priv->irq_tasklet,
ipw_irq_tasklet, (unsigned long)priv);
return ret;
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index 466912e..d853ccb 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -1399,8 +1399,9 @@
}
static void
-il3945_irq_tasklet(struct il_priv *il)
+il3945_irq_tasklet(unsigned long data)
{
+ struct il_priv *il = (struct il_priv *)data;
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
@@ -3432,7 +3433,7 @@
setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il);
tasklet_init(&il->irq_tasklet,
- (void (*)(unsigned long))il3945_irq_tasklet,
+ il3945_irq_tasklet,
(unsigned long)il);
}
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index a91d170..6c2dcd2 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -4361,8 +4361,9 @@
}
static void
-il4965_irq_tasklet(struct il_priv *il)
+il4965_irq_tasklet(unsigned long data)
{
+ struct il_priv *il = (struct il_priv *)data;
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
@@ -6260,7 +6261,7 @@
setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il);
tasklet_init(&il->irq_tasklet,
- (void (*)(unsigned long))il4965_irq_tasklet,
+ il4965_irq_tasklet,
(unsigned long)il);
}
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 140b6ea..db2373f 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -717,7 +717,7 @@
u32 gp = _il_rd(il, CSR_EEPROM_GP);
int sz;
int ret;
- u16 addr;
+ int addr;
/* allocate eeprom */
sz = il->cfg->eeprom_size;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index c520356..f0f205c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -736,7 +736,8 @@
static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
{
int i;
- char name[] = "iwlwifi";
+ char name[16];
+ static atomic_t counter = ATOMIC_INIT(0);
if (!iwl_mvm_is_tt_in_fw(mvm)) {
mvm->tz_device.tzone = NULL;
@@ -746,6 +747,7 @@
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
+ sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
mvm->tz_device.tzone = thermal_zone_device_register(name,
IWL_MAX_DTS_TRIPS,
IWL_WRITABLE_TRIPS_MSK,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index a2ebe46..395bbe2 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -898,9 +898,13 @@
return err;
}
def_rxq = trans_pcie->rxq;
- if (!rba->alloc_wq)
+ if (!rba->alloc_wq) {
rba->alloc_wq = alloc_workqueue("rb_allocator",
WQ_HIGHPRI | WQ_UNBOUND, 1);
+ if (!rba->alloc_wq)
+ return -ENOMEM;
+ }
+
INIT_WORK(&rba->rx_alloc, iwl_pcie_rx_allocator_work);
cancel_work_sync(&rba->rx_alloc);
diff --git a/drivers/net/wireless/intersil/hostap/hostap_ap.c b/drivers/net/wireless/intersil/hostap/hostap_ap.c
index c995ace..30171d4 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_ap.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_ap.c
@@ -2570,7 +2570,7 @@
sta->supported_rates[0] = 2;
if (sta->tx_supp_rates & WLAN_RATE_2M)
sta->supported_rates[1] = 4;
- if (sta->tx_supp_rates & WLAN_RATE_5M5)
+ if (sta->tx_supp_rates & WLAN_RATE_5M5)
sta->supported_rates[2] = 11;
if (sta->tx_supp_rates & WLAN_RATE_11M)
sta->supported_rates[3] = 22;
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
index 8244d82..4e91c74 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
@@ -1351,7 +1351,8 @@
int retval;
BUG_ON(in_interrupt());
- BUG_ON(!upriv);
+ if (!upriv)
+ return -EINVAL;
upriv->reply_count = 0;
/* Write the MAGIC number on the simulated registers to keep
diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c
index 3eab802..ece6d72 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -1859,6 +1859,8 @@
rates_max = rates_eid[1];
if (rates_max > MAX_RATES) {
lbs_deb_join("invalid rates");
+ rcu_read_unlock();
+ ret = -EINVAL;
goto out;
}
rates = cmd.bss.rates;
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 828c6f5..5fde2e2 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2878,6 +2878,13 @@
vs_param_set->header.len =
cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
& 0x00FF) + 2);
+ if (le16_to_cpu(vs_param_set->header.len) >
+ MWIFIEX_MAX_VSIE_LEN) {
+ mwifiex_dbg(priv->adapter, ERROR,
+ "Invalid param length!\n");
+ break;
+ }
+
memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
le16_to_cpu(vs_param_set->header.len));
*buffer += le16_to_cpu(vs_param_set->header.len) +
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index be3be7a..f2d10ba 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -274,6 +274,7 @@
if (country_ie_len >
(IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) {
+ rcu_read_unlock();
mwifiex_dbg(priv->adapter, ERROR,
"11D: country_ie_len overflow!, deauth AP\n");
return -EINVAL;
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index df9704de0..c6fc09d 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -917,59 +917,117 @@
switch (*pos) {
case WLAN_EID_SUPP_RATES:
+ if (pos[1] > 32)
+ return;
sta_ptr->tdls_cap.rates_len = pos[1];
for (i = 0; i < pos[1]; i++)
sta_ptr->tdls_cap.rates[i] = pos[i + 2];
break;
case WLAN_EID_EXT_SUPP_RATES:
+ if (pos[1] > 32)
+ return;
basic = sta_ptr->tdls_cap.rates_len;
+ if (pos[1] > 32 - basic)
+ return;
for (i = 0; i < pos[1]; i++)
sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
sta_ptr->tdls_cap.rates_len += pos[1];
break;
case WLAN_EID_HT_CAPABILITY:
- memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,
+ if (pos > end - sizeof(struct ieee80211_ht_cap) - 2)
+ return;
+ if (pos[1] != sizeof(struct ieee80211_ht_cap))
+ return;
+ /* copy the ie's value into ht_capb*/
+ memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
sizeof(struct ieee80211_ht_cap));
sta_ptr->is_11n_enabled = 1;
break;
case WLAN_EID_HT_OPERATION:
- memcpy(&sta_ptr->tdls_cap.ht_oper, pos,
+ if (pos > end -
+ sizeof(struct ieee80211_ht_operation) - 2)
+ return;
+ if (pos[1] != sizeof(struct ieee80211_ht_operation))
+ return;
+ /* copy the ie's value into ht_oper*/
+ memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
sizeof(struct ieee80211_ht_operation));
break;
case WLAN_EID_BSS_COEX_2040:
+ if (pos > end - 3)
+ return;
+ if (pos[1] != 1)
+ return;
sta_ptr->tdls_cap.coex_2040 = pos[2];
break;
case WLAN_EID_EXT_CAPABILITY:
+ if (pos > end - sizeof(struct ieee_types_header))
+ return;
+ if (pos[1] < sizeof(struct ieee_types_header))
+ return;
+ if (pos[1] > 8)
+ return;
memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
sizeof(struct ieee_types_header) +
min_t(u8, pos[1], 8));
break;
case WLAN_EID_RSN:
+ if (pos > end - sizeof(struct ieee_types_header))
+ return;
+ if (pos[1] < sizeof(struct ieee_types_header))
+ return;
+ if (pos[1] > IEEE_MAX_IE_SIZE -
+ sizeof(struct ieee_types_header))
+ return;
memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
sizeof(struct ieee_types_header) +
min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
sizeof(struct ieee_types_header)));
break;
case WLAN_EID_QOS_CAPA:
+ if (pos > end - 3)
+ return;
+ if (pos[1] != 1)
+ return;
sta_ptr->tdls_cap.qos_info = pos[2];
break;
case WLAN_EID_VHT_OPERATION:
- if (priv->adapter->is_hw_11ac_capable)
- memcpy(&sta_ptr->tdls_cap.vhtoper, pos,
+ if (priv->adapter->is_hw_11ac_capable) {
+ if (pos > end -
+ sizeof(struct ieee80211_vht_operation) - 2)
+ return;
+ if (pos[1] !=
+ sizeof(struct ieee80211_vht_operation))
+ return;
+ /* copy the ie's value into vhtoper*/
+ memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
sizeof(struct ieee80211_vht_operation));
+ }
break;
case WLAN_EID_VHT_CAPABILITY:
if (priv->adapter->is_hw_11ac_capable) {
- memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos,
+ if (pos > end -
+ sizeof(struct ieee80211_vht_cap) - 2)
+ return;
+ if (pos[1] != sizeof(struct ieee80211_vht_cap))
+ return;
+ /* copy the ie's value into vhtcap*/
+ memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
sizeof(struct ieee80211_vht_cap));
sta_ptr->is_11ac_enabled = 1;
}
break;
case WLAN_EID_AID:
- if (priv->adapter->is_hw_11ac_capable)
+ if (priv->adapter->is_hw_11ac_capable) {
+ if (pos > end - 4)
+ return;
+ if (pos[1] != 2)
+ return;
sta_ptr->tdls_cap.aid =
le16_to_cpu(*(__le16 *)(pos + 2));
+ }
+ break;
default:
break;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index 9843560..c93fcaf 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -980,6 +980,10 @@
"WMM Parameter Set Count: %d\n",
wmm_param_ie->qos_info_bitmap & mask);
+ if (wmm_param_ie->vend_hdr.len + 2 >
+ sizeof(struct ieee_types_wmm_parameter))
+ break;
+
memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
wmm_ie, wmm_param_ie,
wmm_param_ie->vend_hdr.len + 2);
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index e15b462..21b7cb8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -1095,13 +1095,15 @@
return ret;
}
-static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
+static void _rtl_pci_irq_tasklet(unsigned long data)
{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
_rtl_pci_tx_chk_waitq(hw);
}
-static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
+static void _rtl_pci_prepare_bcn_tasklet(unsigned long data)
{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -1223,10 +1225,10 @@
/*task */
tasklet_init(&rtlpriv->works.irq_tasklet,
- (void (*)(unsigned long))_rtl_pci_irq_tasklet,
+ _rtl_pci_irq_tasklet,
(unsigned long)hw);
tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet,
- (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet,
+ _rtl_pci_prepare_bcn_tasklet,
(unsigned long)hw);
INIT_WORK(&rtlpriv->works.lps_change_work,
rtl_lps_change_work_callback);
diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c
index 7c1eaea..d2fe134 100644
--- a/drivers/nfc/fdp/fdp.c
+++ b/drivers/nfc/fdp/fdp.c
@@ -192,7 +192,7 @@
const struct firmware *fw;
struct sk_buff *skb;
unsigned long len;
- u8 max_size, payload_size;
+ int max_size, payload_size;
int rc = 0;
if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) ||
@@ -215,8 +215,7 @@
while (len) {
- payload_size = min_t(unsigned long, (unsigned long) max_size,
- len);
+ payload_size = min_t(unsigned long, max_size, len);
skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size),
GFP_KERNEL);
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
index f837c39..0f69051 100644
--- a/drivers/nfc/pn544/i2c.c
+++ b/drivers/nfc/pn544/i2c.c
@@ -240,6 +240,7 @@
out:
gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity);
+ usleep_range(10000, 15000);
}
static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode)
diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c
index 12e819d..3afc53f 100644
--- a/drivers/nfc/pn544/pn544.c
+++ b/drivers/nfc/pn544/pn544.c
@@ -704,7 +704,7 @@
target->nfcid1_len != 10)
return -EOPNOTSUPP;
- return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
+ return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
PN544_RF_READER_CMD_ACTIVATE_NEXT,
target->nfcid1, target->nfcid1_len, NULL);
} else if (target->supported_protocols & (NFC_PROTO_JEWEL_MASK |
diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
index 3cd995d..151b220 100644
--- a/drivers/nfc/port100.c
+++ b/drivers/nfc/port100.c
@@ -573,7 +573,7 @@
{
struct port100_frame *frame = _frame;
- frame->datalen = cpu_to_le16(le16_to_cpu(frame->datalen) + len);
+ le16_add_cpu(&frame->datalen, len);
}
static bool port100_rx_frame_is_valid(void *_frame)
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
old mode 100644
new mode 100755
index 0a963b1..000a96a
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -133,4 +133,8 @@
help
OpenFirmware BatteryData accessors
+config OF_DMA_DEFAULT_COHERENT
+ # arches should select this if DMA is coherent by default for OF devices
+ bool
+
endif # OF
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 2c1b08a..b87b3cd 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -929,12 +929,16 @@
* @np: device node
*
* It returns true if "dma-coherent" property was found
- * for this device in DT.
+ * for this device in the DT, or if DMA is coherent by
+ * default for OF devices on the current platform.
*/
bool of_dma_is_coherent(struct device_node *np)
{
struct device_node *node = of_node_get(np);
+ if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT))
+ return true;
+
while (node) {
if (of_property_read_bool(node, "dma-coherent")) {
of_node_put(node);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index 9397c46..f011a87 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -502,7 +502,7 @@
/* Disable Link training */
val = ks_dw_app_readl(ks_pcie, CMD_STATUS);
val &= ~LTSSM_EN_VAL;
- ks_dw_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val);
+ ks_dw_app_writel(ks_pcie, CMD_STATUS, val);
/* Initiate Link Training */
val = ks_dw_app_readl(ks_pcie, CMD_STATUS);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 1d32fe2..9ec3cb6 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -181,6 +181,7 @@
failed2:
sysfs_remove_link(&dev->dev.kobj, buf);
failed1:
+ pci_stop_and_remove_bus_device(virtfn);
pci_dev_put(dev);
mutex_lock(&iov->dev->sriov->lock);
pci_stop_and_remove_bus_device(virtfn);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index f30ca75..e631636 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1833,12 +1833,18 @@
/* restore size and flags */
list_for_each_entry(fail_res, &fail_head, list) {
struct resource *res = fail_res->res;
+ int idx;
res->start = fail_res->start;
res->end = fail_res->end;
res->flags = fail_res->flags;
- if (fail_res->dev->subordinate)
- res->flags = 0;
+
+ if (pci_is_bridge(fail_res->dev)) {
+ idx = res - &fail_res->dev->resource[0];
+ if (idx >= PCI_BRIDGE_RESOURCES &&
+ idx <= PCI_BRIDGE_RESOURCE_END)
+ res->flags = 0;
+ }
}
free_list(&fail_head);
@@ -1904,12 +1910,18 @@
/* restore size and flags */
list_for_each_entry(fail_res, &fail_head, list) {
struct resource *res = fail_res->res;
+ int idx;
res->start = fail_res->start;
res->end = fail_res->end;
res->flags = fail_res->flags;
- if (fail_res->dev->subordinate)
- res->flags = 0;
+
+ if (pci_is_bridge(fail_res->dev)) {
+ idx = res - &fail_res->dev->resource[0];
+ if (idx >= PCI_BRIDGE_RESOURCES &&
+ idx <= PCI_BRIDGE_RESOURCE_END)
+ res->flags = 0;
+ }
}
free_list(&fail_head);
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index f83a2a6..1e945aa 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -958,7 +958,13 @@
raw_spin_lock_irqsave(&byt_lock, flags);
value = readl(reg);
- value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+
+ /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
+ if (value & BYT_DIRECT_IRQ_EN)
+ /* nothing to do */ ;
+ else
+ value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+
writel(value, reg);
raw_spin_unlock_irqrestore(&byt_lock, flags);
}
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
index 18ef704..771689a 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
@@ -2324,7 +2324,7 @@
FN_ATAG0_A, 0, FN_REMOCON_B, 0,
/* IP0_11_8 [4] */
FN_SD1_DAT2_A, FN_MMC_D2, 0, FN_BS,
- FN_ATADIR0_A, 0, FN_SDSELF_B, 0,
+ FN_ATADIR0_A, 0, FN_SDSELF_A, 0,
FN_PWM4_B, 0, 0, 0,
0, 0, 0, 0,
/* IP0_7_5 [3] */
@@ -2366,7 +2366,7 @@
FN_TS_SDAT0_A, 0, 0, 0,
0, 0, 0, 0,
/* IP1_10_8 [3] */
- FN_SD1_CLK_B, FN_MMC_D6, 0, FN_A24,
+ FN_SD1_CD_A, FN_MMC_D6, 0, FN_A24,
FN_DREQ1_A, 0, FN_HRX0_B, FN_TS_SPSYNC0_A,
/* IP1_7_5 [3] */
FN_A23, FN_HTX0_B, FN_TX2_B, FN_DACK2_A,
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c
index e1c34e1..3ddb956 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c
@@ -500,17 +500,15 @@
SD_WP_MARK, SD_CLK_MARK, SD_CMD_MARK,
CRX0_MARK, CRX1_MARK,
CTX0_MARK, CTX1_MARK,
+ CRX0_CRX1_MARK, CTX0_CTX1_MARK,
PWM1A_MARK, PWM1B_MARK, PWM1C_MARK, PWM1D_MARK,
PWM1E_MARK, PWM1F_MARK, PWM1G_MARK, PWM1H_MARK,
PWM2A_MARK, PWM2B_MARK, PWM2C_MARK, PWM2D_MARK,
PWM2E_MARK, PWM2F_MARK, PWM2G_MARK, PWM2H_MARK,
IERXD_MARK, IETXD_MARK,
- CRX0_CRX1_MARK,
WDTOVF_MARK,
- CRX0X1_MARK,
-
/* DMAC */
TEND0_MARK, DACK0_MARK, DREQ0_MARK,
TEND1_MARK, DACK1_MARK, DREQ1_MARK,
@@ -998,12 +996,12 @@
PINMUX_DATA(PJ3_DATA, PJ3MD_00),
PINMUX_DATA(CRX1_MARK, PJ3MD_01),
- PINMUX_DATA(CRX0X1_MARK, PJ3MD_10),
+ PINMUX_DATA(CRX0_CRX1_MARK, PJ3MD_10),
PINMUX_DATA(IRQ1_PJ_MARK, PJ3MD_11),
PINMUX_DATA(PJ2_DATA, PJ2MD_000),
PINMUX_DATA(CTX1_MARK, PJ2MD_001),
- PINMUX_DATA(CRX0_CRX1_MARK, PJ2MD_010),
+ PINMUX_DATA(CTX0_CTX1_MARK, PJ2MD_010),
PINMUX_DATA(CS2_MARK, PJ2MD_011),
PINMUX_DATA(SCK0_MARK, PJ2MD_100),
PINMUX_DATA(LCD_M_DISP_MARK, PJ2MD_101),
@@ -1248,6 +1246,7 @@
GPIO_FN(CTX1),
GPIO_FN(CRX1),
GPIO_FN(CTX0),
+ GPIO_FN(CTX0_CTX1),
GPIO_FN(CRX0),
GPIO_FN(CRX0_CRX1),
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7269.c b/drivers/pinctrl/sh-pfc/pfc-sh7269.c
index cfdb4fc..3df0c0d 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh7269.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh7269.c
@@ -740,13 +740,12 @@
CRX0_MARK, CTX0_MARK,
CRX1_MARK, CTX1_MARK,
CRX2_MARK, CTX2_MARK,
- CRX0_CRX1_MARK,
- CRX0_CRX1_CRX2_MARK,
- CTX0CTX1CTX2_MARK,
+ CRX0_CRX1_MARK, CTX0_CTX1_MARK,
+ CRX0_CRX1_CRX2_MARK, CTX0_CTX1_CTX2_MARK,
CRX1_PJ22_MARK, CTX1_PJ23_MARK,
CRX2_PJ20_MARK, CTX2_PJ21_MARK,
- CRX0CRX1_PJ22_MARK,
- CRX0CRX1CRX2_PJ20_MARK,
+ CRX0_CRX1_PJ22_MARK, CTX0_CTX1_PJ23_MARK,
+ CRX0_CRX1_CRX2_PJ20_MARK, CTX0_CTX1_CTX2_PJ21_MARK,
/* VDC */
DV_CLK_MARK,
@@ -824,6 +823,7 @@
PINMUX_DATA(CS3_MARK, PC8MD_001),
PINMUX_DATA(TXD7_MARK, PC8MD_010),
PINMUX_DATA(CTX1_MARK, PC8MD_011),
+ PINMUX_DATA(CTX0_CTX1_MARK, PC8MD_100),
PINMUX_DATA(PC7_DATA, PC7MD_000),
PINMUX_DATA(CKE_MARK, PC7MD_001),
@@ -836,11 +836,12 @@
PINMUX_DATA(CAS_MARK, PC6MD_001),
PINMUX_DATA(SCK7_MARK, PC6MD_010),
PINMUX_DATA(CTX0_MARK, PC6MD_011),
+ PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC6MD_100),
PINMUX_DATA(PC5_DATA, PC5MD_000),
PINMUX_DATA(RAS_MARK, PC5MD_001),
PINMUX_DATA(CRX0_MARK, PC5MD_011),
- PINMUX_DATA(CTX0CTX1CTX2_MARK, PC5MD_100),
+ PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC5MD_100),
PINMUX_DATA(IRQ0_PC_MARK, PC5MD_101),
PINMUX_DATA(PC4_DATA, PC4MD_00),
@@ -1292,30 +1293,32 @@
PINMUX_DATA(LCD_DATA23_PJ23_MARK, PJ23MD_010),
PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011),
PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100),
- PINMUX_DATA(CTX1_MARK, PJ23MD_101),
+ PINMUX_DATA(CTX1_PJ23_MARK, PJ23MD_101),
+ PINMUX_DATA(CTX0_CTX1_PJ23_MARK, PJ23MD_110),
PINMUX_DATA(PJ22_DATA, PJ22MD_000),
PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001),
PINMUX_DATA(LCD_DATA22_PJ22_MARK, PJ22MD_010),
PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011),
PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100),
- PINMUX_DATA(CRX1_MARK, PJ22MD_101),
- PINMUX_DATA(CRX0_CRX1_MARK, PJ22MD_110),
+ PINMUX_DATA(CRX1_PJ22_MARK, PJ22MD_101),
+ PINMUX_DATA(CRX0_CRX1_PJ22_MARK, PJ22MD_110),
PINMUX_DATA(PJ21_DATA, PJ21MD_000),
PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001),
PINMUX_DATA(LCD_DATA21_PJ21_MARK, PJ21MD_010),
PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011),
PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100),
- PINMUX_DATA(CTX2_MARK, PJ21MD_101),
+ PINMUX_DATA(CTX2_PJ21_MARK, PJ21MD_101),
+ PINMUX_DATA(CTX0_CTX1_CTX2_PJ21_MARK, PJ21MD_110),
PINMUX_DATA(PJ20_DATA, PJ20MD_000),
PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001),
PINMUX_DATA(LCD_DATA20_PJ20_MARK, PJ20MD_010),
PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011),
PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100),
- PINMUX_DATA(CRX2_MARK, PJ20MD_101),
- PINMUX_DATA(CRX0CRX1CRX2_PJ20_MARK, PJ20MD_110),
+ PINMUX_DATA(CRX2_PJ20_MARK, PJ20MD_101),
+ PINMUX_DATA(CRX0_CRX1_CRX2_PJ20_MARK, PJ20MD_110),
PINMUX_DATA(PJ19_DATA, PJ19MD_000),
PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001),
@@ -1666,12 +1669,24 @@
GPIO_FN(WDTOVF),
/* CAN */
+ GPIO_FN(CTX2),
+ GPIO_FN(CRX2),
GPIO_FN(CTX1),
GPIO_FN(CRX1),
GPIO_FN(CTX0),
GPIO_FN(CRX0),
+ GPIO_FN(CTX0_CTX1),
GPIO_FN(CRX0_CRX1),
+ GPIO_FN(CTX0_CTX1_CTX2),
GPIO_FN(CRX0_CRX1_CRX2),
+ GPIO_FN(CTX2_PJ21),
+ GPIO_FN(CRX2_PJ20),
+ GPIO_FN(CTX1_PJ23),
+ GPIO_FN(CRX1_PJ22),
+ GPIO_FN(CTX0_CTX1_PJ23),
+ GPIO_FN(CRX0_CRX1_PJ22),
+ GPIO_FN(CTX0_CTX1_CTX2_PJ21),
+ GPIO_FN(CRX0_CRX1_CRX2_PJ20),
/* DMAC */
GPIO_FN(TEND0),
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
index b16cc0c..8c9be67 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
@@ -673,7 +673,8 @@
}
if (ntn_ctx->conn.dl.smmu_enabled)
ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.dl);
- ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.ul);
+
+ ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.ul);
return ret;
}
diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h
index 3b40b41..858804d 100644
--- a/drivers/platform/msm/ipa/ipa_common_i.h
+++ b/drivers/platform/msm/ipa/ipa_common_i.h
@@ -21,6 +21,8 @@
#include <linux/ipa_uc_offload.h>
#include <linux/ipa_wdi3.h>
#include <linux/ratelimit.h>
+#include <linux/swab.h>
+#include <linux/compiler.h>
#define WARNON_RATELIMIT_BURST 1
#define IPA_RATELIMIT_BURST 1
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 23e0bf7..4b6922b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -629,75 +629,74 @@
)
{
int ep_index = -1, i;
+ int pair_id = 0;
- ep_info->num_ep_pairs = 0;
for (i = 0; i < ep_info->max_ep_pairs; i++) {
pair_info[i].consumer_pipe_num = -1;
pair_info[i].producer_pipe_num = -1;
pair_info[i].ep_id = -1;
}
- ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_PROD);
- if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
- pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
- ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_CONS);
- if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
- pair_info[ep_info->num_ep_pairs].producer_pipe_num =
- ep_index;
- pair_info[ep_info->num_ep_pairs].ep_id =
- IPA_USB1_EP_ID;
+ if ((!ep_info->teth_prot_valid) || (ep_info->teth_prot_valid &&
+ ep_info->teth_prot == IPA_PROT_RMNET_CV2X)) {
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_PROD);
- IPADBG("ep_pair_info consumer_pipe_num %d",
- pair_info[ep_info->num_ep_pairs].
- consumer_pipe_num);
- IPADBG(" producer_pipe_num %d ep_id %d\n",
- pair_info[ep_info->num_ep_pairs].
- producer_pipe_num,
- pair_info[ep_info->num_ep_pairs].ep_id);
- ep_info->num_ep_pairs++;
- } else {
- pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
- IPADBG("ep_pair_info consumer_pipe_num %d",
- pair_info[ep_info->num_ep_pairs].
- consumer_pipe_num);
- IPADBG(" producer_pipe_num %d ep_id %d\n",
- pair_info[ep_info->num_ep_pairs].
- producer_pipe_num,
- pair_info[ep_info->num_ep_pairs].ep_id);
+ if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
+ pair_info[pair_id].consumer_pipe_num = ep_index;
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB2_CONS);
+
+ if ((ep_index != -1) &&
+ (ipa3_ctx->ep[ep_index].valid)) {
+ pair_info[pair_id].producer_pipe_num = ep_index;
+ pair_info[pair_id].ep_id = IPA_USB1_EP_ID;
+
+ IPADBG("ep_pair_info consumer_pipe_num %d",
+ pair_info[pair_id].consumer_pipe_num);
+ IPADBG(" producer_pipe_num %d ep_id %d\n",
+ pair_info[pair_id].producer_pipe_num,
+ pair_info[pair_id].ep_id);
+ pair_id++;
+ } else {
+ pair_info[pair_id].consumer_pipe_num = -1;
+ IPADBG("ep_pair_info consumer_pipe_num %d",
+ pair_info[pair_id].consumer_pipe_num);
+ IPADBG(" producer_pipe_num %d ep_id %d\n",
+ pair_info[pair_id].producer_pipe_num,
+ pair_info[pair_id].ep_id);
+ }
}
}
+ if ((!ep_info->teth_prot_valid) || (ep_info->teth_prot_valid &&
+ ep_info->teth_prot == IPA_PROT_RMNET)) {
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
- ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
+ if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
+ pair_info[pair_id].consumer_pipe_num = ep_index;
+ ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_CONS);
- if ((ep_index != -1) && ipa3_ctx->ep[ep_index].valid) {
- pair_info[ep_info->num_ep_pairs].consumer_pipe_num = ep_index;
- ep_index = ipa3_get_ep_mapping(IPA_CLIENT_USB_CONS);
- if ((ep_index != -1) && (ipa3_ctx->ep[ep_index].valid)) {
- pair_info[ep_info->num_ep_pairs].producer_pipe_num =
- ep_index;
- pair_info[ep_info->num_ep_pairs].ep_id =
- IPA_USB0_EP_ID;
+ if ((ep_index != -1) &&
+ (ipa3_ctx->ep[ep_index].valid)) {
+ pair_info[pair_id].producer_pipe_num = ep_index;
+ pair_info[pair_id].ep_id = IPA_USB0_EP_ID;
- IPADBG("ep_pair_info consumer_pipe_num %d",
- pair_info[ep_info->num_ep_pairs].
- consumer_pipe_num);
- IPADBG(" producer_pipe_num %d ep_id %d\n",
- pair_info[ep_info->num_ep_pairs].
- producer_pipe_num,
- pair_info[ep_info->num_ep_pairs].ep_id);
- ep_info->num_ep_pairs++;
- } else {
- pair_info[ep_info->num_ep_pairs].consumer_pipe_num = -1;
- IPADBG("ep_pair_info consumer_pipe_num %d",
- pair_info[ep_info->num_ep_pairs].
- consumer_pipe_num);
- IPADBG(" producer_pipe_num %d ep_id %d\n",
- pair_info[ep_info->num_ep_pairs].
- producer_pipe_num,
- pair_info[ep_info->num_ep_pairs].ep_id);
+ IPADBG("ep_pair_info consumer_pipe_num %d",
+ pair_info[pair_id].consumer_pipe_num);
+ IPADBG(" producer_pipe_num %d ep_id %d\n",
+ pair_info[pair_id].producer_pipe_num,
+ pair_info[pair_id].ep_id);
+ pair_id++;
+ } else {
+ pair_info[pair_id].consumer_pipe_num = -1;
+ IPADBG("ep_pair_info consumer_pipe_num %d",
+ pair_info[pair_id].consumer_pipe_num);
+ IPADBG(" producer_pipe_num %d ep_id %d\n",
+ pair_info[pair_id].producer_pipe_num,
+ pair_info[pair_id].ep_id);
+ }
}
}
+ ep_info->num_ep_pairs = pair_id;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index bc107d8..17f22f1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1590,7 +1590,7 @@
(RMNET_IOCTL_FEAT_NOTIFY_MUX_CHANNEL |
RMNET_IOCTL_FEAT_SET_EGRESS_DATA_FORMAT |
RMNET_IOCTL_FEAT_SET_INGRESS_DATA_FORMAT);
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
rc = -EFAULT;
@@ -1604,7 +1604,7 @@
/* Get MRU */
case RMNET_IOCTL_GET_MRU:
extend_ioctl_data.u.data = mru;
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
rc = -EFAULT;
@@ -1613,7 +1613,7 @@
case RMNET_IOCTL_GET_SG_SUPPORT:
extend_ioctl_data.u.data =
ipa3_rmnet_res.ipa_advertise_sg_support;
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
rc = -EFAULT;
@@ -1622,7 +1622,7 @@
case RMNET_IOCTL_GET_EPID:
IPAWANDBG("get ioctl: RMNET_IOCTL_GET_EPID\n");
extend_ioctl_data.u.data = epid;
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
rc = -EFAULT;
@@ -1643,7 +1643,7 @@
ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_PROD);
extend_ioctl_data.u.ipa_ep_pair.producer_pipe_num =
ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
rc = -EFAULT;
@@ -1660,13 +1660,19 @@
break;
/* Get driver name */
case RMNET_IOCTL_GET_DRIVER_NAME:
- memcpy(&extend_ioctl_data.u.if_name,
- IPA_NETDEV()->name, IFNAMSIZ);
- extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
- if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+ if (IPA_NETDEV() != NULL) {
+ memcpy(&extend_ioctl_data.u.if_name,
+ IPA_NETDEV()->name, IFNAMSIZ);
+ extend_ioctl_data.u.if_name[IFNAMSIZ - 1] =
+ '\0';
+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
+ rc = -EFAULT;
+ } else {
+ IPAWANERR("IPA_NETDEV is NULL\n");
rc = -EFAULT;
+ }
break;
/* Add MUX ID */
case RMNET_IOCTL_ADD_MUX_CHANNEL:
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index 42e3997..9f5adf0 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -82,6 +82,8 @@
static void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify);
static int mhi_dev_pcie_notify_event;
static void mhi_dev_transfer_completion_cb(void *mreq);
+static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
+ struct mhi_dev_channel *ch, struct mhi_dev_ring *evt_ring);
static struct mhi_dev_uevent_info channel_state_info[MHI_MAX_CHANNELS];
/*
@@ -90,17 +92,14 @@
*
* @req : ring cache request
*/
-static void mhi_dev_ring_cache_completion_cb(void *req)
+static void mhi_dev_ring_cache_completion_cb(void *req)
{
- struct ring_cache_req *ring_req = NULL;
+ struct ring_cache_req *ring_req = req;
- if (req)
- ring_req = (struct ring_cache_req *)req;
- else {
- pr_err("%s():ring cache req data is NULL\n", __func__);
- return;
- }
- complete(ring_req->done);
+ if (ring_req)
+ complete(ring_req->done);
+ else
+ mhi_log(MHI_MSG_ERROR, "ring cache req is NULL\n");
}
void mhi_dev_read_from_host(struct mhi_dev *mhi, struct mhi_addr *transfer)
@@ -193,13 +192,310 @@
}
EXPORT_SYMBOL(mhi_dev_write_to_host);
+/*
+ * mhi_dev_event_buf_completion_cb() - CB function called by IPA driver
+ * when transfer completion event buffer copy to host is done.
+ *
+ * @req - event_req structure
+ */
+static void mhi_dev_event_buf_completion_cb(void *req)
+{
+ struct event_req *ereq = req;
+
+ if (ereq)
+ dma_unmap_single(&mhi_ctx->pdev->dev, ereq->dma,
+ ereq->dma_len, DMA_TO_DEVICE);
+ else
+ mhi_log(MHI_MSG_ERROR, "event req is null\n");
+}
+
+/*
+ * mhi_dev_event_rd_offset_completion_cb() - CB function called by IPA driver
+ * when event ring rd_offset transfer is done.
+ *
+ * @req - event_req structure
+ */
+static void mhi_dev_event_rd_offset_completion_cb(void *req)
+{
+ union mhi_dev_ring_ctx *ctx;
+ int rc;
+ struct event_req *ereq = req;
+ struct mhi_dev_channel *ch = ereq->context;
+ struct mhi_dev *mhi = ch->ring->mhi_dev;
+ unsigned long flags;
+
+ if (ereq->event_rd_dma)
+ dma_unmap_single(&mhi_ctx->pdev->dev, ereq->event_rd_dma,
+ sizeof(uint64_t), DMA_TO_DEVICE);
+ /* rp update in host memory should be flushed before sending an MSI */
+ wmb();
+ ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[ereq->event_ring];
+ rc = ep_pcie_trigger_msi(mhi_ctx->phandle, ctx->ev.msivec);
+ if (rc)
+ pr_err("%s: error sending in msi\n", __func__);
+
+ /* Add back the flushed events space to the event buffer */
+ ch->evt_buf_wp = ereq->start + ereq->num_events;
+ if (ch->evt_buf_wp == ch->evt_buf_size)
+ ch->evt_buf_wp = 0;
+ /* Return the event req to the list */
+ spin_lock_irqsave(&mhi->lock, flags);
+ if (ch->curr_ereq == NULL)
+ ch->curr_ereq = ereq;
+ else
+ list_add_tail(&ereq->list, &ch->event_req_buffers);
+ spin_unlock_irqrestore(&mhi->lock, flags);
+}
+
+static int mhi_dev_send_multiple_tr_events(struct mhi_dev *mhi, int evnt_ring,
+ struct event_req *ereq, uint32_t evt_len)
+{
+ int rc = 0;
+ uint64_t evnt_ring_idx = mhi->ev_ring_start + evnt_ring;
+ struct mhi_dev_ring *ring = &mhi->ring[evnt_ring_idx];
+ union mhi_dev_ring_ctx *ctx;
+ struct mhi_addr transfer_addr;
+ struct mhi_dev_channel *ch;
+
+ if (!ereq) {
+ pr_err("%s(): invalid event req\n", __func__);
+ return -EINVAL;
+ }
+
+ if (evnt_ring_idx > mhi->cfg.event_rings) {
+ pr_err("Invalid event ring idx: %lld\n", evnt_ring_idx);
+ return -EINVAL;
+ }
+
+ if (mhi_ring_get_state(ring) == RING_STATE_UINT) {
+ ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[evnt_ring];
+ rc = mhi_ring_start(ring, ctx, mhi);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR,
+ "error starting event ring %d\n", evnt_ring);
+ return rc;
+ }
+ }
+ ch = ereq->context;
+ /* Check the limits of the buffer to be flushed */
+ if (ereq->tr_events < ch->tr_events ||
+ (ereq->tr_events + ereq->num_events) >
+ (ch->tr_events + ch->evt_buf_size)) {
+ pr_err("%s: Invalid completion event buffer!\n", __func__);
+ mhi_log(MHI_MSG_ERROR,
+ "Invalid cmpl evt buf - start %pK, end %pK\n",
+ ereq->tr_events, ereq->tr_events + ereq->num_events);
+ return -EINVAL;
+ }
+
+ mhi_log(MHI_MSG_VERBOSE, "Flushing %d cmpl events of ch %d\n",
+ ereq->num_events, ch->ch_id);
+ /* add the events */
+ ereq->client_cb = mhi_dev_event_buf_completion_cb;
+ ereq->event_type = SEND_EVENT_BUFFER;
+ rc = mhi_dev_add_element(ring, ereq->tr_events, ereq, evt_len);
+ if (rc) {
+ pr_err("%s(): error in adding element rc %d\n", __func__, rc);
+ return rc;
+ }
+ ring->ring_ctx_shadow->ev.rp = (ring->rd_offset *
+ sizeof(union mhi_dev_ring_element_type)) +
+ ring->ring_ctx->generic.rbase;
+
+ mhi_log(MHI_MSG_VERBOSE, "ev.rp = %llx for %lld\n",
+ ring->ring_ctx_shadow->ev.rp, evnt_ring_idx);
+
+ if (mhi->use_ipa) {
+ transfer_addr.host_pa = (mhi->ev_ctx_shadow.host_pa +
+ sizeof(struct mhi_dev_ev_ctx) *
+ evnt_ring) + (size_t)&ring->ring_ctx->ev.rp -
+ (size_t)ring->ring_ctx;
+ /*
+ * As ev_ctx_cache memory is dma_alloc_coherent, dma_map_single
+ * should not be called. Pass physical address to write to host.
+ */
+ transfer_addr.phy_addr = (mhi->ev_ctx_cache_dma_handle +
+ sizeof(struct mhi_dev_ev_ctx) * evnt_ring) +
+ (size_t)&ring->ring_ctx->ev.rp -
+ (size_t)ring->ring_ctx;
+ } else {
+ transfer_addr.device_va = (mhi->ev_ctx_shadow.device_va +
+ sizeof(struct mhi_dev_ev_ctx) *
+ evnt_ring) + (size_t)&ring->ring_ctx->ev.rp -
+ (size_t)ring->ring_ctx;
+ }
+
+ transfer_addr.virt_addr = &ring->ring_ctx_shadow->ev.rp;
+ transfer_addr.size = sizeof(uint64_t);
+ ereq->event_type = SEND_EVENT_RD_OFFSET;
+ ereq->client_cb = mhi_dev_event_rd_offset_completion_cb;
+ ereq->event_ring = evnt_ring;
+ mhi_dev_write_to_host(mhi, &transfer_addr, ereq, MHI_DEV_DMA_ASYNC);
+ return rc;
+}
+
+static int mhi_dev_flush_transfer_completion_events(struct mhi_dev *mhi,
+ struct mhi_dev_channel *ch)
+{
+ int rc = 0;
+ unsigned long flags;
+ struct event_req *flush_ereq;
+
+ /*
+ * Channel got closed with transfers pending
+ * Do not send completion events to host
+ */
+ if (ch->state == MHI_DEV_CH_CLOSED) {
+ mhi_log(MHI_MSG_DBG, "Ch %d closed with %d writes pending\n",
+ ch->ch_id, ch->pend_wr_count + 1);
+ return -ENODEV;
+ }
+
+ do {
+ spin_lock_irqsave(&mhi->lock, flags);
+ if (list_empty(&ch->flush_event_req_buffers)) {
+ spin_unlock_irqrestore(&mhi->lock, flags);
+ break;
+ }
+ flush_ereq = container_of(ch->flush_event_req_buffers.next,
+ struct event_req, list);
+ list_del_init(&flush_ereq->list);
+ spin_unlock_irqrestore(&mhi->lock, flags);
+
+ mhi_log(MHI_MSG_DBG, "Flush called for ch %d\n", ch->ch_id);
+ rc = mhi_dev_send_multiple_tr_events(mhi,
+ mhi->ch_ctx_cache[ch->ch_id].err_indx,
+ flush_ereq,
+ (flush_ereq->num_events *
+ sizeof(union mhi_dev_ring_element_type)));
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR, "failed to send compl evts\n");
+ break;
+ }
+ } while (true);
+
+ return rc;
+}
+
+static bool mhi_dev_is_full_compl_evt_buf(struct mhi_dev_channel *ch)
+{
+ if (((ch->evt_buf_rp + 1) % ch->evt_buf_size) == ch->evt_buf_wp)
+ return true;
+
+ return false;
+}
+
+static void mhi_dev_rollback_compl_evt(struct mhi_dev_channel *ch)
+{
+ if (ch->evt_buf_rp)
+ ch->evt_buf_rp--;
+ else
+ ch->evt_buf_rp = ch->evt_buf_size - 1;
+}
+
+/*
+ * mhi_dev_queue_transfer_completion() - Queues a transfer completion
+ * event to the event buffer (where events are stored until they get
+ * flushed to host). Also determines when the completion events are
+ * to be flushed (sent) to host.
+ *
+ * @req - event_req structure
+ * @flush - Set to true when completion events are to be flushed.
+ */
+
+static int mhi_dev_queue_transfer_completion(struct mhi_req *mreq, bool *flush)
+{
+ union mhi_dev_ring_element_type *compl_ev;
+ struct mhi_dev_channel *ch = mreq->client->channel;
+ unsigned long flags;
+
+ if (mhi_dev_is_full_compl_evt_buf(ch) || ch->curr_ereq == NULL) {
+ mhi_log(MHI_MSG_VERBOSE, "Ran out of %s\n",
+ (ch->curr_ereq ? "compl evts" : "ereqs"));
+ return -EBUSY;
+ }
+
+ if (mreq->el->tre.ieot) {
+ compl_ev = ch->tr_events + ch->evt_buf_rp;
+ compl_ev->evt_tr_comp.chid = ch->ch_id;
+ compl_ev->evt_tr_comp.type =
+ MHI_DEV_RING_EL_TRANSFER_COMPLETION_EVENT;
+ compl_ev->evt_tr_comp.len = mreq->transfer_len;
+ compl_ev->evt_tr_comp.code = MHI_CMD_COMPL_CODE_EOT;
+ compl_ev->evt_tr_comp.ptr = ch->ring->ring_ctx->generic.rbase +
+ mreq->rd_offset * TR_RING_ELEMENT_SZ;
+ ch->evt_buf_rp++;
+ if (ch->evt_buf_rp == ch->evt_buf_size)
+ ch->evt_buf_rp = 0;
+ ch->curr_ereq->num_events++;
+ /*
+ * It is not necessary to flush when we need to wrap-around, if
+ * we do have free space in the buffer upon wrap-around.
+ * But when we really need to flush, we need a separate dma op
+ * anyway for the current chunk (from flush_start to the
+ * physical buffer end) since the buffer is circular. So we
+ * might as well flush on wrap-around.
+ * Also, we flush when we hit the threshold as well. The flush
+ * threshold is based on the channel's event ring size.
+ *
+ * In summary, completion event buffer flush is done if
+ * * Client requests it (snd_cmpl was set to 1) OR
+ * * Physical end of the event buffer is reached OR
+ * * Flush threshold is reached for the current ereq
+ *
+ * When events are to be flushed, the current ereq is moved to
+ * the flush list, and the flush param is set to true for the
+ * second and third cases above. The actual flush of the events
+ * is done in the write_to_host API (for the write path) or
+ * in the transfer completion callback (for the read path).
+ */
+ if (ch->evt_buf_rp == 0 ||
+ ch->curr_ereq->num_events >=
+ MHI_CMPL_EVT_FLUSH_THRSHLD(ch->evt_buf_size)
+ || mreq->snd_cmpl) {
+ if (flush)
+ *flush = true;
+
+ if (!mreq->snd_cmpl)
+ mreq->snd_cmpl = 1;
+
+ ch->curr_ereq->tr_events = ch->tr_events +
+ ch->curr_ereq->start;
+ ch->curr_ereq->context = ch;
+
+ /* Move current event req to flush list*/
+ spin_lock_irqsave(&mhi_ctx->lock, flags);
+ list_add_tail(&ch->curr_ereq->list,
+ &ch->flush_event_req_buffers);
+
+ if (!list_empty(&ch->event_req_buffers)) {
+ ch->curr_ereq =
+ container_of(ch->event_req_buffers.next,
+ struct event_req, list);
+ list_del_init(&ch->curr_ereq->list);
+ ch->curr_ereq->num_events = 0;
+ ch->curr_ereq->start = ch->evt_buf_rp;
+ } else {
+ pr_err("%s evt req buffers empty\n", __func__);
+ mhi_log(MHI_MSG_ERROR,
+ "evt req buffers empty\n");
+ ch->curr_ereq = NULL;
+ }
+ spin_unlock_irqrestore(&mhi_ctx->lock, flags);
+ }
+ return 0;
+ }
+
+ mhi_log(MHI_MSG_ERROR, "ieot is not valid\n");
+ return -EINVAL;
+}
int mhi_transfer_host_to_device(void *dev, uint64_t host_pa, uint32_t len,
struct mhi_dev *mhi, struct mhi_req *mreq)
{
int rc = 0;
uint64_t bit_40 = ((u64) 1) << 40, host_addr_pa = 0, offset = 0;
struct mhi_dev_ring *ring = NULL;
-
+ struct mhi_dev_channel *ch;
if (!mhi || !dev || !host_pa || !mreq) {
pr_err("%s():Invalid parameters\n", __func__);
@@ -226,20 +522,37 @@
}
memcpy(dev, mhi->read_handle, len);
} else if (mreq->mode == IPA_DMA_ASYNC) {
- ring = mreq->client->channel->ring;
+ ch = mreq->client->channel;
+ ring = ch->ring;
mreq->dma = dma_map_single(&mhi->pdev->dev, dev, len,
DMA_FROM_DEVICE);
mhi_dev_ring_inc_index(ring, ring->rd_offset);
- if (ring->rd_offset == ring->wr_offset)
+ if (ring->rd_offset == ring->wr_offset) {
+ mhi_log(MHI_MSG_VERBOSE,
+ "Setting snd_cmpl to 1 for ch %d\n", ch->ch_id);
mreq->snd_cmpl = 1;
- else
- mreq->snd_cmpl = 0;
+ }
+
+ /* Queue the completion event for the current transfer */
+ rc = mhi_dev_queue_transfer_completion(mreq, NULL);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR,
+ "Failed to queue completion for ch %d, rc %d\n",
+ ch->ch_id, rc);
+ return rc;
+ }
rc = ipa_dma_async_memcpy(mreq->dma, host_addr_pa,
(int) len, mhi_dev_transfer_completion_cb,
mreq);
if (rc) {
- pr_err("error while reading chan using async:%d\n", rc);
+ mhi_log(MHI_MSG_ERROR,
+ "DMA read error %d for ch %d\n", rc, ch->ch_id);
+ /* Roll back the completion event that we wrote above */
+ mhi_dev_rollback_compl_evt(ch);
+ /* Unmap the buffer */
+ dma_unmap_single(&mhi_ctx->pdev->dev, mreq->dma,
+ len, DMA_FROM_DEVICE);
return rc;
}
}
@@ -253,6 +566,9 @@
int rc = 0;
uint64_t bit_40 = ((u64) 1) << 40, host_addr_pa = 0, offset = 0;
struct mhi_dev_ring *ring = NULL;
+ bool flush = false;
+ struct mhi_dev_channel *ch;
+ u32 snd_cmpl;
if (!mhi || !dev || !req || !host_addr) {
pr_err("%sInvalid parameters\n", __func__);
@@ -275,17 +591,45 @@
rc = ipa_dma_sync_memcpy(host_addr_pa,
(u64) mhi->write_dma_handle, (int) len);
} else if (req->mode == IPA_DMA_ASYNC) {
+ ch = req->client->channel;
req->dma = dma_map_single(&mhi->pdev->dev, req->buf,
req->len, DMA_TO_DEVICE);
- ring = req->client->channel->ring;
+
+ ring = ch->ring;
mhi_dev_ring_inc_index(ring, ring->rd_offset);
if (ring->rd_offset == ring->wr_offset)
req->snd_cmpl = 1;
+ snd_cmpl = req->snd_cmpl;
+
+ /* Queue the completion event for the current transfer */
+ rc = mhi_dev_queue_transfer_completion(req, &flush);
+ if (rc) {
+ pr_err("Failed to queue completion: %d\n", rc);
+ return rc;
+ }
+
rc = ipa_dma_async_memcpy(host_addr_pa,
(uint64_t) req->dma, (int) len,
mhi_dev_transfer_completion_cb, req);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR, "Error sending data to host\n");
+ /* Roll back the completion event that we wrote above */
+ mhi_dev_rollback_compl_evt(ch);
+ /* Unmap the buffer */
+ dma_unmap_single(&mhi_ctx->pdev->dev, req->dma,
+ req->len, DMA_TO_DEVICE);
+ return rc;
+ }
+ if (snd_cmpl || flush) {
+ rc = mhi_dev_flush_transfer_completion_events(mhi, ch);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR,
+ "Failed to flush write completions to host\n");
+ return rc;
+ }
+ }
}
- return rc;
+ return 0;
}
EXPORT_SYMBOL(mhi_transfer_device_to_host);
@@ -493,6 +837,11 @@
switch (type) {
case MHI_DEV_RING_EL_RESET:
case MHI_DEV_RING_EL_STOP:
+ if ((chid-HW_CHANNEL_BASE) > NUM_HW_CHANNELS) {
+ pr_err("Invalid Channel ID = 0x%X\n", chid);
+ return -EINVAL;
+ }
+
rc = ipa_mhi_disconnect_pipe(
mhi->ipa_clnt_hndl[chid-HW_CHANNEL_BASE]);
if (rc)
@@ -524,6 +873,11 @@
return -EINVAL;
}
+ if ((chid-HW_CHANNEL_BASE) > NUM_HW_CHANNELS) {
+ pr_err("Invalid Channel = 0x%X\n", chid);
+ return -EINVAL;
+ }
+
rc = ipa_mhi_connect_pipe(&connect_params,
&mhi->ipa_clnt_hndl[chid-HW_CHANNEL_BASE]);
if (rc)
@@ -666,130 +1020,6 @@
return rc;
}
-/*
- * mhi_dev_event_buf_completion_cb() -Cb function called by IPA driver
- * when transfer completion event buffer copy is done.
- *
- * @req - event_req structure
- */
-
-static void mhi_dev_event_buf_completion_cb(void *req)
-{
- struct event_req *ereq = NULL;
-
- if (req) {
- ereq = (struct event_req *)req;
- } else {
- pr_err("%s():event req data is invalid\n", __func__);
- return;
- }
- dma_unmap_single(&mhi_ctx->pdev->dev, ereq->dma,
- ereq->dma_len, DMA_TO_DEVICE);
-}
-
-/**
- * mhi_dev_event_rd_offset_completion_cb() -CB function called by IPA driver
- * when event rd_offset transfer is done.
- *
- * @req - event_req structure
- */
-
-static void mhi_dev_event_rd_offset_completion_cb(void *req)
-{
- union mhi_dev_ring_ctx *ctx;
- int rc = 0;
- struct event_req *ereq = (struct event_req *)req;
- struct mhi_dev_channel *ch = ereq->context;
- struct mhi_dev *mhi = ch->ring->mhi_dev;
- unsigned long flags;
-
- dma_unmap_single(&mhi_ctx->pdev->dev, ereq->event_rd_dma,
- sizeof(uint64_t), DMA_TO_DEVICE);
- ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[ereq->event_ring];
- rc = ep_pcie_trigger_msi(mhi_ctx->phandle, ctx->ev.msivec);
- if (rc)
- pr_err("%s: error sending in msi\n", __func__);
-
- /* return the event req to pre allocated pooled list */
- spin_lock_irqsave(&mhi->lock, flags);
- list_add_tail(&ereq->list, &ch->event_req_buffers);
- spin_unlock_irqrestore(&mhi->lock, flags);
-}
-
-static int mhi_dev_send_multiple_tr_events(struct mhi_dev *mhi, int evnt_ring,
- struct event_req *ereq, uint32_t evt_len)
-{
- int rc = 0;
- uint64_t evnt_ring_idx = mhi->ev_ring_start + evnt_ring;
- struct mhi_dev_ring *ring = &mhi->ring[evnt_ring_idx];
- union mhi_dev_ring_ctx *ctx;
- struct mhi_addr transfer_addr;
- static int count;
-
- if (!ereq) {
- pr_err("%s(): invalid event req\n", __func__);
- return -EINVAL;
- }
-
- if (count == 0) {
- rc = ep_pcie_get_msi_config(mhi->phandle, &mhi->msi_cfg);
- if (rc) {
- pr_err("Error retrieving pcie msi logic\n");
- return rc;
- }
- count++;
- }
-
- if (evnt_ring_idx > mhi->cfg.event_rings) {
- pr_err("Invalid event ring idx: %lld\n", evnt_ring_idx);
- return -EINVAL;
- }
-
- ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[evnt_ring];
- if (mhi_ring_get_state(ring) == RING_STATE_UINT) {
- rc = mhi_ring_start(ring, ctx, mhi);
- if (rc) {
- mhi_log(MHI_MSG_ERROR,
- "error starting event ring %d\n", evnt_ring);
- return rc;
- }
- }
-
- /* add the ring element */
- ereq->client_cb = mhi_dev_event_buf_completion_cb;
- ereq->event_type = SEND_EVENT_BUFFER;
- rc = mhi_dev_add_element(ring, ereq->tr_events, ereq, evt_len);
- if (rc) {
- pr_err("%s(): error in adding element rc %d\n", __func__, rc);
- return rc;
- }
- ring->ring_ctx_shadow->ev.rp = (ring->rd_offset *
- sizeof(union mhi_dev_ring_element_type)) +
- ring->ring_ctx->generic.rbase;
-
- mhi_log(MHI_MSG_VERBOSE, "ev.rp = %llx for %lld\n",
- ring->ring_ctx_shadow->ev.rp, evnt_ring_idx);
-
- if (mhi->use_ipa)
- transfer_addr.host_pa = (mhi->ev_ctx_shadow.host_pa +
- sizeof(struct mhi_dev_ev_ctx) *
- evnt_ring) + (uint32_t)&ring->ring_ctx->ev.rp -
- (uint32_t)ring->ring_ctx;
- else
- transfer_addr.device_va = (mhi->ev_ctx_shadow.device_va +
- sizeof(struct mhi_dev_ev_ctx) *
- evnt_ring) + (uint32_t)&ring->ring_ctx->ev.rp -
- (uint32_t)ring->ring_ctx;
-
- transfer_addr.virt_addr = &ring->ring_ctx_shadow->ev.rp;
- transfer_addr.size = sizeof(uint64_t);
- ereq->event_type = SEND_EVENT_RD_OFFSET;
- ereq->client_cb = mhi_dev_event_rd_offset_completion_cb;
- ereq->event_ring = evnt_ring;
- mhi_dev_write_to_host(mhi, &transfer_addr, ereq, MHI_DEV_DMA_ASYNC);
- return rc;
-}
-
static int mhi_dev_send_completion_event(struct mhi_dev_channel *ch,
uint32_t rd_ofst, uint32_t len,
enum mhi_dev_cmd_completion_code code)
@@ -854,6 +1084,12 @@
struct mhi_dev_ready_cb_info *info;
enum mhi_ctrl_info state_data;
+ /* Currently no clients register for HW channel notify */
+ if (ch_id >= MHI_MAX_SOFTWARE_CHANNELS) {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel :%d\n", ch_id);
+ return;
+ }
+
list_for_each_entry(info, &mhi_ctx->client_cb_list, list)
if (info->cb && info->cb_data.channel == ch_id) {
mhi_ctrl_state_info(info->cb_data.channel, &state_data);
@@ -962,6 +1198,7 @@
struct mhi_addr host_addr;
struct mhi_dev_channel *ch;
struct mhi_dev_ring *ring;
+ union mhi_dev_ring_ctx *evt_ctx;
ch_id = el->generic.chid;
mhi_log(MHI_MSG_VERBOSE, "for channel:%d and cmd:%d\n",
@@ -1026,6 +1263,26 @@
return;
}
+ if (mhi->use_ipa) {
+ uint32_t evnt_ring_idx = mhi->ev_ring_start +
+ mhi->ch_ctx_cache[ch_id].err_indx;
+ struct mhi_dev_ring *evt_ring =
+ &mhi->ring[evnt_ring_idx];
+ evt_ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache
+ [mhi->ch_ctx_cache[ch_id].err_indx];
+ if (mhi_ring_get_state(evt_ring) == RING_STATE_UINT) {
+ rc = mhi_ring_start(evt_ring, evt_ctx, mhi);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR,
+ "error starting event ring %d\n",
+ mhi->ch_ctx_cache[ch_id].err_indx);
+ return;
+ }
+ }
+ mhi_dev_alloc_evt_buf_evt_req(mhi, &mhi->ch[ch_id],
+ evt_ring);
+ }
+
if (mhi->use_ipa)
host_addr.host_pa = mhi->ch_ctx_shadow.host_pa +
sizeof(struct mhi_dev_ch_ctx) * ch_id;
@@ -1349,7 +1606,7 @@
struct mhi_dev_client_cb_reason reason;
mhi_ctx->ctrl_info = info;
- for (i = 0; i < MHI_MAX_CHANNELS; ++i) {
+ for (i = 0; i < MHI_MAX_SOFTWARE_CHANNELS; ++i) {
channel_state_info[i].ctrl_info = info;
/* Notify kernel clients */
mhi_dev_trigger_cb(i);
@@ -1439,28 +1696,12 @@
static void mhi_dev_transfer_completion_cb(void *mreq)
{
- struct mhi_dev_channel *ch;
- struct mhi_dev_client *client;
- union mhi_dev_ring_element_type *el;
int rc = 0;
- struct mhi_req *req = (struct mhi_req *)mreq;
- union mhi_dev_ring_element_type *compl_ev = NULL;
- struct mhi_dev *mhi = NULL;
- unsigned long flags;
- size_t transfer_len;
- u32 snd_cmpl;
- uint32_t rd_offset;
+ struct mhi_req *req = mreq;
+ struct mhi_dev_channel *ch = req->client->channel;
+ u32 snd_cmpl = req->snd_cmpl;
- client = req->client;
- ch = client->channel;
- mhi = ch->ring->mhi_dev;
- el = req->el;
- transfer_len = req->transfer_len;
- snd_cmpl = req->snd_cmpl;
- rd_offset = req->rd_offset;
- ch->curr_ereq->context = ch;
-
- if (mhi->ch_ctx_cache[ch->ch_id].ch_type ==
+ if (mhi_ctx->ch_ctx_cache[ch->ch_id].ch_type ==
MHI_DEV_CH_TYPE_INBOUND_CHANNEL)
ch->pend_wr_count--;
@@ -1480,41 +1721,16 @@
/* Trigger client call back */
req->client_cb(req);
- if (el->tre.ieot) {
- compl_ev = ch->curr_ereq->tr_events + ch->curr_ereq->num_events;
- compl_ev->evt_tr_comp.chid = ch->ch_id;
- compl_ev->evt_tr_comp.type =
- MHI_DEV_RING_EL_TRANSFER_COMPLETION_EVENT;
- compl_ev->evt_tr_comp.len = transfer_len;
- compl_ev->evt_tr_comp.code = MHI_CMD_COMPL_CODE_EOT;
- compl_ev->evt_tr_comp.ptr = ch->ring->ring_ctx->generic.rbase +
- rd_offset * TR_RING_ELEMENT_SZ;
- ch->curr_ereq->num_events++;
-
- if (ch->curr_ereq->num_events >= MAX_TR_EVENTS || snd_cmpl) {
- mhi_log(MHI_MSG_VERBOSE,
- "num of tr events %d for ch %d\n",
- ch->curr_ereq->num_events, ch->ch_id);
- rc = mhi_dev_send_multiple_tr_events(mhi,
- mhi->ch_ctx_cache[ch->ch_id].err_indx,
- ch->curr_ereq, (ch->curr_ereq->num_events*
- sizeof(union mhi_dev_ring_element_type)));
- if (rc)
- mhi_log(MHI_MSG_ERROR,
- "failed to send compl evts\n");
- if (!list_empty(&ch->event_req_buffers)) {
- ch->curr_ereq =
- container_of(ch->event_req_buffers.next,
- struct event_req, list);
- spin_lock_irqsave(&mhi->lock, flags);
- list_del_init(&ch->curr_ereq->list);
- spin_unlock_irqrestore(&mhi->lock, flags);
- ch->curr_ereq->num_events = 0;
- } else
- pr_err("%s evt req buffers empty\n", __func__);
+ /* Flush read completions to host */
+ if (snd_cmpl && mhi_ctx->ch_ctx_cache[ch->ch_id].ch_type ==
+ MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL) {
+ mhi_log(MHI_MSG_DBG, "Calling flush for ch %d\n", ch->ch_id);
+ rc = mhi_dev_flush_transfer_completion_events(mhi_ctx, ch);
+ if (rc) {
+ mhi_log(MHI_MSG_ERROR,
+ "Failed to flush read completions to host\n");
}
- } else
- mhi_log(MHI_MSG_ERROR, "ieot is not valid\n");
+ }
if (ch->state == MHI_DEV_CH_PENDING_STOP) {
ch->state = MHI_DEV_CH_STOPPED;
@@ -1924,8 +2140,104 @@
mhi_ring_set_cb(&dev->ring[i], mhi_dev_process_tre_ring);
}
+ return 0;
+}
+
+static uint32_t mhi_dev_get_evt_ring_size(struct mhi_dev *mhi, uint32_t ch_id)
+{
+ uint32_t info;
+ int rc;
+
+ /* If channel was started by host, get event ring size */
+ rc = mhi_ctrl_state_info(ch_id, &info);
+ if (rc || (info != MHI_STATE_CONNECTED))
+ return NUM_TR_EVENTS_DEFAULT;
+
+ return mhi->ring[mhi->ev_ring_start +
+ mhi->ch_ctx_cache[ch_id].err_indx].ring_size;
+}
+
+static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
+ struct mhi_dev_channel *ch, struct mhi_dev_ring *evt_ring)
+{
+ int rc;
+ uint32_t size, i;
+
+ if (evt_ring)
+ size = evt_ring->ring_size;
+ else
+ size = mhi_dev_get_evt_ring_size(mhi, ch->ch_id);
+
+ if (!size) {
+ mhi_log(MHI_MSG_ERROR,
+ "Evt buf size is 0 for channel %d", ch->ch_id);
+ return -EINVAL;
+ }
+
+ /* Previous allocated evt buf size matches requested size */
+ if (size == ch->evt_buf_size)
+ return 0;
+
+ /*
+ * Either evt buf and evt reqs were not allocated yet or
+ * they were allocated with a different size
+ */
+ if (ch->evt_buf_size) {
+ kfree(ch->ereqs);
+ kfree(ch->tr_events);
+ }
+ /*
+ * Set number of event flush req buffers equal to size of
+ * event buf since in the worst case we may need to flush
+ * every event ring element individually
+ */
+ ch->evt_buf_size = size;
+ ch->evt_req_size = size;
+
+ mhi_log(MHI_MSG_INFO,
+ "Channel %d evt buf size is %d\n", ch->ch_id, ch->evt_buf_size);
+
+ /* Allocate event requests */
+ ch->ereqs = kcalloc(ch->evt_req_size, sizeof(*ch->ereqs), GFP_KERNEL);
+ if (!ch->ereqs)
+ return -ENOMEM;
+
+ /* Allocate buffers to queue transfer completion events */
+ ch->tr_events = kcalloc(ch->evt_buf_size, sizeof(*ch->tr_events),
+ GFP_KERNEL);
+ if (!ch->tr_events) {
+ rc = -ENOMEM;
+ goto free_ereqs;
+ }
+
+ /* Organize event flush requests into a linked list */
+ INIT_LIST_HEAD(&ch->event_req_buffers);
+ INIT_LIST_HEAD(&ch->flush_event_req_buffers);
+ for (i = 0; i < ch->evt_req_size; ++i)
+ list_add_tail(&ch->ereqs[i].list, &ch->event_req_buffers);
+
+ ch->curr_ereq =
+ container_of(ch->event_req_buffers.next,
+ struct event_req, list);
+ list_del_init(&ch->curr_ereq->list);
+ ch->curr_ereq->start = 0;
+
+ /*
+ * Initialize cmpl event buffer indexes - evt_buf_rp and
+ * evt_buf_wp point to the first and last free index available.
+ */
+ ch->evt_buf_rp = 0;
+ ch->evt_buf_wp = ch->evt_buf_size - 1;
return 0;
+
+free_ereqs:
+ kfree(ch->ereqs);
+ ch->ereqs = NULL;
+ ch->evt_buf_size = 0;
+ ch->evt_req_size = 0;
+
+ return rc;
}
int mhi_dev_open_channel(uint32_t chan_id,
@@ -1934,7 +2246,6 @@
(struct mhi_dev_client_cb_reason *cb))
{
int rc = 0;
- int i = 0;
struct mhi_dev_channel *ch;
struct platform_device *pdev;
@@ -1958,37 +2269,9 @@
goto exit;
}
- /* Pre allocate event requests */
- ch->ereqs = kcalloc(MHI_MAX_EVT_REQ, sizeof(*ch->ereqs), GFP_KERNEL);
- if (!ch->ereqs) {
- rc = -ENOMEM;
+ rc = mhi_dev_alloc_evt_buf_evt_req(mhi_ctx, ch, NULL);
+ if (rc)
goto free_client;
- }
- /* pre allocate buffers to queue transfer completion events */
- ch->tr_events = kcalloc(MHI_MAX_EVT_REQ,
- MAX_TR_EVENTS * sizeof(*ch->tr_events),
- GFP_KERNEL);
- if (!ch->tr_events) {
- rc = -ENOMEM;
- goto free_ereqs;
- }
-
- /*
- * Organize the above allocated event request block and
- * completion event block into linked lists. Each event
- * request includes a pointer to a block of MAX_TR_EVENTS
- * completion events.
- */
- INIT_LIST_HEAD(&mhi_ctx->ch[chan_id].event_req_buffers);
- for (i = 0; i < MHI_MAX_EVT_REQ; ++i) {
- ch->ereqs[i].tr_events = ch->tr_events + i * MAX_TR_EVENTS;
- list_add_tail(&ch->ereqs[i].list,
- &mhi_ctx->ch[chan_id].event_req_buffers);
- }
- mhi_ctx->ch[chan_id].curr_ereq =
- container_of(mhi_ctx->ch[chan_id].event_req_buffers.next,
- struct event_req, list);
- list_del_init(&mhi_ctx->ch[chan_id].curr_ereq->list);
ch->active_client = (*handle_client);
(*handle_client)->channel = ch;
@@ -2004,11 +2287,10 @@
goto exit;
-free_ereqs:
- kfree(ch->ereqs);
- ch->ereqs = NULL;
free_client:
kfree(*handle_client);
+ *handle_client = NULL;
+
exit:
mutex_unlock(&ch->ch_lock);
return rc;
@@ -2020,6 +2302,11 @@
struct mhi_dev_channel *ch;
int rc;
+ if (!handle) {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel access\n");
+ return -EINVAL;
+ }
+
ch = handle->channel;
if (!ch)
return -EINVAL;
@@ -2053,6 +2340,10 @@
int count = 0;
int rc = 0;
+ if (!handle) {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV);
+ return -EINVAL;
+ }
ch = handle->channel;
do {
@@ -2090,6 +2381,8 @@
ch->active_client = NULL;
kfree(ch->ereqs);
kfree(ch->tr_events);
+ ch->evt_buf_size = 0;
+ ch->evt_req_size = 0;
ch->ereqs = NULL;
ch->tr_events = NULL;
kfree(handle);
@@ -2548,11 +2841,6 @@
return;
}
- /*Enable MHI dev network stack Interface*/
- rc = mhi_dev_net_interface_init();
- if (rc)
- pr_err("%s Failed to initialize mhi_dev_net iface\n", __func__);
-
rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec);
if (rc)
return;
@@ -2619,6 +2907,11 @@
}
mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_CONFIGURED);
+
+ /*Enable MHI dev network stack Interface*/
+ rc = mhi_dev_net_interface_init();
+ if (rc)
+ pr_err("%s Failed to initialize mhi_dev_net iface\n", __func__);
}
static void mhi_ring_init_cb(void *data)
@@ -2644,8 +2937,8 @@
return -ENXIO;
}
- if (channel > MHI_MAX_CHANNELS) {
- pr_err("Invalid channel :%d\n", channel);
+ if (channel >= MHI_MAX_SOFTWARE_CHANNELS) {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel :%d\n", channel);
return -EINVAL;
}
@@ -2684,6 +2977,12 @@
{
struct mhi_dev_client_cb_reason reason;
+ /* Currently no clients register for HW channel notify */
+ if (uevent_idx >= MHI_MAX_SOFTWARE_CHANNELS) {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel :%d\n", uevent_idx);
+ return;
+ }
+
if (uevent_idx == MHI_DEV_UEVENT_CTRL)
mhi_ctx->ctrl_info = info;
@@ -2703,7 +3002,12 @@
if (idx == MHI_DEV_UEVENT_CTRL)
*info = mhi_ctx->ctrl_info;
else
- *info = channel_state_info[idx].ctrl_info;
+ if (idx < MHI_MAX_SOFTWARE_CHANNELS)
+ *info = channel_state_info[idx].ctrl_info;
+ else {
+ mhi_log(MHI_MSG_ERROR, "Invalid channel :%d\n", idx);
+ return -EINVAL;
+ }
mhi_log(MHI_MSG_VERBOSE, "idx:%d, ctrl:%d", idx, *info);
@@ -2883,8 +3187,10 @@
if (!mhi->ch)
return -ENOMEM;
- for (i = 0; i < mhi->cfg.channels; i++)
+ for (i = 0; i < mhi->cfg.channels; i++) {
+ mhi->ch[i].ch_id = i;
mutex_init(&mhi->ch[i].ch_lock);
+ }
}
spin_lock_init(&mhi->lock);
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index 8f7a8e3..20d5d66 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -271,16 +271,18 @@
#define NUM_CHANNELS 128
#define HW_CHANNEL_BASE 100
+#define NUM_HW_CHANNELS 15
#define HW_CHANNEL_END 107
#define MHI_ENV_VALUE 2
#define MHI_MASK_ROWS_CH_EV_DB 4
#define TRB_MAX_DATA_SIZE 8192
#define MHI_CTRL_STATE 100
-/*maximum trasnfer completion events buffer*/
-#define MAX_TR_EVENTS 50
-/*maximum event requests */
-#define MHI_MAX_EVT_REQ 50
+/* maximum transfer completion events buffer */
+#define NUM_TR_EVENTS_DEFAULT 128
+
+/* Set flush threshold to 80% of event buf size */
+#define MHI_CMPL_EVT_FLUSH_THRSHLD(n) ((n * 8) / 10)
/* Possible ring element types */
union mhi_dev_ring_element_type {
@@ -418,6 +420,11 @@
struct event_req {
union mhi_dev_ring_element_type *tr_events;
+ /*
+ * Start index of the completion event buffer segment
+ * to be flushed to host
+ */
+ u32 start;
u32 num_events;
dma_addr_t dma;
u32 dma_len;
@@ -443,14 +450,23 @@
struct mutex ch_lock;
/* client which the current inbound/outbound message is for */
struct mhi_dev_client *active_client;
+ /* Pointer to completion event buffer */
+ union mhi_dev_ring_element_type *tr_events;
+ /* Indices for completion event buffer */
+ uint32_t evt_buf_rp;
+ uint32_t evt_buf_wp;
+ uint32_t evt_buf_size;
/*
- * Pointer to event request structs used to temporarily store
+ * Pointer to a block of event request structs used to temporarily store
* completion events and meta data before sending them to host
*/
struct event_req *ereqs;
- /* Pointer to completion event buffers */
- union mhi_dev_ring_element_type *tr_events;
+ /* Linked list head for event request structs */
struct list_head event_req_buffers;
+ uint32_t evt_req_size;
+ /* Linked list head for event request structs to be flushed */
+ struct list_head flush_event_req_buffers;
+ /* Pointer to the currently used event request struct */
struct event_req *curr_ereq;
/* current TRE being processed */
@@ -522,7 +538,7 @@
uint32_t ch_ring_start;
/* IPA Handles */
- u32 ipa_clnt_hndl[4];
+ u32 ipa_clnt_hndl[NUM_HW_CHANNELS];
struct workqueue_struct *ring_init_wq;
struct work_struct ring_init_cb_work;
struct work_struct re_init;
@@ -533,7 +549,6 @@
u32 ifc_id;
struct ep_pcie_hw *phandle;
struct work_struct pcie_event;
- struct ep_pcie_msi_config msi_cfg;
atomic_t write_active;
atomic_t is_suspended;
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index 4adf2ba..043de9d 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -364,7 +364,7 @@
{
struct ltc294x_info *info = i2c_get_clientdata(client);
- cancel_delayed_work(&info->work);
+ cancel_delayed_work_sync(&info->work);
power_supply_unregister(info->supply);
return 0;
}
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 42bbc4c..7e5aacf 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -2670,7 +2670,7 @@
}
rc = fg_sram_write(chip, CYCLE_COUNT_WORD, CYCLE_COUNT_OFFSET,
(u8 *)&chip->cyc_ctr.count,
- sizeof(chip->cyc_ctr.count) / sizeof(u8 *),
+ sizeof(chip->cyc_ctr.count) / (sizeof(u8 *)),
FG_IMA_DEFAULT);
if (rc < 0)
pr_err("failed to clear cycle counter rc=%d\n", rc);
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..2e15acf 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -337,6 +337,11 @@
static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
{
struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = pwmchip_remove(&omap->chip);
+ if (ret)
+ return ret;
if (pm_runtime_active(&omap->dm_timer_pdev->dev))
omap->pdata->stop(omap->dm_timer);
@@ -345,7 +350,7 @@
mutex_destroy(&omap->mutex);
- return pwmchip_remove(&omap->chip);
+ return 0;
}
static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index dfa8d50..28646e4 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -589,7 +589,7 @@
}
if (!pdata->dvs_gpio[i]) {
- dev_warn(dev, "there is no dvs%d gpio\n", i);
+ dev_info(dev, "there is no dvs%d gpio\n", i);
continue;
}
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index c6bfb349..b997805 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1488,7 +1488,7 @@
return 0;
}
-module_init(remoteproc_init);
+subsys_initcall(remoteproc_init);
static void __exit remoteproc_exit(void)
{
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 5292826..18c2030 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -304,6 +304,7 @@
config RTC_DRV_MAX8907
tristate "Maxim MAX8907"
depends on MFD_MAX8907
+ select REGMAP_IRQ
help
If you say yes here you will get support for the
RTC of Maxim MAX8907 PMIC.
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index c554e52..b962dbe 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -730,7 +730,7 @@
rtc_cmos_int_handler = cmos_interrupt;
retval = request_irq(rtc_irq, rtc_cmos_int_handler,
- IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev),
+ 0, dev_name(&cmos_rtc.rtc->dev),
cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c
index e5ad527..a8c2d38 100644
--- a/drivers/rtc/rtc-hym8563.c
+++ b/drivers/rtc/rtc-hym8563.c
@@ -105,7 +105,7 @@
if (!hym8563->valid) {
dev_warn(&client->dev, "no valid clock/calendar values available\n");
- return -EPERM;
+ return -EINVAL;
}
ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 9082476..4e9f794 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -302,8 +302,10 @@
cio_ignore_proc_seq_next(struct seq_file *s, void *it, loff_t *offset)
{
struct ccwdev_iter *iter;
+ loff_t p = *offset;
- if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1))
+ (*offset)++;
+ if (p >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1))
return NULL;
iter = it;
if (iter->devno == __MAX_SUBCHANNEL) {
@@ -313,7 +315,6 @@
return NULL;
} else
iter->devno++;
- (*offset)++;
return iter;
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 64ab9ea..def3208 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -2321,7 +2321,7 @@
* At some speeds, we only support
* ST transfers.
*/
- if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
+ if ((syncrate->sxfr_u2 & ST_SXFR) != 0)
*ppr_options &= ~MSG_EXT_PPR_DT_REQ;
break;
}
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index 894d97e..5db5767 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1383,7 +1383,7 @@
return -EINVAL;
/* Delete NPIV lnodes */
- csio_lnodes_exit(hw, 1);
+ csio_lnodes_exit(hw, 1);
/* Block upper IOs */
csio_lnodes_block_request(hw);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index c5bc41d..7760b9a 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -9818,6 +9818,7 @@
ioa_cfg->max_devs_supported = ipr_max_devs;
if (ioa_cfg->sis64) {
+ host->max_channel = IPR_MAX_SIS64_BUSES;
host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS;
host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET;
if (ipr_max_devs > IPR_MAX_SIS64_DEVS)
@@ -9826,6 +9827,7 @@
+ ((sizeof(struct ipr_config_table_entry64)
* ioa_cfg->max_devs_supported)));
} else {
+ host->max_channel = IPR_VSET_BUS;
host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS;
host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET;
if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS)
@@ -9835,7 +9837,6 @@
* ioa_cfg->max_devs_supported)));
}
- host->max_channel = IPR_VSET_BUS;
host->unique_id = host->host_no;
host->max_cmd_len = IPR_MAX_CDB_LEN;
host->can_queue = ioa_cfg->max_cmds;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 8995053..5b23882 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1306,6 +1306,7 @@
#define IPR_ARRAY_VIRTUAL_BUS 0x1
#define IPR_VSET_VIRTUAL_BUS 0x2
#define IPR_IOAFP_VIRTUAL_BUS 0x3
+#define IPR_MAX_SIS64_BUSES 0x4
#define IPR_GET_RES_PHYS_LOC(res) \
(((res)->bus << 24) | ((res)->target << 8) | (res)->lun)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index d605643..60c3e2b 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -882,6 +882,10 @@
static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
{
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+ struct iscsi_session *session = cls_session->dd_data;
+
+ if (WARN_ON_ONCE(session->leadconn))
+ return;
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 10ae624..9fa6a56 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3978,7 +3978,8 @@
if (!instance->ctrl_context)
return KILL_ADAPTER;
else if (instance->unload ||
- test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags))
+ test_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE,
+ &instance->reset_flags))
return IGNORE_TIMEOUT;
else
return INITIATE_OCR;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index fe1a209..874e5a7 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3438,6 +3438,7 @@
if (instance->requestorId && !instance->skip_heartbeat_timer_del)
del_timer_sync(&instance->sriov_heartbeat_timer);
set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+ set_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING);
instance->instancet->disable_intr(instance);
msleep(1000);
@@ -3594,7 +3595,7 @@
atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
}
out:
- clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+ clear_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags);
mutex_unlock(&instance->reset_mutex);
return retval;
}
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index e3bee04..034653d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -93,6 +93,7 @@
#define MEGASAS_FP_CMD_LEN 16
#define MEGASAS_FUSION_IN_RESET 0
+#define MEGASAS_FUSION_OCR_NOT_POSSIBLE 1
#define THRESHOLD_REPLY_COUNT 50
#define JBOD_MAPS_COUNT 2
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index bf29ad4..9bbea42 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -5723,9 +5723,8 @@
mcp->mb[7] = LSW(MSD(req_dma));
mcp->mb[8] = MSW(addr);
/* Setting RAM ID to valid */
- mcp->mb[10] |= BIT_7;
/* For MCTP RAM ID is 0x40 */
- mcp->mb[10] |= 0x40;
+ mcp->mb[10] = BIT_7 | 0x40;
mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
MBX_0;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 54380b4..104e13a 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1600,8 +1600,7 @@
return (u8 *)&ha->hablob->fw->data[offset];
}
-static __le32
-qla82xx_get_fw_size(struct qla_hw_data *ha)
+static u32 qla82xx_get_fw_size(struct qla_hw_data *ha)
{
struct qla82xx_uri_data_desc *uri_desc = NULL;
@@ -1612,7 +1611,7 @@
return cpu_to_le32(uri_desc->size);
}
- return cpu_to_le32(*(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET]);
+ return get_unaligned_le32(&ha->hablob->fw->data[FW_SIZE_OFFSET]);
}
static u8 *
@@ -1803,7 +1802,7 @@
}
flashaddr = FLASH_ADDR_START;
- size = (__force u32)qla82xx_get_fw_size(ha) / 8;
+ size = qla82xx_get_fw_size(ha) / 8;
ptr64 = (u64 *)qla82xx_get_fw_offs(ha);
for (i = 0; i < size; i++) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index e730aab..65bbca7 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -451,6 +451,12 @@
goto fail;
}
if (ql2xmultique_tag) {
+ ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);
+ if (unlikely(!ha->wq)) {
+ ql_log(ql_log_warn, vha, 0x01e0,
+ "Failed to alloc workqueue.\n");
+ goto fail;
+ }
/* create a request queue for IO */
options |= BIT_7;
req = qla25xx_create_req_que(ha, options, 0, 0, -1,
@@ -458,9 +464,8 @@
if (!req) {
ql_log(ql_log_warn, vha, 0x00e0,
"Failed to create request queue.\n");
- goto fail;
+ goto fail2;
}
- ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);
vha->req = ha->req_q_map[req];
options |= BIT_1;
for (ques = 1; ques < ha->max_rsp_queues; ques++) {
@@ -468,7 +473,7 @@
if (!ret) {
ql_log(ql_log_warn, vha, 0x00e8,
"Failed to create response queue.\n");
- goto fail2;
+ goto fail3;
}
}
ha->flags.cpu_affinity_enabled = 1;
@@ -482,11 +487,13 @@
ha->max_rsp_queues, ha->max_req_queues);
}
return 0;
-fail2:
+
+fail3:
qla25xx_delete_queues(vha);
- destroy_workqueue(ha->wq);
- ha->wq = NULL;
vha->req = ha->req_q_map[0];
+fail2:
+ destroy_workqueue(ha->wq);
+ ha->wq = NULL;
fail:
ha->mqenable = 0;
kfree(ha->req_q_map);
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index f714d5f..3fda583 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -4150,7 +4150,7 @@
dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues,
ha->queues_dma);
- if (ha->fw_dump)
+ if (ha->fw_dump)
vfree(ha->fw_dump);
ha->queues_len = 0;
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index ab7bc4e..fff9c4d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2964,6 +2964,24 @@
return err;
}
+static int iscsi_session_has_conns(int sid)
+{
+ struct iscsi_cls_conn *conn;
+ unsigned long flags;
+ int found = 0;
+
+ spin_lock_irqsave(&connlock, flags);
+ list_for_each_entry(conn, &connlist, conn_list) {
+ if (iscsi_conn_get_sid(conn) == sid) {
+ found = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&connlock, flags);
+
+ return found;
+}
+
static int
iscsi_set_iface_params(struct iscsi_transport *transport,
struct iscsi_uevent *ev, uint32_t len)
@@ -3538,10 +3556,12 @@
break;
case ISCSI_UEVENT_DESTROY_SESSION:
session = iscsi_session_lookup(ev->u.d_session.sid);
- if (session)
- transport->destroy_session(session);
- else
+ if (!session)
err = -EINVAL;
+ else if (iscsi_session_has_conns(ev->u.d_session.sid))
+ err = -EBUSY;
+ else
+ transport->destroy_session(session);
break;
case ISCSI_UEVENT_UNBIND_SESSION:
session = iscsi_session_lookup(ev->u.d_session.sid);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 1c4a14d..dd0fdc6 100755
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2861,9 +2861,10 @@
if (sd_validate_opt_xfer_size(sdkp, dev_max)) {
rw_max = q->limits.io_opt =
sdkp->opt_xfer_blocks * sdp->sector_size;
- } else
+ } else {
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
(sector_t)BLK_DEF_MAX_SECTORS);
+ }
/* Do not exceed controller limit */
rw_max = min(rw_max, queue_max_hw_sectors(q));
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 91403f0..95e1b25 100755
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -8112,7 +8112,8 @@
hba->dev_info.f_power_on_wp_en = flag;
/* Add required well known logical units to scsi mid layer */
- if (ufshcd_scsi_add_wlus(hba))
+ ret = ufshcd_scsi_add_wlus(hba);
+ if (ret)
goto out;
/* Initialize devfreq after UFS device is detected */
diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c
index 1e977ca..89dcd97 100644
--- a/drivers/soc/qcom/dcc_v2.c
+++ b/drivers/soc/qcom/dcc_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -299,19 +299,19 @@
ret = dcc_sram_writel(drvdata, addr, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
ret = dcc_sram_writel(drvdata,
entry->mask, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
ret = dcc_sram_writel(drvdata,
entry->write_val, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
addr = 0;
break;
}
@@ -394,18 +394,18 @@
ret = dcc_sram_writel(drvdata, addr, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
ret = dcc_sram_writel(drvdata, link, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
ret = dcc_sram_writel(drvdata,
entry->write_val, sram_offset);
if (ret)
goto overstep;
- sram_offset += 4;
+ sram_offset += 4;
addr = 0x00;
link = 0;
break;
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 64918e8..7dee607 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -67,6 +67,7 @@
HW_PLATFORM_STP = 23,
HW_PLATFORM_SBC = 24,
HW_PLATFORM_ADP = 25,
+ HW_PLATFORM_TTP = 30,
HW_PLATFORM_HDK = 31,
HW_PLATFORM_INVALID
};
@@ -89,6 +90,7 @@
[HW_PLATFORM_STP] = "STP",
[HW_PLATFORM_SBC] = "SBC",
[HW_PLATFORM_ADP] = "ADP",
+ [HW_PLATFORM_TTP] = "TTP",
[HW_PLATFORM_HDK] = "HDK",
};
diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
index 5b18f6f..cd61c88 100644
--- a/drivers/soc/tegra/fuse/tegra-apbmisc.c
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -134,7 +134,7 @@
apbmisc.flags = IORESOURCE_MEM;
/* strapping options */
- if (tegra_get_chip_id() == TEGRA124) {
+ if (of_machine_is_compatible("nvidia,tegra124")) {
straps.start = 0x7000e864;
straps.end = 0x7000e867;
} else {
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 1bfa889..88b108e 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -974,6 +974,11 @@
struct spi_qup *controller = spi_master_get_devdata(master);
int ret;
+ if (pm_runtime_suspended(device)) {
+ ret = spi_qup_pm_resume_runtime(device);
+ if (ret)
+ return ret;
+ }
ret = spi_master_suspend(master);
if (ret)
return ret;
@@ -982,10 +987,8 @@
if (ret)
return ret;
- if (!pm_runtime_suspended(device)) {
- clk_disable_unprepare(controller->cclk);
- clk_disable_unprepare(controller->iclk);
- }
+ clk_disable_unprepare(controller->cclk);
+ clk_disable_unprepare(controller->iclk);
return 0;
}
diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 18aeace..d26c0ed 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -415,9 +415,6 @@
zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry);
- /* Dummy generic FIFO entry */
- zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0);
-
/* Manually start the generic FIFO command */
zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST,
zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) |
diff --git a/drivers/staging/greybus/audio_manager.c b/drivers/staging/greybus/audio_manager.c
index aa6508b..ed7c325 100644
--- a/drivers/staging/greybus/audio_manager.c
+++ b/drivers/staging/greybus/audio_manager.c
@@ -90,8 +90,8 @@
list_for_each_entry_safe(module, next, &modules_list, list) {
list_del(&module->list);
- kobject_put(&module->kobj);
ida_simple_remove(&module_id, module->id);
+ kobject_put(&module->kobj);
}
is_empty = list_empty(&modules_list);
diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
index f7f4cd6..8d2678b 100644
--- a/drivers/staging/greybus/tools/loopback_test.c
+++ b/drivers/staging/greybus/tools/loopback_test.c
@@ -20,6 +20,7 @@
#include <signal.h>
#define MAX_NUM_DEVICES 10
+#define MAX_SYSFS_PREFIX 0x80
#define MAX_SYSFS_PATH 0x200
#define CSV_MAX_LINE 0x1000
#define SYSFS_MAX_INT 0x20
@@ -68,7 +69,7 @@
};
struct loopback_device {
- char name[MAX_SYSFS_PATH];
+ char name[MAX_STR_LEN];
char sysfs_entry[MAX_SYSFS_PATH];
char debugfs_entry[MAX_SYSFS_PATH];
struct loopback_results results;
@@ -94,8 +95,8 @@
int stop_all;
int poll_count;
char test_name[MAX_STR_LEN];
- char sysfs_prefix[MAX_SYSFS_PATH];
- char debugfs_prefix[MAX_SYSFS_PATH];
+ char sysfs_prefix[MAX_SYSFS_PREFIX];
+ char debugfs_prefix[MAX_SYSFS_PREFIX];
struct timespec poll_timeout;
struct loopback_device devices[MAX_NUM_DEVICES];
struct loopback_results aggregate_results;
@@ -646,7 +647,7 @@
static int open_poll_files(struct loopback_test *t)
{
struct loopback_device *dev;
- char buf[MAX_STR_LEN];
+ char buf[MAX_SYSFS_PATH + MAX_STR_LEN];
char dummy;
int fds_idx = 0;
int i;
@@ -917,10 +918,10 @@
t.iteration_max = atoi(optarg);
break;
case 'S':
- snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
+ snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
break;
case 'D':
- snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg);
+ snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg);
break;
case 'm':
t.mask = atol(optarg);
@@ -971,10 +972,10 @@
}
if (!strcmp(t.sysfs_prefix, ""))
- snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", sysfs_prefix);
+ snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", sysfs_prefix);
if (!strcmp(t.debugfs_prefix, ""))
- snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", debugfs_prefix);
+ snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", debugfs_prefix);
ret = find_loopback_devices(&t);
if (ret)
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index c7bf8ab..50793c9 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -2052,7 +2052,7 @@
struct ieee_param *param;
uint ret = 0;
- if (p->length < sizeof(struct ieee_param) || !p->pointer) {
+ if (!p->pointer || p->length != sizeof(struct ieee_param)) {
ret = -EINVAL;
goto out;
}
@@ -2859,7 +2859,7 @@
goto out;
}
- if (!p->pointer) {
+ if (!p->pointer || p->length != sizeof(struct ieee_param)) {
ret = -EINVAL;
goto out;
}
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index 537a99e..c140880 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -40,12 +40,14 @@
/****** 8188EUS ********/
{USB_DEVICE(0x056e, 0x4008)}, /* Elecom WDC-150SU2M */
{USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
+ {USB_DEVICE(0x0B05, 0x18F0)}, /* ASUS USB-N10 Nano B1 */
{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
{USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
{USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
{USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
+ {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */
{} /* Terminating entry */
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 97ca4ec..37bc3c6 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -565,8 +565,7 @@
return 0;
} else if ((tmpx < vc->vc_cols - 2)
&& (ch == SPACE || ch == 0 || IS_WDLM(ch))
- && ((char)get_char(vc, (u_short *) &tmp_pos + 1, &temp) >
- SPACE)) {
+ && ((char)get_char(vc, (u_short *)tmp_pos + 1, &temp) > SPACE)) {
tmp_pos += 2;
tmpx++;
} else
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index 655f000..7b73fa2 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -140,7 +140,7 @@
vnt_rf_rssi_to_dbm(priv, *rssi, &rx_dbm);
- priv->bb_pre_ed_rssi = (u8)rx_dbm + 1;
+ priv->bb_pre_ed_rssi = (u8)-rx_dbm + 1;
priv->current_rssi = priv->bb_pre_ed_rssi;
frame = skb_data + 8;
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 6a107f8..52ad5c1 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -3443,6 +3443,8 @@
WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
pr_debug("overlen frm: len=%zd\n",
skblen - sizeof(struct p80211_caphdr));
+
+ return;
}
skb = dev_alloc_skb(skblen);
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index bfb6b0a..f7149bb 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -179,6 +179,7 @@
cancel_work_sync(&hw->link_bh);
cancel_work_sync(&hw->commsqual_bh);
+ cancel_work_sync(&hw->usb_work);
/* Now we complete any outstanding commands
* and tell everyone who is waiting for their
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 9636d87..b6c4f55 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1168,9 +1168,7 @@
hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
conn->cid);
- if (target_get_sess_cmd(&cmd->se_cmd, true) < 0)
- return iscsit_add_reject_cmd(cmd,
- ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
+ target_get_sess_cmd(&cmd->se_cmd, true);
cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
scsilun_to_int(&hdr->lun));
@@ -1988,9 +1986,7 @@
conn->sess->se_sess, 0, DMA_NONE,
TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
- if (target_get_sess_cmd(&cmd->se_cmd, true) < 0)
- return iscsit_add_reject_cmd(cmd,
- ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
+ target_get_sess_cmd(&cmd->se_cmd, true);
/*
* TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4162,6 +4158,9 @@
iscsit_stop_nopin_response_timer(conn);
iscsit_stop_nopin_timer(conn);
+ if (conn->conn_transport->iscsit_wait_conn)
+ conn->conn_transport->iscsit_wait_conn(conn);
+
/*
* During Connection recovery drop unacknowledged out of order
* commands for this connection, and prepare the other commands
@@ -4244,11 +4243,6 @@
* must wait until they have completed.
*/
iscsit_check_conn_usage_count(conn);
- target_sess_cmd_list_set_waiting(sess->se_sess);
- target_wait_for_sess_cmds(sess->se_sess);
-
- if (conn->conn_transport->iscsit_wait_conn)
- conn->conn_transport->iscsit_wait_conn(conn);
ahash_request_free(conn->conn_tx_hash);
if (conn->conn_rx_hash) {
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index e8819aa..c4e9eba 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -181,7 +181,7 @@
struct hlist_head *h;
struct hlist_node *n;
struct irq_info *i;
- int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+ int ret;
mutex_lock(&hash_mutex);
@@ -216,9 +216,8 @@
INIT_LIST_HEAD(&up->list);
i->head = &up->list;
spin_unlock_irq(&i->lock);
- irq_flags |= up->port.irqflags;
ret = request_irq(up->port.irq, serial8250_interrupt,
- irq_flags, "serial", i);
+ up->port.irqflags, "serial", i);
if (ret < 0)
serial_do_unlink(i, up);
}
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 8f12333..c7a7574 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2199,6 +2199,10 @@
}
}
+ /* Check if we need to have shared IRQs */
+ if (port->irq && (up->port.flags & UPF_SHARE_IRQ))
+ up->port.irqflags |= IRQF_SHARED;
+
if (port->irq) {
unsigned char iir1;
/*
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
index d446251..246f4aa 100644
--- a/drivers/tty/serial/ar933x_uart.c
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -289,6 +289,10 @@
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_HOST_INT_EN);
+ /* enable RX and TX ready overide */
+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
+
/* reenable the UART */
ar933x_uart_rmw(up, AR933X_UART_CS_REG,
AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
@@ -421,6 +425,10 @@
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_HOST_INT_EN);
+ /* enable RX and TX ready overide */
+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE);
+
/* Enable RX interrupts */
up->ier = AR933X_UART_INT_RX_VALID;
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 325f9db..4a7eb85 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -501,7 +501,8 @@
atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
if (atmel_uart_is_half_duplex(port))
- atmel_start_rx(port);
+ if (!atomic_read(&atmel_port->tasklet_shutdown))
+ atmel_start_rx(port);
}
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e75bd8d..325c38c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -532,7 +532,7 @@
sport->tx_bytes = uart_circ_chars_pending(xmit);
- if (xmit->tail < xmit->head) {
+ if (xmit->tail < xmit->head || xmit->head == 0) {
sport->dma_tx_nents = 1;
sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
} else {
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 401c983..a10e4aa 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -581,7 +581,7 @@
port->membase = devm_ioremap_resource(&pdev->dev, reg);
if (IS_ERR(port->membase))
- return -PTR_ERR(port->membase);
+ return PTR_ERR(port->membase);
data = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart_data),
GFP_KERNEL);
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index e645ee1..7446ce2 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -1349,10 +1349,10 @@
DBGINFO(("%s throttle\n", info->device_name));
if (I_IXOFF(tty))
send_xchar(tty, STOP_CHAR(tty));
- if (C_CRTSCTS(tty)) {
+ if (C_CRTSCTS(tty)) {
spin_lock_irqsave(&info->lock,flags);
info->signals &= ~SerialSignal_RTS;
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
}
@@ -1374,10 +1374,10 @@
else
send_xchar(tty, START_CHAR(tty));
}
- if (C_CRTSCTS(tty)) {
+ if (C_CRTSCTS(tty)) {
spin_lock_irqsave(&info->lock,flags);
info->signals |= SerialSignal_RTS;
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
}
@@ -2576,8 +2576,8 @@
info->read_status_mask = IRQ_RXOVER;
if (I_INPCK(info->port.tty))
info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
- if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
- info->read_status_mask |= MASK_BREAK;
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
+ info->read_status_mask |= MASK_BREAK;
if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
if (I_IGNBRK(info->port.tty)) {
@@ -3208,7 +3208,7 @@
info->signals &= ~SerialSignal_DTR;
spin_lock_irqsave(&info->lock,flags);
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
return 0;
}
@@ -3219,7 +3219,7 @@
struct slgt_info *info = container_of(port, struct slgt_info, port);
spin_lock_irqsave(&info->lock,flags);
- get_signals(info);
+ get_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
return (info->signals & SerialSignal_DCD) ? 1 : 0;
}
@@ -3234,7 +3234,7 @@
info->signals |= SerialSignal_RTS | SerialSignal_DTR;
else
info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index dec1565..2f6df8d 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -1467,10 +1467,10 @@
if (I_IXOFF(tty))
send_xchar(tty, STOP_CHAR(tty));
- if (C_CRTSCTS(tty)) {
+ if (C_CRTSCTS(tty)) {
spin_lock_irqsave(&info->lock,flags);
info->serial_signals &= ~SerialSignal_RTS;
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
}
@@ -1496,10 +1496,10 @@
send_xchar(tty, START_CHAR(tty));
}
- if (C_CRTSCTS(tty)) {
+ if (C_CRTSCTS(tty)) {
spin_lock_irqsave(&info->lock,flags);
info->serial_signals |= SerialSignal_RTS;
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
}
@@ -2485,7 +2485,7 @@
if (status & SerialSignal_CTS) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx start...");
- info->port.tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
tx_start(info);
info->pending_bh |= BH_TRANSMIT;
return;
@@ -2494,7 +2494,7 @@
if (!(status & SerialSignal_CTS)) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx stop...");
- info->port.tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
tx_stop(info);
}
}
@@ -2821,8 +2821,8 @@
info->read_status_mask2 = OVRN;
if (I_INPCK(info->port.tty))
info->read_status_mask2 |= PE | FRME;
- if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
- info->read_status_mask1 |= BRKD;
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
+ info->read_status_mask1 |= BRKD;
if (I_IGNPAR(info->port.tty))
info->ignore_status_mask2 |= PE | FRME;
if (I_IGNBRK(info->port.tty)) {
@@ -3192,7 +3192,7 @@
unsigned long flags;
spin_lock_irqsave(&info->lock,flags);
- get_signals(info);
+ get_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS : 0) |
@@ -3230,7 +3230,7 @@
info->serial_signals &= ~SerialSignal_DTR;
spin_lock_irqsave(&info->lock,flags);
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
return 0;
@@ -3242,7 +3242,7 @@
unsigned long flags;
spin_lock_irqsave(&info->lock,flags);
- get_signals(info);
+ get_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
@@ -3258,7 +3258,7 @@
info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
else
info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
- set_signals(info);
+ set_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
}
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 547bd21..89fada4 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -544,7 +544,6 @@
*/
orig_log_level = console_loglevel;
console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
- pr_info("SysRq : ");
op_p = __sysrq_get_key_op(key);
if (op_p) {
@@ -553,14 +552,15 @@
* should not) and is the invoked operation enabled?
*/
if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
- pr_cont("%s\n", op_p->action_msg);
+ pr_info("%s\n", op_p->action_msg);
console_loglevel = orig_log_level;
op_p->handler(key);
} else {
- pr_cont("This sysrq operation is disabled.\n");
+ pr_info("This sysrq operation is disabled.\n");
+ console_loglevel = orig_log_level;
}
} else {
- pr_cont("HELP : ");
+ pr_info("HELP : ");
/* Only print the help msg once per handler */
for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
if (sysrq_key_table[i]) {
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 368ce18..225689c 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -13,6 +13,7 @@
#include <linux/tty.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -40,6 +41,7 @@
static int sel_end;
static int sel_buffer_lth;
static char *sel_buffer;
+static DEFINE_MUTEX(sel_lock);
/* clear_selection, highlight and highlight_pointer can be called
from interrupt (via scrollback/front) */
@@ -78,6 +80,11 @@
}
}
+bool vc_is_sel(struct vc_data *vc)
+{
+ return vc == sel_cons;
+}
+
/*
* User settable table: what characters are to be considered alphabetic?
* 256 bits. Locked by the console lock.
@@ -156,14 +163,14 @@
* The entire selection process is managed under the console_lock. It's
* a lot under the lock but its hardly a performance path
*/
-int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
+static int __set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
{
struct vc_data *vc = vc_cons[fg_console].d;
int sel_mode, new_sel_start, new_sel_end, spc;
char *bp, *obp;
int i, ps, pe, multiplier;
u16 c;
- int mode;
+ int mode, ret = 0;
poke_blanked_console();
@@ -324,7 +331,21 @@
}
}
sel_buffer_lth = bp - sel_buffer;
- return 0;
+
+ return ret;
+}
+
+int set_selection(const struct tiocl_selection __user *v, struct tty_struct *tty)
+{
+ int ret;
+
+ mutex_lock(&sel_lock);
+ console_lock();
+ ret = __set_selection(v, tty);
+ console_unlock();
+ mutex_unlock(&sel_lock);
+
+ return ret;
}
/* Insert the contents of the selection buffer into the
@@ -341,6 +362,7 @@
unsigned int count;
struct tty_ldisc *ld;
DECLARE_WAITQUEUE(wait, current);
+ int ret = 0;
console_lock();
poke_blanked_console();
@@ -352,10 +374,17 @@
tty_buffer_lock_exclusive(&vc->port);
add_wait_queue(&vc->paste_wait, &wait);
+ mutex_lock(&sel_lock);
while (sel_buffer && sel_buffer_lth > pasted) {
set_current_state(TASK_INTERRUPTIBLE);
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
if (tty_throttled(tty)) {
+ mutex_unlock(&sel_lock);
schedule();
+ mutex_lock(&sel_lock);
continue;
}
__set_current_state(TASK_RUNNING);
@@ -364,10 +393,11 @@
count);
pasted += count;
}
+ mutex_unlock(&sel_lock);
remove_wait_queue(&vc->paste_wait, &wait);
__set_current_state(TASK_RUNNING);
tty_buffer_unlock_exclusive(&vc->port);
tty_ldisc_deref(ld);
- return 0;
+ return ret;
}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 232cb0a..29fb08c8 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -595,8 +595,9 @@
static void hide_cursor(struct vc_data *vc)
{
- if (vc == sel_cons)
+ if (vc_is_sel(vc))
clear_selection();
+
vc->vc_sw->con_cursor(vc, CM_ERASE);
hide_softcursor(vc);
}
@@ -606,7 +607,7 @@
if (!con_is_fg(vc) || console_blanked || vc->vc_mode == KD_GRAPHICS)
return;
if (vc->vc_deccm) {
- if (vc == sel_cons)
+ if (vc_is_sel(vc))
clear_selection();
add_softcursor(vc);
if ((vc->vc_cursor_type & 0x0f) != 1)
@@ -753,6 +754,17 @@
vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
}
+static void vc_port_destruct(struct tty_port *port)
+{
+ struct vc_data *vc = container_of(port, struct vc_data, port);
+
+ kfree(vc);
+}
+
+static const struct tty_port_operations vc_port_ops = {
+ .destruct = vc_port_destruct,
+};
+
int vc_allocate(unsigned int currcons) /* return 0 on success */
{
struct vt_notifier_param param;
@@ -778,6 +790,7 @@
vc_cons[currcons].d = vc;
tty_port_init(&vc->port);
+ vc->port.ops = &vc_port_ops;
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
visual_init(vc, currcons, 1);
@@ -876,7 +889,7 @@
if (!newscreen)
return -ENOMEM;
- if (vc == sel_cons)
+ if (vc_is_sel(vc))
clear_selection();
old_rows = vc->vc_rows;
@@ -2690,9 +2703,7 @@
switch (type)
{
case TIOCL_SETSEL:
- console_lock();
ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
- console_unlock();
break;
case TIOCL_PASTESEL:
ret = paste_selection(tty);
@@ -2898,6 +2909,7 @@
tty->driver_data = vc;
vc->port.tty = tty;
+ tty_port_get(&vc->port);
if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
@@ -2933,6 +2945,13 @@
console_unlock();
}
+static void con_cleanup(struct tty_struct *tty)
+{
+ struct vc_data *vc = tty->driver_data;
+
+ tty_port_put(&vc->port);
+}
+
static int default_color = 7; /* white */
static int default_italic_color = 2; // green (ASCII)
static int default_underline_color = 3; // cyan (ASCII)
@@ -3057,7 +3076,8 @@
.throttle = con_throttle,
.unthrottle = con_unthrottle,
.resize = vt_resize,
- .shutdown = con_shutdown
+ .shutdown = con_shutdown,
+ .cleanup = con_cleanup,
};
static struct cdev vc0_cdev;
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 638eb9b..4ed0d77 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -38,11 +38,32 @@
#include <linux/kbd_diacr.h>
#include <linux/selection.h>
-char vt_dont_switch;
-extern struct tty_driver *console_driver;
+bool vt_dont_switch;
-#define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count)
-#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
+static inline bool vt_in_use(unsigned int i)
+{
+ const struct vc_data *vc = vc_cons[i].d;
+
+ /*
+ * console_lock must be held to prevent the vc from being deallocated
+ * while we're checking whether it's in-use.
+ */
+ WARN_CONSOLE_UNLOCKED();
+
+ return vc && kref_read(&vc->port.kref) > 1;
+}
+
+static inline bool vt_busy(int i)
+{
+ if (vt_in_use(i))
+ return true;
+ if (i == fg_console)
+ return true;
+ if (vc_is_sel(vc_cons[i].d))
+ return true;
+
+ return false;
+}
/*
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
@@ -292,16 +313,14 @@
int ret = 0;
console_lock();
- if (VT_BUSY(vc_num))
+ if (vt_busy(vc_num))
ret = -EBUSY;
else if (vc_num)
vc = vc_deallocate(vc_num);
console_unlock();
- if (vc && vc_num >= MIN_NR_CONSOLES) {
- tty_port_destroy(&vc->port);
- kfree(vc);
- }
+ if (vc && vc_num >= MIN_NR_CONSOLES)
+ tty_port_put(&vc->port);
return ret;
}
@@ -314,17 +333,15 @@
console_lock();
for (i = 1; i < MAX_NR_CONSOLES; i++)
- if (!VT_BUSY(i))
+ if (!vt_busy(i))
vc[i] = vc_deallocate(i);
else
vc[i] = NULL;
console_unlock();
for (i = 1; i < MAX_NR_CONSOLES; i++) {
- if (vc[i] && i >= MIN_NR_CONSOLES) {
- tty_port_destroy(&vc[i]->port);
- kfree(vc[i]);
- }
+ if (vc[i] && i >= MIN_NR_CONSOLES)
+ tty_port_put(&vc[i]->port);
}
}
@@ -338,22 +355,13 @@
{
struct vc_data *vc = tty->driver_data;
struct console_font_op op; /* used in multiple places here */
- unsigned int console;
+ unsigned int console = vc->vc_num;
unsigned char ucval;
unsigned int uival;
void __user *up = (void __user *)arg;
int i, perm;
int ret = 0;
- console = vc->vc_num;
-
-
- if (!vc_cons_allocated(console)) { /* impossible? */
- ret = -ENOIOCTLCMD;
- goto out;
- }
-
-
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
@@ -644,15 +652,16 @@
struct vt_stat __user *vtstat = up;
unsigned short state, mask;
- /* Review: FIXME: Console lock ? */
if (put_user(fg_console + 1, &vtstat->v_active))
ret = -EFAULT;
else {
state = 1; /* /dev/tty0 is always open */
+ console_lock(); /* required by vt_in_use() */
for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
++i, mask <<= 1)
- if (VT_IS_IN_USE(i))
+ if (vt_in_use(i))
state |= mask;
+ console_unlock();
ret = put_user(state, &vtstat->v_state);
}
break;
@@ -662,10 +671,11 @@
* Returns the first available (non-opened) console.
*/
case VT_OPENQRY:
- /* FIXME: locking ? - but then this is a stupid API */
+ console_lock(); /* required by vt_in_use() */
for (i = 0; i < MAX_NR_CONSOLES; ++i)
- if (! VT_IS_IN_USE(i))
+ if (!vt_in_use(i))
break;
+ console_unlock();
uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
goto setint;
@@ -850,58 +860,49 @@
case VT_RESIZEX:
{
- struct vt_consize __user *vtconsize = up;
- ushort ll,cc,vlin,clin,vcol,ccol;
+ struct vt_consize v;
if (!perm)
return -EPERM;
- if (!access_ok(VERIFY_READ, vtconsize,
- sizeof(struct vt_consize))) {
- ret = -EFAULT;
- break;
- }
+ if (copy_from_user(&v, up, sizeof(struct vt_consize)))
+ return -EFAULT;
/* FIXME: Should check the copies properly */
- __get_user(ll, &vtconsize->v_rows);
- __get_user(cc, &vtconsize->v_cols);
- __get_user(vlin, &vtconsize->v_vlin);
- __get_user(clin, &vtconsize->v_clin);
- __get_user(vcol, &vtconsize->v_vcol);
- __get_user(ccol, &vtconsize->v_ccol);
- vlin = vlin ? vlin : vc->vc_scan_lines;
- if (clin) {
- if (ll) {
- if (ll != vlin/clin) {
- /* Parameters don't add up */
- ret = -EINVAL;
- break;
- }
- } else
- ll = vlin/clin;
+ if (!v.v_vlin)
+ v.v_vlin = vc->vc_scan_lines;
+ if (v.v_clin) {
+ int rows = v.v_vlin/v.v_clin;
+ if (v.v_rows != rows) {
+ if (v.v_rows) /* Parameters don't add up */
+ return -EINVAL;
+ v.v_rows = rows;
+ }
}
- if (vcol && ccol) {
- if (cc) {
- if (cc != vcol/ccol) {
- ret = -EINVAL;
- break;
- }
- } else
- cc = vcol/ccol;
+ if (v.v_vcol && v.v_ccol) {
+ int cols = v.v_vcol/v.v_ccol;
+ if (v.v_cols != cols) {
+ if (v.v_cols)
+ return -EINVAL;
+ v.v_cols = cols;
+ }
}
- if (clin > 32) {
- ret = -EINVAL;
- break;
- }
-
+ if (v.v_clin > 32)
+ return -EINVAL;
+
for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ struct vc_data *vcp;
+
if (!vc_cons[i].d)
continue;
console_lock();
- if (vlin)
- vc_cons[i].d->vc_scan_lines = vlin;
- if (clin)
- vc_cons[i].d->vc_font.height = clin;
- vc_cons[i].d->vc_resize_user = 1;
- vc_resize(vc_cons[i].d, cc, ll);
+ vcp = vc_cons[i].d;
+ if (vcp) {
+ if (v.v_vlin)
+ vcp->vc_scan_lines = v.v_vlin;
+ if (v.v_clin)
+ vcp->vc_font.height = v.v_clin;
+ vcp->vc_resize_user = 1;
+ vc_resize(vcp, v.v_cols, v.v_rows);
+ }
console_unlock();
}
break;
@@ -1023,12 +1024,12 @@
case VT_LOCKSWITCH:
if (!capable(CAP_SYS_TTY_CONFIG))
return -EPERM;
- vt_dont_switch = 1;
+ vt_dont_switch = true;
break;
case VT_UNLOCKSWITCH:
if (!capable(CAP_SYS_TTY_CONFIG))
return -EPERM;
- vt_dont_switch = 0;
+ vt_dont_switch = false;
break;
case VT_GETHIFONTMASK:
ret = put_user(vc->vc_hi_font_mask,
@@ -1196,18 +1197,10 @@
{
struct vc_data *vc = tty->driver_data;
struct console_font_op op; /* used in multiple places here */
- unsigned int console;
void __user *up = (void __user *)arg;
int perm;
int ret = 0;
- console = vc->vc_num;
-
- if (!vc_cons_allocated(console)) { /* impossible? */
- ret = -ENOIOCTLCMD;
- goto out;
- }
-
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
@@ -1267,7 +1260,7 @@
arg = (unsigned long)compat_ptr(arg);
goto fallback;
}
-out:
+
return ret;
fallback:
diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
index e1134a4..a00b4ae 100644
--- a/drivers/uio/uio_dmem_genirq.c
+++ b/drivers/uio/uio_dmem_genirq.c
@@ -135,11 +135,13 @@
if (irq_on) {
if (test_and_clear_bit(0, &priv->flags))
enable_irq(dev_info->irq);
+ spin_unlock_irqrestore(&priv->lock, flags);
} else {
- if (!test_and_set_bit(0, &priv->flags))
+ if (!test_and_set_bit(0, &priv->flags)) {
+ spin_unlock_irqrestore(&priv->lock, flags);
disable_irq(dev_info->irq);
+ }
}
- spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index b2edbd4..5b0bffba 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -828,10 +828,10 @@
tmp.flags = ASYNC_LOW_LATENCY;
tmp.xmit_fifo_size = acm->writesize;
tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
- tmp.close_delay = acm->port.close_delay / 10;
+ tmp.close_delay = jiffies_to_msecs(acm->port.close_delay) / 10;
tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
ASYNC_CLOSING_WAIT_NONE :
- acm->port.closing_wait / 10;
+ jiffies_to_msecs(acm->port.closing_wait) / 10;
if (copy_to_user(info, &tmp, sizeof(tmp)))
return -EFAULT;
@@ -844,20 +844,28 @@
{
struct serial_struct new_serial;
unsigned int closing_wait, close_delay;
+ unsigned int old_closing_wait, old_close_delay;
int retval = 0;
if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
return -EFAULT;
- close_delay = new_serial.close_delay * 10;
+ close_delay = msecs_to_jiffies(new_serial.close_delay * 10);
closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
- ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
+ ASYNC_CLOSING_WAIT_NONE :
+ msecs_to_jiffies(new_serial.closing_wait * 10);
+
+ /* we must redo the rounding here, so that the values match */
+ old_close_delay = jiffies_to_msecs(acm->port.close_delay) / 10;
+ old_closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
+ ASYNC_CLOSING_WAIT_NONE :
+ jiffies_to_msecs(acm->port.closing_wait) / 10;
mutex_lock(&acm->port.mutex);
if (!capable(CAP_SYS_ADMIN)) {
- if ((close_delay != acm->port.close_delay) ||
- (closing_wait != acm->port.closing_wait))
+ if ((new_serial.close_delay != old_close_delay) ||
+ (new_serial.closing_wait != old_closing_wait))
retval = -EPERM;
else
retval = -EOPNOTSUPP;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 5121d26..25379bd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -965,13 +965,17 @@
{
struct usb_hub *hub;
struct usb_interface *intf;
+ int ret;
if (!udev->parent) /* Can't remove a root hub */
return -EINVAL;
hub = usb_hub_to_struct_hub(udev->parent);
intf = to_usb_interface(hub->intfdev);
- usb_autopm_get_interface(intf);
+ ret = usb_autopm_get_interface(intf);
+ if (ret < 0)
+ return ret;
+
set_bit(udev->portnum, hub->removed_bits);
hub_port_logical_disconnect(hub, udev->portnum);
usb_autopm_put_interface(intf);
@@ -1198,11 +1202,6 @@
#ifdef CONFIG_PM
udev->reset_resume = 1;
#endif
- /* Don't set the change_bits when the device
- * was powered off.
- */
- if (test_bit(port1, hub->power_bits))
- set_bit(port1, hub->change_bits);
} else {
/* The power session is gone; tell hub_wq */
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 460c855..53c1f6e 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -179,7 +179,10 @@
if (!port_dev->is_superspeed && peer)
pm_runtime_get_sync(&peer->dev);
- usb_autopm_get_interface(intf);
+ retval = usb_autopm_get_interface(intf);
+ if (retval < 0)
+ return retval;
+
retval = usb_hub_set_port_power(hdev, hub, port1, true);
msleep(hub_power_on_good_delay(hub));
if (udev && !retval) {
@@ -232,7 +235,10 @@
if (usb_port_block_power_off)
return -EBUSY;
- usb_autopm_get_interface(intf);
+ retval = usb_autopm_get_interface(intf);
+ if (retval < 0)
+ return retval;
+
retval = usb_hub_set_port_power(hdev, hub, port1, false);
usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
if (!port_dev->is_superspeed)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 19e819a..6c4bb47 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -86,6 +86,9 @@
/* Logitech PTZ Pro Camera */
{ USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
+ /* Logitech Screen Share */
+ { USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM },
+
/* Logitech Quickcam Fusion */
{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
@@ -226,6 +229,12 @@
{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+ /* Realtek hub in Dell WD19 (Type-C) */
+ { USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM },
+
+ /* Generic RTL8153 based ethernet adapters */
+ { USB_DEVICE(0x0bda, 0x8153), .driver_info = USB_QUIRK_NO_LPM },
+
/* Action Semiconductor flash disk */
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
@@ -291,6 +300,9 @@
/* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* novation SoundControl XL */
+ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME },
+
{ } /* terminating entry must be last */
};
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 3d98684..e6700b8 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -54,6 +54,10 @@
#include "dbm.h"
#include "debug.h"
#include "xhci.h"
+#ifdef CONFIG_TUSB1064_XR_MISC
+#include "../../misc/tusb1064.h"
+#endif
+
#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */
@@ -2956,9 +2960,13 @@
EXTCON_PROP_USB_TYPEC_POLARITY, &val);
if (ret)
mdwc->typec_orientation = ORIENTATION_NONE;
- else
+ else {
mdwc->typec_orientation = val.intval ?
ORIENTATION_CC2 : ORIENTATION_CC1;
+#ifdef CONFIG_TUSB1064_XR_MISC
+ tusb1064_usb_event(val.intval ? true : false);
+#endif
+ }
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 12331e5..6b4bba8 100755
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -25,17 +25,6 @@
#include <asm/unaligned.h>
#include "u_os_desc.h"
-#define SSUSB_GADGET_VBUS_DRAW 900 /* in mA */
-#define SSUSB_GADGET_VBUS_DRAW_UNITS 8
-#define HSUSB_GADGET_VBUS_DRAW_UNITS 2
-
-/*
- * Based on enumerated USB speed, draw power with set_config and resume
- * HSUSB: 500mA, SSUSB: 900mA
- */
-#define USB_VBUS_DRAW(speed)\
- (speed == USB_SPEED_SUPER ?\
- SSUSB_GADGET_VBUS_DRAW : CONFIG_USB_GADGET_VBUS_DRAW)
/* disable LPM by default */
static bool disable_l1_for_hs;
@@ -569,16 +558,22 @@
static u8 encode_bMaxPower(enum usb_device_speed speed,
struct usb_configuration *c)
{
- unsigned int val = CONFIG_USB_GADGET_VBUS_DRAW;
+ unsigned val;
- switch (speed) {
- case USB_SPEED_SUPER:
- /* with super-speed report 900mA */
- val = SSUSB_GADGET_VBUS_DRAW;
- return (u8)(val / SSUSB_GADGET_VBUS_DRAW_UNITS);
- default:
- return DIV_ROUND_UP(val, HSUSB_GADGET_VBUS_DRAW_UNITS);
- }
+ if (c->MaxPower)
+ val = c->MaxPower;
+ else
+ val = CONFIG_USB_GADGET_VBUS_DRAW;
+ if (!val)
+ return 0;
+ if (speed < USB_SPEED_SUPER)
+ return min(val, 500U) / 2;
+ else
+ /*
+ * USB 3.x supports up to 900mA, but since 900 isn't divisible
+ * by 8 the integral division will effectively cap to 896mA.
+ */
+ return min(val, 900U) / 8;
}
static int config_buf(struct usb_configuration *config,
@@ -897,6 +892,7 @@
struct usb_gadget *gadget = cdev->gadget;
struct usb_configuration *c = NULL;
int result = -EINVAL;
+ unsigned power = gadget_is_otg(gadget) ? 8 : 100;
int tmp;
if (number) {
@@ -986,8 +982,14 @@
}
}
+ /* when we return, be sure our power usage is valid */
+ power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
+ if (gadget->speed < USB_SPEED_SUPER)
+ power = min(power, 500U);
+ else
+ power = min(power, 900U);
done:
- usb_gadget_vbus_draw(gadget, USB_VBUS_DRAW(gadget->speed));
+ usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status)
result = USB_GADGET_DELAYED_STATUS;
return result;
@@ -2487,6 +2489,7 @@
{
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
+ unsigned maxpower;
int ret;
unsigned long flags;
@@ -2528,7 +2531,14 @@
f->resume(f);
}
- usb_gadget_vbus_draw(gadget, USB_VBUS_DRAW(gadget->speed));
+ maxpower = cdev->config->MaxPower ?
+ cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
+ if (gadget->speed < USB_SPEED_SUPER)
+ maxpower = min(maxpower, 500U);
+ else
+ maxpower = min(maxpower, 900U);
+
+ usb_gadget_vbus_draw(gadget, maxpower);
}
spin_unlock_irqrestore(&cdev->lock, flags);
diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c
index 5453df1..c9bd871 100644
--- a/drivers/usb/gadget/function/f_cdev.c
+++ b/drivers/usb/gadget/function/f_cdev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2013-2020, The Linux Foundation. All rights reserved.
* Linux Foundation chooses to take subject only to the GPLv2 license terms,
* and distributes only under these terms.
*
@@ -58,6 +58,7 @@
#define BRIDGE_RX_BUF_SIZE 2048
#define BRIDGE_TX_QUEUE_SIZE 8
#define BRIDGE_TX_BUF_SIZE 2048
+#define BRIDGE_RX_BUF_SIZE_STANDALONE (50 * 1024)
#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
@@ -350,6 +351,9 @@
NULL,
};
+static bool standalone_mode;
+static unsigned int bridge_rx_buf_size = BRIDGE_RX_BUF_SIZE;
+
static inline struct f_cdev *func_to_port(struct usb_function *f)
{
return container_of(f, struct f_cdev, port_usb.func);
@@ -952,7 +956,7 @@
req = list_entry(pool->next, struct usb_request, list);
list_del_init(&req->list);
- req->length = BRIDGE_RX_BUF_SIZE;
+ req->length = bridge_rx_buf_size;
req->complete = usb_cser_read_complete;
spin_unlock_irqrestore(&port->port_lock, flags);
ret = usb_ep_queue(ep, req, GFP_KERNEL);
@@ -1046,7 +1050,7 @@
ret = usb_cser_alloc_requests(port->port_usb.out,
&port->read_pool,
- BRIDGE_RX_QUEUE_SIZE, BRIDGE_RX_BUF_SIZE, 0,
+ BRIDGE_RX_QUEUE_SIZE, bridge_rx_buf_size, 0,
usb_cser_read_complete);
if (ret) {
pr_err("unable to allocate out requests\n");
@@ -1247,6 +1251,8 @@
current_rx_req = NULL;
current_rx_buf = NULL;
}
+ if (standalone_mode)
+ break;
}
port->pending_rx_bytes = pending_rx_bytes;
@@ -2059,6 +2065,28 @@
return &port->port_usb.func;
}
+static int __init f_cdev_init(void)
+{
+ char *cmdline;
+
+ cmdline = strnstr(boot_command_line,
+ "msm_drm.dsi_display0=dsi_sim_vid_display",
+ strlen(boot_command_line));
+ if (cmdline) {
+ pr_debug("%s tethered mode cmdline:%s\n",
+ __func__, cmdline);
+ standalone_mode = false;
+ bridge_rx_buf_size = BRIDGE_RX_BUF_SIZE;
+ } else {
+ pr_debug("%s standalone mode cmdline:\n",
+ __func__);
+ standalone_mode = true;
+ bridge_rx_buf_size = BRIDGE_RX_BUF_SIZE_STANDALONE;
+ }
+ return 0;
+}
+device_initcall(f_cdev_init);
+
DECLARE_USB_FUNCTION_INIT(cser, cser_alloc_inst, cser_alloc);
MODULE_DESCRIPTION("USB Serial Character Driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c
index f7dfb0a..a3a4e5d 100644
--- a/drivers/usb/gadget/function/f_ecm.c
+++ b/drivers/usb/gadget/function/f_ecm.c
@@ -56,6 +56,7 @@
struct usb_ep *notify;
struct usb_request *notify_req;
u8 notify_state;
+ atomic_t notify_count;
bool is_open;
/* FIXME is_open needs some irq-ish locking
@@ -384,7 +385,7 @@
int status;
/* notification already in flight? */
- if (!req)
+ if (atomic_read(&ecm->notify_count))
return;
event = req->buf;
@@ -424,10 +425,10 @@
event->bmRequestType = 0xA1;
event->wIndex = cpu_to_le16(ecm->ctrl_id);
- ecm->notify_req = NULL;
+ atomic_inc(&ecm->notify_count);
status = usb_ep_queue(ecm->notify, req, GFP_ATOMIC);
if (status < 0) {
- ecm->notify_req = req;
+ atomic_dec(&ecm->notify_count);
DBG(cdev, "notify --> %d\n", status);
}
}
@@ -452,17 +453,19 @@
switch (req->status) {
case 0:
/* no fault */
+ atomic_dec(&ecm->notify_count);
break;
case -ECONNRESET:
case -ESHUTDOWN:
+ atomic_set(&ecm->notify_count, 0);
ecm->notify_state = ECM_NOTIFY_NONE;
break;
default:
DBG(cdev, "event %02x --> %d\n",
event->bNotificationType, req->status);
+ atomic_dec(&ecm->notify_count);
break;
}
- ecm->notify_req = req;
ecm_do_notify(ecm);
}
@@ -922,6 +925,11 @@
usb_free_all_descriptors(f);
+ if (atomic_read(&ecm->notify_count)) {
+ usb_ep_dequeue(ecm->notify, ecm->notify_req);
+ atomic_set(&ecm->notify_count, 0);
+ }
+
kfree(ecm->notify_req->buf);
usb_ep_free_request(ecm->notify, ecm->notify_req);
opts->bound = false;
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index fa1544be..7c6db0d 100755
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1296,6 +1296,7 @@
{
struct ffs_io_data *io_data = kiocb->private;
struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
+ unsigned long flags;
int value;
ENTER();
@@ -1303,14 +1304,14 @@
ffs_log("enter:state %d setup_state %d flag %lu", epfile->ffs->state,
epfile->ffs->setup_state, epfile->ffs->flags);
- spin_lock_irq(&epfile->ffs->eps_lock);
+ spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
if (likely(io_data && io_data->ep && io_data->req))
value = usb_ep_dequeue(io_data->ep, io_data->req);
else
value = -EINVAL;
- spin_unlock_irq(&epfile->ffs->eps_lock);
+ spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
ffs_log("exit: value %d", value);
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index f252d32..2524146 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -73,6 +73,7 @@
static void gsi_free_trb_buffer(struct f_gsi *gsi);
static struct gsi_ctrl_pkt *gsi_ctrl_pkt_alloc(unsigned int len, gfp_t flags);
static void gsi_ctrl_pkt_free(struct gsi_ctrl_pkt *pkt);
+static int gsi_ctrl_send_cpkt_tomodem(struct f_gsi *gsi, void *buf, size_t len);
static inline bool is_ext_prot_ether(int prot_id)
{
@@ -740,6 +741,12 @@
ipa_out_channel_out_params.db_reg_phs_addr_msb;
}
+ /* Send 0 byte packet to QTI only if DTR linetstate is HIGH already */
+ if (gsi->rmnet_dtr_status &&
+ (gsi->prot_id == USB_PROT_RMNET_IPA ||
+ gsi->prot_id == USB_PROT_RMNET_V2X_IPA))
+ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
+
return ret;
end_xfer_ep_out:
@@ -2220,6 +2227,14 @@
queue_work(gsi->c_port.uevent_wq,
&gsi->c_port.uevent_work);
+ /* Send 0 byte packet to QTI only if IPA connect is done */
+ if (gsi->rmnet_dtr_status) {
+ if (gsi->prot_id == USB_PROT_RMNET_ETHER)
+ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
+ else if (gsi->d_port.in_channel_handle != -EINVAL)
+ gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
+ }
+
value = 0;
break;
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
@@ -2624,10 +2639,7 @@
if (gsi->prot_id == USB_PROT_DIAG_IPA ||
gsi->prot_id == USB_PROT_DPL_ETHER ||
gsi->prot_id == USB_PROT_GPS_CTRL ||
- gsi->prot_id == USB_PROT_MBIM_IPA ||
- gsi->prot_id == USB_PROT_RMNET_IPA ||
- gsi->prot_id == USB_PROT_RMNET_V2X_IPA ||
- gsi->prot_id == USB_PROT_RMNET_ETHER)
+ gsi->prot_id == USB_PROT_MBIM_IPA)
gsi_ctrl_send_cpkt_tomodem(gsi, NULL, 0);
if (gsi->c_port.uevent_wq)
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 373c31a..f48b08e 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -57,6 +57,7 @@
struct usb_ep *notify;
struct usb_request *notify_req;
u8 notify_state;
+ atomic_t notify_count;
bool is_open;
const struct ndp_parser_opts *parser_opts;
@@ -551,7 +552,7 @@
int status;
/* notification already in flight? */
- if (!req)
+ if (atomic_read(&ncm->notify_count))
return;
event = req->buf;
@@ -591,7 +592,8 @@
event->bmRequestType = 0xA1;
event->wIndex = cpu_to_le16(ncm->ctrl_id);
- ncm->notify_req = NULL;
+ atomic_inc(&ncm->notify_count);
+
/*
* In double buffering if there is a space in FIFO,
* completion callback can be called right after the call,
@@ -601,7 +603,7 @@
status = usb_ep_queue(ncm->notify, req, GFP_ATOMIC);
spin_lock(&ncm->lock);
if (status < 0) {
- ncm->notify_req = req;
+ atomic_dec(&ncm->notify_count);
DBG(cdev, "notify --> %d\n", status);
}
}
@@ -636,17 +638,19 @@
case 0:
VDBG(cdev, "Notification %02x sent\n",
event->bNotificationType);
+ atomic_dec(&ncm->notify_count);
break;
case -ECONNRESET:
case -ESHUTDOWN:
+ atomic_set(&ncm->notify_count, 0);
ncm->notify_state = NCM_NOTIFY_NONE;
break;
default:
DBG(cdev, "event %02x --> %d\n",
event->bNotificationType, req->status);
+ atomic_dec(&ncm->notify_count);
break;
}
- ncm->notify_req = req;
ncm_do_notify(ncm);
spin_unlock(&ncm->lock);
}
@@ -1716,6 +1720,11 @@
ncm_string_defs[0].id = 0;
usb_free_all_descriptors(f);
+ if (atomic_read(&ncm->notify_count)) {
+ usb_ep_dequeue(ncm->notify, ncm->notify_req);
+ atomic_set(&ncm->notify_count, 0);
+ }
+
kfree(ncm->notify_req->buf);
usb_ep_free_request(ncm->notify, ncm->notify_req);
diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c
index 312ae24..76a5896 100644
--- a/drivers/usb/gadget/function/f_qdss.c
+++ b/drivers/usb/gadget/function/f_qdss.c
@@ -1,7 +1,7 @@
/*
* f_qdss.c -- QDSS function Driver
*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1129,8 +1129,21 @@
static void usb_qdss_free_inst(struct usb_function_instance *fi)
{
struct usb_qdss_opts *opts;
+ struct usb_qdss_ch *ch;
+ unsigned long flags;
opts = container_of(fi, struct usb_qdss_opts, func_inst);
+ spin_lock_irqsave(&qdss_lock, flags);
+ list_for_each_entry(ch, &usb_qdss_ch_list, list) {
+ if (!strcmp(opts->channel_name, ch->name)) {
+ list_del(&ch->list);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&qdss_lock, flags);
+ kfree(opts->channel_name);
+ destroy_workqueue(opts->usb_qdss->wq);
kfree(opts->usb_qdss);
kfree(opts);
}
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
index d0d6611..1c40ae8 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -720,8 +720,10 @@
port->n_read = 0;
started = gs_start_rx(port);
- /* unblock any pending writes into our circular buffer */
if (started) {
+ gs_start_tx(port);
+ /* Unblock any pending writes into our circular buffer, in case
+ * we didn't in gs_start_tx() */
tty_wakeup(port->port.tty);
} else {
gs_free_requests(ep, head, &port->read_allocated);
diff --git a/drivers/usb/gadget/legacy/cdc2.c b/drivers/usb/gadget/legacy/cdc2.c
index 51c0868..5ee25be 100644
--- a/drivers/usb/gadget/legacy/cdc2.c
+++ b/drivers/usb/gadget/legacy/cdc2.c
@@ -229,7 +229,7 @@
.name = "g_cdc",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
+ .max_speed = USB_SPEED_SUPER,
.bind = cdc_bind,
.unbind = cdc_unbind,
};
diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c
index 6da7316..54ee4e3 100644
--- a/drivers/usb/gadget/legacy/g_ffs.c
+++ b/drivers/usb/gadget/legacy/g_ffs.c
@@ -153,7 +153,7 @@
.name = DRIVER_NAME,
.dev = &gfs_dev_desc,
.strings = gfs_dev_strings,
- .max_speed = USB_SPEED_HIGH,
+ .max_speed = USB_SPEED_SUPER,
.bind = gfs_bind,
.unbind = gfs_unbind,
};
diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c
index a70a406..3b7fc5c 100644
--- a/drivers/usb/gadget/legacy/multi.c
+++ b/drivers/usb/gadget/legacy/multi.c
@@ -486,7 +486,7 @@
.name = "g_multi",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
+ .max_speed = USB_SPEED_SUPER,
.bind = multi_bind,
.unbind = multi_unbind,
.needs_serial = 1,
diff --git a/drivers/usb/gadget/legacy/ncm.c b/drivers/usb/gadget/legacy/ncm.c
index 0aba682..2fb4a84 100644
--- a/drivers/usb/gadget/legacy/ncm.c
+++ b/drivers/usb/gadget/legacy/ncm.c
@@ -203,7 +203,7 @@
.name = "g_ncm",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
+ .max_speed = USB_SPEED_SUPER,
.bind = gncm_bind,
.unbind = gncm_unbind,
};
diff --git a/drivers/usb/gadget/legacy/qti_gadget.c b/drivers/usb/gadget/legacy/qti_gadget.c
index 77b458a..972168c 100644
--- a/drivers/usb/gadget/legacy/qti_gadget.c
+++ b/drivers/usb/gadget/legacy/qti_gadget.c
@@ -497,7 +497,7 @@
gadget->cdev.desc.bDeviceProtocol = (u8)val;
/* Check if pid passed via cmdline which takes precedence */
- if (usb_pid_string != NULL) {
+ if (usb_pid_string[0] != 0) {
ret = kstrtoint(usb_pid_string, 16, &val);
if (ret)
return ret;
diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c
index 39b7136..9e246d2 100644
--- a/drivers/usb/gadget/udc/gr_udc.c
+++ b/drivers/usb/gadget/udc/gr_udc.c
@@ -2200,8 +2200,6 @@
return -ENOMEM;
}
- spin_lock(&dev->lock);
-
/* Inside lock so that no gadget can use this udc until probe is done */
retval = usb_add_gadget_udc(dev->dev, &dev->gadget);
if (retval) {
@@ -2210,15 +2208,21 @@
}
dev->added = 1;
- retval = gr_udc_init(dev);
- if (retval)
- goto out;
+ spin_lock(&dev->lock);
- gr_dfs_create(dev);
+ retval = gr_udc_init(dev);
+ if (retval) {
+ spin_unlock(&dev->lock);
+ goto out;
+ }
/* Clear all interrupt enables that might be left on since last boot */
gr_disable_interrupts_and_pullup(dev);
+ spin_unlock(&dev->lock);
+
+ gr_dfs_create(dev);
+
retval = gr_request_irq(dev, dev->irq);
if (retval) {
dev_err(dev->dev, "Failed to request irq %d\n", dev->irq);
@@ -2247,8 +2251,6 @@
dev_info(dev->dev, "regs: %p, irq %d\n", dev->regs, dev->irq);
out:
- spin_unlock(&dev->lock);
-
if (retval)
gr_remove(pdev);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1ac64d7..ea9c2e5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1532,13 +1532,16 @@
/* Allow 3 retries for everything but isoc, set CErr = 3 */
if (!usb_endpoint_xfer_isoc(&ep->desc))
err_count = 3;
- /* Some devices get this wrong */
- if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH)
- max_packet = 512;
- if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_FULL
- && max_packet < 8)
- max_packet = 8;
+ /* HS bulk max packet should be 512, FS bulk supports 8, 16, 32 or 64 */
+ if (usb_endpoint_xfer_bulk(&ep->desc)) {
+ if (udev->speed == USB_SPEED_HIGH)
+ max_packet = 512;
+ if (udev->speed == USB_SPEED_FULL) {
+ max_packet = rounddown_pow_of_two(max_packet);
+ max_packet = clamp_val(max_packet, 8, 64);
+ }
+ }
/* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */
if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index e10808c..adf21ac 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -53,6 +53,7 @@
#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8
#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0
+#define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
@@ -170,7 +171,8 @@
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) {
+ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_CML_XHCI)) {
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
}
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 75afa8f..d6176d5 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -524,6 +524,7 @@
static struct platform_driver usb_xhci_driver = {
.probe = xhci_plat_probe,
.remove = xhci_plat_remove,
+ .shutdown = usb_hcd_platform_shutdown,
.driver = {
.name = "xhci-hcd",
.pm = DEV_PM_OPS,
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 19b5f08..01ef25b 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1494,10 +1494,7 @@
* We need to map sg if the transfer_buffer is
* NULL.
*/
- if (!urb->transfer_buffer)
- qh->use_sg = true;
-
- if (qh->use_sg) {
+ if (!urb->transfer_buffer) {
/* sg_miter_start is already done in musb_ep_program */
if (!sg_miter_next(&qh->sg_miter)) {
dev_err(musb->controller, "error: sg list empty\n");
@@ -1505,9 +1502,8 @@
status = -EINVAL;
goto done;
}
- urb->transfer_buffer = qh->sg_miter.addr;
length = min_t(u32, length, qh->sg_miter.length);
- musb_write_fifo(hw_ep, length, urb->transfer_buffer);
+ musb_write_fifo(hw_ep, length, qh->sg_miter.addr);
qh->sg_miter.consumed = length;
sg_miter_stop(&qh->sg_miter);
} else {
@@ -1516,11 +1512,6 @@
qh->segsize = length;
- if (qh->use_sg) {
- if (offset + length >= urb->transfer_buffer_length)
- qh->use_sg = false;
- }
-
musb_ep_select(mbase, epnum);
musb_writew(epio, MUSB_TXCSR,
MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
@@ -2040,8 +2031,10 @@
urb->actual_length += xfer_len;
qh->offset += xfer_len;
if (done) {
- if (qh->use_sg)
+ if (qh->use_sg) {
qh->use_sg = false;
+ urb->transfer_buffer = NULL;
+ }
if (urb->status == -EINPROGRESS)
urb->status = status;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index e8be8e3..457ad33 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -388,8 +388,6 @@
.init = omap2430_musb_init,
.exit = omap2430_musb_exit,
- .set_vbus = omap2430_musb_set_vbus,
-
.enable = omap2430_musb_enable,
.disable = omap2430_musb_disable,
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 3811792..a6a7380 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2020, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,6 +42,13 @@
module_param(rev3_sink_only, bool, 0644);
MODULE_PARM_DESC(rev3_sink_only, "Enable power delivery rev3.0 sink only mode");
+#define XR1_DISCOVER_VDO 0x1085
+#define XR1_DEFAULT_VDO 0x0
+#define XR1_PIN_E_VDO 0x0082
+#define DP_USBPD_EVT_STATUS_XR1 0x10
+#define DP_USBPD_EVT_CONFIGURE_XR1 0x11
+static bool sxr_dp_mode;
+
enum usbpd_state {
PE_UNKNOWN,
PE_ERROR_RECOVERY,
@@ -394,6 +401,9 @@
#define IS_EXT(m, t) ((m) && PD_MSG_HDR_IS_EXTENDED((m)->hdr) && \
(PD_MSG_HDR_TYPE((m)->hdr) == (t)))
+#define SXR_SEND_SVDM(pd, cmd, num, tx_vdos, pos) usbpd_send_svdm(pd, 0xFF01, \
+ cmd, SVDM_CMD_TYPE_RESP_ACK, \
+ num, tx_vdos, pos)
struct usbpd {
struct device dev;
struct workqueue_struct *wq;
@@ -488,6 +498,7 @@
u8 get_battery_status_db;
bool send_get_battery_status;
u32 battery_sts_dobj;
+ bool is_sxr_dp_sink;
};
static LIST_HEAD(_usbpd); /* useful for debugging */
@@ -1698,7 +1709,47 @@
}
if (handler && handler->svdm_received) {
- handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos);
+ if (pd->is_sxr_dp_sink) {
+ u32 tx_vdos[1];
+
+ switch (cmd) {
+ /*CMD 3, Type 1, PayLoad 43 */
+ case USBPD_SVDM_DISCOVER_MODES:
+ usbpd_dbg(&pd->dev,
+ "USBPD_SVDM_DISCOVER_MODES\n");
+ tx_vdos[0] = XR1_DISCOVER_VDO;
+ usbpd_dbg(&pd->dev, "sending RESP_ACK\n");
+ SXR_SEND_SVDM(pd, cmd, 0x0, tx_vdos, 0x1);
+ break;
+ /*CMD 4, Type 1, PayLoad 44 */
+ case USBPD_SVDM_ENTER_MODE:
+ usbpd_dbg(&pd->dev, "USBPD_SVDM_ENTER_MODE\n");
+ tx_vdos[0] = XR1_DEFAULT_VDO;
+ usbpd_dbg(&pd->dev, "sending RESP_ACK\n");
+ SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x0);
+ break;
+ /*CMD 10, Type 1, PayLoad 50 */
+ case DP_USBPD_EVT_STATUS_XR1:
+ tx_vdos[0] = XR1_PIN_E_VDO; // Pin assign E
+ usbpd_dbg(&pd->dev,
+ "DP_USBPD_EVT_STATUS_XR1\n");
+ SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x1);
+ break;
+ /*CMD 11, Type 1, PayLoad 51 */
+ case DP_USBPD_EVT_CONFIGURE_XR1:
+ usbpd_dbg(&pd->dev,
+ "DP_USBPD_EVT_CONFIGURE_XR1\n");
+ tx_vdos[0] = XR1_DEFAULT_VDO;
+ usbpd_dbg(&pd->dev,
+ "DP_USBPD_EVT_STATUS_XR1\n");
+ SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x0);
+ break;
+ default:
+ usbpd_dbg(&pd->dev, "default mode:%d\n", cmd);
+ }
+ } else
+ handler->svdm_received(handler, cmd, cmd_type, vdos,
+ num_vdos);
return;
}
@@ -1716,9 +1767,21 @@
usbpd_send_svdm(pd, USBPD_SID, cmd,
SVDM_CMD_TYPE_RESP_ACK, 0, tx_vdos, 3);
- } else if (cmd != USBPD_SVDM_ATTENTION) {
- usbpd_send_svdm(pd, svid, cmd, SVDM_CMD_TYPE_RESP_NAK,
+ } else if (cmd != USBPD_SVDM_ATTENTION) {
+ if (pd->is_sxr_dp_sink) {
+ u32 tx_vdos_pd[3] = {
+ ID_HDR_VID,
+ 0xFF01,
+ 0x0,
+ };
+ usbpd_send_svdm(pd, USBPD_SID, cmd,
+ SVDM_CMD_TYPE_RESP_ACK, 0,
+ tx_vdos_pd, 3);
+ } else {
+ usbpd_send_svdm(pd, svid, cmd,
+ SVDM_CMD_TYPE_RESP_NAK,
SVDM_HDR_OBJ_POS(vdm_hdr), NULL, 0);
+ }
}
break;
@@ -4117,6 +4180,15 @@
goto put_psy;
}
+ /*
+ * Need to set is_sxr_dp_sink to TRUE only when device tree node is
+ * present, and sim_vid_display string is present in
+ * boot_command_line string.
+ */
+ if (sxr_dp_mode)
+ pd->is_sxr_dp_sink = device_property_present(parent,
+ "qcom,sxr1130-sxr-dp-sink");
+
pd->vconn_is_external = device_property_present(parent,
"qcom,vconn-uses-external-source");
@@ -4236,6 +4308,15 @@
static int __init usbpd_init(void)
{
+ char *cmdline;
+
+ cmdline = strnstr(boot_command_line,
+ "msm_drm.dsi_display0=dsi_sim_vid_display",
+ strlen(boot_command_line));
+ sxr_dp_mode = false;
+ if (cmdline)
+ sxr_dp_mode = true;
+
usbpd_ipc_log = ipc_log_context_create(NUM_LOG_PAGES, "usb_pd", 0);
return class_register(&usbpd_class);
}
diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c
index 9d66366..88a0dee 100644
--- a/drivers/usb/phy/phy-msm-qusb.c
+++ b/drivers/usb/phy/phy-msm-qusb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1029,7 +1029,7 @@
qphy->iface_clk = NULL;
if (ret == -EPROBE_DEFER)
return ret;
- dev_err(dev, "couldn't get iface_clk(%d)\n", ret);
+ dev_err(dev, "couldn't get iface_clk(%d)\n", ret);
}
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 19158800..7755524 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -634,7 +634,7 @@
/* grab the txcredits for the ports if available */
position = 2;
portNumber = 0;
- while ((position < length) &&
+ while ((position < length - 1) &&
(portNumber < edge_serial->serial->num_ports)) {
txCredits = data[position] | (data[position+1] << 8);
if (txCredits) {
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 5ea4cd1..737b665 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1172,6 +1172,8 @@
.driver_info = NCTRL(0) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */
.driver_info = NCTRL(0) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110b, 0xff), /* Telit ME910G1 (ECM) */
+ .driver_info = NCTRL(0) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
@@ -1981,8 +1983,14 @@
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
+ { USB_DEVICE_INTERFACE_CLASS(0x1435, 0xd191, 0xff), /* Wistron Neweb D19Q1 */
+ .driver_info = RSVD(1) | RSVD(4) },
+ { USB_DEVICE_INTERFACE_CLASS(0x1690, 0x7588, 0xff), /* ASKEY WWHC050 */
+ .driver_info = RSVD(1) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff), /* Olicard 600 */
.driver_info = RSVD(4) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2033, 0xff), /* BroadMobi BM806U */
+ .driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2060, 0xff), /* BroadMobi BM818 */
.driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 8fd5e19..4fcded2 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -88,6 +88,7 @@
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD381_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 496cbcc..54d2fb9 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -128,6 +128,7 @@
#define HP_LM920_PRODUCT_ID 0x026b
#define HP_TD620_PRODUCT_ID 0x0956
#define HP_LD960_PRODUCT_ID 0x0b39
+#define HP_LD381_PRODUCT_ID 0x0f7f
#define HP_LCM220_PRODUCT_ID 0x3139
#define HP_LCM960_PRODUCT_ID 0x3239
#define HP_LD220_PRODUCT_ID 0x3524
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a6999042..d022b5f 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -46,6 +46,7 @@
struct scsi_cmnd *cmnd[MAX_CMNDS];
spinlock_t lock;
struct work_struct work;
+ struct work_struct scan_work; /* for async scanning */
};
enum {
@@ -115,6 +116,17 @@
spin_unlock_irqrestore(&devinfo->lock, flags);
}
+static void uas_scan_work(struct work_struct *work)
+{
+ struct uas_dev_info *devinfo =
+ container_of(work, struct uas_dev_info, scan_work);
+ struct Scsi_Host *shost = usb_get_intfdata(devinfo->intf);
+
+ dev_dbg(&devinfo->intf->dev, "starting scan\n");
+ scsi_scan_host(shost);
+ dev_dbg(&devinfo->intf->dev, "scan complete\n");
+}
+
static void uas_add_work(struct uas_cmd_info *cmdinfo)
{
struct scsi_pointer *scp = (void *)cmdinfo;
@@ -989,6 +1001,7 @@
init_usb_anchor(&devinfo->data_urbs);
spin_lock_init(&devinfo->lock);
INIT_WORK(&devinfo->work, uas_do_work);
+ INIT_WORK(&devinfo->scan_work, uas_scan_work);
result = uas_configure_endpoints(devinfo);
if (result)
@@ -1005,7 +1018,9 @@
if (result)
goto free_streams;
- scsi_scan_host(shost);
+ /* Submit the delayed_work for SCSI-device scanning */
+ schedule_work(&devinfo->scan_work);
+
return result;
free_streams:
@@ -1173,6 +1188,12 @@
usb_kill_anchored_urbs(&devinfo->data_urbs);
uas_zap_pending(devinfo, DID_NO_CONNECT);
+ /*
+ * Prevent SCSI scanning (if it hasn't started yet)
+ * or wait for the SCSI-scanning routine to stop.
+ */
+ cancel_work_sync(&devinfo->scan_work);
+
scsi_remove_host(shost);
uas_free_streams(devinfo);
scsi_host_put(shost);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 3ebf6307..a52ae34 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1277,6 +1277,12 @@
USB_SC_RBC, USB_PR_BULK, NULL,
0 ),
+UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100,
+ "Samsung",
+ "Flash Drive FIT",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_MAX_SECTORS_64),
+
/* aeb */
UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
"Feiya",
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index dd8798b..861f43f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -914,11 +914,7 @@
static struct socket *get_raw_socket(int fd)
{
- struct {
- struct sockaddr_ll sa;
- char buf[MAX_ADDR_LEN];
- } uaddr;
- int uaddr_len = sizeof uaddr, r;
+ int r;
struct socket *sock = sockfd_lookup(fd, &r);
if (!sock)
@@ -930,12 +926,7 @@
goto err;
}
- r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa,
- &uaddr_len, 0);
- if (r)
- goto err;
-
- if (uaddr.sa.sll_family != AF_PACKET) {
+ if (sock->sk->sk_family != AF_PACKET) {
r = -EPFNOSUPPORT;
goto err;
}
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index dda1c4b..42c0a26 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1323,6 +1323,9 @@
static int vgacon_resize(struct vc_data *c, unsigned int width,
unsigned int height, unsigned int user)
{
+ if ((width << 1) * height > vga_vram_size)
+ return -EINVAL;
+
if (width % 2 || width > screen_info.orig_video_cols ||
height > (screen_info.orig_video_lines * vga_default_font_height)/
c->vc_font.height)
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 7c1b7d9..55da18f 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2019, 2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1325,19 +1325,37 @@
/*Map the splash addr for VIDEO mode panel before smmu attach*/
if ((mfd->panel.type == MIPI_VIDEO_PANEL) &&
(mdp3_session->in_splash_screen)) {
+ rc = mdss_smmu_set_attribute(MDSS_IOMMU_DOMAIN_UNSECURE,
+ EARLY_MAP, 1);
+ if (rc) {
+ pr_err("mdp3 set attribute failed for early map\n");
+ goto reset_error;
+ }
+ rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
+ if (IS_ERR_VALUE((unsigned long)rc)) {
+ pr_err("mdp3 iommu attach failed\n");
+ goto reset_error;
+ }
rc = mdss_smmu_map(MDSS_IOMMU_DOMAIN_UNSECURE,
mdp3_res->splash_mem_addr,
mdp3_res->splash_mem_addr,
mdp3_res->splash_mem_size,
IOMMU_READ | IOMMU_NOEXEC);
- }
+ if (rc)
+ pr_err("iommu memory mapping failed ret=%d\n", rc);
+ else
+ pr_info("iommu map passed for PA=VA\n");
- rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
- if (rc) {
- pr_err("fail to attach dma iommu\n");
- if (mdp3_res->idle_pc)
- mdp3_clk_enable(0, 0);
- goto reset_error;
+ rc = mdss_smmu_set_attribute(MDSS_IOMMU_DOMAIN_UNSECURE,
+ EARLY_MAP, 0);
+ } else {
+ rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
+ if (rc) {
+ pr_err("fail to attach dma iommu\n");
+ if (mdp3_res->idle_pc)
+ mdp3_clk_enable(0, 0);
+ goto reset_error;
+ }
}
vsync_client = mdp3_dma->vsync_client;
@@ -1737,7 +1755,7 @@
static bool splash_done;
struct mdss_panel_data *panel;
- int rc;
+ int stride, rc;
pr_debug("mdp3_ctrl_pan_display\n");
if (!mfd || !mfd->mdp.private1)
@@ -1790,9 +1808,21 @@
if (IS_ERR_VALUE(rc))
goto pan_error;
}
- rc = mdp3_session->dma->update(mdp3_session->dma,
- (void *)(int)(mfd->iova + offset),
- mdp3_session->intf, NULL);
+ if (mdp3_ctrl_get_intf_type(mfd) ==
+ MDP3_DMA_OUTPUT_SEL_SPI_CMD) {
+ stride = fbi->fix.line_length;
+ pr_debug("addr = %x, smemlen = %d, stride = %d, offset = %x\n",
+ (int)mfd->iova, (int)fbi->fix.smem_len,
+ stride, (int)offset);
+ rc = mdss_spi_panel_kickoff(mdp3_session->panel,
+ (mfd->fbi->screen_base + offset),
+ (int)fbi->fix.smem_len,
+ stride);
+ } else {
+ rc = mdp3_session->dma->update(mdp3_session->dma,
+ (void *)(int)(mfd->iova + offset),
+ mdp3_session->intf, NULL);
+ }
/* This is for the previous frame */
if (rc < 0) {
mdp3_ctrl_notify(mdp3_session,
diff --git a/drivers/video/fbdev/msm/mdss_spi_panel.c b/drivers/video/fbdev/msm/mdss_spi_panel.c
index 5cff450..b111fe4 100644
--- a/drivers/video/fbdev/msm/mdss_spi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_spi_panel.c
@@ -415,7 +415,7 @@
}
int mdss_spi_panel_kickoff(struct mdss_panel_data *pdata,
- char *buf, int len, int dma_stride)
+ char __iomem *buf, int len, int dma_stride)
{
struct spi_panel_data *ctrl_pdata = NULL;
char *tx_buf;
diff --git a/drivers/video/fbdev/msm/mdss_spi_panel.h b/drivers/video/fbdev/msm/mdss_spi_panel.h
index 80b7ea8..2521e40 100644
--- a/drivers/video/fbdev/msm/mdss_spi_panel.h
+++ b/drivers/video/fbdev/msm/mdss_spi_panel.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -121,7 +121,7 @@
};
int mdss_spi_panel_kickoff(struct mdss_panel_data *pdata,
- char *buf, int len, int stride);
+ char __iomem *buf, int len, int stride);
int is_spi_panel_continuous_splash_on(struct mdss_panel_data *pdata);
void mdp3_spi_vsync_enable(struct mdss_panel_data *pdata,
struct mdp3_notification *vsync_client);
@@ -130,7 +130,7 @@
#else
static inline int mdss_spi_panel_kickoff(struct mdss_panel_data *pdata,
- char *buf, int len, int stride){
+ char __iomem *buf, int len, int stride){
return 0;
}
static inline int is_spi_panel_continuous_splash_on(
diff --git a/drivers/video/fbdev/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c
index d059d04..20195d3 100644
--- a/drivers/video/fbdev/pxa168fb.c
+++ b/drivers/video/fbdev/pxa168fb.c
@@ -769,8 +769,8 @@
failed_free_clk:
clk_disable_unprepare(fbi->clk);
failed_free_fbmem:
- dma_free_coherent(fbi->dev, info->fix.smem_len,
- info->screen_base, fbi->fb_start_dma);
+ dma_free_wc(fbi->dev, info->fix.smem_len,
+ info->screen_base, fbi->fb_start_dma);
failed_free_info:
kfree(info);
@@ -804,7 +804,7 @@
irq = platform_get_irq(pdev, 0);
- dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+ dma_free_wc(fbi->dev, info->fix.smem_len,
info->screen_base, info->fix.smem_start);
clk_disable_unprepare(fbi->clk);
diff --git a/drivers/vme/bridges/vme_fake.c b/drivers/vme/bridges/vme_fake.c
index 30b3acc..e81ec76 100644
--- a/drivers/vme/bridges/vme_fake.c
+++ b/drivers/vme/bridges/vme_fake.c
@@ -418,8 +418,9 @@
}
}
-static u8 fake_vmeread8(struct fake_driver *bridge, unsigned long long addr,
- u32 aspace, u32 cycle)
+static noinline_for_stack u8 fake_vmeread8(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
{
u8 retval = 0xff;
int i;
@@ -450,8 +451,9 @@
return retval;
}
-static u16 fake_vmeread16(struct fake_driver *bridge, unsigned long long addr,
- u32 aspace, u32 cycle)
+static noinline_for_stack u16 fake_vmeread16(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
{
u16 retval = 0xffff;
int i;
@@ -482,8 +484,9 @@
return retval;
}
-static u32 fake_vmeread32(struct fake_driver *bridge, unsigned long long addr,
- u32 aspace, u32 cycle)
+static noinline_for_stack u32 fake_vmeread32(struct fake_driver *bridge,
+ unsigned long long addr,
+ u32 aspace, u32 cycle)
{
u32 retval = 0xffffffff;
int i;
@@ -613,8 +616,9 @@
return retval;
}
-static void fake_vmewrite8(struct fake_driver *bridge, u8 *buf,
- unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite8(struct fake_driver *bridge,
+ u8 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
{
int i;
unsigned long long start, end, offset;
@@ -643,8 +647,9 @@
}
-static void fake_vmewrite16(struct fake_driver *bridge, u16 *buf,
- unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite16(struct fake_driver *bridge,
+ u16 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
{
int i;
unsigned long long start, end, offset;
@@ -673,8 +678,9 @@
}
-static void fake_vmewrite32(struct fake_driver *bridge, u32 *buf,
- unsigned long long addr, u32 aspace, u32 cycle)
+static noinline_for_stack void fake_vmewrite32(struct fake_driver *bridge,
+ u32 *buf, unsigned long long addr,
+ u32 aspace, u32 cycle)
{
int i;
unsigned long long start, end, offset;
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index 7386111..daeb645 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -126,13 +126,6 @@
struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd);
int ret;
- ret = da9062_reset_watchdog_timer(wdt);
- if (ret) {
- dev_err(wdt->hw->dev, "Failed to ping the watchdog (err = %d)\n",
- ret);
- return ret;
- }
-
ret = regmap_update_bits(wdt->hw->regmap,
DA9062AA_CONTROL_D,
DA9062AA_TWDSCALE_MASK,
diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c
index 0da9943..c310e84 100644
--- a/drivers/watchdog/wdat_wdt.c
+++ b/drivers/watchdog/wdat_wdt.c
@@ -392,7 +392,7 @@
memset(&r, 0, sizeof(r));
r.start = gas->address;
- r.end = r.start + gas->access_width - 1;
+ r.end = r.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1;
if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
r.flags = IORESOURCE_MEM;
} else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c
index 08cb419..5f6b77e 100644
--- a/drivers/xen/preempt.c
+++ b/drivers/xen/preempt.c
@@ -37,7 +37,9 @@
* cpu.
*/
__this_cpu_write(xen_in_preemptible_hcall, false);
- _cond_resched();
+ local_irq_enable();
+ cond_resched();
+ local_irq_disable();
__this_cpu_write(xen_in_preemptible_hcall, true);
}
}
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 305deb6..b5ebb43 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -331,26 +331,6 @@
struct tree_mod_root old_root;
};
-static inline void tree_mod_log_read_lock(struct btrfs_fs_info *fs_info)
-{
- read_lock(&fs_info->tree_mod_log_lock);
-}
-
-static inline void tree_mod_log_read_unlock(struct btrfs_fs_info *fs_info)
-{
- read_unlock(&fs_info->tree_mod_log_lock);
-}
-
-static inline void tree_mod_log_write_lock(struct btrfs_fs_info *fs_info)
-{
- write_lock(&fs_info->tree_mod_log_lock);
-}
-
-static inline void tree_mod_log_write_unlock(struct btrfs_fs_info *fs_info)
-{
- write_unlock(&fs_info->tree_mod_log_lock);
-}
-
/*
* Pull a new tree mod seq number for our operation.
*/
@@ -370,14 +350,12 @@
u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
struct seq_list *elem)
{
- tree_mod_log_write_lock(fs_info);
- spin_lock(&fs_info->tree_mod_seq_lock);
+ write_lock(&fs_info->tree_mod_log_lock);
if (!elem->seq) {
elem->seq = btrfs_inc_tree_mod_seq(fs_info);
list_add_tail(&elem->list, &fs_info->tree_mod_seq_list);
}
- spin_unlock(&fs_info->tree_mod_seq_lock);
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
return elem->seq;
}
@@ -396,7 +374,7 @@
if (!seq_putting)
return;
- spin_lock(&fs_info->tree_mod_seq_lock);
+ write_lock(&fs_info->tree_mod_log_lock);
list_del(&elem->list);
elem->seq = 0;
@@ -407,19 +385,17 @@
* blocker with lower sequence number exists, we
* cannot remove anything from the log
*/
- spin_unlock(&fs_info->tree_mod_seq_lock);
+ write_unlock(&fs_info->tree_mod_log_lock);
return;
}
min_seq = cur_elem->seq;
}
}
- spin_unlock(&fs_info->tree_mod_seq_lock);
/*
* anything that's lower than the lowest existing (read: blocked)
* sequence number can be removed from the tree.
*/
- tree_mod_log_write_lock(fs_info);
tm_root = &fs_info->tree_mod_log;
for (node = rb_first(tm_root); node; node = next) {
next = rb_next(node);
@@ -429,7 +405,7 @@
rb_erase(node, tm_root);
kfree(tm);
}
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
}
/*
@@ -440,7 +416,7 @@
* for root replace operations, or the logical address of the affected
* block for all other operations.
*
- * Note: must be called with write lock (tree_mod_log_write_lock).
+ * Note: must be called with write lock for fs_info::tree_mod_log_lock.
*/
static noinline int
__tree_mod_log_insert(struct btrfs_fs_info *fs_info, struct tree_mod_elem *tm)
@@ -480,7 +456,7 @@
* Determines if logging can be omitted. Returns 1 if it can. Otherwise, it
* returns zero with the tree_mod_log_lock acquired. The caller must hold
* this until all tree mod log insertions are recorded in the rb tree and then
- * call tree_mod_log_write_unlock() to release.
+ * write unlock fs_info::tree_mod_log_lock.
*/
static inline int tree_mod_dont_log(struct btrfs_fs_info *fs_info,
struct extent_buffer *eb) {
@@ -490,9 +466,9 @@
if (eb && btrfs_header_level(eb) == 0)
return 1;
- tree_mod_log_write_lock(fs_info);
+ write_lock(&fs_info->tree_mod_log_lock);
if (list_empty(&(fs_info)->tree_mod_seq_list)) {
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
return 1;
}
@@ -556,7 +532,7 @@
}
ret = __tree_mod_log_insert(fs_info, tm);
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&eb->fs_info->tree_mod_log_lock);
if (ret)
kfree(tm);
@@ -620,7 +596,7 @@
ret = __tree_mod_log_insert(fs_info, tm);
if (ret)
goto free_tms;
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&eb->fs_info->tree_mod_log_lock);
kfree(tm_list);
return 0;
@@ -631,7 +607,7 @@
kfree(tm_list[i]);
}
if (locked)
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&eb->fs_info->tree_mod_log_lock);
kfree(tm_list);
kfree(tm);
@@ -712,7 +688,7 @@
if (!ret)
ret = __tree_mod_log_insert(fs_info, tm);
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
if (ret)
goto free_tms;
kfree(tm_list);
@@ -739,7 +715,7 @@
struct tree_mod_elem *cur = NULL;
struct tree_mod_elem *found = NULL;
- tree_mod_log_read_lock(fs_info);
+ read_lock(&fs_info->tree_mod_log_lock);
tm_root = &fs_info->tree_mod_log;
node = tm_root->rb_node;
while (node) {
@@ -767,7 +743,7 @@
break;
}
}
- tree_mod_log_read_unlock(fs_info);
+ read_unlock(&fs_info->tree_mod_log_lock);
return found;
}
@@ -848,7 +824,7 @@
goto free_tms;
}
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
kfree(tm_list);
return 0;
@@ -860,7 +836,7 @@
kfree(tm_list[i]);
}
if (locked)
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&fs_info->tree_mod_log_lock);
kfree(tm_list);
return ret;
@@ -920,7 +896,7 @@
goto free_tms;
ret = __tree_mod_log_free_eb(fs_info, tm_list, nritems);
- tree_mod_log_write_unlock(fs_info);
+ write_unlock(&eb->fs_info->tree_mod_log_lock);
if (ret)
goto free_tms;
kfree(tm_list);
@@ -1271,7 +1247,7 @@
unsigned long p_size = sizeof(struct btrfs_key_ptr);
n = btrfs_header_nritems(eb);
- tree_mod_log_read_lock(fs_info);
+ read_lock(&fs_info->tree_mod_log_lock);
while (tm && tm->seq >= time_seq) {
/*
* all the operations are recorded with the operator used for
@@ -1326,7 +1302,7 @@
if (tm->logical != first_tm->logical)
break;
}
- tree_mod_log_read_unlock(fs_info);
+ read_unlock(&fs_info->tree_mod_log_lock);
btrfs_set_header_nritems(eb, n);
}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a423c36..2bc37d0 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -851,14 +851,12 @@
struct list_head delayed_iputs;
struct mutex cleaner_delayed_iput_mutex;
- /* this protects tree_mod_seq_list */
- spinlock_t tree_mod_seq_lock;
atomic64_t tree_mod_seq;
- struct list_head tree_mod_seq_list;
- /* this protects tree_mod_log */
+ /* this protects tree_mod_log and tree_mod_seq_list */
rwlock_t tree_mod_log_lock;
struct rb_root tree_mod_log;
+ struct list_head tree_mod_seq_list;
atomic_t nr_async_submits;
atomic_t async_submit_draining;
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 74c17db..c1ca4ce 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -279,7 +279,7 @@
if (head->is_data)
return;
- spin_lock(&fs_info->tree_mod_seq_lock);
+ read_lock(&fs_info->tree_mod_log_lock);
if (!list_empty(&fs_info->tree_mod_seq_list)) {
struct seq_list *elem;
@@ -287,7 +287,7 @@
struct seq_list, list);
seq = elem->seq;
}
- spin_unlock(&fs_info->tree_mod_seq_lock);
+ read_unlock(&fs_info->tree_mod_log_lock);
ref = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node,
list);
@@ -315,7 +315,7 @@
struct seq_list *elem;
int ret = 0;
- spin_lock(&fs_info->tree_mod_seq_lock);
+ read_lock(&fs_info->tree_mod_log_lock);
if (!list_empty(&fs_info->tree_mod_seq_list)) {
elem = list_first_entry(&fs_info->tree_mod_seq_list,
struct seq_list, list);
@@ -329,7 +329,7 @@
}
}
- spin_unlock(&fs_info->tree_mod_seq_lock);
+ read_unlock(&fs_info->tree_mod_log_lock);
return ret;
}
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index bab3b84..1ed918c 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2104,7 +2104,7 @@
}
/* helper to cleanup tree roots */
-static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
+static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root)
{
free_root_extent_buffers(info->tree_root);
@@ -2113,7 +2113,7 @@
free_root_extent_buffers(info->csum_root);
free_root_extent_buffers(info->quota_root);
free_root_extent_buffers(info->uuid_root);
- if (chunk_root)
+ if (free_chunk_root)
free_root_extent_buffers(info->chunk_root);
free_root_extent_buffers(info->free_space_root);
}
@@ -2519,7 +2519,6 @@
spin_lock_init(&fs_info->delayed_iput_lock);
spin_lock_init(&fs_info->defrag_inodes_lock);
spin_lock_init(&fs_info->free_chunk_lock);
- spin_lock_init(&fs_info->tree_mod_seq_lock);
spin_lock_init(&fs_info->super_lock);
spin_lock_init(&fs_info->qgroup_op_lock);
spin_lock_init(&fs_info->buffer_lock);
@@ -2980,6 +2979,7 @@
/* do not make disk changes in broken FS or nologreplay is given */
if (btrfs_super_log_root(disk_super) != 0 &&
!btrfs_test_opt(tree_root->fs_info, NOLOGREPLAY)) {
+ btrfs_info(fs_info, "start tree-log replay");
ret = btrfs_replay_log(fs_info, fs_devices);
if (ret) {
err = ret;
@@ -3136,7 +3136,7 @@
btrfs_free_block_groups(fs_info);
fail_tree_roots:
- free_root_pointers(fs_info, 1);
+ free_root_pointers(fs_info, true);
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
fail_sb_buffer:
@@ -3165,7 +3165,7 @@
if (!btrfs_test_opt(tree_root->fs_info, USEBACKUPROOT))
goto fail_tree_roots;
- free_root_pointers(fs_info, 0);
+ free_root_pointers(fs_info, false);
/* don't use the log in recovery mode, it won't be valid */
btrfs_set_super_log_root(disk_super, 0);
@@ -3862,7 +3862,7 @@
btrfs_stop_all_workers(fs_info);
clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
- free_root_pointers(fs_info, 1);
+ free_root_pointers(fs_info, true);
iput(fs_info->btree_inode);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 36eabea..6e0b6bc 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4049,6 +4049,14 @@
*/
scanned = 1;
index = 0;
+
+ /*
+ * If we're looping we could run into a page that is locked by a
+ * writer and that writer could be waiting on writeback for a
+ * page in our current bio, and thus deadlock, so flush the
+ * write bio here.
+ */
+ flush_write_bio(data);
goto retry;
}
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 26f9ac7..4f59b40 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -227,6 +227,17 @@
struct extent_map *merge = NULL;
struct rb_node *rb;
+ /*
+ * We can't modify an extent map that is in the tree and that is being
+ * used by another task, as it can cause that other task to see it in
+ * inconsistent state during the merging. We always have 1 reference for
+ * the tree and 1 for this task (which is unpinning the extent map or
+ * clearing the logging flag), so anything > 2 means it's being used by
+ * other tasks too.
+ */
+ if (atomic_read(&em->refs) > 2)
+ return;
+
if (em->start != 0) {
rb = rb_prev(&em->rb_node);
if (rb)
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index b2d1e95..7dc2284 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -837,10 +837,15 @@
}
btrfs_start_ordered_extent(inode, ordered, 1);
end = ordered->file_offset;
+ /*
+ * If the ordered extent had an error save the error but don't
+ * exit without waiting first for all other ordered extents in
+ * the range to complete.
+ */
if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags))
ret = -EIO;
btrfs_put_ordered_extent(ordered);
- if (ret || end == 0 || end == start)
+ if (end == 0 || end == start)
break;
end--;
}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 0c71cdd..9286603 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1809,6 +1809,8 @@
}
if (btrfs_super_log_root(fs_info->super_copy) != 0) {
+ btrfs_warn(fs_info,
+ "mount required to replay tree-log, cannot remount read-write");
ret = -EINVAL;
goto restore;
}
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index bf62ad9..9edc267 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -112,7 +112,6 @@
spin_lock_init(&fs_info->qgroup_op_lock);
spin_lock_init(&fs_info->super_lock);
spin_lock_init(&fs_info->fs_roots_radix_lock);
- spin_lock_init(&fs_info->tree_mod_seq_lock);
mutex_init(&fs_info->qgroup_ioctl_lock);
mutex_init(&fs_info->qgroup_rescan_lock);
rwlock_init(&fs_info->tree_mod_log_lock);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index fd6c746..31df020 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1917,6 +1917,14 @@
struct btrfs_transaction *prev_trans = NULL;
int ret;
+ /*
+ * Some places just start a transaction to commit it. We need to make
+ * sure that if this commit fails that the abort code actually marks the
+ * transaction as failed, so set trans->dirty to make the abort code do
+ * the right thing.
+ */
+ trans->dirty = true;
+
/* Stop the commit early if ->aborted is set */
if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
ret = cur_trans->aborted;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 7ee573c..f796829 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4443,13 +4443,8 @@
struct btrfs_file_extent_item);
if (btrfs_file_extent_type(leaf, extent) ==
- BTRFS_FILE_EXTENT_INLINE) {
- len = btrfs_file_extent_inline_len(leaf,
- path->slots[0],
- extent);
- ASSERT(len == i_size);
+ BTRFS_FILE_EXTENT_INLINE)
return 0;
- }
len = btrfs_file_extent_num_bytes(leaf, extent);
/* Last extent goes beyond i_size, no need to log a hole. */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 15bac39..10aedc2 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -603,7 +603,7 @@
((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
*pmode |= (S_IXUGO & (*pbits_to_set));
- cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
+ cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
return;
}
@@ -632,7 +632,7 @@
if (mode & S_IXUGO)
*pace_flags |= SET_FILE_EXEC_RIGHTS;
- cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
+ cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
mode, *pace_flags);
return;
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 6fcd43a..a605ec9 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2927,8 +2927,10 @@
{
struct cifs_sb_info *old = CIFS_SB(sb);
struct cifs_sb_info *new = mnt_data->cifs_sb;
- bool old_set = old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
- bool new_set = new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH;
+ bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+ old->prepath;
+ bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
+ new->prepath;
if (old_set && new_set && !strcmp(new->prepath, old->prepath))
return 1;
@@ -3399,7 +3401,7 @@
cifs_sb->mnt_gid = pvolume_info->linux_gid;
cifs_sb->mnt_file_mode = pvolume_info->file_mode;
cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
- cifs_dbg(FYI, "file mode: 0x%hx dir mode: 0x%hx\n",
+ cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n",
cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
cifs_sb->actimeo = pvolume_info->actimeo;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d6475dc..0262c8f 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -551,7 +551,6 @@
if (server->ops->close)
server->ops->close(xid, tcon, &fid);
cifs_del_pending_open(&open);
- fput(file);
rc = -ENOMEM;
}
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b1c0961..dfa85ad 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1573,7 +1573,7 @@
struct TCP_Server_Info *server;
char *full_path;
- cifs_dbg(FYI, "In cifs_mkdir, mode = 0x%hx inode = 0x%p\n",
+ cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p\n",
mode, inode);
cifs_sb = CIFS_SB(inode->i_sb);
@@ -1990,6 +1990,7 @@
struct inode *inode = d_inode(dentry);
struct super_block *sb = dentry->d_sb;
char *full_path = NULL;
+ int count = 0;
if (inode == NULL)
return -ENOENT;
@@ -2011,15 +2012,18 @@
full_path, inode, inode->i_count.counter,
dentry, cifs_get_time(dentry), jiffies);
+again:
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
else
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL);
-
+ if (rc == -EAGAIN && count++ < 10)
+ goto again;
out:
kfree(full_path);
free_xid(xid);
+
return rc;
}
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 5255dea..e8dc28d 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -247,9 +247,14 @@
*/
mutex_lock(&tcon->ses->session_mutex);
rc = cifs_negotiate_protocol(0, tcon->ses);
- if (!rc && tcon->ses->need_reconnect)
+ if (!rc && tcon->ses->need_reconnect) {
rc = cifs_setup_session(0, tcon->ses, nls_codepage);
-
+ if ((rc == -EACCES) && !tcon->retry) {
+ rc = -EHOSTDOWN;
+ mutex_unlock(&tcon->ses->session_mutex);
+ goto failed;
+ }
+ }
if (rc || !tcon->need_reconnect) {
mutex_unlock(&tcon->ses->session_mutex);
goto out;
@@ -291,6 +296,7 @@
case SMB2_SET_INFO:
rc = -EAGAIN;
}
+failed:
unload_nls(nls_codepage);
return rc;
}
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index cb77e7e..ff6cf23 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -339,8 +339,10 @@
struct extent_crypt_result ecr;
int rc = 0;
- BUG_ON(!crypt_stat || !crypt_stat->tfm
- || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
+ if (!crypt_stat || !crypt_stat->tfm
+ || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
+ return -EINVAL;
+
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
crypt_stat->key_size);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index fa218cd..b134315 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1335,7 +1335,7 @@
printk(KERN_WARNING "Tag 1 packet contains key larger "
"than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES");
rc = -EINVAL;
- goto out;
+ goto out_free;
}
memcpy((*new_auth_tok)->session_key.encrypted_key,
&data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2)));
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 4f457d5..26464f9 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -397,6 +397,7 @@
* ecryptfs_message_buf_len),
GFP_KERNEL);
if (!ecryptfs_msg_ctx_arr) {
+ kfree(ecryptfs_daemon_hash);
rc = -ENOMEM;
printk(KERN_ERR "%s: Failed to allocate memory\n", __func__);
goto out;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 6fcb29b..186912c 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1047,9 +1047,9 @@
if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
goto cantfind_ext2;
- sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
- le32_to_cpu(es->s_first_data_block) - 1)
- / EXT2_BLOCKS_PER_GROUP(sb)) + 1;
+ sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+ le32_to_cpu(es->s_first_data_block) - 1)
+ / EXT2_BLOCKS_PER_GROUP(sb)) + 1;
db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
EXT2_DESC_PER_BLOCK(sb);
sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL);
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 2455fe1..de601f3 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -279,6 +279,7 @@
ext4_group_t ngroups = ext4_get_groups_count(sb);
struct ext4_group_desc *desc;
struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct buffer_head *bh_p;
if (block_group >= ngroups) {
ext4_error(sb, "block_group >= groups_count - block_group = %u,"
@@ -289,7 +290,14 @@
group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
- if (!sbi->s_group_desc[group_desc]) {
+ bh_p = sbi_array_rcu_deref(sbi, s_group_desc, group_desc);
+ /*
+ * sbi_array_rcu_deref returns with rcu unlocked, this is ok since
+ * the pointer being dereferenced won't be dereferenced again. By
+ * looking at the usage in add_new_gdb() the value isn't modified,
+ * just the pointer, and so it remains valid.
+ */
+ if (!bh_p) {
ext4_error(sb, "Group descriptor not loaded - "
"block_group = %u, group_desc = %u, desc = %u",
block_group, group_desc, offset);
@@ -297,10 +305,10 @@
}
desc = (struct ext4_group_desc *)(
- (__u8 *)sbi->s_group_desc[group_desc]->b_data +
+ (__u8 *)bh_p->b_data +
offset * EXT4_DESC_SIZE(sb));
if (bh)
- *bh = sbi->s_group_desc[group_desc];
+ *bh = bh_p;
return desc;
}
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3c89ced..022d67f 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -124,12 +124,14 @@
if (err != ERR_BAD_DX_DIR) {
return err;
}
- /*
- * We don't set the inode dirty flag since it's not
- * critical that it get flushed back to the disk.
- */
- ext4_clear_inode_flag(file_inode(file),
- EXT4_INODE_INDEX);
+ /* Can we just clear INDEX flag to ignore htree information? */
+ if (!ext4_has_metadata_csum(sb)) {
+ /*
+ * We don't set the inode dirty flag since it's not
+ * critical that it gets flushed back to the disk.
+ */
+ ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
+ }
}
if (ext4_has_inline_data(inode)) {
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 2255c07..9261599 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1366,7 +1366,7 @@
loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
- struct buffer_head **s_group_desc;
+ struct buffer_head * __rcu *s_group_desc;
unsigned int s_mount_opt;
unsigned int s_mount_opt2;
unsigned int s_mount_flags;
@@ -1426,7 +1426,7 @@
#endif
/* for buddy allocator */
- struct ext4_group_info ***s_group_info;
+ struct ext4_group_info ** __rcu *s_group_info;
struct inode *s_buddy_cache;
spinlock_t s_md_lock;
unsigned short *s_mb_offsets;
@@ -1474,7 +1474,7 @@
unsigned int s_extent_max_zeroout_kb;
unsigned int s_log_groups_per_flex;
- struct flex_groups *s_flex_groups;
+ struct flex_groups * __rcu *s_flex_groups;
ext4_group_t s_flex_groups_allocated;
/* workqueue for reserved extent conversions (buffered io) */
@@ -1513,8 +1513,11 @@
struct ratelimit_state s_warning_ratelimit_state;
struct ratelimit_state s_msg_ratelimit_state;
- /* Barrier between changing inodes' journal flags and writepages ops. */
- struct percpu_rw_semaphore s_journal_flag_rwsem;
+ /*
+ * Barrier between writepages ops and changing any inode's JOURNAL_DATA
+ * or EXTENTS flag.
+ */
+ struct percpu_rw_semaphore s_writepages_rwsem;
};
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@ -1540,6 +1543,23 @@
}
/*
+ * Returns: sbi->field[index]
+ * Used to access an array element from the following sbi fields which require
+ * rcu protection to avoid dereferencing an invalid pointer due to reassignment
+ * - s_group_desc
+ * - s_group_info
+ * - s_flex_group
+ */
+#define sbi_array_rcu_deref(sbi, field, index) \
+({ \
+ typeof(*((sbi)->field)) _v; \
+ rcu_read_lock(); \
+ _v = ((typeof(_v)*)rcu_dereference((sbi)->field))[index]; \
+ rcu_read_unlock(); \
+ _v; \
+})
+
+/*
* Inode dynamic state flags
*/
enum {
@@ -2367,8 +2387,11 @@
struct ext4_filename *fname);
static inline void ext4_update_dx_flag(struct inode *inode)
{
- if (!ext4_has_feature_dir_index(inode->i_sb))
+ if (!ext4_has_feature_dir_index(inode->i_sb)) {
+ /* ext4_iget() should have caught this... */
+ WARN_ON_ONCE(ext4_has_feature_metadata_csum(inode->i_sb));
ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
+ }
}
static const unsigned char ext4_filetype_table[] = {
DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
@@ -2544,6 +2567,7 @@
extern bool ext4_empty_dir(struct inode *inode);
/* resize.c */
+extern void ext4_kvfree_array_rcu(void *to_free);
extern int ext4_group_add(struct super_block *sb,
struct ext4_new_group_data *input);
extern int ext4_group_extend(struct super_block *sb,
@@ -2784,13 +2808,13 @@
struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
ext4_group_t group)
{
- struct ext4_group_info ***grp_info;
+ struct ext4_group_info **grp_info;
long indexv, indexh;
BUG_ON(group >= EXT4_SB(sb)->s_groups_count);
- grp_info = EXT4_SB(sb)->s_group_info;
indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
- return grp_info[indexv][indexh];
+ grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
+ return grp_info[indexh];
}
/*
@@ -2840,7 +2864,7 @@
!inode_is_locked(inode));
down_write(&EXT4_I(inode)->i_data_sem);
if (newsize > EXT4_I(inode)->i_disksize)
- EXT4_I(inode)->i_disksize = newsize;
+ WRITE_ONCE(EXT4_I(inode)->i_disksize, newsize);
up_write(&EXT4_I(inode)->i_data_sem);
}
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index e37e5f1..358ad1f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -331,11 +331,13 @@
percpu_counter_inc(&sbi->s_freeinodes_counter);
if (sbi->s_log_groups_per_flex) {
- ext4_group_t f = ext4_flex_group(sbi, block_group);
+ struct flex_groups *fg;
- atomic_inc(&sbi->s_flex_groups[f].free_inodes);
+ fg = sbi_array_rcu_deref(sbi, s_flex_groups,
+ ext4_flex_group(sbi, block_group));
+ atomic_inc(&fg->free_inodes);
if (is_directory)
- atomic_dec(&sbi->s_flex_groups[f].used_dirs);
+ atomic_dec(&fg->used_dirs);
}
BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata");
fatal = ext4_handle_dirty_metadata(handle, NULL, bh2);
@@ -376,12 +378,13 @@
int flex_size, struct orlov_stats *stats)
{
struct ext4_group_desc *desc;
- struct flex_groups *flex_group = EXT4_SB(sb)->s_flex_groups;
if (flex_size > 1) {
- stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
- stats->free_clusters = atomic64_read(&flex_group[g].free_clusters);
- stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
+ struct flex_groups *fg = sbi_array_rcu_deref(EXT4_SB(sb),
+ s_flex_groups, g);
+ stats->free_inodes = atomic_read(&fg->free_inodes);
+ stats->free_clusters = atomic64_read(&fg->free_clusters);
+ stats->used_dirs = atomic_read(&fg->used_dirs);
return;
}
@@ -988,7 +991,8 @@
if (sbi->s_log_groups_per_flex) {
ext4_group_t f = ext4_flex_group(sbi, group);
- atomic_inc(&sbi->s_flex_groups[f].used_dirs);
+ atomic_inc(&sbi_array_rcu_deref(sbi, s_flex_groups,
+ f)->used_dirs);
}
}
if (ext4_has_group_desc_csum(sb)) {
@@ -1011,7 +1015,8 @@
if (sbi->s_log_groups_per_flex) {
flex_group = ext4_flex_group(sbi, group);
- atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes);
+ atomic_dec(&sbi_array_rcu_deref(sbi, s_flex_groups,
+ flex_group)->free_inodes);
}
inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 31e1229..fd545f36 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2492,7 +2492,7 @@
* truncate are avoided by checking i_size under i_data_sem.
*/
disksize = ((loff_t)mpd->first_page) << PAGE_SHIFT;
- if (disksize > EXT4_I(inode)->i_disksize) {
+ if (disksize > READ_ONCE(EXT4_I(inode)->i_disksize)) {
int err2;
loff_t i_size;
@@ -2659,7 +2659,7 @@
struct blk_plug plug;
bool give_up_on_write = false;
- percpu_down_read(&sbi->s_journal_flag_rwsem);
+ percpu_down_read(&sbi->s_writepages_rwsem);
trace_ext4_writepages(inode, wbc);
if (dax_mapping(mapping)) {
@@ -2860,7 +2860,7 @@
out_writepages:
trace_ext4_writepages_result(inode, wbc, ret,
nr_to_write - wbc->nr_to_write);
- percpu_up_read(&sbi->s_journal_flag_rwsem);
+ percpu_up_read(&sbi->s_writepages_rwsem);
return ret;
}
@@ -4660,6 +4660,18 @@
ret = -EFSCORRUPTED;
goto bad_inode;
}
+ /*
+ * If dir_index is not enabled but there's dir with INDEX flag set,
+ * we'd normally treat htree data as empty space. But with metadata
+ * checksumming that corrupts checksums so forbid that.
+ */
+ if (!ext4_has_feature_dir_index(sb) && ext4_has_metadata_csum(sb) &&
+ ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) {
+ EXT4_ERROR_INODE(inode,
+ "iget: Dir with htree data on filesystem without dir_index feature.");
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+ }
ei->i_disksize = inode->i_size;
#ifdef CONFIG_QUOTA
ei->i_reserved_quota = 0;
@@ -5746,7 +5758,7 @@
}
}
- percpu_down_write(&sbi->s_journal_flag_rwsem);
+ percpu_down_write(&sbi->s_writepages_rwsem);
jbd2_journal_lock_updates(journal);
/*
@@ -5763,7 +5775,7 @@
err = jbd2_journal_flush(journal);
if (err < 0) {
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_journal_flag_rwsem);
+ percpu_up_write(&sbi->s_writepages_rwsem);
ext4_inode_resume_unlocked_dio(inode);
return err;
}
@@ -5772,7 +5784,7 @@
ext4_set_aops(inode);
jbd2_journal_unlock_updates(journal);
- percpu_up_write(&sbi->s_journal_flag_rwsem);
+ percpu_up_write(&sbi->s_writepages_rwsem);
if (val)
up_write(&EXT4_I(inode)->i_mmap_sem);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 3d6f73e..471686e 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2377,7 +2377,7 @@
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
unsigned size;
- struct ext4_group_info ***new_groupinfo;
+ struct ext4_group_info ***old_groupinfo, ***new_groupinfo;
size = (ngroups + EXT4_DESC_PER_BLOCK(sb) - 1) >>
EXT4_DESC_PER_BLOCK_BITS(sb);
@@ -2390,13 +2390,16 @@
ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
return -ENOMEM;
}
- if (sbi->s_group_info) {
- memcpy(new_groupinfo, sbi->s_group_info,
+ rcu_read_lock();
+ old_groupinfo = rcu_dereference(sbi->s_group_info);
+ if (old_groupinfo)
+ memcpy(new_groupinfo, old_groupinfo,
sbi->s_group_info_size * sizeof(*sbi->s_group_info));
- kvfree(sbi->s_group_info);
- }
- sbi->s_group_info = new_groupinfo;
+ rcu_read_unlock();
+ rcu_assign_pointer(sbi->s_group_info, new_groupinfo);
sbi->s_group_info_size = size / sizeof(*sbi->s_group_info);
+ if (old_groupinfo)
+ ext4_kvfree_array_rcu(old_groupinfo);
ext4_debug("allocated s_groupinfo array for %d meta_bg's\n",
sbi->s_group_info_size);
return 0;
@@ -2408,6 +2411,7 @@
{
int i;
int metalen = 0;
+ int idx = group >> EXT4_DESC_PER_BLOCK_BITS(sb);
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_group_info **meta_group_info;
struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
@@ -2426,12 +2430,12 @@
"for a buddy group");
goto exit_meta_group_info;
}
- sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)] =
- meta_group_info;
+ rcu_read_lock();
+ rcu_dereference(sbi->s_group_info)[idx] = meta_group_info;
+ rcu_read_unlock();
}
- meta_group_info =
- sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)];
+ meta_group_info = sbi_array_rcu_deref(sbi, s_group_info, idx);
i = group & (EXT4_DESC_PER_BLOCK(sb) - 1);
meta_group_info[i] = kmem_cache_zalloc(cachep, GFP_NOFS);
@@ -2479,8 +2483,13 @@
exit_group_info:
/* If a meta_group_info table has been allocated, release it now */
if (group % EXT4_DESC_PER_BLOCK(sb) == 0) {
- kfree(sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)]);
- sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)] = NULL;
+ struct ext4_group_info ***group_info;
+
+ rcu_read_lock();
+ group_info = rcu_dereference(sbi->s_group_info);
+ kfree(group_info[idx]);
+ group_info[idx] = NULL;
+ rcu_read_unlock();
}
exit_meta_group_info:
return -ENOMEM;
@@ -2493,6 +2502,7 @@
struct ext4_sb_info *sbi = EXT4_SB(sb);
int err;
struct ext4_group_desc *desc;
+ struct ext4_group_info ***group_info;
struct kmem_cache *cachep;
err = ext4_mb_alloc_groupinfo(sb, ngroups);
@@ -2527,11 +2537,16 @@
while (i-- > 0)
kmem_cache_free(cachep, ext4_get_group_info(sb, i));
i = sbi->s_group_info_size;
+ rcu_read_lock();
+ group_info = rcu_dereference(sbi->s_group_info);
while (i-- > 0)
- kfree(sbi->s_group_info[i]);
+ kfree(group_info[i]);
+ rcu_read_unlock();
iput(sbi->s_buddy_cache);
err_freesgi:
- kvfree(sbi->s_group_info);
+ rcu_read_lock();
+ kvfree(rcu_dereference(sbi->s_group_info));
+ rcu_read_unlock();
return -ENOMEM;
}
@@ -2720,7 +2735,7 @@
ext4_group_t ngroups = ext4_get_groups_count(sb);
ext4_group_t i;
int num_meta_group_infos;
- struct ext4_group_info *grinfo;
+ struct ext4_group_info *grinfo, ***group_info;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
@@ -2738,9 +2753,12 @@
num_meta_group_infos = (ngroups +
EXT4_DESC_PER_BLOCK(sb) - 1) >>
EXT4_DESC_PER_BLOCK_BITS(sb);
+ rcu_read_lock();
+ group_info = rcu_dereference(sbi->s_group_info);
for (i = 0; i < num_meta_group_infos; i++)
- kfree(sbi->s_group_info[i]);
- kvfree(sbi->s_group_info);
+ kfree(group_info[i]);
+ kvfree(group_info);
+ rcu_read_unlock();
}
kfree(sbi->s_mb_offsets);
kfree(sbi->s_mb_maxs);
@@ -2999,7 +3017,8 @@
ext4_group_t flex_group = ext4_flex_group(sbi,
ac->ac_b_ex.fe_group);
atomic64_sub(ac->ac_b_ex.fe_len,
- &sbi->s_flex_groups[flex_group].free_clusters);
+ &sbi_array_rcu_deref(sbi, s_flex_groups,
+ flex_group)->free_clusters);
}
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
@@ -4890,7 +4909,8 @@
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
atomic64_add(count_clusters,
- &sbi->s_flex_groups[flex_group].free_clusters);
+ &sbi_array_rcu_deref(sbi, s_flex_groups,
+ flex_group)->free_clusters);
}
if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
@@ -5035,7 +5055,8 @@
if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed),
- &sbi->s_flex_groups[flex_group].free_clusters);
+ &sbi_array_rcu_deref(sbi, s_flex_groups,
+ flex_group)->free_clusters);
}
ext4_mb_unload_buddy(&e4b);
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 364ea4d..bce2d69 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -434,6 +434,7 @@
int ext4_ext_migrate(struct inode *inode)
{
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
handle_t *handle;
int retval = 0, i;
__le32 *i_data;
@@ -458,6 +459,8 @@
*/
return retval;
+ percpu_down_write(&sbi->s_writepages_rwsem);
+
/*
* Worst case we can touch the allocation bitmaps, a bgd
* block, and a block to link in the orphan list. We do need
@@ -468,7 +471,7 @@
if (IS_ERR(handle)) {
retval = PTR_ERR(handle);
- return retval;
+ goto out_unlock;
}
goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) *
EXT4_INODES_PER_GROUP(inode->i_sb)) + 1;
@@ -479,7 +482,7 @@
if (IS_ERR(tmp_inode)) {
retval = PTR_ERR(tmp_inode);
ext4_journal_stop(handle);
- return retval;
+ goto out_unlock;
}
i_size_write(tmp_inode, i_size_read(inode));
/*
@@ -521,7 +524,7 @@
*/
ext4_orphan_del(NULL, tmp_inode);
retval = PTR_ERR(handle);
- goto out;
+ goto out_tmp_inode;
}
ei = EXT4_I(inode);
@@ -602,10 +605,11 @@
/* Reset the extent details */
ext4_ext_tree_init(handle, tmp_inode);
ext4_journal_stop(handle);
-out:
+out_tmp_inode:
unlock_new_inode(tmp_inode);
iput(tmp_inode);
-
+out_unlock:
+ percpu_up_write(&sbi->s_writepages_rwsem);
return retval;
}
@@ -615,7 +619,8 @@
int ext4_ind_migrate(struct inode *inode)
{
struct ext4_extent_header *eh;
- struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ struct ext4_super_block *es = sbi->s_es;
struct ext4_inode_info *ei = EXT4_I(inode);
struct ext4_extent *ex;
unsigned int i, len;
@@ -639,9 +644,13 @@
if (test_opt(inode->i_sb, DELALLOC))
ext4_alloc_da_blocks(inode);
+ percpu_down_write(&sbi->s_writepages_rwsem);
+
handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ goto out_unlock;
+ }
down_write(&EXT4_I(inode)->i_data_sem);
ret = ext4_ext_check_inode(inode);
@@ -676,5 +685,7 @@
errout:
ext4_journal_stop(handle);
up_write(&EXT4_I(inode)->i_data_sem);
+out_unlock:
+ percpu_up_write(&sbi->s_writepages_rwsem);
return ret;
}
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index c2e830a..fb1ad95 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -119,10 +119,10 @@
{
__ext4_warning(sb, function, line, "%s", msg);
__ext4_warning(sb, function, line,
- "MMP failure info: last update time: %llu, last update "
- "node: %s, last update device: %s",
- (long long unsigned int) le64_to_cpu(mmp->mmp_time),
- mmp->mmp_nodename, mmp->mmp_bdevname);
+ "MMP failure info: last update time: %llu, last update node: %.*s, last update device: %.*s",
+ (unsigned long long)le64_to_cpu(mmp->mmp_time),
+ (int)sizeof(mmp->mmp_nodename), mmp->mmp_nodename,
+ (int)sizeof(mmp->mmp_bdevname), mmp->mmp_bdevname);
}
/*
@@ -153,6 +153,7 @@
mmp_check_interval = max(EXT4_MMP_CHECK_MULT * mmp_update_interval,
EXT4_MMP_MIN_CHECK_INTERVAL);
mmp->mmp_check_interval = cpu_to_le16(mmp_check_interval);
+ BUILD_BUG_ON(sizeof(mmp->mmp_bdevname) < BDEVNAME_SIZE);
bdevname(bh->b_bdev, mmp->mmp_bdevname);
memcpy(mmp->mmp_nodename, init_utsname()->nodename,
@@ -377,7 +378,8 @@
/*
* Start a kernel thread to update the MMP block periodically.
*/
- EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%s",
+ EXT4_SB(sb)->s_mmp_tsk = kthread_run(kmmpd, mmpd_data, "kmmpd-%.*s",
+ (int)sizeof(mmp->mmp_bdevname),
bdevname(bh->b_bdev,
mmp->mmp_bdevname));
if (IS_ERR(EXT4_SB(sb)->s_mmp_tsk)) {
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 9485f40..7f3015a 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1406,6 +1406,7 @@
/*
* We deal with the read-ahead logic here.
*/
+ cond_resched();
if (ra_ptr >= ra_max) {
/* Refill the readahead buffer */
ra_ptr = 0;
@@ -2108,6 +2109,13 @@
retval = ext4_dx_add_entry(handle, &fname, dir, inode);
if (!retval || (retval != ERR_BAD_DX_DIR))
goto out;
+ /* Can we just ignore htree data? */
+ if (ext4_has_metadata_csum(sb)) {
+ EXT4_ERROR_INODE(dir,
+ "Directory has corrupted htree index.");
+ retval = -EFSCORRUPTED;
+ goto out;
+ }
ext4_clear_inode_flag(dir, EXT4_INODE_INDEX);
dx_fallback++;
ext4_mark_inode_dirty(handle, dir);
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 55bda9f..e165e56 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -471,22 +471,32 @@
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) {
gfp_t gfp_flags = GFP_NOFS;
+ /*
+ * Since bounce page allocation uses a mempool, we can only use
+ * a waiting mask (i.e. request guaranteed allocation) on the
+ * first page of the bio. Otherwise it can deadlock.
+ */
+ if (io->io_bio)
+ gfp_flags = GFP_NOWAIT | __GFP_NOWARN;
retry_encrypt:
- if (!fscrypt_using_hardware_encryption(inode))
- data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0,
- page->index, gfp_flags);
- if (IS_ERR(data_page)) {
- ret = PTR_ERR(data_page);
- if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) {
- if (io->io_bio) {
- ext4_io_submit(io);
+ if (!fscrypt_using_hardware_encryption(inode)) {
+ data_page = fscrypt_encrypt_page(inode, page,
+ PAGE_SIZE, 0, page->index, gfp_flags);
+ if (IS_ERR(data_page)) {
+ ret = PTR_ERR(data_page);
+ if (ret == -ENOMEM && (io->io_bio ||
+ wbc->sync_mode == WB_SYNC_ALL)) {
+ gfp_flags = GFP_NOFS;
+ if (io->io_bio)
+ ext4_io_submit(io);
+ else
+ gfp_flags |= __GFP_NOFAIL;
congestion_wait(BLK_RW_ASYNC, HZ/50);
+ goto retry_encrypt;
}
- gfp_flags |= __GFP_NOFAIL;
- goto retry_encrypt;
+ data_page = NULL;
+ goto out;
}
- data_page = NULL;
- goto out;
}
}
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index aef2a24..845d984 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -16,6 +16,33 @@
#include "ext4_jbd2.h"
+struct ext4_rcu_ptr {
+ struct rcu_head rcu;
+ void *ptr;
+};
+
+static void ext4_rcu_ptr_callback(struct rcu_head *head)
+{
+ struct ext4_rcu_ptr *ptr;
+
+ ptr = container_of(head, struct ext4_rcu_ptr, rcu);
+ kvfree(ptr->ptr);
+ kfree(ptr);
+}
+
+void ext4_kvfree_array_rcu(void *to_free)
+{
+ struct ext4_rcu_ptr *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
+
+ if (ptr) {
+ ptr->ptr = to_free;
+ call_rcu(&ptr->rcu, ext4_rcu_ptr_callback);
+ return;
+ }
+ synchronize_rcu();
+ kvfree(to_free);
+}
+
int ext4_resize_begin(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -541,8 +568,8 @@
brelse(gdb);
goto out;
}
- memcpy(gdb->b_data, sbi->s_group_desc[j]->b_data,
- gdb->b_size);
+ memcpy(gdb->b_data, sbi_array_rcu_deref(sbi,
+ s_group_desc, j)->b_data, gdb->b_size);
set_buffer_uptodate(gdb);
err = ext4_handle_dirty_metadata(handle, NULL, gdb);
@@ -849,13 +876,15 @@
}
brelse(dind);
- o_group_desc = EXT4_SB(sb)->s_group_desc;
+ rcu_read_lock();
+ o_group_desc = rcu_dereference(EXT4_SB(sb)->s_group_desc);
memcpy(n_group_desc, o_group_desc,
EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
+ rcu_read_unlock();
n_group_desc[gdb_num] = gdb_bh;
- EXT4_SB(sb)->s_group_desc = n_group_desc;
+ rcu_assign_pointer(EXT4_SB(sb)->s_group_desc, n_group_desc);
EXT4_SB(sb)->s_gdb_count++;
- kvfree(o_group_desc);
+ ext4_kvfree_array_rcu(o_group_desc);
le16_add_cpu(&es->s_reserved_gdt_blocks, -1);
err = ext4_handle_dirty_super(handle, sb);
@@ -903,9 +932,11 @@
return err;
}
- o_group_desc = EXT4_SB(sb)->s_group_desc;
+ rcu_read_lock();
+ o_group_desc = rcu_dereference(EXT4_SB(sb)->s_group_desc);
memcpy(n_group_desc, o_group_desc,
EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
+ rcu_read_unlock();
n_group_desc[gdb_num] = gdb_bh;
BUFFER_TRACE(gdb_bh, "get_write_access");
@@ -916,9 +947,9 @@
return err;
}
- EXT4_SB(sb)->s_group_desc = n_group_desc;
+ rcu_assign_pointer(EXT4_SB(sb)->s_group_desc, n_group_desc);
EXT4_SB(sb)->s_gdb_count++;
- kvfree(o_group_desc);
+ ext4_kvfree_array_rcu(o_group_desc);
return err;
}
@@ -1180,7 +1211,8 @@
* use non-sparse filesystems anymore. This is already checked above.
*/
if (gdb_off) {
- gdb_bh = sbi->s_group_desc[gdb_num];
+ gdb_bh = sbi_array_rcu_deref(sbi, s_group_desc,
+ gdb_num);
BUFFER_TRACE(gdb_bh, "get_write_access");
err = ext4_journal_get_write_access(handle, gdb_bh);
@@ -1262,7 +1294,7 @@
/*
* get_write_access() has been called on gdb_bh by ext4_add_new_desc().
*/
- gdb_bh = sbi->s_group_desc[gdb_num];
+ gdb_bh = sbi_array_rcu_deref(sbi, s_group_desc, gdb_num);
/* Update group descriptor block for new group */
gdp = (struct ext4_group_desc *)(gdb_bh->b_data +
gdb_off * EXT4_DESC_SIZE(sb));
@@ -1390,11 +1422,14 @@
percpu_counter_read(&sbi->s_freeclusters_counter));
if (ext4_has_feature_flex_bg(sb) && sbi->s_log_groups_per_flex) {
ext4_group_t flex_group;
+ struct flex_groups *fg;
+
flex_group = ext4_flex_group(sbi, group_data[0].group);
+ fg = sbi_array_rcu_deref(sbi, s_flex_groups, flex_group);
atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
- &sbi->s_flex_groups[flex_group].free_clusters);
+ &fg->free_clusters);
atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
- &sbi->s_flex_groups[flex_group].free_inodes);
+ &fg->free_inodes);
}
/*
@@ -1489,7 +1524,8 @@
for (; gdb_num <= gdb_num_end; gdb_num++) {
struct buffer_head *gdb_bh;
- gdb_bh = sbi->s_group_desc[gdb_num];
+ gdb_bh = sbi_array_rcu_deref(sbi, s_group_desc,
+ gdb_num);
if (old_gdb == gdb_bh->b_blocknr)
continue;
update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7c5fcdd..38f2e5f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -826,6 +826,8 @@
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_super_block *es = sbi->s_es;
+ struct buffer_head **group_desc;
+ struct flex_groups **flex_groups;
int aborted = 0;
int i, err;
@@ -857,15 +859,23 @@
if (!(sb->s_flags & MS_RDONLY))
ext4_commit_super(sb, 1);
+ rcu_read_lock();
+ group_desc = rcu_dereference(sbi->s_group_desc);
for (i = 0; i < sbi->s_gdb_count; i++)
- brelse(sbi->s_group_desc[i]);
- kvfree(sbi->s_group_desc);
- kvfree(sbi->s_flex_groups);
+ brelse(group_desc[i]);
+ kvfree(group_desc);
+ flex_groups = rcu_dereference(sbi->s_flex_groups);
+ if (flex_groups) {
+ for (i = 0; i < sbi->s_flex_groups_allocated; i++)
+ kvfree(flex_groups[i]);
+ kvfree(flex_groups);
+ }
+ rcu_read_unlock();
percpu_counter_destroy(&sbi->s_freeclusters_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
- percpu_free_rwsem(&sbi->s_journal_flag_rwsem);
+ percpu_free_rwsem(&sbi->s_writepages_rwsem);
brelse(sbi->s_sbh);
#ifdef CONFIG_QUOTA
for (i = 0; i < EXT4_MAXQUOTAS; i++)
@@ -2116,8 +2126,8 @@
int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
- struct flex_groups *new_groups;
- int size;
+ struct flex_groups **old_groups, **new_groups;
+ int size, i, j;
if (!sbi->s_log_groups_per_flex)
return 0;
@@ -2126,22 +2136,37 @@
if (size <= sbi->s_flex_groups_allocated)
return 0;
- size = roundup_pow_of_two(size * sizeof(struct flex_groups));
- new_groups = ext4_kvzalloc(size, GFP_KERNEL);
+ new_groups = ext4_kvzalloc(roundup_pow_of_two(size *
+ sizeof(*sbi->s_flex_groups)), GFP_KERNEL);
if (!new_groups) {
- ext4_msg(sb, KERN_ERR, "not enough memory for %d flex groups",
- size / (int) sizeof(struct flex_groups));
+ ext4_msg(sb, KERN_ERR,
+ "not enough memory for %d flex group pointers", size);
return -ENOMEM;
}
-
- if (sbi->s_flex_groups) {
- memcpy(new_groups, sbi->s_flex_groups,
- (sbi->s_flex_groups_allocated *
- sizeof(struct flex_groups)));
- kvfree(sbi->s_flex_groups);
+ for (i = sbi->s_flex_groups_allocated; i < size; i++) {
+ new_groups[i] = ext4_kvzalloc(roundup_pow_of_two(
+ sizeof(struct flex_groups)),
+ GFP_KERNEL);
+ if (!new_groups[i]) {
+ for (j = sbi->s_flex_groups_allocated; j < i; j++)
+ kvfree(new_groups[j]);
+ kvfree(new_groups);
+ ext4_msg(sb, KERN_ERR,
+ "not enough memory for %d flex groups", size);
+ return -ENOMEM;
+ }
}
- sbi->s_flex_groups = new_groups;
- sbi->s_flex_groups_allocated = size / sizeof(struct flex_groups);
+ rcu_read_lock();
+ old_groups = rcu_dereference(sbi->s_flex_groups);
+ if (old_groups)
+ memcpy(new_groups, old_groups,
+ (sbi->s_flex_groups_allocated *
+ sizeof(struct flex_groups *)));
+ rcu_read_unlock();
+ rcu_assign_pointer(sbi->s_flex_groups, new_groups);
+ sbi->s_flex_groups_allocated = size;
+ if (old_groups)
+ ext4_kvfree_array_rcu(old_groups);
return 0;
}
@@ -2149,6 +2174,7 @@
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct ext4_group_desc *gdp = NULL;
+ struct flex_groups *fg;
ext4_group_t flex_group;
int i, err;
@@ -2166,12 +2192,11 @@
gdp = ext4_get_group_desc(sb, i, NULL);
flex_group = ext4_flex_group(sbi, i);
- atomic_add(ext4_free_inodes_count(sb, gdp),
- &sbi->s_flex_groups[flex_group].free_inodes);
+ fg = sbi_array_rcu_deref(sbi, s_flex_groups, flex_group);
+ atomic_add(ext4_free_inodes_count(sb, gdp), &fg->free_inodes);
atomic64_add(ext4_free_group_clusters(sb, gdp),
- &sbi->s_flex_groups[flex_group].free_clusters);
- atomic_add(ext4_used_dirs_count(sb, gdp),
- &sbi->s_flex_groups[flex_group].used_dirs);
+ &fg->free_clusters);
+ atomic_add(ext4_used_dirs_count(sb, gdp), &fg->used_dirs);
}
return 1;
@@ -2750,17 +2775,11 @@
return 0;
}
-#ifndef CONFIG_QUOTA
- if (ext4_has_feature_quota(sb) && !readonly) {
+#if !IS_ENABLED(CONFIG_QUOTA) || !IS_ENABLED(CONFIG_QFMT_V2)
+ if (!readonly && (ext4_has_feature_quota(sb) ||
+ ext4_has_feature_project(sb))) {
ext4_msg(sb, KERN_ERR,
- "Filesystem with quota feature cannot be mounted RDWR "
- "without CONFIG_QUOTA");
- return 0;
- }
- if (ext4_has_feature_project(sb) && !readonly) {
- ext4_msg(sb, KERN_ERR,
- "Filesystem with project quota feature cannot be mounted RDWR "
- "without CONFIG_QUOTA");
+ "The kernel was not built with CONFIG_QUOTA and CONFIG_QFMT_V2");
return 0;
}
#endif /* CONFIG_QUOTA */
@@ -3416,9 +3435,10 @@
static int ext4_fill_super(struct super_block *sb, void *data, int silent)
{
char *orig_data = kstrdup(data, GFP_KERNEL);
- struct buffer_head *bh;
+ struct buffer_head *bh, **group_desc;
struct ext4_super_block *es = NULL;
struct ext4_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ struct flex_groups **flex_groups;
ext4_fsblk_t block;
ext4_fsblk_t sb_block = get_sb_block(&data);
ext4_fsblk_t logical_sb_block;
@@ -3968,9 +3988,10 @@
goto failed_mount;
}
}
- sbi->s_group_desc = ext4_kvmalloc(db_count *
+ rcu_assign_pointer(sbi->s_group_desc,
+ ext4_kvmalloc(db_count *
sizeof(struct buffer_head *),
- GFP_KERNEL);
+ GFP_KERNEL));
if (sbi->s_group_desc == NULL) {
ext4_msg(sb, KERN_ERR, "not enough memory");
ret = -ENOMEM;
@@ -3980,14 +4001,19 @@
bgl_lock_init(sbi->s_blockgroup_lock);
for (i = 0; i < db_count; i++) {
+ struct buffer_head *bh;
+
block = descriptor_loc(sb, logical_sb_block, i);
- sbi->s_group_desc[i] = sb_bread_unmovable(sb, block);
- if (!sbi->s_group_desc[i]) {
+ bh = sb_bread_unmovable(sb, block);
+ if (!bh) {
ext4_msg(sb, KERN_ERR,
"can't read group descriptor %d", i);
db_count = i;
goto failed_mount2;
}
+ rcu_read_lock();
+ rcu_dereference(sbi->s_group_desc)[i] = bh;
+ rcu_read_unlock();
}
sbi->s_gdb_count = db_count;
if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
@@ -4238,7 +4264,7 @@
err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0,
GFP_KERNEL);
if (!err)
- err = percpu_init_rwsem(&sbi->s_journal_flag_rwsem);
+ err = percpu_init_rwsem(&sbi->s_writepages_rwsem);
if (err) {
ext4_msg(sb, KERN_ERR, "insufficient memory");
@@ -4326,13 +4352,19 @@
ext4_unregister_li_request(sb);
failed_mount6:
ext4_mb_release(sb);
- if (sbi->s_flex_groups)
- kvfree(sbi->s_flex_groups);
+ rcu_read_lock();
+ flex_groups = rcu_dereference(sbi->s_flex_groups);
+ if (flex_groups) {
+ for (i = 0; i < sbi->s_flex_groups_allocated; i++)
+ kvfree(flex_groups[i]);
+ kvfree(flex_groups);
+ }
+ rcu_read_unlock();
percpu_counter_destroy(&sbi->s_freeclusters_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
- percpu_free_rwsem(&sbi->s_journal_flag_rwsem);
+ percpu_free_rwsem(&sbi->s_writepages_rwsem);
failed_mount5:
ext4_ext_release(sb);
ext4_release_system_zone(sb);
@@ -4359,9 +4391,12 @@
if (sbi->s_mmp_tsk)
kthread_stop(sbi->s_mmp_tsk);
failed_mount2:
+ rcu_read_lock();
+ group_desc = rcu_dereference(sbi->s_group_desc);
for (i = 0; i < db_count; i++)
- brelse(sbi->s_group_desc[i]);
- kvfree(sbi->s_group_desc);
+ brelse(group_desc[i]);
+ kvfree(group_desc);
+ rcu_read_unlock();
failed_mount:
if (sbi->s_chksum_driver)
crypto_free_shash(sbi->s_chksum_driver);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index eea5bc2..7e2ef06 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -736,6 +736,13 @@
return NULL;
init_rwsem(&ei->truncate_lock);
+ /* Zeroing to allow iput() even if partial initialized inode. */
+ ei->mmu_private = 0;
+ ei->i_start = 0;
+ ei->i_logstart = 0;
+ ei->i_attrs = 0;
+ ei->i_pos = 0;
+
return &ei->vfs_inode;
}
@@ -1367,16 +1374,6 @@
return 0;
}
-static void fat_dummy_inode_init(struct inode *inode)
-{
- /* Initialize this dummy inode to work as no-op. */
- MSDOS_I(inode)->mmu_private = 0;
- MSDOS_I(inode)->i_start = 0;
- MSDOS_I(inode)->i_logstart = 0;
- MSDOS_I(inode)->i_attrs = 0;
- MSDOS_I(inode)->i_pos = 0;
-}
-
static int fat_read_root(struct inode *inode)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
@@ -1821,13 +1818,11 @@
fat_inode = new_inode(sb);
if (!fat_inode)
goto out_fail;
- fat_dummy_inode_init(fat_inode);
sbi->fat_inode = fat_inode;
fsinfo_inode = new_inode(sb);
if (!fsinfo_inode)
goto out_fail;
- fat_dummy_inode_init(fsinfo_inode);
fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
sbi->fsinfo_inode = fsinfo_inode;
insert_inode_hash(fsinfo_inode);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index bd6202b..daad7b0 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1248,7 +1248,7 @@
if (!(*opened & FILE_OPENED))
return finish_no_open(file, d);
dput(d);
- return 0;
+ return excl && (flags & O_CREAT) ? -EEXIST : 0;
}
BUG_ON(d != NULL);
diff --git a/fs/inode.c b/fs/inode.c
index bbd4531..0e148a6 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -135,6 +135,7 @@
inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
inode->i_flags = 0;
+ atomic64_set(&inode->i_sequence, 0);
atomic_set(&inode->i_count, 1);
inode->i_op = &empty_iops;
inode->i_fop = &no_open_fops;
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 4d5a5a4..addb078 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -168,7 +168,7 @@
"journal space in %s\n", __func__,
journal->j_devname);
WARN_ON(1);
- jbd2_journal_abort(journal, 0);
+ jbd2_journal_abort(journal, -EIO);
}
write_lock(&journal->j_state_lock);
} else {
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index d002b2b..1d06f81 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -779,7 +779,7 @@
err = journal_submit_commit_record(journal, commit_transaction,
&cbh, crc32_sum);
if (err)
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, err);
}
blk_finish_plug(&plug);
@@ -872,7 +872,7 @@
err = journal_submit_commit_record(journal, commit_transaction,
&cbh, crc32_sum);
if (err)
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, err);
}
if (cbh)
err = journal_wait_on_commit_record(journal, cbh);
@@ -969,29 +969,33 @@
* it. */
/*
- * A buffer which has been freed while still being journaled by
- * a previous transaction.
- */
- if (buffer_freed(bh)) {
+ * A buffer which has been freed while still being journaled
+ * by a previous transaction, refile the buffer to BJ_Forget of
+ * the running transaction. If the just committed transaction
+ * contains "add to orphan" operation, we can completely
+ * invalidate the buffer now. We are rather through in that
+ * since the buffer may be still accessible when blocksize <
+ * pagesize and it is attached to the last partial page.
+ */
+ if (buffer_freed(bh) && !jh->b_next_transaction) {
+ struct address_space *mapping;
+
+ clear_buffer_freed(bh);
+ clear_buffer_jbddirty(bh);
+
/*
- * If the running transaction is the one containing
- * "add to orphan" operation (b_next_transaction !=
- * NULL), we have to wait for that transaction to
- * commit before we can really get rid of the buffer.
- * So just clear b_modified to not confuse transaction
- * credit accounting and refile the buffer to
- * BJ_Forget of the running transaction. If the just
- * committed transaction contains "add to orphan"
- * operation, we can completely invalidate the buffer
- * now. We are rather through in that since the
- * buffer may be still accessible when blocksize <
- * pagesize and it is attached to the last partial
- * page.
+ * Block device buffers need to stay mapped all the
+ * time, so it is enough to clear buffer_jbddirty and
+ * buffer_freed bits. For the file mapping buffers (i.e.
+ * journalled data) we need to unmap buffer and clear
+ * more bits. We also need to be careful about the check
+ * because the data page mapping can get cleared under
+ * out hands, which alse need not to clear more bits
+ * because the page and buffers will be freed and can
+ * never be reused once we are done with them.
*/
- jh->b_modified = 0;
- if (!jh->b_next_transaction) {
- clear_buffer_freed(bh);
- clear_buffer_jbddirty(bh);
+ mapping = READ_ONCE(bh->b_page->mapping);
+ if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) {
clear_buffer_mapped(bh);
clear_buffer_new(bh);
clear_buffer_req(bh);
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 3cbcf64..efc8cfd 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1670,6 +1670,11 @@
journal->j_devname);
return -EFSCORRUPTED;
}
+ /*
+ * clear JBD2_ABORT flag initialized in journal_init_common
+ * here to update log tail information with the newest seq.
+ */
+ journal->j_flags &= ~JBD2_ABORT;
/* OK, we've finished with the dynamic journal bits:
* reinitialise the dynamic contents of the superblock in memory
@@ -1677,7 +1682,6 @@
if (journal_reset(journal))
goto recovery_error;
- journal->j_flags &= ~JBD2_ABORT;
journal->j_flags |= JBD2_LOADED;
return 0;
@@ -2096,12 +2100,10 @@
__jbd2_journal_abort_hard(journal);
- if (errno) {
- jbd2_journal_update_sb_errno(journal);
- write_lock(&journal->j_state_lock);
- journal->j_flags |= JBD2_REC_ERR;
- write_unlock(&journal->j_state_lock);
- }
+ jbd2_journal_update_sb_errno(journal);
+ write_lock(&journal->j_state_lock);
+ journal->j_flags |= JBD2_REC_ERR;
+ write_unlock(&journal->j_state_lock);
}
/**
@@ -2143,11 +2145,6 @@
* failure to disk. ext3_error, for example, now uses this
* functionality.
*
- * Errors which originate from within the journaling layer will NOT
- * supply an errno; a null errno implies that absolutely no further
- * writes are done to the journal (unless there are any already in
- * progress).
- *
*/
void jbd2_journal_abort(journal_t *journal, int errno)
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 799f96c..8de458d 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1037,8 +1037,8 @@
/* For undo access buffer must have data copied */
if (undo && !jh->b_committed_data)
goto out;
- if (jh->b_transaction != handle->h_transaction &&
- jh->b_next_transaction != handle->h_transaction)
+ if (READ_ONCE(jh->b_transaction) != handle->h_transaction &&
+ READ_ONCE(jh->b_next_transaction) != handle->h_transaction)
goto out;
/*
* There are two reasons for the barrier here:
@@ -2213,14 +2213,16 @@
return -EBUSY;
}
/*
- * OK, buffer won't be reachable after truncate. We just set
- * j_next_transaction to the running transaction (if there is
- * one) and mark buffer as freed so that commit code knows it
- * should clear dirty bits when it is done with the buffer.
+ * OK, buffer won't be reachable after truncate. We just clear
+ * b_modified to not confuse transaction credit accounting, and
+ * set j_next_transaction to the running transaction (if there
+ * is one) and mark buffer as freed so that commit code knows
+ * it should clear dirty bits when it is done with the buffer.
*/
set_buffer_freed(bh);
if (journal->j_running_transaction && buffer_jbddirty(bh))
jh->b_next_transaction = journal->j_running_transaction;
+ jh->b_modified = 0;
jbd2_journal_put_journal_head(jh);
spin_unlock(&journal->j_list_lock);
jbd_unlock_bh_state(bh);
@@ -2446,8 +2448,8 @@
* our jh reference and thus __jbd2_journal_file_buffer() must not
* take a new one.
*/
- jh->b_transaction = jh->b_next_transaction;
- jh->b_next_transaction = NULL;
+ WRITE_ONCE(jh->b_transaction, jh->b_next_transaction);
+ WRITE_ONCE(jh->b_next_transaction, NULL);
if (buffer_freed(bh))
jlist = BJ_Forget;
else if (jh->b_modified)
diff --git a/fs/libfs.c b/fs/libfs.c
index 9dc0e1e..278457f 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -799,7 +799,7 @@
{
struct simple_attr *attr;
- attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+ attr = kzalloc(sizeof(*attr), GFP_KERNEL);
if (!attr)
return -ENOMEM;
@@ -839,9 +839,11 @@
if (ret)
return ret;
- if (*ppos) { /* continued read */
+ if (*ppos && attr->get_buf[0]) {
+ /* continued read */
size = strlen(attr->get_buf);
- } else { /* first read */
+ } else {
+ /* first read */
u64 val;
ret = attr->get(attr->data, &val);
if (ret)
diff --git a/fs/namei.c b/fs/namei.c
index a251978..60937b8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1469,7 +1469,7 @@
nd->path.dentry = parent;
nd->seq = seq;
if (unlikely(!path_connected(&nd->path)))
- return -ENOENT;
+ return -ECHILD;
break;
} else {
struct mount *mnt = real_mount(nd->path.mnt);
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index b1daeaf..c342876 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -89,7 +89,7 @@
config NFS_SWAP
bool "Provide swap over NFS support"
default n
- depends on NFS_FS
+ depends on NFS_FS && SWAP
select SUNRPC_SWAP
help
This option enables swapon to work on files located on NFS mounts.
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 9d75374..0d4a56c 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -419,7 +419,7 @@
uint32_t nrclists,
struct referring_call_list *rclists)
{
- bool status = 0;
+ bool status = false;
int i, j;
struct nfs4_session *session;
struct nfs4_slot_table *tbl;
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 1e5321d..2517fcd 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -57,7 +57,7 @@
const struct file_operations nfs_dir_operations = {
.llseek = nfs_llseek_dir,
.read = generic_read_dir,
- .iterate_shared = nfs_readdir,
+ .iterate = nfs_readdir,
.open = nfs_opendir,
.release = nfs_closedir,
.fsync = nfs_fsync_dir,
@@ -145,7 +145,6 @@
};
struct nfs_cache_array {
- atomic_t refcount;
int size;
int eof_index;
u64 last_cookie;
@@ -170,6 +169,17 @@
unsigned int eof:1;
} nfs_readdir_descriptor_t;
+static
+void nfs_readdir_init_array(struct page *page)
+{
+ struct nfs_cache_array *array;
+
+ array = kmap_atomic(page);
+ memset(array, 0, sizeof(struct nfs_cache_array));
+ array->eof_index = -1;
+ kunmap_atomic(array);
+}
+
/*
* The caller is responsible for calling nfs_readdir_release_array(page)
*/
@@ -201,20 +211,12 @@
int i;
array = kmap_atomic(page);
- if (atomic_dec_and_test(&array->refcount))
- for (i = 0; i < array->size; i++)
- kfree(array->array[i].string.name);
+ for (i = 0; i < array->size; i++)
+ kfree(array->array[i].string.name);
+ array->size = 0;
kunmap_atomic(array);
}
-static bool grab_page(struct page *page)
-{
- struct nfs_cache_array *array = kmap_atomic(page);
- bool res = atomic_inc_not_zero(&array->refcount);
- kunmap_atomic(array);
- return res;
-}
-
/*
* the caller is responsible for freeing qstr.name
* when called by nfs_readdir_add_to_array, the strings will be freed in
@@ -287,7 +289,7 @@
desc->cache_entry_index = index;
return 0;
out_eof:
- desc->eof = 1;
+ desc->eof = true;
return -EBADCOOKIE;
}
@@ -341,7 +343,7 @@
if (array->eof_index >= 0) {
status = -EBADCOOKIE;
if (*desc->dir_cookie == array->last_cookie)
- desc->eof = 1;
+ desc->eof = true;
}
out:
return status;
@@ -653,6 +655,8 @@
int status = -ENOMEM;
unsigned int array_size = ARRAY_SIZE(pages);
+ nfs_readdir_init_array(page);
+
entry.prev_cookie = 0;
entry.cookie = desc->last_cookie;
entry.eof = 0;
@@ -673,9 +677,6 @@
status = PTR_ERR(array);
goto out_label_free;
}
- memset(array, 0, sizeof(struct nfs_cache_array));
- atomic_set(&array->refcount, 1);
- array->eof_index = -1;
status = nfs_readdir_alloc_pages(pages, array_size);
if (status < 0)
@@ -730,6 +731,7 @@
unlock_page(page);
return 0;
error:
+ nfs_readdir_clear_array(page);
unlock_page(page);
return ret;
}
@@ -737,7 +739,6 @@
static
void cache_page_release(nfs_readdir_descriptor_t *desc)
{
- nfs_readdir_clear_array(desc->page);
put_page(desc->page);
desc->page = NULL;
}
@@ -745,33 +746,34 @@
static
struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
{
- struct page *page;
-
- for (;;) {
- page = read_cache_page(desc->file->f_mapping,
+ return read_cache_page(desc->file->f_mapping,
desc->page_index, (filler_t *)nfs_readdir_filler, desc);
- if (IS_ERR(page) || grab_page(page))
- break;
- put_page(page);
- }
- return page;
}
/*
* Returns 0 if desc->dir_cookie was found on page desc->page_index
+ * and locks the page to prevent removal from the page cache.
*/
static
-int find_cache_page(nfs_readdir_descriptor_t *desc)
+int find_and_lock_cache_page(nfs_readdir_descriptor_t *desc)
{
int res;
desc->page = get_cache_page(desc);
if (IS_ERR(desc->page))
return PTR_ERR(desc->page);
-
- res = nfs_readdir_search_array(desc);
+ res = lock_page_killable(desc->page);
if (res != 0)
- cache_page_release(desc);
+ goto error;
+ res = -EAGAIN;
+ if (desc->page->mapping != NULL) {
+ res = nfs_readdir_search_array(desc);
+ if (res == 0)
+ return 0;
+ }
+ unlock_page(desc->page);
+error:
+ cache_page_release(desc);
return res;
}
@@ -786,7 +788,7 @@
desc->last_cookie = 0;
}
do {
- res = find_cache_page(desc);
+ res = find_and_lock_cache_page(desc);
} while (res == -EAGAIN);
return res;
}
@@ -815,7 +817,7 @@
ent = &array->array[i];
if (!dir_emit(desc->ctx, ent->string.name, ent->string.len,
nfs_compat_user_ino64(ent->ino), ent->d_type)) {
- desc->eof = 1;
+ desc->eof = true;
break;
}
desc->ctx->pos++;
@@ -827,11 +829,10 @@
ctx->duped = 1;
}
if (array->eof_index >= 0)
- desc->eof = 1;
+ desc->eof = true;
nfs_readdir_release_array(desc->page);
out:
- cache_page_release(desc);
dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
(unsigned long long)*desc->dir_cookie, res);
return res;
@@ -877,13 +878,13 @@
status = nfs_do_filldir(desc);
+ out_release:
+ nfs_readdir_clear_array(desc->page);
+ cache_page_release(desc);
out:
dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
__func__, status);
return status;
- out_release:
- cache_page_release(desc);
- goto out;
}
/* The file offset position represents the dirent entry number. A
@@ -928,7 +929,7 @@
if (res == -EBADCOOKIE) {
res = 0;
/* This means either end of directory */
- if (*desc->dir_cookie && desc->eof == 0) {
+ if (*desc->dir_cookie && !desc->eof) {
/* Or that the server has 'lost' a cookie */
res = uncached_readdir(desc);
if (res == 0)
@@ -948,6 +949,8 @@
break;
res = nfs_do_filldir(desc);
+ unlock_page(desc->page);
+ cache_page_release(desc);
if (res < 0)
break;
} while (!desc->eof);
@@ -960,11 +963,13 @@
static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
{
+ struct inode *inode = file_inode(filp);
struct nfs_open_dir_context *dir_ctx = filp->private_data;
dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
filp, offset, whence);
+ inode_lock(inode);
switch (whence) {
case 1:
offset += filp->f_pos;
@@ -972,13 +977,16 @@
if (offset >= 0)
break;
default:
- return -EINVAL;
+ offset = -EINVAL;
+ goto out;
}
if (offset != filp->f_pos) {
filp->f_pos = offset;
dir_ctx->dir_cookie = 0;
dir_ctx->duped = 0;
}
+out:
+ inode_unlock(inode);
return offset;
}
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 1ec6dd4..3ee60c5 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -847,7 +847,7 @@
spin_lock(&nn->nfs_client_lock);
list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
- if (nfs4_cb_match_client(addr, clp, minorversion) == false)
+ if (!nfs4_cb_match_client(addr, clp, minorversion))
continue;
if (!nfs4_has_session(clp))
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ca4249a..632d3c3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2916,6 +2916,11 @@
exception.retry = 1;
continue;
}
+ if (status == -NFS4ERR_EXPIRED) {
+ nfs4_schedule_lease_recovery(server->nfs_client);
+ exception.retry = 1;
+ continue;
+ }
if (status == -EAGAIN) {
/* We must have found a delegation */
exception.retry = 1;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 0e008db..c3abf92 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1436,7 +1436,7 @@
if ((range->iomode == IOMODE_RW &&
ls_range->iomode != IOMODE_RW) ||
(range->iomode != ls_range->iomode &&
- strict_iomode == true) ||
+ strict_iomode) ||
!pnfs_lseg_range_intersecting(ls_range, range))
return 0;
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 6481369..f6cc2fd 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -680,7 +680,7 @@
/* Client gets 2 lease periods to return it */
cutoff = ktime_add_ns(task->tk_start,
- nn->nfsd4_lease * NSEC_PER_SEC * 2);
+ (u64)nn->nfsd4_lease * NSEC_PER_SEC * 2);
if (ktime_before(now, cutoff)) {
rpc_delay(task, HZ/100); /* 10 mili-seconds */
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index db4bd70..4509c76 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6034,7 +6034,7 @@
}
if (fl_flags & FL_SLEEP) {
- nbl->nbl_time = jiffies;
+ nbl->nbl_time = get_seconds();
spin_lock(&nn->blocked_locks_lock);
list_add_tail(&nbl->nbl_list, &lock_sop->lo_blocked);
list_add_tail(&nbl->nbl_lru, &nn->blocked_locks_lru);
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 133d8bf..7872b1e 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -591,7 +591,7 @@
struct nfsd4_blocked_lock {
struct list_head nbl_list;
struct list_head nbl_lru;
- unsigned long nbl_time;
+ time_t nbl_time;
struct file_lock nbl_lock;
struct knfsd_fh nbl_fh;
struct nfsd4_callback nbl_cb;
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 497a4171..bfb50fc 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -637,9 +637,11 @@
{
struct ocfs2_inode_info *oi = OCFS2_I(inode);
- oi->i_sync_tid = handle->h_transaction->t_tid;
- if (datasync)
- oi->i_datasync_tid = handle->h_transaction->t_tid;
+ if (!is_handle_aborted(handle)) {
+ oi->i_sync_tid = handle->h_transaction->t_tid;
+ if (datasync)
+ oi->i_datasync_tid = handle->h_transaction->t_tid;
+ }
}
#endif /* OCFS2_JOURNAL_H */
diff --git a/fs/open.c b/fs/open.c
index 2ff8876..f2b82c4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -837,9 +837,6 @@
* the return value of d_splice_alias(), then the caller needs to perform dput()
* on it after finish_open().
*
- * On successful return @file is a fully instantiated open file. After this, if
- * an error occurs in ->atomic_open(), it needs to clean up with fput().
- *
* Returns zero on success or -errno if the open failed.
*/
int finish_open(struct file *file, struct dentry *dentry,
diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
index 0748a26..7d7df00 100644
--- a/fs/orangefs/orangefs-debugfs.c
+++ b/fs/orangefs/orangefs-debugfs.c
@@ -304,6 +304,7 @@
static void *help_next(struct seq_file *m, void *v, loff_t *pos)
{
+ (*pos)++;
gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n");
return NULL;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index a97e352..5f5fff0 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -2249,7 +2249,8 @@
/* also releases the path */
unfix_nodes(&s_ins_balance);
#ifdef REISERQUOTA_DEBUG
- reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
+ if (inode)
+ reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
"reiserquota insert_item(): freeing %u id=%u type=%c",
quota_bytes, inode->i_uid, head2type(ih));
#endif
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index bfed2a7..677608a 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1928,7 +1928,7 @@
if (!sbi->s_jdev) {
SWARN(silent, s, "", "Cannot allocate memory for "
"journal device name");
- goto error;
+ goto error_unlocked;
}
}
#ifdef CONFIG_QUOTA
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index b4fbeef..5ef0d1d 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -721,6 +721,7 @@
int err, page_idx, page_cnt, ret = 0, n = 0;
int allocate = bu->buf ? 0 : 1;
loff_t isize;
+ gfp_t ra_gfp_mask = readahead_gfp_mask(mapping) & ~__GFP_FS;
err = ubifs_tnc_get_bu_keys(c, bu);
if (err)
@@ -782,8 +783,9 @@
if (page_offset > end_index)
break;
- page = find_or_create_page(mapping, page_offset,
- GFP_NOFS | __GFP_COLD);
+ page = pagecache_get_page(mapping, page_offset,
+ FGP_LOCK|FGP_ACCESSED|FGP_CREAT|FGP_NOWAIT,
+ ra_gfp_mask);
if (!page)
break;
if (!PageUptodate(page))
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 03369a8..4abdba4 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -2460,17 +2460,29 @@
static unsigned int udf_count_free(struct super_block *sb)
{
unsigned int accum = 0;
- struct udf_sb_info *sbi;
+ struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map;
+ unsigned int part = sbi->s_partition;
+ int ptype = sbi->s_partmaps[part].s_partition_type;
- sbi = UDF_SB(sb);
+ if (ptype == UDF_METADATA_MAP25) {
+ part = sbi->s_partmaps[part].s_type_specific.s_metadata.
+ s_phys_partition_ref;
+ } else if (ptype == UDF_VIRTUAL_MAP15 || ptype == UDF_VIRTUAL_MAP20) {
+ /*
+ * Filesystems with VAT are append-only and we cannot write to
+ * them. Let's just report 0 here.
+ */
+ return 0;
+ }
+
if (sbi->s_lvid_bh) {
struct logicalVolIntegrityDesc *lvid =
(struct logicalVolIntegrityDesc *)
sbi->s_lvid_bh->b_data;
- if (le32_to_cpu(lvid->numOfPartitions) > sbi->s_partition) {
+ if (le32_to_cpu(lvid->numOfPartitions) > part) {
accum = le32_to_cpu(
- lvid->freeSpaceTable[sbi->s_partition]);
+ lvid->freeSpaceTable[part]);
if (accum == 0xFFFFFFFF)
accum = 0;
}
@@ -2479,7 +2491,7 @@
if (accum)
return accum;
- map = &sbi->s_partmaps[sbi->s_partition];
+ map = &sbi->s_partmaps[part];
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
accum += udf_count_free_bitmap(sb,
map->s_uspace.s_bitmap);
diff --git a/gen_headers_arm.bp b/gen_headers_arm.bp
new file mode 100644
index 0000000..e8d2f2f
--- /dev/null
+++ b/gen_headers_arm.bp
@@ -0,0 +1,976 @@
+// ***** DO NOT EDIT *****
+// This file is generated by kernel_headers.py
+
+gen_headers_srcs_arm = [
+ "arch/arm/include/uapi/asm/Kbuild",
+ "include/uapi/asm-generic/Kbuild.asm",
+ "Makefile",
+ "arch/arm/tools/syscall.tbl",
+ "include/uapi/**/*.h",
+ "arch/arm/include/uapi/**/*.h",
+]
+
+gen_headers_exclude_srcs_arm = [
+ "include/uapi/linux/a.out.h",
+ "include/uapi/drm/armada_drm.h",
+ "include/uapi/drm/etnaviv_drm.h",
+ "include/uapi/drm/omap_drm.h",
+ "include/uapi/drm/vgem_drm.h",
+ "include/uapi/linux/auto_dev-ioctl.h",
+ "include/uapi/linux/batman_adv.h",
+ "include/uapi/linux/bcache.h",
+ "include/uapi/linux/btrfs_tree.h",
+ "include/uapi/linux/cryptouser.h",
+ "include/uapi/linux/dma-buf.h",
+ "include/uapi/linux/hash_info.h",
+ "include/uapi/linux/kcm.h",
+ "include/uapi/linux/kcov.h",
+ "include/uapi/linux/kfd_ioctl.h",
+ "include/uapi/linux/lightnvm.h",
+ "include/uapi/linux/module.h",
+ "include/uapi/linux/nilfs2_api.h",
+ "include/uapi/linux/nilfs2_ondisk.h",
+ "include/uapi/linux/nsfs.h",
+ "include/uapi/linux/pr.h",
+ "include/uapi/linux/qrtr.h",
+ "include/uapi/linux/stm.h",
+ "include/uapi/linux/tee.h",
+ "include/uapi/linux/userio.h",
+ "include/uapi/linux/wil6210_uapi.h",
+ "include/uapi/rdma/qedr-abi.h",
+ "include/uapi/video/adf.h",
+ "include/uapi/linux/cifs/cifs_mount.h",
+ "include/uapi/linux/genwqe/genwqe_card.h",
+ "include/uapi/linux/netfilter/xt_HARDIDLETIMER.h",
+ "include/uapi/linux/usb/f_accessory.h",
+ "include/uapi/linux/usb/f_mtp.h",
+]
+
+gen_headers_out_arm = [
+
+ // Matching generated-y:
+
+ "asm/unistd-common.h",
+ "asm/unistd-oabi.h",
+ "asm/unistd-eabi.h",
+
+ // Matching mandatory-y:
+
+ "asm/bitsperlong.h",
+ "asm/errno.h",
+ "asm/ioctl.h",
+ "asm/ipcbuf.h",
+ "asm/msgbuf.h",
+ "asm/param.h",
+ "asm/poll.h",
+ "asm/resource.h",
+ "asm/sembuf.h",
+ "asm/shmbuf.h",
+ "asm/siginfo.h",
+ "asm/socket.h",
+ "asm/sockios.h",
+ "asm/termbits.h",
+ "asm/termios.h",
+
+ // From include/uapi/**/*.h
+
+ "asm-generic/auxvec.h",
+ "asm-generic/bitsperlong.h",
+ "asm-generic/errno-base.h",
+ "asm-generic/errno.h",
+ "asm-generic/fcntl.h",
+ "asm-generic/int-l64.h",
+ "asm-generic/int-ll64.h",
+ "asm-generic/ioctl.h",
+ "asm-generic/ioctls.h",
+ "asm-generic/ipcbuf.h",
+ "asm-generic/kvm_para.h",
+ "asm-generic/mman-common.h",
+ "asm-generic/mman.h",
+ "asm-generic/msgbuf.h",
+ "asm-generic/param.h",
+ "asm-generic/poll.h",
+ "asm-generic/posix_types.h",
+ "asm-generic/resource.h",
+ "asm-generic/sembuf.h",
+ "asm-generic/setup.h",
+ "asm-generic/shmbuf.h",
+ "asm-generic/shmparam.h",
+ "asm-generic/siginfo.h",
+ "asm-generic/signal-defs.h",
+ "asm-generic/signal.h",
+ "asm-generic/socket.h",
+ "asm-generic/sockios.h",
+ "asm-generic/stat.h",
+ "asm-generic/statfs.h",
+ "asm-generic/swab.h",
+ "asm-generic/termbits.h",
+ "asm-generic/termios.h",
+ "asm-generic/types.h",
+ "asm-generic/ucontext.h",
+ "asm-generic/unistd.h",
+ "drm/amdgpu_drm.h",
+ "drm/drm.h",
+ "drm/drm_fourcc.h",
+ "drm/drm_mode.h",
+ "drm/drm_sarea.h",
+ "drm/exynos_drm.h",
+ "drm/i810_drm.h",
+ "drm/i915_drm.h",
+ "drm/mga_drm.h",
+ "drm/msm_drm.h",
+ "drm/msm_drm_pp.h",
+ "drm/nouveau_drm.h",
+ "drm/qxl_drm.h",
+ "drm/r128_drm.h",
+ "drm/radeon_drm.h",
+ "drm/savage_drm.h",
+ "drm/sde_drm.h",
+ "drm/sis_drm.h",
+ "drm/tegra_drm.h",
+ "drm/vc4_drm.h",
+ "drm/via_drm.h",
+ "drm/virtgpu_drm.h",
+ "drm/vmwgfx_drm.h",
+ "linux/acct.h",
+ "linux/adb.h",
+ "linux/adfs_fs.h",
+ "linux/affs_hardblocks.h",
+ "linux/agpgart.h",
+ "linux/aio_abi.h",
+ "linux/am437x-vpfe.h",
+ "linux/apm_bios.h",
+ "linux/arcfb.h",
+ "linux/atalk.h",
+ "linux/atm.h",
+ "linux/atm_eni.h",
+ "linux/atm_he.h",
+ "linux/atm_idt77105.h",
+ "linux/atm_nicstar.h",
+ "linux/atm_tcp.h",
+ "linux/atm_zatm.h",
+ "linux/atmapi.h",
+ "linux/atmarp.h",
+ "linux/atmbr2684.h",
+ "linux/atmclip.h",
+ "linux/atmdev.h",
+ "linux/atmioc.h",
+ "linux/atmlec.h",
+ "linux/atmmpc.h",
+ "linux/atmppp.h",
+ "linux/atmsap.h",
+ "linux/atmsvc.h",
+ "linux/audit.h",
+ "linux/auto_fs.h",
+ "linux/auto_fs4.h",
+ "linux/auxvec.h",
+ "linux/ax25.h",
+ "linux/b1lli.h",
+ "linux/batterydata-interface.h",
+ "linux/baycom.h",
+ "linux/bcm933xx_hcs.h",
+ "linux/bfs_fs.h",
+ "linux/bgcom_interface.h",
+ "linux/binfmts.h",
+ "linux/blkpg.h",
+ "linux/blktrace_api.h",
+ "linux/bpf.h",
+ "linux/bpf_common.h",
+ "linux/bpf_perf_event.h",
+ "linux/bpqether.h",
+ "linux/bsg.h",
+ "linux/bt-bmc.h",
+ "linux/btrfs.h",
+ "linux/can.h",
+ "linux/capability.h",
+ "linux/capi.h",
+ "linux/cciss_defs.h",
+ "linux/cciss_ioctl.h",
+ "linux/cdrom.h",
+ "linux/cgroupstats.h",
+ "linux/chio.h",
+ "linux/cm4000_cs.h",
+ "linux/cn_proc.h",
+ "linux/coda.h",
+ "linux/coda_psdev.h",
+ "linux/coff.h",
+ "linux/connector.h",
+ "linux/const.h",
+ "linux/coresight-stm.h",
+ "linux/cramfs_fs.h",
+ "linux/cuda.h",
+ "linux/cyclades.h",
+ "linux/cycx_cfm.h",
+ "linux/dcbnl.h",
+ "linux/dccp.h",
+ "linux/devlink.h",
+ "linux/dlm.h",
+ "linux/dlm_device.h",
+ "linux/dlm_netlink.h",
+ "linux/dlm_plock.h",
+ "linux/dlmconstants.h",
+ "linux/dm-ioctl.h",
+ "linux/dm-log-userspace.h",
+ "linux/dn.h",
+ "linux/dqblk_xfs.h",
+ "linux/edd.h",
+ "linux/efs_fs_sb.h",
+ "linux/elf-em.h",
+ "linux/elf-fdpic.h",
+ "linux/elf.h",
+ "linux/elfcore.h",
+ "linux/errno.h",
+ "linux/errqueue.h",
+ "linux/esoc_ctrl.h",
+ "linux/ethtool.h",
+ "linux/eventpoll.h",
+ "linux/fadvise.h",
+ "linux/falloc.h",
+ "linux/fanotify.h",
+ "linux/fb.h",
+ "linux/fcntl.h",
+ "linux/fd.h",
+ "linux/fdreg.h",
+ "linux/fib_rules.h",
+ "linux/fiemap.h",
+ "linux/filter.h",
+ "linux/fips_status.h",
+ "linux/firewire-cdev.h",
+ "linux/firewire-constants.h",
+ "linux/flat.h",
+ "linux/fou.h",
+ "linux/fs.h",
+ "linux/fsl_hypervisor.h",
+ "linux/fuse.h",
+ "linux/futex.h",
+ "linux/gameport.h",
+ "linux/gen_stats.h",
+ "linux/genetlink.h",
+ "linux/gfs2_ondisk.h",
+ "linux/gigaset_dev.h",
+ "linux/gpio.h",
+ "linux/gsmmux.h",
+ "linux/gtp.h",
+ "linux/hbtp_input.h",
+ "linux/hdlc.h",
+ "linux/hdlcdrv.h",
+ "linux/hdreg.h",
+ "linux/hid.h",
+ "linux/hiddev.h",
+ "linux/hidraw.h",
+ "linux/hpet.h",
+ "linux/hsr_netlink.h",
+ "linux/hw_breakpoint.h",
+ "linux/hyperv.h",
+ "linux/hysdn_if.h",
+ "linux/i2c-dev.h",
+ "linux/i2c.h",
+ "linux/i2o-dev.h",
+ "linux/i8k.h",
+ "linux/icmp.h",
+ "linux/icmpv6.h",
+ "linux/if.h",
+ "linux/if_addr.h",
+ "linux/if_addrlabel.h",
+ "linux/if_alg.h",
+ "linux/if_arcnet.h",
+ "linux/if_arp.h",
+ "linux/if_bonding.h",
+ "linux/if_bridge.h",
+ "linux/if_cablemodem.h",
+ "linux/if_eql.h",
+ "linux/if_ether.h",
+ "linux/if_fc.h",
+ "linux/if_fddi.h",
+ "linux/if_frad.h",
+ "linux/if_hippi.h",
+ "linux/if_infiniband.h",
+ "linux/if_link.h",
+ "linux/if_ltalk.h",
+ "linux/if_macsec.h",
+ "linux/if_packet.h",
+ "linux/if_phonet.h",
+ "linux/if_plip.h",
+ "linux/if_ppp.h",
+ "linux/if_pppol2tp.h",
+ "linux/if_pppolac.h",
+ "linux/if_pppopns.h",
+ "linux/if_pppox.h",
+ "linux/if_slip.h",
+ "linux/if_team.h",
+ "linux/if_tun.h",
+ "linux/if_tunnel.h",
+ "linux/if_vlan.h",
+ "linux/if_x25.h",
+ "linux/igmp.h",
+ "linux/ila.h",
+ "linux/in.h",
+ "linux/in6.h",
+ "linux/in_route.h",
+ "linux/inet_diag.h",
+ "linux/inotify.h",
+ "linux/input-event-codes.h",
+ "linux/input.h",
+ "linux/ioctl.h",
+ "linux/ion.h",
+ "linux/ip.h",
+ "linux/ip6_tunnel.h",
+ "linux/ip_vs.h",
+ "linux/ipa_qmi_service_v01.h",
+ "linux/ipc.h",
+ "linux/ipmi.h",
+ "linux/ipmi_msgdefs.h",
+ "linux/ipsec.h",
+ "linux/ipv6.h",
+ "linux/ipv6_route.h",
+ "linux/ipx.h",
+ "linux/irda.h",
+ "linux/irqnr.h",
+ "linux/isdn.h",
+ "linux/isdn_divertif.h",
+ "linux/isdn_ppp.h",
+ "linux/isdnif.h",
+ "linux/iso_fs.h",
+ "linux/ivtv.h",
+ "linux/ivtvfb.h",
+ "linux/ixjuser.h",
+ "linux/jffs2.h",
+ "linux/joystick.h",
+ "linux/kcmp.h",
+ "linux/kd.h",
+ "linux/kdev_t.h",
+ "linux/kernel-page-flags.h",
+ "linux/kernel.h",
+ "linux/kernelcapi.h",
+ "linux/kexec.h",
+ "linux/keyboard.h",
+ "linux/keyctl.h",
+ "linux/kvm.h",
+ "linux/kvm_para.h",
+ "linux/l2tp.h",
+ "linux/libc-compat.h",
+ "linux/limits.h",
+ "linux/lirc.h",
+ "linux/llc.h",
+ "linux/loop.h",
+ "linux/lp.h",
+ "linux/lwtunnel.h",
+ "linux/magic.h",
+ "linux/major.h",
+ "linux/map_to_7segment.h",
+ "linux/matroxfb.h",
+ "linux/mdio.h",
+ "linux/mdss_rotator.h",
+ "linux/media-bus-format.h",
+ "linux/media.h",
+ "linux/mei.h",
+ "linux/membarrier.h",
+ "linux/memfd.h",
+ "linux/mempolicy.h",
+ "linux/meye.h",
+ "linux/mhi.h",
+ "linux/mic_common.h",
+ "linux/mic_ioctl.h",
+ "linux/mii.h",
+ "linux/minix_fs.h",
+ "linux/mman.h",
+ "linux/mmtimer.h",
+ "linux/mpls.h",
+ "linux/mpls_iptunnel.h",
+ "linux/mqueue.h",
+ "linux/mroute.h",
+ "linux/mroute6.h",
+ "linux/msdos_fs.h",
+ "linux/msg.h",
+ "linux/msm-core-interface.h",
+ "linux/msm_dsps.h",
+ "linux/msm_ion.h",
+ "linux/msm_ipa.h",
+ "linux/msm_ipc.h",
+ "linux/msm_kgsl.h",
+ "linux/msm_mdp.h",
+ "linux/msm_mdp_ext.h",
+ "linux/msm_rmnet.h",
+ "linux/msm_rotator.h",
+ "linux/msm_vidc_dec.h",
+ "linux/msm_vidc_enc.h",
+ "linux/mtio.h",
+ "linux/n_r3964.h",
+ "linux/nbd.h",
+ "linux/ncp.h",
+ "linux/ncp_fs.h",
+ "linux/ncp_mount.h",
+ "linux/ncp_no.h",
+ "linux/ndctl.h",
+ "linux/neighbour.h",
+ "linux/net.h",
+ "linux/net_dropmon.h",
+ "linux/net_map.h",
+ "linux/net_namespace.h",
+ "linux/net_tstamp.h",
+ "linux/netconf.h",
+ "linux/netdevice.h",
+ "linux/netfilter.h",
+ "linux/netfilter_arp.h",
+ "linux/netfilter_bridge.h",
+ "linux/netfilter_decnet.h",
+ "linux/netfilter_ipv4.h",
+ "linux/netfilter_ipv6.h",
+ "linux/netlink.h",
+ "linux/netlink_diag.h",
+ "linux/netrom.h",
+ "linux/nfc.h",
+ "linux/nfs.h",
+ "linux/nfs2.h",
+ "linux/nfs3.h",
+ "linux/nfs4.h",
+ "linux/nfs4_mount.h",
+ "linux/nfs_fs.h",
+ "linux/nfs_idmap.h",
+ "linux/nfs_mount.h",
+ "linux/nfsacl.h",
+ "linux/nl80211.h",
+ "linux/nubus.h",
+ "linux/nvme_ioctl.h",
+ "linux/nvram.h",
+ "linux/okl4-link-shbuf.h",
+ "linux/omap3isp.h",
+ "linux/omapfb.h",
+ "linux/oom.h",
+ "linux/openvswitch.h",
+ "linux/packet_diag.h",
+ "linux/param.h",
+ "linux/parport.h",
+ "linux/patchkey.h",
+ "linux/pci.h",
+ "linux/pci_regs.h",
+ "linux/perf_event.h",
+ "linux/personality.h",
+ "linux/pfkeyv2.h",
+ "linux/pg.h",
+ "linux/phantom.h",
+ "linux/phonet.h",
+ "linux/pkt_cls.h",
+ "linux/pkt_sched.h",
+ "linux/pktcdvd.h",
+ "linux/pmu.h",
+ "linux/poll.h",
+ "linux/posix_acl.h",
+ "linux/posix_acl_xattr.h",
+ "linux/posix_types.h",
+ "linux/ppdev.h",
+ "linux/ppp-comp.h",
+ "linux/ppp-ioctl.h",
+ "linux/ppp_defs.h",
+ "linux/pps.h",
+ "linux/prctl.h",
+ "linux/psci.h",
+ "linux/ptp_clock.h",
+ "linux/ptrace.h",
+ "linux/qbt1000.h",
+ "linux/qcedev.h",
+ "linux/qcota.h",
+ "linux/qg-profile.h",
+ "linux/qg.h",
+ "linux/qnx4_fs.h",
+ "linux/qnxtypes.h",
+ "linux/qrng.h",
+ "linux/qseecom.h",
+ "linux/quota.h",
+ "linux/radeonfb.h",
+ "linux/random.h",
+ "linux/raw.h",
+ "linux/rds.h",
+ "linux/reboot.h",
+ "linux/reiserfs_fs.h",
+ "linux/reiserfs_xattr.h",
+ "linux/resource.h",
+ "linux/rfkill.h",
+ "linux/rio_cm_cdev.h",
+ "linux/rio_mport_cdev.h",
+ "linux/rmnet_data.h",
+ "linux/rmnet_ipa_fd_ioctl.h",
+ "linux/romfs_fs.h",
+ "linux/rose.h",
+ "linux/route.h",
+ "linux/rtc.h",
+ "linux/rtnetlink.h",
+ "linux/scc.h",
+ "linux/sched.h",
+ "linux/scif_ioctl.h",
+ "linux/screen_info.h",
+ "linux/sctp.h",
+ "linux/sdla.h",
+ "linux/seccomp.h",
+ "linux/securebits.h",
+ "linux/seemp_api.h",
+ "linux/seemp_param_id.h",
+ "linux/selinux_netlink.h",
+ "linux/sem.h",
+ "linux/serial.h",
+ "linux/serial_core.h",
+ "linux/serial_reg.h",
+ "linux/serio.h",
+ "linux/shm.h",
+ "linux/signal.h",
+ "linux/signalfd.h",
+ "linux/smcinvoke.h",
+ "linux/smiapp.h",
+ "linux/snmp.h",
+ "linux/sock_diag.h",
+ "linux/socket.h",
+ "linux/sockev.h",
+ "linux/sockios.h",
+ "linux/sonet.h",
+ "linux/sonypi.h",
+ "linux/sound.h",
+ "linux/soundcard.h",
+ "linux/spcom.h",
+ "linux/stat.h",
+ "linux/stddef.h",
+ "linux/string.h",
+ "linux/suspend_ioctls.h",
+ "linux/swab.h",
+ "linux/sync_file.h",
+ "linux/synclink.h",
+ "linux/sysctl.h",
+ "linux/sysinfo.h",
+ "linux/target_core_user.h",
+ "linux/taskstats.h",
+ "linux/tcp.h",
+ "linux/tcp_metrics.h",
+ "linux/telephony.h",
+ "linux/termios.h",
+ "linux/thermal.h",
+ "linux/time.h",
+ "linux/times.h",
+ "linux/timex.h",
+ "linux/tiocl.h",
+ "linux/tipc.h",
+ "linux/tipc_config.h",
+ "linux/tipc_netlink.h",
+ "linux/toshiba.h",
+ "linux/tty.h",
+ "linux/tty_flags.h",
+ "linux/types.h",
+ "linux/udf_fs_i.h",
+ "linux/udp.h",
+ "linux/uhid.h",
+ "linux/uinput.h",
+ "linux/uio.h",
+ "linux/ultrasound.h",
+ "linux/un.h",
+ "linux/unistd.h",
+ "linux/unix_diag.h",
+ "linux/usbdevice_fs.h",
+ "linux/usbip.h",
+ "linux/userfaultfd.h",
+ "linux/utime.h",
+ "linux/utsname.h",
+ "linux/uuid.h",
+ "linux/uvcvideo.h",
+ "linux/v4l2-common.h",
+ "linux/v4l2-controls.h",
+ "linux/v4l2-dv-timings.h",
+ "linux/v4l2-mediabus.h",
+ "linux/v4l2-subdev.h",
+ "linux/veth.h",
+ "linux/vfio.h",
+ "linux/vhost.h",
+ "linux/videodev2.h",
+ "linux/virtio_9p.h",
+ "linux/virtio_balloon.h",
+ "linux/virtio_blk.h",
+ "linux/virtio_config.h",
+ "linux/virtio_console.h",
+ "linux/virtio_gpu.h",
+ "linux/virtio_ids.h",
+ "linux/virtio_input.h",
+ "linux/virtio_net.h",
+ "linux/virtio_pci.h",
+ "linux/virtio_ring.h",
+ "linux/virtio_rng.h",
+ "linux/virtio_scsi.h",
+ "linux/virtio_types.h",
+ "linux/virtio_vsock.h",
+ "linux/vm_bms.h",
+ "linux/vm_sockets.h",
+ "linux/vt.h",
+ "linux/vtpm_proxy.h",
+ "linux/wait.h",
+ "linux/wanrouter.h",
+ "linux/watchdog.h",
+ "linux/wimax.h",
+ "linux/wireless.h",
+ "linux/x25.h",
+ "linux/xattr.h",
+ "linux/xfrm.h",
+ "linux/xilinx-v4l2-controls.h",
+ "linux/zorro.h",
+ "linux/zorro_ids.h",
+ "media/cam_cpas.h",
+ "media/cam_defs.h",
+ "media/cam_fd.h",
+ "media/cam_icp.h",
+ "media/cam_isp.h",
+ "media/cam_isp_ife.h",
+ "media/cam_isp_vfe.h",
+ "media/cam_jpeg.h",
+ "media/cam_lrme.h",
+ "media/cam_req_mgr.h",
+ "media/cam_sensor.h",
+ "media/cam_sync.h",
+ "media/msm_cam_sensor.h",
+ "media/msm_camera.h",
+ "media/msm_camsensor_sdk.h",
+ "media/msm_fd.h",
+ "media/msm_isp.h",
+ "media/msm_jpeg.h",
+ "media/msm_jpeg_dma.h",
+ "media/msm_media_info.h",
+ "media/msm_sde_rotator.h",
+ "media/msm_vidc.h",
+ "media/msm_vidc_private.h",
+ "media/msmb_camera.h",
+ "media/msmb_generic_buf_mgr.h",
+ "media/msmb_isp.h",
+ "media/msmb_ispif.h",
+ "media/msmb_pproc.h",
+ "media/msmb_qca.h",
+ "media/radio-iris-commands.h",
+ "media/radio-iris.h",
+ "miniISP/miniISP_ioctl.h",
+ "misc/cxl.h",
+ "mtd/inftl-user.h",
+ "mtd/mtd-abi.h",
+ "mtd/mtd-user.h",
+ "mtd/nftl-user.h",
+ "mtd/ubi-user.h",
+ "rdma/cxgb3-abi.h",
+ "rdma/cxgb4-abi.h",
+ "rdma/ib_user_cm.h",
+ "rdma/ib_user_mad.h",
+ "rdma/ib_user_sa.h",
+ "rdma/ib_user_verbs.h",
+ "rdma/mlx4-abi.h",
+ "rdma/mlx5-abi.h",
+ "rdma/mthca-abi.h",
+ "rdma/nes-abi.h",
+ "rdma/ocrdma-abi.h",
+ "rdma/rdma_netlink.h",
+ "rdma/rdma_user_cm.h",
+ "rdma/rdma_user_rxe.h",
+ "scsi/cxlflash_ioctl.h",
+ "scsi/scsi_bsg_fc.h",
+ "scsi/scsi_ioctl.h",
+ "scsi/scsi_netlink.h",
+ "scsi/scsi_netlink_fc.h",
+ "scsi/sg.h",
+ "sound/asequencer.h",
+ "sound/asoc.h",
+ "sound/asound.h",
+ "sound/asound_fm.h",
+ "sound/compress_offload.h",
+ "sound/compress_params.h",
+ "sound/emu10k1.h",
+ "sound/firewire.h",
+ "sound/hdsp.h",
+ "sound/hdspm.h",
+ "sound/sb16_csp.h",
+ "sound/sfnt_info.h",
+ "sound/snd_sst_tokens.h",
+ "sound/tlv.h",
+ "sound/usb_stream.h",
+ "video/edid.h",
+ "video/msm_hdmi_hdcp_mgr.h",
+ "video/msm_hdmi_modes.h",
+ "video/sisfb.h",
+ "video/uvesafb.h",
+ "xen/evtchn.h",
+ "xen/gntalloc.h",
+ "xen/gntdev.h",
+ "xen/privcmd.h",
+ "linux/android/binder.h",
+ "linux/byteorder/big_endian.h",
+ "linux/byteorder/little_endian.h",
+ "linux/caif/caif_socket.h",
+ "linux/caif/if_caif.h",
+ "linux/can/bcm.h",
+ "linux/can/error.h",
+ "linux/can/gw.h",
+ "linux/can/netlink.h",
+ "linux/can/raw.h",
+ "linux/dvb/audio.h",
+ "linux/dvb/ca.h",
+ "linux/dvb/dmx.h",
+ "linux/dvb/frontend.h",
+ "linux/dvb/net.h",
+ "linux/dvb/osd.h",
+ "linux/dvb/version.h",
+ "linux/dvb/video.h",
+ "linux/hdlc/ioctl.h",
+ "linux/hsi/cs-protocol.h",
+ "linux/hsi/hsi_char.h",
+ "linux/iio/events.h",
+ "linux/iio/types.h",
+ "linux/isdn/capicmd.h",
+ "linux/mfd/msm-adie-codec.h",
+ "linux/mmc/core.h",
+ "linux/mmc/ioctl.h",
+ "linux/mmc/mmc.h",
+ "linux/netfilter/nf_conntrack_common.h",
+ "linux/netfilter/nf_conntrack_ftp.h",
+ "linux/netfilter/nf_conntrack_sctp.h",
+ "linux/netfilter/nf_conntrack_tcp.h",
+ "linux/netfilter/nf_conntrack_tuple_common.h",
+ "linux/netfilter/nf_log.h",
+ "linux/netfilter/nf_nat.h",
+ "linux/netfilter/nf_tables.h",
+ "linux/netfilter/nf_tables_compat.h",
+ "linux/netfilter/nfnetlink.h",
+ "linux/netfilter/nfnetlink_acct.h",
+ "linux/netfilter/nfnetlink_compat.h",
+ "linux/netfilter/nfnetlink_conntrack.h",
+ "linux/netfilter/nfnetlink_cthelper.h",
+ "linux/netfilter/nfnetlink_cttimeout.h",
+ "linux/netfilter/nfnetlink_log.h",
+ "linux/netfilter/nfnetlink_queue.h",
+ "linux/netfilter/x_tables.h",
+ "linux/netfilter/xt_AUDIT.h",
+ "linux/netfilter/xt_CHECKSUM.h",
+ "linux/netfilter/xt_CLASSIFY.h",
+ "linux/netfilter/xt_CONNMARK.h",
+ "linux/netfilter/xt_CONNSECMARK.h",
+ "linux/netfilter/xt_CT.h",
+ "linux/netfilter/xt_DSCP.h",
+ "linux/netfilter/xt_HMARK.h",
+ "linux/netfilter/xt_IDLETIMER.h",
+ "linux/netfilter/xt_LED.h",
+ "linux/netfilter/xt_LOG.h",
+ "linux/netfilter/xt_MARK.h",
+ "linux/netfilter/xt_NFLOG.h",
+ "linux/netfilter/xt_NFQUEUE.h",
+ "linux/netfilter/xt_RATEEST.h",
+ "linux/netfilter/xt_SECMARK.h",
+ "linux/netfilter/xt_SYNPROXY.h",
+ "linux/netfilter/xt_TCPMSS.h",
+ "linux/netfilter/xt_TCPOPTSTRIP.h",
+ "linux/netfilter/xt_TEE.h",
+ "linux/netfilter/xt_TPROXY.h",
+ "linux/netfilter/xt_addrtype.h",
+ "linux/netfilter/xt_bpf.h",
+ "linux/netfilter/xt_cgroup.h",
+ "linux/netfilter/xt_cluster.h",
+ "linux/netfilter/xt_comment.h",
+ "linux/netfilter/xt_connbytes.h",
+ "linux/netfilter/xt_connlabel.h",
+ "linux/netfilter/xt_connlimit.h",
+ "linux/netfilter/xt_connmark.h",
+ "linux/netfilter/xt_conntrack.h",
+ "linux/netfilter/xt_cpu.h",
+ "linux/netfilter/xt_dccp.h",
+ "linux/netfilter/xt_devgroup.h",
+ "linux/netfilter/xt_dscp.h",
+ "linux/netfilter/xt_ecn.h",
+ "linux/netfilter/xt_esp.h",
+ "linux/netfilter/xt_hashlimit.h",
+ "linux/netfilter/xt_helper.h",
+ "linux/netfilter/xt_ipcomp.h",
+ "linux/netfilter/xt_iprange.h",
+ "linux/netfilter/xt_ipvs.h",
+ "linux/netfilter/xt_l2tp.h",
+ "linux/netfilter/xt_length.h",
+ "linux/netfilter/xt_limit.h",
+ "linux/netfilter/xt_mac.h",
+ "linux/netfilter/xt_mark.h",
+ "linux/netfilter/xt_multiport.h",
+ "linux/netfilter/xt_nfacct.h",
+ "linux/netfilter/xt_osf.h",
+ "linux/netfilter/xt_owner.h",
+ "linux/netfilter/xt_physdev.h",
+ "linux/netfilter/xt_pkttype.h",
+ "linux/netfilter/xt_policy.h",
+ "linux/netfilter/xt_quota.h",
+ "linux/netfilter/xt_rateest.h",
+ "linux/netfilter/xt_realm.h",
+ "linux/netfilter/xt_recent.h",
+ "linux/netfilter/xt_rpfilter.h",
+ "linux/netfilter/xt_sctp.h",
+ "linux/netfilter/xt_set.h",
+ "linux/netfilter/xt_socket.h",
+ "linux/netfilter/xt_state.h",
+ "linux/netfilter/xt_statistic.h",
+ "linux/netfilter/xt_string.h",
+ "linux/netfilter/xt_tcpmss.h",
+ "linux/netfilter/xt_tcpudp.h",
+ "linux/netfilter/xt_time.h",
+ "linux/netfilter/xt_u32.h",
+ "linux/netfilter_arp/arp_tables.h",
+ "linux/netfilter_arp/arpt_mangle.h",
+ "linux/netfilter_bridge/ebt_802_3.h",
+ "linux/netfilter_bridge/ebt_among.h",
+ "linux/netfilter_bridge/ebt_arp.h",
+ "linux/netfilter_bridge/ebt_arpreply.h",
+ "linux/netfilter_bridge/ebt_ip.h",
+ "linux/netfilter_bridge/ebt_ip6.h",
+ "linux/netfilter_bridge/ebt_limit.h",
+ "linux/netfilter_bridge/ebt_log.h",
+ "linux/netfilter_bridge/ebt_mark_m.h",
+ "linux/netfilter_bridge/ebt_mark_t.h",
+ "linux/netfilter_bridge/ebt_nat.h",
+ "linux/netfilter_bridge/ebt_nflog.h",
+ "linux/netfilter_bridge/ebt_pkttype.h",
+ "linux/netfilter_bridge/ebt_redirect.h",
+ "linux/netfilter_bridge/ebt_stp.h",
+ "linux/netfilter_bridge/ebt_vlan.h",
+ "linux/netfilter_bridge/ebtables.h",
+ "linux/netfilter_ipv4/ip_tables.h",
+ "linux/netfilter_ipv4/ipt_CLUSTERIP.h",
+ "linux/netfilter_ipv4/ipt_ECN.h",
+ "linux/netfilter_ipv4/ipt_LOG.h",
+ "linux/netfilter_ipv4/ipt_NATTYPE.h",
+ "linux/netfilter_ipv4/ipt_REJECT.h",
+ "linux/netfilter_ipv4/ipt_TTL.h",
+ "linux/netfilter_ipv4/ipt_ah.h",
+ "linux/netfilter_ipv4/ipt_ecn.h",
+ "linux/netfilter_ipv4/ipt_ttl.h",
+ "linux/netfilter_ipv6/ip6_tables.h",
+ "linux/netfilter_ipv6/ip6t_HL.h",
+ "linux/netfilter_ipv6/ip6t_LOG.h",
+ "linux/netfilter_ipv6/ip6t_NPT.h",
+ "linux/netfilter_ipv6/ip6t_REJECT.h",
+ "linux/netfilter_ipv6/ip6t_ah.h",
+ "linux/netfilter_ipv6/ip6t_frag.h",
+ "linux/netfilter_ipv6/ip6t_hl.h",
+ "linux/netfilter_ipv6/ip6t_ipv6header.h",
+ "linux/netfilter_ipv6/ip6t_mh.h",
+ "linux/netfilter_ipv6/ip6t_opts.h",
+ "linux/netfilter_ipv6/ip6t_rt.h",
+ "linux/nfc/nfcinfo.h",
+ "linux/nfsd/cld.h",
+ "linux/nfsd/debug.h",
+ "linux/nfsd/export.h",
+ "linux/nfsd/nfsfh.h",
+ "linux/nfsd/stats.h",
+ "linux/raid/md_p.h",
+ "linux/raid/md_u.h",
+ "linux/spi/spidev.h",
+ "linux/sunrpc/debug.h",
+ "linux/tc_act/tc_bpf.h",
+ "linux/tc_act/tc_connmark.h",
+ "linux/tc_act/tc_csum.h",
+ "linux/tc_act/tc_defact.h",
+ "linux/tc_act/tc_gact.h",
+ "linux/tc_act/tc_ife.h",
+ "linux/tc_act/tc_ipt.h",
+ "linux/tc_act/tc_mirred.h",
+ "linux/tc_act/tc_nat.h",
+ "linux/tc_act/tc_pedit.h",
+ "linux/tc_act/tc_skbedit.h",
+ "linux/tc_act/tc_skbmod.h",
+ "linux/tc_act/tc_tunnel_key.h",
+ "linux/tc_act/tc_vlan.h",
+ "linux/tc_ematch/tc_em_cmp.h",
+ "linux/tc_ematch/tc_em_meta.h",
+ "linux/tc_ematch/tc_em_nbyte.h",
+ "linux/tc_ematch/tc_em_text.h",
+ "linux/usb/audio.h",
+ "linux/usb/cdc-wdm.h",
+ "linux/usb/cdc.h",
+ "linux/usb/ch11.h",
+ "linux/usb/ch9.h",
+ "linux/usb/functionfs.h",
+ "linux/usb/g_printer.h",
+ "linux/usb/gadgetfs.h",
+ "linux/usb/midi.h",
+ "linux/usb/tmc.h",
+ "linux/usb/usb_ctrl_qti.h",
+ "linux/usb/video.h",
+ "linux/wimax/i2400m.h",
+ "rdma/hfi/hfi1_user.h",
+ "scsi/fc/fc_els.h",
+ "scsi/fc/fc_fs.h",
+ "scsi/fc/fc_gs.h",
+ "scsi/fc/fc_ns.h",
+ "scsi/ufs/ioctl.h",
+ "scsi/ufs/ufs.h",
+ "linux/mfd/wcd9xxx/wcd9320_registers.h",
+ "linux/mfd/wcd9xxx/wcd9xxx_registers.h",
+ "linux/netfilter/ipset/ip_set.h",
+ "linux/netfilter/ipset/ip_set_bitmap.h",
+ "linux/netfilter/ipset/ip_set_hash.h",
+ "linux/netfilter/ipset/ip_set_list.h",
+
+ // From arch/arm/include/uapi/**/*.h
+
+ "asm/auxvec.h",
+ "asm/byteorder.h",
+ "asm/fcntl.h",
+ "asm/hwcap.h",
+ "asm/ioctls.h",
+ "asm/kvm.h",
+ "asm/kvm_para.h",
+ "asm/mman.h",
+ "asm/perf_regs.h",
+ "asm/posix_types.h",
+ "asm/ptrace.h",
+ "asm/setup.h",
+ "asm/sigcontext.h",
+ "asm/signal.h",
+ "asm/stat.h",
+ "asm/statfs.h",
+ "asm/swab.h",
+ "asm/types.h",
+ "asm/unistd.h",
+]
+
+genrule {
+ // This module generates the gen_headers_<arch>.bp file
+ // (i.e., a new version of this file) so that it can be
+ // checked later to ensure that it matches the checked-
+ // in version (this file).
+ name: "qti_generate_gen_headers_arm",
+ srcs: gen_headers_srcs_arm,
+ exclude_srcs: gen_headers_exclude_srcs_arm,
+ tool_files: ["kernel_headers.py"],
+ cmd: "python3 $(location kernel_headers.py) " +
+ kernel_headers_verbose +
+ "--header_arch arm " +
+ "--gen_dir $(genDir) " +
+ "--arch_asm_kbuild $(location arch/arm/include/uapi/asm/Kbuild) " +
+ "--arch_include_uapi $(locations arch/arm/include/uapi/**/*.h) " +
+ "--asm_generic_kbuild $(location include/uapi/asm-generic/Kbuild.asm) " +
+ "blueprints " +
+ "# $(in)",
+ out: ["gen_headers_arm.bp"],
+}
+
+genrule {
+ name: "qti_generate_kernel_headers_arm",
+ tools: ["headers_install.sh"],
+ tool_files: [
+ "kernel_headers.py",
+ "arch/arm/tools/syscallhdr.sh",
+ ],
+ srcs: gen_headers_srcs_arm +[
+ "gen_headers_arm.bp",
+ ":qti_generate_gen_headers_arm",
+ ],
+ exclude_srcs: gen_headers_exclude_srcs_arm,
+ cmd: "python3 $(location kernel_headers.py) " +
+ kernel_headers_verbose +
+ "--header_arch arm " +
+ "--gen_dir $(genDir) " +
+ "--arch_asm_kbuild $(location arch/arm/include/uapi/asm/Kbuild) " +
+ "--arch_include_uapi $(locations arch/arm/include/uapi/**/*.h) " +
+ "--asm_generic_kbuild $(location include/uapi/asm-generic/Kbuild.asm) " +
+ "headers " +
+ "--old_gen_headers_bp $(location gen_headers_arm.bp) " +
+ "--new_gen_headers_bp $(location :qti_generate_gen_headers_arm) " +
+ "--version_makefile $(location Makefile) " +
+ "--arch_syscall_tool $(location arch/arm/tools/syscallhdr.sh) " +
+ "--arch_syscall_tbl $(location arch/arm/tools/syscall.tbl) " +
+ "--headers_install $(location headers_install.sh) " +
+ "--include_uapi $(locations include/uapi/**/*.h)",
+ out: ["linux/version.h"] + gen_headers_out_arm,
+}
diff --git a/gen_headers_arm64.bp b/gen_headers_arm64.bp
new file mode 100644
index 0000000..5060c14
--- /dev/null
+++ b/gen_headers_arm64.bp
@@ -0,0 +1,970 @@
+// ***** DO NOT EDIT *****
+// This file is generated by kernel_headers.py
+
+gen_headers_srcs_arm64 = [
+ "arch/arm64/include/uapi/asm/Kbuild",
+ "include/uapi/asm-generic/Kbuild.asm",
+ "Makefile",
+ "include/uapi/**/*.h",
+ "arch/arm64/include/uapi/**/*.h",
+]
+
+gen_headers_exclude_srcs_arm64 = [
+ "include/uapi/linux/a.out.h",
+ "include/uapi/linux/kvm_para.h",
+ "include/uapi/drm/armada_drm.h",
+ "include/uapi/drm/etnaviv_drm.h",
+ "include/uapi/drm/omap_drm.h",
+ "include/uapi/drm/vgem_drm.h",
+ "include/uapi/linux/auto_dev-ioctl.h",
+ "include/uapi/linux/batman_adv.h",
+ "include/uapi/linux/bcache.h",
+ "include/uapi/linux/btrfs_tree.h",
+ "include/uapi/linux/cryptouser.h",
+ "include/uapi/linux/dma-buf.h",
+ "include/uapi/linux/hash_info.h",
+ "include/uapi/linux/kcm.h",
+ "include/uapi/linux/kcov.h",
+ "include/uapi/linux/kfd_ioctl.h",
+ "include/uapi/linux/lightnvm.h",
+ "include/uapi/linux/module.h",
+ "include/uapi/linux/nilfs2_api.h",
+ "include/uapi/linux/nilfs2_ondisk.h",
+ "include/uapi/linux/nsfs.h",
+ "include/uapi/linux/pr.h",
+ "include/uapi/linux/qrtr.h",
+ "include/uapi/linux/stm.h",
+ "include/uapi/linux/tee.h",
+ "include/uapi/linux/userio.h",
+ "include/uapi/linux/wil6210_uapi.h",
+ "include/uapi/rdma/qedr-abi.h",
+ "include/uapi/video/adf.h",
+ "include/uapi/linux/cifs/cifs_mount.h",
+ "include/uapi/linux/genwqe/genwqe_card.h",
+ "include/uapi/linux/netfilter/xt_HARDIDLETIMER.h",
+ "include/uapi/linux/usb/f_accessory.h",
+ "include/uapi/linux/usb/f_mtp.h",
+]
+
+gen_headers_out_arm64 = [
+
+ // Matching generic-y:
+
+ "asm/kvm_para.h",
+
+ // Matching mandatory-y:
+
+ "asm/errno.h",
+ "asm/ioctl.h",
+ "asm/ioctls.h",
+ "asm/ipcbuf.h",
+ "asm/mman.h",
+ "asm/msgbuf.h",
+ "asm/poll.h",
+ "asm/resource.h",
+ "asm/sembuf.h",
+ "asm/shmbuf.h",
+ "asm/socket.h",
+ "asm/sockios.h",
+ "asm/swab.h",
+ "asm/termbits.h",
+ "asm/termios.h",
+ "asm/types.h",
+
+ // From include/uapi/**/*.h
+
+ "asm-generic/auxvec.h",
+ "asm-generic/bitsperlong.h",
+ "asm-generic/errno-base.h",
+ "asm-generic/errno.h",
+ "asm-generic/fcntl.h",
+ "asm-generic/int-l64.h",
+ "asm-generic/int-ll64.h",
+ "asm-generic/ioctl.h",
+ "asm-generic/ioctls.h",
+ "asm-generic/ipcbuf.h",
+ "asm-generic/kvm_para.h",
+ "asm-generic/mman-common.h",
+ "asm-generic/mman.h",
+ "asm-generic/msgbuf.h",
+ "asm-generic/param.h",
+ "asm-generic/poll.h",
+ "asm-generic/posix_types.h",
+ "asm-generic/resource.h",
+ "asm-generic/sembuf.h",
+ "asm-generic/setup.h",
+ "asm-generic/shmbuf.h",
+ "asm-generic/shmparam.h",
+ "asm-generic/siginfo.h",
+ "asm-generic/signal-defs.h",
+ "asm-generic/signal.h",
+ "asm-generic/socket.h",
+ "asm-generic/sockios.h",
+ "asm-generic/stat.h",
+ "asm-generic/statfs.h",
+ "asm-generic/swab.h",
+ "asm-generic/termbits.h",
+ "asm-generic/termios.h",
+ "asm-generic/types.h",
+ "asm-generic/ucontext.h",
+ "asm-generic/unistd.h",
+ "drm/amdgpu_drm.h",
+ "drm/drm.h",
+ "drm/drm_fourcc.h",
+ "drm/drm_mode.h",
+ "drm/drm_sarea.h",
+ "drm/exynos_drm.h",
+ "drm/i810_drm.h",
+ "drm/i915_drm.h",
+ "drm/mga_drm.h",
+ "drm/msm_drm.h",
+ "drm/msm_drm_pp.h",
+ "drm/nouveau_drm.h",
+ "drm/qxl_drm.h",
+ "drm/r128_drm.h",
+ "drm/radeon_drm.h",
+ "drm/savage_drm.h",
+ "drm/sde_drm.h",
+ "drm/sis_drm.h",
+ "drm/tegra_drm.h",
+ "drm/vc4_drm.h",
+ "drm/via_drm.h",
+ "drm/virtgpu_drm.h",
+ "drm/vmwgfx_drm.h",
+ "linux/acct.h",
+ "linux/adb.h",
+ "linux/adfs_fs.h",
+ "linux/affs_hardblocks.h",
+ "linux/agpgart.h",
+ "linux/aio_abi.h",
+ "linux/am437x-vpfe.h",
+ "linux/apm_bios.h",
+ "linux/arcfb.h",
+ "linux/atalk.h",
+ "linux/atm.h",
+ "linux/atm_eni.h",
+ "linux/atm_he.h",
+ "linux/atm_idt77105.h",
+ "linux/atm_nicstar.h",
+ "linux/atm_tcp.h",
+ "linux/atm_zatm.h",
+ "linux/atmapi.h",
+ "linux/atmarp.h",
+ "linux/atmbr2684.h",
+ "linux/atmclip.h",
+ "linux/atmdev.h",
+ "linux/atmioc.h",
+ "linux/atmlec.h",
+ "linux/atmmpc.h",
+ "linux/atmppp.h",
+ "linux/atmsap.h",
+ "linux/atmsvc.h",
+ "linux/audit.h",
+ "linux/auto_fs.h",
+ "linux/auto_fs4.h",
+ "linux/auxvec.h",
+ "linux/ax25.h",
+ "linux/b1lli.h",
+ "linux/batterydata-interface.h",
+ "linux/baycom.h",
+ "linux/bcm933xx_hcs.h",
+ "linux/bfs_fs.h",
+ "linux/bgcom_interface.h",
+ "linux/binfmts.h",
+ "linux/blkpg.h",
+ "linux/blktrace_api.h",
+ "linux/bpf.h",
+ "linux/bpf_common.h",
+ "linux/bpf_perf_event.h",
+ "linux/bpqether.h",
+ "linux/bsg.h",
+ "linux/bt-bmc.h",
+ "linux/btrfs.h",
+ "linux/can.h",
+ "linux/capability.h",
+ "linux/capi.h",
+ "linux/cciss_defs.h",
+ "linux/cciss_ioctl.h",
+ "linux/cdrom.h",
+ "linux/cgroupstats.h",
+ "linux/chio.h",
+ "linux/cm4000_cs.h",
+ "linux/cn_proc.h",
+ "linux/coda.h",
+ "linux/coda_psdev.h",
+ "linux/coff.h",
+ "linux/connector.h",
+ "linux/const.h",
+ "linux/coresight-stm.h",
+ "linux/cramfs_fs.h",
+ "linux/cuda.h",
+ "linux/cyclades.h",
+ "linux/cycx_cfm.h",
+ "linux/dcbnl.h",
+ "linux/dccp.h",
+ "linux/devlink.h",
+ "linux/dlm.h",
+ "linux/dlm_device.h",
+ "linux/dlm_netlink.h",
+ "linux/dlm_plock.h",
+ "linux/dlmconstants.h",
+ "linux/dm-ioctl.h",
+ "linux/dm-log-userspace.h",
+ "linux/dn.h",
+ "linux/dqblk_xfs.h",
+ "linux/edd.h",
+ "linux/efs_fs_sb.h",
+ "linux/elf-em.h",
+ "linux/elf-fdpic.h",
+ "linux/elf.h",
+ "linux/elfcore.h",
+ "linux/errno.h",
+ "linux/errqueue.h",
+ "linux/esoc_ctrl.h",
+ "linux/ethtool.h",
+ "linux/eventpoll.h",
+ "linux/fadvise.h",
+ "linux/falloc.h",
+ "linux/fanotify.h",
+ "linux/fb.h",
+ "linux/fcntl.h",
+ "linux/fd.h",
+ "linux/fdreg.h",
+ "linux/fib_rules.h",
+ "linux/fiemap.h",
+ "linux/filter.h",
+ "linux/fips_status.h",
+ "linux/firewire-cdev.h",
+ "linux/firewire-constants.h",
+ "linux/flat.h",
+ "linux/fou.h",
+ "linux/fs.h",
+ "linux/fsl_hypervisor.h",
+ "linux/fuse.h",
+ "linux/futex.h",
+ "linux/gameport.h",
+ "linux/gen_stats.h",
+ "linux/genetlink.h",
+ "linux/gfs2_ondisk.h",
+ "linux/gigaset_dev.h",
+ "linux/gpio.h",
+ "linux/gsmmux.h",
+ "linux/gtp.h",
+ "linux/hbtp_input.h",
+ "linux/hdlc.h",
+ "linux/hdlcdrv.h",
+ "linux/hdreg.h",
+ "linux/hid.h",
+ "linux/hiddev.h",
+ "linux/hidraw.h",
+ "linux/hpet.h",
+ "linux/hsr_netlink.h",
+ "linux/hw_breakpoint.h",
+ "linux/hyperv.h",
+ "linux/hysdn_if.h",
+ "linux/i2c-dev.h",
+ "linux/i2c.h",
+ "linux/i2o-dev.h",
+ "linux/i8k.h",
+ "linux/icmp.h",
+ "linux/icmpv6.h",
+ "linux/if.h",
+ "linux/if_addr.h",
+ "linux/if_addrlabel.h",
+ "linux/if_alg.h",
+ "linux/if_arcnet.h",
+ "linux/if_arp.h",
+ "linux/if_bonding.h",
+ "linux/if_bridge.h",
+ "linux/if_cablemodem.h",
+ "linux/if_eql.h",
+ "linux/if_ether.h",
+ "linux/if_fc.h",
+ "linux/if_fddi.h",
+ "linux/if_frad.h",
+ "linux/if_hippi.h",
+ "linux/if_infiniband.h",
+ "linux/if_link.h",
+ "linux/if_ltalk.h",
+ "linux/if_macsec.h",
+ "linux/if_packet.h",
+ "linux/if_phonet.h",
+ "linux/if_plip.h",
+ "linux/if_ppp.h",
+ "linux/if_pppol2tp.h",
+ "linux/if_pppolac.h",
+ "linux/if_pppopns.h",
+ "linux/if_pppox.h",
+ "linux/if_slip.h",
+ "linux/if_team.h",
+ "linux/if_tun.h",
+ "linux/if_tunnel.h",
+ "linux/if_vlan.h",
+ "linux/if_x25.h",
+ "linux/igmp.h",
+ "linux/ila.h",
+ "linux/in.h",
+ "linux/in6.h",
+ "linux/in_route.h",
+ "linux/inet_diag.h",
+ "linux/inotify.h",
+ "linux/input-event-codes.h",
+ "linux/input.h",
+ "linux/ioctl.h",
+ "linux/ion.h",
+ "linux/ip.h",
+ "linux/ip6_tunnel.h",
+ "linux/ip_vs.h",
+ "linux/ipa_qmi_service_v01.h",
+ "linux/ipc.h",
+ "linux/ipmi.h",
+ "linux/ipmi_msgdefs.h",
+ "linux/ipsec.h",
+ "linux/ipv6.h",
+ "linux/ipv6_route.h",
+ "linux/ipx.h",
+ "linux/irda.h",
+ "linux/irqnr.h",
+ "linux/isdn.h",
+ "linux/isdn_divertif.h",
+ "linux/isdn_ppp.h",
+ "linux/isdnif.h",
+ "linux/iso_fs.h",
+ "linux/ivtv.h",
+ "linux/ivtvfb.h",
+ "linux/ixjuser.h",
+ "linux/jffs2.h",
+ "linux/joystick.h",
+ "linux/kcmp.h",
+ "linux/kd.h",
+ "linux/kdev_t.h",
+ "linux/kernel-page-flags.h",
+ "linux/kernel.h",
+ "linux/kernelcapi.h",
+ "linux/kexec.h",
+ "linux/keyboard.h",
+ "linux/keyctl.h",
+ "linux/kvm.h",
+ "linux/l2tp.h",
+ "linux/libc-compat.h",
+ "linux/limits.h",
+ "linux/lirc.h",
+ "linux/llc.h",
+ "linux/loop.h",
+ "linux/lp.h",
+ "linux/lwtunnel.h",
+ "linux/magic.h",
+ "linux/major.h",
+ "linux/map_to_7segment.h",
+ "linux/matroxfb.h",
+ "linux/mdio.h",
+ "linux/mdss_rotator.h",
+ "linux/media-bus-format.h",
+ "linux/media.h",
+ "linux/mei.h",
+ "linux/membarrier.h",
+ "linux/memfd.h",
+ "linux/mempolicy.h",
+ "linux/meye.h",
+ "linux/mhi.h",
+ "linux/mic_common.h",
+ "linux/mic_ioctl.h",
+ "linux/mii.h",
+ "linux/minix_fs.h",
+ "linux/mman.h",
+ "linux/mmtimer.h",
+ "linux/mpls.h",
+ "linux/mpls_iptunnel.h",
+ "linux/mqueue.h",
+ "linux/mroute.h",
+ "linux/mroute6.h",
+ "linux/msdos_fs.h",
+ "linux/msg.h",
+ "linux/msm-core-interface.h",
+ "linux/msm_dsps.h",
+ "linux/msm_ion.h",
+ "linux/msm_ipa.h",
+ "linux/msm_ipc.h",
+ "linux/msm_kgsl.h",
+ "linux/msm_mdp.h",
+ "linux/msm_mdp_ext.h",
+ "linux/msm_rmnet.h",
+ "linux/msm_rotator.h",
+ "linux/msm_vidc_dec.h",
+ "linux/msm_vidc_enc.h",
+ "linux/mtio.h",
+ "linux/n_r3964.h",
+ "linux/nbd.h",
+ "linux/ncp.h",
+ "linux/ncp_fs.h",
+ "linux/ncp_mount.h",
+ "linux/ncp_no.h",
+ "linux/ndctl.h",
+ "linux/neighbour.h",
+ "linux/net.h",
+ "linux/net_dropmon.h",
+ "linux/net_map.h",
+ "linux/net_namespace.h",
+ "linux/net_tstamp.h",
+ "linux/netconf.h",
+ "linux/netdevice.h",
+ "linux/netfilter.h",
+ "linux/netfilter_arp.h",
+ "linux/netfilter_bridge.h",
+ "linux/netfilter_decnet.h",
+ "linux/netfilter_ipv4.h",
+ "linux/netfilter_ipv6.h",
+ "linux/netlink.h",
+ "linux/netlink_diag.h",
+ "linux/netrom.h",
+ "linux/nfc.h",
+ "linux/nfs.h",
+ "linux/nfs2.h",
+ "linux/nfs3.h",
+ "linux/nfs4.h",
+ "linux/nfs4_mount.h",
+ "linux/nfs_fs.h",
+ "linux/nfs_idmap.h",
+ "linux/nfs_mount.h",
+ "linux/nfsacl.h",
+ "linux/nl80211.h",
+ "linux/nubus.h",
+ "linux/nvme_ioctl.h",
+ "linux/nvram.h",
+ "linux/okl4-link-shbuf.h",
+ "linux/omap3isp.h",
+ "linux/omapfb.h",
+ "linux/oom.h",
+ "linux/openvswitch.h",
+ "linux/packet_diag.h",
+ "linux/param.h",
+ "linux/parport.h",
+ "linux/patchkey.h",
+ "linux/pci.h",
+ "linux/pci_regs.h",
+ "linux/perf_event.h",
+ "linux/personality.h",
+ "linux/pfkeyv2.h",
+ "linux/pg.h",
+ "linux/phantom.h",
+ "linux/phonet.h",
+ "linux/pkt_cls.h",
+ "linux/pkt_sched.h",
+ "linux/pktcdvd.h",
+ "linux/pmu.h",
+ "linux/poll.h",
+ "linux/posix_acl.h",
+ "linux/posix_acl_xattr.h",
+ "linux/posix_types.h",
+ "linux/ppdev.h",
+ "linux/ppp-comp.h",
+ "linux/ppp-ioctl.h",
+ "linux/ppp_defs.h",
+ "linux/pps.h",
+ "linux/prctl.h",
+ "linux/psci.h",
+ "linux/ptp_clock.h",
+ "linux/ptrace.h",
+ "linux/qbt1000.h",
+ "linux/qcedev.h",
+ "linux/qcota.h",
+ "linux/qg-profile.h",
+ "linux/qg.h",
+ "linux/qnx4_fs.h",
+ "linux/qnxtypes.h",
+ "linux/qrng.h",
+ "linux/qseecom.h",
+ "linux/quota.h",
+ "linux/radeonfb.h",
+ "linux/random.h",
+ "linux/raw.h",
+ "linux/rds.h",
+ "linux/reboot.h",
+ "linux/reiserfs_fs.h",
+ "linux/reiserfs_xattr.h",
+ "linux/resource.h",
+ "linux/rfkill.h",
+ "linux/rio_cm_cdev.h",
+ "linux/rio_mport_cdev.h",
+ "linux/rmnet_data.h",
+ "linux/rmnet_ipa_fd_ioctl.h",
+ "linux/romfs_fs.h",
+ "linux/rose.h",
+ "linux/route.h",
+ "linux/rtc.h",
+ "linux/rtnetlink.h",
+ "linux/scc.h",
+ "linux/sched.h",
+ "linux/scif_ioctl.h",
+ "linux/screen_info.h",
+ "linux/sctp.h",
+ "linux/sdla.h",
+ "linux/seccomp.h",
+ "linux/securebits.h",
+ "linux/seemp_api.h",
+ "linux/seemp_param_id.h",
+ "linux/selinux_netlink.h",
+ "linux/sem.h",
+ "linux/serial.h",
+ "linux/serial_core.h",
+ "linux/serial_reg.h",
+ "linux/serio.h",
+ "linux/shm.h",
+ "linux/signal.h",
+ "linux/signalfd.h",
+ "linux/smcinvoke.h",
+ "linux/smiapp.h",
+ "linux/snmp.h",
+ "linux/sock_diag.h",
+ "linux/socket.h",
+ "linux/sockev.h",
+ "linux/sockios.h",
+ "linux/sonet.h",
+ "linux/sonypi.h",
+ "linux/sound.h",
+ "linux/soundcard.h",
+ "linux/spcom.h",
+ "linux/stat.h",
+ "linux/stddef.h",
+ "linux/string.h",
+ "linux/suspend_ioctls.h",
+ "linux/swab.h",
+ "linux/sync_file.h",
+ "linux/synclink.h",
+ "linux/sysctl.h",
+ "linux/sysinfo.h",
+ "linux/target_core_user.h",
+ "linux/taskstats.h",
+ "linux/tcp.h",
+ "linux/tcp_metrics.h",
+ "linux/telephony.h",
+ "linux/termios.h",
+ "linux/thermal.h",
+ "linux/time.h",
+ "linux/times.h",
+ "linux/timex.h",
+ "linux/tiocl.h",
+ "linux/tipc.h",
+ "linux/tipc_config.h",
+ "linux/tipc_netlink.h",
+ "linux/toshiba.h",
+ "linux/tty.h",
+ "linux/tty_flags.h",
+ "linux/types.h",
+ "linux/udf_fs_i.h",
+ "linux/udp.h",
+ "linux/uhid.h",
+ "linux/uinput.h",
+ "linux/uio.h",
+ "linux/ultrasound.h",
+ "linux/un.h",
+ "linux/unistd.h",
+ "linux/unix_diag.h",
+ "linux/usbdevice_fs.h",
+ "linux/usbip.h",
+ "linux/userfaultfd.h",
+ "linux/utime.h",
+ "linux/utsname.h",
+ "linux/uuid.h",
+ "linux/uvcvideo.h",
+ "linux/v4l2-common.h",
+ "linux/v4l2-controls.h",
+ "linux/v4l2-dv-timings.h",
+ "linux/v4l2-mediabus.h",
+ "linux/v4l2-subdev.h",
+ "linux/veth.h",
+ "linux/vfio.h",
+ "linux/vhost.h",
+ "linux/videodev2.h",
+ "linux/virtio_9p.h",
+ "linux/virtio_balloon.h",
+ "linux/virtio_blk.h",
+ "linux/virtio_config.h",
+ "linux/virtio_console.h",
+ "linux/virtio_gpu.h",
+ "linux/virtio_ids.h",
+ "linux/virtio_input.h",
+ "linux/virtio_net.h",
+ "linux/virtio_pci.h",
+ "linux/virtio_ring.h",
+ "linux/virtio_rng.h",
+ "linux/virtio_scsi.h",
+ "linux/virtio_types.h",
+ "linux/virtio_vsock.h",
+ "linux/vm_bms.h",
+ "linux/vm_sockets.h",
+ "linux/vt.h",
+ "linux/vtpm_proxy.h",
+ "linux/wait.h",
+ "linux/wanrouter.h",
+ "linux/watchdog.h",
+ "linux/wimax.h",
+ "linux/wireless.h",
+ "linux/x25.h",
+ "linux/xattr.h",
+ "linux/xfrm.h",
+ "linux/xilinx-v4l2-controls.h",
+ "linux/zorro.h",
+ "linux/zorro_ids.h",
+ "media/cam_cpas.h",
+ "media/cam_defs.h",
+ "media/cam_fd.h",
+ "media/cam_icp.h",
+ "media/cam_isp.h",
+ "media/cam_isp_ife.h",
+ "media/cam_isp_vfe.h",
+ "media/cam_jpeg.h",
+ "media/cam_lrme.h",
+ "media/cam_req_mgr.h",
+ "media/cam_sensor.h",
+ "media/cam_sync.h",
+ "media/msm_cam_sensor.h",
+ "media/msm_camera.h",
+ "media/msm_camsensor_sdk.h",
+ "media/msm_fd.h",
+ "media/msm_isp.h",
+ "media/msm_jpeg.h",
+ "media/msm_jpeg_dma.h",
+ "media/msm_media_info.h",
+ "media/msm_sde_rotator.h",
+ "media/msm_vidc.h",
+ "media/msm_vidc_private.h",
+ "media/msmb_camera.h",
+ "media/msmb_generic_buf_mgr.h",
+ "media/msmb_isp.h",
+ "media/msmb_ispif.h",
+ "media/msmb_pproc.h",
+ "media/msmb_qca.h",
+ "media/radio-iris-commands.h",
+ "media/radio-iris.h",
+ "miniISP/miniISP_ioctl.h",
+ "misc/cxl.h",
+ "mtd/inftl-user.h",
+ "mtd/mtd-abi.h",
+ "mtd/mtd-user.h",
+ "mtd/nftl-user.h",
+ "mtd/ubi-user.h",
+ "rdma/cxgb3-abi.h",
+ "rdma/cxgb4-abi.h",
+ "rdma/ib_user_cm.h",
+ "rdma/ib_user_mad.h",
+ "rdma/ib_user_sa.h",
+ "rdma/ib_user_verbs.h",
+ "rdma/mlx4-abi.h",
+ "rdma/mlx5-abi.h",
+ "rdma/mthca-abi.h",
+ "rdma/nes-abi.h",
+ "rdma/ocrdma-abi.h",
+ "rdma/rdma_netlink.h",
+ "rdma/rdma_user_cm.h",
+ "rdma/rdma_user_rxe.h",
+ "scsi/cxlflash_ioctl.h",
+ "scsi/scsi_bsg_fc.h",
+ "scsi/scsi_ioctl.h",
+ "scsi/scsi_netlink.h",
+ "scsi/scsi_netlink_fc.h",
+ "scsi/sg.h",
+ "sound/asequencer.h",
+ "sound/asoc.h",
+ "sound/asound.h",
+ "sound/asound_fm.h",
+ "sound/compress_offload.h",
+ "sound/compress_params.h",
+ "sound/emu10k1.h",
+ "sound/firewire.h",
+ "sound/hdsp.h",
+ "sound/hdspm.h",
+ "sound/sb16_csp.h",
+ "sound/sfnt_info.h",
+ "sound/snd_sst_tokens.h",
+ "sound/tlv.h",
+ "sound/usb_stream.h",
+ "video/edid.h",
+ "video/msm_hdmi_hdcp_mgr.h",
+ "video/msm_hdmi_modes.h",
+ "video/sisfb.h",
+ "video/uvesafb.h",
+ "xen/evtchn.h",
+ "xen/gntalloc.h",
+ "xen/gntdev.h",
+ "xen/privcmd.h",
+ "linux/android/binder.h",
+ "linux/byteorder/big_endian.h",
+ "linux/byteorder/little_endian.h",
+ "linux/caif/caif_socket.h",
+ "linux/caif/if_caif.h",
+ "linux/can/bcm.h",
+ "linux/can/error.h",
+ "linux/can/gw.h",
+ "linux/can/netlink.h",
+ "linux/can/raw.h",
+ "linux/dvb/audio.h",
+ "linux/dvb/ca.h",
+ "linux/dvb/dmx.h",
+ "linux/dvb/frontend.h",
+ "linux/dvb/net.h",
+ "linux/dvb/osd.h",
+ "linux/dvb/version.h",
+ "linux/dvb/video.h",
+ "linux/hdlc/ioctl.h",
+ "linux/hsi/cs-protocol.h",
+ "linux/hsi/hsi_char.h",
+ "linux/iio/events.h",
+ "linux/iio/types.h",
+ "linux/isdn/capicmd.h",
+ "linux/mfd/msm-adie-codec.h",
+ "linux/mmc/core.h",
+ "linux/mmc/ioctl.h",
+ "linux/mmc/mmc.h",
+ "linux/netfilter/nf_conntrack_common.h",
+ "linux/netfilter/nf_conntrack_ftp.h",
+ "linux/netfilter/nf_conntrack_sctp.h",
+ "linux/netfilter/nf_conntrack_tcp.h",
+ "linux/netfilter/nf_conntrack_tuple_common.h",
+ "linux/netfilter/nf_log.h",
+ "linux/netfilter/nf_nat.h",
+ "linux/netfilter/nf_tables.h",
+ "linux/netfilter/nf_tables_compat.h",
+ "linux/netfilter/nfnetlink.h",
+ "linux/netfilter/nfnetlink_acct.h",
+ "linux/netfilter/nfnetlink_compat.h",
+ "linux/netfilter/nfnetlink_conntrack.h",
+ "linux/netfilter/nfnetlink_cthelper.h",
+ "linux/netfilter/nfnetlink_cttimeout.h",
+ "linux/netfilter/nfnetlink_log.h",
+ "linux/netfilter/nfnetlink_queue.h",
+ "linux/netfilter/x_tables.h",
+ "linux/netfilter/xt_AUDIT.h",
+ "linux/netfilter/xt_CHECKSUM.h",
+ "linux/netfilter/xt_CLASSIFY.h",
+ "linux/netfilter/xt_CONNMARK.h",
+ "linux/netfilter/xt_CONNSECMARK.h",
+ "linux/netfilter/xt_CT.h",
+ "linux/netfilter/xt_DSCP.h",
+ "linux/netfilter/xt_HMARK.h",
+ "linux/netfilter/xt_IDLETIMER.h",
+ "linux/netfilter/xt_LED.h",
+ "linux/netfilter/xt_LOG.h",
+ "linux/netfilter/xt_MARK.h",
+ "linux/netfilter/xt_NFLOG.h",
+ "linux/netfilter/xt_NFQUEUE.h",
+ "linux/netfilter/xt_RATEEST.h",
+ "linux/netfilter/xt_SECMARK.h",
+ "linux/netfilter/xt_SYNPROXY.h",
+ "linux/netfilter/xt_TCPMSS.h",
+ "linux/netfilter/xt_TCPOPTSTRIP.h",
+ "linux/netfilter/xt_TEE.h",
+ "linux/netfilter/xt_TPROXY.h",
+ "linux/netfilter/xt_addrtype.h",
+ "linux/netfilter/xt_bpf.h",
+ "linux/netfilter/xt_cgroup.h",
+ "linux/netfilter/xt_cluster.h",
+ "linux/netfilter/xt_comment.h",
+ "linux/netfilter/xt_connbytes.h",
+ "linux/netfilter/xt_connlabel.h",
+ "linux/netfilter/xt_connlimit.h",
+ "linux/netfilter/xt_connmark.h",
+ "linux/netfilter/xt_conntrack.h",
+ "linux/netfilter/xt_cpu.h",
+ "linux/netfilter/xt_dccp.h",
+ "linux/netfilter/xt_devgroup.h",
+ "linux/netfilter/xt_dscp.h",
+ "linux/netfilter/xt_ecn.h",
+ "linux/netfilter/xt_esp.h",
+ "linux/netfilter/xt_hashlimit.h",
+ "linux/netfilter/xt_helper.h",
+ "linux/netfilter/xt_ipcomp.h",
+ "linux/netfilter/xt_iprange.h",
+ "linux/netfilter/xt_ipvs.h",
+ "linux/netfilter/xt_l2tp.h",
+ "linux/netfilter/xt_length.h",
+ "linux/netfilter/xt_limit.h",
+ "linux/netfilter/xt_mac.h",
+ "linux/netfilter/xt_mark.h",
+ "linux/netfilter/xt_multiport.h",
+ "linux/netfilter/xt_nfacct.h",
+ "linux/netfilter/xt_osf.h",
+ "linux/netfilter/xt_owner.h",
+ "linux/netfilter/xt_physdev.h",
+ "linux/netfilter/xt_pkttype.h",
+ "linux/netfilter/xt_policy.h",
+ "linux/netfilter/xt_quota.h",
+ "linux/netfilter/xt_rateest.h",
+ "linux/netfilter/xt_realm.h",
+ "linux/netfilter/xt_recent.h",
+ "linux/netfilter/xt_rpfilter.h",
+ "linux/netfilter/xt_sctp.h",
+ "linux/netfilter/xt_set.h",
+ "linux/netfilter/xt_socket.h",
+ "linux/netfilter/xt_state.h",
+ "linux/netfilter/xt_statistic.h",
+ "linux/netfilter/xt_string.h",
+ "linux/netfilter/xt_tcpmss.h",
+ "linux/netfilter/xt_tcpudp.h",
+ "linux/netfilter/xt_time.h",
+ "linux/netfilter/xt_u32.h",
+ "linux/netfilter_arp/arp_tables.h",
+ "linux/netfilter_arp/arpt_mangle.h",
+ "linux/netfilter_bridge/ebt_802_3.h",
+ "linux/netfilter_bridge/ebt_among.h",
+ "linux/netfilter_bridge/ebt_arp.h",
+ "linux/netfilter_bridge/ebt_arpreply.h",
+ "linux/netfilter_bridge/ebt_ip.h",
+ "linux/netfilter_bridge/ebt_ip6.h",
+ "linux/netfilter_bridge/ebt_limit.h",
+ "linux/netfilter_bridge/ebt_log.h",
+ "linux/netfilter_bridge/ebt_mark_m.h",
+ "linux/netfilter_bridge/ebt_mark_t.h",
+ "linux/netfilter_bridge/ebt_nat.h",
+ "linux/netfilter_bridge/ebt_nflog.h",
+ "linux/netfilter_bridge/ebt_pkttype.h",
+ "linux/netfilter_bridge/ebt_redirect.h",
+ "linux/netfilter_bridge/ebt_stp.h",
+ "linux/netfilter_bridge/ebt_vlan.h",
+ "linux/netfilter_bridge/ebtables.h",
+ "linux/netfilter_ipv4/ip_tables.h",
+ "linux/netfilter_ipv4/ipt_CLUSTERIP.h",
+ "linux/netfilter_ipv4/ipt_ECN.h",
+ "linux/netfilter_ipv4/ipt_LOG.h",
+ "linux/netfilter_ipv4/ipt_NATTYPE.h",
+ "linux/netfilter_ipv4/ipt_REJECT.h",
+ "linux/netfilter_ipv4/ipt_TTL.h",
+ "linux/netfilter_ipv4/ipt_ah.h",
+ "linux/netfilter_ipv4/ipt_ecn.h",
+ "linux/netfilter_ipv4/ipt_ttl.h",
+ "linux/netfilter_ipv6/ip6_tables.h",
+ "linux/netfilter_ipv6/ip6t_HL.h",
+ "linux/netfilter_ipv6/ip6t_LOG.h",
+ "linux/netfilter_ipv6/ip6t_NPT.h",
+ "linux/netfilter_ipv6/ip6t_REJECT.h",
+ "linux/netfilter_ipv6/ip6t_ah.h",
+ "linux/netfilter_ipv6/ip6t_frag.h",
+ "linux/netfilter_ipv6/ip6t_hl.h",
+ "linux/netfilter_ipv6/ip6t_ipv6header.h",
+ "linux/netfilter_ipv6/ip6t_mh.h",
+ "linux/netfilter_ipv6/ip6t_opts.h",
+ "linux/netfilter_ipv6/ip6t_rt.h",
+ "linux/nfc/nfcinfo.h",
+ "linux/nfsd/cld.h",
+ "linux/nfsd/debug.h",
+ "linux/nfsd/export.h",
+ "linux/nfsd/nfsfh.h",
+ "linux/nfsd/stats.h",
+ "linux/raid/md_p.h",
+ "linux/raid/md_u.h",
+ "linux/spi/spidev.h",
+ "linux/sunrpc/debug.h",
+ "linux/tc_act/tc_bpf.h",
+ "linux/tc_act/tc_connmark.h",
+ "linux/tc_act/tc_csum.h",
+ "linux/tc_act/tc_defact.h",
+ "linux/tc_act/tc_gact.h",
+ "linux/tc_act/tc_ife.h",
+ "linux/tc_act/tc_ipt.h",
+ "linux/tc_act/tc_mirred.h",
+ "linux/tc_act/tc_nat.h",
+ "linux/tc_act/tc_pedit.h",
+ "linux/tc_act/tc_skbedit.h",
+ "linux/tc_act/tc_skbmod.h",
+ "linux/tc_act/tc_tunnel_key.h",
+ "linux/tc_act/tc_vlan.h",
+ "linux/tc_ematch/tc_em_cmp.h",
+ "linux/tc_ematch/tc_em_meta.h",
+ "linux/tc_ematch/tc_em_nbyte.h",
+ "linux/tc_ematch/tc_em_text.h",
+ "linux/usb/audio.h",
+ "linux/usb/cdc-wdm.h",
+ "linux/usb/cdc.h",
+ "linux/usb/ch11.h",
+ "linux/usb/ch9.h",
+ "linux/usb/functionfs.h",
+ "linux/usb/g_printer.h",
+ "linux/usb/gadgetfs.h",
+ "linux/usb/midi.h",
+ "linux/usb/tmc.h",
+ "linux/usb/usb_ctrl_qti.h",
+ "linux/usb/video.h",
+ "linux/wimax/i2400m.h",
+ "rdma/hfi/hfi1_user.h",
+ "scsi/fc/fc_els.h",
+ "scsi/fc/fc_fs.h",
+ "scsi/fc/fc_gs.h",
+ "scsi/fc/fc_ns.h",
+ "scsi/ufs/ioctl.h",
+ "scsi/ufs/ufs.h",
+ "linux/mfd/wcd9xxx/wcd9320_registers.h",
+ "linux/mfd/wcd9xxx/wcd9xxx_registers.h",
+ "linux/netfilter/ipset/ip_set.h",
+ "linux/netfilter/ipset/ip_set_bitmap.h",
+ "linux/netfilter/ipset/ip_set_hash.h",
+ "linux/netfilter/ipset/ip_set_list.h",
+
+ // From arch/arm64/include/uapi/**/*.h
+
+ "asm/auxvec.h",
+ "asm/bitsperlong.h",
+ "asm/byteorder.h",
+ "asm/fcntl.h",
+ "asm/hwcap.h",
+ "asm/kvm.h",
+ "asm/param.h",
+ "asm/perf_regs.h",
+ "asm/posix_types.h",
+ "asm/ptrace.h",
+ "asm/setup.h",
+ "asm/sigcontext.h",
+ "asm/siginfo.h",
+ "asm/signal.h",
+ "asm/stat.h",
+ "asm/statfs.h",
+ "asm/ucontext.h",
+ "asm/unistd.h",
+]
+
+genrule {
+ // This module generates the gen_headers_<arch>.bp file
+ // (i.e., a new version of this file) so that it can be
+ // checked later to ensure that it matches the checked-
+ // in version (this file).
+ name: "qti_generate_gen_headers_arm64",
+ srcs: gen_headers_srcs_arm64,
+ exclude_srcs: gen_headers_exclude_srcs_arm64,
+ tool_files: ["kernel_headers.py"],
+ cmd: "python3 $(location kernel_headers.py) " +
+ kernel_headers_verbose +
+ "--header_arch arm64 " +
+ "--gen_dir $(genDir) " +
+ "--arch_asm_kbuild $(location arch/arm64/include/uapi/asm/Kbuild) " +
+ "--arch_include_uapi $(locations arch/arm64/include/uapi/**/*.h) " +
+ "--asm_generic_kbuild $(location include/uapi/asm-generic/Kbuild.asm) " +
+ "blueprints " +
+ "# $(in)",
+ out: ["gen_headers_arm64.bp"],
+}
+
+genrule {
+ name: "qti_generate_kernel_headers_arm64",
+ tools: ["headers_install.sh"],
+ tool_files: [
+ "kernel_headers.py",
+ ],
+ srcs: gen_headers_srcs_arm64 +[
+ "gen_headers_arm64.bp",
+ ":qti_generate_gen_headers_arm64",
+ ],
+ exclude_srcs: gen_headers_exclude_srcs_arm64,
+ cmd: "python3 $(location kernel_headers.py) " +
+ kernel_headers_verbose +
+ "--header_arch arm64 " +
+ "--gen_dir $(genDir) " +
+ "--arch_asm_kbuild $(location arch/arm64/include/uapi/asm/Kbuild) " +
+ "--arch_include_uapi $(locations arch/arm64/include/uapi/**/*.h) " +
+ "--asm_generic_kbuild $(location include/uapi/asm-generic/Kbuild.asm) " +
+ "headers " +
+ "--old_gen_headers_bp $(location gen_headers_arm64.bp) " +
+ "--new_gen_headers_bp $(location :qti_generate_gen_headers_arm64) " +
+ "--version_makefile $(location Makefile) " +
+ "--headers_install $(location headers_install.sh) " +
+ "--include_uapi $(locations include/uapi/**/*.h)",
+ out: ["linux/version.h"] + gen_headers_out_arm64,
+}
diff --git a/include/Kbuild b/include/Kbuild
deleted file mode 100644
index 9205b04..0000000
--- a/include/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# Top-level Makefile calls into asm-$(ARCH)
-# List only non-arch directories below
-
-ifneq ($(VSERVICES_SUPPORT), "")
-header-y += vservices/
-endif
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 1d798ab..f502d25 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -551,6 +551,8 @@
#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
#define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
+#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) - 1))
+
/*******************************************************************************
*
* Miscellaneous constants
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
deleted file mode 100644
index d2ee86b..0000000
--- a/include/asm-generic/Kbuild.asm
+++ /dev/null
@@ -1 +0,0 @@
-include include/uapi/asm-generic/Kbuild.asm
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index b5c134a..c363e3b 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -458,6 +458,7 @@
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
+u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match);
enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
bool drm_detect_hdmi_monitor(struct edid *edid);
bool drm_detect_monitor_audio(struct edid *edid);
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 9934d91..2e44dad 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -405,6 +405,8 @@
* Field for setting the HDMI picture aspect ratio of a mode.
*/
enum hdmi_picture_aspect picture_aspect_ratio;
+
+ u32 vic_id;
};
#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 76ad8a9..cee74a5 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -3,7 +3,8 @@
#include <asm/types.h>
#include <linux/bits.h>
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
extern unsigned int __sw_hweight8(unsigned int w);
extern unsigned int __sw_hweight16(unsigned int w);
diff --git a/include/linux/clk/msm-clk.h b/include/linux/clk/msm-clk.h
index baa8e52..f442538 100644
--- a/include/linux/clk/msm-clk.h
+++ b/include/linux/clk/msm-clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009, 2012-2017, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -55,6 +55,11 @@
/* Set clock-specific configuration parameters */
int clk_set_flags(struct clk *clk, unsigned long flags);
+/* Set clock duty-cycle as a ratio of numerator/denominator for the desired
+ * duty cycle
+ */
+int clk_set_duty_cycle(struct clk *clk, u32 numerator, u32 denominator);
+
/* returns the mux selection index associated with a particular parent */
int parent_to_src_sel(struct clk_src *parents, int num_parents, struct clk *p);
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 9e9408d..2ccbda2 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -148,10 +148,10 @@
* a new RANGE of SSIDs to the msg_mask_tbl.
*/
#define MSG_MASK_TBL_CNT 26
-#define APPS_EVENT_LAST_ID 0xCC1
+#define APPS_EVENT_LAST_ID 0xCC2
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 132
+#define MSG_SSID_0_LAST 134
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -363,7 +363,9 @@
MSG_LVL_HIGH,
MSG_LVL_HIGH,
MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR,
- MSG_LVL_HIGH
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_1[] = {
@@ -925,7 +927,7 @@
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x1CD6, /* EQUIP ID 1 */
+ 0x1CDD, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 42aaba1..af73d93 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -699,6 +699,7 @@
struct rcu_head i_rcu;
};
u64 i_version;
+ atomic64_t i_sequence; /* see futex */
atomic_t i_count;
atomic_t i_dio_count;
atomic_t i_writecount;
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 6435f46..c015fa9 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -34,23 +34,26 @@
union futex_key {
struct {
+ u64 i_seq;
unsigned long pgoff;
- struct inode *inode;
- int offset;
+ unsigned int offset;
} shared;
struct {
+ union {
+ struct mm_struct *mm;
+ u64 __tmp;
+ };
unsigned long address;
- struct mm_struct *mm;
- int offset;
+ unsigned int offset;
} private;
struct {
+ u64 ptr;
unsigned long word;
- void *ptr;
- int offset;
+ unsigned int offset;
} both;
};
-#define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } }
+#define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = 0ULL } }
#ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 09a2a13..877bb9a 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -454,7 +454,7 @@
};
#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
-#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
+#define HID_MAX_BUFFER_SIZE 8192 /* 8kb */
#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
#define HID_OUTPUT_FIFO_SIZE 64
diff --git a/include/linux/kref.h b/include/linux/kref.h
index e15828f..e2df6d3 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -33,6 +33,11 @@
atomic_set(&kref->refcount, 1);
}
+static inline int kref_read(const struct kref *kref)
+{
+ return atomic_read(&kref->refcount);
+}
+
/**
* kref_get - increment refcount for object.
* @kref: object.
diff --git a/include/linux/libata.h b/include/linux/libata.h
index df58b01..cdfb67b 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1222,6 +1222,7 @@
};
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
+extern void ata_pci_shutdown_one(struct pci_dev *pdev);
extern void ata_pci_remove_one(struct pci_dev *pdev);
#ifdef CONFIG_PM
diff --git a/include/linux/list_nulls.h b/include/linux/list_nulls.h
index 87ff4f5..9e20bf7 100644
--- a/include/linux/list_nulls.h
+++ b/include/linux/list_nulls.h
@@ -71,10 +71,10 @@
struct hlist_nulls_node *first = h->first;
n->next = first;
- n->pprev = &h->first;
+ WRITE_ONCE(n->pprev, &h->first);
h->first = n;
if (!is_a_nulls(first))
- first->pprev = &n->next;
+ WRITE_ONCE(first->pprev, &n->next);
}
static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
@@ -84,13 +84,13 @@
WRITE_ONCE(*pprev, next);
if (!is_a_nulls(next))
- next->pprev = pprev;
+ WRITE_ONCE(next->pprev, pprev);
}
static inline void hlist_nulls_del(struct hlist_nulls_node *n)
{
__hlist_nulls_del(n);
- n->pprev = LIST_POISON2;
+ WRITE_ONCE(n->pprev, LIST_POISON2);
}
/**
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 867110c..8eafced 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -333,6 +333,7 @@
* is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc.
* has_fixups: Set to true if this phy has fixups/quirks.
* suspended: Set to true if this phy has been suspended successfully.
+ * suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus.
* state: state of the PHY for management purposes
* dev_flags: Device-specific flags used by the PHY driver.
* link_timeout: The number of timer firings to wait before the
@@ -369,6 +370,7 @@
bool is_pseudo_fixed_link;
bool has_fixups;
bool suspended;
+ bool suspended_by_mdio_bus;
enum phy_state state;
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
index 106f4e0..4d71e36 100644
--- a/include/linux/rculist_nulls.h
+++ b/include/linux/rculist_nulls.h
@@ -33,7 +33,7 @@
{
if (!hlist_nulls_unhashed(n)) {
__hlist_nulls_del(n);
- n->pprev = NULL;
+ WRITE_ONCE(n->pprev, NULL);
}
}
@@ -65,7 +65,7 @@
static inline void hlist_nulls_del_rcu(struct hlist_nulls_node *n)
{
__hlist_nulls_del(n);
- n->pprev = LIST_POISON2;
+ WRITE_ONCE(n->pprev, LIST_POISON2);
}
/**
@@ -93,10 +93,10 @@
struct hlist_nulls_node *first = h->first;
n->next = first;
- n->pprev = &h->first;
+ WRITE_ONCE(n->pprev, &h->first);
rcu_assign_pointer(hlist_nulls_first_rcu(h), n);
if (!is_a_nulls(first))
- first->pprev = &n->next;
+ WRITE_ONCE(first->pprev, &n->next);
}
/**
diff --git a/include/linux/selection.h b/include/linux/selection.h
index 8e4624e..f1070e4 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -12,8 +12,8 @@
struct tty_struct;
-extern struct vc_data *sel_cons;
struct tty_struct;
+struct vc_data;
extern void clear_selection(void);
extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
@@ -22,6 +22,8 @@
extern int mouse_reporting(void);
extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
+bool vc_is_sel(struct vc_data *vc);
+
extern int console_blanked;
extern const unsigned char color_table[];
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index f113e0e..4f92e0a 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -96,8 +96,9 @@
extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
unsigned long pgoff);
-void vmalloc_sync_all(void);
-
+void vmalloc_sync_mappings(void);
+void vmalloc_sync_unmappings(void);
+
/*
* Lowlevel-APIs (not for driver use!)
*/
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 6abd24f..362db91 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -141,7 +141,7 @@
return false;
}
-extern char vt_dont_switch;
+extern bool vt_dont_switch;
extern int default_utf8;
extern int global_cursor_default;
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 8ffa940..7600241 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -268,7 +268,7 @@
struct v4l2_subdev *__sd; \
\
__v4l2_device_call_subdevs_p(v4l2_dev, __sd, \
- !(grpid) || __sd->grp_id == (grpid), o, f , \
+ (grpid) == 0 || __sd->grp_id == (grpid), o, f , \
##args); \
} while (0)
@@ -280,7 +280,7 @@
({ \
struct v4l2_subdev *__sd; \
__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \
- !(grpid) || __sd->grp_id == (grpid), o, f , \
+ (grpid) == 0 || __sd->grp_id == (grpid), o, f , \
##args); \
})
@@ -294,8 +294,8 @@
struct v4l2_subdev *__sd; \
\
__v4l2_device_call_subdevs_p(v4l2_dev, __sd, \
- !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f , \
- ##args); \
+ (grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o, \
+ f , ##args); \
} while (0)
/*
@@ -308,8 +308,8 @@
({ \
struct v4l2_subdev *__sd; \
__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \
- !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f , \
- ##args); \
+ (grpmsk) == 0 || (__sd->grp_id & (grpmsk)), o, \
+ f , ##args); \
})
/*
diff --git a/include/media/v4l2-rect.h b/include/media/v4l2-rect.h
index d2125f0..1584c76 100644
--- a/include/media/v4l2-rect.h
+++ b/include/media/v4l2-rect.h
@@ -75,10 +75,10 @@
r->left = boundary->left;
if (r->top < boundary->top)
r->top = boundary->top;
- if (r->left + r->width > boundary->width)
- r->left = boundary->width - r->width;
- if (r->top + r->height > boundary->height)
- r->top = boundary->height - r->height;
+ if (r->left + r->width > boundary->left + boundary->width)
+ r->left = boundary->left + boundary->width - r->width;
+ if (r->top + r->height > boundary->top + boundary->height)
+ r->top = boundary->top + boundary->height - r->height;
}
/**
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fbbe3e8..db31d9f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -48,6 +48,9 @@
/* Indicate support for including KEK length in rekey data */
#define CFG80211_REKEY_DATA_KEK_LEN 1
+/* Indicate backport support for key configuration for Beacon protection*/
+#define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1
+
/**
* Indicate backport support for the new cfg80211_roamed event which unifies the
* old APIs cfg80211_roamed and cfg80211_roamed_bss and takes a structure to
@@ -2688,6 +2691,8 @@
* @set_default_key: set the default key on an interface
*
* @set_default_mgmt_key: set the default management frame key on an interface
+
+ * @set_default_beacon_key: set the default Beacon frame key on an interface
*
* @set_rekey_data: give the data necessary for GTK rekeying to the driver
*
@@ -2991,6 +2996,9 @@
int (*set_default_mgmt_key)(struct wiphy *wiphy,
struct net_device *netdev,
u8 key_index);
+ int (*set_default_beacon_key)(struct wiphy *wiphy,
+ struct net_device *netdev,
+ u8 key_index);
int (*start_ap)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ap_settings *settings);
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 8dbfdf7..b4eee18 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -93,6 +93,7 @@
[FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
[FRA_PRIORITY] = { .type = NLA_U32 }, \
[FRA_FWMARK] = { .type = NLA_U32 }, \
+ [FRA_TUN_ID] = { .type = NLA_U64 }, \
[FRA_FWMASK] = { .type = NLA_U32 }, \
[FRA_TABLE] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index 1505cf7..7a85a4e 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <linux/in6.h>
#include <linux/siphash.h>
+#include <linux/string.h>
#include <uapi/linux/if_ether.h>
/**
@@ -204,4 +205,12 @@
return ((char *)target_container) + flow_dissector->offset[key_id];
}
+static inline void
+flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
+ struct flow_dissector_key_basic *key_basic)
+{
+ memset(key_control, 0, sizeof(*key_control));
+ memset(key_basic, 0, sizeof(*key_basic));
+}
+
#endif
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 9cefd94..96c475b 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -37,6 +37,7 @@
ND_OPT_DNSSL = 31, /* RFC6106 */
ND_OPT_6CO = 34, /* RFC6775 */
ND_OPT_CAPTIVE_PORTAL = 37, /* RFC7710 */
+ ND_OPT_PREF64 = 38, /* RFC-ietf-6man-ra-pref64-09 */
__ND_OPT_MAX
};
diff --git a/include/scsi/fc/Kbuild b/include/scsi/fc/Kbuild
deleted file mode 100644
index e69de29..0000000
--- a/include/scsi/fc/Kbuild
+++ /dev/null
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
index 1a2ae08..c1260d8 100644
--- a/include/scsi/iscsi_proto.h
+++ b/include/scsi/iscsi_proto.h
@@ -638,7 +638,6 @@
#define ISCSI_REASON_BOOKMARK_INVALID 9
#define ISCSI_REASON_BOOKMARK_NO_RESOURCES 10
#define ISCSI_REASON_NEGOTIATION_RESET 11
-#define ISCSI_REASON_WAITING_FOR_LOGOUT 12
/* Max. number of Key=Value pairs in a text message */
#define MAX_KEY_VALUE_PAIRS 8192
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 9e1aa1a..1bf6f0f 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -93,9 +93,9 @@
struct list_head list; /* list of all substream for given stream */
int stream; /* direction */
int number; /* substream number */
- unsigned int opened: 1, /* open flag */
- append: 1, /* append flag (merge more streams) */
- active_sensing: 1; /* send active sensing when close */
+ bool opened; /* open flag */
+ bool append; /* append flag (merge more streams) */
+ bool active_sensing; /* send active sensing when close */
int use_count; /* use counter (for output) */
size_t bytes;
struct snd_rawmidi *rmidi;
diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild
deleted file mode 100644
index 96815bd..0000000
--- a/include/uapi/Kbuild
+++ /dev/null
@@ -1,17 +0,0 @@
-# UAPI Header export list
-# Top-level Makefile calls into asm-$(ARCH)
-# List only non-arch directories below
-
-
-header-y += asm-generic/
-header-y += linux/
-header-y += sound/
-header-y += mtd/
-header-y += rdma/
-header-y += video/
-header-y += drm/
-header-y += xen/
-header-y += scsi/
-header-y += misc/
-header-y += media/
-header-y += miniISP/
diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild
deleted file mode 100644
index b73de7b..0000000
--- a/include/uapi/asm-generic/Kbuild
+++ /dev/null
@@ -1,36 +0,0 @@
-# UAPI Header export list
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += errno-base.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += int-l64.h
-header-y += int-ll64.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman-common.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += shmparam.h
-header-y += siginfo.h
-header-y += signal-defs.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
diff --git a/include/uapi/asm-generic/Kbuild.asm b/include/uapi/asm-generic/Kbuild.asm
index fcd50b75..2138144 100644
--- a/include/uapi/asm-generic/Kbuild.asm
+++ b/include/uapi/asm-generic/Kbuild.asm
@@ -1,49 +1,33 @@
#
-# Headers that are optional in usr/include/asm/
-#
-opt-header += kvm.h
-opt-header += kvm_para.h
-opt-header += a.out.h
-
-#
# Headers that are mandatory in usr/include/asm/
#
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += byteorder.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += ptrace.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += sigcontext.h
-header-y += siginfo.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += unistd.h
-
-header-y += $(foreach hdr,$(opt-header), \
- $(if \
- $(wildcard \
- $(srctree)/arch/$(SRCARCH)/include/uapi/asm/$(hdr) \
- $(srctree)/arch/$(SRCARCH)/include/asm/$(hdr) \
- ), \
- $(hdr) \
- ))
+mandatory-y += auxvec.h
+mandatory-y += bitsperlong.h
+mandatory-y += byteorder.h
+mandatory-y += errno.h
+mandatory-y += fcntl.h
+mandatory-y += ioctl.h
+mandatory-y += ioctls.h
+mandatory-y += ipcbuf.h
+mandatory-y += mman.h
+mandatory-y += msgbuf.h
+mandatory-y += param.h
+mandatory-y += poll.h
+mandatory-y += posix_types.h
+mandatory-y += ptrace.h
+mandatory-y += resource.h
+mandatory-y += sembuf.h
+mandatory-y += setup.h
+mandatory-y += shmbuf.h
+mandatory-y += sigcontext.h
+mandatory-y += siginfo.h
+mandatory-y += signal.h
+mandatory-y += socket.h
+mandatory-y += sockios.h
+mandatory-y += stat.h
+mandatory-y += statfs.h
+mandatory-y += swab.h
+mandatory-y += termbits.h
+mandatory-y += termios.h
+mandatory-y += types.h
+mandatory-y += unistd.h
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
index 999c120..74758ea 100644
--- a/include/uapi/drm/Kbuild
+++ b/include/uapi/drm/Kbuild
@@ -1,24 +1,5 @@
# UAPI Header export list
-header-y += drm.h
-header-y += drm_fourcc.h
-header-y += drm_mode.h
-header-y += drm_sarea.h
-header-y += amdgpu_drm.h
-header-y += exynos_drm.h
-header-y += i810_drm.h
-header-y += i915_drm.h
-header-y += mga_drm.h
-header-y += nouveau_drm.h
-header-y += qxl_drm.h
-header-y += r128_drm.h
-header-y += radeon_drm.h
-header-y += savage_drm.h
-header-y += sis_drm.h
-header-y += tegra_drm.h
-header-y += via_drm.h
-header-y += vmwgfx_drm.h
-header-y += msm_drm.h
-header-y += vc4_drm.h
-header-y += virtgpu_drm.h
-header-y += sde_drm.h
-header-y += msm_drm_pp.h
+no-export-headers += armada_drm.h
+no-export-headers += etnaviv_drm.h
+no-export-headers += omap_drm.h
+no-export-headers += vgem_drm.h
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index c2882c2..6dca52c 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -1,522 +1,39 @@
# UAPI Header export list
-header-y += android/
-header-y += byteorder/
-header-y += can/
-header-y += caif/
-header-y += dvb/
-header-y += hdlc/
-header-y += hsi/
-header-y += iio/
-header-y += isdn/
-header-y += mmc/
-header-y += nfsd/
-header-y += raid/
-header-y += spi/
-header-y += sunrpc/
-header-y += tc_act/
-header-y += tc_ematch/
-header-y += netfilter/
-header-y += netfilter_arp/
-header-y += netfilter_bridge/
-header-y += netfilter_ipv4/
-header-y += netfilter_ipv6/
-header-y += usb/
-header-y += wimax/
-header-y += mfd/
-header-y += msm_ipa.h
-genhdr-y += version.h
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/a.out.h \
- $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h),)
-header-y += a.out.h
+ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/a.out.h),)
+no-export-headers += a.out.h
endif
-header-y += acct.h
-header-y += adb.h
-header-y += adfs_fs.h
-header-y += affs_hardblocks.h
-header-y += agpgart.h
-header-y += aio_abi.h
-header-y += am437x-vpfe.h
-header-y += apm_bios.h
-header-y += arcfb.h
-header-y += atalk.h
-header-y += atmapi.h
-header-y += atmarp.h
-header-y += atmbr2684.h
-header-y += atmclip.h
-header-y += atmdev.h
-header-y += atm_eni.h
-header-y += atm.h
-header-y += atm_he.h
-header-y += atm_idt77105.h
-header-y += atmioc.h
-header-y += atmlec.h
-header-y += atmmpc.h
-header-y += atm_nicstar.h
-header-y += atmppp.h
-header-y += atmsap.h
-header-y += atmsvc.h
-header-y += atm_tcp.h
-header-y += atm_zatm.h
-header-y += audit.h
-header-y += auto_fs4.h
-header-y += auto_fs.h
-header-y += auxvec.h
-header-y += ax25.h
-header-y += b1lli.h
-header-y += batterydata-interface.h
-header-y += baycom.h
-header-y += bcm933xx_hcs.h
-header-y += bfs_fs.h
-header-y += binfmts.h
-header-y += blkpg.h
-header-y += blktrace_api.h
-header-y += bpf_common.h
-header-y += bpf_perf_event.h
-header-y += bpf.h
-header-y += bpqether.h
-header-y += bsg.h
-header-y += bt-bmc.h
-header-y += btrfs.h
-header-y += can.h
-header-y += capability.h
-header-y += capi.h
-header-y += cciss_defs.h
-header-y += cciss_ioctl.h
-header-y += cdrom.h
-header-y += cgroupstats.h
-header-y += chio.h
-header-y += cm4000_cs.h
-header-y += cn_proc.h
-header-y += coda.h
-header-y += coda_psdev.h
-header-y += coff.h
-header-y += connector.h
-header-y += const.h
-header-y += coresight-stm.h
-header-y += cramfs_fs.h
-header-y += cuda.h
-header-y += cyclades.h
-header-y += cycx_cfm.h
-header-y += dcbnl.h
-header-y += dccp.h
-header-y += devlink.h
-header-y += dlmconstants.h
-header-y += dlm_device.h
-header-y += dlm.h
-header-y += dlm_netlink.h
-header-y += dlm_plock.h
-header-y += dm-ioctl.h
-header-y += dm-log-userspace.h
-header-y += dn.h
-header-y += dqblk_xfs.h
-header-y += edd.h
-header-y += efs_fs_sb.h
-header-y += elfcore.h
-header-y += elf-em.h
-header-y += elf-fdpic.h
-header-y += elf.h
-header-y += errno.h
-header-y += errqueue.h
-header-y += esoc_ctrl.h
-header-y += ethtool.h
-header-y += eventpoll.h
-header-y += fadvise.h
-header-y += falloc.h
-header-y += fanotify.h
-header-y += fb.h
-header-y += fcntl.h
-header-y += fd.h
-header-y += fdreg.h
-header-y += fib_rules.h
-header-y += fiemap.h
-header-y += filter.h
-header-y += fips_status.h
-header-y += firewire-cdev.h
-header-y += firewire-constants.h
-header-y += flat.h
-header-y += fou.h
-header-y += fs.h
-header-y += fsl_hypervisor.h
-header-y += fuse.h
-header-y += futex.h
-header-y += gameport.h
-header-y += genetlink.h
-header-y += gen_stats.h
-header-y += gfs2_ondisk.h
-header-y += gigaset_dev.h
-header-y += gpio.h
-header-y += gsmmux.h
-header-y += gtp.h
-header-y += hbtp_input.h
-header-y += hdlcdrv.h
-header-y += hdlc.h
-header-y += hdreg.h
-header-y += hiddev.h
-header-y += hid.h
-header-y += hidraw.h
-header-y += hpet.h
-header-y += hsr_netlink.h
-header-y += hyperv.h
-header-y += hysdn_if.h
-header-y += i2c-dev.h
-header-y += i2c.h
-header-y += i2o-dev.h
-header-y += i8k.h
-header-y += icmp.h
-header-y += icmpv6.h
-header-y += if_addr.h
-header-y += if_addrlabel.h
-header-y += if_alg.h
-header-y += if_arcnet.h
-header-y += if_arp.h
-header-y += if_bonding.h
-header-y += if_bridge.h
-header-y += if_cablemodem.h
-header-y += if_eql.h
-header-y += if_ether.h
-header-y += if_fc.h
-header-y += if_fddi.h
-header-y += if_frad.h
-header-y += if.h
-header-y += if_hippi.h
-header-y += if_infiniband.h
-header-y += if_link.h
-header-y += if_ltalk.h
-header-y += if_macsec.h
-header-y += if_packet.h
-header-y += if_phonet.h
-header-y += if_plip.h
-header-y += if_ppp.h
-header-y += if_pppol2tp.h
-header-y += if_pppox.h
-header-y += if_slip.h
-header-y += if_team.h
-header-y += if_tun.h
-header-y += if_tunnel.h
-header-y += if_vlan.h
-header-y += if_x25.h
-header-y += igmp.h
-header-y += ila.h
-header-y += in6.h
-header-y += inet_diag.h
-header-y += in.h
-header-y += inotify.h
-header-y += input.h
-header-y += input-event-codes.h
-header-y += in_route.h
-header-y += ioctl.h
-header-y += ion.h
-header-y += ip6_tunnel.h
-header-y += ipc.h
-header-y += ip.h
-header-y += ipmi.h
-header-y += ipmi_msgdefs.h
-header-y += ipsec.h
-header-y += ipv6.h
-header-y += ipv6_route.h
-header-y += ip_vs.h
-header-y += ipx.h
-header-y += irda.h
-header-y += irqnr.h
-header-y += isdn_divertif.h
-header-y += isdn.h
-header-y += isdnif.h
-header-y += isdn_ppp.h
-header-y += iso_fs.h
-header-y += ivtvfb.h
-header-y += ivtv.h
-header-y += ixjuser.h
-header-y += jffs2.h
-header-y += joystick.h
-header-y += kcmp.h
-header-y += kdev_t.h
-header-y += kd.h
-header-y += kernelcapi.h
-header-y += kernel.h
-header-y += kernel-page-flags.h
-header-y += kexec.h
-header-y += keyboard.h
-header-y += keyctl.h
-
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h \
- $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h),)
-header-y += kvm.h
+ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h),)
+no-export-headers += kvm.h
endif
-
-ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm_para.h \
- $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h),)
-header-y += kvm_para.h
+ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm_para.h),)
+no-export-headers += kvm_para.h
endif
-header-y += hw_breakpoint.h
-header-y += l2tp.h
-header-y += libc-compat.h
-header-y += lirc.h
-header-y += limits.h
-header-y += llc.h
-header-y += loop.h
-header-y += lp.h
-header-y += lwtunnel.h
-header-y += magic.h
-header-y += major.h
-header-y += map_to_7segment.h
-header-y += matroxfb.h
-header-y += mdio.h
-header-y += mdss_rotator.h
-header-y += media.h
-header-y += media-bus-format.h
-header-y += mei.h
-header-y += membarrier.h
-header-y += memfd.h
-header-y += mempolicy.h
-header-y += meye.h
-header-y += mhi.h
-header-y += mic_common.h
-header-y += mic_ioctl.h
-header-y += mii.h
-header-y += minix_fs.h
-header-y += mman.h
-header-y += mmtimer.h
-header-y += mpls.h
-header-y += mpls_iptunnel.h
-header-y += mqueue.h
-header-y += mroute6.h
-header-y += mroute.h
-header-y += msdos_fs.h
-header-y += msg.h
-header-y += msm_ion.h
-header-y += msm_ipc.h
-header-y += msm_kgsl.h
-header-y += msm_mdp.h
-header-y += msm_mdp_ext.h
-header-y += msm_rmnet.h
-header-y += mtio.h
-header-y += nbd.h
-header-y += ncp_fs.h
-header-y += ncp.h
-header-y += ncp_mount.h
-header-y += ncp_no.h
-header-y += ndctl.h
-header-y += neighbour.h
-header-y += netconf.h
-header-y += netdevice.h
-header-y += net_dropmon.h
-header-y += netfilter_arp.h
-header-y += netfilter_bridge.h
-header-y += netfilter_decnet.h
-header-y += netfilter.h
-header-y += netfilter_ipv4.h
-header-y += netfilter_ipv6.h
-header-y += net.h
-header-y += netlink_diag.h
-header-y += netlink.h
-header-y += netrom.h
-header-y += net_map.h
-header-y += net_namespace.h
-header-y += net_tstamp.h
-header-y += nfc.h
-header-y += nfs2.h
-header-y += nfs3.h
-header-y += nfs4.h
-header-y += nfs4_mount.h
-header-y += nfsacl.h
-header-y += nfs_fs.h
-header-y += nfs.h
-header-y += nfs_idmap.h
-header-y += nfs_mount.h
-header-y += nl80211.h
-header-y += n_r3964.h
-header-y += nubus.h
-header-y += nvme_ioctl.h
-header-y += nvram.h
-header-y += omap3isp.h
-header-y += omapfb.h
-header-y += oom.h
-header-y += openvswitch.h
-header-y += packet_diag.h
-header-y += param.h
-header-y += parport.h
-header-y += patchkey.h
-header-y += pci.h
-header-y += pci_regs.h
-header-y += perf_event.h
-header-y += personality.h
-header-y += pfkeyv2.h
-header-y += pg.h
-header-y += phantom.h
-header-y += phonet.h
-header-y += pktcdvd.h
-header-y += pkt_cls.h
-header-y += pkt_sched.h
-header-y += pmu.h
-header-y += poll.h
-header-y += posix_acl.h
-header-y += posix_acl_xattr.h
-header-y += posix_types.h
-header-y += ppdev.h
-header-y += ppp-comp.h
-header-y += ppp_defs.h
-header-y += ppp-ioctl.h
-header-y += pps.h
-header-y += prctl.h
-header-y += psci.h
-header-y += ptp_clock.h
-header-y += ptrace.h
-header-y += qbt1000.h
-header-y += qcedev.h
-header-y += qcota.h
-header-y += qg.h
-header-y += qg-profile.h
-header-y += qnx4_fs.h
-header-y += qnxtypes.h
-header-y += qrng.h
-header-y += qseecom.h
-header-y += quota.h
-header-y += radeonfb.h
-header-y += random.h
-header-y += raw.h
-header-y += rds.h
-header-y += reboot.h
-header-y += reiserfs_fs.h
-header-y += reiserfs_xattr.h
-header-y += resource.h
-header-y += rfkill.h
-header-y += rio_cm_cdev.h
-header-y += rio_mport_cdev.h
-header-y += romfs_fs.h
-header-y += rmnet_data.h
-header-y += rose.h
-header-y += route.h
-header-y += rtc.h
-header-y += rtnetlink.h
-header-y += scc.h
-header-y += sched.h
-header-y += scif_ioctl.h
-header-y += screen_info.h
-header-y += sctp.h
-header-y += sdla.h
-header-y += seccomp.h
-header-y += securebits.h
-header-y += seemp_api.h
-header-y += seemp_param_id.h
-header-y += selinux_netlink.h
-header-y += sem.h
-header-y += serial_core.h
-header-y += serial.h
-header-y += serial_reg.h
-header-y += serio.h
-header-y += shm.h
-header-y += signalfd.h
-header-y += signal.h
-header-y += smcinvoke.h
-header-y += smiapp.h
-header-y += snmp.h
-header-y += sock_diag.h
-header-y += socket.h
-header-y += sockev.h
-header-y += sockios.h
-header-y += sonet.h
-header-y += sonypi.h
-header-y += soundcard.h
-header-y += sound.h
-header-y += spcom.h
-header-y += stat.h
-header-y += stddef.h
-header-y += string.h
-header-y += suspend_ioctls.h
-header-y += swab.h
-header-y += synclink.h
-header-y += sync_file.h
-header-y += sysctl.h
-header-y += sysinfo.h
-header-y += target_core_user.h
-header-y += taskstats.h
-header-y += tcp.h
-header-y += tcp_metrics.h
-header-y += telephony.h
-header-y += termios.h
-header-y += thermal.h
-header-y += time.h
-header-y += times.h
-header-y += timex.h
-header-y += tiocl.h
-header-y += tipc_config.h
-header-y += tipc_netlink.h
-header-y += tipc.h
-header-y += toshiba.h
-header-y += tty_flags.h
-header-y += tty.h
-header-y += types.h
-header-y += udf_fs_i.h
-header-y += udp.h
-header-y += uhid.h
-header-y += uinput.h
-header-y += uio.h
-header-y += ultrasound.h
-header-y += un.h
-header-y += unistd.h
-header-y += unix_diag.h
-header-y += usbdevice_fs.h
-header-y += usbip.h
-header-y += utime.h
-header-y += utsname.h
-header-y += uuid.h
-header-y += uvcvideo.h
-header-y += v4l2-common.h
-header-y += v4l2-controls.h
-header-y += v4l2-dv-timings.h
-header-y += v4l2-mediabus.h
-header-y += v4l2-subdev.h
-header-y += msm_vidc_dec.h
-header-y += msm_vidc_enc.h
-header-y += veth.h
-header-y += vfio.h
-header-y += vhost.h
-header-y += videodev2.h
-header-y += virtio_9p.h
-header-y += virtio_balloon.h
-header-y += virtio_blk.h
-header-y += virtio_config.h
-header-y += virtio_console.h
-header-y += virtio_gpu.h
-header-y += virtio_ids.h
-header-y += virtio_input.h
-header-y += virtio_net.h
-header-y += virtio_pci.h
-header-y += virtio_ring.h
-header-y += virtio_rng.h
-header-y += virtio_scsi.h
-header-y += virtio_types.h
-header-y += virtio_vsock.h
-header-y += vm_bms.h
-header-y += vm_sockets.h
-header-y += vt.h
-header-y += vtpm_proxy.h
-header-y += wait.h
-header-y += wanrouter.h
-header-y += watchdog.h
-header-y += wimax.h
-header-y += wireless.h
-header-y += x25.h
-header-y += xattr.h
-header-y += xfrm.h
-header-y += xilinx-v4l2-controls.h
-header-y += zorro.h
-header-y += zorro_ids.h
-header-y += userfaultfd.h
-header-y += ipa_qmi_service_v01.h
-header-y += msm_ipa.h
-header-y += rmnet_ipa_fd_ioctl.h
-header-y += msm_dsps.h
-header-y += msm-core-interface.h
-header-y += msm_rotator.h
-header-y += bgcom_interface.h
-header-y += nfc/
+no-export-headers += auto_dev-ioctl.h
+no-export-headers += batman_adv.h
+no-export-headers += bcache.h
+no-export-headers += btrfs_tree.h
+no-export-headers += cryptouser.h
+no-export-headers += dma-buf.h
+no-export-headers += hash_info.h
+no-export-headers += kcm.h
+no-export-headers += kcov.h
+no-export-headers += kfd_ioctl.h
+no-export-headers += lightnvm.h
+no-export-headers += module.h
+no-export-headers += nilfs2_api.h
+no-export-headers += nilfs2_ondisk.h
+no-export-headers += nsfs.h
+no-export-headers += pr.h
+no-export-headers += qrtr.h
+no-export-headers += stm.h
+no-export-headers += tee.h
+no-export-headers += userio.h
+no-export-headers += wil6210_uapi.h
ifneq ($(VSERVICES_SUPPORT), "")
include include/linux/Kbuild.vservices
endif
-header-y += okl4-link-shbuf.h
diff --git a/include/uapi/linux/android/Kbuild b/include/uapi/linux/android/Kbuild
deleted file mode 100644
index ca011ee..0000000
--- a/include/uapi/linux/android/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += binder.h
diff --git a/include/uapi/linux/byteorder/Kbuild b/include/uapi/linux/byteorder/Kbuild
deleted file mode 100644
index 619225b..0000000
--- a/include/uapi/linux/byteorder/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += big_endian.h
-header-y += little_endian.h
diff --git a/include/uapi/linux/caif/Kbuild b/include/uapi/linux/caif/Kbuild
deleted file mode 100644
index 4339661..0000000
--- a/include/uapi/linux/caif/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += caif_socket.h
-header-y += if_caif.h
diff --git a/include/uapi/linux/can/Kbuild b/include/uapi/linux/can/Kbuild
deleted file mode 100644
index 21c91bf..0000000
--- a/include/uapi/linux/can/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# UAPI Header export list
-header-y += bcm.h
-header-y += error.h
-header-y += gw.h
-header-y += netlink.h
-header-y += raw.h
diff --git a/include/uapi/linux/cifs/Kbuild b/include/uapi/linux/cifs/Kbuild
new file mode 100644
index 0000000..c922dbe
--- /dev/null
+++ b/include/uapi/linux/cifs/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+no-export-headers += cifs_mount.h
diff --git a/include/uapi/linux/dvb/Kbuild b/include/uapi/linux/dvb/Kbuild
deleted file mode 100644
index d40942c..0000000
--- a/include/uapi/linux/dvb/Kbuild
+++ /dev/null
@@ -1,9 +0,0 @@
-# UAPI Header export list
-header-y += audio.h
-header-y += ca.h
-header-y += dmx.h
-header-y += frontend.h
-header-y += net.h
-header-y += osd.h
-header-y += version.h
-header-y += video.h
diff --git a/include/uapi/linux/genwqe/Kbuild b/include/uapi/linux/genwqe/Kbuild
new file mode 100644
index 0000000..b50fc21
--- /dev/null
+++ b/include/uapi/linux/genwqe/Kbuild
@@ -0,0 +1,2 @@
+# UAPI Header export list
+no-export-headers += genwqe_card.h
diff --git a/include/uapi/linux/hdlc/Kbuild b/include/uapi/linux/hdlc/Kbuild
deleted file mode 100644
index 8c1d2cb..0000000
--- a/include/uapi/linux/hdlc/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += ioctl.h
diff --git a/include/uapi/linux/hsi/Kbuild b/include/uapi/linux/hsi/Kbuild
deleted file mode 100644
index a16a005..0000000
--- a/include/uapi/linux/hsi/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += hsi_char.h cs-protocol.h
diff --git a/include/uapi/linux/iio/Kbuild b/include/uapi/linux/iio/Kbuild
deleted file mode 100644
index 86f76d8..0000000
--- a/include/uapi/linux/iio/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += events.h
-header-y += types.h
diff --git a/include/uapi/linux/isdn/Kbuild b/include/uapi/linux/isdn/Kbuild
deleted file mode 100644
index 89e5285..0000000
--- a/include/uapi/linux/isdn/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += capicmd.h
diff --git a/include/uapi/linux/mmc/Kbuild b/include/uapi/linux/mmc/Kbuild
deleted file mode 100644
index ce4e885..0000000
--- a/include/uapi/linux/mmc/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# UAPI Header export list
-header-y += core.h
-header-y += core.h
-header-y += ioctl.h
-header-y += mmc.h
-header-y += mmc.h
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index 864943f..078672b 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -1838,6 +1838,12 @@
IPA_DATA_EP_TYP_BAM_DMUX,
};
+enum ipa_data_ep_prot_type {
+ IPA_PROT_RMNET = 0,
+ IPA_PROT_RMNET_CV2X = 1,
+ IPA_PROT_MAX
+};
+
struct ipa_ep_pair_info {
uint32_t consumer_pipe_num;
uint32_t producer_pipe_num;
@@ -1852,6 +1858,8 @@
* @num_ep_pairs: number of ep_pairs - o/p param
* @ep_pair_size: sizeof(ipa_ep_pair_info) * max_ep_pairs
* @info: structure contains ep pair info
+ * @teth_prot : RMNET/CV2X --i/p param
+ * @teth_prot_valid - validity of i/p param protocol
*/
struct ipa_ioc_get_ep_info {
enum ipa_peripheral_ep_type ep_type;
@@ -1859,6 +1867,8 @@
uint8_t num_ep_pairs;
uint32_t ep_pair_size;
uintptr_t info;
+ enum ipa_data_ep_prot_type teth_prot;
+ uint8_t teth_prot_valid;
};
/**
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index 03f194a..6b00ca2 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -1,89 +1,2 @@
# UAPI Header export list
-header-y += ipset/
-header-y += nf_conntrack_common.h
-header-y += nf_conntrack_ftp.h
-header-y += nf_conntrack_sctp.h
-header-y += nf_conntrack_tcp.h
-header-y += nf_conntrack_tuple_common.h
-header-y += nf_log.h
-header-y += nf_tables.h
-header-y += nf_tables_compat.h
-header-y += nf_nat.h
-header-y += nfnetlink.h
-header-y += nfnetlink_acct.h
-header-y += nfnetlink_compat.h
-header-y += nfnetlink_conntrack.h
-header-y += nfnetlink_cthelper.h
-header-y += nfnetlink_cttimeout.h
-header-y += nfnetlink_log.h
-header-y += nfnetlink_queue.h
-header-y += x_tables.h
-header-y += xt_AUDIT.h
-header-y += xt_CHECKSUM.h
-header-y += xt_CLASSIFY.h
-header-y += xt_CONNMARK.h
-header-y += xt_CONNSECMARK.h
-header-y += xt_CT.h
-header-y += xt_DSCP.h
-header-y += xt_HMARK.h
-header-y += xt_IDLETIMER.h
-header-y += xt_LED.h
-header-y += xt_LOG.h
-header-y += xt_MARK.h
-header-y += xt_NFLOG.h
-header-y += xt_NFQUEUE.h
-header-y += xt_RATEEST.h
-header-y += xt_SECMARK.h
-header-y += xt_SYNPROXY.h
-header-y += xt_TCPMSS.h
-header-y += xt_TCPOPTSTRIP.h
-header-y += xt_TEE.h
-header-y += xt_TPROXY.h
-header-y += xt_addrtype.h
-header-y += xt_bpf.h
-header-y += xt_cgroup.h
-header-y += xt_cluster.h
-header-y += xt_comment.h
-header-y += xt_connbytes.h
-header-y += xt_connlabel.h
-header-y += xt_connlimit.h
-header-y += xt_connmark.h
-header-y += xt_conntrack.h
-header-y += xt_cpu.h
-header-y += xt_dccp.h
-header-y += xt_devgroup.h
-header-y += xt_dscp.h
-header-y += xt_ecn.h
-header-y += xt_esp.h
-header-y += xt_hashlimit.h
-header-y += xt_helper.h
-header-y += xt_ipcomp.h
-header-y += xt_iprange.h
-header-y += xt_ipvs.h
-header-y += xt_l2tp.h
-header-y += xt_length.h
-header-y += xt_limit.h
-header-y += xt_mac.h
-header-y += xt_mark.h
-header-y += xt_multiport.h
-header-y += xt_nfacct.h
-header-y += xt_osf.h
-header-y += xt_owner.h
-header-y += xt_physdev.h
-header-y += xt_pkttype.h
-header-y += xt_policy.h
-header-y += xt_quota.h
-header-y += xt_rateest.h
-header-y += xt_realm.h
-header-y += xt_recent.h
-header-y += xt_rpfilter.h
-header-y += xt_sctp.h
-header-y += xt_set.h
-header-y += xt_socket.h
-header-y += xt_state.h
-header-y += xt_statistic.h
-header-y += xt_string.h
-header-y += xt_tcpmss.h
-header-y += xt_tcpudp.h
-header-y += xt_time.h
-header-y += xt_u32.h
+no-export-headers += xt_HARDIDLETIMER.h
diff --git a/include/uapi/linux/netfilter/ipset/Kbuild b/include/uapi/linux/netfilter/ipset/Kbuild
deleted file mode 100644
index d268042..0000000
--- a/include/uapi/linux/netfilter/ipset/Kbuild
+++ /dev/null
@@ -1,5 +0,0 @@
-# UAPI Header export list
-header-y += ip_set.h
-header-y += ip_set_bitmap.h
-header-y += ip_set_hash.h
-header-y += ip_set_list.h
diff --git a/include/uapi/linux/netfilter_arp/Kbuild b/include/uapi/linux/netfilter_arp/Kbuild
deleted file mode 100644
index 62d5637..0000000
--- a/include/uapi/linux/netfilter_arp/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += arp_tables.h
-header-y += arpt_mangle.h
diff --git a/include/uapi/linux/netfilter_bridge/Kbuild b/include/uapi/linux/netfilter_bridge/Kbuild
deleted file mode 100644
index 0fbad8e..0000000
--- a/include/uapi/linux/netfilter_bridge/Kbuild
+++ /dev/null
@@ -1,18 +0,0 @@
-# UAPI Header export list
-header-y += ebt_802_3.h
-header-y += ebt_among.h
-header-y += ebt_arp.h
-header-y += ebt_arpreply.h
-header-y += ebt_ip.h
-header-y += ebt_ip6.h
-header-y += ebt_limit.h
-header-y += ebt_log.h
-header-y += ebt_mark_m.h
-header-y += ebt_mark_t.h
-header-y += ebt_nat.h
-header-y += ebt_nflog.h
-header-y += ebt_pkttype.h
-header-y += ebt_redirect.h
-header-y += ebt_stp.h
-header-y += ebt_vlan.h
-header-y += ebtables.h
diff --git a/include/uapi/linux/netfilter_ipv4/Kbuild b/include/uapi/linux/netfilter_ipv4/Kbuild
deleted file mode 100644
index 7391cdc..0000000
--- a/include/uapi/linux/netfilter_ipv4/Kbuild
+++ /dev/null
@@ -1,11 +0,0 @@
-# UAPI Header export list
-header-y += ip_tables.h
-header-y += ipt_CLUSTERIP.h
-header-y += ipt_ECN.h
-header-y += ipt_LOG.h
-header-y += ipt_REJECT.h
-header-y += ipt_TTL.h
-header-y += ipt_ah.h
-header-y += ipt_ecn.h
-header-y += ipt_ttl.h
-header-y += ipt_NATTYPE.h
diff --git a/include/uapi/linux/netfilter_ipv6/Kbuild b/include/uapi/linux/netfilter_ipv6/Kbuild
deleted file mode 100644
index 75a668c..0000000
--- a/include/uapi/linux/netfilter_ipv6/Kbuild
+++ /dev/null
@@ -1,13 +0,0 @@
-# UAPI Header export list
-header-y += ip6_tables.h
-header-y += ip6t_HL.h
-header-y += ip6t_LOG.h
-header-y += ip6t_NPT.h
-header-y += ip6t_REJECT.h
-header-y += ip6t_ah.h
-header-y += ip6t_frag.h
-header-y += ip6t_hl.h
-header-y += ip6t_ipv6header.h
-header-y += ip6t_mh.h
-header-y += ip6t_opts.h
-header-y += ip6t_rt.h
diff --git a/include/uapi/linux/nfsd/Kbuild b/include/uapi/linux/nfsd/Kbuild
deleted file mode 100644
index c11bc40..0000000
--- a/include/uapi/linux/nfsd/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# UAPI Header export list
-header-y += cld.h
-header-y += debug.h
-header-y += export.h
-header-y += nfsfh.h
-header-y += stats.h
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 17f1635..1cef158 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4164,6 +4164,10 @@
* @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
* attributes, specifying what a key should be set as default as.
* See &enum nl80211_key_default_types.
+ * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode.
+ * Defaults to @NL80211_KEY_RX_TX.
+ * @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key
+ *
* @__NL80211_KEY_AFTER_LAST: internal
* @NL80211_KEY_MAX: highest key attribute
*/
@@ -4177,6 +4181,8 @@
NL80211_KEY_DEFAULT_MGMT,
NL80211_KEY_TYPE,
NL80211_KEY_DEFAULT_TYPES,
+ NL80211_KEY_MODE,
+ NL80211_KEY_DEFAULT_BEACON,
/* keep last */
__NL80211_KEY_AFTER_LAST,
@@ -5125,6 +5131,26 @@
* @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
* (set/del PMKSA operations) in AP mode.
*
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
+ * filtering of sched scan results using band specific RSSI thresholds.
+ *
+ * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
+ * to a station.
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
+ * station mode (SAE password is passed as part of the connect command).
+ *
+ * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
+ * with VLAN tagged frames and separate VLAN-specific netdevs added using
+ * vconfig similarly to the Ethernet case.
+ *
+ * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
+ * feature, which prevents bufferbloat by using the expected transmission
+ * time to limit the amount of data buffered in the hardware.
+ *
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
+ * and can receive key configuration for BIGTK using key indexes 6 and 7.
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -5164,6 +5190,13 @@
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
+ NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
+ NL80211_EXT_FEATURE_EXT_KEY_ID,
+ NL80211_EXT_FEATURE_STA_TX_PWR,
+ NL80211_EXT_FEATURE_SAE_OFFLOAD,
+ NL80211_EXT_FEATURE_VLAN_OFFLOAD,
+ NL80211_EXT_FEATURE_AQL,
+ NL80211_EXT_FEATURE_BEACON_PROTECTION,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/include/uapi/linux/qrtr.h b/include/uapi/linux/qrtr.h
index 66c0748..4b25d2f 100644
--- a/include/uapi/linux/qrtr.h
+++ b/include/uapi/linux/qrtr.h
@@ -3,10 +3,45 @@
#include <linux/socket.h>
+#define QRTR_NODE_BCAST 0xffffffffu
+#define QRTR_PORT_CTRL 0xfffffffeu
+
struct sockaddr_qrtr {
__kernel_sa_family_t sq_family;
__u32 sq_node;
__u32 sq_port;
};
+enum qrtr_pkt_type {
+ QRTR_TYPE_DATA = 1,
+ QRTR_TYPE_HELLO = 2,
+ QRTR_TYPE_BYE = 3,
+ QRTR_TYPE_NEW_SERVER = 4,
+ QRTR_TYPE_DEL_SERVER = 5,
+ QRTR_TYPE_DEL_CLIENT = 6,
+ QRTR_TYPE_RESUME_TX = 7,
+ QRTR_TYPE_EXIT = 8,
+ QRTR_TYPE_PING = 9,
+ QRTR_TYPE_NEW_LOOKUP = 10,
+ QRTR_TYPE_DEL_LOOKUP = 11,
+};
+
+struct qrtr_ctrl_pkt {
+ __le32 cmd;
+
+ union {
+ struct {
+ __le32 service;
+ __le32 instance;
+ __le32 node;
+ __le32 port;
+ } server;
+
+ struct {
+ __le32 node;
+ __le32 port;
+ } client;
+ };
+} __packed;
+
#endif /* _LINUX_QRTR_H */
diff --git a/include/uapi/linux/raid/Kbuild b/include/uapi/linux/raid/Kbuild
deleted file mode 100644
index e2c3d25..0000000
--- a/include/uapi/linux/raid/Kbuild
+++ /dev/null
@@ -1,3 +0,0 @@
-# UAPI Header export list
-header-y += md_p.h
-header-y += md_u.h
diff --git a/include/uapi/linux/spi/Kbuild b/include/uapi/linux/spi/Kbuild
deleted file mode 100644
index 0cc747e..0000000
--- a/include/uapi/linux/spi/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += spidev.h
diff --git a/include/uapi/linux/sunrpc/Kbuild b/include/uapi/linux/sunrpc/Kbuild
deleted file mode 100644
index 8e02e47..0000000
--- a/include/uapi/linux/sunrpc/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += debug.h
diff --git a/include/uapi/linux/tc_act/Kbuild b/include/uapi/linux/tc_act/Kbuild
deleted file mode 100644
index e3db740..0000000
--- a/include/uapi/linux/tc_act/Kbuild
+++ /dev/null
@@ -1,15 +0,0 @@
-# UAPI Header export list
-header-y += tc_csum.h
-header-y += tc_defact.h
-header-y += tc_gact.h
-header-y += tc_ipt.h
-header-y += tc_mirred.h
-header-y += tc_nat.h
-header-y += tc_pedit.h
-header-y += tc_skbedit.h
-header-y += tc_vlan.h
-header-y += tc_bpf.h
-header-y += tc_connmark.h
-header-y += tc_ife.h
-header-y += tc_tunnel_key.h
-header-y += tc_skbmod.h
diff --git a/include/uapi/linux/tc_ematch/Kbuild b/include/uapi/linux/tc_ematch/Kbuild
deleted file mode 100644
index 53fca39..0000000
--- a/include/uapi/linux/tc_ematch/Kbuild
+++ /dev/null
@@ -1,5 +0,0 @@
-# UAPI Header export list
-header-y += tc_em_cmp.h
-header-y += tc_em_meta.h
-header-y += tc_em_nbyte.h
-header-y += tc_em_text.h
diff --git a/include/uapi/linux/usb/Kbuild b/include/uapi/linux/usb/Kbuild
index ba153d5..e511bf6 100644
--- a/include/uapi/linux/usb/Kbuild
+++ b/include/uapi/linux/usb/Kbuild
@@ -1,13 +1,3 @@
# UAPI Header export list
-header-y += audio.h
-header-y += cdc.h
-header-y += cdc-wdm.h
-header-y += ch11.h
-header-y += ch9.h
-header-y += functionfs.h
-header-y += g_printer.h
-header-y += gadgetfs.h
-header-y += midi.h
-header-y += tmc.h
-header-y += usb_ctrl_qti.h
-header-y += video.h
+no-export-headers += f_accessory.h
+no-export-headers += f_mtp.h
diff --git a/include/uapi/linux/wimax/Kbuild b/include/uapi/linux/wimax/Kbuild
deleted file mode 100644
index 1c97be4..0000000
--- a/include/uapi/linux/wimax/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += i2400m.h
diff --git a/include/uapi/misc/Kbuild b/include/uapi/misc/Kbuild
deleted file mode 100644
index e96cae7..0000000
--- a/include/uapi/misc/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# misc Header export list
-header-y += cxl.h
diff --git a/include/uapi/mtd/Kbuild b/include/uapi/mtd/Kbuild
deleted file mode 100644
index 5a691e1..0000000
--- a/include/uapi/mtd/Kbuild
+++ /dev/null
@@ -1,6 +0,0 @@
-# UAPI Header export list
-header-y += inftl-user.h
-header-y += mtd-abi.h
-header-y += mtd-user.h
-header-y += nftl-user.h
-header-y += ubi-user.h
diff --git a/include/uapi/rdma/Kbuild b/include/uapi/rdma/Kbuild
index f14ab7f..c2a45be 100644
--- a/include/uapi/rdma/Kbuild
+++ b/include/uapi/rdma/Kbuild
@@ -1,16 +1,2 @@
# UAPI Header export list
-header-y += ib_user_cm.h
-header-y += ib_user_mad.h
-header-y += ib_user_sa.h
-header-y += ib_user_verbs.h
-header-y += rdma_netlink.h
-header-y += rdma_user_cm.h
-header-y += hfi/
-header-y += rdma_user_rxe.h
-header-y += cxgb3-abi.h
-header-y += cxgb4-abi.h
-header-y += mlx4-abi.h
-header-y += mlx5-abi.h
-header-y += mthca-abi.h
-header-y += nes-abi.h
-header-y += ocrdma-abi.h
+no-export-headers += qedr-abi.h
diff --git a/include/uapi/rdma/hfi/Kbuild b/include/uapi/rdma/hfi/Kbuild
deleted file mode 100644
index ef23c29..0000000
--- a/include/uapi/rdma/hfi/Kbuild
+++ /dev/null
@@ -1,2 +0,0 @@
-# UAPI Header export list
-header-y += hfi1_user.h
diff --git a/include/uapi/scsi/Kbuild b/include/uapi/scsi/Kbuild
deleted file mode 100644
index 9a0da84..0000000
--- a/include/uapi/scsi/Kbuild
+++ /dev/null
@@ -1,9 +0,0 @@
-# UAPI Header export list
-header-y += fc/
-header-y += ufs/
-header-y += scsi_bsg_fc.h
-header-y += sg.h
-header-y += scsi_ioctl.h
-header-y += scsi_netlink.h
-header-y += scsi_netlink_fc.h
-header-y += cxlflash_ioctl.h
diff --git a/include/uapi/scsi/fc/Kbuild b/include/uapi/scsi/fc/Kbuild
deleted file mode 100644
index 5ead9fa..0000000
--- a/include/uapi/scsi/fc/Kbuild
+++ /dev/null
@@ -1,5 +0,0 @@
-# UAPI Header export list
-header-y += fc_els.h
-header-y += fc_fs.h
-header-y += fc_gs.h
-header-y += fc_ns.h
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
deleted file mode 100644
index 9578d8b..0000000
--- a/include/uapi/sound/Kbuild
+++ /dev/null
@@ -1,16 +0,0 @@
-# UAPI Header export list
-header-y += asequencer.h
-header-y += asoc.h
-header-y += asound.h
-header-y += asound_fm.h
-header-y += compress_offload.h
-header-y += compress_params.h
-header-y += emu10k1.h
-header-y += firewire.h
-header-y += hdsp.h
-header-y += hdspm.h
-header-y += sb16_csp.h
-header-y += sfnt_info.h
-header-y += tlv.h
-header-y += usb_stream.h
-header-y += snd_sst_tokens.h
diff --git a/include/uapi/video/Kbuild b/include/uapi/video/Kbuild
index b98fa51..35ee3b6 100644
--- a/include/uapi/video/Kbuild
+++ b/include/uapi/video/Kbuild
@@ -1,6 +1,2 @@
# UAPI Header export list
-header-y += edid.h
-header-y += msm_hdmi_hdcp_mgr.h
-header-y += msm_hdmi_modes.h
-header-y += sisfb.h
-header-y += uvesafb.h
+no-export-headers += adf.h
diff --git a/include/uapi/xen/Kbuild b/include/uapi/xen/Kbuild
deleted file mode 100644
index 5c45962..0000000
--- a/include/uapi/xen/Kbuild
+++ /dev/null
@@ -1,5 +0,0 @@
-# UAPI Header export list
-header-y += evtchn.h
-header-y += gntalloc.h
-header-y += gntdev.h
-header-y += privcmd.h
diff --git a/include/video/Kbuild b/include/video/Kbuild
deleted file mode 100644
index e69de29..0000000
--- a/include/video/Kbuild
+++ /dev/null
diff --git a/ipc/sem.c b/ipc/sem.c
index 10b94bc..5cd9d80 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -2159,11 +2159,9 @@
ipc_assert_locked_object(&sma->sem_perm);
list_del(&un->list_id);
- /* we are the last process using this ulp, acquiring ulp->lock
- * isn't required. Besides that, we are also protected against
- * IPC_RMID as we hold sma->sem_perm lock now
- */
+ spin_lock(&ulp->lock);
list_del_rcu(&un->list_proc);
+ spin_unlock(&ulp->lock);
/* perform adjustments registered in un */
for (i = 0; i < sma->sem_nsems; i++) {
diff --git a/kernel/audit.c b/kernel/audit.c
index 194fa1a..7d9b52a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -756,13 +756,11 @@
audit_log_end(ab);
}
-static int audit_set_feature(struct sk_buff *skb)
+static int audit_set_feature(struct audit_features *uaf)
{
- struct audit_features *uaf;
int i;
BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names));
- uaf = nlmsg_data(nlmsg_hdr(skb));
/* if there is ever a version 2 we should handle that here */
@@ -832,6 +830,7 @@
{
u32 seq;
void *data;
+ int data_len;
int err;
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
@@ -855,6 +854,7 @@
}
seq = nlh->nlmsg_seq;
data = nlmsg_data(nlh);
+ data_len = nlmsg_len(nlh);
switch (msg_type) {
case AUDIT_GET: {
@@ -876,7 +876,7 @@
struct audit_status s;
memset(&s, 0, sizeof(s));
/* guard against past and future API changes */
- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
+ memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
if (s.mask & AUDIT_STATUS_ENABLED) {
err = audit_set_enabled(s.enabled);
if (err < 0)
@@ -908,9 +908,9 @@
}
if (audit_enabled != AUDIT_OFF)
audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
+ mutex_lock(&audit_sock_mutex);
audit_pid = new_pid;
audit_nlk_portid = NETLINK_CB(skb).portid;
- mutex_lock(&audit_sock_mutex);
audit_sock = skb->sk;
mutex_unlock(&audit_sock_mutex);
}
@@ -941,7 +941,9 @@
return err;
break;
case AUDIT_SET_FEATURE:
- err = audit_set_feature(skb);
+ if (data_len < sizeof(struct audit_features))
+ return -EINVAL;
+ err = audit_set_feature(data);
if (err)
return err;
break;
@@ -953,6 +955,8 @@
err = audit_filter(msg_type, AUDIT_FILTER_USER);
if (err == 1) { /* match or error */
+ char *str = data;
+
err = 0;
if (msg_type == AUDIT_USER_TTY) {
err = tty_audit_push();
@@ -961,19 +965,17 @@
}
mutex_unlock(&audit_cmd_mutex);
audit_log_common_recv_msg(&ab, msg_type);
- if (msg_type != AUDIT_USER_TTY)
+ if (msg_type != AUDIT_USER_TTY) {
+ /* ensure NULL termination */
+ str[data_len - 1] = '\0';
audit_log_format(ab, " msg='%.*s'",
AUDIT_MESSAGE_TEXT_MAX,
- (char *)data);
- else {
- int size;
-
+ str);
+ } else {
audit_log_format(ab, " data=");
- size = nlmsg_len(nlh);
- if (size > 0 &&
- ((unsigned char *)data)[size - 1] == '\0')
- size--;
- audit_log_n_untrustedstring(ab, data, size);
+ if (data_len > 0 && str[data_len - 1] == '\0')
+ data_len--;
+ audit_log_n_untrustedstring(ab, str, data_len);
}
audit_set_portid(ab, NETLINK_CB(skb).portid);
audit_log_end(ab);
@@ -982,7 +984,7 @@
break;
case AUDIT_ADD_RULE:
case AUDIT_DEL_RULE:
- if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
+ if (data_len < sizeof(struct audit_rule_data))
return -EINVAL;
if (audit_enabled == AUDIT_LOCKED) {
audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE);
@@ -991,7 +993,7 @@
return -EPERM;
}
err = audit_rule_change(msg_type, NETLINK_CB(skb).portid,
- seq, data, nlmsg_len(nlh));
+ seq, data, data_len);
break;
case AUDIT_LIST_RULES:
err = audit_list_rules_send(skb, seq);
@@ -1005,7 +1007,7 @@
case AUDIT_MAKE_EQUIV: {
void *bufp = data;
u32 sizes[2];
- size_t msglen = nlmsg_len(nlh);
+ size_t msglen = data_len;
char *old, *new;
err = -EINVAL;
@@ -1081,7 +1083,7 @@
memset(&s, 0, sizeof(s));
/* guard against past and future API changes */
- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh)));
+ memcpy(&s, data, min_t(size_t, sizeof(s), data_len));
/* check if new data is valid */
if ((s.enabled != 0 && s.enabled != 1) ||
(s.log_passwd != 0 && s.log_passwd != 1))
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 42b7251..a71ff99 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -434,6 +434,7 @@
bufp = data->buf;
for (i = 0; i < data->field_count; i++) {
struct audit_field *f = &entry->rule.fields[i];
+ u32 f_val;
err = -EINVAL;
@@ -442,12 +443,12 @@
goto exit_free;
f->type = data->fields[i];
- f->val = data->values[i];
+ f_val = data->values[i];
/* Support legacy tests for a valid loginuid */
- if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) {
+ if ((f->type == AUDIT_LOGINUID) && (f_val == AUDIT_UID_UNSET)) {
f->type = AUDIT_LOGINUID_SET;
- f->val = 0;
+ f_val = 0;
entry->rule.pflags |= AUDIT_LOGINUID_LEGACY;
}
@@ -463,7 +464,7 @@
case AUDIT_SUID:
case AUDIT_FSUID:
case AUDIT_OBJ_UID:
- f->uid = make_kuid(current_user_ns(), f->val);
+ f->uid = make_kuid(current_user_ns(), f_val);
if (!uid_valid(f->uid))
goto exit_free;
break;
@@ -472,11 +473,12 @@
case AUDIT_SGID:
case AUDIT_FSGID:
case AUDIT_OBJ_GID:
- f->gid = make_kgid(current_user_ns(), f->val);
+ f->gid = make_kgid(current_user_ns(), f_val);
if (!gid_valid(f->gid))
goto exit_free;
break;
case AUDIT_ARCH:
+ f->val = f_val;
entry->rule.arch_f = f;
break;
case AUDIT_SUBJ_USER:
@@ -489,11 +491,13 @@
case AUDIT_OBJ_TYPE:
case AUDIT_OBJ_LEV_LOW:
case AUDIT_OBJ_LEV_HIGH:
- str = audit_unpack_string(&bufp, &remain, f->val);
- if (IS_ERR(str))
+ str = audit_unpack_string(&bufp, &remain, f_val);
+ if (IS_ERR(str)) {
+ err = PTR_ERR(str);
goto exit_free;
- entry->rule.buflen += f->val;
-
+ }
+ entry->rule.buflen += f_val;
+ f->lsm_str = str;
err = security_audit_rule_init(f->type, f->op, str,
(void **)&f->lsm_rule);
/* Keep currently invalid fields around in case they
@@ -502,68 +506,71 @@
pr_warn("audit rule for LSM \'%s\' is invalid\n",
str);
err = 0;
- }
- if (err) {
- kfree(str);
+ } else if (err)
goto exit_free;
- } else
- f->lsm_str = str;
break;
case AUDIT_WATCH:
- str = audit_unpack_string(&bufp, &remain, f->val);
- if (IS_ERR(str))
+ str = audit_unpack_string(&bufp, &remain, f_val);
+ if (IS_ERR(str)) {
+ err = PTR_ERR(str);
goto exit_free;
- entry->rule.buflen += f->val;
-
- err = audit_to_watch(&entry->rule, str, f->val, f->op);
+ }
+ err = audit_to_watch(&entry->rule, str, f_val, f->op);
if (err) {
kfree(str);
goto exit_free;
}
+ entry->rule.buflen += f_val;
break;
case AUDIT_DIR:
- str = audit_unpack_string(&bufp, &remain, f->val);
- if (IS_ERR(str))
+ str = audit_unpack_string(&bufp, &remain, f_val);
+ if (IS_ERR(str)) {
+ err = PTR_ERR(str);
goto exit_free;
- entry->rule.buflen += f->val;
-
+ }
err = audit_make_tree(&entry->rule, str, f->op);
kfree(str);
if (err)
goto exit_free;
+ entry->rule.buflen += f_val;
break;
case AUDIT_INODE:
+ f->val = f_val;
err = audit_to_inode(&entry->rule, f);
if (err)
goto exit_free;
break;
case AUDIT_FILTERKEY:
- if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN)
+ if (entry->rule.filterkey || f_val > AUDIT_MAX_KEY_LEN)
goto exit_free;
- str = audit_unpack_string(&bufp, &remain, f->val);
- if (IS_ERR(str))
- goto exit_free;
- entry->rule.buflen += f->val;
- entry->rule.filterkey = str;
- break;
- case AUDIT_EXE:
- if (entry->rule.exe || f->val > PATH_MAX)
- goto exit_free;
- str = audit_unpack_string(&bufp, &remain, f->val);
+ str = audit_unpack_string(&bufp, &remain, f_val);
if (IS_ERR(str)) {
err = PTR_ERR(str);
goto exit_free;
}
- entry->rule.buflen += f->val;
-
- audit_mark = audit_alloc_mark(&entry->rule, str, f->val);
+ entry->rule.buflen += f_val;
+ entry->rule.filterkey = str;
+ break;
+ case AUDIT_EXE:
+ if (entry->rule.exe || f_val > PATH_MAX)
+ goto exit_free;
+ str = audit_unpack_string(&bufp, &remain, f_val);
+ if (IS_ERR(str)) {
+ err = PTR_ERR(str);
+ goto exit_free;
+ }
+ audit_mark = audit_alloc_mark(&entry->rule, str, f_val);
if (IS_ERR(audit_mark)) {
kfree(str);
err = PTR_ERR(audit_mark);
goto exit_free;
}
+ entry->rule.buflen += f_val;
entry->rule.exe = audit_mark;
break;
+ default:
+ f->val = f_val;
+ break;
}
}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 42af9fa..c92cf06 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -983,7 +983,7 @@
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
{
- union bpf_attr attr = {};
+ union bpf_attr attr;
int err;
if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
@@ -1019,6 +1019,7 @@
}
/* copy attributes from user space, may be less than sizeof(bpf_attr) */
+ memset(&attr, 0, sizeof(attr));
if (copy_from_user(&attr, uattr, size) != 0)
return -EFAULT;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 0ded03f..e3311fe 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -6488,6 +6488,10 @@
return;
}
+ /* Don't associate the sock with unrelated interrupted task's cgroup. */
+ if (in_interrupt())
+ return;
+
rcu_read_lock();
while (true) {
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 81a78c2..9f4c88f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -522,8 +522,7 @@
if (WARN_ON_ONCE((!cpu_online(cpu))))
return -ECANCELED;
- /* Unpark the stopper thread and the hotplug thread of the target cpu */
- stop_machine_unpark(cpu);
+ /* Unpark the hotplug thread of the target cpu */
kthread_unpark(st->thread);
/*
@@ -1130,8 +1129,8 @@
/*
* Called from the idle task. Wake up the controlling task which brings the
- * stopper and the hotplug thread of the upcoming CPU up and then delegates
- * the rest of the online bringup to the hotplug thread.
+ * hotplug thread of the upcoming CPU up and then delegates the rest of the
+ * online bringup to the hotplug thread.
*/
void cpuhp_online_idle(enum cpuhp_state state)
{
@@ -1141,6 +1140,12 @@
if (state != CPUHP_AP_ONLINE_IDLE)
return;
+ /*
+ * Unpart the stopper thread before we start the idle loop (and start
+ * scheduling); this ensures the stopper task is always available.
+ */
+ stop_machine_unpark(smp_processor_id());
+
st->state = CPUHP_AP_ONLINE_IDLE;
complete(&st->done);
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 456647a..d4a26b3 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5479,7 +5479,15 @@
*/
user_lock_limit *= num_online_cpus();
- user_locked = atomic_long_read(&user->locked_vm) + user_extra;
+ user_locked = atomic_long_read(&user->locked_vm);
+
+ /*
+ * sysctl_perf_event_mlock may have changed, so that
+ * user->locked_vm > user_lock_limit
+ */
+ if (user_locked > user_lock_limit)
+ user_locked = user_lock_limit;
+ user_locked += user_extra;
if (user_locked > user_lock_limit)
extra = user_locked - user_lock_limit;
diff --git a/kernel/futex.c b/kernel/futex.c
index 2e766ff..7123d9c 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -390,9 +390,9 @@
*/
static struct futex_hash_bucket *hash_futex(union futex_key *key)
{
- u32 hash = jhash2((u32*)&key->both.word,
- (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
+ u32 hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / 4,
key->both.offset);
+
return &futex_queues[hash & (futex_hashsize - 1)];
}
@@ -434,7 +434,7 @@
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
case FUT_OFF_INODE:
- ihold(key->shared.inode); /* implies smp_mb(); (B) */
+ smp_mb(); /* explicit smp_mb(); (B) */
break;
case FUT_OFF_MMSHARED:
futex_get_mm(key); /* implies smp_mb(); (B) */
@@ -468,7 +468,6 @@
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
case FUT_OFF_INODE:
- iput(key->shared.inode);
break;
case FUT_OFF_MMSHARED:
mmdrop(key->private.mm);
@@ -476,6 +475,46 @@
}
}
+/*
+ * Generate a machine wide unique identifier for this inode.
+ *
+ * This relies on u64 not wrapping in the life-time of the machine; which with
+ * 1ns resolution means almost 585 years.
+ *
+ * This further relies on the fact that a well formed program will not unmap
+ * the file while it has a (shared) futex waiting on it. This mapping will have
+ * a file reference which pins the mount and inode.
+ *
+ * If for some reason an inode gets evicted and read back in again, it will get
+ * a new sequence number and will _NOT_ match, even though it is the exact same
+ * file.
+ *
+ * It is important that match_futex() will never have a false-positive, esp.
+ * for PI futexes that can mess up the state. The above argues that false-negatives
+ * are only possible for malformed programs.
+ */
+static u64 get_inode_sequence_number(struct inode *inode)
+{
+ static atomic64_t i_seq;
+ u64 old;
+
+ /* Does the inode already have a sequence number? */
+ old = atomic64_read(&inode->i_sequence);
+ if (likely(old))
+ return old;
+
+ for (;;) {
+ u64 new = atomic64_add_return(1, &i_seq);
+ if (WARN_ON_ONCE(!new))
+ continue;
+
+ old = atomic64_cmpxchg_relaxed(&inode->i_sequence, 0, new);
+ if (old)
+ return old;
+ return new;
+ }
+}
+
/**
* get_futex_key() - Get parameters which are the keys for a futex
* @uaddr: virtual address of the futex
@@ -488,9 +527,15 @@
*
* The key words are stored in *key on success.
*
- * For shared mappings, it's (page->index, file_inode(vma->vm_file),
- * offset_within_page). For private mappings, it's (uaddr, current->mm).
- * We can usually work out the index without swapping in the page.
+ * For shared mappings (when @fshared), the key is:
+ * ( inode->i_sequence, page->index, offset_within_page )
+ * [ also see get_inode_sequence_number() ]
+ *
+ * For private mappings (or when !@fshared), the key is:
+ * ( current->mm, address, 0 )
+ *
+ * This allows (cross process, where applicable) identification of the futex
+ * without keeping the page pinned for the duration of the FUTEX_WAIT.
*
* lock_page() might sleep, the caller should not hold a spinlock.
*/
@@ -630,8 +675,6 @@
key->private.mm = mm;
key->private.address = address;
- get_futex_key_refs(key); /* implies smp_mb(); (B) */
-
} else {
struct inode *inode;
@@ -663,40 +706,14 @@
goto again;
}
- /*
- * Take a reference unless it is about to be freed. Previously
- * this reference was taken by ihold under the page lock
- * pinning the inode in place so i_lock was unnecessary. The
- * only way for this check to fail is if the inode was
- * truncated in parallel which is almost certainly an
- * application bug. In such a case, just retry.
- *
- * We are not calling into get_futex_key_refs() in file-backed
- * cases, therefore a successful atomic_inc return below will
- * guarantee that get_futex_key() will still imply smp_mb(); (B).
- */
- if (!atomic_inc_not_zero(&inode->i_count)) {
- rcu_read_unlock();
- put_page(page);
-
- goto again;
- }
-
- /* Should be impossible but lets be paranoid for now */
- if (WARN_ON_ONCE(inode->i_mapping != mapping)) {
- err = -EFAULT;
- rcu_read_unlock();
- iput(inode);
-
- goto out;
- }
-
key->both.offset |= FUT_OFF_INODE; /* inode-based key */
- key->shared.inode = inode;
+ key->shared.i_seq = get_inode_sequence_number(inode);
key->shared.pgoff = basepage_index(tail);
rcu_read_unlock();
}
+ get_futex_key_refs(key); /* implies smp_mb(); (B) */
+
out:
put_page(page);
return err;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index be7f489..b2fc2a5 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -233,7 +233,11 @@
if (desc->affinity_notify) {
kref_get(&desc->affinity_notify->kref);
- schedule_work(&desc->affinity_notify->work);
+ if (!schedule_work(&desc->affinity_notify->work)) {
+ /* Work was already scheduled, drop our extra ref */
+ kref_put(&desc->affinity_notify->kref,
+ desc->affinity_notify->release);
+ }
}
irqd_set(data, IRQD_AFFINITY_SET);
@@ -333,7 +337,10 @@
raw_spin_unlock_irqrestore(&desc->lock, flags);
if (old_notify) {
- cancel_work_sync(&old_notify->work);
+ if (cancel_work_sync(&old_notify->work)) {
+ /* Pending work had a ref, put that one too */
+ kref_put(&old_notify->kref, old_notify->release);
+ }
kref_put(&old_notify->kref, old_notify->release);
}
diff --git a/kernel/notifier.c b/kernel/notifier.c
index fd2c9ac..0f70f1b 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -552,7 +552,7 @@
int register_die_notifier(struct notifier_block *nb)
{
- vmalloc_sync_all();
+ vmalloc_sync_mappings();
return atomic_notifier_chain_register(&die_chain, nb);
}
EXPORT_SYMBOL_GPL(register_die_notifier);
diff --git a/kernel/padata.c b/kernel/padata.c
index 63449fc5..286c514 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -34,6 +34,8 @@
#define MAX_OBJ_NUM 1000
+static void padata_free_pd(struct parallel_data *pd);
+
static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
{
int cpu, target_cpu;
@@ -301,6 +303,7 @@
struct padata_serial_queue *squeue;
struct parallel_data *pd;
LIST_HEAD(local_list);
+ int cnt;
local_bh_disable();
squeue = container_of(serial_work, struct padata_serial_queue, work);
@@ -310,6 +313,8 @@
list_replace_init(&squeue->serial.list, &local_list);
spin_unlock(&squeue->serial.lock);
+ cnt = 0;
+
while (!list_empty(&local_list)) {
struct padata_priv *padata;
@@ -319,9 +324,12 @@
list_del_init(&padata->list);
padata->serial(padata);
- atomic_dec(&pd->refcnt);
+ cnt++;
}
local_bh_enable();
+
+ if (atomic_sub_and_test(cnt, &pd->refcnt))
+ padata_free_pd(pd);
}
/**
@@ -444,7 +452,7 @@
setup_timer(&pd->timer, padata_reorder_timer, (unsigned long)pd);
atomic_set(&pd->seq_nr, -1);
atomic_set(&pd->reorder_objects, 0);
- atomic_set(&pd->refcnt, 0);
+ atomic_set(&pd->refcnt, 1);
pd->pinst = pinst;
spin_lock_init(&pd->lock);
@@ -469,31 +477,6 @@
kfree(pd);
}
-/* Flush all objects out of the padata queues. */
-static void padata_flush_queues(struct parallel_data *pd)
-{
- int cpu;
- struct padata_parallel_queue *pqueue;
- struct padata_serial_queue *squeue;
-
- for_each_cpu(cpu, pd->cpumask.pcpu) {
- pqueue = per_cpu_ptr(pd->pqueue, cpu);
- flush_work(&pqueue->work);
- }
-
- del_timer_sync(&pd->timer);
-
- if (atomic_read(&pd->reorder_objects))
- padata_reorder(pd);
-
- for_each_cpu(cpu, pd->cpumask.cbcpu) {
- squeue = per_cpu_ptr(pd->squeue, cpu);
- flush_work(&squeue->work);
- }
-
- BUG_ON(atomic_read(&pd->refcnt) != 0);
-}
-
static void __padata_start(struct padata_instance *pinst)
{
pinst->flags |= PADATA_INIT;
@@ -507,10 +490,6 @@
pinst->flags &= ~PADATA_INIT;
synchronize_rcu();
-
- get_online_cpus();
- padata_flush_queues(pinst->pd);
- put_online_cpus();
}
/* Replace the internal control structure with a new one. */
@@ -531,8 +510,8 @@
if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu))
notification_mask |= PADATA_CPU_SERIAL;
- padata_flush_queues(pd_old);
- padata_free_pd(pd_old);
+ if (atomic_dec_and_test(&pd_old->refcnt))
+ padata_free_pd(pd_old);
if (notification_mask)
blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
index 5fdbc23..e2a69e8 100644
--- a/kernel/sched/psi.c
+++ b/kernel/sched/psi.c
@@ -185,7 +185,8 @@
for_each_possible_cpu(cpu)
seqcount_init(&per_cpu_ptr(group->pcpu, cpu)->seq);
- group->avg_next_update = sched_clock() + psi_period;
+ group->avg_last_update = sched_clock();
+ group->avg_next_update = group->avg_last_update + psi_period;
INIT_DELAYED_WORK(&group->avgs_work, psi_avgs_work);
mutex_init(&group->avgs_lock);
/* Init trigger-related members */
@@ -481,7 +482,7 @@
u32 remaining;
remaining = win->size - elapsed;
- growth += div_u64(win->prev_growth * remaining, win->size);
+ growth += div64_u64(win->prev_growth * remaining, win->size);
}
return growth;
@@ -1198,7 +1199,10 @@
if (static_branch_likely(&psi_disabled))
return -EOPNOTSUPP;
- buf_size = min(nbytes, (sizeof(buf) - 1));
+ if (!nbytes)
+ return -EINVAL;
+
+ buf_size = min(nbytes, sizeof(buf));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index e2f1d27..0ed63b8 100755
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2338,7 +2338,7 @@
#else /* CONFIG_SCHED_WALT */
static inline u64 sched_ktime_clock(void)
{
- return 0;
+ return sched_clock();
}
static inline void note_task_waking(struct task_struct *p, u64 wallclock) { }
#endif /* CONFIG_SCHED_WALT */
@@ -2371,16 +2371,20 @@
static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
{
struct update_util_data *data;
+ u64 clock;
#ifdef CONFIG_SCHED_WALT
if (!(flags & SCHED_CPUFREQ_WALT))
return;
+ clock = sched_ktime_clock();
+#else
+ clock = rq_clock(rq);
#endif
data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
cpu_of(rq)));
if (data)
- data->func(data, sched_ktime_clock(), flags);
+ data->func(data, clock, flags);
}
static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags)
diff --git a/kernel/signal.c b/kernel/signal.c
index 43d1c6a..0ee5396 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -377,27 +377,32 @@
{
struct sigqueue *q = NULL;
struct user_struct *user;
+ int sigpending;
/*
* Protect access to @t credentials. This can go away when all
* callers hold rcu read lock.
+ *
+ * NOTE! A pending signal will hold on to the user refcount,
+ * and we get/put the refcount only when the sigpending count
+ * changes from/to zero.
*/
rcu_read_lock();
- user = get_uid(__task_cred(t)->user);
- atomic_inc(&user->sigpending);
+ user = __task_cred(t)->user;
+ sigpending = atomic_inc_return(&user->sigpending);
+ if (sigpending == 1)
+ get_uid(user);
rcu_read_unlock();
- if (override_rlimit ||
- atomic_read(&user->sigpending) <=
- task_rlimit(t, RLIMIT_SIGPENDING)) {
+ if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
q = kmem_cache_alloc(sigqueue_cachep, flags);
} else {
print_dropped_signal(sig);
}
if (unlikely(q == NULL)) {
- atomic_dec(&user->sigpending);
- free_uid(user);
+ if (atomic_dec_and_test(&user->sigpending))
+ free_uid(user);
} else {
INIT_LIST_HEAD(&q->list);
q->flags = 0;
@@ -411,8 +416,8 @@
{
if (q->flags & SIGQUEUE_PREALLOC)
return;
- atomic_dec(&q->user->sigpending);
- free_uid(q->user);
+ if (atomic_dec_and_test(&q->user->sigpending))
+ free_uid(q->user);
kmem_cache_free(sigqueue_cachep, q);
}
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 8a6970e..fd31559 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -272,8 +272,15 @@
next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
if (next_cpu >= nr_cpu_ids)
next_cpu = cpumask_first(cpu_online_mask);
- watchdog_timer.expires += WATCHDOG_INTERVAL;
- add_timer_on(&watchdog_timer, next_cpu);
+
+ /*
+ * Arm timer if not already pending: could race with concurrent
+ * pair clocksource_stop_watchdog() clocksource_start_watchdog().
+ */
+ if (!timer_pending(&watchdog_timer)) {
+ watchdog_timer.expires += WATCHDOG_INTERVAL;
+ add_timer_on(&watchdog_timer, next_cpu);
+ }
out:
spin_unlock(&watchdog_lock);
}
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f39616f..3126dbc 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -5457,9 +5457,10 @@
struct trace_array *tr = m->private;
struct trace_pid_list *pid_list = rcu_dereference_sched(tr->function_pids);
- if (v == FTRACE_NO_PIDS)
+ if (v == FTRACE_NO_PIDS) {
+ (*pos)++;
return NULL;
-
+ }
return trace_pid_next(pid_list, v, pos);
}
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 7e6971b..8a88e85 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -126,9 +126,10 @@
{
struct trace_event_file *event_file = event_file_data(m->private);
- if (t == SHOW_AVAILABLE_TRIGGERS)
+ if (t == SHOW_AVAILABLE_TRIGGERS) {
+ (*pos)++;
return NULL;
-
+ }
return seq_list_next(t, &event_file->triggers, pos);
}
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index 413ff10..d19f219 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -277,18 +277,22 @@
d_tracing = tracing_init_dentry();
if (IS_ERR(d_tracing))
- return 0;
+ return -ENODEV;
stat_dir = tracefs_create_dir("trace_stat", d_tracing);
- if (!stat_dir)
+ if (!stat_dir) {
pr_warn("Could not create tracefs 'trace_stat' entry\n");
+ return -ENOMEM;
+ }
return 0;
}
static int init_stat_file(struct stat_session *session)
{
- if (!stat_dir && tracing_stat_init())
- return -ENODEV;
+ int ret;
+
+ if (!stat_dir && (ret = tracing_stat_init()))
+ return ret;
session->file = tracefs_create_file(session->ts->name, 0644,
stat_dir,
@@ -301,7 +305,7 @@
int register_stat_tracer(struct tracer_stat *trace)
{
struct stat_session *session, *node;
- int ret;
+ int ret = -EINVAL;
if (!trace)
return -EINVAL;
@@ -312,17 +316,15 @@
/* Already registered? */
mutex_lock(&all_stat_sessions_mutex);
list_for_each_entry(node, &all_stat_sessions, session_list) {
- if (node->ts == trace) {
- mutex_unlock(&all_stat_sessions_mutex);
- return -EINVAL;
- }
+ if (node->ts == trace)
+ goto out;
}
- mutex_unlock(&all_stat_sessions_mutex);
+ ret = -ENOMEM;
/* Init the session */
session = kzalloc(sizeof(*session), GFP_KERNEL);
if (!session)
- return -ENOMEM;
+ goto out;
session->ts = trace;
INIT_LIST_HEAD(&session->session_list);
@@ -331,15 +333,16 @@
ret = init_stat_file(session);
if (ret) {
destroy_session(session);
- return ret;
+ goto out;
}
+ ret = 0;
/* Register */
- mutex_lock(&all_stat_sessions_mutex);
list_add_tail(&session->session_list, &all_stat_sessions);
+ out:
mutex_unlock(&all_stat_sessions_mutex);
- return 0;
+ return ret;
}
void unregister_stat_tracer(struct tracer_stat *trace)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 6ffc72e..ac381bf 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1414,14 +1414,16 @@
WARN_ON_ONCE(!is_chained_work(wq)))
return;
retry:
- if (req_cpu == WORK_CPU_UNBOUND)
- cpu = wq_select_unbound_cpu(raw_smp_processor_id());
-
/* pwq which will be used unless @work is executing elsewhere */
- if (!(wq->flags & WQ_UNBOUND))
- pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);
- else
+ if (wq->flags & WQ_UNBOUND) {
+ if (req_cpu == WORK_CPU_UNBOUND)
+ cpu = wq_select_unbound_cpu(raw_smp_processor_id());
pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu));
+ } else {
+ if (req_cpu == WORK_CPU_UNBOUND)
+ cpu = raw_smp_processor_id();
+ pwq = per_cpu_ptr(wq->cpu_pwqs, cpu);
+ }
/*
* If @work was previously on a different pool, it might still be
diff --git a/kernel_headers.py b/kernel_headers.py
new file mode 100644
index 0000000..d36ca87
--- /dev/null
+++ b/kernel_headers.py
@@ -0,0 +1,1076 @@
+# Copyright 2019 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Generates gen_headers_<arch>.bp or generates/checks kernel headers."""
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+import argparse
+import filecmp
+import os
+import re
+import subprocess
+import sys
+
+
+def gen_version_h(verbose, gen_dir, version_makefile):
+ """Generate linux/version.h
+
+ Scan the version_makefile for the version info, and then generate
+ linux/version.h in the gen_dir as done in kernel Makefile function
+ filechk_version.h
+
+ Args:
+ verbose: Set True to print progress messages.
+ gen_dir: Where to place the generated files.
+ version_makefile: The makefile that contains version info.
+ Return:
+ If version info not found, False. Otherwise, True.
+ """
+
+ version_re = re.compile(r'VERSION\s*=\s*(\d+)')
+ patchlevel_re = re.compile(r'PATCHLEVEL\s*=\s*(\d+)')
+ sublevel_re = re.compile(r'SUBLEVEL\s*=\s*(\d+)')
+
+ version_str = None
+ patchlevel_str = None
+ sublevel_str = None
+
+ if verbose:
+ print('gen_version_h: processing [%s]' % version_makefile)
+
+ with open(version_makefile, 'r') as f:
+ while not version_str or not patchlevel_str or not sublevel_str:
+ line = f.readline()
+
+ if not line:
+ print(
+ 'error: gen_version_h: failed to parse kernel version from %s' %
+ version_makefile)
+ return False
+
+ line = line.rstrip()
+
+ if verbose:
+ print('gen_version_h: line is %s' % line)
+
+ if not version_str:
+ match = version_re.match(line)
+ if match:
+ if verbose:
+ print('gen_version_h: matched version [%s]' % line)
+ version_str = match.group(1)
+ continue
+
+ if not patchlevel_str:
+ match = patchlevel_re.match(line)
+ if match:
+ if verbose:
+ print('gen_version_h: matched patchlevel [%s]' % line)
+ patchlevel_str = match.group(1)
+ continue
+
+ if not sublevel_str:
+ match = sublevel_re.match(line)
+ if match:
+ if verbose:
+ print('gen_version_h: matched sublevel [%s]' % line)
+ sublevel_str = match.group(1)
+ continue
+
+ version = int(version_str)
+ patchlevel = int(patchlevel_str)
+ sublevel = int(sublevel_str)
+
+ if verbose:
+ print(
+ 'gen_version_h: found kernel version %d.%d.%d' %
+ (version, patchlevel, sublevel))
+
+ version_h = os.path.join(gen_dir, 'linux', 'version.h')
+
+ with open(version_h, 'w') as f:
+ # This code must match the code in Makefile in the make function
+ # filechk_version.h
+ version_code = (version << 16) + (patchlevel << 8) + sublevel
+ f.write('#define LINUX_VERSION_CODE %d\n' % version_code)
+ f.write(
+ '#define KERNEL_VERSION(a,b,c) ' +
+ '(((a) << 16) + ((b) << 8) + (c))\n')
+
+ return True
+
+
+def scan_arch_kbuild(verbose, arch_asm_kbuild, asm_generic_kbuild, arch_include_uapi):
+ """Scan arch_asm_kbuild for generated headers.
+
+ This function processes the Kbuild file to scan for three types of files that
+ need to be generated. The first type are syscall generated headers, which are
+ identified by adding to the generated-y make variable. The second type are
+ generic headers, which are arch-specific headers that simply wrap the
+ asm-generic counterpart, and are identified by adding to the generic-y make
+ variable. The third type are mandatory headers that should be present in the
+ /usr/include/asm folder.
+
+ Args:
+ verbose: Set True to print progress messages.
+ arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
+ asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
+ arch_include_uapi: Headers in /arch/<arch>/include/uapi directory
+ Return:
+ Two lists of discovered headers, one for generated and one for generic.
+ """
+
+ generated_y_re = re.compile(r'generated-y\s*\+=\s*(\S+)')
+ generic_y_re = re.compile(r'generic-y\s*\+=\s*(\S+)')
+ mandatory_y_re = re.compile(r'mandatory-y\s*\+=\s*(\S+)')
+
+ # This loop parses arch_asm_kbuild for various kinds of headers to generate.
+
+ if verbose:
+ print('scan_arch_kbuild: processing [%s]' % arch_asm_kbuild)
+
+ generated_list = []
+ generic_list = []
+ arch_include_uapi_list = [os.path.basename(x) for x in arch_include_uapi]
+ mandatory_pre_list = []
+ mandatory_list = []
+
+
+ with open(arch_asm_kbuild, 'r') as f:
+ while True:
+ line = f.readline()
+
+ if not line:
+ break
+
+ line = line.rstrip()
+
+ if verbose:
+ print('scan_arch_kbuild: line is %s' % line)
+
+ match = generated_y_re.match(line)
+
+ if match:
+ if verbose:
+ print('scan_arch_kbuild: matched [%s]' % line)
+ generated_list.append(match.group(1))
+ continue
+
+ match = generic_y_re.match(line)
+
+ if match:
+ if verbose:
+ print('scan_arch_kbuild: matched [%s]' % line)
+ generic_list.append(match.group(1))
+ continue
+
+ # This loop parses asm_generic_kbuild for various kinds of headers to generate.
+
+ if verbose:
+ print('scan_arch_kbuild: processing [%s]' % asm_generic_kbuild)
+
+ with open(asm_generic_kbuild, 'r') as f:
+ while True:
+ line = f.readline()
+
+ if not line:
+ break
+
+ line = line.rstrip()
+
+ if verbose:
+ print('scan_arch_kbuild: line is %s' % line)
+
+ match = mandatory_y_re.match(line)
+
+ if match:
+ if verbose:
+ print('scan_arch_kbuild: matched [%s]' % line)
+ mandatory_pre_list.append(match.group(1))
+ continue
+
+ # Mandatory headers need to be generated if they are not already generated.
+ comb_list = generic_list + generated_list + arch_include_uapi_list
+ mandatory_list = [x for x in mandatory_pre_list if x not in comb_list]
+ if verbose:
+ print("generic")
+ for x in generic_list:
+ print(x)
+ print("generated")
+ for x in generated_list:
+ print(x)
+ print("mandatory")
+ for x in mandatory_list:
+ print(x)
+ print("arch_include_uapi_list")
+ for x in arch_include_uapi_list:
+ print(x)
+
+ return (generated_list, generic_list, mandatory_list)
+
+
+def gen_arch_headers(
+ verbose, gen_dir, arch_asm_kbuild, asm_generic_kbuild, arch_syscall_tool, arch_syscall_tbl, arch_include_uapi):
+ """Process arch-specific and asm-generic uapi/asm/Kbuild to generate headers.
+
+ The function consists of a call to scan_arch_kbuild followed by three loops.
+ The first loop generates headers found and placed in the generated_list by
+ scan_arch_kbuild. The second loop generates headers found and placed in the
+ generic_list by the scan_arch_kbuild. The third loop generates headers found
+ in mandatory_list by scan_arch_kbuild.
+
+ The function does some parsing of file names and tool invocations. If that
+ parsing fails for some reason (e.g., we don't know how to generate the
+ header) or a tool invocation fails, then this function will count that as
+ an error but keep processing. In the end, the function returns the number of
+ errors encountered.
+
+ Args:
+ verbose: Set True to print progress messages.
+ gen_dir: Where to place the generated files.
+ arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
+ asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
+ arch_syscall_tool: The arch script that generates syscall headers, or None.
+ arch_syscall_tbl: The arch script that defines syscall vectors, or None.
+ arch_include_uapi: Headers in arch/<arch>/include/uapi directory.
+ Return:
+ The number of parsing errors encountered.
+ """
+
+ error_count = 0
+
+ # First generate the lists
+
+ (generated_list, generic_list, mandatory_list) = scan_arch_kbuild(verbose, arch_asm_kbuild, asm_generic_kbuild ,arch_include_uapi)
+
+ # Now we're at the first loop, which is able to generate syscall headers
+ # found in the first loop, and placed in generated_list. It's okay for this
+ # list to be empty. In that case, of course, the loop does nothing.
+
+ abi_re = re.compile(r'unistd-(\S+)\.h')
+
+ for generated in generated_list:
+ gen_h = os.path.join(gen_dir, 'asm', generated)
+ match = abi_re.match(generated)
+
+ if match:
+ abi = match.group(1)
+
+ cmd = [
+ '/bin/bash',
+ arch_syscall_tool,
+ arch_syscall_tbl,
+ gen_h,
+ abi,
+ '',
+ '__NR_SYSCALL_BASE',
+ ]
+
+ if verbose:
+ print('gen_arch_headers: cmd is %s' % cmd)
+
+ result = subprocess.call(cmd)
+
+ if result != 0:
+ print('error: gen_arch_headers: cmd %s failed %d' % (cmd, result))
+ error_count += 1
+ else:
+ print('error: gen_arch_headers: syscall header has bad filename: %s' % generated)
+ error_count += 1
+
+ # Now we're at the second loop, which generates wrappers from arch-specific
+ # headers listed in generic_list to the corresponding asm-generic header.
+
+ for generic in generic_list:
+ wrap_h = os.path.join(gen_dir, 'asm', generic)
+ with open(wrap_h, 'w') as f:
+ f.write('#include <asm-generic/%s>\n' % generic)
+
+ # Now we're at the third loop, which generates wrappers from asm
+ # headers listed in mandatory_list to the corresponding asm-generic header.
+
+ for mandatory in mandatory_list:
+ wrap_h = os.path.join(gen_dir, 'asm', mandatory)
+ with open(wrap_h, 'w') as f:
+ f.write('#include <asm-generic/%s>\n' % mandatory)
+ return error_count
+
+
+def run_headers_install(verbose, gen_dir, headers_install, prefix, h):
+ """Process a header through the headers_install script.
+
+ The headers_install script does some processing of a header so that it is
+ appropriate for inclusion in a userland program. This function invokes that
+ script for one header file.
+
+ The input file is a header file found in the directory named by prefix. This
+ function stips the prefix from the header to generate the name of the
+ processed header.
+
+ Args:
+ verbose: Set True to print progress messages.
+ gen_dir: Where to place the generated files.
+ headers_install: The script that munges the header.
+ prefix: The prefix to strip from h to generate the output filename.
+ h: The input header to process.
+ Return:
+ If parsing or the tool fails, False. Otherwise, True
+ """
+
+ if not h.startswith(prefix):
+ print('error: expected prefix [%s] on header [%s]' % (prefix, h))
+ return False
+
+ out_h = os.path.join(gen_dir, h[len(prefix):])
+ (out_h_dirname, out_h_basename) = os.path.split(out_h)
+ h_dirname = os.path.dirname(h)
+
+ cmd = [headers_install, out_h_dirname, h_dirname, out_h_basename]
+
+ if verbose:
+ print('run_headers_install: cmd is %s' % cmd)
+
+ result = subprocess.call(cmd)
+
+ if result != 0:
+ print('error: run_headers_install: cmd %s failed %d' % (cmd, result))
+ return False
+
+ return True
+
+
+def glob_headers(prefix, rel_glob, excludes):
+ """Recursively scan the a directory for headers.
+
+ This function recursively scans the directory identified by prefix for
+ headers. We don't yet have a new enough version of python3 to use the
+ better glob function, so right now we assume the glob is '**/*.h'.
+
+ The function filters out any files that match the items in excludes.
+
+ Args:
+ prefix: The directory to recursively scan for headers.
+ rel_glob: The shell-style glob that identifies the header pattern.
+ excludes: A list of headers to exclude from the glob.
+ Return:
+ A list of headers discovered with excludes excluded.
+ """
+
+ # If we had python 3.5+, we could use the fancy new glob.glob.
+ # full_glob = os.path.join(prefix, rel_glob)
+ # full_srcs = glob.glob(full_glob, recursive=True)
+
+ full_dirs = [prefix]
+ full_srcs = []
+
+ while full_dirs:
+ full_dir = full_dirs.pop(0)
+ items = sorted(os.listdir(full_dir))
+
+ for item in items:
+ full_item = os.path.join(full_dir, item)
+
+ if os.path.isdir(full_item):
+ full_dirs.append(full_item)
+ continue
+
+ if full_item in excludes:
+ continue
+
+ if full_item.endswith('.h'):
+ full_srcs.append(full_item)
+
+ return full_srcs
+
+
+def find_out(verbose, module_dir, prefix, rel_glob, excludes, outs):
+ """Build a list of outputs for the genrule that creates kernel headers.
+
+ This function scans for headers in the source tree and produces a list of
+ output (generated) headers.
+
+ Args:
+ verbose: Set True to print progress messages.
+ module_dir: The root directory of the kernel source.
+ prefix: The prefix with in the kernel source tree to search for headers.
+ rel_glob: The pattern to use when matching headers under prefix.
+ excludes: A list of files to exclude from the glob.
+ outs: The list to populdate with the headers that will be generated.
+ Return:
+ The number of errors encountered.
+ """
+
+ # Turn prefix, which is relative to the soong module, to a full prefix that
+ # is relative to the Android source tree.
+
+ full_prefix = os.path.join(module_dir, prefix)
+
+ # Convert the list of excludes, which are relative to the soong module, to a
+ # set of excludes (for easy hashing), relative to the Android source tree.
+
+ full_excludes = set()
+
+ if excludes:
+ for exclude in excludes:
+ full_exclude = os.path.join(full_prefix, exclude)
+ full_excludes.add(full_exclude)
+
+ # Glob those headers.
+
+ full_srcs = glob_headers(full_prefix, rel_glob, full_excludes)
+
+ # Now convert the file names, which are relative to the Android source tree,
+ # to be relative to the gen dir. This means stripping off the module prefix
+ # and the directory within this module.
+
+ module_dir_sep = module_dir + os.sep
+ prefix_sep = prefix + os.sep
+
+ if verbose:
+ print('find_out: module_dir_sep [%s]' % module_dir_sep)
+ print('find_out: prefix_sep [%s]' % prefix_sep)
+
+ error_count = 0
+
+ for full_src in full_srcs:
+ if verbose:
+ print('find_out: full_src [%s]' % full_src)
+
+ if not full_src.startswith(module_dir_sep):
+ print('error: expected %s to start with %s' % (full_src, module_dir_sep))
+ error_count += 1
+ continue
+
+ local_src = full_src[len(module_dir_sep):]
+
+ if verbose:
+ print('find_out: local_src [%s]' % local_src)
+
+ if not local_src.startswith(prefix_sep):
+ print('error: expected %s to start with %s' % (local_src, prefix_sep))
+ error_count += 1
+ continue
+
+ # After stripping the module directory and the prefix, we're left with the
+ # name of a header that we'll generate, relative to the base of of a the
+ # the include path.
+
+ local_out = local_src[len(prefix_sep):]
+
+ if verbose:
+ print('find_out: local_out [%s]' % local_out)
+
+ outs.append(local_out)
+
+ return error_count
+
+def scan_no_export_headers(verbose, module_dir, prefix):
+ """Scan include/uapi kbuild for no-export-headers
+
+ This function processes the Kbuild file to scan for no-export files that
+ should not export to usr/include/uapi which is identified by adding
+ to the no-export-headers make variable.
+
+ Args:
+ verbose: Set True to print progress messages.
+ module_dir: The root directory of the kernel source.
+ prefix: The prefix with in the kernel source tree to search for headers.
+ Return:
+ lists of no-export-headers.
+ """
+
+ no_export_headers_re = re.compile(r'no-export-headers\s*\+=\s*(\S+)')
+ header_re = re.compile(r'include/uapi/')
+ full_dirs_ = os.path.join(module_dir, prefix)
+ full_dirs = [full_dirs_]
+
+ if verbose:
+ print('scan_no_export_headers: processing [%s]' % full_dirs)
+
+ full_srcs = []
+ no_export_headers_lists = []
+
+ while full_dirs:
+ full_dir = full_dirs.pop(0)
+ items = sorted(os.listdir(full_dir))
+
+ for item in items:
+ full_item = os.path.join(full_dir, item)
+
+ if os.path.isdir(full_item):
+ full_dirs.append(full_item)
+ continue
+
+ if (full_item.find('Kbuild') != -1):
+ full_srcs.append(full_item)
+
+ for full_src in full_srcs:
+ with open(full_src, 'r') as f:
+ while True:
+ line = f.readline()
+
+ if not line:
+ break
+
+ line = line.rstrip()
+
+ match = no_export_headers_re.match(line)
+
+ if match:
+ if verbose:
+ print('scan_no_export_headers: matched [%s]' % line)
+
+ if (match.group(1) == "kvm.h" or
+ match.group(1) == "kvm_para.h" or
+ match.group(1) == "a.out.h"):
+ continue
+
+ (full_src_dir_name, full_src_base_name) = full_src.split('include/uapi/')
+ no_export_header_file_name = os.path.join(os.path.dirname(full_src_base_name),match.group(1))
+
+ if verbose:
+ print('scan_no_export_headers: no_export_header_file_name = ',no_export_header_file_name)
+
+ no_export_headers_lists.append(no_export_header_file_name)
+ continue
+
+ if verbose:
+ for x in no_export_headers_lists:
+ print('scan_no_export_headers: no_export_headers_lists [%s]' % x)
+
+ return no_export_headers_lists
+
+def gen_blueprints(
+ verbose, header_arch, gen_dir, arch_asm_kbuild, asm_generic_kbuild, module_dir,
+ rel_arch_asm_kbuild, rel_asm_generic_kbuild, arch_include_uapi, techpack_include_uapi):
+ """Generate a blueprints file containing modules that invoke this script.
+
+ This function generates a blueprints file that contains modules that
+ invoke this script to generate kernel headers. We generate the blueprints
+ file as needed, but we don't actually use the generated file. The blueprints
+ file that we generate ends up in the out directory, and we can use it to
+ detect if the checked-in version of the file (in the source directory) is out
+ of date. This pattern occurs in the Android source tree in several places.
+
+ Args:
+ verbose: Set True to print progress messages.
+ header_arch: The arch for which to generate headers.
+ gen_dir: Where to place the generated files.
+ arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
+ asm_generic_kbuild: The Kbuild file containing lists of mandatory headers.
+ module_dir: The root directory of the kernel source.
+ rel_arch_asm_kbuild: arch_asm_kbuild relative to module_dir.
+ Return:
+ The number of errors encountered.
+ """
+ error_count = 0
+
+ # The old and new blueprints files. We generate the new one, but we need to
+ # refer to the old one in the modules that we generate.
+ old_gen_headers_bp = 'gen_headers_%s.bp' % header_arch
+ new_gen_headers_bp = os.path.join(gen_dir, old_gen_headers_bp)
+
+ # Tools and tool files.
+ headers_install_sh = 'headers_install.sh'
+ kernel_headers_py = 'kernel_headers.py'
+ arm_syscall_tool = 'arch/arm/tools/syscallhdr.sh'
+
+ # Sources
+ makefile = 'Makefile'
+ arm_syscall_tbl = 'arch/arm/tools/syscall.tbl'
+ rel_glob = '**/*.h'
+ generic_prefix = 'include/uapi'
+ arch_prefix = os.path.join('arch', header_arch, generic_prefix)
+ generic_src = os.path.join(generic_prefix, rel_glob)
+ arch_src = os.path.join(arch_prefix, rel_glob)
+ techpack_src = os.path.join('techpack/*',generic_prefix, '*',rel_glob)
+
+ # Excluded sources, architecture specific.
+ exclude_srcs = []
+
+ if header_arch == "arm":
+ exclude_srcs = ['linux/a.out.h']
+
+ if header_arch == "arm64":
+ exclude_srcs = ['linux/a.out.h', 'linux/kvm_para.h']
+
+ no_export_headers_lists = scan_no_export_headers(verbose, module_dir, generic_prefix)
+
+ for no_export_headers_list in no_export_headers_lists:
+ exclude_srcs.append(no_export_headers_list)
+
+ if verbose:
+ for x in exclude_srcs:
+ print('gen_blueprints : exclude_srcs [%s]' % x)
+
+ # Scan the arch_asm_kbuild file for files that need to be generated and those
+ # that are generic (i.e., need to be wrapped).
+
+ (generated_list, generic_list, mandatory_list) = scan_arch_kbuild(verbose,
+ arch_asm_kbuild, asm_generic_kbuild, arch_include_uapi)
+
+ generic_out = []
+ error_count += find_out(
+ verbose, module_dir, generic_prefix, rel_glob, exclude_srcs, generic_out)
+
+ arch_out = []
+ error_count += find_out(
+ verbose, module_dir, arch_prefix, rel_glob, None, arch_out)
+
+ techpack_out = [x.split('include/uapi/')[1] for x in techpack_include_uapi]
+
+ if error_count != 0:
+ return error_count
+
+ # Generate the blueprints file.
+
+ if verbose:
+ print('gen_blueprints: generating %s' % new_gen_headers_bp)
+
+ with open(new_gen_headers_bp, 'w') as f:
+ f.write('// ***** DO NOT EDIT *****\n')
+ f.write('// This file is generated by %s\n' % kernel_headers_py)
+ f.write('\n')
+ f.write('gen_headers_srcs_%s = [\n' % header_arch)
+ f.write(' "%s",\n' % rel_arch_asm_kbuild)
+ f.write(' "%s",\n' % rel_asm_generic_kbuild)
+ f.write(' "%s",\n' % makefile)
+
+ if header_arch == "arm":
+ f.write(' "%s",\n' % arm_syscall_tbl)
+
+ f.write(' "%s",\n' % generic_src)
+ f.write(' "%s",\n' % arch_src)
+ f.write(']\n')
+ f.write('\n')
+
+ if exclude_srcs:
+ f.write('gen_headers_exclude_srcs_%s = [\n' % header_arch)
+ for h in exclude_srcs:
+ f.write(' "%s",\n' % os.path.join(generic_prefix, h))
+ f.write(']\n')
+ f.write('\n')
+
+ f.write('gen_headers_out_%s = [\n' % header_arch)
+
+ if generated_list:
+ f.write('\n')
+ f.write(' // Matching generated-y:\n')
+ f.write('\n')
+ for h in generated_list:
+ f.write(' "asm/%s",\n' % h)
+
+ if generic_list:
+ f.write('\n')
+ f.write(' // Matching generic-y:\n')
+ f.write('\n')
+ for h in generic_list:
+ f.write(' "asm/%s",\n' % h)
+
+ if mandatory_list:
+ f.write('\n')
+ f.write(' // Matching mandatory-y:\n')
+ f.write('\n')
+ for h in mandatory_list:
+ f.write(' "asm/%s",\n' % h)
+
+ if generic_out:
+ f.write('\n')
+ f.write(' // From %s\n' % generic_src)
+ f.write('\n')
+ for h in generic_out:
+ f.write(' "%s",\n' % h)
+
+ if arch_out:
+ f.write('\n')
+ f.write(' // From %s\n' % arch_src)
+ f.write('\n')
+ for h in arch_out:
+ f.write(' "%s",\n' % h)
+
+ if techpack_out:
+ f.write('\n')
+ f.write(' // From %s\n' % techpack_src)
+ f.write('\n')
+ for h in techpack_out:
+ f.write(' "%s",\n' % h)
+
+ f.write(']\n')
+ f.write('\n')
+
+ gen_blueprints_module_name = 'qti_generate_gen_headers_%s' % header_arch
+
+ f.write('genrule {\n')
+ f.write(' // This module generates the gen_headers_<arch>.bp file\n')
+ f.write(' // (i.e., a new version of this file) so that it can be\n')
+ f.write(' // checked later to ensure that it matches the checked-\n')
+ f.write(' // in version (this file).\n')
+ f.write(' name: "%s",\n' % gen_blueprints_module_name)
+ f.write(' srcs: gen_headers_srcs_%s,\n' % header_arch)
+ if exclude_srcs:
+ f.write(' exclude_srcs: gen_headers_exclude_srcs_%s,\n' % header_arch)
+
+ f.write(' tool_files: ["kernel_headers.py"],\n')
+ f.write(' cmd: "python3 $(location kernel_headers.py) " +\n')
+ f.write(' kernel_headers_verbose +\n')
+ f.write(' "--header_arch %s " +\n' % header_arch)
+ f.write(' "--gen_dir $(genDir) " +\n')
+ f.write(' "--arch_asm_kbuild $(location %s) " +\n' % rel_arch_asm_kbuild)
+ f.write(' "--arch_include_uapi $(locations %s) " +\n' % arch_src)
+ f.write(' "--asm_generic_kbuild $(location %s) " +\n' % rel_asm_generic_kbuild)
+ f.write(' "blueprints " +\n')
+ f.write(' "# $(in)",\n')
+ f.write(' out: ["gen_headers_%s.bp"],\n' % header_arch)
+ f.write('}\n')
+ f.write('\n')
+
+ f.write('genrule {\n')
+ f.write(' name: "qti_generate_kernel_headers_%s",\n' % header_arch)
+ f.write(' tools: ["%s"],\n' % headers_install_sh)
+ f.write(' tool_files: [\n')
+ f.write(' "%s",\n' % kernel_headers_py)
+
+ if header_arch == "arm":
+ f.write(' "%s",\n' % arm_syscall_tool)
+
+ f.write(' ],\n')
+ f.write(' srcs: gen_headers_srcs_%s +[\n' % header_arch)
+ f.write(' "%s",\n' % old_gen_headers_bp)
+ f.write(' ":%s",\n' % gen_blueprints_module_name)
+ f.write(' ],\n')
+
+ if exclude_srcs:
+ f.write(' exclude_srcs: gen_headers_exclude_srcs_%s,\n' % header_arch)
+
+ f.write(' cmd: "python3 $(location %s) " +\n' % kernel_headers_py)
+ f.write(' kernel_headers_verbose +\n')
+ f.write(' "--header_arch %s " +\n' % header_arch)
+ f.write(' "--gen_dir $(genDir) " +\n')
+ f.write(' "--arch_asm_kbuild $(location %s) " +\n' % rel_arch_asm_kbuild)
+ f.write(' "--arch_include_uapi $(locations %s) " +\n' % arch_src)
+ f.write(' "--asm_generic_kbuild $(location %s) " +\n' % rel_asm_generic_kbuild)
+ f.write(' "headers " +\n')
+ f.write(' "--old_gen_headers_bp $(location %s) " +\n' % old_gen_headers_bp)
+ f.write(' "--new_gen_headers_bp $(location :%s) " +\n' % gen_blueprints_module_name)
+ f.write(' "--version_makefile $(location %s) " +\n' % makefile)
+
+ if header_arch == "arm":
+ f.write(' "--arch_syscall_tool $(location %s) " +\n' % arm_syscall_tool)
+ f.write(' "--arch_syscall_tbl $(location %s) " +\n' % arm_syscall_tbl)
+
+ f.write(' "--headers_install $(location %s) " +\n' % headers_install_sh)
+ f.write(' "--include_uapi $(locations %s)",\n' % generic_src)
+ f.write(' out: ["linux/version.h"] + gen_headers_out_%s,\n' % header_arch)
+ f.write('}\n')
+
+ return 0
+
+def parse_bp_for_headers(file_name, headers):
+ parsing_headers = False
+ pattern = re.compile("gen_headers_out_[a-zA-Z0-9]+\s*=\s*\[\s*")
+ with open(file_name, 'r') as f:
+ for line in f:
+ line = line.strip()
+ if pattern.match(line):
+ parsing_headers = True
+ continue
+
+ if line.find("]") != -1 and parsing_headers:
+ break
+
+ if not parsing_headers:
+ continue
+
+ if line.find("//") == 0:
+ continue
+
+ headers.add(line[1:-2])
+
+def headers_diff(old_file, new_file):
+ old_headers = set()
+ new_headers = set()
+ diff_detected = False
+
+ parse_bp_for_headers(old_file, old_headers)
+ parse_bp_for_headers(new_file, new_headers)
+
+ diff = old_headers - new_headers
+ if len(diff):
+ diff_detected = True
+ print("Headers to remove:")
+ for x in diff:
+ print("\t{}".format(x))
+
+ diff = new_headers - old_headers
+ if len(diff):
+ diff_detected = True
+ print("Headers to add:")
+ for x in diff:
+ print("\t{}".format(x))
+
+ return diff_detected
+
+def gen_headers(
+ verbose, header_arch, gen_dir, arch_asm_kbuild, asm_generic_kbuild, module_dir,
+ old_gen_headers_bp, new_gen_headers_bp, version_makefile,
+ arch_syscall_tool, arch_syscall_tbl, headers_install, include_uapi,
+ arch_include_uapi, techpack_include_uapi):
+ """Generate the kernel headers.
+
+ This script generates the version.h file, the arch-specific headers including
+ syscall-related generated files and wrappers around generic files, and uses
+ the headers_install tool to process other generic uapi and arch-specific uapi
+ files.
+
+ Args:
+ verbose: Set True to print progress messages.
+ header_arch: The arch for which to generate headers.
+ gen_dir: Where to place the generated files.
+ arch_asm_kbuild: The Kbuild file containing lists of headers to generate.
+ asm_generic_kbuild: The Kbuild file containing mandatory headers.
+ module_dir: The root directory of the kernel source.
+ old_gen_headers_bp: The old gen_headers_<arch>.bp file to check.
+ new_gen_headers_bp: The new gen_headers_<arch>.bp file to check.
+ version_makefile: The kernel Makefile that contains version info.
+ arch_syscall_tool: The arch script that generates syscall headers.
+ arch_syscall_tbl: The arch script that defines syscall vectors.
+ headers_install: The headers_install tool to process input headers.
+ include_uapi: The list of include/uapi header files.
+ arch_include_uapi: The list of arch/<arch>/include/uapi header files.
+ Return:
+ The number of errors encountered.
+ """
+
+ if headers_diff(old_gen_headers_bp, new_gen_headers_bp):
+ print('error: gen_headers blueprints file is out of date, suggested fix:')
+ print('#######Please add or remove the above mentioned headers from %s' % (old_gen_headers_bp))
+ print('then re-run the build')
+ return 1
+
+ error_count = 0
+
+ if not gen_version_h(verbose, gen_dir, version_makefile):
+ error_count += 1
+
+ error_count += gen_arch_headers(
+ verbose, gen_dir, arch_asm_kbuild, asm_generic_kbuild, arch_syscall_tool, arch_syscall_tbl ,arch_include_uapi)
+
+ uapi_include_prefix = os.path.join(module_dir, 'include', 'uapi') + os.sep
+
+ arch_uapi_include_prefix = os.path.join(
+ module_dir, 'arch', header_arch, 'include', 'uapi') + os.sep
+
+ for h in include_uapi:
+ if not run_headers_install(
+ verbose, gen_dir, headers_install,
+ uapi_include_prefix, h):
+ error_count += 1
+
+ for h in arch_include_uapi:
+ if not run_headers_install(
+ verbose, gen_dir, headers_install,
+ arch_uapi_include_prefix, h):
+ error_count += 1
+
+ for h in techpack_include_uapi:
+ techpack_uapi_include_prefix = os.path.join(h.split('/include/uapi')[0], 'include', 'uapi') + os.sep
+ if not run_headers_install(
+ verbose, gen_dir, headers_install,
+ techpack_uapi_include_prefix, h):
+ error_count += 1
+
+ return error_count
+
+def extract_techpack_uapi_headers(verbose, module_dir):
+
+ """EXtract list of uapi headers from techpack/* directories. We need to export
+ these headers to userspace.
+
+ Args:
+ verbose: Verbose option is provided to script
+ module_dir: Base directory
+ Returs:
+ List of uapi headers
+ """
+
+ techpack_subdir = []
+ techpack_dir = os.path.join(module_dir,'techpack')
+ techpack_uapi = []
+ techpack_uapi_sub = []
+
+ #get list of techpack directories under techpack/
+ if os.path.isdir(techpack_dir):
+ items = sorted(os.listdir(techpack_dir))
+ for x in items:
+ p = os.path.join(techpack_dir, x)
+ if os.path.isdir(p):
+ techpack_subdir.append(p)
+
+ #Print list of subdirs obtained
+ if (verbose):
+ for x in techpack_subdir:
+ print(x)
+
+ #For every subdirectory get list of .h files under include/uapi and append to techpack_uapi list
+ for x in techpack_subdir:
+ techpack_uapi_path = os.path.join(x, 'include/uapi')
+ if (os.path.isdir(techpack_uapi_path)):
+ techpack_uapi_sub = []
+ find_out(verbose, x, 'include/uapi', '**/*.h', None, techpack_uapi_sub)
+ tmp = [os.path.join(techpack_uapi_path, y) for y in techpack_uapi_sub]
+ techpack_uapi = techpack_uapi + tmp
+
+ if (verbose):
+ for x in techpack_uapi:
+ print(x)
+
+ return techpack_uapi
+
+def main():
+ """Parse command line arguments and perform top level control."""
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+
+ # Arguments that apply to every invocation of this script.
+
+ parser.add_argument(
+ '--verbose',
+ action='store_true',
+ help='Print output that describes the workings of this script.')
+ parser.add_argument(
+ '--header_arch',
+ required=True,
+ help='The arch for which to generate headers.')
+ parser.add_argument(
+ '--gen_dir',
+ required=True,
+ help='Where to place the generated files.')
+ parser.add_argument(
+ '--arch_asm_kbuild',
+ required=True,
+ help='The Kbuild file containing lists of headers to generate.')
+ parser.add_argument(
+ '--asm_generic_kbuild',
+ required=True,
+ help='The Kbuild file containing lists of mandatory headers.')
+ parser.add_argument(
+ '--arch_include_uapi',
+ required=True,
+ nargs='*',
+ help='The list of arch/<arch>/include/uapi header files.')
+
+ # The modes.
+
+ subparsers = parser.add_subparsers(
+ dest='mode',
+ help='Select mode')
+ parser_blueprints = subparsers.add_parser(
+ 'blueprints',
+ help='Generate the gen_headers_<arch>.bp file.')
+ parser_headers = subparsers.add_parser(
+ 'headers',
+ help='Check blueprints, then generate kernel headers.')
+
+ # Arguments that apply to headers mode.
+
+ parser_headers.add_argument(
+ '--old_gen_headers_bp',
+ required=True,
+ help='The old gen_headers_<arch>.bp file to check.')
+ parser_headers.add_argument(
+ '--new_gen_headers_bp',
+ required=True,
+ help='The new gen_headers_<arch>.bp file to check.')
+ parser_headers.add_argument(
+ '--version_makefile',
+ required=True,
+ help='The kernel Makefile that contains version info.')
+ parser_headers.add_argument(
+ '--arch_syscall_tool',
+ help='The arch script that generates syscall headers, if applicable.')
+ parser_headers.add_argument(
+ '--arch_syscall_tbl',
+ help='The arch script that defines syscall vectors, if applicable.')
+ parser_headers.add_argument(
+ '--headers_install',
+ required=True,
+ help='The headers_install tool to process input headers.')
+ parser_headers.add_argument(
+ '--include_uapi',
+ required=True,
+ nargs='*',
+ help='The list of include/uapi header files.')
+
+ args = parser.parse_args()
+
+ if args.verbose:
+ print('mode [%s]' % args.mode)
+ print('header_arch [%s]' % args.header_arch)
+ print('gen_dir [%s]' % args.gen_dir)
+ print('arch_asm_kbuild [%s]' % args.arch_asm_kbuild)
+ print('asm_generic_kbuild [%s]' % args.asm_generic_kbuild)
+
+ # Extract the module_dir from args.arch_asm_kbuild and rel_arch_asm_kbuild.
+
+ rel_arch_asm_kbuild = os.path.join(
+ 'arch', args.header_arch, 'include/uapi/asm/Kbuild')
+
+ suffix = os.sep + rel_arch_asm_kbuild
+
+ if not args.arch_asm_kbuild.endswith(suffix):
+ print('error: expected %s to end with %s' % (args.arch_asm_kbuild, suffix))
+ return 1
+
+ module_dir = args.arch_asm_kbuild[:-len(suffix)]
+
+ rel_asm_generic_kbuild = os.path.join('include/uapi/asm-generic', os.path.basename(args.asm_generic_kbuild))
+
+
+ if args.verbose:
+ print('module_dir [%s]' % module_dir)
+
+ techpack_include_uapi = []
+
+
+ if args.mode == 'blueprints':
+ return gen_blueprints(
+ args.verbose, args.header_arch, args.gen_dir, args.arch_asm_kbuild,
+ args.asm_generic_kbuild, module_dir, rel_arch_asm_kbuild, rel_asm_generic_kbuild, args.arch_include_uapi, techpack_include_uapi)
+
+ if args.mode == 'headers':
+ if args.verbose:
+ print('old_gen_headers_bp [%s]' % args.old_gen_headers_bp)
+ print('new_gen_headers_bp [%s]' % args.new_gen_headers_bp)
+ print('version_makefile [%s]' % args.version_makefile)
+ print('arch_syscall_tool [%s]' % args.arch_syscall_tool)
+ print('arch_syscall_tbl [%s]' % args.arch_syscall_tbl)
+ print('headers_install [%s]' % args.headers_install)
+
+ return gen_headers(
+ args.verbose, args.header_arch, args.gen_dir, args.arch_asm_kbuild,
+ args.asm_generic_kbuild, module_dir, args.old_gen_headers_bp, args.new_gen_headers_bp,
+ args.version_makefile, args.arch_syscall_tool, args.arch_syscall_tbl,
+ args.headers_install, args.include_uapi, args.arch_include_uapi, techpack_include_uapi)
+
+ print('error: unknown mode: %s' % args.mode)
+ return 1
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index a854cc3..ef8c14a 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -317,7 +317,7 @@
if (prv)
table->nents = ++table->orig_nents;
- return -ENOMEM;
+ return -ENOMEM;
}
sg_init_table(sg, alloc_size);
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index f87d138..759ff41 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -92,15 +92,19 @@
return true;
if (stack_slabs[depot_index] == NULL) {
stack_slabs[depot_index] = *prealloc;
+ *prealloc = NULL;
} else {
- stack_slabs[depot_index + 1] = *prealloc;
+ /* If this is the last depot slab, do not touch the next one. */
+ if (depot_index + 1 < STACK_ALLOC_MAX_SLABS) {
+ stack_slabs[depot_index + 1] = *prealloc;
+ *prealloc = NULL;
+ }
/*
* This smp_store_release pairs with smp_load_acquire() from
* |next_slab_inited| above and in depot_save_stack().
*/
smp_store_release(&next_slab_inited, 1);
}
- *prealloc = NULL;
return true;
}
diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 7cde4c1..c0b65e0 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -125,6 +125,7 @@
if (!ptr1 || !ptr2) {
pr_err("Allocation failed\n");
kfree(ptr1);
+ kfree(ptr2);
return;
}
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c319cd9..fad4a0c 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2096,7 +2096,7 @@
unsigned long flags;
pgoff_t end;
- VM_BUG_ON_PAGE(is_huge_zero_page(page), page);
+ VM_BUG_ON_PAGE(is_huge_zero_page(head), head);
VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(!PageSwapBacked(page), page);
VM_BUG_ON_PAGE(!PageCompound(page), page);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 0ec91c8..f8088c1 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3500,7 +3500,7 @@
struct mem_cgroup_thresholds *thresholds;
struct mem_cgroup_threshold_ary *new;
unsigned long usage;
- int i, j, size;
+ int i, j, size, entries;
mutex_lock(&memcg->thresholds_lock);
@@ -3520,14 +3520,20 @@
__mem_cgroup_threshold(memcg, type == _MEMSWAP);
/* Calculate new number of threshold */
- size = 0;
+ size = entries = 0;
for (i = 0; i < thresholds->primary->size; i++) {
if (thresholds->primary->entries[i].eventfd != eventfd)
size++;
+ else
+ entries++;
}
new = thresholds->spare;
+ /* If no items related to eventfd have been cleared, nothing to do */
+ if (!entries)
+ goto unlock;
+
/* Set thresholds array to NULL if we don't have thresholds */
if (!size) {
kfree(new);
@@ -5755,6 +5761,10 @@
return;
}
+ /* Do not associate the sock with unrelated interrupted task's memcg. */
+ if (in_interrupt())
+ return;
+
rcu_read_lock();
memcg = mem_cgroup_from_task(current);
if (memcg == root_mem_cgroup)
diff --git a/mm/nommu.c b/mm/nommu.c
index d033ee8..eaec7a6 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -445,10 +445,14 @@
EXPORT_SYMBOL_GPL(vm_unmap_aliases);
/*
- * Implement a stub for vmalloc_sync_all() if the architecture chose not to
- * have one.
+ * Implement a stub for vmalloc_sync_[un]mapping() if the architecture
+ * chose not to have one.
*/
-void __weak vmalloc_sync_all(void)
+void __weak vmalloc_sync_mappings(void)
+{
+}
+
+void __weak vmalloc_sync_unmappings(void)
{
}
diff --git a/mm/slub.c b/mm/slub.c
index fc12c5b..cae85b2 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1922,8 +1922,6 @@
if (node == NUMA_NO_NODE)
searchnode = numa_mem_id();
- else if (!node_present_pages(node))
- searchnode = node_to_mem_node(node);
object = get_partial_node(s, get_node(s, searchnode), c, flags);
if (object || node != NUMA_NO_NODE)
@@ -2519,17 +2517,27 @@
struct page *page;
page = c->page;
- if (!page)
+ if (!page) {
+ /*
+ * if the node is not online or has no normal memory, just
+ * ignore the node constraint
+ */
+ if (unlikely(node != NUMA_NO_NODE &&
+ !node_state(node, N_NORMAL_MEMORY)))
+ node = NUMA_NO_NODE;
goto new_slab;
+ }
redo:
if (unlikely(!node_match(page, node))) {
- int searchnode = node;
-
- if (node != NUMA_NO_NODE && !node_present_pages(node))
- searchnode = node_to_mem_node(node);
-
- if (unlikely(!node_match(page, searchnode))) {
+ /*
+ * same as above but node_match() being false already
+ * implies node != NUMA_NO_NODE
+ */
+ if (!node_state(node, N_NORMAL_MEMORY)) {
+ node = NUMA_NO_NODE;
+ goto redo;
+ } else {
stat(s, ALLOC_NODE_MISMATCH);
deactivate_slab(s, page, c->freelist);
c->page = NULL;
@@ -2948,11 +2956,13 @@
barrier();
if (likely(page == c->page)) {
- set_freepointer(s, tail_obj, c->freelist);
+ void **freelist = READ_ONCE(c->freelist);
+
+ set_freepointer(s, tail_obj, freelist);
if (unlikely(!this_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
- c->freelist, tid,
+ freelist, tid,
head, next_tid(tid)))) {
note_cmpxchg_failure("slab_free", s, tid);
@@ -3128,6 +3138,15 @@
if (unlikely(!object)) {
/*
+ * We may have removed an object from c->freelist using
+ * the fastpath in the previous iteration; in that case,
+ * c->tid has not been bumped yet.
+ * Since ___slab_alloc() may reenable interrupts while
+ * allocating memory, we should bump c->tid now.
+ */
+ c->tid = next_tid(c->tid);
+
+ /*
* Invoking slow path likely have side-effect
* of re-populating per CPU c->freelist
*/
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 75b8f85..5e6f7727 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1816,7 +1816,7 @@
* First make sure the mappings are removed from all page-tables
* before they are freed.
*/
- vmalloc_sync_all();
+ vmalloc_sync_unmappings();
/*
* In this function, newly allocated vm_struct has VM_UNINITIALIZED
@@ -2352,16 +2352,19 @@
EXPORT_SYMBOL(remap_vmalloc_range);
/*
- * Implement a stub for vmalloc_sync_all() if the architecture chose not to
- * have one.
+ * Implement stubs for vmalloc_sync_[un]mappings () if the architecture chose
+ * not to have one.
*
* The purpose of this function is to make sure the vmalloc area
* mappings are identical in all page-tables in the system.
*/
-void __weak vmalloc_sync_all(void)
+void __weak vmalloc_sync_mappings(void)
{
}
+void __weak vmalloc_sync_unmappings(void)
+{
+}
static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data)
{
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 780700f..2b66362 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -34,6 +34,7 @@
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
+#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/pkt_sched.h>
@@ -149,7 +150,7 @@
* Return: 0 on success, a negative error code otherwise.
*/
static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
- int max_if_num)
+ unsigned int max_if_num)
{
void *data_ptr;
size_t old_size;
@@ -193,7 +194,8 @@
*/
static void
batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
- int max_if_num, int del_if_num)
+ unsigned int max_if_num,
+ unsigned int del_if_num)
{
size_t chunk_size;
size_t if_offset;
@@ -231,7 +233,8 @@
*/
static void
batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
- int max_if_num, int del_if_num)
+ unsigned int max_if_num,
+ unsigned int del_if_num)
{
size_t if_offset;
void *data_ptr;
@@ -268,7 +271,8 @@
* Return: 0 on success, a negative error code otherwise.
*/
static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
- int max_if_num, int del_if_num)
+ unsigned int max_if_num,
+ unsigned int del_if_num)
{
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
@@ -302,7 +306,8 @@
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
{
struct batadv_orig_node *orig_node;
- int size, hash_added;
+ int hash_added;
+ size_t size;
orig_node = batadv_orig_hash_find(bat_priv, addr);
if (orig_node)
@@ -366,14 +371,18 @@
unsigned char *ogm_buff;
u32 random_seqno;
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+
/* randomize initial seqno to avoid collision */
get_random_bytes(&random_seqno, sizeof(random_seqno));
atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
- if (!ogm_buff)
+ if (!ogm_buff) {
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
return -ENOMEM;
+ }
hard_iface->bat_iv.ogm_buff = ogm_buff;
@@ -385,35 +394,59 @@
batadv_ogm_packet->reserved = 0;
batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+
return 0;
}
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
{
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+
kfree(hard_iface->bat_iv.ogm_buff);
hard_iface->bat_iv.ogm_buff = NULL;
+
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
{
struct batadv_ogm_packet *batadv_ogm_packet;
- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
+ void *ogm_buff;
- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+
+ ogm_buff = hard_iface->bat_iv.ogm_buff;
+ if (!ogm_buff)
+ goto unlock;
+
+ batadv_ogm_packet = ogm_buff;
ether_addr_copy(batadv_ogm_packet->orig,
hard_iface->net_dev->dev_addr);
ether_addr_copy(batadv_ogm_packet->prev_sender,
hard_iface->net_dev->dev_addr);
+
+unlock:
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
static void
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
{
struct batadv_ogm_packet *batadv_ogm_packet;
- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
+ void *ogm_buff;
- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+
+ ogm_buff = hard_iface->bat_iv.ogm_buff;
+ if (!ogm_buff)
+ goto unlock;
+
+ batadv_ogm_packet = ogm_buff;
batadv_ogm_packet->ttl = BATADV_TTL;
+
+unlock:
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
}
/* when do we schedule our own ogm to be sent */
@@ -898,7 +931,7 @@
u32 i;
size_t word_index;
u8 *w;
- int if_num;
+ unsigned int if_num;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -919,7 +952,11 @@
}
}
-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
+/**
+ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
+ * @hard_iface: interface whose ogm buffer should be transmitted
+ */
+static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
@@ -930,8 +967,10 @@
u16 tvlv_len = 0;
unsigned long send_time;
- if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
- (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
+ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
+
+ /* interface already disabled by batadv_iv_ogm_iface_disable */
+ if (!*ogm_buff)
return;
/* the interface gets activated here to avoid race conditions between
@@ -1000,6 +1039,17 @@
batadv_hardif_put(primary_if);
}
+static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
+{
+ if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
+ hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+ return;
+
+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+ batadv_iv_ogm_schedule_buff(hard_iface);
+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+}
+
/**
* batadv_iv_ogm_orig_update - use OGM to update corresponding data in an
* originator
@@ -1028,7 +1078,7 @@
struct batadv_neigh_node *tmp_neigh_node = NULL;
struct batadv_neigh_node *router = NULL;
struct batadv_orig_node *orig_node_tmp;
- int if_num;
+ unsigned int if_num;
u8 sum_orig, sum_neigh;
u8 *neigh_addr;
u8 tq_avg;
@@ -1186,7 +1236,7 @@
u8 total_count;
u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
- int if_num;
+ unsigned int if_num;
unsigned int tq_asym_penalty, inv_asym_penalty;
unsigned int combined_tq;
unsigned int tq_iface_penalty;
@@ -1227,7 +1277,7 @@
orig_node->last_seen = jiffies;
/* find packet count of corresponding one hop neighbor */
- spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
+ spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
if_num = if_incoming->if_num;
orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
@@ -1237,7 +1287,7 @@
} else {
neigh_rq_count = 0;
}
- spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
+ spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */
if (orig_eq_count > neigh_rq_count)
@@ -1705,9 +1755,9 @@
if (is_my_orig) {
unsigned long *word;
- int offset;
+ size_t offset;
s32 bit_pos;
- s16 if_num;
+ unsigned int if_num;
u8 *weight;
orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
@@ -2473,12 +2523,22 @@
return ret;
}
-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
+static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
{
/* begin scheduling originator messages on that interface */
batadv_iv_ogm_schedule(hard_iface);
}
+/**
+ * batadv_iv_init_sel_class - initialize GW selection class
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
+{
+ /* set default TQ difference threshold to 20 */
+ atomic_set(&bat_priv->gw.sel_class, 20);
+}
+
static struct batadv_gw_node *
batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
{
@@ -2803,8 +2863,8 @@
static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
.name = "BATMAN_IV",
.iface = {
- .activate = batadv_iv_iface_activate,
.enable = batadv_iv_ogm_iface_enable,
+ .enabled = batadv_iv_iface_enabled,
.disable = batadv_iv_ogm_iface_disable,
.update_mac = batadv_iv_ogm_iface_update_mac,
.primary_set = batadv_iv_ogm_primary_iface_set,
@@ -2827,6 +2887,7 @@
.del_if = batadv_iv_ogm_orig_del_if,
},
.gw = {
+ .init_sel_class = batadv_iv_init_sel_class,
.get_best_gw_node = batadv_iv_gw_get_best_gw_node,
.is_eligible = batadv_iv_gw_is_eligible,
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 4348118..18fa602 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -19,7 +19,6 @@
#include "main.h"
#include <linux/atomic.h>
-#include <linux/bug.h>
#include <linux/cache.h>
#include <linux/errno.h>
#include <linux/if_ether.h>
@@ -623,11 +622,11 @@
int ret = 0;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
- if (WARN_ON(!ifinfo1))
+ if (!ifinfo1)
goto err_ifinfo1;
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
- if (WARN_ON(!ifinfo2))
+ if (!ifinfo2)
goto err_ifinfo2;
ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
@@ -649,11 +648,11 @@
bool ret = false;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
- if (WARN_ON(!ifinfo1))
+ if (!ifinfo1)
goto err_ifinfo1;
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
- if (WARN_ON(!ifinfo2))
+ if (!ifinfo2)
goto err_ifinfo2;
threshold = ifinfo1->bat_v.throughput / 4;
@@ -668,6 +667,16 @@
return ret;
}
+/**
+ * batadv_v_init_sel_class - initialize GW selection class
+ * @bat_priv: the bat priv with all the soft interface information
+ */
+static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
+{
+ /* set default throughput difference threshold to 5Mbps */
+ atomic_set(&bat_priv->gw.sel_class, 50);
+}
+
static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv,
char *buff, size_t count)
{
@@ -805,7 +814,7 @@
}
orig_gw = batadv_gw_node_get(bat_priv, orig_node);
- if (!orig_node)
+ if (!orig_gw)
goto out;
if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)
@@ -1054,6 +1063,7 @@
.dump = batadv_v_orig_dump,
},
.gw = {
+ .init_sel_class = batadv_v_init_sel_class,
.store_sel_class = batadv_v_store_sel_class,
.show_sel_class = batadv_v_show_sel_class,
.get_best_gw_node = batadv_v_gw_get_best_gw_node,
@@ -1094,9 +1104,6 @@
if (ret < 0)
return ret;
- /* set default throughput difference threshold to 5Mbps */
- atomic_set(&bat_priv->gw.sel_class, 50);
-
return 0;
}
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 5d79004..62df763 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -19,6 +19,7 @@
#include "main.h"
#include <linux/atomic.h>
+#include <linux/bitops.h>
#include <linux/byteorder/generic.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@@ -29,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/netdevice.h>
+#include <linux/nl80211.h>
#include <linux/random.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -100,8 +102,12 @@
*/
return 0;
}
- if (!ret)
- return sinfo.expected_throughput / 100;
+ if (ret)
+ goto default_throughput;
+ if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)))
+ goto default_throughput;
+
+ return sinfo.expected_throughput / 100;
}
/* unsupported WiFi driver version */
@@ -185,6 +191,7 @@
struct sk_buff *skb;
int probe_len, i;
int elp_skb_len;
+ void *tmp;
/* this probing routine is for Wifi neighbours only */
if (!batadv_is_wifi_netdev(hard_iface->net_dev))
@@ -216,7 +223,8 @@
* the packet to be exactly of that size to make the link
* throughput estimation effective.
*/
- skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+ tmp = skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+ memset(tmp, 0, probe_len - hard_iface->bat_v.elp_skb->len);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Sending unicast (probe) ELP packet on interface %s to %pM\n",
@@ -327,21 +335,23 @@
*/
int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
{
+ static const size_t tvlv_padding = sizeof(__be32);
struct batadv_elp_packet *elp_packet;
unsigned char *elp_buff;
u32 random_seqno;
size_t size;
int res = -ENOMEM;
- size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN;
+ size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding;
hard_iface->bat_v.elp_skb = dev_alloc_skb(size);
if (!hard_iface->bat_v.elp_skb)
goto out;
skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
- elp_buff = skb_put(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
+ elp_buff = skb_put(hard_iface->bat_v.elp_skb,
+ BATADV_ELP_HLEN + tvlv_padding);
elp_packet = (struct batadv_elp_packet *)elp_buff;
- memset(elp_packet, 0, BATADV_ELP_HLEN);
+ memset(elp_packet, 0, BATADV_ELP_HLEN + tvlv_padding);
elp_packet->packet_type = BATADV_ELP;
elp_packet->version = BATADV_COMPAT_VERSION;
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index f435435..b0cae59 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -28,6 +28,8 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
+#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/random.h>
#include <linux/rculist.h>
@@ -127,22 +129,19 @@
}
/**
- * batadv_v_ogm_send - periodic worker broadcasting the own OGM
- * @work: work queue item
+ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
+ * @bat_priv: the bat priv with all the soft interface information
*/
-static void batadv_v_ogm_send(struct work_struct *work)
+static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
{
struct batadv_hard_iface *hard_iface;
- struct batadv_priv_bat_v *bat_v;
- struct batadv_priv *bat_priv;
struct batadv_ogm2_packet *ogm_packet;
struct sk_buff *skb, *skb_tmp;
unsigned char *ogm_buff, *pkt_buff;
int ogm_buff_len;
u16 tvlv_len = 0;
- bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
- bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
+ lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
goto out;
@@ -210,6 +209,23 @@
}
/**
+ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
+ * @work: work queue item
+ */
+static void batadv_v_ogm_send(struct work_struct *work)
+{
+ struct batadv_priv_bat_v *bat_v;
+ struct batadv_priv *bat_priv;
+
+ bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+ bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
+
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+ batadv_v_ogm_send_softif(bat_priv);
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+}
+
+/**
* batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V
* @hard_iface: the interface to prepare
*
@@ -235,11 +251,15 @@
struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
struct batadv_ogm2_packet *ogm_packet;
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
if (!bat_priv->bat_v.ogm_buff)
- return;
+ goto unlock;
ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
+
+unlock:
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}
/**
@@ -827,6 +847,8 @@
atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
+ mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
+
return 0;
}
@@ -838,7 +860,11 @@
{
cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+
kfree(bat_priv->bat_v.ogm_buff);
bat_priv->bat_v.ogm_buff = NULL;
bat_priv->bat_v.ogm_buff_len = 0;
+
+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index b4ffba7dd..e0ab277 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -18,6 +18,7 @@
#include "debugfs.h"
#include "main.h"
+#include <linux/dcache.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/errno.h>
@@ -340,6 +341,25 @@
}
/**
+ * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif
+ * @hard_iface: hard interface which was renamed
+ */
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
+{
+ const char *name = hard_iface->net_dev->name;
+ struct dentry *dir;
+ struct dentry *d;
+
+ dir = hard_iface->debug_dir;
+ if (!dir)
+ return;
+
+ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
+ if (!d)
+ pr_err("Can't rename debugfs dir to %s\n", name);
+}
+
+/**
* batadv_debugfs_del_hardif - delete the base directory for a hard interface
* in debugfs.
* @hard_iface: hard interface which is deleted.
@@ -403,6 +423,26 @@
return -ENOMEM;
}
+/**
+ * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif
+ * @dev: net_device which was renamed
+ */
+void batadv_debugfs_rename_meshif(struct net_device *dev)
+{
+ struct batadv_priv *bat_priv = netdev_priv(dev);
+ const char *name = dev->name;
+ struct dentry *dir;
+ struct dentry *d;
+
+ dir = bat_priv->debug_dir;
+ if (!dir)
+ return;
+
+ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
+ if (!d)
+ pr_err("Can't rename debugfs dir to %s\n", name);
+}
+
void batadv_debugfs_del_meshif(struct net_device *dev)
{
struct batadv_priv *bat_priv = netdev_priv(dev);
diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h
index e49121e..59a0d6d 100644
--- a/net/batman-adv/debugfs.h
+++ b/net/batman-adv/debugfs.h
@@ -29,8 +29,10 @@
void batadv_debugfs_init(void);
void batadv_debugfs_destroy(void);
int batadv_debugfs_add_meshif(struct net_device *dev);
+void batadv_debugfs_rename_meshif(struct net_device *dev);
void batadv_debugfs_del_meshif(struct net_device *dev);
int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface);
#else
@@ -48,6 +50,10 @@
return 0;
}
+static inline void batadv_debugfs_rename_meshif(struct net_device *dev)
+{
+}
+
static inline void batadv_debugfs_del_meshif(struct net_device *dev)
{
}
@@ -59,6 +65,11 @@
}
static inline
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
+{
+}
+
+static inline
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface)
{
}
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 3b440b8..83c7009 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -1025,8 +1025,9 @@
skb_reset_mac_header(skb_new);
skb_new->protocol = eth_type_trans(skb_new,
bat_priv->soft_iface);
- bat_priv->stats.rx_packets++;
- bat_priv->stats.rx_bytes += skb->len + ETH_HLEN + hdr_size;
+ batadv_inc_counter(bat_priv, BATADV_CNT_RX);
+ batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
+ skb->len + ETH_HLEN + hdr_size);
bat_priv->soft_iface->last_rx = jiffies;
netif_rx(skb_new);
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index a06b604..fef21f7 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -232,8 +232,10 @@
spin_unlock_bh(&chain->lock);
err:
- if (!ret)
+ if (!ret) {
kfree(frag_entry_new);
+ kfree_skb(skb);
+ }
return ret;
}
@@ -305,7 +307,7 @@
*
* There are three possible outcomes: 1) Packet is merged: Return true and
* set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
- * to NULL; 3) Error: Return false and leave skb as is.
+ * to NULL; 3) Error: Return false and free skb.
*
* Return: true when packet is merged or buffered, false when skb is not not
* used.
@@ -330,9 +332,9 @@
goto out_err;
out:
- *skb = skb_out;
ret = true;
out_err:
+ *skb = skb_out;
return ret;
}
@@ -482,12 +484,20 @@
*/
if (skb->priority >= 256 && skb->priority <= 263)
frag_header.priority = skb->priority - 256;
+ else
+ frag_header.priority = 0;
ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
ether_addr_copy(frag_header.dest, orig_node->orig);
/* Eat and send fragments from the tail of skb */
while (skb->len > max_fragment_size) {
+ /* The initial check in this function should cover this case */
+ if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
+ ret = -1;
+ goto out;
+ }
+
skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
if (!skb_fragment)
goto out;
@@ -505,12 +515,6 @@
}
frag_header.no++;
-
- /* The initial check in this function should cover this case */
- if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
- ret = -1;
- goto out;
- }
}
/* Make room for the fragment header. */
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index ed9aaf3..3bd7ed6 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -31,6 +31,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/rculist.h>
@@ -325,6 +326,9 @@
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: originator announcing gateway capabilities
* @gateway: announced bandwidth information
+ *
+ * Has to be called with the appropriate locks being acquired
+ * (gw.list_lock).
*/
static void batadv_gw_node_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
@@ -332,6 +336,8 @@
{
struct batadv_gw_node *gw_node;
+ lockdep_assert_held(&bat_priv->gw.list_lock);
+
if (gateway->bandwidth_down == 0)
return;
@@ -346,10 +352,8 @@
gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
- spin_lock_bh(&bat_priv->gw.list_lock);
kref_get(&gw_node->refcount);
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
- spin_unlock_bh(&bat_priv->gw.list_lock);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -404,11 +408,14 @@
{
struct batadv_gw_node *gw_node, *curr_gw = NULL;
+ spin_lock_bh(&bat_priv->gw.list_lock);
gw_node = batadv_gw_node_get(bat_priv, orig_node);
if (!gw_node) {
batadv_gw_node_add(bat_priv, orig_node, gateway);
+ spin_unlock_bh(&bat_priv->gw.list_lock);
goto out;
}
+ spin_unlock_bh(&bat_priv->gw.list_lock);
if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
(gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 2118481..3e3f91a 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -253,6 +253,11 @@
*/
void batadv_gw_init(struct batadv_priv *bat_priv)
{
+ if (bat_priv->algo_ops->gw.init_sel_class)
+ bat_priv->algo_ops->gw.init_sel_class(bat_priv);
+ else
+ atomic_set(&bat_priv->gw.sel_class, 1);
+
batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
NULL, BATADV_TVLV_GW, 1,
BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 8f7883b..f528761 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/printk.h>
#include <linux/rculist.h>
@@ -539,6 +540,11 @@
hard_iface->soft_iface = soft_iface;
bat_priv = netdev_priv(hard_iface->soft_iface);
+ if (bat_priv->num_ifaces >= UINT_MAX) {
+ ret = -ENOSPC;
+ goto err_dev;
+ }
+
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
soft_iface, NULL, NULL);
if (ret)
@@ -591,6 +597,9 @@
batadv_hardif_recalc_extra_skbroom(soft_iface);
+ if (bat_priv->algo_ops->iface.enabled)
+ bat_priv->algo_ops->iface.enabled(hard_iface);
+
out:
return 0;
@@ -646,7 +655,7 @@
batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
/* nobody uses this interface anymore */
- if (!bat_priv->num_ifaces) {
+ if (bat_priv->num_ifaces == 0) {
batadv_gw_check_client_stop(bat_priv);
if (autodel == BATADV_IF_CLEANUP_AUTO)
@@ -682,7 +691,7 @@
if (ret)
goto free_if;
- hard_iface->if_num = -1;
+ hard_iface->if_num = 0;
hard_iface->net_dev = net_dev;
hard_iface->soft_iface = NULL;
hard_iface->if_status = BATADV_IF_NOT_IN_USE;
@@ -694,6 +703,7 @@
INIT_LIST_HEAD(&hard_iface->list);
INIT_HLIST_HEAD(&hard_iface->neigh_list);
+ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
spin_lock_init(&hard_iface->neigh_list_lock);
kref_init(&hard_iface->refcount);
@@ -750,6 +760,32 @@
rtnl_unlock();
}
+/**
+ * batadv_hard_if_event_softif() - Handle events for soft interfaces
+ * @event: NETDEV_* event to handle
+ * @net_dev: net_device which generated an event
+ *
+ * Return: NOTIFY_* result
+ */
+static int batadv_hard_if_event_softif(unsigned long event,
+ struct net_device *net_dev)
+{
+ struct batadv_priv *bat_priv;
+
+ switch (event) {
+ case NETDEV_REGISTER:
+ batadv_sysfs_add_meshif(net_dev);
+ bat_priv = netdev_priv(net_dev);
+ batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
+ break;
+ case NETDEV_CHANGENAME:
+ batadv_debugfs_rename_meshif(net_dev);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
static int batadv_hard_if_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -758,12 +794,8 @@
struct batadv_hard_iface *primary_if = NULL;
struct batadv_priv *bat_priv;
- if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
- batadv_sysfs_add_meshif(net_dev);
- bat_priv = netdev_priv(net_dev);
- batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
- return NOTIFY_DONE;
- }
+ if (batadv_softif_is_valid(net_dev))
+ return batadv_hard_if_event_softif(event, net_dev);
hard_iface = batadv_hardif_get_by_netdev(net_dev);
if (!hard_iface && (event == NETDEV_REGISTER ||
@@ -807,6 +839,9 @@
if (hard_iface == primary_if)
batadv_primary_if_update_addr(bat_priv, NULL);
break;
+ case NETDEV_CHANGENAME:
+ batadv_debugfs_rename_hardif(hard_iface);
+ break;
default:
break;
}
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 7c8d160..8466f83 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -1495,7 +1495,7 @@
}
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
- int max_if_num)
+ unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_algo_ops *bao = bat_priv->algo_ops;
@@ -1530,7 +1530,7 @@
}
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
- int max_if_num)
+ unsigned int max_if_num)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index ebc5618..fab0b2c 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -78,9 +78,9 @@
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
- int max_if_num);
+ unsigned int max_if_num);
int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
- int max_if_num);
+ unsigned int max_if_num);
struct batadv_orig_node_vlan *
batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
unsigned short vid);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 8b98609..19059ae 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -930,7 +930,6 @@
bool is4addr;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
- unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
/* the caller function should have already pulled 2 bytes */
@@ -951,9 +950,13 @@
if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
return NET_RX_DROP;
+ unicast_packet = (struct batadv_unicast_packet *)skb->data;
+
/* packet for me */
if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
if (is4addr) {
+ unicast_4addr_packet =
+ (struct batadv_unicast_4addr_packet *)skb->data;
subtype = unicast_4addr_packet->subtype;
batadv_dat_inc_counter(bat_priv, subtype);
@@ -1080,6 +1083,12 @@
batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX);
batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len);
+ /* batadv_frag_skb_buffer will always consume the skb and
+ * the caller should therefore never try to free the
+ * skb after this point
+ */
+ ret = NET_RX_SUCCESS;
+
/* Add fragment to buffer and merge if possible. */
if (!batadv_frag_skb_buffer(&skb, orig_node_src))
goto out;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index a92512a46..99d2c45 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -808,7 +808,6 @@
atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0);
#endif
atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF);
- atomic_set(&bat_priv->gw.sel_class, 20);
atomic_set(&bat_priv->gw.bandwidth_down, 100);
atomic_set(&bat_priv->gw.bandwidth_up, 20);
atomic_set(&bat_priv->orig_interval, 1000);
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 1fab9bc..d40d839 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -867,7 +867,7 @@
struct batadv_orig_node_vlan *vlan;
u8 *tt_change_ptr;
- rcu_read_lock();
+ spin_lock_bh(&orig_node->vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
num_vlan++;
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -905,7 +905,7 @@
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
- rcu_read_unlock();
+ spin_unlock_bh(&orig_node->vlan_list_lock);
return tvlv_len;
}
@@ -936,15 +936,20 @@
struct batadv_tvlv_tt_vlan_data *tt_vlan;
struct batadv_softif_vlan *vlan;
u16 num_vlan = 0;
- u16 num_entries = 0;
+ u16 vlan_entries = 0;
+ u16 total_entries = 0;
u16 tvlv_len;
u8 *tt_change_ptr;
int change_offset;
- rcu_read_lock();
+ spin_lock_bh(&bat_priv->softif_vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ vlan_entries = atomic_read(&vlan->tt.num_entries);
+ if (vlan_entries < 1)
+ continue;
+
num_vlan++;
- num_entries += atomic_read(&vlan->tt.num_entries);
+ total_entries += vlan_entries;
}
change_offset = sizeof(**tt_data);
@@ -952,7 +957,7 @@
/* if tt_len is negative, allocate the space needed by the full table */
if (*tt_len < 0)
- *tt_len = batadv_tt_len(num_entries);
+ *tt_len = batadv_tt_len(total_entries);
tvlv_len = *tt_len;
tvlv_len += change_offset;
@@ -969,6 +974,10 @@
tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ vlan_entries = atomic_read(&vlan->tt.num_entries);
+ if (vlan_entries < 1)
+ continue;
+
tt_vlan->vid = htons(vlan->vid);
tt_vlan->crc = htonl(vlan->tt.crc);
@@ -979,7 +988,7 @@
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
- rcu_read_unlock();
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
return tvlv_len;
}
@@ -1539,6 +1548,8 @@
* by a given originator
* @entry: the TT global entry to check
* @orig_node: the originator to search in the list
+ * @flags: a pointer to store TT flags for the given @entry received
+ * from @orig_node
*
* find out if an orig_node is already in the list of a tt_global_entry.
*
@@ -1546,7 +1557,8 @@
*/
static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
- const struct batadv_orig_node *orig_node)
+ const struct batadv_orig_node *orig_node,
+ u8 *flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
bool found = false;
@@ -1554,15 +1566,51 @@
orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
if (orig_entry) {
found = true;
+
+ if (flags)
+ *flags = orig_entry->flags;
+
batadv_tt_orig_list_entry_put(orig_entry);
}
return found;
}
+/**
+ * batadv_tt_global_sync_flags - update TT sync flags
+ * @tt_global: the TT global entry to update sync flags in
+ *
+ * Updates the sync flag bits in the tt_global flag attribute with a logical
+ * OR of all sync flags from any of its TT orig entries.
+ */
+static void
+batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
+{
+ struct batadv_tt_orig_list_entry *orig_entry;
+ const struct hlist_head *head;
+ u16 flags = BATADV_NO_FLAGS;
+
+ rcu_read_lock();
+ head = &tt_global->orig_list;
+ hlist_for_each_entry_rcu(orig_entry, head, list)
+ flags |= orig_entry->flags;
+ rcu_read_unlock();
+
+ flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
+ tt_global->common.flags = flags;
+}
+
+/**
+ * batadv_tt_global_orig_entry_add - add or update a TT orig entry
+ * @tt_global: the TT global entry to add an orig entry in
+ * @orig_node: the originator to add an orig entry for
+ * @ttvn: translation table version number of this changeset
+ * @flags: TT sync flags
+ */
static void
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
- struct batadv_orig_node *orig_node, int ttvn)
+ struct batadv_orig_node *orig_node, int ttvn,
+ u8 flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
@@ -1574,7 +1622,8 @@
* was added during a "temporary client detection"
*/
orig_entry->ttvn = ttvn;
- goto out;
+ orig_entry->flags = flags;
+ goto sync_flags;
}
orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
@@ -1586,6 +1635,7 @@
batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
orig_entry->orig_node = orig_node;
orig_entry->ttvn = ttvn;
+ orig_entry->flags = flags;
kref_init(&orig_entry->refcount);
kref_get(&orig_entry->refcount);
@@ -1593,6 +1643,8 @@
&tt_global->orig_list);
atomic_inc(&tt_global->orig_list_count);
+sync_flags:
+ batadv_tt_global_sync_flags(tt_global);
out:
if (orig_entry)
batadv_tt_orig_list_entry_put(orig_entry);
@@ -1656,7 +1708,9 @@
ether_addr_copy(common->addr, tt_addr);
common->vid = vid;
- common->flags = flags;
+ if (!is_multicast_ether_addr(common->addr))
+ common->flags = flags & (~BATADV_TT_SYNC_MASK);
+
tt_global_entry->roam_at = 0;
/* node must store current time in case of roaming. This is
* needed to purge this entry out on timeout (if nobody claims
@@ -1698,7 +1752,7 @@
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
goto out;
if (batadv_tt_global_entry_has_orig(tt_global_entry,
- orig_node))
+ orig_node, NULL))
goto out_remove;
batadv_tt_global_del_orig_list(tt_global_entry);
goto add_orig_entry;
@@ -1716,10 +1770,11 @@
}
/* the change can carry possible "attribute" flags like the
- * TT_CLIENT_WIFI, therefore they have to be copied in the
+ * TT_CLIENT_TEMP, therefore they have to be copied in the
* client entry
*/
- common->flags |= flags;
+ if (!is_multicast_ether_addr(common->addr))
+ common->flags |= flags & (~BATADV_TT_SYNC_MASK);
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a
@@ -1736,7 +1791,8 @@
}
add_orig_entry:
/* add the new orig_entry (if needed) or update it */
- batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
+ batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
+ flags & BATADV_TT_SYNC_MASK);
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Creating new global tt entry: %pM (vid: %d, via %pM)\n",
@@ -1959,6 +2015,7 @@
struct batadv_tt_orig_list_entry *orig,
bool best)
{
+ u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags;
void *hdr;
struct batadv_orig_node_vlan *vlan;
u8 last_ttvn;
@@ -1988,7 +2045,7 @@
nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) ||
nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
- nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags))
+ nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags))
goto nla_put_failure;
if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
@@ -2602,6 +2659,7 @@
unsigned short vid)
{
struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+ struct batadv_tt_orig_list_entry *tt_orig;
struct batadv_tt_common_entry *tt_common;
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
@@ -2640,8 +2698,9 @@
/* find out if this global entry is announced by this
* originator
*/
- if (!batadv_tt_global_entry_has_orig(tt_global,
- orig_node))
+ tt_orig = batadv_tt_global_orig_entry_find(tt_global,
+ orig_node);
+ if (!tt_orig)
continue;
/* use network order to read the VID: this ensures that
@@ -2653,10 +2712,12 @@
/* compute the CRC on flags that have to be kept in sync
* among nodes
*/
- flags = tt_common->flags & BATADV_TT_SYNC_MASK;
+ flags = tt_orig->flags;
crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
+
+ batadv_tt_orig_list_entry_put(tt_orig);
}
rcu_read_unlock();
}
@@ -2834,23 +2895,46 @@
}
/**
- * batadv_tt_local_valid - verify that given tt entry is a valid one
+ * batadv_tt_local_valid() - verify local tt entry and get flags
* @entry_ptr: to be checked local tt entry
* @data_ptr: not used but definition required to satisfy the callback prototype
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given local TT entry. If it is, then the provided
+ * flags pointer is updated.
*
* Return: true if the entry is a valid, false otherwise.
*/
-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
+static bool batadv_tt_local_valid(const void *entry_ptr,
+ const void *data_ptr,
+ u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
return false;
+
+ if (flags)
+ *flags = tt_common_entry->flags;
+
return true;
}
+/**
+ * batadv_tt_global_valid() - verify global tt entry and get flags
+ * @entry_ptr: to be checked global tt entry
+ * @data_ptr: an orig_node object (may be NULL)
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given global TT entry. If it is, then the provided
+ * flags pointer is updated either with the common (summed) TT flags if data_ptr
+ * is NULL or the specific, per originator TT flags otherwise.
+ *
+ * Return: true if the entry is a valid, false otherwise.
+ */
static bool batadv_tt_global_valid(const void *entry_ptr,
- const void *data_ptr)
+ const void *data_ptr,
+ u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
const struct batadv_tt_global_entry *tt_global_entry;
@@ -2864,7 +2948,8 @@
struct batadv_tt_global_entry,
common);
- return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
+ return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
+ flags);
}
/**
@@ -2874,25 +2959,34 @@
* @hash: hash table containing the tt entries
* @tt_len: expected tvlv tt data buffer length in number of bytes
* @tvlv_buff: pointer to the buffer to fill with the TT data
- * @valid_cb: function to filter tt change entries
+ * @valid_cb: function to filter tt change entries and to return TT flags
* @cb_data: data passed to the filter function as argument
+ *
+ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
+ * is not provided then this becomes a no-op.
*/
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
struct batadv_hashtable *hash,
void *tvlv_buff, u16 tt_len,
bool (*valid_cb)(const void *,
- const void *),
+ const void *,
+ u8 *flags),
void *cb_data)
{
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tvlv_tt_change *tt_change;
struct hlist_head *head;
u16 tt_tot, tt_num_entries = 0;
+ u8 flags;
+ bool ret;
u32 i;
tt_tot = batadv_tt_entries(tt_len);
tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
+ if (!valid_cb)
+ return;
+
rcu_read_lock();
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -2902,11 +2996,12 @@
if (tt_tot == tt_num_entries)
break;
- if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
+ ret = valid_cb(tt_common_entry, cb_data, &flags);
+ if (!ret)
continue;
ether_addr_copy(tt_change->addr, tt_common_entry->addr);
- tt_change->flags = tt_common_entry->flags;
+ tt_change->flags = flags;
tt_change->vid = htons(tt_common_entry->vid);
memset(tt_change->reserved, 0,
sizeof(tt_change->reserved));
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index b3dd1a3..c17b74e 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -27,6 +27,7 @@
#include <linux/compiler.h>
#include <linux/if_ether.h>
#include <linux/kref.h>
+#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/sched.h> /* for linux/wait.h */
@@ -81,11 +82,13 @@
* @ogm_buff: buffer holding the OGM packet
* @ogm_buff_len: length of the OGM packet buffer
* @ogm_seqno: OGM sequence number - used to identify each OGM
+ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
*/
struct batadv_hard_iface_bat_iv {
unsigned char *ogm_buff;
int ogm_buff_len;
atomic_t ogm_seqno;
+ struct mutex ogm_buff_mutex;
};
/**
@@ -139,7 +142,7 @@
*/
struct batadv_hard_iface {
struct list_head list;
- s16 if_num;
+ unsigned int if_num;
char if_status;
struct net_device *net_dev;
u8 num_bcasts;
@@ -966,12 +969,14 @@
* @ogm_buff: buffer holding the OGM packet
* @ogm_buff_len: length of the OGM packet buffer
* @ogm_seqno: OGM sequence number - used to identify each OGM
+ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
* @ogm_wq: workqueue used to schedule OGM transmissions
*/
struct batadv_priv_bat_v {
unsigned char *ogm_buff;
int ogm_buff_len;
atomic_t ogm_seqno;
+ struct mutex ogm_buff_mutex;
struct delayed_work ogm_wq;
};
@@ -1060,7 +1065,7 @@
atomic_t bcast_seqno;
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
- char num_ifaces;
+ unsigned int num_ifaces;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
@@ -1241,6 +1246,7 @@
* struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client
* @orig_node: pointer to orig node announcing this non-mesh client
* @ttvn: translation table version number which added the non-mesh client
+ * @flags: per orig entry TT sync flags
* @list: list node for batadv_tt_global_entry::orig_list
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
@@ -1248,6 +1254,7 @@
struct batadv_tt_orig_list_entry {
struct batadv_orig_node *orig_node;
u8 ttvn;
+ u8 flags;
struct hlist_node list;
struct kref refcount;
struct rcu_head rcu;
@@ -1397,6 +1404,7 @@
* @activate: start routing mechanisms when hard-interface is brought up
* (optional)
* @enable: init routing info when hard-interface is enabled
+ * @enabled: notification when hard-interface was enabled (optional)
* @disable: de-init routing info when hard-interface is disabled
* @update_mac: (re-)init mac addresses of the protocol information
* belonging to this hard-interface
@@ -1405,6 +1413,7 @@
struct batadv_algo_iface_ops {
void (*activate)(struct batadv_hard_iface *hard_iface);
int (*enable)(struct batadv_hard_iface *hard_iface);
+ void (*enabled)(struct batadv_hard_iface *hard_iface);
void (*disable)(struct batadv_hard_iface *hard_iface);
void (*update_mac)(struct batadv_hard_iface *hard_iface);
void (*primary_set)(struct batadv_hard_iface *hard_iface);
@@ -1452,9 +1461,10 @@
*/
struct batadv_algo_orig_ops {
void (*free)(struct batadv_orig_node *orig_node);
- int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
- int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
- int del_if_num);
+ int (*add_if)(struct batadv_orig_node *orig_node,
+ unsigned int max_if_num);
+ int (*del_if)(struct batadv_orig_node *orig_node,
+ unsigned int max_if_num, unsigned int del_if_num);
#ifdef CONFIG_BATMAN_ADV_DEBUGFS
void (*print)(struct batadv_priv *priv, struct seq_file *seq,
struct batadv_hard_iface *hard_iface);
@@ -1466,6 +1476,7 @@
/**
* struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific)
+ * @init_sel_class: initialize GW selection class (optional)
* @store_sel_class: parse and stores a new GW selection class (optional)
* @show_sel_class: prints the current GW selection class (optional)
* @get_best_gw_node: select the best GW from the list of available nodes
@@ -1476,6 +1487,7 @@
* @dump: dump gateways to a netlink socket (optional)
*/
struct batadv_algo_gw_ops {
+ void (*init_sel_class)(struct batadv_priv *bat_priv);
ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff,
size_t count);
ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff);
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 31c4041..955fc01 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -714,7 +714,7 @@
frh = nlmsg_data(nlh);
frh->family = ops->family;
- frh->table = rule->table;
+ frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT;
if (nla_put_u32(skb, FRA_TABLE, rule->table))
goto nla_put_failure;
if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen))
diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c
index 2e4eef7..db65b0c 100644
--- a/net/core/netclassid_cgroup.c
+++ b/net/core/netclassid_cgroup.c
@@ -55,30 +55,60 @@
kfree(css_cls_state(css));
}
+/*
+ * To avoid freezing of sockets creation for tasks with big number of threads
+ * and opened sockets lets release file_lock every 1000 iterated descriptors.
+ * New sockets will already have been created with new classid.
+ */
+
+struct update_classid_context {
+ u32 classid;
+ unsigned int batch;
+};
+
+#define UPDATE_CLASSID_BATCH 1000
+
static int update_classid_sock(const void *v, struct file *file, unsigned n)
{
int err;
+ struct update_classid_context *ctx = (void *)v;
struct socket *sock = sock_from_file(file, &err);
if (sock) {
spin_lock(&cgroup_sk_update_lock);
- sock_cgroup_set_classid(&sock->sk->sk_cgrp_data,
- (unsigned long)v);
+ sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid);
spin_unlock(&cgroup_sk_update_lock);
}
+ if (--ctx->batch == 0) {
+ ctx->batch = UPDATE_CLASSID_BATCH;
+ return n + 1;
+ }
return 0;
}
+static void update_classid_task(struct task_struct *p, u32 classid)
+{
+ struct update_classid_context ctx = {
+ .classid = classid,
+ .batch = UPDATE_CLASSID_BATCH
+ };
+ unsigned int fd = 0;
+
+ do {
+ task_lock(p);
+ fd = iterate_fd(p->files, fd, update_classid_sock, &ctx);
+ task_unlock(p);
+ cond_resched();
+ } while (fd);
+}
+
static void cgrp_attach(struct cgroup_taskset *tset)
{
struct cgroup_subsys_state *css;
struct task_struct *p;
cgroup_taskset_for_each(p, css, tset) {
- task_lock(p);
- iterate_fd(p->files, 0, update_classid_sock,
- (void *)(unsigned long)css_cls_state(css)->classid);
- task_unlock(p);
+ update_classid_task(p, css_cls_state(css)->classid);
}
}
@@ -100,10 +130,7 @@
css_task_iter_start(css, &it);
while ((p = css_task_iter_next(&it))) {
- task_lock(p);
- iterate_fd(p->files, 0, update_classid_sock,
- (void *)(unsigned long)cs->classid);
- task_unlock(p);
+ update_classid_task(p, cs->classid);
cond_resched();
}
css_task_iter_end(&it);
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index 21bffde..76d55a8 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -84,6 +84,8 @@
brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
brcm_tag[3] = (1 << p->port) & BRCM_IG_DSTMAP1_MASK;
+ skb->offload_fwd_mark = 1;
+
return skb;
out_free:
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
index 6705420..d720658 100644
--- a/net/hsr/hsr_framereg.c
+++ b/net/hsr/hsr_framereg.c
@@ -468,13 +468,9 @@
struct hsr_port *port;
unsigned long tdiff;
-
- rcu_read_lock();
node = find_node_by_AddrA(&hsr->node_db, addr);
- if (!node) {
- rcu_read_unlock();
- return -ENOENT; /* No such entry */
- }
+ if (!node)
+ return -ENOENT;
ether_addr_copy(addr_b, node->MacAddressB);
@@ -509,7 +505,5 @@
*addr_b_ifindex = -1;
}
- rcu_read_unlock();
-
return 0;
}
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index d4d1617..4f869d0 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -137,6 +137,7 @@
.name = "HSR",
.version = 1,
.maxattr = HSR_A_MAX,
+ .netnsok = true,
};
static const struct genl_multicast_group hsr_mcgrps[] = {
@@ -264,17 +265,16 @@
if (!na)
goto invalid;
- hsr_dev = __dev_get_by_index(genl_info_net(info),
- nla_get_u32(info->attrs[HSR_A_IFINDEX]));
+ rcu_read_lock();
+ hsr_dev = dev_get_by_index_rcu(genl_info_net(info),
+ nla_get_u32(info->attrs[HSR_A_IFINDEX]));
if (!hsr_dev)
- goto invalid;
+ goto rcu_unlock;
if (!is_hsr_master(hsr_dev))
- goto invalid;
-
+ goto rcu_unlock;
/* Send reply */
-
- skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
if (!skb_out) {
res = -ENOMEM;
goto fail;
@@ -326,12 +326,10 @@
res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq);
if (res < 0)
goto nla_put_failure;
- rcu_read_lock();
port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
if (port)
res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX,
port->dev->ifindex);
- rcu_read_unlock();
if (res < 0)
goto nla_put_failure;
@@ -341,20 +339,22 @@
res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq);
if (res < 0)
goto nla_put_failure;
- rcu_read_lock();
port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
if (port)
res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX,
port->dev->ifindex);
- rcu_read_unlock();
if (res < 0)
goto nla_put_failure;
+ rcu_read_unlock();
+
genlmsg_end(skb_out, msg_head);
genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);
return 0;
+rcu_unlock:
+ rcu_read_unlock();
invalid:
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
return 0;
@@ -364,6 +364,7 @@
/* Fall through */
fail:
+ rcu_read_unlock();
return res;
}
@@ -371,16 +372,14 @@
*/
static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
{
- /* For receiving */
- struct nlattr *na;
- struct net_device *hsr_dev;
-
- /* For sending */
- struct sk_buff *skb_out;
- void *msg_head;
- struct hsr_priv *hsr;
- void *pos;
unsigned char addr[ETH_ALEN];
+ struct net_device *hsr_dev;
+ struct sk_buff *skb_out;
+ struct hsr_priv *hsr;
+ bool restart = false;
+ struct nlattr *na;
+ void *pos = NULL;
+ void *msg_head;
int res;
if (!info)
@@ -390,17 +389,17 @@
if (!na)
goto invalid;
- hsr_dev = __dev_get_by_index(genl_info_net(info),
- nla_get_u32(info->attrs[HSR_A_IFINDEX]));
+ rcu_read_lock();
+ hsr_dev = dev_get_by_index_rcu(genl_info_net(info),
+ nla_get_u32(info->attrs[HSR_A_IFINDEX]));
if (!hsr_dev)
- goto invalid;
+ goto rcu_unlock;
if (!is_hsr_master(hsr_dev))
- goto invalid;
+ goto rcu_unlock;
-
+restart:
/* Send reply */
-
- skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ skb_out = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (!skb_out) {
res = -ENOMEM;
goto fail;
@@ -414,18 +413,26 @@
goto nla_put_failure;
}
- res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
- if (res < 0)
- goto nla_put_failure;
+ if (!restart) {
+ res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
+ if (res < 0)
+ goto nla_put_failure;
+ }
hsr = netdev_priv(hsr_dev);
- rcu_read_lock();
- pos = hsr_get_next_node(hsr, NULL, addr);
+ if (!pos)
+ pos = hsr_get_next_node(hsr, NULL, addr);
while (pos) {
res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr);
if (res < 0) {
- rcu_read_unlock();
+ if (res == -EMSGSIZE) {
+ genlmsg_end(skb_out, msg_head);
+ genlmsg_unicast(genl_info_net(info), skb_out,
+ info->snd_portid);
+ restart = true;
+ goto restart;
+ }
goto nla_put_failure;
}
pos = hsr_get_next_node(hsr, pos, addr);
@@ -437,15 +444,18 @@
return 0;
+rcu_unlock:
+ rcu_read_unlock();
invalid:
netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL);
return 0;
nla_put_failure:
- kfree_skb(skb_out);
+ nlmsg_free(skb_out);
/* Fall through */
fail:
+ rcu_read_unlock();
return res;
}
diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
index f5b6038..3d94f54 100644
--- a/net/hsr/hsr_slave.c
+++ b/net/hsr/hsr_slave.c
@@ -31,6 +31,8 @@
rcu_read_lock(); /* hsr->node_db, hsr->ports */
port = hsr_port_get_rcu(skb->dev);
+ if (!port)
+ goto finish_pass;
if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) {
/* Directly kill frames sent by ourselves */
@@ -149,16 +151,16 @@
if (port == NULL)
return -ENOMEM;
+ port->hsr = hsr;
+ port->dev = dev;
+ port->type = type;
+
if (type != HSR_PT_MASTER) {
res = hsr_portdev_setup(dev, port);
if (res)
goto fail_dev_setup;
}
- port->hsr = hsr;
- port->dev = dev;
- port->type = type;
-
list_add_tail_rcu(&port->port_list, &hsr->ports);
synchronize_rcu();
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index 35c4326..040983f 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -30,7 +30,13 @@
[IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, },
[IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, },
[IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_BCN_ORD] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_SF_ORD] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_PAN_COORD] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_BAT_EXT] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_COORD_REALIGN] = { .type = NLA_U8, },
[IEEE802154_ATTR_PAGE] = { .type = NLA_U8, },
+ [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, },
[IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, },
[IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, },
[IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, },
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 0e5571d..90f1024 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2793,6 +2793,33 @@
hdr->control_flag, hdr->src_node_id,
hdr->src_port_id, hdr->dst_node_id,
hdr->dst_port_id);
+ /**
+ * update forwarding port information as well in routing
+ * table which will help to cleanup clients/services
+ * running in modem when MSM goes down
+ */
+ rport_ptr = ipc_router_get_rport_ref(hdr->src_node_id,
+ hdr->src_port_id);
+ if (!rport_ptr) {
+ rport_ptr =
+ ipc_router_create_rport(hdr->src_node_id,
+ hdr->src_port_id,
+ xprt_info);
+ if (!rport_ptr) {
+ IPC_RTR_ERR(
+ "%s: Rmt Prt %08x:%08x create failed\n",
+ __func__, hdr->src_node_id,
+ hdr->src_port_id);
+ }
+ }
+ /**
+ * just to fail safe check is added, if rport
+ * allocation failed above we still forward the
+ * packet to remote.
+ */
+ if (rport_ptr)
+ kref_put(&rport_ptr->ref,
+ ipc_router_release_rport);
forward_msg(xprt_info, pkt);
goto read_next_pkt1;
}
@@ -3545,16 +3572,6 @@
ipc_router_destroy_rport(rport_ptr);
}
- if (port_ptr->type == SERVER_PORT) {
- memset(&msg, 0, sizeof(msg));
- msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
- msg.srv.service = port_ptr->port_name.service;
- msg.srv.instance = port_ptr->port_name.instance;
- msg.srv.node_id = port_ptr->this_port.node_id;
- msg.srv.port_id = port_ptr->this_port.port_id;
- broadcast_ctl_msg(&msg);
- }
-
/* Server port could have been a client port earlier.
* Send REMOVE_CLIENT message in either case.
*/
@@ -3584,6 +3601,19 @@
port_ptr->this_port.node_id,
port_ptr->this_port.port_id);
}
+ /**
+ * released server information from hash table, now
+ * it is safe to broadcast remove server message so that
+ * next call to lookup server will not succeed until
+ * server open the port again
+ */
+ memset(&msg, 0, sizeof(msg));
+ msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
+ msg.srv.service = port_ptr->port_name.service;
+ msg.srv.instance = port_ptr->port_name.instance;
+ msg.srv.node_id = port_ptr->this_port.node_id;
+ msg.srv.port_id = port_ptr->this_port.port_id;
+ broadcast_ctl_msg(&msg);
}
mutex_lock(&port_ptr->port_lock_lhc3);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index b54b3ca..4d265d4 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -298,6 +298,7 @@
config NET_IPVTI
tristate "Virtual (secure) IP: tunneling"
+ depends on IPV6 || IPV6=n
select INET_TUNNEL
select NET_IP_TUNNEL
depends on INET_XFRM_MODE_TUNNEL
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 71bcab9..0a6f727 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1738,6 +1738,7 @@
{
unsigned char optbuf[sizeof(struct ip_options) + 40];
struct ip_options *opt = (struct ip_options *)optbuf;
+ int res;
if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES)
return;
@@ -1749,7 +1750,11 @@
memset(opt, 0, sizeof(struct ip_options));
opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr);
- if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL))
+ rcu_read_lock();
+ res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL);
+ rcu_read_unlock();
+
+ if (res)
return;
if (gateway)
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c
index 7efe740..4a5e55e 100644
--- a/net/ipv4/gre_demux.c
+++ b/net/ipv4/gre_demux.c
@@ -60,7 +60,9 @@
}
EXPORT_SYMBOL_GPL(gre_del_protocol);
-/* Fills in tpi and returns header length to be pulled. */
+/* Fills in tpi and returns header length to be pulled.
+ * Note that caller must use pskb_may_pull() before pulling GRE header.
+ */
int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
bool *csum_err, __be16 proto, int nhs)
{
@@ -114,8 +116,14 @@
* - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
*/
if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) {
+ u8 _val, *val;
+
+ val = skb_header_pointer(skb, nhs + hdr_len,
+ sizeof(_val), &_val);
+ if (!val)
+ return -EINVAL;
tpi->proto = proto;
- if ((*(u8 *)options & 0xF0) != 0x40)
+ if ((*val & 0xF0) != 0x40)
hdr_len += 4;
}
tpi->hdr_len = hdr_len;
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index ec41715..58e0dab 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -208,17 +208,39 @@
int mtu;
if (!dst) {
- struct rtable *rt;
+ switch (skb->protocol) {
+ case htons(ETH_P_IP): {
+ struct rtable *rt;
- fl->u.ip4.flowi4_oif = dev->ifindex;
- fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
- rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
- if (IS_ERR(rt)) {
+ fl->u.ip4.flowi4_oif = dev->ifindex;
+ fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
+ rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
+ if (IS_ERR(rt)) {
+ dev->stats.tx_carrier_errors++;
+ goto tx_error_icmp;
+ }
+ dst = &rt->dst;
+ skb_dst_set(skb, dst);
+ break;
+ }
+#if IS_ENABLED(CONFIG_IPV6)
+ case htons(ETH_P_IPV6):
+ fl->u.ip6.flowi6_oif = dev->ifindex;
+ fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
+ dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
+ if (dst->error) {
+ dst_release(dst);
+ dst = NULL;
+ dev->stats.tx_carrier_errors++;
+ goto tx_error_icmp;
+ }
+ skb_dst_set(skb, dst);
+ break;
+#endif
+ default:
dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
- dst = &rt->dst;
- skb_dst_set(skb, dst);
}
dst_hold(dst);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index cbfa4fd..3b99f09 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -995,21 +995,22 @@
static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
{
struct dst_entry *dst = &rt->dst;
+ u32 old_mtu = ipv4_mtu(dst);
struct fib_result res;
bool lock = false;
if (ip_mtu_locked(dst))
return;
- if (ipv4_mtu(dst) < mtu)
+ if (old_mtu < mtu)
return;
if (mtu < ip_rt_min_pmtu) {
lock = true;
- mtu = ip_rt_min_pmtu;
+ mtu = min(old_mtu, ip_rt_min_pmtu);
}
- if (rt->rt_pmtu == mtu &&
+ if (rt->rt_pmtu == mtu && !lock &&
time_before(jiffies, dst->expires - ip_rt_mtu_expires / 2))
return;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2fd3998..3fabbb5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2330,9 +2330,11 @@
tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
tp->snd_cwnd_cnt = 0;
tp->window_clamp = 0;
+ tp->delivered = 0;
tcp_set_ca_state(sk, TCP_CA_Open);
tp->is_sack_reneg = 0;
tcp_clear_retrans(tp);
+ tp->total_retrans = 0;
inet_csk_delack_init(sk);
/* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
* issue in __tcp_select_window()
@@ -2344,8 +2346,12 @@
dst_release(sk->sk_rx_dst);
sk->sk_rx_dst = NULL;
tcp_saved_syn_free(tp);
+ tp->segs_in = 0;
+ tp->segs_out = 0;
tp->bytes_acked = 0;
tp->bytes_received = 0;
+ tp->data_segs_in = 0;
+ tp->data_segs_out = 0;
/* Clean up fastopen related fields */
tcp_free_fastopen_req(tp);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 162b0e3..016efd3 100755
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3236,6 +3236,10 @@
(dev->type != ARPHRD_NONE) &&
(dev->type != ARPHRD_RAWIP)) {
/* Alas, we support only Ethernet autoconfiguration. */
+ idev = __in6_dev_get(dev);
+ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP &&
+ dev->flags & IFF_MULTICAST)
+ ipv6_mc_up(idev);
return;
}
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 7ba9a6e..f03855d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -784,8 +784,7 @@
found++;
break;
}
- if (rt_can_ecmp)
- fallback_ins = fallback_ins ?: ins;
+ fallback_ins = fallback_ins ?: ins;
goto next_iter;
}
@@ -825,7 +824,9 @@
}
if (fallback_ins && !found) {
- /* No ECMP-able route found, replace first non-ECMP one */
+ /* No matching route with same ecmp-able-ness found, replace
+ * first matching route
+ */
ins = fallback_ins;
iter = *ins;
found++;
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 9fbb735..365f445 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -315,7 +315,7 @@
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
rcu_read_unlock();
- return 0;
+ goto discard;
}
ipv6h = ipv6_hdr(skb);
@@ -454,15 +454,33 @@
int mtu;
if (!dst) {
- fl->u.ip6.flowi6_oif = dev->ifindex;
- fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
- dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
- if (dst->error) {
- dst_release(dst);
- dst = NULL;
+ switch (skb->protocol) {
+ case htons(ETH_P_IP): {
+ struct rtable *rt;
+
+ fl->u.ip4.flowi4_oif = dev->ifindex;
+ fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
+ rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
+ if (IS_ERR(rt))
+ goto tx_err_link_failure;
+ dst = &rt->dst;
+ skb_dst_set(skb, dst);
+ break;
+ }
+ case htons(ETH_P_IPV6):
+ fl->u.ip6.flowi6_oif = dev->ifindex;
+ fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
+ dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
+ if (dst->error) {
+ dst_release(dst);
+ dst = NULL;
+ goto tx_err_link_failure;
+ }
+ skb_dst_set(skb, dst);
+ break;
+ default:
goto tx_err_link_failure;
}
- skb_dst_set(skb, dst);
}
dst_hold(dst);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 81fd35e..1080770 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -184,9 +184,15 @@
retv = -EBUSY;
break;
}
- } else if (sk->sk_protocol != IPPROTO_TCP)
+ } else if (sk->sk_protocol == IPPROTO_TCP) {
+ if (sk->sk_prot != &tcpv6_prot) {
+ retv = -EBUSY;
+ break;
+ }
break;
-
+ } else {
+ break;
+ }
if (sk->sk_state != TCP_ESTABLISHED) {
retv = -ENOTCONN;
break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 8ab4668..300fb16 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -197,6 +197,7 @@
return opt->nd_opt_type == ND_OPT_RDNSS ||
opt->nd_opt_type == ND_OPT_DNSSL ||
opt->nd_opt_type == ND_OPT_CAPTIVE_PORTAL ||
+ opt->nd_opt_type == ND_OPT_PREF64 ||
ndisc_ops_is_useropt(dev, opt->nd_opt_type);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4f808aa..c1f007a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3035,6 +3035,7 @@
*/
cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL |
NLM_F_REPLACE);
+ cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE;
nhn++;
}
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 5f4c228..f7eaa10 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1131,7 +1131,8 @@
}
}
- if (!(mpath->flags & MESH_PATH_RESOLVING))
+ if (!(mpath->flags & MESH_PATH_RESOLVING) &&
+ mesh_path_sel_is_hwmp(sdata))
mesh_queue_preq(mpath, PREQ_Q_F_START);
if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 74652eb..a6f2652 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3841,7 +3841,7 @@
lockdep_assert_held(&local->sta_mtx);
- list_for_each_entry_rcu(sta, &local->sta_list, list) {
+ list_for_each_entry(sta, &local->sta_list, list) {
if (sdata != sta->sdata &&
(!sta->sdata->bss || sta->sdata->bss != sdata->bss))
continue;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c800bc7..4f7061c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -3,6 +3,7 @@
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2016 Intel Deutschland GmbH
+ * Copyright (C) 2018-2020 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -945,6 +946,11 @@
might_sleep();
lockdep_assert_held(&local->sta_mtx);
+ while (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
+ ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+ WARN_ON_ONCE(ret);
+ }
+
/* now keys can no longer be reached */
ieee80211_free_sta_keys(local, sta);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index f8de166..850264f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3412,8 +3412,26 @@
tx.skb = skb;
tx.sdata = vif_to_sdata(info->control.vif);
- if (txq->sta)
+ if (txq->sta) {
tx.sta = container_of(txq->sta, struct sta_info, sta);
+ /*
+ * Drop unicast frames to unauthorised stations unless they are
+ * EAPOL frames from the local station.
+ */
+ if (unlikely(ieee80211_is_data(hdr->frame_control) &&
+ !ieee80211_vif_is_mesh(&tx.sdata->vif) &&
+ tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
+ !is_multicast_ether_addr(hdr->addr1) &&
+ !test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) &&
+ (!(info->control.flags &
+ IEEE80211_TX_CTRL_PORT_CTRL_PROTO) ||
+ !ether_addr_equal(tx.sdata->vif.addr,
+ hdr->addr2)))) {
+ I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
+ ieee80211_free_txskb(&local->hw, skb);
+ goto begin;
+ }
+ }
/*
* The key can be removed while the packet was queued, so need to call
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0bb144c..9dff794 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -943,16 +943,22 @@
elem_parse_failed = true;
break;
case WLAN_EID_VHT_OPERATION:
- if (elen >= sizeof(struct ieee80211_vht_operation))
+ if (elen >= sizeof(struct ieee80211_vht_operation)) {
elems->vht_operation = (void *)pos;
- else
- elem_parse_failed = true;
+ if (calc_crc)
+ crc = crc32_be(crc, pos - 2, elen + 2);
+ break;
+ }
+ elem_parse_failed = true;
break;
case WLAN_EID_OPMODE_NOTIF:
- if (elen > 0)
+ if (elen > 0) {
elems->opmode_notif = pos;
- else
- elem_parse_failed = true;
+ if (calc_crc)
+ crc = crc32_be(crc, pos - 2, elen + 2);
+ break;
+ }
+ elem_parse_failed = true;
break;
case WLAN_EID_MESH_ID:
elems->mesh_id = pos;
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index 3f49912..8396dc8 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -711,6 +711,8 @@
[NFCTH_NAME] = { .type = NLA_NUL_STRING,
.len = NF_CT_HELPER_NAME_LEN-1 },
[NFCTH_QUEUE_NUM] = { .type = NLA_U32, },
+ [NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, },
+ [NFCTH_STATUS] = { .type = NLA_U32, },
};
static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {
diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
index 763ebc3..f93047f9 100644
--- a/net/netfilter/nft_fwd_netdev.c
+++ b/net/netfilter/nft_fwd_netdev.c
@@ -62,6 +62,13 @@
return -1;
}
+static int nft_fwd_validate(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nft_data **data)
+{
+ return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS));
+}
+
static struct nft_expr_type nft_fwd_netdev_type;
static const struct nft_expr_ops nft_fwd_netdev_ops = {
.type = &nft_fwd_netdev_type,
@@ -69,6 +76,7 @@
.eval = nft_fwd_netdev_eval,
.init = nft_fwd_netdev_init,
.dump = nft_fwd_netdev_dump,
+ .validate = nft_fwd_validate,
};
static struct nft_expr_type nft_fwd_netdev_type __read_mostly = {
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index a1a29cd..140a9ae2 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -735,6 +735,8 @@
return hashlimit_mt_common(skb, par, hinfo, &info->cfg, 2);
}
+#define HASHLIMIT_MAX_SIZE 1048576
+
static int hashlimit_mt_check_common(const struct xt_mtchk_param *par,
struct xt_hashlimit_htable **hinfo,
struct hashlimit_cfg2 *cfg,
@@ -745,6 +747,14 @@
if (cfg->gc_interval == 0 || cfg->expire == 0)
return -EINVAL;
+ if (cfg->size > HASHLIMIT_MAX_SIZE) {
+ cfg->size = HASHLIMIT_MAX_SIZE;
+ pr_info_ratelimited("size too large, truncated to %u\n", cfg->size);
+ }
+ if (cfg->max > HASHLIMIT_MAX_SIZE) {
+ cfg->max = HASHLIMIT_MAX_SIZE;
+ pr_info_ratelimited("max too large, truncated to %u\n", cfg->max);
+ }
if (par->family == NFPROTO_IPV4) {
if (cfg->srcmask > 32 || cfg->dstmask > 32)
return -EINVAL;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0254874..2058652 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1003,7 +1003,8 @@
if (nlk->netlink_bind && groups) {
int group;
- for (group = 0; group < nlk->ngroups; group++) {
+ /* nl_groups is a u32, so cap the maximum groups we can bind */
+ for (group = 0; group < BITS_PER_TYPE(u32); group++) {
if (!test_bit(group, &groups))
continue;
err = nlk->netlink_bind(net, group + 1);
@@ -1022,7 +1023,7 @@
netlink_insert(sk, nladdr->nl_pid) :
netlink_autobind(sock);
if (err) {
- netlink_undo_bind(nlk->ngroups, groups, sk);
+ netlink_undo_bind(BITS_PER_TYPE(u32), groups, sk);
return err;
}
}
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c
index 5a58f9f..291f24f 100644
--- a/net/nfc/hci/core.c
+++ b/net/nfc/hci/core.c
@@ -193,13 +193,20 @@
void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
struct sk_buff *skb)
{
- u8 gate = hdev->pipes[pipe].gate;
u8 status = NFC_HCI_ANY_OK;
struct hci_create_pipe_resp *create_info;
struct hci_delete_pipe_noti *delete_info;
struct hci_all_pipe_cleared_noti *cleared_info;
+ u8 gate;
- pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd);
+ pr_debug("from pipe %x cmd %x\n", pipe, cmd);
+
+ if (pipe >= NFC_HCI_MAX_PIPES) {
+ status = NFC_HCI_ANY_E_NOK;
+ goto exit;
+ }
+
+ gate = hdev->pipes[pipe].gate;
switch (cmd) {
case NFC_HCI_ADM_NOTIFY_PIPE_CREATED:
@@ -387,8 +394,14 @@
struct sk_buff *skb)
{
int r = 0;
- u8 gate = hdev->pipes[pipe].gate;
+ u8 gate;
+ if (pipe >= NFC_HCI_MAX_PIPES) {
+ pr_err("Discarded event %x to invalid pipe %x\n", event, pipe);
+ goto exit;
+ }
+
+ gate = hdev->pipes[pipe].gate;
if (gate == NFC_HCI_INVALID_GATE) {
pr_err("Discarded event %x to unopened pipe %x\n", event, pipe);
goto exit;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index d3c8dd5..e79a49f 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -62,7 +62,10 @@
[NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
[NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING,
.len = NFC_FIRMWARE_NAME_MAXSIZE },
+ [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 },
[NFC_ATTR_SE_APDU] = { .type = NLA_BINARY },
+ [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 },
+ [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
[NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
};
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index ee930b3..a419201 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -26,18 +26,6 @@
#define QRTR_MIN_EPH_SOCKET 0x4000
#define QRTR_MAX_EPH_SOCKET 0x7fff
-enum qrtr_pkt_type {
- QRTR_TYPE_DATA = 1,
- QRTR_TYPE_HELLO = 2,
- QRTR_TYPE_BYE = 3,
- QRTR_TYPE_NEW_SERVER = 4,
- QRTR_TYPE_DEL_SERVER = 5,
- QRTR_TYPE_DEL_CLIENT = 6,
- QRTR_TYPE_RESUME_TX = 7,
- QRTR_TYPE_EXIT = 8,
- QRTR_TYPE_PING = 9,
-};
-
/**
* struct qrtr_hdr - (I|R)PCrouter packet header
* @version: protocol version
@@ -61,8 +49,6 @@
} __packed;
#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
-#define QRTR_NODE_BCAST ((unsigned int)-1)
-#define QRTR_PORT_CTRL ((unsigned int)-2)
struct qrtr_sock {
/* WARNING: sk must be the first member */
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index f60e355..d6a6477 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -401,6 +401,7 @@
RXRPC_CALL_SEND_PING, /* A ping will need to be sent */
RXRPC_CALL_PINGING, /* Ping in process */
RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */
+ RXRPC_CALL_DISCONNECTED, /* The call has been disconnected */
};
/*
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index 1ed18d8..88bcd14 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -464,7 +464,7 @@
_debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, conn);
- if (conn)
+ if (conn && !test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
rxrpc_disconnect_call(call);
for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
@@ -539,6 +539,7 @@
{
struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
+ rxrpc_put_connection(call->conn);
rxrpc_put_peer(call->peer);
kfree(call->rxtx_buffer);
kfree(call->rxtx_annotations);
@@ -560,7 +561,6 @@
ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
- ASSERTCMP(call->conn, ==, NULL);
/* Clean up the Rx/Tx buffer */
for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++)
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index 0fce919..dd41733 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -736,9 +736,9 @@
struct rxrpc_channel *chan = &conn->channels[channel];
trace_rxrpc_client(conn, channel, rxrpc_client_chan_disconnect);
- call->conn = NULL;
spin_lock(&conn->channel_lock);
+ set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
/* Calls that have never actually been assigned a channel can simply be
* discarded. If the conn didn't get used either, it will follow
@@ -828,7 +828,6 @@
spin_unlock(&rxrpc_client_conn_cache_lock);
out_2:
spin_unlock(&conn->channel_lock);
- rxrpc_put_connection(conn);
_leave("");
return;
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index e1e83af..e7c89b9 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -211,9 +211,8 @@
__rxrpc_disconnect_call(conn, call);
spin_unlock(&conn->channel_lock);
- call->conn = NULL;
+ set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
conn->idle_timestamp = jiffies;
- rxrpc_put_connection(conn);
}
/*
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index a4380e1..f0ccc6a 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -582,8 +582,7 @@
immediate_ack, true,
rxrpc_propose_ack_input_data);
- if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1)
- rxrpc_notify_socket(call);
+ rxrpc_notify_socket(call);
_leave(" [queued]");
}
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 64389f4..d568c96 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -96,7 +96,7 @@
*/
int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping)
{
- struct rxrpc_connection *conn = NULL;
+ struct rxrpc_connection *conn;
struct rxrpc_ack_buffer *pkt;
struct msghdr msg;
struct kvec iov[2];
@@ -106,18 +106,14 @@
int ret;
u8 reason;
- spin_lock_bh(&call->lock);
- if (call->conn)
- conn = rxrpc_get_connection_maybe(call->conn);
- spin_unlock_bh(&call->lock);
- if (!conn)
+ if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
return -ECONNRESET;
pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
- if (!pkt) {
- rxrpc_put_connection(conn);
+ if (!pkt)
return -ENOMEM;
- }
+
+ conn = call->conn;
msg.msg_name = &call->peer->srx.transport;
msg.msg_namelen = call->peer->srx.transport_len;
@@ -204,7 +200,6 @@
}
out:
- rxrpc_put_connection(conn);
kfree(pkt);
return ret;
}
@@ -214,20 +209,18 @@
*/
int rxrpc_send_abort_packet(struct rxrpc_call *call)
{
- struct rxrpc_connection *conn = NULL;
+ struct rxrpc_connection *conn;
struct rxrpc_abort_buffer pkt;
struct msghdr msg;
struct kvec iov[1];
rxrpc_serial_t serial;
int ret;
- spin_lock_bh(&call->lock);
- if (call->conn)
- conn = rxrpc_get_connection_maybe(call->conn);
- spin_unlock_bh(&call->lock);
- if (!conn)
+ if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
return -ECONNRESET;
+ conn = call->conn;
+
msg.msg_name = &call->peer->srx.transport;
msg.msg_namelen = call->peer->srx.transport_len;
msg.msg_control = NULL;
@@ -255,7 +248,6 @@
ret = kernel_sendmsg(conn->params.local->socket,
&msg, iov, 1, sizeof(pkt));
- rxrpc_put_connection(conn);
return ret;
}
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index eee299b..1890431 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -141,6 +141,7 @@
if (!atomic_read(&head->ht.nelems))
return -1;
+ flow_dissector_init_keys(&skb_key.control, &skb_key.basic);
fl_clear_masked_range(&skb_key, &head->mask);
info = skb_tunnel_info(skb);
@@ -364,6 +365,7 @@
[TCA_FLOWER_KEY_TCP_DST_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_UDP_SRC_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_UDP_DST_MASK] = { .type = NLA_U16 },
+ [TCA_FLOWER_FLAGS] = { .type = NLA_U32 },
};
static void fl_set_key_val(struct nlattr **tb,
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index 61ddfba..fe29c57 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -111,6 +111,7 @@
static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = {
[TCA_MATCHALL_UNSPEC] = { .type = NLA_UNSPEC },
[TCA_MATCHALL_CLASSID] = { .type = NLA_U32 },
+ [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 },
};
static int mall_set_parms(struct net *net, struct tcf_proto *tp,
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 455fc8f..f203735 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -542,8 +542,8 @@
fp = &b->ht[h];
for (pfp = rtnl_dereference(*fp); pfp;
fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
- if (pfp == f) {
- *fp = f->next;
+ if (pfp == fold) {
+ rcu_assign_pointer(*fp, fold->next);
break;
}
}
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 322438f..8673f981 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -455,10 +455,8 @@
static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
[TCA_RSVP_CLASSID] = { .type = NLA_U32 },
- [TCA_RSVP_DST] = { .type = NLA_BINARY,
- .len = RSVP_DST_LEN * sizeof(u32) },
- [TCA_RSVP_SRC] = { .type = NLA_BINARY,
- .len = RSVP_DST_LEN * sizeof(u32) },
+ [TCA_RSVP_DST] = { .len = RSVP_DST_LEN * sizeof(u32) },
+ [TCA_RSVP_SRC] = { .len = RSVP_DST_LEN * sizeof(u32) },
[TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) },
};
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index db80a64..ab66e2b 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -301,12 +301,32 @@
cp->fall_through = p->fall_through;
cp->tp = tp;
+ if (tb[TCA_TCINDEX_HASH])
+ cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
+
+ if (tb[TCA_TCINDEX_MASK])
+ cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
+
+ if (tb[TCA_TCINDEX_SHIFT])
+ cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
+
+ if (!cp->hash) {
+ /* Hash not specified, use perfect hash if the upper limit
+ * of the hashing index is below the threshold.
+ */
+ if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
+ cp->hash = (cp->mask >> cp->shift) + 1;
+ else
+ cp->hash = DEFAULT_HASH_SIZE;
+ }
+
if (p->perfect) {
int i;
if (tcindex_alloc_perfect_hash(cp) < 0)
goto errout;
- for (i = 0; i < cp->hash; i++)
+ cp->alloc_hash = cp->hash;
+ for (i = 0; i < min(cp->hash, p->hash); i++)
cp->perfect[i].res = p->perfect[i].res;
balloc = 1;
}
@@ -321,15 +341,6 @@
if (old_r)
cr.res = r->res;
- if (tb[TCA_TCINDEX_HASH])
- cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
-
- if (tb[TCA_TCINDEX_MASK])
- cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
-
- if (tb[TCA_TCINDEX_SHIFT])
- cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
-
err = -EBUSY;
/* Hash already allocated, make sure that we still meet the
@@ -347,16 +358,6 @@
if (tb[TCA_TCINDEX_FALL_THROUGH])
cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
- if (!cp->hash) {
- /* Hash not specified, use perfect hash if the upper limit
- * of the hashing index is below the threshold.
- */
- if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
- cp->hash = (cp->mask >> cp->shift) + 1;
- else
- cp->hash = DEFAULT_HASH_SIZE;
- }
-
if (!cp->perfect && !cp->h)
cp->alloc_hash = cp->hash;
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 7e7eba3..9f53d4e 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -697,6 +697,7 @@
[TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
[TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 },
[TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 },
+ [TCA_FQ_ORPHAN_MASK] = { .type = NLA_U32 },
[TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NLA_U32 },
};
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index bfd0686..1a3c753 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -177,6 +177,16 @@
return 1;
}
+/* Check for format error in an ABORT chunk */
+static inline bool sctp_err_chunk_valid(struct sctp_chunk *chunk)
+{
+ struct sctp_errhdr *err;
+
+ sctp_walk_errors(err, chunk->chunk_hdr);
+
+ return (void *)err == (void *)chunk->chunk_end;
+}
+
/**********************************************************
* These are the state functions for handling chunk events.
**********************************************************/
@@ -2159,6 +2169,9 @@
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
+ if (!sctp_err_chunk_valid(chunk))
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
}
@@ -2201,6 +2214,9 @@
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
+ if (!sctp_err_chunk_valid(chunk))
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
/* Stop the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
@@ -2466,6 +2482,9 @@
sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands);
+ if (!sctp_err_chunk_valid(chunk))
+ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+
return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands);
}
@@ -2482,15 +2501,9 @@
/* See if we have an error cause code in the chunk. */
len = ntohs(chunk->chunk_hdr->length);
- if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) {
- sctp_errhdr_t *err;
- sctp_walk_errors(err, chunk->chunk_hdr);
- if ((void *)err != (void *)chunk->chunk_end)
- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
-
+ if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
- }
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
/* ASSOC_FAILED will DELETE_TCB. */
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index b4b68c6..d7775ca 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1180,6 +1180,7 @@
dprintk("RPC: No creds found!\n");
goto out;
} else {
+ struct timespec64 boot;
/* steal creds */
rsci.cred = ud->creds;
@@ -1200,6 +1201,9 @@
&expiry, GFP_KERNEL);
if (status)
goto out;
+
+ getboottime64(&boot);
+ expiry -= boot.tv_sec;
}
rsci.h.expiry_time = expiry;
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c
index e9e9129..3cedf2c 100644
--- a/net/wireless/ethtool.c
+++ b/net/wireless/ethtool.c
@@ -6,9 +6,13 @@
void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct device *pdev = wiphy_dev(wdev->wiphy);
- strlcpy(info->driver, wiphy_dev(wdev->wiphy)->driver->name,
- sizeof(info->driver));
+ if (pdev->driver)
+ strlcpy(info->driver, pdev->driver->name,
+ sizeof(info->driver));
+ else
+ strlcpy(info->driver, "N/A", sizeof(info->driver));
strlcpy(info->version, init_utsname()->release, sizeof(info->version));
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 25bd83b..475d1f5 100755
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -333,6 +333,7 @@
[NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
+ [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
[NL80211_ATTR_PID] = { .type = NLA_U32 },
@@ -358,6 +359,8 @@
[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
[NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
+ [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
+ [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
[NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
[NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
[NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
@@ -406,6 +409,8 @@
[NL80211_ATTR_MDID] = { .type = NLA_U16 },
[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
+ [NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 },
[NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
[NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
[NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
@@ -431,6 +436,7 @@
[NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
+ [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
@@ -773,7 +779,7 @@
struct key_params p;
int idx;
int type;
- bool def, defmgmt;
+ bool def, defmgmt, defbeacon;
bool def_uni, def_multi;
};
@@ -787,12 +793,13 @@
k->def = !!tb[NL80211_KEY_DEFAULT];
k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
+ k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
if (k->def) {
k->def_uni = true;
k->def_multi = true;
}
- if (k->defmgmt)
+ if (k->defmgmt || k->defbeacon)
k->def_multi = true;
if (tb[NL80211_KEY_IDX])
@@ -899,10 +906,11 @@
if (err)
return err;
- if (k->def && k->defmgmt)
+ if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
+ (k->defbeacon ? 1 : 0) > 1)
return -EINVAL;
- if (k->defmgmt) {
+ if (k->defmgmt || k->defbeacon) {
if (k->def_uni || !k->def_multi)
return -EINVAL;
}
@@ -911,11 +919,14 @@
if (k->defmgmt) {
if (k->idx < 4 || k->idx > 5)
return -EINVAL;
+ } else if (k->defbeacon) {
+ if (k->idx < 6 || k->idx > 7)
+ return -EINVAL;
} else if (k->def) {
if (k->idx < 0 || k->idx > 3)
return -EINVAL;
} else {
- if (k->idx < 0 || k->idx > 5)
+ if (k->idx < 0 || k->idx > 7)
return -EINVAL;
}
}
@@ -3156,10 +3167,15 @@
void *hdr;
struct sk_buff *msg;
- if (info->attrs[NL80211_ATTR_KEY_IDX])
+ if (info->attrs[NL80211_ATTR_KEY_IDX]) {
key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+ if (key_idx > 5 &&
+ !wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_BEACON_PROTECTION))
+ return -EINVAL;
+ }
- if (key_idx > 5)
+ if (key_idx > 7)
return -EINVAL;
if (info->attrs[NL80211_ATTR_MAC])
@@ -3236,7 +3252,7 @@
return -EINVAL;
/* only support setting default key */
- if (!key.def && !key.defmgmt)
+ if (!key.def && !key.defmgmt && !key.defbeacon)
return -EINVAL;
wdev_lock(dev->ieee80211_ptr);
@@ -3260,6 +3276,24 @@
#ifdef CONFIG_CFG80211_WEXT
dev->ieee80211_ptr->wext.default_key = key.idx;
#endif
+ } else if (key.defbeacon) {
+ if (key.def_uni || !key.def_multi) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (!rdev->ops->set_default_beacon_key) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ err = nl80211_key_allowed(dev->ieee80211_ptr);
+ if (err)
+ goto out;
+
+ err = rdev_set_default_beacon_key(rdev, dev, key.idx);
+ if (err)
+ goto out;
} else {
if (key.def_uni || !key.def_multi) {
err = -EINVAL;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8be0578..349c80d 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -135,6 +135,19 @@
return ret;
}
+static inline int
+rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u8 key_index)
+{
+ int ret;
+
+ trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index);
+ ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev,
+ key_index);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
static inline int rdev_start_ap(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct cfg80211_ap_settings *settings)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 545848c..9588b72 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1737,7 +1737,7 @@
break;
}
- if (IS_ERR(reg_rule)) {
+ if (IS_ERR_OR_NULL(reg_rule)) {
pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n",
chan->center_freq);
if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 0dc41fd..5d1c8ec 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1027,9 +1027,16 @@
* Delete all the keys ... pairwise keys can't really
* exist any more anyway, but default keys might.
*/
- if (rdev->ops->del_key)
- for (i = 0; i < 6; i++)
+ if (rdev->ops->del_key) {
+ int max_key_idx = 5;
+
+ if (wiphy_ext_feature_isset(
+ wdev->wiphy,
+ NL80211_EXT_FEATURE_BEACON_PROTECTION))
+ max_key_idx = 7;
+ for (i = 0; i <= max_key_idx; i++)
rdev_del_key(rdev, dev, i, false, NULL);
+ }
rdev_set_qos_map(rdev, dev, NULL);
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ef56df5..42cfc51 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -470,6 +470,23 @@
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
);
+TRACE_EVENT(rdev_set_default_beacon_key,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index),
+ TP_ARGS(wiphy, netdev, key_index),
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ __field(u8, key_index)
+ ),
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ __entry->key_index = key_index;
+ ),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
+ WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
+);
+
TRACE_EVENT(rdev_start_ap,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_ap_settings *settings),
diff --git a/net/wireless/util.c b/net/wireless/util.c
index bdd0b62..e7ea152 100755
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -221,7 +221,12 @@
struct key_params *params, int key_idx,
bool pairwise, const u8 *mac_addr)
{
- if (key_idx < 0 || key_idx > 5)
+ int max_key_idx = 5;
+
+ if (wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_BEACON_PROTECTION))
+ max_key_idx = 7;
+ if (key_idx < 0 || key_idx > max_key_idx)
return -EINVAL;
if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 61e6d03..088ea61 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -345,7 +345,9 @@
static void xfrm_policy_kill(struct xfrm_policy *policy)
{
+ write_lock_bh(&policy->lock);
policy->walk.dead = 1;
+ write_unlock_bh(&policy->lock);
atomic_inc(&policy->genid);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d47a4cf..5ea9c1a 100755
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -109,7 +109,8 @@
return 0;
uctx = nla_data(rt);
- if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
+ if (uctx->len > nla_len(rt) ||
+ uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
return -EINVAL;
return 0;
@@ -2247,6 +2248,9 @@
err = verify_newpolicy_info(&ua->policy);
if (err)
goto free_state;
+ err = verify_sec_ctx_len(attrs);
+ if (err)
+ goto free_state;
/* build an XP */
xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic
index e4d017d5..95f7d80 100644
--- a/scripts/Makefile.asm-generic
+++ b/scripts/Makefile.asm-generic
@@ -15,7 +15,7 @@
# Stale wrappers when the corresponding files are removed from generic-y
# need removing.
-generated-y := $(generic-y) $(genhdr-y) $(generated-y)
+generated-y := $(generic-y) $(generated-y)
all-files := $(patsubst %, $(obj)/%, $(generated-y))
old-headers := $(wildcard $(obj)/*.h)
unwanted := $(filter-out $(all-files),$(old-headers))
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index d08b6fb..1532038 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -70,5 +70,6 @@
KBUILD_CFLAGS += $(call cc-disable-warning, sign-compare)
KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length)
KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized)
+KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
endif
endif
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
index 1106d6c..82abf5a 100644
--- a/scripts/Makefile.headersinst
+++ b/scripts/Makefile.headersinst
@@ -1,33 +1,56 @@
# ==========================================================================
# Installing headers
#
-# header-y - list files to be installed. They are preprocessed
-# to remove __KERNEL__ section of the file
-# genhdr-y - Same as header-y but in a generated/ directory
+# All headers under include/uapi, include/generated/uapi,
+# arch/<arch>/include/uapi and arch/<arch>/include/generated/uapi are
+# exported.
+# They are preprocessed to remove __KERNEL__ section of the file.
#
# ==========================================================================
+PHONY := __headers
+__headers:
+
+include scripts/Kbuild.include
+
+srcdir := $(srctree)/$(obj)
+subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+# caller may set destination dir (when installing to asm/)
+_dst := $(if $(dst),$(dst),$(obj))
+
+# Recursion
+__headers: $(subdirs)
+
+.PHONY: $(subdirs)
+$(subdirs):
+ $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
+
+# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi.
+# We have only sub-directories there.
+skip-inst := $(if $(filter %/uapi,$(obj)),1)
+
+ifeq ($(skip-inst),)
+
# generated header directory
gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
+# Kbuild file is optional
kbuild-file := $(srctree)/$(obj)/Kbuild
-include $(kbuild-file)
-
-# called may set destination dir (when installing to asm/)
-_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj)))
+-include $(kbuild-file)
old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
ifneq ($(wildcard $(old-kbuild-file)),)
include $(old-kbuild-file)
endif
-include scripts/Kbuild.include
-
installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
-header-y := $(sort $(header-y))
-subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
-header-y := $(filter-out %/, $(header-y))
+gendir := $(objtree)/$(gen)
+header-files := $(notdir $(wildcard $(srcdir)/*.h))
+header-files += $(notdir $(wildcard $(srcdir)/*.agh))
+header-files := $(filter-out $(no-export-headers), $(header-files))
+genhdr-files := $(notdir $(wildcard $(gendir)/*.h))
+genhdr-files := $(filter-out $(header-files), $(genhdr-files))
# files used to track state of install/check
install-file := $(installdir)/.install
@@ -35,36 +58,22 @@
# generic-y list all files an architecture uses from asm-generic
# Use this to build a list of headers which require a wrapper
-wrapper-files := $(filter $(header-y), $(generic-y))
-
-srcdir := $(srctree)/$(obj)
-gendir := $(objtree)/$(gen)
+generic-files := $(notdir $(wildcard $(srctree)/include/uapi/asm-generic/*.h))
+wrapper-files := $(filter $(generic-files), $(generic-y))
+wrapper-files := $(filter-out $(header-files), $(wrapper-files))
oldsrcdir := $(srctree)/$(subst /uapi,,$(obj))
# all headers files for this dir
-header-y := $(filter-out $(generic-y), $(header-y))
-all-files := $(header-y) $(genhdr-y) $(wrapper-files)
+all-files := $(header-files) $(genhdr-files) $(wrapper-files)
output-files := $(addprefix $(installdir)/, $(all-files))
-input-files1 := $(foreach hdr, $(header-y), \
- $(if $(wildcard $(srcdir)/$(hdr)), \
- $(wildcard $(srcdir)/$(hdr))) \
- )
-input-files1-name := $(notdir $(input-files1))
-input-files2 := $(foreach hdr, $(header-y), \
- $(if $(wildcard $(srcdir)/$(hdr)),, \
- $(if $(wildcard $(oldsrcdir)/$(hdr)), \
- $(wildcard $(oldsrcdir)/$(hdr)), \
- $(error Missing UAPI file $(srcdir)/$(hdr))) \
- ))
-input-files2-name := $(notdir $(input-files2))
-input-files3 := $(foreach hdr, $(genhdr-y), \
- $(if $(wildcard $(gendir)/$(hdr)), \
- $(wildcard $(gendir)/$(hdr)), \
- $(error Missing generated UAPI file $(gendir)/$(hdr)) \
- ))
-input-files3-name := $(notdir $(input-files3))
+ifneq ($(mandatory-y),)
+missing := $(filter-out $(all-files),$(mandatory-y))
+ifneq ($(missing),)
+$(error Some mandatory headers ($(missing)) are missing in $(obj))
+endif
+endif
# Work out what needs to be removed
oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h))
@@ -78,9 +87,8 @@
quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
file$(if $(word 2, $(all-files)),s))
cmd_install = \
- $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(input-files1-name); \
- $(CONFIG_SHELL) $< $(installdir) $(oldsrcdir) $(input-files2-name); \
- $(CONFIG_SHELL) $< $(installdir) $(gendir) $(input-files3-name); \
+ $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(header-files); \
+ $(CONFIG_SHELL) $< $(installdir) $(gendir) $(genhdr-files); \
for F in $(wrapper-files); do \
echo "\#include <asm-generic/$$F>" > $(installdir)/$$F; \
done; \
@@ -98,21 +106,21 @@
$(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
touch $@
-PHONY += __headersinst __headerscheck
-
ifndef HDRCHECK
# Rules for installing headers
-__headersinst: $(subdirs) $(install-file)
+__headers: $(install-file)
@:
targets += $(install-file)
-$(install-file): scripts/headers_install.sh $(input-files1) $(input-files2) $(input-files3) FORCE
+$(install-file): scripts/headers_install.sh \
+ $(addprefix $(srcdir)/,$(header-files)) \
+ $(addprefix $(gendir)/,$(genhdr-files)) FORCE
$(if $(unwanted),$(call cmd,remove),)
$(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@)))
$(call if_changed,install)
else
-__headerscheck: $(subdirs) $(check-file)
+__headers: $(check-file)
@:
targets += $(check-file)
@@ -121,11 +129,6 @@
endif
-# Recursion
-.PHONY: $(subdirs)
-$(subdirs):
- $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
-
targets := $(wildcard $(sort $(targets)))
cmd_files := $(wildcard \
$(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
@@ -134,6 +137,8 @@
include $(cmd_files)
endif
+endif # skip-inst
+
.PHONY: $(PHONY)
PHONY += FORCE
FORCE: ;
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 790fbf6..e4e0f6a 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -38,7 +38,6 @@
#include "srcpos.h"
#include "dtc-parser.tab.h"
-YYLTYPE yylloc;
extern bool treesource_error;
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index ba525c2..750f7a4 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -637,7 +637,6 @@
#include "srcpos.h"
#include "dtc-parser.tab.h"
-YYLTYPE yylloc;
extern bool treesource_error;
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 27aac27..fa423fc 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1238,7 +1238,7 @@
sym_calc_value(csym);
if (mode == def_random)
- has_changed = randomize_choice_values(csym);
+ has_changed |= randomize_choice_values(csym);
else {
set_all_choice_values(csym);
has_changed = true;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 84d9a2e..f11a4ab 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -867,7 +867,7 @@
if (orig->ae.xp_node) {
rc = avc_xperms_populate(node, orig->ae.xp_node);
if (rc) {
- kmem_cache_free(avc_node_cachep, node);
+ avc_node_kill(node);
goto out_unlock;
}
}
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index c6888d7..0e3dd60 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -111,7 +111,7 @@
while (plugin->next) {
if (plugin->dst_frames)
frames = plugin->dst_frames(plugin, frames);
- if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0))
+ if ((snd_pcm_sframes_t)frames <= 0)
return -ENXIO;
plugin = plugin->next;
err = snd_pcm_plugin_alloc(plugin, frames);
@@ -123,7 +123,7 @@
while (plugin->prev) {
if (plugin->src_frames)
frames = plugin->src_frames(plugin, frames);
- if (snd_BUG_ON((snd_pcm_sframes_t)frames <= 0))
+ if ((snd_pcm_sframes_t)frames <= 0)
return -ENXIO;
plugin = plugin->prev;
err = snd_pcm_plugin_alloc(plugin, frames);
@@ -209,6 +209,8 @@
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
plugin = snd_pcm_plug_last(plug);
while (plugin && drv_frames > 0) {
+ if (drv_frames > plugin->buf_frames)
+ drv_frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames)
drv_frames = plugin->src_frames(plugin, drv_frames);
@@ -220,6 +222,8 @@
plugin_next = plugin->next;
if (plugin->dst_frames)
drv_frames = plugin->dst_frames(plugin, drv_frames);
+ if (drv_frames > plugin->buf_frames)
+ drv_frames = plugin->buf_frames;
plugin = plugin_next;
}
} else
@@ -248,11 +252,15 @@
if (frames < 0)
return frames;
}
+ if (frames > plugin->buf_frames)
+ frames = plugin->buf_frames;
plugin = plugin_next;
}
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
plugin = snd_pcm_plug_last(plug);
while (plugin) {
+ if (frames > plugin->buf_frames)
+ frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames);
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9debd1b..cdfb8f9 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -615,6 +615,7 @@
len = snd_seq_oss_timer_start(dp->timer);
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
+ snd_midi_event_reset_decode(mdev->coder);
} else {
len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
if (len > 0)
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index eee4ea1..198eea5 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -564,7 +564,7 @@
event->queue = queue;
event->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK;
if (real_time) {
- event->time.time = snd_seq_timer_get_cur_time(q->timer);
+ event->time.time = snd_seq_timer_get_cur_time(q->timer, true);
event->flags |= SNDRV_SEQ_TIME_STAMP_REAL;
} else {
event->time.tick = snd_seq_timer_get_cur_tick(q->timer);
@@ -1639,7 +1639,7 @@
tmr = queue->timer;
status->events = queue->tickq->cells + queue->timeq->cells;
- status->time = snd_seq_timer_get_cur_time(tmr);
+ status->time = snd_seq_timer_get_cur_time(tmr, true);
status->tick = snd_seq_timer_get_cur_tick(tmr);
status->running = tmr->running;
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 1a6dc4f..ea1aa07 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -261,6 +261,8 @@
{
unsigned long flags;
struct snd_seq_event_cell *cell;
+ snd_seq_tick_time_t cur_tick;
+ snd_seq_real_time_t cur_time;
if (q == NULL)
return;
@@ -277,17 +279,18 @@
__again:
/* Process tick queue... */
+ cur_tick = snd_seq_timer_get_cur_tick(q->timer);
for (;;) {
- cell = snd_seq_prioq_cell_out(q->tickq,
- &q->timer->tick.cur_tick);
+ cell = snd_seq_prioq_cell_out(q->tickq, &cur_tick);
if (!cell)
break;
snd_seq_dispatch_event(cell, atomic, hop);
}
/* Process time queue... */
+ cur_time = snd_seq_timer_get_cur_time(q->timer, false);
for (;;) {
- cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time);
+ cell = snd_seq_prioq_cell_out(q->timeq, &cur_time);
if (!cell)
break;
snd_seq_dispatch_event(cell, atomic, hop);
@@ -415,6 +418,7 @@
int snd_seq_queue_set_owner(int queueid, int client, int locked)
{
struct snd_seq_queue *q = queueptr(queueid);
+ unsigned long flags;
if (q == NULL)
return -EINVAL;
@@ -424,8 +428,10 @@
return -EPERM;
}
+ spin_lock_irqsave(&q->owner_lock, flags);
q->locked = locked ? 1 : 0;
q->owner = client;
+ spin_unlock_irqrestore(&q->owner_lock, flags);
queue_access_unlock(q);
queuefree(q);
@@ -564,15 +570,17 @@
unsigned long flags;
int i;
struct snd_seq_queue *q;
+ bool matched;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
if ((q = queueptr(i)) == NULL)
continue;
spin_lock_irqsave(&q->owner_lock, flags);
- if (q->owner == client)
+ matched = (q->owner == client);
+ if (matched)
q->klocked = 1;
spin_unlock_irqrestore(&q->owner_lock, flags);
- if (q->owner == client) {
+ if (matched) {
if (q->timer->running)
snd_seq_timer_stop(q->timer);
snd_seq_timer_reset(q->timer);
@@ -764,6 +772,8 @@
int i, bpm;
struct snd_seq_queue *q;
struct snd_seq_timer *tmr;
+ bool locked;
+ int owner;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
if ((q = queueptr(i)) == NULL)
@@ -775,9 +785,14 @@
else
bpm = 0;
+ spin_lock_irq(&q->owner_lock);
+ locked = q->locked;
+ owner = q->owner;
+ spin_unlock_irq(&q->owner_lock);
+
snd_iprintf(buffer, "queue %d: [%s]\n", q->queue, q->name);
- snd_iprintf(buffer, "owned by client : %d\n", q->owner);
- snd_iprintf(buffer, "lock status : %s\n", q->locked ? "Locked" : "Free");
+ snd_iprintf(buffer, "owned by client : %d\n", owner);
+ snd_iprintf(buffer, "lock status : %s\n", locked ? "Locked" : "Free");
snd_iprintf(buffer, "queued time events : %d\n", snd_seq_prioq_avail(q->timeq));
snd_iprintf(buffer, "queued tick events : %d\n", snd_seq_prioq_avail(q->tickq));
snd_iprintf(buffer, "timer state : %s\n", tmr->running ? "Running" : "Stopped");
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 0e1feb5..bd5e5a5 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -436,14 +436,15 @@
}
/* return current 'real' time. use timeofday() to get better granularity. */
-snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
+snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr,
+ bool adjust_ktime)
{
snd_seq_real_time_t cur_time;
unsigned long flags;
spin_lock_irqsave(&tmr->lock, flags);
cur_time = tmr->cur_time;
- if (tmr->running) {
+ if (adjust_ktime && tmr->running) {
struct timespec64 tm;
ktime_get_ts64(&tm);
@@ -460,7 +461,13 @@
high PPQ values) */
snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr)
{
- return tmr->tick.cur_tick;
+ snd_seq_tick_time_t cur_tick;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tmr->lock, flags);
+ cur_tick = tmr->tick.cur_tick;
+ spin_unlock_irqrestore(&tmr->lock, flags);
+ return cur_tick;
}
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
index 9506b66..5d47d55 100644
--- a/sound/core/seq/seq_timer.h
+++ b/sound/core/seq/seq_timer.h
@@ -135,7 +135,8 @@
int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position);
int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position);
int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base);
-snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr);
+snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr,
+ bool adjust_ktime);
snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr);
extern int seq_default_timer_class;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 1ebb346..d6fc84c 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -95,6 +95,7 @@
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
continue;
snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream);
+ snd_midi_event_reset_decode(vmidi->parser);
} else {
len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev);
if (len > 0)
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 172dacd..c182341 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -925,7 +925,7 @@
{
int i;
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
if (dummy->pcm_hw.formats & (1ULL << i))
snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
}
diff --git a/sound/hda/hdmi_chmap.c b/sound/hda/hdmi_chmap.c
index f21633c..acbe61b 100644
--- a/sound/hda/hdmi_chmap.c
+++ b/sound/hda/hdmi_chmap.c
@@ -249,7 +249,7 @@
for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
if (spk_alloc & (1 << i))
- j += snprintf(buf + j, buflen - j, " %s",
+ j += scnprintf(buf + j, buflen - j, " %s",
cea_speaker_allocation_names[i]);
}
buf[j] = '\0'; /* necessary when j == 0 */
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 1b5e217..2ad28ce 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4104,7 +4104,7 @@
for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
if (pcm & (AC_SUPPCM_BITS_8 << i))
- j += snprintf(buf + j, buflen - j, " %d", bits[i]);
+ j += scnprintf(buf + j, buflen - j, " %d", bits[i]);
buf[j] = '\0'; /* necessary when j == 0 */
}
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index ba7fe9b..864cc8c 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -373,7 +373,7 @@
for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++)
if (pcm & (1 << i))
- j += snprintf(buf + j, buflen - j, " %d",
+ j += scnprintf(buf + j, buflen - j, " %d",
alsa_rates[i]);
buf[j] = '\0'; /* necessary when j == 0 */
diff --git a/sound/pci/hda/hda_sysfs.c b/sound/pci/hda/hda_sysfs.c
index 9739fce..f3ac19d 100644
--- a/sound/pci/hda/hda_sysfs.c
+++ b/sound/pci/hda/hda_sysfs.c
@@ -221,7 +221,7 @@
mutex_lock(&codec->user_mutex);
for (i = 0; i < codec->init_verbs.used; i++) {
struct hda_verb *v = snd_array_elem(&codec->init_verbs, i);
- len += snprintf(buf + len, PAGE_SIZE - len,
+ len += scnprintf(buf + len, PAGE_SIZE - len,
"0x%02x 0x%03x 0x%04x\n",
v->nid, v->verb, v->param);
}
@@ -271,7 +271,7 @@
mutex_lock(&codec->user_mutex);
for (i = 0; i < codec->hints.used; i++) {
struct hda_hint *hint = snd_array_elem(&codec->hints, i);
- len += snprintf(buf + len, PAGE_SIZE - len,
+ len += scnprintf(buf + len, PAGE_SIZE - len,
"%s = %s\n", hint->key, hint->val);
}
mutex_unlock(&codec->user_mutex);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 8557b94..1e99500 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -853,6 +853,7 @@
SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
+ SND_PCI_QUIRK(0x17aa, 0x21d2, "Lenovo T420s", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a64612d..000b59d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4212,6 +4212,8 @@
is_ctia = (val & 0x1c02) == 0x1c02;
break;
case 0x10ec0225:
+ codec->power_save_node = 1;
+ /* fall through */
case 0x10ec0295:
case 0x10ec0299:
alc_process_coef_fw(codec, coef0225);
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index fbbc252..2a127fe 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -117,10 +117,10 @@
}
/* spu_memload - write to SPU address space */
-static void spu_memload(u32 toi, void *from, int length)
+static void spu_memload(u32 toi, const void *from, int length)
{
unsigned long flags;
- u32 *froml = from;
+ const u32 *froml = from;
u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi);
int i;
u32 val;
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 22aec9a..838d03a 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -25,6 +25,8 @@
config SND_ATMEL_SOC_SSC_DMA
tristate
+ select SND_ATMEL_SOC_DMA
+ select SND_ATMEL_SOC_PDC
config SND_ATMEL_SOC_SSC
tristate
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 72b19e6..c0807b8 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -1441,13 +1441,15 @@
}
pcm512x->sclk = devm_clk_get(dev, NULL);
- if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
if (!IS_ERR(pcm512x->sclk)) {
ret = clk_prepare_enable(pcm512x->sclk);
if (ret != 0) {
dev_err(dev, "Failed to enable SCLK: %d\n", ret);
- return ret;
+ goto err;
}
}
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
index 7547420..3d91cef 100644
--- a/sound/soc/qcom/apq8016_sbc.c
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -128,7 +128,8 @@
link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0);
if (!link->codec_of_node) {
dev_err(card->dev, "error getting codec phandle\n");
- return ERR_PTR(-EINVAL);
+ ret = -EINVAL;
+ goto error;
}
ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1ed8c16..0b8e65d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -4382,7 +4382,7 @@
continue;
if (w->power) {
dapm_seq_insert(w, &down_list, false);
- w->power = 0;
+ w->new_power = 0;
powerdown = 1;
}
}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 851b9d7..d444dba 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2330,42 +2330,81 @@
}
EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
+static int dpcm_dai_trigger_fe_be(struct snd_pcm_substream *substream,
+ int cmd, bool fe_first)
+{
+ struct snd_soc_pcm_runtime *fe = substream->private_data;
+ int ret;
+
+ /* call trigger on the frontend before the backend. */
+ if (fe_first) {
+ dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
+ fe->dai_link->name, cmd);
+
+ ret = soc_pcm_trigger(substream, cmd);
+ if (ret < 0)
+ return ret;
+
+ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
+ return ret;
+ }
+
+ /* call trigger on the frontend after the backend. */
+ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
+ fe->dai_link->name, cmd);
+
+ ret = soc_pcm_trigger(substream, cmd);
+
+ return ret;
+}
+
static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *fe = substream->private_data;
- int stream = substream->stream, ret;
+ int stream = substream->stream;
+ int ret = 0;
enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
switch (trigger) {
case SND_SOC_DPCM_TRIGGER_PRE:
- /* call trigger on the frontend before the backend. */
-
- dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
- fe->dai_link->name, cmd);
-
- ret = soc_pcm_trigger(substream, cmd);
- if (ret < 0) {
- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
- goto out;
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
-
- ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
break;
case SND_SOC_DPCM_TRIGGER_POST:
- /* call trigger on the frontend after the backend. */
-
- ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
- if (ret < 0) {
- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
- goto out;
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
-
- dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
- fe->dai_link->name, cmd);
-
- ret = soc_pcm_trigger(substream, cmd);
break;
case SND_SOC_DPCM_TRIGGER_BESPOKE:
/* bespoke trigger() - handles both FE and BEs */
@@ -2374,10 +2413,6 @@
fe->dai_link->name, cmd);
ret = soc_pcm_bespoke_trigger(substream, cmd);
- if (ret < 0) {
- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
- goto out;
- }
break;
default:
dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
@@ -2386,6 +2421,12 @@
goto out;
}
+ if (ret < 0) {
+ dev_err(fe->dev, "ASoC: trigger FE cmd: %d failed: %d\n",
+ cmd, ret);
+ goto out;
+ }
+
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
@@ -3307,16 +3348,16 @@
ssize_t offset = 0;
/* FE state */
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
"[%s - %s]\n", fe->dai_link->name,
stream ? "Capture" : "Playback");
- offset += snprintf(buf + offset, size - offset, "State: %s\n",
+ offset += scnprintf(buf + offset, size - offset, "State: %s\n",
dpcm_state_string(fe->dpcm[stream].state));
if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
(fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
"Hardware Params: "
"Format = %s, Channels = %d, Rate = %d\n",
snd_pcm_format_name(params_format(params)),
@@ -3324,10 +3365,10 @@
params_rate(params));
/* BEs state */
- offset += snprintf(buf + offset, size - offset, "Backends:\n");
+ offset += scnprintf(buf + offset, size - offset, "Backends:\n");
if (list_empty(&fe->dpcm[stream].be_clients)) {
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
" No active DSP links\n");
goto out;
}
@@ -3336,16 +3377,16 @@
struct snd_soc_pcm_runtime *be = dpcm->be;
params = &dpcm->hw_params;
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
"- %s\n", be->dai_link->name);
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
" State: %s\n",
dpcm_state_string(be->dpcm[stream].state));
if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
(be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
- offset += snprintf(buf + offset, size - offset,
+ offset += scnprintf(buf + offset, size - offset,
" Hardware Params: "
"Format = %s, Channels = %d, Rate = %d\n",
snd_pcm_format_name(params_format(params)),
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 0918924..ea3a9bd 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -306,7 +306,7 @@
line6_midibuf_read(mb, line6->buffer_message,
LINE6_MIDI_MESSAGE_MAXLEN);
- if (done == 0)
+ if (done <= 0)
break;
line6->message_length = done;
diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c
index 36a610b..c931d48 100644
--- a/sound/usb/line6/midibuf.c
+++ b/sound/usb/line6/midibuf.c
@@ -163,7 +163,7 @@
int midi_length_prev =
midibuf_message_length(this->command_prev);
- if (midi_length_prev > 0) {
+ if (midi_length_prev > 1) {
midi_length = midi_length_prev - 1;
repeat = 1;
} else
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a5299cb..064f348 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1149,6 +1149,7 @@
case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */
case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
+ case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */
return true;
}
return false;
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 0b34dbc..7dcb33d 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -132,7 +132,7 @@
info->num_dsps = 2; // 0: Prepad Data, 1: FPGA Code
if (us428->chip_status & USX2Y_STAT_CHIP_INIT)
info->chip_ready = 1;
- info->version = USX2Y_DRIVER_VERSION;
+ info->version = USX2Y_DRIVER_VERSION;
return 0;
}
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index f99f49e4..21e714c 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -194,6 +194,7 @@
size_t name_len = strlen(fs->name);
/* name + "_PATH" + '\0' */
char upper_name[name_len + 5 + 1];
+
memcpy(upper_name, fs->name, name_len);
mem_toupper(upper_name, name_len);
strcpy(&upper_name[name_len], "_PATH");
@@ -203,7 +204,8 @@
return false;
fs->found = true;
- strncpy(fs->path, override_path, sizeof(fs->path));
+ strncpy(fs->path, override_path, sizeof(fs->path) - 1);
+ fs->path[sizeof(fs->path) - 1] = '\0';
return true;
}
diff --git a/tools/objtool/arch/x86/lib/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
index 0f7eb4f..82e105b 100644
--- a/tools/objtool/arch/x86/lib/x86-opcode-map.txt
+++ b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
@@ -909,7 +909,7 @@
GrpTable: Grp3_2
0: TEST Ev,Iz
-1:
+1: TEST Ev,Iz
2: NOT Ev
3: NEG Ev
4: MUL rAX,Ev
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index cd86fd7..ebcc086 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -34,7 +34,7 @@
# Only pass canonical directory names as the output directory:
#
ifneq ($(O),)
- FULL_O := $(shell readlink -f $(O) || echo $(O))
+ FULL_O := $(shell cd $(PWD); readlink -f $(O) || echo $(O))
endif
#
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a53fef0..ade6abd 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2930,6 +2930,7 @@
continue;
}
+ actions->ms.map = map;
top = pstack__peek(browser->pstack);
if (top == &browser->hists->dso_filter) {
/*
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index df68925..ab8ebfa 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -88,7 +88,7 @@
return true;
}
- if (!strncmp(filename, "/system/lib/", 11)) {
+ if (!strncmp(filename, "/system/lib/", 12)) {
char *ndk, *app;
const char *arch;
size_t ndk_length;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ffaa798..82e4f15 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -623,14 +623,19 @@
return -EINVAL;
}
- /* Try to get actual symbol name from symtab */
- symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
+ if (dwarf_entrypc(sp_die, &eaddr) == 0) {
+ /* If the DIE has entrypc, use it. */
+ symbol = dwarf_diename(sp_die);
+ } else {
+ /* Try to get actual symbol name and address from symtab */
+ symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
+ eaddr = sym.st_value;
+ }
if (!symbol) {
pr_warning("Failed to find symbol at 0x%lx\n",
(unsigned long)paddr);
return -ENOENT;
}
- eaddr = sym.st_value;
tp->offset = (unsigned long)(paddr - eaddr);
tp->address = (unsigned long)paddr;
diff --git a/tools/power/acpi/Makefile.config b/tools/power/acpi/Makefile.config
index a1883bb..fb5559f 100644
--- a/tools/power/acpi/Makefile.config
+++ b/tools/power/acpi/Makefile.config
@@ -18,7 +18,7 @@
OUTPUT=$(srctree)/
ifeq ("$(origin O)", "command line")
- OUTPUT := $(O)/power/acpi/
+ OUTPUT := $(O)/tools/power/acpi/
endif
#$(info Determined 'OUTPUT' to be $(OUTPUT))
diff --git a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
index 2116df9..c097a37 100644
--- a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c
@@ -83,7 +83,7 @@
static struct pci_dev *amd_fam14h_pci_dev;
static int nbp1_entered;
-struct timespec start_time;
+static struct timespec start_time;
static unsigned long long timediff;
#ifdef DEBUG
diff --git a/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
index 5b3205f..5277df2 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
+++ b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
@@ -21,7 +21,7 @@
static unsigned long long **previous_count;
static unsigned long long **current_count;
-struct timespec start_time;
+static struct timespec start_time;
static unsigned long long timediff;
static int cpuidle_get_count_percent(unsigned int id, double *percent,
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
index 05f953f..80a21cb 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
@@ -29,6 +29,8 @@
0
};
+int cpu_count;
+
static struct cpuidle_monitor *monitors[MONITORS_MAX];
static unsigned int avail_monitors;
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
index 9e43f33..3558bba 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
@@ -18,7 +18,7 @@
#define CSTATE_NAME_LEN 5
#define CSTATE_DESC_LEN 60
-int cpu_count;
+extern int cpu_count;
/* Hard to define the right names ...: */
enum power_range_e {
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 7ea4438..882c182 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -1,7 +1,7 @@
ifneq ($(O),)
ifeq ($(origin O), command line)
- dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
- ABSOLUTE_O := $(shell cd $(O) ; pwd)
+ dummy := $(if $(shell cd $(PWD); test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
+ ABSOLUTE_O := $(shell cd $(PWD); cd $(O) ; pwd)
OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
COMMAND_O := O=$(ABSOLUTE_O)
ifeq ($(objtree),)
diff --git a/tools/usb/usbip/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c
index b4c37e7..187dfaa6 100644
--- a/tools/usb/usbip/src/usbip_network.c
+++ b/tools/usb/usbip/src/usbip_network.c
@@ -62,39 +62,39 @@
info("using port %d (\"%s\")", usbip_port, usbip_port_string);
}
-void usbip_net_pack_uint32_t(int pack, uint32_t *num)
+uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num)
{
uint32_t i;
if (pack)
- i = htonl(*num);
+ i = htonl(num);
else
- i = ntohl(*num);
+ i = ntohl(num);
- *num = i;
+ return i;
}
-void usbip_net_pack_uint16_t(int pack, uint16_t *num)
+uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num)
{
uint16_t i;
if (pack)
- i = htons(*num);
+ i = htons(num);
else
- i = ntohs(*num);
+ i = ntohs(num);
- *num = i;
+ return i;
}
void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev)
{
- usbip_net_pack_uint32_t(pack, &udev->busnum);
- usbip_net_pack_uint32_t(pack, &udev->devnum);
- usbip_net_pack_uint32_t(pack, &udev->speed);
+ udev->busnum = usbip_net_pack_uint32_t(pack, udev->busnum);
+ udev->devnum = usbip_net_pack_uint32_t(pack, udev->devnum);
+ udev->speed = usbip_net_pack_uint32_t(pack, udev->speed);
- usbip_net_pack_uint16_t(pack, &udev->idVendor);
- usbip_net_pack_uint16_t(pack, &udev->idProduct);
- usbip_net_pack_uint16_t(pack, &udev->bcdDevice);
+ udev->idVendor = usbip_net_pack_uint16_t(pack, udev->idVendor);
+ udev->idProduct = usbip_net_pack_uint16_t(pack, udev->idProduct);
+ udev->bcdDevice = usbip_net_pack_uint16_t(pack, udev->bcdDevice);
}
void usbip_net_pack_usb_interface(int pack __attribute__((unused)),
@@ -141,6 +141,14 @@
return usbip_net_xmit(sockfd, buff, bufflen, 1);
}
+static inline void usbip_net_pack_op_common(int pack,
+ struct op_common *op_common)
+{
+ op_common->version = usbip_net_pack_uint16_t(pack, op_common->version);
+ op_common->code = usbip_net_pack_uint16_t(pack, op_common->code);
+ op_common->status = usbip_net_pack_uint32_t(pack, op_common->status);
+}
+
int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status)
{
struct op_common op_common;
@@ -152,7 +160,7 @@
op_common.code = code;
op_common.status = status;
- PACK_OP_COMMON(1, &op_common);
+ usbip_net_pack_op_common(1, &op_common);
rc = usbip_net_send(sockfd, &op_common, sizeof(op_common));
if (rc < 0) {
@@ -176,7 +184,7 @@
goto err;
}
- PACK_OP_COMMON(0, &op_common);
+ usbip_net_pack_op_common(0, &op_common);
if (op_common.version != USBIP_VERSION) {
dbg("version mismatch: %d %d", op_common.version,
diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h
index c1e875c..573fa83 100644
--- a/tools/usb/usbip/src/usbip_network.h
+++ b/tools/usb/usbip/src/usbip_network.h
@@ -33,12 +33,6 @@
} __attribute__((packed));
-#define PACK_OP_COMMON(pack, op_common) do {\
- usbip_net_pack_uint16_t(pack, &(op_common)->version);\
- usbip_net_pack_uint16_t(pack, &(op_common)->code);\
- usbip_net_pack_uint32_t(pack, &(op_common)->status);\
-} while (0)
-
/* ---------------------------------------------------------------------- */
/* Dummy Code */
#define OP_UNSPEC 0x00
@@ -164,11 +158,11 @@
} while (0)
#define PACK_OP_DEVLIST_REPLY(pack, reply) do {\
- usbip_net_pack_uint32_t(pack, &(reply)->ndev);\
+ (reply)->ndev = usbip_net_pack_uint32_t(pack, (reply)->ndev);\
} while (0)
-void usbip_net_pack_uint32_t(int pack, uint32_t *num);
-void usbip_net_pack_uint16_t(int pack, uint16_t *num);
+uint32_t usbip_net_pack_uint32_t(int pack, uint32_t num);
+uint16_t usbip_net_pack_uint16_t(int pack, uint16_t num);
void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev);
void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c0dff53..4e4bb5d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2045,12 +2045,12 @@
if (slots->generation != ghc->generation)
kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
- if (unlikely(!ghc->memslot))
- return kvm_write_guest(kvm, ghc->gpa, data, len);
-
if (kvm_is_error_hva(ghc->hva))
return -EFAULT;
+ if (unlikely(!ghc->memslot))
+ return kvm_write_guest(kvm, ghc->gpa, data, len);
+
r = __copy_to_user((void __user *)ghc->hva, data, len);
if (r)
return -EFAULT;
@@ -2071,12 +2071,12 @@
if (slots->generation != ghc->generation)
kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
- if (unlikely(!ghc->memslot))
- return kvm_read_guest(kvm, ghc->gpa, data, len);
-
if (kvm_is_error_hva(ghc->hva))
return -EFAULT;
+ if (unlikely(!ghc->memslot))
+ return kvm_read_guest(kvm, ghc->gpa, data, len);
+
r = __copy_from_user(data, (void __user *)ghc->hva, len);
if (r)
return -EFAULT;