diff options
author | Mike Pagano <mpagano@gentoo.org> | 2023-08-11 07:57:59 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2023-08-11 07:57:59 -0400 |
commit | 83969a9a6db88921f9b70e114e8aa94aea497fbb (patch) | |
tree | 5bf7a9cae98f337d219b52525fefbd268bee14b6 | |
parent | Linux patch 4.19.290 (diff) | |
download | linux-patches-4.19-292.tar.gz linux-patches-4.19-292.tar.bz2 linux-patches-4.19-292.zip |
Linux patch 4.19.2914.19-292
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1290_linux-4.19.291.patch | 22013 |
2 files changed, 22017 insertions, 0 deletions
diff --git a/0000_README b/0000_README index a3f10bc0..b68b9988 100644 --- a/0000_README +++ b/0000_README @@ -1203,6 +1203,10 @@ Patch: 1289_linux-4.19.290.patch From: https://www.kernel.org Desc: Linux 4.19.290 +Patch: 1290_linux-4.19.291.patch +From: https://www.kernel.org +Desc: Linux 4.19.291 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1290_linux-4.19.291.patch b/1290_linux-4.19.291.patch new file mode 100644 index 00000000..9e95eefd --- /dev/null +++ b/1290_linux-4.19.291.patch @@ -0,0 +1,22013 @@ +diff --git a/Documentation/admin-guide/security-bugs.rst b/Documentation/admin-guide/security-bugs.rst +index 30187d49dc2c7..67161e1b0f0bd 100644 +--- a/Documentation/admin-guide/security-bugs.rst ++++ b/Documentation/admin-guide/security-bugs.rst +@@ -56,31 +56,28 @@ information submitted to the security list and any followup discussions + of the report are treated confidentially even after the embargo has been + lifted, in perpetuity. + +-Coordination +------------- +- +-Fixes for sensitive bugs, such as those that might lead to privilege +-escalations, may need to be coordinated with the private +-<linux-distros@vs.openwall.org> mailing list so that distribution vendors +-are well prepared to issue a fixed kernel upon public disclosure of the +-upstream fix. Distros will need some time to test the proposed patch and +-will generally request at least a few days of embargo, and vendor update +-publication prefers to happen Tuesday through Thursday. When appropriate, +-the security team can assist with this coordination, or the reporter can +-include linux-distros from the start. In this case, remember to prefix +-the email Subject line with "[vs]" as described in the linux-distros wiki: +-<http://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists> ++Coordination with other groups ++------------------------------ ++ ++The kernel security team strongly recommends that reporters of potential ++security issues NEVER contact the "linux-distros" mailing list until ++AFTER discussing it with the kernel security team. Do not Cc: both ++lists at once. You may contact the linux-distros mailing list after a ++fix has been agreed on and you fully understand the requirements that ++doing so will impose on you and the kernel community. ++ ++The different lists have different goals and the linux-distros rules do ++not contribute to actually fixing any potential security problems. + + CVE assignment + -------------- + +-The security team does not normally assign CVEs, nor do we require them +-for reports or fixes, as this can needlessly complicate the process and +-may delay the bug handling. If a reporter wishes to have a CVE identifier +-assigned ahead of public disclosure, they will need to contact the private +-linux-distros list, described above. When such a CVE identifier is known +-before a patch is provided, it is desirable to mention it in the commit +-message if the reporter agrees. ++The security team does not assign CVEs, nor do we require them for ++reports or fixes, as this can needlessly complicate the process and may ++delay the bug handling. If a reporter wishes to have a CVE identifier ++assigned, they should find one by themselves, for example by contacting ++MITRE directly. However under no circumstances will a patch inclusion ++be delayed to wait for a CVE identifier to arrive. + + Non-disclosure agreements + ------------------------- +diff --git a/MAINTAINERS b/MAINTAINERS +index 3d3d7f5d1c3f1..59003315a9597 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1180,7 +1180,7 @@ N: owl + F: arch/arm/mach-actions/ + F: arch/arm/boot/dts/owl-* + F: arch/arm64/boot/dts/actions/ +-F: drivers/clocksource/owl-* ++F: drivers/clocksource/timer-owl* + F: drivers/pinctrl/actions/* + F: drivers/soc/actions/ + F: include/dt-bindings/power/owl-* +@@ -1603,7 +1603,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) + S: Maintained + F: arch/arm/boot/dts/lpc43* + F: drivers/clk/nxp/clk-lpc18xx* +-F: drivers/clocksource/time-lpc32xx.c ++F: drivers/clocksource/timer-lpc32xx.c + F: drivers/i2c/busses/i2c-lpc2k.c + F: drivers/memory/pl172.c + F: drivers/mtd/spi-nor/nxp-spifi.c +@@ -2219,7 +2219,7 @@ F: arch/arm/mach-vexpress/ + F: */*/vexpress* + F: */*/*/vexpress* + F: drivers/clk/versatile/clk-vexpress-osc.c +-F: drivers/clocksource/versatile.c ++F: drivers/clocksource/timer-versatile.c + N: mps2 + + ARM/VFP SUPPORT +@@ -2241,7 +2241,7 @@ M: Tony Prisk <linux@prisktech.co.nz> + L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) + S: Maintained + F: arch/arm/mach-vt8500/ +-F: drivers/clocksource/vt8500_timer.c ++F: drivers/clocksource/timer-vt8500.c + F: drivers/i2c/busses/i2c-wmt.c + F: drivers/mmc/host/wmt-sdmmc.c + F: drivers/pwm/pwm-vt8500.c +@@ -2306,7 +2306,7 @@ F: drivers/cpuidle/cpuidle-zynq.c + F: drivers/block/xsysace.c + N: zynq + N: xilinx +-F: drivers/clocksource/cadence_ttc_timer.c ++F: drivers/clocksource/timer-cadence-ttc.c + F: drivers/i2c/busses/i2c-cadence.c + F: drivers/mmc/host/sdhci-of-arasan.c + F: drivers/edac/synopsys_edac.c +diff --git a/Makefile b/Makefile +index 5cd8768fc083f..f110fc4f127fa 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 290 ++SUBLEVEL = 291 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h +index 225e7df2d8ed8..0733752ce7fe8 100644 +--- a/arch/arc/include/asm/entry-arcv2.h ++++ b/arch/arc/include/asm/entry-arcv2.h +@@ -7,232 +7,252 @@ + #include <asm/irqflags-arcv2.h> + #include <asm/thread_info.h> /* For THREAD_SIZE */ + ++/* ++ * Interrupt/Exception stack layout (pt_regs) for ARCv2 ++ * (End of struct aligned to end of page [unless nested]) ++ * ++ * INTERRUPT EXCEPTION ++ * ++ * manual --------------------- manual ++ * | orig_r0 | ++ * | event/ECR | ++ * | bta | ++ * | user_r25 | ++ * | gp | ++ * | fp | ++ * | sp | ++ * | r12 | ++ * | r30 | ++ * | r58 | ++ * | r59 | ++ * hw autosave --------------------- ++ * optional | r0 | ++ * | r1 | ++ * ~ ~ ++ * | r9 | ++ * | r10 | ++ * | r11 | ++ * | blink | ++ * | lpe | ++ * | lps | ++ * | lpc | ++ * | ei base | ++ * | ldi base | ++ * | jli base | ++ * --------------------- ++ * hw autosave | pc / eret | ++ * mandatory | stat32 / erstatus | ++ * --------------------- ++ */ ++ + /*------------------------------------------------------------------------*/ +-.macro INTERRUPT_PROLOGUE called_from ++.macro INTERRUPT_PROLOGUE + +- ; Before jumping to Interrupt Vector, hardware micro-ops did following: ++ ; (A) Before jumping to Interrupt Vector, hardware micro-ops did following: + ; 1. SP auto-switched to kernel mode stack +- ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0) +- ; 3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32 ++ ; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0) ++ ; 3. Auto save: (mandatory) Push PC and STAT32 on stack ++ ; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE ++ ; 4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI + ; +- ; Now manually save: r12, sp, fp, gp, r25 ++ ; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair + + #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE +-.ifnc \called_from, exception +- st.as r9, [sp, -10] ; save r9 in it's final stack slot +- sub sp, sp, 12 ; skip JLI, LDI, EI +- +- PUSH lp_count +- PUSHAX lp_start +- PUSHAX lp_end +- PUSH blink +- +- PUSH r11 +- PUSH r10 +- +- sub sp, sp, 4 ; skip r9 +- +- PUSH r8 +- PUSH r7 +- PUSH r6 +- PUSH r5 +- PUSH r4 +- PUSH r3 +- PUSH r2 +- PUSH r1 +- PUSH r0 +-.endif +-#endif ++ ; carve pt_regs on stack (case #3), PC/STAT32 already on stack ++ sub sp, sp, SZ_PT_REGS - 8 + +-#ifdef CONFIG_ARC_HAS_ACCL_REGS +- PUSH r59 +- PUSH r58 ++ __SAVE_REGFILE_HARD ++#else ++ ; carve pt_regs on stack (case #4), which grew partially already ++ sub sp, sp, PT_r0 + #endif + +- PUSH r30 +- PUSH r12 ++ __SAVE_REGFILE_SOFT ++.endm ++ ++/*------------------------------------------------------------------------*/ ++.macro EXCEPTION_PROLOGUE ++ ++ ; (A) Before jumping to Exception Vector, hardware micro-ops did following: ++ ; 1. SP auto-switched to kernel mode stack ++ ; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0) ++ ; ++ ; (B) Manually save the complete reg file below ++ ++ sub sp, sp, SZ_PT_REGS ; carve pt_regs ++ ++ ; _HARD saves r10 clobbered by _SOFT as scratch hence comes first ++ ++ __SAVE_REGFILE_HARD ++ __SAVE_REGFILE_SOFT ++ ++ st r0, [sp] ; orig_r0 ++ ++ lr r10, [eret] ++ lr r11, [erstatus] ++ ST2 r10, r11, PT_ret ++ ++ lr r10, [ecr] ++ lr r11, [erbta] ++ ST2 r10, r11, PT_event ++ mov r9, r10 ++ ++ ; OUTPUT: r9 has ECR ++.endm ++ ++/*------------------------------------------------------------------------ ++ * This macro saves the registers manually which would normally be autosaved ++ * by hardware on taken interrupts. It is used by ++ * - exception handlers (which don't have autosave) ++ * - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE ++ */ ++.macro __SAVE_REGFILE_HARD ++ ++ ST2 r0, r1, PT_r0 ++ ST2 r2, r3, PT_r2 ++ ST2 r4, r5, PT_r4 ++ ST2 r6, r7, PT_r6 ++ ST2 r8, r9, PT_r8 ++ ST2 r10, r11, PT_r10 ++ ++ st blink, [sp, PT_blink] ++ ++ lr r10, [lp_end] ++ lr r11, [lp_start] ++ ST2 r10, r11, PT_lpe ++ ++ st lp_count, [sp, PT_lpc] ++ ++ ; skip JLI, LDI, EI for now ++.endm ++ ++/*------------------------------------------------------------------------ ++ * This macros saves a bunch of other registers which can't be autosaved for ++ * various reasons: ++ * - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11 ++ * - r30: free reg, used by gcc as scratch ++ * - ACCL/ACCH pair when they exist ++ */ ++.macro __SAVE_REGFILE_SOFT ++ ++ ST2 gp, fp, PT_r26 ; gp (r26), fp (r27) ++ ++ st r12, [sp, PT_sp + 4] ++ st r30, [sp, PT_sp + 8] + + ; Saving pt_regs->sp correctly requires some extra work due to the way + ; Auto stack switch works + ; - U mode: retrieve it from AUX_USER_SP + ; - K mode: add the offset from current SP where H/w starts auto push + ; +- ; Utilize the fact that Z bit is set if Intr taken in U mode +- mov.nz r9, sp +- add.nz r9, r9, SZ_PT_REGS - PT_sp - 4 +- bnz 1f ++ ; 1. Utilize the fact that Z bit is set if Intr taken in U mode ++ ; 2. Upon entry SP is always saved (for any inspection, unwinding etc), ++ ; but on return, restored only if U mode + +- lr r9, [AUX_USER_SP] +-1: +- PUSH r9 ; SP ++ lr r10, [AUX_USER_SP] ; U mode SP ++ ++ ; ISA requires ADD.nz to have same dest and src reg operands ++ mov.nz r10, sp ++ add.nz r10, r10, SZ_PT_REGS ; K mode SP + +- PUSH fp +- PUSH gp ++ st r10, [sp, PT_sp] ; SP (pt_regs->sp) + + #ifdef CONFIG_ARC_CURR_IN_REG +- PUSH r25 ; user_r25 ++ st r25, [sp, PT_user_r25] + GET_CURR_TASK_ON_CPU r25 +-#else +- sub sp, sp, 4 + #endif + +-.ifnc \called_from, exception +- sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs +-.endif ++#ifdef CONFIG_ARC_HAS_ACCL_REGS ++ ST2 r58, r59, PT_sp + 12 ++#endif + + .endm + + /*------------------------------------------------------------------------*/ +-.macro INTERRUPT_EPILOGUE called_from ++.macro __RESTORE_REGFILE_SOFT + +-.ifnc \called_from, exception +- add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss +-.endif ++ LD2 gp, fp, PT_r26 ; gp (r26), fp (r27) + +-#ifdef CONFIG_ARC_CURR_IN_REG +- POP r25 +-#else +- add sp, sp, 4 +-#endif ++ ld r12, [sp, PT_sp + 4] ++ ld r30, [sp, PT_sp + 8] + +- POP gp +- POP fp +- +- ; Don't touch AUX_USER_SP if returning to K mode (Z bit set) +- ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE) +- add.z sp, sp, 4 ++ ; Restore SP (into AUX_USER_SP) only if returning to U mode ++ ; - for K mode, it will be implicitly restored as stack is unwound ++ ; - Z flag set on K is inverse of what hardware does on interrupt entry ++ ; but that doesn't really matter + bz 1f + +- POPAX AUX_USER_SP ++ ld r10, [sp, PT_sp] ; SP (pt_regs->sp) ++ sr r10, [AUX_USER_SP] + 1: +- POP r12 +- POP r30 + +-#ifdef CONFIG_ARC_HAS_ACCL_REGS +- POP r58 +- POP r59 ++#ifdef CONFIG_ARC_CURR_IN_REG ++ ld r25, [sp, PT_user_r25] + #endif + +-#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE +-.ifnc \called_from, exception +- POP r0 +- POP r1 +- POP r2 +- POP r3 +- POP r4 +- POP r5 +- POP r6 +- POP r7 +- POP r8 +- POP r9 +- POP r10 +- POP r11 +- +- POP blink +- POPAX lp_end +- POPAX lp_start +- +- POP r9 +- mov lp_count, r9 +- +- add sp, sp, 12 ; skip JLI, LDI, EI +- ld.as r9, [sp, -10] ; reload r9 which got clobbered +-.endif ++#ifdef CONFIG_ARC_HAS_ACCL_REGS ++ LD2 r58, r59, PT_sp + 12 + #endif ++.endm + ++/*------------------------------------------------------------------------*/ ++.macro __RESTORE_REGFILE_HARD ++ ++ ld blink, [sp, PT_blink] ++ ++ LD2 r10, r11, PT_lpe ++ sr r10, [lp_end] ++ sr r11, [lp_start] ++ ++ ld r10, [sp, PT_lpc] ; lp_count can't be target of LD ++ mov lp_count, r10 ++ ++ LD2 r0, r1, PT_r0 ++ LD2 r2, r3, PT_r2 ++ LD2 r4, r5, PT_r4 ++ LD2 r6, r7, PT_r6 ++ LD2 r8, r9, PT_r8 ++ LD2 r10, r11, PT_r10 + .endm + ++ + /*------------------------------------------------------------------------*/ +-.macro EXCEPTION_PROLOGUE ++.macro INTERRUPT_EPILOGUE + +- ; Before jumping to Exception Vector, hardware micro-ops did following: +- ; 1. SP auto-switched to kernel mode stack +- ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0) +- ; +- ; Now manually save the complete reg file +- +- PUSH r9 ; freeup a register: slot of erstatus +- +- PUSHAX eret +- sub sp, sp, 12 ; skip JLI, LDI, EI +- PUSH lp_count +- PUSHAX lp_start +- PUSHAX lp_end +- PUSH blink +- +- PUSH r11 +- PUSH r10 +- +- ld.as r9, [sp, 10] ; load stashed r9 (status32 stack slot) +- lr r10, [erstatus] +- st.as r10, [sp, 10] ; save status32 at it's right stack slot +- +- PUSH r9 +- PUSH r8 +- PUSH r7 +- PUSH r6 +- PUSH r5 +- PUSH r4 +- PUSH r3 +- PUSH r2 +- PUSH r1 +- PUSH r0 +- +- ; -- for interrupts, regs above are auto-saved by h/w in that order -- +- ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25) +- ; +- ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE) +- ; Although H/w exception micro-ops do set Z flag for U mode (just like +- ; for interrupts), it could get clobbered in case we soft land here from +- ; a TLB Miss exception handler (tlbex.S) ++ ; INPUT: r0 has STAT32 of calling context ++ ; INPUT: Z flag set if returning to K mode + +- and r10, r10, STATUS_U_MASK +- xor.f 0, r10, STATUS_U_MASK ++ ; _SOFT clobbers r10 restored by _HARD hence the order + +- INTERRUPT_PROLOGUE exception ++ __RESTORE_REGFILE_SOFT + +- PUSHAX erbta +- PUSHAX ecr ; r9 contains ECR, expected by EV_Trap ++#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE ++ __RESTORE_REGFILE_HARD ++ add sp, sp, SZ_PT_REGS - 8 ++#else ++ add sp, sp, PT_r0 ++#endif + +- PUSH r0 ; orig_r0 + .endm + + /*------------------------------------------------------------------------*/ + .macro EXCEPTION_EPILOGUE + +- ; Assumes r0 has PT_status32 +- btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE +- +- add sp, sp, 8 ; orig_r0/ECR don't need restoring +- POPAX erbta +- +- INTERRUPT_EPILOGUE exception ++ ; INPUT: r0 has STAT32 of calling context + +- POP r0 +- POP r1 +- POP r2 +- POP r3 +- POP r4 +- POP r5 +- POP r6 +- POP r7 +- POP r8 +- POP r9 +- POP r10 +- POP r11 ++ btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP + +- POP blink +- POPAX lp_end +- POPAX lp_start ++ ld r10, [sp, PT_event + 4] ++ sr r10, [erbta] + +- POP r9 +- mov lp_count, r9 ++ LD2 r10, r11, PT_ret ++ sr r10, [eret] ++ sr r11, [erstatus] + +- add sp, sp, 12 ; skip JLI, LDI, EI +- POPAX eret +- POPAX erstatus ++ __RESTORE_REGFILE_SOFT ++ __RESTORE_REGFILE_HARD + +- ld.as r9, [sp, -12] ; reload r9 which got clobbered ++ add sp, sp, SZ_PT_REGS + .endm + + .macro FAKE_RET_FROM_EXCPN +diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h +index 07c8e1a6c56e2..b89ca8b4d5975 100644 +--- a/arch/arc/include/asm/linkage.h ++++ b/arch/arc/include/asm/linkage.h +@@ -11,12 +11,30 @@ + + #include <asm/dwarf.h> + +-#ifdef __ASSEMBLY__ +- + #define ASM_NL ` /* use '`' to mark new line in macro */ + #define __ALIGN .align 4 + #define __ALIGN_STR __stringify(__ALIGN) + ++#ifdef __ASSEMBLY__ ++ ++.macro ST2 e, o, off ++#ifdef CONFIG_ARC_HAS_LL64 ++ std \e, [sp, \off] ++#else ++ st \e, [sp, \off] ++ st \o, [sp, \off+4] ++#endif ++.endm ++ ++.macro LD2 e, o, off ++#ifdef CONFIG_ARC_HAS_LL64 ++ ldd \e, [sp, \off] ++#else ++ ld \e, [sp, \off] ++ ld \o, [sp, \off+4] ++#endif ++.endm ++ + /* annotation for data we want in DCCM - if enabled in .config */ + .macro ARCFP_DATA nm + #ifdef CONFIG_ARC_HAS_DCCM +diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c +index ecaf34e9235c2..e90dccecfd833 100644 +--- a/arch/arc/kernel/asm-offsets.c ++++ b/arch/arc/kernel/asm-offsets.c +@@ -58,7 +58,14 @@ int main(void) + DEFINE(PT_r5, offsetof(struct pt_regs, r5)); + DEFINE(PT_r6, offsetof(struct pt_regs, r6)); + DEFINE(PT_r7, offsetof(struct pt_regs, r7)); ++ DEFINE(PT_r8, offsetof(struct pt_regs, r8)); ++ DEFINE(PT_r10, offsetof(struct pt_regs, r10)); ++ DEFINE(PT_r26, offsetof(struct pt_regs, r26)); + DEFINE(PT_ret, offsetof(struct pt_regs, ret)); ++ DEFINE(PT_blink, offsetof(struct pt_regs, blink)); ++ DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end)); ++ DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count)); ++ DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25)); + + DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); + DEFINE(SZ_PT_REGS, sizeof(struct pt_regs)); +diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S +index 562089d62d9d6..6cbf0ee8a20a7 100644 +--- a/arch/arc/kernel/entry-arcv2.S ++++ b/arch/arc/kernel/entry-arcv2.S +@@ -70,7 +70,7 @@ reserved: + + ENTRY(handle_interrupt) + +- INTERRUPT_PROLOGUE irq ++ INTERRUPT_PROLOGUE + + # irq control APIs local_irq_save/restore/disable/enable fiddle with + # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio) +@@ -226,7 +226,7 @@ debug_marker_l1: + bset.nz r11, r11, AUX_IRQ_ACT_BIT_U ; NZ means U + sr r11, [AUX_IRQ_ACT] + +- INTERRUPT_EPILOGUE irq ++ INTERRUPT_EPILOGUE + rtie + + ;####### Return from Exception / pure kernel mode ####### +diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S +index 0e1e47a67c736..e50cac799a518 100644 +--- a/arch/arc/mm/tlbex.S ++++ b/arch/arc/mm/tlbex.S +@@ -396,6 +396,17 @@ EV_TLBMissD_fast_ret: ; additional label for VDK OS-kit instrumentation + ;-------- Common routine to call Linux Page Fault Handler ----------- + do_slow_path_pf: + ++#ifdef CONFIG_ISA_ARCV2 ++ ; Set Z flag if exception in U mode. Hardware micro-ops do this on any ++ ; taken interrupt/exception, and thus is already the case at the entry ++ ; above, but ensuing code would have already clobbered. ++ ; EXCEPTION_PROLOGUE called in slow path, relies on correct Z flag set ++ ++ lr r2, [erstatus] ++ and r2, r2, STATUS_U_MASK ++ bxor.f 0, r2, STATUS_U_BIT ++#endif ++ + ; Restore the 4-scratch regs saved by fast path miss handler + TLBMISS_RESTORE_REGS + +diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi +index 6edc4bd1e7eaf..a6406a347690e 100644 +--- a/arch/arm/boot/dts/bcm5301x.dtsi ++++ b/arch/arm/boot/dts/bcm5301x.dtsi +@@ -468,7 +468,6 @@ + "spi_lr_session_done", + "spi_lr_overread"; + clocks = <&iprocmed>; +- clock-names = "iprocmed"; + num-cs = <2>; + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi +index d91cc532d0e2c..fcd7e4dc949a1 100644 +--- a/arch/arm/boot/dts/imx6qdl.dtsi ++++ b/arch/arm/boot/dts/imx6qdl.dtsi +@@ -46,6 +46,10 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg; ++ usb1 = &usbh1; ++ usb2 = &usbh2; ++ usb3 = &usbh3; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi +index afde0ed6d71af..b00f791471c66 100644 +--- a/arch/arm/boot/dts/imx6sl.dtsi ++++ b/arch/arm/boot/dts/imx6sl.dtsi +@@ -32,6 +32,9 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi +index d7d092a5522a3..9f0c82d79a361 100644 +--- a/arch/arm/boot/dts/imx6sll.dtsi ++++ b/arch/arm/boot/dts/imx6sll.dtsi +@@ -36,6 +36,8 @@ + spi1 = &ecspi2; + spi3 = &ecspi3; + spi4 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +@@ -49,20 +51,18 @@ + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; +- operating-points = < ++ operating-points = + /* kHz uV */ +- 996000 1275000 +- 792000 1175000 +- 396000 1075000 +- 198000 975000 +- >; +- fsl,soc-operating-points = < ++ <996000 1275000>, ++ <792000 1175000>, ++ <396000 1075000>, ++ <198000 975000>; ++ fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ +- 996000 1175000 +- 792000 1175000 +- 396000 1175000 +- 198000 1175000 +- >; ++ <996000 1175000>, ++ <792000 1175000>, ++ <396000 1175000>, ++ <198000 1175000>; + clock-latency = <61036>; /* two CLK32 periods */ + clocks = <&clks IMX6SLL_CLK_ARM>, + <&clks IMX6SLL_CLK_PLL2_PFD2>, +@@ -271,7 +271,7 @@ + status = "disabled"; + }; + +- ssi1: ssi-controller@2028000 { ++ ssi1: ssi@2028000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x02028000 0x4000>; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; +@@ -284,7 +284,7 @@ + status = "disabled"; + }; + +- ssi2: ssi-controller@202c000 { ++ ssi2: ssi@202c000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x0202c000 0x4000>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; +@@ -297,7 +297,7 @@ + status = "disabled"; + }; + +- ssi3: ssi-controller@2030000 { ++ ssi3: ssi@2030000 { + compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; + reg = <0x02030000 0x4000>; + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; +@@ -518,7 +518,7 @@ + reg = <0x020ca000 0x1000>; + interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6SLL_CLK_USBPHY2>; +- phy-reg_3p0-supply = <®_3p0>; ++ phy-3p0-supply = <®_3p0>; + fsl,anatop = <&anatop>; + }; + +diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi +index b9ab1118be30b..a0c0e631ebbe6 100644 +--- a/arch/arm/boot/dts/imx6sx.dtsi ++++ b/arch/arm/boot/dts/imx6sx.dtsi +@@ -49,6 +49,9 @@ + spi2 = &ecspi3; + spi3 = &ecspi4; + spi4 = &ecspi5; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi +index 334638ff50750..dcb187995f760 100644 +--- a/arch/arm/boot/dts/imx6ul.dtsi ++++ b/arch/arm/boot/dts/imx6ul.dtsi +@@ -47,6 +47,8 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi +index 7234e8330a576..34904f7eeb133 100644 +--- a/arch/arm/boot/dts/imx7d.dtsi ++++ b/arch/arm/boot/dts/imx7d.dtsi +@@ -7,6 +7,12 @@ + #include <dt-bindings/reset/imx7-reset.h> + + / { ++ aliases { ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; ++ }; ++ + cpus { + cpu0: cpu@0 { + clock-frequency = <996000000>; +diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi +index 7eaf96b425bed..8a6d698e253d2 100644 +--- a/arch/arm/boot/dts/imx7s.dtsi ++++ b/arch/arm/boot/dts/imx7s.dtsi +@@ -46,6 +46,8 @@ + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbh; + }; + + cpus { +diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c +index de998830f534f..b07956883e165 100644 +--- a/arch/arm/mach-ep93xx/timer-ep93xx.c ++++ b/arch/arm/mach-ep93xx/timer-ep93xx.c +@@ -9,6 +9,7 @@ + #include <linux/io.h> + #include <asm/mach/time.h> + #include "soc.h" ++#include "platform.h" + + /************************************************************************* + * Timer handling for EP93xx +@@ -60,7 +61,7 @@ static u64 notrace ep93xx_read_sched_clock(void) + return ret; + } + +-u64 ep93xx_clocksource_read(struct clocksource *c) ++static u64 ep93xx_clocksource_read(struct clocksource *c) + { + u64 ret; + +diff --git a/arch/arm/mach-orion5x/board-dt.c b/arch/arm/mach-orion5x/board-dt.c +index 3d36f1d951964..3f651df3a71cf 100644 +--- a/arch/arm/mach-orion5x/board-dt.c ++++ b/arch/arm/mach-orion5x/board-dt.c +@@ -63,6 +63,9 @@ static void __init orion5x_dt_init(void) + if (of_machine_is_compatible("maxtor,shared-storage-2")) + mss2_init(); + ++ if (of_machine_is_compatible("lacie,d2-network")) ++ d2net_init(); ++ + of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL); + } + +diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h +index eb96009e21c4c..b9cfdb4564568 100644 +--- a/arch/arm/mach-orion5x/common.h ++++ b/arch/arm/mach-orion5x/common.h +@@ -75,6 +75,12 @@ extern void mss2_init(void); + static inline void mss2_init(void) {} + #endif + ++#ifdef CONFIG_MACH_D2NET_DT ++void d2net_init(void); ++#else ++static inline void d2net_init(void) {} ++#endif ++ + /***************************************************************************** + * Helpers to access Orion registers + ****************************************************************************/ +diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c +index 575ec085cffaf..73bedccedb581 100644 +--- a/arch/arm/mach-sa1100/assabet.c ++++ b/arch/arm/mach-sa1100/assabet.c +@@ -570,7 +570,7 @@ static void __init map_sa1100_gpio_regs( void ) + */ + static void __init get_assabet_scr(void) + { +- unsigned long uninitialized_var(scr), i; ++ unsigned long scr, i; + + GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ + GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ +diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c +index 971119c294741..aa10e5e46ebb2 100644 +--- a/arch/arm/probes/kprobes/checkers-common.c ++++ b/arch/arm/probes/kprobes/checkers-common.c +@@ -48,7 +48,7 @@ enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn, + * Different from other insn uses imm8, the real addressing offset of + * STRD in T32 encoding should be imm8 * 4. See ARMARM description. + */ +-enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, ++static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, + struct arch_probes_insn *asi, + const struct decode_header *h) + { +diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c +index 62da8e2211e4b..0a7090a65bcad 100644 +--- a/arch/arm/probes/kprobes/core.c ++++ b/arch/arm/probes/kprobes/core.c +@@ -239,7 +239,7 @@ singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) + * kprobe, and that level is reserved for user kprobe handlers, so we can't + * risk encountering a new kprobe in an interrupt handler. + */ +-void __kprobes kprobe_handler(struct pt_regs *regs) ++static void __kprobes kprobe_handler(struct pt_regs *regs) + { + struct kprobe *p, *cur; + struct kprobe_ctlblk *kcb; +diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c +index cf08cb7267670..1516c340a0766 100644 +--- a/arch/arm/probes/kprobes/opt-arm.c ++++ b/arch/arm/probes/kprobes/opt-arm.c +@@ -158,8 +158,6 @@ __arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty) + } + } + +-extern void kprobe_handler(struct pt_regs *regs); +- + static void + optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) + { +diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c +index cc237fa9b90fb..1c86c5d980c5b 100644 +--- a/arch/arm/probes/kprobes/test-core.c ++++ b/arch/arm/probes/kprobes/test-core.c +@@ -723,7 +723,7 @@ static const char coverage_register_lookup[16] = { + [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP, + }; + +-unsigned coverage_start_registers(const struct decode_header *h) ++static unsigned coverage_start_registers(const struct decode_header *h) + { + unsigned regs = 0; + int i; +diff --git a/arch/arm/probes/kprobes/test-core.h b/arch/arm/probes/kprobes/test-core.h +index 94285203e9f74..459ebda077139 100644 +--- a/arch/arm/probes/kprobes/test-core.h ++++ b/arch/arm/probes/kprobes/test-core.h +@@ -456,3 +456,7 @@ void kprobe_thumb32_test_cases(void); + #else + void kprobe_arm_test_cases(void); + #endif ++ ++void __kprobes_test_case_start(void); ++void __kprobes_test_case_end_16(void); ++void __kprobes_test_case_end_32(void); +diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +index 636bab51de38d..40a54b55ababd 100644 +--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts ++++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +@@ -125,7 +125,7 @@ + status = "okay"; + clock-frequency = <100000>; + i2c-sda-falling-time-ns = <890>; /* hcnt */ +- i2c-sdl-falling-time-ns = <890>; /* lcnt */ ++ i2c-scl-falling-time-ns = <890>; /* lcnt */ + + adc@14 { + compatible = "lltc,ltc2497"; +diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +index 8bf3091a899c8..5abffdaf4077e 100644 +--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi ++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +@@ -165,7 +165,7 @@ + }; + + scif1_pins: scif1 { +- groups = "scif1_data_b", "scif1_ctrl"; ++ groups = "scif1_data_b"; + function = "scif1"; + }; + +@@ -178,7 +178,6 @@ + &scif1 { + pinctrl-0 = <&scif1_pins>; + pinctrl-names = "default"; +- uart-has-rtscts; + + status = "okay"; + }; +diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c +index 968b5f33e725e..1a8e20652e7ce 100644 +--- a/arch/ia64/kernel/process.c ++++ b/arch/ia64/kernel/process.c +@@ -444,7 +444,7 @@ static void + do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) + { + unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm; +- unsigned long uninitialized_var(ip); /* GCC be quiet */ ++ unsigned long ip; + elf_greg_t *dst = arg; + struct pt_regs *pt; + char nat; +diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c +index db3104c9fac53..33f68be018a22 100644 +--- a/arch/ia64/mm/discontig.c ++++ b/arch/ia64/mm/discontig.c +@@ -181,7 +181,7 @@ static void *per_cpu_node_setup(void *cpu_data, int node) + void __init setup_per_cpu_areas(void) + { + struct pcpu_alloc_info *ai; +- struct pcpu_group_info *uninitialized_var(gi); ++ struct pcpu_group_info *gi; + unsigned int *cpu_map; + void *base; + unsigned long base_offset; +diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c +index acf10eb9da15c..02470929fb393 100644 +--- a/arch/ia64/mm/tlb.c ++++ b/arch/ia64/mm/tlb.c +@@ -339,7 +339,7 @@ EXPORT_SYMBOL(flush_tlb_range); + + void ia64_tlb_init(void) + { +- ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */ ++ ia64_ptce_info_t ptce_info; + u64 tr_pgbits; + long status; + pal_vm_info_1_u_t vm_info_1; +diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug +index ffe0cf0f0bea2..923b3b794d13f 100644 +--- a/arch/powerpc/Kconfig.debug ++++ b/arch/powerpc/Kconfig.debug +@@ -232,7 +232,7 @@ config PPC_EARLY_DEBUG_40x + + config PPC_EARLY_DEBUG_CPM + bool "Early serial debugging for Freescale CPM-based serial ports" +- depends on SERIAL_CPM ++ depends on SERIAL_CPM=y + help + Select this to enable early debugging for Freescale chips + using a CPM-based serial port. This assumes that the bootwrapper +diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h +index f3f4710d4ff52..99129b0cd8b8a 100644 +--- a/arch/powerpc/include/asm/word-at-a-time.h ++++ b/arch/powerpc/include/asm/word-at-a-time.h +@@ -34,7 +34,7 @@ static inline long find_zero(unsigned long mask) + return leading_zero_bits >> 3; + } + +-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) ++static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) + { + unsigned long rhs = val | c->low_bits; + *data = rhs; +diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c +index a5091c0347475..aff86679af961 100644 +--- a/arch/powerpc/mm/init_64.c ++++ b/arch/powerpc/mm/init_64.c +@@ -266,8 +266,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, + start = _ALIGN_DOWN(start, page_size); + if (altmap) { + alt_start = altmap->base_pfn; +- alt_end = altmap->base_pfn + altmap->reserve + +- altmap->free + altmap->alloc + altmap->align; ++ alt_end = altmap->base_pfn + altmap->reserve + altmap->free; + } + + pr_debug("vmemmap_free %lx...%lx\n", start, end); +diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c +index fc98912f42cf6..76a8102bdb987 100644 +--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c ++++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c +@@ -340,7 +340,7 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, + { + int l1irq; + int l2irq; +- struct irq_chip *uninitialized_var(irqchip); ++ struct irq_chip *irqchip; + void *hndlr; + int type; + u32 reg; +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index bce678c7179c8..f272b662301e4 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -145,7 +145,7 @@ static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm) + + static inline int pcpu_stopped(struct pcpu *pcpu) + { +- u32 uninitialized_var(status); ++ u32 status; + + if (__pcpu_sigp(pcpu->address, SIGP_SENSE, + 0, &status) != SIGP_CC_STATUS_STORED) +diff --git a/arch/s390/kernel/sthyi.c b/arch/s390/kernel/sthyi.c +index 888cc2f166db7..ce6084e28d904 100644 +--- a/arch/s390/kernel/sthyi.c ++++ b/arch/s390/kernel/sthyi.c +@@ -460,9 +460,9 @@ static int sthyi_update_cache(u64 *rc) + * + * Fills the destination with system information returned by the STHYI + * instruction. The data is generated by emulation or execution of STHYI, +- * if available. The return value is the condition code that would be +- * returned, the rc parameter is the return code which is passed in +- * register R2 + 1. ++ * if available. The return value is either a negative error value or ++ * the condition code that would be returned, the rc parameter is the ++ * return code which is passed in register R2 + 1. + */ + int sthyi_fill(void *dst, u64 *rc) + { +diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c +index a389fa85cca2d..5450d43d26ea5 100644 +--- a/arch/s390/kvm/intercept.c ++++ b/arch/s390/kvm/intercept.c +@@ -360,8 +360,8 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu) + */ + int handle_sthyi(struct kvm_vcpu *vcpu) + { +- int reg1, reg2, r = 0; +- u64 code, addr, cc = 0, rc = 0; ++ int reg1, reg2, cc = 0, r = 0; ++ u64 code, addr, rc = 0; + struct sthyi_sctns *sctns = NULL; + + if (!test_kvm_facility(vcpu->kvm, 74)) +@@ -392,7 +392,10 @@ int handle_sthyi(struct kvm_vcpu *vcpu) + return -ENOMEM; + + cc = sthyi_fill(sctns, &rc); +- ++ if (cc < 0) { ++ free_page((unsigned long)sctns); ++ return cc; ++ } + out: + if (!cc) { + r = write_guest(vcpu, addr, reg2, sctns, PAGE_SIZE); +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 3aade928c18dd..92041d442d2e6 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -1716,6 +1716,10 @@ static unsigned long kvm_s390_next_dirty_cmma(struct kvm_memslots *slots, + ms = slots->memslots + slotidx; + ofs = 0; + } ++ ++ if (cur_gfn < ms->base_gfn) ++ ofs = 0; ++ + ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs); + while ((slotidx > 0) && (ofs >= ms->npages)) { + slotidx--; +diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c +index afde2a7d3eb35..e0679d8a9b34b 100644 +--- a/arch/sh/drivers/dma/dma-sh.c ++++ b/arch/sh/drivers/dma/dma-sh.c +@@ -21,6 +21,18 @@ + #include <cpu/dma-register.h> + #include <cpu/dma.h> + ++/* ++ * Some of the SoCs feature two DMAC modules. In such a case, the channels are ++ * distributed equally among them. ++ */ ++#ifdef SH_DMAC_BASE1 ++#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2) ++#else ++#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS ++#endif ++ ++#define SH_DMAC_CH_SZ 0x10 ++ + /* + * Define the default configuration for dual address memory-memory transfer. + * The 0x400 value represents auto-request, external->external. +@@ -32,7 +44,7 @@ static unsigned long dma_find_base(unsigned int chan) + unsigned long base = SH_DMAC_BASE0; + + #ifdef SH_DMAC_BASE1 +- if (chan >= 6) ++ if (chan >= SH_DMAC_NR_MD_CH) + base = SH_DMAC_BASE1; + #endif + +@@ -43,13 +55,13 @@ static unsigned long dma_base_addr(unsigned int chan) + { + unsigned long base = dma_find_base(chan); + +- /* Normalize offset calculation */ +- if (chan >= 9) +- chan -= 6; +- if (chan >= 4) +- base += 0x10; ++ chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ; ++ ++ /* DMAOR is placed inside the channel register space. Step over it. */ ++ if (chan >= DMAOR) ++ base += SH_DMAC_CH_SZ; + +- return base + (chan * 0x10); ++ return base + chan; + } + + #ifdef CONFIG_SH_DMA_IRQ_MULTI +@@ -253,12 +265,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) + #define NR_DMAOR 1 + #endif + +-/* +- * DMAOR bases are broken out amongst channel groups. DMAOR0 manages +- * channels 0 - 5, DMAOR1 6 - 11 (optional). +- */ +-#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) +-#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6) ++#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \ ++ SH_DMAC_NR_MD_CH) + DMAOR) ++#define dmaor_write_reg(n, data) __raw_writew(data, \ ++ dma_find_base((n) * \ ++ SH_DMAC_NR_MD_CH) + DMAOR) + + static inline int dmaor_reset(int no) + { +diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c +index a5bd036426789..75dcb1d6bc62f 100644 +--- a/arch/sh/kernel/cpu/sh2/probe.c ++++ b/arch/sh/kernel/cpu/sh2/probe.c +@@ -24,7 +24,7 @@ static int __init scan_cache(unsigned long node, const char *uname, + if (!of_flat_dt_is_compatible(node, "jcore,cache")) + return 0; + +- j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); ++ j2_ccr_base = ioremap(of_flat_dt_translate_address(node), 4); + + return 1; + } +diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c +index 736348ead4218..2ecf1dcc86b20 100644 +--- a/arch/x86/kernel/quirks.c ++++ b/arch/x86/kernel/quirks.c +@@ -96,7 +96,7 @@ static void ich_force_hpet_resume(void) + static void ich_force_enable_hpet(struct pci_dev *dev) + { + u32 val; +- u32 uninitialized_var(rcba); ++ u32 rcba; + int err = 0; + + if (hpet_address || force_hpet_address) +@@ -186,7 +186,7 @@ static void hpet_print_force_info(void) + static void old_ich_force_hpet_resume(void) + { + u32 val; +- u32 uninitialized_var(gen_cntl); ++ u32 gen_cntl; + + if (!force_hpet_address || !cached_dev) + return; +@@ -208,7 +208,7 @@ static void old_ich_force_hpet_resume(void) + static void old_ich_force_enable_hpet(struct pci_dev *dev) + { + u32 val; +- u32 uninitialized_var(gen_cntl); ++ u32 gen_cntl; + + if (hpet_address || force_hpet_address) + return; +@@ -299,7 +299,7 @@ static void vt8237_force_hpet_resume(void) + + static void vt8237_force_enable_hpet(struct pci_dev *dev) + { +- u32 uninitialized_var(val); ++ u32 val; + + if (hpet_address || force_hpet_address) + return; +@@ -430,7 +430,7 @@ static void nvidia_force_hpet_resume(void) + + static void nvidia_force_enable_hpet(struct pci_dev *dev) + { +- u32 uninitialized_var(val); ++ u32 val; + + if (hpet_address || force_hpet_address) + return; +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 1f1298f6cbc26..2e4f6a1ebca56 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -96,6 +96,17 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); + DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info); + EXPORT_PER_CPU_SYMBOL(cpu_info); + ++struct mwait_cpu_dead { ++ unsigned int control; ++ unsigned int status; ++}; ++ ++/* ++ * Cache line aligned data for mwait_play_dead(). Separate on purpose so ++ * that it's unlikely to be touched by other CPUs. ++ */ ++static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead); ++ + /* Logical package management. We might want to allocate that dynamically */ + unsigned int __max_logical_packages __read_mostly; + EXPORT_SYMBOL(__max_logical_packages); +@@ -1595,10 +1606,10 @@ static bool wakeup_cpu0(void) + */ + static inline void mwait_play_dead(void) + { ++ struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead); + unsigned int eax, ebx, ecx, edx; + unsigned int highest_cstate = 0; + unsigned int highest_subcstate = 0; +- void *mwait_ptr; + int i; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) +@@ -1632,13 +1643,6 @@ static inline void mwait_play_dead(void) + (highest_subcstate - 1); + } + +- /* +- * This should be a memory location in a cache line which is +- * unlikely to be touched by other processors. The actual +- * content is immaterial as it is not actually modified in any way. +- */ +- mwait_ptr = ¤t_thread_info()->flags; +- + wbinvd(); + + while (1) { +@@ -1650,9 +1654,9 @@ static inline void mwait_play_dead(void) + * case where we return around the loop. + */ + mb(); +- clflush(mwait_ptr); ++ clflush(md); + mb(); +- __monitor(mwait_ptr, 0, 0); ++ __monitor(md, 0, 0); + mb(); + __mwait(eax, 0); + /* +diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c +index d027dddc41cad..f49329aabec80 100644 +--- a/arch/xtensa/platforms/iss/network.c ++++ b/arch/xtensa/platforms/iss/network.c +@@ -236,7 +236,7 @@ static int tuntap_probe(struct iss_net_private *lp, int index, char *init) + + init += sizeof(TRANSPORT_TUNTAP_NAME) - 1; + if (*init == ',') { +- rem = split_if_spec(init + 1, &mac_str, &dev_name); ++ rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL); + if (rem != NULL) { + pr_err("%s: extra garbage on specification : '%s'\n", + dev->name, rem); +diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c +index 552c1f725b6cf..40188632958cd 100644 +--- a/drivers/acpi/acpi_pad.c ++++ b/drivers/acpi/acpi_pad.c +@@ -95,7 +95,7 @@ static void round_robin_cpu(unsigned int tsk_index) + cpumask_var_t tmp; + int cpu; + unsigned long min_weight = -1; +- unsigned long uninitialized_var(preferred_cpu); ++ unsigned long preferred_cpu; + + if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) + return; +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 957f6b28bceaa..2295b74714e15 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -178,7 +178,7 @@ static ssize_t ata_scsi_park_show(struct device *device, + struct ata_link *link; + struct ata_device *dev; + unsigned long now; +- unsigned int uninitialized_var(msecs); ++ unsigned int msecs; + int rc = 0; + + ap = ata_shost_to_port(sdev->host); +diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c +index 84c6b225b56e9..9ee4aefca8675 100644 +--- a/drivers/ata/pata_ns87415.c ++++ b/drivers/ata/pata_ns87415.c +@@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap) + * LOCKING: + * Inherited from caller. + */ +-void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) ++static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) + { + struct ata_ioports *ioaddr = &ap->ioaddr; + +diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c +index d5c76b50d3575..88f810745fd89 100644 +--- a/drivers/atm/zatm.c ++++ b/drivers/atm/zatm.c +@@ -939,7 +939,7 @@ static int open_tx_first(struct atm_vcc *vcc) + vcc->qos.txtp.max_pcr >= ATM_OC3_PCR); + if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr; + else { +- int uninitialized_var(pcr); ++ int pcr; + + if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU; + if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr, +diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c +index e7cb0c6ade81e..d89f618231cb1 100644 +--- a/drivers/base/arch_topology.c ++++ b/drivers/base/arch_topology.c +@@ -44,7 +44,7 @@ static ssize_t cpu_capacity_show(struct device *dev, + { + struct cpu *cpu = container_of(dev, struct cpu, dev); + +- return sprintf(buf, "%lu\n", topology_get_cpu_scale(NULL, cpu->dev.id)); ++ return sysfs_emit(buf, "%lu\n", topology_get_cpu_scale(NULL, cpu->dev.id)); + } + + static ssize_t cpu_capacity_store(struct device *dev, +diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c +index ce015ce2977c4..51eb403f89de6 100644 +--- a/drivers/base/cacheinfo.c ++++ b/drivers/base/cacheinfo.c +@@ -372,7 +372,7 @@ static ssize_t size_show(struct device *dev, + { + struct cacheinfo *this_leaf = dev_get_drvdata(dev); + +- return sprintf(buf, "%uK\n", this_leaf->size >> 10); ++ return sysfs_emit(buf, "%uK\n", this_leaf->size >> 10); + } + + static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) +@@ -402,11 +402,11 @@ static ssize_t type_show(struct device *dev, + + switch (this_leaf->type) { + case CACHE_TYPE_DATA: +- return sprintf(buf, "Data\n"); ++ return sysfs_emit(buf, "Data\n"); + case CACHE_TYPE_INST: +- return sprintf(buf, "Instruction\n"); ++ return sysfs_emit(buf, "Instruction\n"); + case CACHE_TYPE_UNIFIED: +- return sprintf(buf, "Unified\n"); ++ return sysfs_emit(buf, "Unified\n"); + default: + return -EINVAL; + } +@@ -420,11 +420,11 @@ static ssize_t allocation_policy_show(struct device *dev, + int n = 0; + + if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE)) +- n = sprintf(buf, "ReadWriteAllocate\n"); ++ n = sysfs_emit(buf, "ReadWriteAllocate\n"); + else if (ci_attr & CACHE_READ_ALLOCATE) +- n = sprintf(buf, "ReadAllocate\n"); ++ n = sysfs_emit(buf, "ReadAllocate\n"); + else if (ci_attr & CACHE_WRITE_ALLOCATE) +- n = sprintf(buf, "WriteAllocate\n"); ++ n = sysfs_emit(buf, "WriteAllocate\n"); + return n; + } + +@@ -436,9 +436,9 @@ static ssize_t write_policy_show(struct device *dev, + int n = 0; + + if (ci_attr & CACHE_WRITE_THROUGH) +- n = sprintf(buf, "WriteThrough\n"); ++ n = sysfs_emit(buf, "WriteThrough\n"); + else if (ci_attr & CACHE_WRITE_BACK) +- n = sprintf(buf, "WriteBack\n"); ++ n = sysfs_emit(buf, "WriteBack\n"); + return n; + } + +diff --git a/drivers/base/core.c b/drivers/base/core.c +index 6e380ad9d08ad..0332800dffd86 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -994,7 +994,7 @@ ssize_t device_show_ulong(struct device *dev, + char *buf) + { + struct dev_ext_attribute *ea = to_ext_attr(attr); +- return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); ++ return sysfs_emit(buf, "%lx\n", *(unsigned long *)(ea->var)); + } + EXPORT_SYMBOL_GPL(device_show_ulong); + +@@ -1019,7 +1019,7 @@ ssize_t device_show_int(struct device *dev, + { + struct dev_ext_attribute *ea = to_ext_attr(attr); + +- return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); ++ return sysfs_emit(buf, "%d\n", *(int *)(ea->var)); + } + EXPORT_SYMBOL_GPL(device_show_int); + +@@ -1040,7 +1040,7 @@ ssize_t device_show_bool(struct device *dev, struct device_attribute *attr, + { + struct dev_ext_attribute *ea = to_ext_attr(attr); + +- return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); ++ return sysfs_emit(buf, "%d\n", *(bool *)(ea->var)); + } + EXPORT_SYMBOL_GPL(device_show_bool); + +@@ -1273,7 +1273,7 @@ static ssize_t online_show(struct device *dev, struct device_attribute *attr, + device_lock(dev); + val = !dev->offline; + device_unlock(dev); +- return sprintf(buf, "%u\n", val); ++ return sysfs_emit(buf, "%u\n", val); + } + + static ssize_t online_store(struct device *dev, struct device_attribute *attr, +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index b1bb6f43f8962..607fc189e57c5 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -156,7 +156,7 @@ static ssize_t show_crash_notes(struct device *dev, struct device_attribute *att + * operation should be safe. No locking required. + */ + addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum)); +- rc = sprintf(buf, "%Lx\n", addr); ++ rc = sysfs_emit(buf, "%Lx\n", addr); + return rc; + } + static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); +@@ -167,7 +167,7 @@ static ssize_t show_crash_notes_size(struct device *dev, + { + ssize_t rc; + +- rc = sprintf(buf, "%zu\n", sizeof(note_buf_t)); ++ rc = sysfs_emit(buf, "%zu\n", sizeof(note_buf_t)); + return rc; + } + static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL); +@@ -264,7 +264,7 @@ static ssize_t print_cpus_offline(struct device *dev, + nr_cpu_ids, total_cpus-1); + } + +- n += snprintf(&buf[n], len - n, "\n"); ++ n += sysfs_emit(&buf[n], "\n"); + return n; + } + static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); +@@ -272,7 +272,7 @@ static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL); + static ssize_t print_cpus_isolated(struct device *dev, + struct device_attribute *attr, char *buf) + { +- int n = 0, len = PAGE_SIZE-2; ++ int n = 0; + cpumask_var_t isolated; + + if (!alloc_cpumask_var(&isolated, GFP_KERNEL)) +@@ -280,7 +280,7 @@ static ssize_t print_cpus_isolated(struct device *dev, + + cpumask_andnot(isolated, cpu_possible_mask, + housekeeping_cpumask(HK_FLAG_DOMAIN)); +- n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(isolated)); ++ n = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated)); + + free_cpumask_var(isolated); + +@@ -292,9 +292,9 @@ static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL); + static ssize_t print_cpus_nohz_full(struct device *dev, + struct device_attribute *attr, char *buf) + { +- int n = 0, len = PAGE_SIZE-2; ++ int n = 0; + +- n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); ++ n = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); + + return n; + } +@@ -328,7 +328,7 @@ static ssize_t print_cpu_modalias(struct device *dev, + ssize_t n; + u32 i; + +- n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:", ++ n = sysfs_emit(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:", + CPU_FEATURE_TYPEVAL); + + for (i = 0; i < MAX_CPU_FEATURES; i++) +@@ -520,56 +520,56 @@ static void __init cpu_dev_register_generic(void) + ssize_t __weak cpu_show_meltdown(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_spectre_v1(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_spectre_v2(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_spec_store_bypass(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_l1tf(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_mds(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_tsx_async_abort(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_itlb_multihit(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_srbds(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "Not affected\n"); ++ return sysfs_emit(buf, "Not affected\n"); + } + + ssize_t __weak cpu_show_mmio_stale_data(struct device *dev, +diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c +index 821e27bda4ca2..2116926cc1d57 100644 +--- a/drivers/base/firmware_loader/fallback.c ++++ b/drivers/base/firmware_loader/fallback.c +@@ -215,7 +215,7 @@ static ssize_t firmware_loading_show(struct device *dev, + loading = fw_sysfs_loading(fw_sysfs->fw_priv); + mutex_unlock(&fw_lock); + +- return sprintf(buf, "%d\n", loading); ++ return sysfs_emit(buf, "%d\n", loading); + } + + /* one pages buffer should be mapped/unmapped only once */ +diff --git a/drivers/base/memory.c b/drivers/base/memory.c +index e270abc86d468..5dbe00a5c7c14 100644 +--- a/drivers/base/memory.c ++++ b/drivers/base/memory.c +@@ -121,7 +121,7 @@ static ssize_t show_mem_start_phys_index(struct device *dev, + unsigned long phys_index; + + phys_index = mem->start_section_nr / sections_per_block; +- return sprintf(buf, "%08lx\n", phys_index); ++ return sysfs_emit(buf, "%08lx\n", phys_index); + } + + /* +@@ -145,7 +145,7 @@ static ssize_t show_mem_removable(struct device *dev, + } + + out: +- return sprintf(buf, "%d\n", ret); ++ return sysfs_emit(buf, "%d\n", ret); + } + + /* +@@ -163,17 +163,17 @@ static ssize_t show_mem_state(struct device *dev, + */ + switch (mem->state) { + case MEM_ONLINE: +- len = sprintf(buf, "online\n"); ++ len = sysfs_emit(buf, "online\n"); + break; + case MEM_OFFLINE: +- len = sprintf(buf, "offline\n"); ++ len = sysfs_emit(buf, "offline\n"); + break; + case MEM_GOING_OFFLINE: +- len = sprintf(buf, "going-offline\n"); ++ len = sysfs_emit(buf, "going-offline\n"); + break; + default: +- len = sprintf(buf, "ERROR-UNKNOWN-%ld\n", +- mem->state); ++ len = sysfs_emit(buf, "ERROR-UNKNOWN-%ld\n", ++ mem->state); + WARN_ON(1); + break; + } +@@ -384,7 +384,7 @@ static ssize_t show_phys_device(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct memory_block *mem = to_memory_block(dev); +- return sprintf(buf, "%d\n", mem->phys_device); ++ return sysfs_emit(buf, "%d\n", mem->phys_device); + } + + #ifdef CONFIG_MEMORY_HOTREMOVE +@@ -422,7 +422,7 @@ static ssize_t show_valid_zones(struct device *dev, + */ + if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages, + &valid_start_pfn, &valid_end_pfn)) +- return sprintf(buf, "none\n"); ++ return sysfs_emit(buf, "none\n"); + start_pfn = valid_start_pfn; + strcat(buf, page_zone(pfn_to_page(start_pfn))->name); + goto out; +@@ -456,7 +456,7 @@ static ssize_t + print_block_size(struct device *dev, struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%lx\n", get_memory_block_size()); ++ return sysfs_emit(buf, "%lx\n", get_memory_block_size()); + } + + static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL); +@@ -470,9 +470,9 @@ show_auto_online_blocks(struct device *dev, struct device_attribute *attr, + char *buf) + { + if (memhp_auto_online) +- return sprintf(buf, "online\n"); ++ return sysfs_emit(buf, "online\n"); + else +- return sprintf(buf, "offline\n"); ++ return sysfs_emit(buf, "offline\n"); + } + + static ssize_t +diff --git a/drivers/base/node.c b/drivers/base/node.c +index 60c2e32f9f614..8defeace001ec 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -69,7 +69,7 @@ static ssize_t node_read_meminfo(struct device *dev, + struct sysinfo i; + + si_meminfo_node(&i, nid); +- n = sprintf(buf, ++ n = sysfs_emit(buf, + "Node %d MemTotal: %8lu kB\n" + "Node %d MemFree: %8lu kB\n" + "Node %d MemUsed: %8lu kB\n" +@@ -96,7 +96,7 @@ static ssize_t node_read_meminfo(struct device *dev, + nid, K(sum_zone_node_page_state(nid, NR_MLOCK))); + + #ifdef CONFIG_HIGHMEM +- n += sprintf(buf + n, ++ n += sysfs_emit(buf + n, + "Node %d HighTotal: %8lu kB\n" + "Node %d HighFree: %8lu kB\n" + "Node %d LowTotal: %8lu kB\n" +@@ -106,7 +106,7 @@ static ssize_t node_read_meminfo(struct device *dev, + nid, K(i.totalram - i.totalhigh), + nid, K(i.freeram - i.freehigh)); + #endif +- n += sprintf(buf + n, ++ n += sysfs_emit(buf + n, + "Node %d Dirty: %8lu kB\n" + "Node %d Writeback: %8lu kB\n" + "Node %d FilePages: %8lu kB\n" +@@ -162,19 +162,19 @@ static DEVICE_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL); + static ssize_t node_read_numastat(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, +- "numa_hit %lu\n" +- "numa_miss %lu\n" +- "numa_foreign %lu\n" +- "interleave_hit %lu\n" +- "local_node %lu\n" +- "other_node %lu\n", +- sum_zone_numa_state(dev->id, NUMA_HIT), +- sum_zone_numa_state(dev->id, NUMA_MISS), +- sum_zone_numa_state(dev->id, NUMA_FOREIGN), +- sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT), +- sum_zone_numa_state(dev->id, NUMA_LOCAL), +- sum_zone_numa_state(dev->id, NUMA_OTHER)); ++ return sysfs_emit(buf, ++ "numa_hit %lu\n" ++ "numa_miss %lu\n" ++ "numa_foreign %lu\n" ++ "interleave_hit %lu\n" ++ "local_node %lu\n" ++ "other_node %lu\n", ++ sum_zone_numa_state(dev->id, NUMA_HIT), ++ sum_zone_numa_state(dev->id, NUMA_MISS), ++ sum_zone_numa_state(dev->id, NUMA_FOREIGN), ++ sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT), ++ sum_zone_numa_state(dev->id, NUMA_LOCAL), ++ sum_zone_numa_state(dev->id, NUMA_OTHER)); + } + static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); + +@@ -612,7 +612,7 @@ static ssize_t print_nodes_state(enum node_states state, char *buf) + { + int n; + +- n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", ++ n = sysfs_emit(buf, "%*pbl", + nodemask_pr_args(&node_states[state])); + buf[n++] = '\n'; + buf[n] = '\0'; +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 2f89e618b142c..1819da6889a71 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -927,7 +927,7 @@ static ssize_t driver_override_show(struct device *dev, + ssize_t len; + + device_lock(dev); +- len = sprintf(buf, "%s\n", pdev->driver_override); ++ len = sysfs_emit(buf, "%s\n", pdev->driver_override); + device_unlock(dev); + return len; + } +diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c +index e865aa4b25047..b32d3cf4f670d 100644 +--- a/drivers/base/power/domain.c ++++ b/drivers/base/power/domain.c +@@ -2433,10 +2433,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state, + + err = of_property_read_u32(state_node, "min-residency-us", &residency); + if (!err) +- genpd_state->residency_ns = 1000 * residency; ++ genpd_state->residency_ns = 1000LL * residency; + +- genpd_state->power_on_latency_ns = 1000 * exit_latency; +- genpd_state->power_off_latency_ns = 1000 * entry_latency; ++ genpd_state->power_on_latency_ns = 1000LL * exit_latency; ++ genpd_state->power_off_latency_ns = 1000LL * entry_latency; + genpd_state->fwnode = &state_node->fwnode; + + return 0; +diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h +index c511def48b486..3f9934bd6137d 100644 +--- a/drivers/base/power/power.h ++++ b/drivers/base/power/power.h +@@ -24,8 +24,11 @@ extern void pm_runtime_remove(struct device *dev); + + #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) + #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) ++#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) + #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ +- WAKE_IRQ_DEDICATED_MANAGED) ++ WAKE_IRQ_DEDICATED_MANAGED | \ ++ WAKE_IRQ_DEDICATED_REVERSE) ++#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) + + struct wake_irq { + struct device *dev; +@@ -38,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_enable_wake_irq_check(struct device *dev, + bool can_change_status); +-extern void dev_pm_disable_wake_irq_check(struct device *dev); ++extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); ++extern void dev_pm_enable_wake_irq_complete(struct device *dev); + + #ifdef CONFIG_PM_SLEEP + +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 911bb8a4bf6df..ab0898c33880a 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -606,6 +606,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) + if (retval) + goto fail; + ++ dev_pm_enable_wake_irq_complete(dev); ++ + no_callback: + __update_runtime_status(dev, RPM_SUSPENDED); + pm_runtime_deactivate_timer(dev); +@@ -640,7 +642,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) + return retval; + + fail: +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, true); + __update_runtime_status(dev, RPM_ACTIVE); + dev->power.deferred_resume = false; + wake_up_all(&dev->power.wait_queue); +@@ -823,7 +825,7 @@ static int rpm_resume(struct device *dev, int rpmflags) + + callback = RPM_GET_CALLBACK(dev, runtime_resume); + +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, false); + retval = rpm_callback(callback, dev); + if (retval) { + __update_runtime_status(dev, RPM_SUSPENDED); +diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c +index d713738ce7967..c61b50aa1d818 100644 +--- a/drivers/base/power/sysfs.c ++++ b/drivers/base/power/sysfs.c +@@ -101,7 +101,7 @@ static const char ctrl_on[] = "on"; + static ssize_t control_show(struct device *dev, struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%s\n", ++ return sysfs_emit(buf, "%s\n", + dev->power.runtime_auto ? ctrl_auto : ctrl_on); + } + +@@ -127,7 +127,7 @@ static ssize_t runtime_active_time_show(struct device *dev, + int ret; + spin_lock_irq(&dev->power.lock); + update_pm_runtime_accounting(dev); +- ret = sprintf(buf, "%i\n", jiffies_to_msecs(dev->power.active_jiffies)); ++ ret = sysfs_emit(buf, "%i\n", jiffies_to_msecs(dev->power.active_jiffies)); + spin_unlock_irq(&dev->power.lock); + return ret; + } +@@ -140,7 +140,7 @@ static ssize_t runtime_suspended_time_show(struct device *dev, + int ret; + spin_lock_irq(&dev->power.lock); + update_pm_runtime_accounting(dev); +- ret = sprintf(buf, "%i\n", ++ ret = sysfs_emit(buf, "%i\n", + jiffies_to_msecs(dev->power.suspended_jiffies)); + spin_unlock_irq(&dev->power.lock); + return ret; +@@ -175,7 +175,7 @@ static ssize_t runtime_status_show(struct device *dev, + return -EIO; + } + } +- return sprintf(buf, p); ++ return sysfs_emit(buf, p); + } + + static DEVICE_ATTR_RO(runtime_status); +@@ -185,7 +185,7 @@ static ssize_t autosuspend_delay_ms_show(struct device *dev, + { + if (!dev->power.use_autosuspend) + return -EIO; +- return sprintf(buf, "%d\n", dev->power.autosuspend_delay); ++ return sysfs_emit(buf, "%d\n", dev->power.autosuspend_delay); + } + + static ssize_t autosuspend_delay_ms_store(struct device *dev, +@@ -214,11 +214,11 @@ static ssize_t pm_qos_resume_latency_us_show(struct device *dev, + s32 value = dev_pm_qos_requested_resume_latency(dev); + + if (value == 0) +- return sprintf(buf, "n/a\n"); ++ return sysfs_emit(buf, "n/a\n"); + if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) + value = 0; + +- return sprintf(buf, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t pm_qos_resume_latency_us_store(struct device *dev, +@@ -258,11 +258,11 @@ static ssize_t pm_qos_latency_tolerance_us_show(struct device *dev, + s32 value = dev_pm_qos_get_user_latency_tolerance(dev); + + if (value < 0) +- return sprintf(buf, "auto\n"); ++ return sysfs_emit(buf, "auto\n"); + if (value == PM_QOS_LATENCY_ANY) +- return sprintf(buf, "any\n"); ++ return sysfs_emit(buf, "any\n"); + +- return sprintf(buf, "%d\n", value); ++ return sysfs_emit(buf, "%d\n", value); + } + + static ssize_t pm_qos_latency_tolerance_us_store(struct device *dev, +@@ -294,8 +294,8 @@ static ssize_t pm_qos_no_power_off_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) +- & PM_QOS_FLAG_NO_POWER_OFF)); ++ return sysfs_emit(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) ++ & PM_QOS_FLAG_NO_POWER_OFF)); + } + + static ssize_t pm_qos_no_power_off_store(struct device *dev, +@@ -323,9 +323,9 @@ static const char _disabled[] = "disabled"; + static ssize_t wakeup_show(struct device *dev, struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%s\n", device_can_wakeup(dev) +- ? (device_may_wakeup(dev) ? _enabled : _disabled) +- : ""); ++ return sysfs_emit(buf, "%s\n", device_can_wakeup(dev) ++ ? (device_may_wakeup(dev) ? _enabled : _disabled) ++ : ""); + } + + static ssize_t wakeup_store(struct device *dev, struct device_attribute *attr, +@@ -511,7 +511,7 @@ static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms); + static ssize_t runtime_usage_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count)); ++ return sysfs_emit(buf, "%d\n", atomic_read(&dev->power.usage_count)); + } + static DEVICE_ATTR_RO(runtime_usage); + +@@ -519,8 +519,8 @@ static ssize_t runtime_active_kids_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%d\n", dev->power.ignore_children ? +- 0 : atomic_read(&dev->power.child_count)); ++ return sysfs_emit(buf, "%d\n", dev->power.ignore_children ? ++ 0 : atomic_read(&dev->power.child_count)); + } + static DEVICE_ATTR_RO(runtime_active_kids); + +@@ -528,12 +528,12 @@ static ssize_t runtime_enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + if (dev->power.disable_depth && (dev->power.runtime_auto == false)) +- return sprintf(buf, "disabled & forbidden\n"); ++ return sysfs_emit(buf, "disabled & forbidden\n"); + if (dev->power.disable_depth) +- return sprintf(buf, "disabled\n"); ++ return sysfs_emit(buf, "disabled\n"); + if (dev->power.runtime_auto == false) +- return sprintf(buf, "forbidden\n"); +- return sprintf(buf, "enabled\n"); ++ return sysfs_emit(buf, "forbidden\n"); ++ return sysfs_emit(buf, "enabled\n"); + } + static DEVICE_ATTR_RO(runtime_enabled); + +@@ -541,9 +541,9 @@ static DEVICE_ATTR_RO(runtime_enabled); + static ssize_t async_show(struct device *dev, struct device_attribute *attr, + char *buf) + { +- return sprintf(buf, "%s\n", +- device_async_suspend_enabled(dev) ? +- _enabled : _disabled); ++ return sysfs_emit(buf, "%s\n", ++ device_async_suspend_enabled(dev) ? ++ _enabled : _disabled); + } + + static ssize_t async_store(struct device *dev, struct device_attribute *attr, +diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c +index b8fa5c0f2d132..e7ba514999163 100644 +--- a/drivers/base/power/wakeirq.c ++++ b/drivers/base/power/wakeirq.c +@@ -156,24 +156,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq) + return IRQ_HANDLED; + } + +-/** +- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt +- * @dev: Device entry +- * @irq: Device wake-up interrupt +- * +- * Unless your hardware has separate wake-up interrupts in addition +- * to the device IO interrupts, you don't need this. +- * +- * Sets up a threaded interrupt handler for a device that has +- * a dedicated wake-up interrupt in addition to the device IO +- * interrupt. +- * +- * The interrupt starts disabled, and needs to be managed for +- * the device by the bus code or the device driver using +- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() +- * functions. +- */ +-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) + { + struct wake_irq *wirq; + int err; +@@ -211,7 +194,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + if (err) + goto err_free_irq; + +- wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; ++ wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; + + return err; + +@@ -224,8 +207,57 @@ err_free: + + return err; + } ++ ++ ++/** ++ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has ++ * a dedicated wake-up interrupt in addition to the device IO ++ * interrupt. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); ++} + EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); + ++/** ++ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt ++ * with reverse enable ordering ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has a dedicated ++ * wake-up interrupt in addition to the device IO interrupt. It sets ++ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() ++ * to enable dedicated wake-up interrupt after running the runtime suspend ++ * callback for @dev. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); ++} ++EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); ++ + /** + * dev_pm_enable_wake_irq - Enable device wake-up interrupt + * @dev: Device +@@ -296,25 +328,56 @@ void dev_pm_enable_wake_irq_check(struct device *dev, + return; + + enable: +- enable_irq(wirq->irq); ++ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { ++ enable_irq(wirq->irq); ++ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; ++ } + } + + /** + * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt + * @dev: Device ++ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE + * + * Disables wake-up interrupt conditionally based on status. + * Should be only called from rpm_suspend() and rpm_resume() path. + */ +-void dev_pm_disable_wake_irq_check(struct device *dev) ++void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) + { + struct wake_irq *wirq = dev->power.wakeirq; + + if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK))) + return; + +- if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) ++ if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) ++ return; ++ ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { ++ wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; + disable_irq_nosync(wirq->irq); ++ } ++} ++ ++/** ++ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before ++ * @dev: Device using the wake IRQ ++ * ++ * Enable wake IRQ conditionally based on status, mainly used if want to ++ * enable wake IRQ after running ->runtime_suspend() which depends on ++ * WAKE_IRQ_DEDICATED_REVERSE. ++ * ++ * Should be only called from rpm_suspend() path. ++ */ ++void dev_pm_enable_wake_irq_complete(struct device *dev) ++{ ++ struct wake_irq *wirq = dev->power.wakeirq; ++ ++ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) ++ return; ++ ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && ++ wirq->status & WAKE_IRQ_DEDICATED_REVERSE) ++ enable_irq(wirq->irq); + } + + /** +@@ -331,7 +394,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq) + + if (device_may_wakeup(wirq->dev)) { + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + enable_irq(wirq->irq); + + enable_irq_wake(wirq->irq); +@@ -354,7 +417,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq) + disable_irq_wake(wirq->irq); + + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + disable_irq_nosync(wirq->irq); + } + } +diff --git a/drivers/base/soc.c b/drivers/base/soc.c +index 7e91894a380b5..23bc9eb794a26 100644 +--- a/drivers/base/soc.c ++++ b/drivers/base/soc.c +@@ -72,13 +72,13 @@ static ssize_t soc_info_get(struct device *dev, + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + if (attr == &dev_attr_machine) +- return sprintf(buf, "%s\n", soc_dev->attr->machine); ++ return sysfs_emit(buf, "%s\n", soc_dev->attr->machine); + if (attr == &dev_attr_family) +- return sprintf(buf, "%s\n", soc_dev->attr->family); ++ return sysfs_emit(buf, "%s\n", soc_dev->attr->family); + if (attr == &dev_attr_revision) +- return sprintf(buf, "%s\n", soc_dev->attr->revision); ++ return sysfs_emit(buf, "%s\n", soc_dev->attr->revision); + if (attr == &dev_attr_soc_id) +- return sprintf(buf, "%s\n", soc_dev->attr->soc_id); ++ return sysfs_emit(buf, "%s\n", soc_dev->attr->soc_id); + + return -EINVAL; + +diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c +index 3f403aab55e1e..b4c2a2c2769bd 100644 +--- a/drivers/block/drbd/drbd_nl.c ++++ b/drivers/block/drbd/drbd_nl.c +@@ -3394,7 +3394,7 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb) + { + struct nlattr *resource_filter; + struct drbd_resource *resource; +- struct drbd_device *uninitialized_var(device); ++ struct drbd_device *device; + int minor, err, retcode; + struct drbd_genlmsghdr *dh; + struct device_info device_info; +@@ -3483,7 +3483,7 @@ int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb) + { + struct nlattr *resource_filter; + struct drbd_resource *resource = NULL, *next_resource; +- struct drbd_connection *uninitialized_var(connection); ++ struct drbd_connection *connection; + int err = 0, retcode; + struct drbd_genlmsghdr *dh; + struct connection_info connection_info; +@@ -3645,7 +3645,7 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb) + { + struct nlattr *resource_filter; + struct drbd_resource *resource; +- struct drbd_device *uninitialized_var(device); ++ struct drbd_device *device; + struct drbd_peer_device *peer_device = NULL; + int minor, err, retcode; + struct drbd_genlmsghdr *dh; +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 12eb48980df7b..2e6c3f658894e 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1991,7 +1991,8 @@ static int loop_add(struct loop_device **l, int i) + lo->tag_set.queue_depth = 128; + lo->tag_set.numa_node = NUMA_NO_NODE; + lo->tag_set.cmd_size = sizeof(struct loop_cmd); +- lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE; ++ lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE | ++ BLK_MQ_F_NO_SCHED; + lo->tag_set.driver_data = lo; + + err = blk_mq_alloc_tag_set(&lo->tag_set); +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 28024248a7b53..5a07964a1e676 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -1646,7 +1646,8 @@ static int nbd_dev_add(int index) + if (err == -ENOSPC) + err = -EEXIST; + } else { +- err = idr_alloc(&nbd_index_idr, nbd, 0, 0, GFP_KERNEL); ++ err = idr_alloc(&nbd_index_idr, nbd, 0, ++ (MINORMASK >> part_shift) + 1, GFP_KERNEL); + if (err >= 0) + index = err; + } +diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c +index dc9b8f377907f..084f7e4254eba 100644 +--- a/drivers/char/hw_random/imx-rngc.c ++++ b/drivers/char/hw_random/imx-rngc.c +@@ -105,7 +105,7 @@ static int imx_rngc_self_test(struct imx_rngc *rngc) + cmd = readl(rngc->base + RNGC_COMMAND); + writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND); + +- ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT); ++ ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); + if (!ret) { + imx_rngc_irq_mask_clear(rngc); + return -ETIMEDOUT; +@@ -188,9 +188,7 @@ static int imx_rngc_init(struct hwrng *rng) + cmd = readl(rngc->base + RNGC_COMMAND); + writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND); + +- ret = wait_for_completion_timeout(&rngc->rng_op_done, +- RNGC_TIMEOUT); +- ++ ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); + if (!ret) { + imx_rngc_irq_mask_clear(rngc); + return -ETIMEDOUT; +diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c +index 7abd604e938c2..58884d8752011 100644 +--- a/drivers/char/hw_random/virtio-rng.c ++++ b/drivers/char/hw_random/virtio-rng.c +@@ -17,6 +17,7 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + ++#include <asm/barrier.h> + #include <linux/err.h> + #include <linux/hw_random.h> + #include <linux/scatterlist.h> +@@ -30,71 +31,111 @@ static DEFINE_IDA(rng_index_ida); + struct virtrng_info { + struct hwrng hwrng; + struct virtqueue *vq; +- struct completion have_data; + char name[25]; +- unsigned int data_avail; + int index; +- bool busy; + bool hwrng_register_done; + bool hwrng_removed; ++ /* data transfer */ ++ struct completion have_data; ++ unsigned int data_avail; ++ unsigned int data_idx; ++ /* minimal size returned by rng_buffer_size() */ ++#if SMP_CACHE_BYTES < 32 ++ u8 data[32]; ++#else ++ u8 data[SMP_CACHE_BYTES]; ++#endif + }; + + static void random_recv_done(struct virtqueue *vq) + { + struct virtrng_info *vi = vq->vdev->priv; ++ unsigned int len; + + /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ +- if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) ++ if (!virtqueue_get_buf(vi->vq, &len)) + return; + ++ smp_store_release(&vi->data_avail, len); + complete(&vi->have_data); + } + +-/* The host will fill any buffer we give it with sweet, sweet randomness. */ +-static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size) ++static void request_entropy(struct virtrng_info *vi) + { + struct scatterlist sg; + +- sg_init_one(&sg, buf, size); ++ reinit_completion(&vi->have_data); ++ vi->data_idx = 0; ++ ++ sg_init_one(&sg, vi->data, sizeof(vi->data)); + + /* There should always be room for one buffer. */ +- virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL); ++ virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL); + + virtqueue_kick(vi->vq); + } + ++static unsigned int copy_data(struct virtrng_info *vi, void *buf, ++ unsigned int size) ++{ ++ size = min_t(unsigned int, size, vi->data_avail); ++ memcpy(buf, vi->data + vi->data_idx, size); ++ vi->data_idx += size; ++ vi->data_avail -= size; ++ if (vi->data_avail == 0) ++ request_entropy(vi); ++ return size; ++} ++ + static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) + { + int ret; + struct virtrng_info *vi = (struct virtrng_info *)rng->priv; ++ unsigned int chunk; ++ size_t read; + + if (vi->hwrng_removed) + return -ENODEV; + +- if (!vi->busy) { +- vi->busy = true; +- reinit_completion(&vi->have_data); +- register_buffer(vi, buf, size); ++ read = 0; ++ ++ /* copy available data */ ++ if (smp_load_acquire(&vi->data_avail)) { ++ chunk = copy_data(vi, buf, size); ++ size -= chunk; ++ read += chunk; + } + + if (!wait) +- return 0; +- +- ret = wait_for_completion_killable(&vi->have_data); +- if (ret < 0) +- return ret; ++ return read; ++ ++ /* We have already copied available entropy, ++ * so either size is 0 or data_avail is 0 ++ */ ++ while (size != 0) { ++ /* data_avail is 0 but a request is pending */ ++ ret = wait_for_completion_killable(&vi->have_data); ++ if (ret < 0) ++ return ret; ++ /* if vi->data_avail is 0, we have been interrupted ++ * by a cleanup, but buffer stays in the queue ++ */ ++ if (vi->data_avail == 0) ++ return read; + +- vi->busy = false; ++ chunk = copy_data(vi, buf + read, size); ++ size -= chunk; ++ read += chunk; ++ } + +- return vi->data_avail; ++ return read; + } + + static void virtio_cleanup(struct hwrng *rng) + { + struct virtrng_info *vi = (struct virtrng_info *)rng->priv; + +- if (vi->busy) +- wait_for_completion(&vi->have_data); ++ complete(&vi->have_data); + } + + static int probe_common(struct virtio_device *vdev) +@@ -130,6 +171,9 @@ static int probe_common(struct virtio_device *vdev) + goto err_find; + } + ++ /* we always have a pending entropy request */ ++ request_entropy(vi); ++ + return 0; + + err_find: +@@ -145,9 +189,9 @@ static void remove_common(struct virtio_device *vdev) + + vi->hwrng_removed = true; + vi->data_avail = 0; ++ vi->data_idx = 0; + complete(&vi->have_data); + vdev->config->reset(vdev); +- vi->busy = false; + if (vi->hwrng_register_done) + hwrng_unregister(&vi->hwrng); + vdev->config->del_vqs(vdev); +diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c +index c95ce9323d77a..430a9eac67e19 100644 +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -270,6 +270,7 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) + int size = 0; + int status; + u32 expected; ++ int rc; + + if (count < TPM_HEADER_SIZE) { + size = -EIO; +@@ -289,8 +290,13 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) + goto out; + } + +- size += recv_data(chip, &buf[TPM_HEADER_SIZE], +- expected - TPM_HEADER_SIZE); ++ rc = recv_data(chip, &buf[TPM_HEADER_SIZE], ++ expected - TPM_HEADER_SIZE); ++ if (rc < 0) { ++ size = rc; ++ goto out; ++ } ++ size += rc; + if (size < expected) { + dev_err(&chip->dev, "Unable to read remainder of result\n"); + size = -ETIME; +diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c +index ecbb63f8d2318..05c77812b6501 100644 +--- a/drivers/char/tpm/tpm_vtpm_proxy.c ++++ b/drivers/char/tpm/tpm_vtpm_proxy.c +@@ -700,37 +700,21 @@ static struct miscdevice vtpmx_miscdev = { + .fops = &vtpmx_fops, + }; + +-static int vtpmx_init(void) +-{ +- return misc_register(&vtpmx_miscdev); +-} +- +-static void vtpmx_cleanup(void) +-{ +- misc_deregister(&vtpmx_miscdev); +-} +- + static int __init vtpm_module_init(void) + { + int rc; + +- rc = vtpmx_init(); +- if (rc) { +- pr_err("couldn't create vtpmx device\n"); +- return rc; +- } +- + workqueue = create_workqueue("tpm-vtpm"); + if (!workqueue) { + pr_err("couldn't create workqueue\n"); +- rc = -ENOMEM; +- goto err_vtpmx_cleanup; ++ return -ENOMEM; + } + +- return 0; +- +-err_vtpmx_cleanup: +- vtpmx_cleanup(); ++ rc = misc_register(&vtpmx_miscdev); ++ if (rc) { ++ pr_err("couldn't create vtpmx device\n"); ++ destroy_workqueue(workqueue); ++ } + + return rc; + } +@@ -738,7 +722,7 @@ err_vtpmx_cleanup: + static void __exit vtpm_module_exit(void) + { + destroy_workqueue(workqueue); +- vtpmx_cleanup(); ++ misc_deregister(&vtpmx_miscdev); + } + + module_init(vtpm_module_init); +diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c +index dd82485e09a1f..c110f5d40b588 100644 +--- a/drivers/clk/clk-gate.c ++++ b/drivers/clk/clk-gate.c +@@ -43,7 +43,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable) + { + struct clk_gate *gate = to_clk_gate(hw); + int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + u32 reg; + + set ^= enable; +diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile +index db51b2427e8a6..e33b21d3f9d8b 100644 +--- a/drivers/clocksource/Makefile ++++ b/drivers/clocksource/Makefile +@@ -23,8 +23,8 @@ obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o + obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o + obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o + obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o +-obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o +-obj-$(CONFIG_ORION_TIMER) += time-orion.o ++obj-$(CONFIG_ARMADA_370_XP_TIMER) += timer-armada-370-xp.o ++obj-$(CONFIG_ORION_TIMER) += timer-orion.o + obj-$(CONFIG_BCM2835_TIMER) += bcm2835_timer.o + obj-$(CONFIG_CLPS711X_TIMER) += clps711x-timer.o + obj-$(CONFIG_ATLAS7_TIMER) += timer-atlas7.o +@@ -36,25 +36,25 @@ obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o + obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o + obj-$(CONFIG_MESON6_TIMER) += meson6_timer.o + obj-$(CONFIG_TEGRA_TIMER) += tegra20_timer.o +-obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o +-obj-$(CONFIG_NSPIRE_TIMER) += zevio-timer.o ++obj-$(CONFIG_VT8500_TIMER) += timer-vt8500.o ++obj-$(CONFIG_NSPIRE_TIMER) += timer-zevio.o + obj-$(CONFIG_BCM_KONA_TIMER) += bcm_kona_timer.o +-obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o +-obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o ++obj-$(CONFIG_CADENCE_TTC_TIMER) += timer-cadence-ttc.o ++obj-$(CONFIG_CLKSRC_EFM32) += timer-efm32.o + obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o + obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o +-obj-$(CONFIG_CLKSRC_LPC32XX) += time-lpc32xx.o ++obj-$(CONFIG_CLKSRC_LPC32XX) += timer-lpc32xx.o + obj-$(CONFIG_CLKSRC_MPS2) += mps2-timer.o + obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o +-obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o +-obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o +-obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o ++obj-$(CONFIG_FSL_FTM_TIMER) += timer-fsl-ftm.o ++obj-$(CONFIG_VF_PIT_TIMER) += timer-vf-pit.o ++obj-$(CONFIG_CLKSRC_QCOM) += timer-qcom.o + obj-$(CONFIG_MTK_TIMER) += timer-mediatek.o +-obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o ++obj-$(CONFIG_CLKSRC_PISTACHIO) += timer-pistachio.o + obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o + obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o + obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o +-obj-$(CONFIG_OWL_TIMER) += owl-timer.o ++obj-$(CONFIG_OWL_TIMER) += timer-owl.o + obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o + obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o + +@@ -66,7 +66,7 @@ obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp804.o + obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o + obj-$(CONFIG_KEYSTONE_TIMER) += timer-keystone.o + obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o +-obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o ++obj-$(CONFIG_CLKSRC_VERSATILE) += timer-versatile.o + obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o + obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o + obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o +diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c +deleted file mode 100644 +index a7eb858a84a0f..0000000000000 +--- a/drivers/clocksource/cadence_ttc_timer.c ++++ /dev/null +@@ -1,543 +0,0 @@ +-/* +- * This file contains driver for the Cadence Triple Timer Counter Rev 06 +- * +- * Copyright (C) 2011-2013 Xilinx +- * +- * based on arch/mips/kernel/time.c timer driver +- * +- * This software is licensed under the terms of the GNU General Public +- * License version 2, as published by the Free Software Foundation, and +- * may be copied, distributed, and modified under those terms. +- * +- * 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/interrupt.h> +-#include <linux/clockchips.h> +-#include <linux/clocksource.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/slab.h> +-#include <linux/sched_clock.h> +- +-/* +- * This driver configures the 2 16/32-bit count-up timers as follows: +- * +- * T1: Timer 1, clocksource for generic timekeeping +- * T2: Timer 2, clockevent source for hrtimers +- * T3: Timer 3, <unused> +- * +- * The input frequency to the timer module for emulation is 2.5MHz which is +- * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32, +- * the timers are clocked at 78.125KHz (12.8 us resolution). +- +- * The input frequency to the timer module in silicon is configurable and +- * obtained from device tree. The pre-scaler of 32 is used. +- */ +- +-/* +- * Timer Register Offset Definitions of Timer 1, Increment base address by 4 +- * and use same offsets for Timer 2 +- */ +-#define TTC_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */ +-#define TTC_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */ +-#define TTC_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */ +-#define TTC_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */ +-#define TTC_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */ +-#define TTC_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */ +- +-#define TTC_CNT_CNTRL_DISABLE_MASK 0x1 +- +-#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */ +-#define TTC_CLK_CNTRL_PSV_MASK 0x1e +-#define TTC_CLK_CNTRL_PSV_SHIFT 1 +- +-/* +- * Setup the timers to use pre-scaling, using a fixed value for now that will +- * work across most input frequency, but it may need to be more dynamic +- */ +-#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ +-#define PRESCALE 2048 /* The exponent must match this */ +-#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1) +-#define CLK_CNTRL_PRESCALE_EN 1 +-#define CNT_CNTRL_RESET (1 << 4) +- +-#define MAX_F_ERR 50 +- +-/** +- * struct ttc_timer - This definition defines local timer structure +- * +- * @base_addr: Base address of timer +- * @freq: Timer input clock frequency +- * @clk: Associated clock source +- * @clk_rate_change_nb Notifier block for clock rate changes +- */ +-struct ttc_timer { +- void __iomem *base_addr; +- unsigned long freq; +- struct clk *clk; +- struct notifier_block clk_rate_change_nb; +-}; +- +-#define to_ttc_timer(x) \ +- container_of(x, struct ttc_timer, clk_rate_change_nb) +- +-struct ttc_timer_clocksource { +- u32 scale_clk_ctrl_reg_old; +- u32 scale_clk_ctrl_reg_new; +- struct ttc_timer ttc; +- struct clocksource cs; +-}; +- +-#define to_ttc_timer_clksrc(x) \ +- container_of(x, struct ttc_timer_clocksource, cs) +- +-struct ttc_timer_clockevent { +- struct ttc_timer ttc; +- struct clock_event_device ce; +-}; +- +-#define to_ttc_timer_clkevent(x) \ +- container_of(x, struct ttc_timer_clockevent, ce) +- +-static void __iomem *ttc_sched_clock_val_reg; +- +-/** +- * ttc_set_interval - Set the timer interval value +- * +- * @timer: Pointer to the timer instance +- * @cycles: Timer interval ticks +- **/ +-static void ttc_set_interval(struct ttc_timer *timer, +- unsigned long cycles) +-{ +- u32 ctrl_reg; +- +- /* Disable the counter, set the counter value and re-enable counter */ +- ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; +- writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- +- writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); +- +- /* +- * Reset the counter (0x10) so that it starts from 0, one-shot +- * mode makes this needed for timing to be right. +- */ +- ctrl_reg |= CNT_CNTRL_RESET; +- ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; +- writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); +-} +- +-/** +- * ttc_clock_event_interrupt - Clock event timer interrupt handler +- * +- * @irq: IRQ number of the Timer +- * @dev_id: void pointer to the ttc_timer instance +- * +- * returns: Always IRQ_HANDLED - success +- **/ +-static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id) +-{ +- struct ttc_timer_clockevent *ttce = dev_id; +- struct ttc_timer *timer = &ttce->ttc; +- +- /* Acknowledge the interrupt and call event handler */ +- readl_relaxed(timer->base_addr + TTC_ISR_OFFSET); +- +- ttce->ce.event_handler(&ttce->ce); +- +- return IRQ_HANDLED; +-} +- +-/** +- * __ttc_clocksource_read - Reads the timer counter register +- * +- * returns: Current timer counter register value +- **/ +-static u64 __ttc_clocksource_read(struct clocksource *cs) +-{ +- struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; +- +- return (u64)readl_relaxed(timer->base_addr + +- TTC_COUNT_VAL_OFFSET); +-} +- +-static u64 notrace ttc_sched_clock_read(void) +-{ +- return readl_relaxed(ttc_sched_clock_val_reg); +-} +- +-/** +- * ttc_set_next_event - Sets the time interval for next event +- * +- * @cycles: Timer interval ticks +- * @evt: Address of clock event instance +- * +- * returns: Always 0 - success +- **/ +-static int ttc_set_next_event(unsigned long cycles, +- struct clock_event_device *evt) +-{ +- struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); +- struct ttc_timer *timer = &ttce->ttc; +- +- ttc_set_interval(timer, cycles); +- return 0; +-} +- +-/** +- * ttc_set_{shutdown|oneshot|periodic} - Sets the state of timer +- * +- * @evt: Address of clock event instance +- **/ +-static int ttc_shutdown(struct clock_event_device *evt) +-{ +- struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); +- struct ttc_timer *timer = &ttce->ttc; +- u32 ctrl_reg; +- +- ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; +- writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- return 0; +-} +- +-static int ttc_set_periodic(struct clock_event_device *evt) +-{ +- struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); +- struct ttc_timer *timer = &ttce->ttc; +- +- ttc_set_interval(timer, +- DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ)); +- return 0; +-} +- +-static int ttc_resume(struct clock_event_device *evt) +-{ +- struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); +- struct ttc_timer *timer = &ttce->ttc; +- u32 ctrl_reg; +- +- ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; +- writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); +- return 0; +-} +- +-static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, +- unsigned long event, void *data) +-{ +- struct clk_notifier_data *ndata = data; +- struct ttc_timer *ttc = to_ttc_timer(nb); +- struct ttc_timer_clocksource *ttccs = container_of(ttc, +- struct ttc_timer_clocksource, ttc); +- +- switch (event) { +- case PRE_RATE_CHANGE: +- { +- u32 psv; +- unsigned long factor, rate_low, rate_high; +- +- if (ndata->new_rate > ndata->old_rate) { +- factor = DIV_ROUND_CLOSEST(ndata->new_rate, +- ndata->old_rate); +- rate_low = ndata->old_rate; +- rate_high = ndata->new_rate; +- } else { +- factor = DIV_ROUND_CLOSEST(ndata->old_rate, +- ndata->new_rate); +- rate_low = ndata->new_rate; +- rate_high = ndata->old_rate; +- } +- +- if (!is_power_of_2(factor)) +- return NOTIFY_BAD; +- +- if (abs(rate_high - (factor * rate_low)) > MAX_F_ERR) +- return NOTIFY_BAD; +- +- factor = __ilog2_u32(factor); +- +- /* +- * store timer clock ctrl register so we can restore it in case +- * of an abort. +- */ +- ttccs->scale_clk_ctrl_reg_old = +- readl_relaxed(ttccs->ttc.base_addr + +- TTC_CLK_CNTRL_OFFSET); +- +- psv = (ttccs->scale_clk_ctrl_reg_old & +- TTC_CLK_CNTRL_PSV_MASK) >> +- TTC_CLK_CNTRL_PSV_SHIFT; +- if (ndata->new_rate < ndata->old_rate) +- psv -= factor; +- else +- psv += factor; +- +- /* prescaler within legal range? */ +- if (psv & ~(TTC_CLK_CNTRL_PSV_MASK >> TTC_CLK_CNTRL_PSV_SHIFT)) +- return NOTIFY_BAD; +- +- ttccs->scale_clk_ctrl_reg_new = ttccs->scale_clk_ctrl_reg_old & +- ~TTC_CLK_CNTRL_PSV_MASK; +- ttccs->scale_clk_ctrl_reg_new |= psv << TTC_CLK_CNTRL_PSV_SHIFT; +- +- +- /* scale down: adjust divider in post-change notification */ +- if (ndata->new_rate < ndata->old_rate) +- return NOTIFY_DONE; +- +- /* scale up: adjust divider now - before frequency change */ +- writel_relaxed(ttccs->scale_clk_ctrl_reg_new, +- ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); +- break; +- } +- case POST_RATE_CHANGE: +- /* scale up: pre-change notification did the adjustment */ +- if (ndata->new_rate > ndata->old_rate) +- return NOTIFY_OK; +- +- /* scale down: adjust divider now - after frequency change */ +- writel_relaxed(ttccs->scale_clk_ctrl_reg_new, +- ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); +- break; +- +- case ABORT_RATE_CHANGE: +- /* we have to undo the adjustment in case we scale up */ +- if (ndata->new_rate < ndata->old_rate) +- return NOTIFY_OK; +- +- /* restore original register value */ +- writel_relaxed(ttccs->scale_clk_ctrl_reg_old, +- ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); +- /* fall through */ +- default: +- return NOTIFY_DONE; +- } +- +- return NOTIFY_DONE; +-} +- +-static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, +- u32 timer_width) +-{ +- struct ttc_timer_clocksource *ttccs; +- int err; +- +- ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); +- if (!ttccs) +- return -ENOMEM; +- +- ttccs->ttc.clk = clk; +- +- err = clk_prepare_enable(ttccs->ttc.clk); +- if (err) { +- kfree(ttccs); +- return err; +- } +- +- ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); +- +- ttccs->ttc.clk_rate_change_nb.notifier_call = +- ttc_rate_change_clocksource_cb; +- ttccs->ttc.clk_rate_change_nb.next = NULL; +- +- err = clk_notifier_register(ttccs->ttc.clk, +- &ttccs->ttc.clk_rate_change_nb); +- if (err) +- pr_warn("Unable to register clock notifier.\n"); +- +- ttccs->ttc.base_addr = base; +- ttccs->cs.name = "ttc_clocksource"; +- ttccs->cs.rating = 200; +- ttccs->cs.read = __ttc_clocksource_read; +- ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width); +- ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; +- +- /* +- * Setup the clock source counter to be an incrementing counter +- * with no interrupt and it rolls over at 0xFFFF. Pre-scale +- * it by 32 also. Let it start running now. +- */ +- writel_relaxed(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); +- writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, +- ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); +- writel_relaxed(CNT_CNTRL_RESET, +- ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); +- +- err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); +- if (err) { +- kfree(ttccs); +- return err; +- } +- +- ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; +- sched_clock_register(ttc_sched_clock_read, timer_width, +- ttccs->ttc.freq / PRESCALE); +- +- return 0; +-} +- +-static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, +- unsigned long event, void *data) +-{ +- struct clk_notifier_data *ndata = data; +- struct ttc_timer *ttc = to_ttc_timer(nb); +- struct ttc_timer_clockevent *ttcce = container_of(ttc, +- struct ttc_timer_clockevent, ttc); +- +- switch (event) { +- case POST_RATE_CHANGE: +- /* update cached frequency */ +- ttc->freq = ndata->new_rate; +- +- clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE); +- +- /* fall through */ +- case PRE_RATE_CHANGE: +- case ABORT_RATE_CHANGE: +- default: +- return NOTIFY_DONE; +- } +-} +- +-static int __init ttc_setup_clockevent(struct clk *clk, +- void __iomem *base, u32 irq) +-{ +- struct ttc_timer_clockevent *ttcce; +- int err; +- +- ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); +- if (!ttcce) +- return -ENOMEM; +- +- ttcce->ttc.clk = clk; +- +- err = clk_prepare_enable(ttcce->ttc.clk); +- if (err) +- goto out_kfree; +- +- ttcce->ttc.clk_rate_change_nb.notifier_call = +- ttc_rate_change_clockevent_cb; +- ttcce->ttc.clk_rate_change_nb.next = NULL; +- +- err = clk_notifier_register(ttcce->ttc.clk, +- &ttcce->ttc.clk_rate_change_nb); +- if (err) { +- pr_warn("Unable to register clock notifier.\n"); +- goto out_kfree; +- } +- +- ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); +- +- ttcce->ttc.base_addr = base; +- ttcce->ce.name = "ttc_clockevent"; +- ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; +- ttcce->ce.set_next_event = ttc_set_next_event; +- ttcce->ce.set_state_shutdown = ttc_shutdown; +- ttcce->ce.set_state_periodic = ttc_set_periodic; +- ttcce->ce.set_state_oneshot = ttc_shutdown; +- ttcce->ce.tick_resume = ttc_resume; +- ttcce->ce.rating = 200; +- ttcce->ce.irq = irq; +- ttcce->ce.cpumask = cpu_possible_mask; +- +- /* +- * Setup the clock event timer to be an interval timer which +- * is prescaled by 32 using the interval interrupt. Leave it +- * disabled for now. +- */ +- writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); +- writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, +- ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); +- writel_relaxed(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); +- +- err = request_irq(irq, ttc_clock_event_interrupt, +- IRQF_TIMER, ttcce->ce.name, ttcce); +- if (err) +- goto out_kfree; +- +- clockevents_config_and_register(&ttcce->ce, +- ttcce->ttc.freq / PRESCALE, 1, 0xfffe); +- +- return 0; +- +-out_kfree: +- kfree(ttcce); +- return err; +-} +- +-/** +- * ttc_timer_init - Initialize the timer +- * +- * Initializes the timer hardware and register the clock source and clock event +- * timers with Linux kernal timer framework +- */ +-static int __init ttc_timer_init(struct device_node *timer) +-{ +- unsigned int irq; +- void __iomem *timer_baseaddr; +- struct clk *clk_cs, *clk_ce; +- static int initialized; +- int clksel, ret; +- u32 timer_width = 16; +- +- if (initialized) +- return 0; +- +- initialized = 1; +- +- /* +- * Get the 1st Triple Timer Counter (TTC) block from the device tree +- * and use it. Note that the event timer uses the interrupt and it's the +- * 2nd TTC hence the irq_of_parse_and_map(,1) +- */ +- timer_baseaddr = of_iomap(timer, 0); +- if (!timer_baseaddr) { +- pr_err("ERROR: invalid timer base address\n"); +- return -ENXIO; +- } +- +- irq = irq_of_parse_and_map(timer, 1); +- if (irq <= 0) { +- pr_err("ERROR: invalid interrupt number\n"); +- return -EINVAL; +- } +- +- of_property_read_u32(timer, "timer-width", &timer_width); +- +- clksel = readl_relaxed(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); +- clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); +- clk_cs = of_clk_get(timer, clksel); +- if (IS_ERR(clk_cs)) { +- pr_err("ERROR: timer input clock not found\n"); +- return PTR_ERR(clk_cs); +- } +- +- clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); +- clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); +- clk_ce = of_clk_get(timer, clksel); +- if (IS_ERR(clk_ce)) { +- pr_err("ERROR: timer input clock not found\n"); +- return PTR_ERR(clk_ce); +- } +- +- ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); +- if (ret) +- return ret; +- +- ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); +- if (ret) +- return ret; +- +- pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); +- +- return 0; +-} +- +-TIMER_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); +diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c +deleted file mode 100644 +index 846d18daf893b..0000000000000 +--- a/drivers/clocksource/fsl_ftm_timer.c ++++ /dev/null +@@ -1,376 +0,0 @@ +-/* +- * Freescale FlexTimer Module (FTM) timer driver. +- * +- * Copyright 2014 Freescale Semiconductor, Inc. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version 2 +- * of the License, or (at your option) any later version. +- */ +- +-#include <linux/clk.h> +-#include <linux/clockchips.h> +-#include <linux/clocksource.h> +-#include <linux/err.h> +-#include <linux/interrupt.h> +-#include <linux/io.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/sched_clock.h> +-#include <linux/slab.h> +- +-#define FTM_SC 0x00 +-#define FTM_SC_CLK_SHIFT 3 +-#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT) +-#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT) +-#define FTM_SC_PS_MASK 0x7 +-#define FTM_SC_TOIE BIT(6) +-#define FTM_SC_TOF BIT(7) +- +-#define FTM_CNT 0x04 +-#define FTM_MOD 0x08 +-#define FTM_CNTIN 0x4C +- +-#define FTM_PS_MAX 7 +- +-struct ftm_clock_device { +- void __iomem *clksrc_base; +- void __iomem *clkevt_base; +- unsigned long periodic_cyc; +- unsigned long ps; +- bool big_endian; +-}; +- +-static struct ftm_clock_device *priv; +- +-static inline u32 ftm_readl(void __iomem *addr) +-{ +- if (priv->big_endian) +- return ioread32be(addr); +- else +- return ioread32(addr); +-} +- +-static inline void ftm_writel(u32 val, void __iomem *addr) +-{ +- if (priv->big_endian) +- iowrite32be(val, addr); +- else +- iowrite32(val, addr); +-} +- +-static inline void ftm_counter_enable(void __iomem *base) +-{ +- u32 val; +- +- /* select and enable counter clock source */ +- val = ftm_readl(base + FTM_SC); +- val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); +- val |= priv->ps | FTM_SC_CLK(1); +- ftm_writel(val, base + FTM_SC); +-} +- +-static inline void ftm_counter_disable(void __iomem *base) +-{ +- u32 val; +- +- /* disable counter clock source */ +- val = ftm_readl(base + FTM_SC); +- val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); +- ftm_writel(val, base + FTM_SC); +-} +- +-static inline void ftm_irq_acknowledge(void __iomem *base) +-{ +- u32 val; +- +- val = ftm_readl(base + FTM_SC); +- val &= ~FTM_SC_TOF; +- ftm_writel(val, base + FTM_SC); +-} +- +-static inline void ftm_irq_enable(void __iomem *base) +-{ +- u32 val; +- +- val = ftm_readl(base + FTM_SC); +- val |= FTM_SC_TOIE; +- ftm_writel(val, base + FTM_SC); +-} +- +-static inline void ftm_irq_disable(void __iomem *base) +-{ +- u32 val; +- +- val = ftm_readl(base + FTM_SC); +- val &= ~FTM_SC_TOIE; +- ftm_writel(val, base + FTM_SC); +-} +- +-static inline void ftm_reset_counter(void __iomem *base) +-{ +- /* +- * The CNT register contains the FTM counter value. +- * Reset clears the CNT register. Writing any value to COUNT +- * updates the counter with its initial value, CNTIN. +- */ +- ftm_writel(0x00, base + FTM_CNT); +-} +- +-static u64 notrace ftm_read_sched_clock(void) +-{ +- return ftm_readl(priv->clksrc_base + FTM_CNT); +-} +- +-static int ftm_set_next_event(unsigned long delta, +- struct clock_event_device *unused) +-{ +- /* +- * The CNNIN and MOD are all double buffer registers, writing +- * to the MOD register latches the value into a buffer. The MOD +- * register is updated with the value of its write buffer with +- * the following scenario: +- * a, the counter source clock is diabled. +- */ +- ftm_counter_disable(priv->clkevt_base); +- +- /* Force the value of CNTIN to be loaded into the FTM counter */ +- ftm_reset_counter(priv->clkevt_base); +- +- /* +- * The counter increments until the value of MOD is reached, +- * at which point the counter is reloaded with the value of CNTIN. +- * The TOF (the overflow flag) bit is set when the FTM counter +- * changes from MOD to CNTIN. So we should using the delta - 1. +- */ +- ftm_writel(delta - 1, priv->clkevt_base + FTM_MOD); +- +- ftm_counter_enable(priv->clkevt_base); +- +- ftm_irq_enable(priv->clkevt_base); +- +- return 0; +-} +- +-static int ftm_set_oneshot(struct clock_event_device *evt) +-{ +- ftm_counter_disable(priv->clkevt_base); +- return 0; +-} +- +-static int ftm_set_periodic(struct clock_event_device *evt) +-{ +- ftm_set_next_event(priv->periodic_cyc, evt); +- return 0; +-} +- +-static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id) +-{ +- struct clock_event_device *evt = dev_id; +- +- ftm_irq_acknowledge(priv->clkevt_base); +- +- if (likely(clockevent_state_oneshot(evt))) { +- ftm_irq_disable(priv->clkevt_base); +- ftm_counter_disable(priv->clkevt_base); +- } +- +- evt->event_handler(evt); +- +- return IRQ_HANDLED; +-} +- +-static struct clock_event_device ftm_clockevent = { +- .name = "Freescale ftm timer", +- .features = CLOCK_EVT_FEAT_PERIODIC | +- CLOCK_EVT_FEAT_ONESHOT, +- .set_state_periodic = ftm_set_periodic, +- .set_state_oneshot = ftm_set_oneshot, +- .set_next_event = ftm_set_next_event, +- .rating = 300, +-}; +- +-static struct irqaction ftm_timer_irq = { +- .name = "Freescale ftm timer", +- .flags = IRQF_TIMER | IRQF_IRQPOLL, +- .handler = ftm_evt_interrupt, +- .dev_id = &ftm_clockevent, +-}; +- +-static int __init ftm_clockevent_init(unsigned long freq, int irq) +-{ +- int err; +- +- ftm_writel(0x00, priv->clkevt_base + FTM_CNTIN); +- ftm_writel(~0u, priv->clkevt_base + FTM_MOD); +- +- ftm_reset_counter(priv->clkevt_base); +- +- err = setup_irq(irq, &ftm_timer_irq); +- if (err) { +- pr_err("ftm: setup irq failed: %d\n", err); +- return err; +- } +- +- ftm_clockevent.cpumask = cpumask_of(0); +- ftm_clockevent.irq = irq; +- +- clockevents_config_and_register(&ftm_clockevent, +- freq / (1 << priv->ps), +- 1, 0xffff); +- +- ftm_counter_enable(priv->clkevt_base); +- +- return 0; +-} +- +-static int __init ftm_clocksource_init(unsigned long freq) +-{ +- int err; +- +- ftm_writel(0x00, priv->clksrc_base + FTM_CNTIN); +- ftm_writel(~0u, priv->clksrc_base + FTM_MOD); +- +- ftm_reset_counter(priv->clksrc_base); +- +- sched_clock_register(ftm_read_sched_clock, 16, freq / (1 << priv->ps)); +- err = clocksource_mmio_init(priv->clksrc_base + FTM_CNT, "fsl-ftm", +- freq / (1 << priv->ps), 300, 16, +- clocksource_mmio_readl_up); +- if (err) { +- pr_err("ftm: init clock source mmio failed: %d\n", err); +- return err; +- } +- +- ftm_counter_enable(priv->clksrc_base); +- +- return 0; +-} +- +-static int __init __ftm_clk_init(struct device_node *np, char *cnt_name, +- char *ftm_name) +-{ +- struct clk *clk; +- int err; +- +- clk = of_clk_get_by_name(np, cnt_name); +- if (IS_ERR(clk)) { +- pr_err("ftm: Cannot get \"%s\": %ld\n", cnt_name, PTR_ERR(clk)); +- return PTR_ERR(clk); +- } +- err = clk_prepare_enable(clk); +- if (err) { +- pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n", +- cnt_name, err); +- return err; +- } +- +- clk = of_clk_get_by_name(np, ftm_name); +- if (IS_ERR(clk)) { +- pr_err("ftm: Cannot get \"%s\": %ld\n", ftm_name, PTR_ERR(clk)); +- return PTR_ERR(clk); +- } +- err = clk_prepare_enable(clk); +- if (err) +- pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n", +- ftm_name, err); +- +- return clk_get_rate(clk); +-} +- +-static unsigned long __init ftm_clk_init(struct device_node *np) +-{ +- long freq; +- +- freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt"); +- if (freq <= 0) +- return 0; +- +- freq = __ftm_clk_init(np, "ftm-src-counter-en", "ftm-src"); +- if (freq <= 0) +- return 0; +- +- return freq; +-} +- +-static int __init ftm_calc_closest_round_cyc(unsigned long freq) +-{ +- priv->ps = 0; +- +- /* The counter register is only using the lower 16 bits, and +- * if the 'freq' value is to big here, then the periodic_cyc +- * may exceed 0xFFFF. +- */ +- do { +- priv->periodic_cyc = DIV_ROUND_CLOSEST(freq, +- HZ * (1 << priv->ps++)); +- } while (priv->periodic_cyc > 0xFFFF); +- +- if (priv->ps > FTM_PS_MAX) { +- pr_err("ftm: the prescaler is %lu > %d\n", +- priv->ps, FTM_PS_MAX); +- return -EINVAL; +- } +- +- return 0; +-} +- +-static int __init ftm_timer_init(struct device_node *np) +-{ +- unsigned long freq; +- int ret, irq; +- +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); +- if (!priv) +- return -ENOMEM; +- +- ret = -ENXIO; +- priv->clkevt_base = of_iomap(np, 0); +- if (!priv->clkevt_base) { +- pr_err("ftm: unable to map event timer registers\n"); +- goto err_clkevt; +- } +- +- priv->clksrc_base = of_iomap(np, 1); +- if (!priv->clksrc_base) { +- pr_err("ftm: unable to map source timer registers\n"); +- goto err_clksrc; +- } +- +- ret = -EINVAL; +- irq = irq_of_parse_and_map(np, 0); +- if (irq <= 0) { +- pr_err("ftm: unable to get IRQ from DT, %d\n", irq); +- goto err; +- } +- +- priv->big_endian = of_property_read_bool(np, "big-endian"); +- +- freq = ftm_clk_init(np); +- if (!freq) +- goto err; +- +- ret = ftm_calc_closest_round_cyc(freq); +- if (ret) +- goto err; +- +- ret = ftm_clocksource_init(freq); +- if (ret) +- goto err; +- +- ret = ftm_clockevent_init(freq, irq); +- if (ret) +- goto err; +- +- return 0; +- +-err: +- iounmap(priv->clksrc_base); +-err_clksrc: +- iounmap(priv->clkevt_base); +-err_clkevt: +- kfree(priv); +- return ret; +-} +-TIMER_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init); +diff --git a/drivers/clocksource/owl-timer.c b/drivers/clocksource/owl-timer.c +deleted file mode 100644 +index ea00a5e8f95d2..0000000000000 +--- a/drivers/clocksource/owl-timer.c ++++ /dev/null +@@ -1,173 +0,0 @@ +-/* +- * Actions Semi Owl timer +- * +- * Copyright 2012 Actions Semi Inc. +- * Author: Actions Semi, Inc. +- * +- * Copyright (c) 2017 SUSE Linux GmbH +- * Author: Andreas Färber +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License as published by the +- * Free Software Foundation; either version 2 of the License, or (at your +- * option) any later version. +- */ +- +-#include <linux/clk.h> +-#include <linux/clockchips.h> +-#include <linux/interrupt.h> +-#include <linux/irq.h> +-#include <linux/irqreturn.h> +-#include <linux/sched_clock.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +- +-#define OWL_Tx_CTL 0x0 +-#define OWL_Tx_CMP 0x4 +-#define OWL_Tx_VAL 0x8 +- +-#define OWL_Tx_CTL_PD BIT(0) +-#define OWL_Tx_CTL_INTEN BIT(1) +-#define OWL_Tx_CTL_EN BIT(2) +- +-static void __iomem *owl_timer_base; +-static void __iomem *owl_clksrc_base; +-static void __iomem *owl_clkevt_base; +- +-static inline void owl_timer_reset(void __iomem *base) +-{ +- writel(0, base + OWL_Tx_CTL); +- writel(0, base + OWL_Tx_VAL); +- writel(0, base + OWL_Tx_CMP); +-} +- +-static inline void owl_timer_set_enabled(void __iomem *base, bool enabled) +-{ +- u32 ctl = readl(base + OWL_Tx_CTL); +- +- /* PD bit is cleared when set */ +- ctl &= ~OWL_Tx_CTL_PD; +- +- if (enabled) +- ctl |= OWL_Tx_CTL_EN; +- else +- ctl &= ~OWL_Tx_CTL_EN; +- +- writel(ctl, base + OWL_Tx_CTL); +-} +- +-static u64 notrace owl_timer_sched_read(void) +-{ +- return (u64)readl(owl_clksrc_base + OWL_Tx_VAL); +-} +- +-static int owl_timer_set_state_shutdown(struct clock_event_device *evt) +-{ +- owl_timer_set_enabled(owl_clkevt_base, false); +- +- return 0; +-} +- +-static int owl_timer_set_state_oneshot(struct clock_event_device *evt) +-{ +- owl_timer_reset(owl_clkevt_base); +- +- return 0; +-} +- +-static int owl_timer_tick_resume(struct clock_event_device *evt) +-{ +- return 0; +-} +- +-static int owl_timer_set_next_event(unsigned long evt, +- struct clock_event_device *ev) +-{ +- void __iomem *base = owl_clkevt_base; +- +- owl_timer_set_enabled(base, false); +- writel(OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL); +- writel(0, base + OWL_Tx_VAL); +- writel(evt, base + OWL_Tx_CMP); +- owl_timer_set_enabled(base, true); +- +- return 0; +-} +- +-static struct clock_event_device owl_clockevent = { +- .name = "owl_tick", +- .rating = 200, +- .features = CLOCK_EVT_FEAT_ONESHOT | +- CLOCK_EVT_FEAT_DYNIRQ, +- .set_state_shutdown = owl_timer_set_state_shutdown, +- .set_state_oneshot = owl_timer_set_state_oneshot, +- .tick_resume = owl_timer_tick_resume, +- .set_next_event = owl_timer_set_next_event, +-}; +- +-static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id) +-{ +- struct clock_event_device *evt = (struct clock_event_device *)dev_id; +- +- writel(OWL_Tx_CTL_PD, owl_clkevt_base + OWL_Tx_CTL); +- +- evt->event_handler(evt); +- +- return IRQ_HANDLED; +-} +- +-static int __init owl_timer_init(struct device_node *node) +-{ +- struct clk *clk; +- unsigned long rate; +- int timer1_irq, ret; +- +- owl_timer_base = of_io_request_and_map(node, 0, "owl-timer"); +- if (IS_ERR(owl_timer_base)) { +- pr_err("Can't map timer registers\n"); +- return PTR_ERR(owl_timer_base); +- } +- +- owl_clksrc_base = owl_timer_base + 0x08; +- owl_clkevt_base = owl_timer_base + 0x14; +- +- timer1_irq = of_irq_get_byname(node, "timer1"); +- if (timer1_irq <= 0) { +- pr_err("Can't parse timer1 IRQ\n"); +- return -EINVAL; +- } +- +- clk = of_clk_get(node, 0); +- if (IS_ERR(clk)) +- return PTR_ERR(clk); +- +- rate = clk_get_rate(clk); +- +- owl_timer_reset(owl_clksrc_base); +- owl_timer_set_enabled(owl_clksrc_base, true); +- +- sched_clock_register(owl_timer_sched_read, 32, rate); +- clocksource_mmio_init(owl_clksrc_base + OWL_Tx_VAL, node->name, +- rate, 200, 32, clocksource_mmio_readl_up); +- +- owl_timer_reset(owl_clkevt_base); +- +- ret = request_irq(timer1_irq, owl_timer1_interrupt, IRQF_TIMER, +- "owl-timer", &owl_clockevent); +- if (ret) { +- pr_err("failed to request irq %d\n", timer1_irq); +- return ret; +- } +- +- owl_clockevent.cpumask = cpumask_of(0); +- owl_clockevent.irq = timer1_irq; +- +- clockevents_config_and_register(&owl_clockevent, rate, +- 0xf, 0xffffffff); +- +- return 0; +-} +-TIMER_OF_DECLARE(owl_s500, "actions,s500-timer", owl_timer_init); +-TIMER_OF_DECLARE(owl_s700, "actions,s700-timer", owl_timer_init); +-TIMER_OF_DECLARE(owl_s900, "actions,s900-timer", owl_timer_init); +diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c +deleted file mode 100644 +index 89816f89ff3f4..0000000000000 +--- a/drivers/clocksource/qcom-timer.c ++++ /dev/null +@@ -1,258 +0,0 @@ +-/* +- * +- * Copyright (C) 2007 Google, Inc. +- * Copyright (c) 2009-2012,2014, 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 +- * may be copied, distributed, and modified under those terms. +- * +- * 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/clocksource.h> +-#include <linux/clockchips.h> +-#include <linux/cpu.h> +-#include <linux/init.h> +-#include <linux/interrupt.h> +-#include <linux/irq.h> +-#include <linux/io.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/sched_clock.h> +- +-#include <asm/delay.h> +- +-#define TIMER_MATCH_VAL 0x0000 +-#define TIMER_COUNT_VAL 0x0004 +-#define TIMER_ENABLE 0x0008 +-#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) +-#define TIMER_ENABLE_EN BIT(0) +-#define TIMER_CLEAR 0x000C +-#define DGT_CLK_CTL 0x10 +-#define DGT_CLK_CTL_DIV_4 0x3 +-#define TIMER_STS_GPT0_CLR_PEND BIT(10) +- +-#define GPT_HZ 32768 +- +-static void __iomem *event_base; +-static void __iomem *sts_base; +- +-static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) +-{ +- struct clock_event_device *evt = dev_id; +- /* Stop the timer tick */ +- if (clockevent_state_oneshot(evt)) { +- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); +- ctrl &= ~TIMER_ENABLE_EN; +- writel_relaxed(ctrl, event_base + TIMER_ENABLE); +- } +- evt->event_handler(evt); +- return IRQ_HANDLED; +-} +- +-static int msm_timer_set_next_event(unsigned long cycles, +- struct clock_event_device *evt) +-{ +- u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); +- +- ctrl &= ~TIMER_ENABLE_EN; +- writel_relaxed(ctrl, event_base + TIMER_ENABLE); +- +- writel_relaxed(ctrl, event_base + TIMER_CLEAR); +- writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); +- +- if (sts_base) +- while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND) +- cpu_relax(); +- +- writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); +- return 0; +-} +- +-static int msm_timer_shutdown(struct clock_event_device *evt) +-{ +- u32 ctrl; +- +- ctrl = readl_relaxed(event_base + TIMER_ENABLE); +- ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); +- writel_relaxed(ctrl, event_base + TIMER_ENABLE); +- return 0; +-} +- +-static struct clock_event_device __percpu *msm_evt; +- +-static void __iomem *source_base; +- +-static notrace u64 msm_read_timer_count(struct clocksource *cs) +-{ +- return readl_relaxed(source_base + TIMER_COUNT_VAL); +-} +- +-static struct clocksource msm_clocksource = { +- .name = "dg_timer", +- .rating = 300, +- .read = msm_read_timer_count, +- .mask = CLOCKSOURCE_MASK(32), +- .flags = CLOCK_SOURCE_IS_CONTINUOUS, +-}; +- +-static int msm_timer_irq; +-static int msm_timer_has_ppi; +- +-static int msm_local_timer_starting_cpu(unsigned int cpu) +-{ +- struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); +- int err; +- +- evt->irq = msm_timer_irq; +- evt->name = "msm_timer"; +- evt->features = CLOCK_EVT_FEAT_ONESHOT; +- evt->rating = 200; +- evt->set_state_shutdown = msm_timer_shutdown; +- evt->set_state_oneshot = msm_timer_shutdown; +- evt->tick_resume = msm_timer_shutdown; +- evt->set_next_event = msm_timer_set_next_event; +- evt->cpumask = cpumask_of(cpu); +- +- clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); +- +- if (msm_timer_has_ppi) { +- enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); +- } else { +- err = request_irq(evt->irq, msm_timer_interrupt, +- IRQF_TIMER | IRQF_NOBALANCING | +- IRQF_TRIGGER_RISING, "gp_timer", evt); +- if (err) +- pr_err("request_irq failed\n"); +- } +- +- return 0; +-} +- +-static int msm_local_timer_dying_cpu(unsigned int cpu) +-{ +- struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); +- +- evt->set_state_shutdown(evt); +- disable_percpu_irq(evt->irq); +- return 0; +-} +- +-static u64 notrace msm_sched_clock_read(void) +-{ +- return msm_clocksource.read(&msm_clocksource); +-} +- +-static unsigned long msm_read_current_timer(void) +-{ +- return msm_clocksource.read(&msm_clocksource); +-} +- +-static struct delay_timer msm_delay_timer = { +- .read_current_timer = msm_read_current_timer, +-}; +- +-static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, +- bool percpu) +-{ +- struct clocksource *cs = &msm_clocksource; +- int res = 0; +- +- msm_timer_irq = irq; +- msm_timer_has_ppi = percpu; +- +- msm_evt = alloc_percpu(struct clock_event_device); +- if (!msm_evt) { +- pr_err("memory allocation failed for clockevents\n"); +- goto err; +- } +- +- if (percpu) +- res = request_percpu_irq(irq, msm_timer_interrupt, +- "gp_timer", msm_evt); +- +- if (res) { +- pr_err("request_percpu_irq failed\n"); +- } else { +- /* Install and invoke hotplug callbacks */ +- res = cpuhp_setup_state(CPUHP_AP_QCOM_TIMER_STARTING, +- "clockevents/qcom/timer:starting", +- msm_local_timer_starting_cpu, +- msm_local_timer_dying_cpu); +- if (res) { +- free_percpu_irq(irq, msm_evt); +- goto err; +- } +- } +- +-err: +- writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); +- res = clocksource_register_hz(cs, dgt_hz); +- if (res) +- pr_err("clocksource_register failed\n"); +- sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); +- msm_delay_timer.freq = dgt_hz; +- register_current_timer_delay(&msm_delay_timer); +- +- return res; +-} +- +-static int __init msm_dt_timer_init(struct device_node *np) +-{ +- u32 freq; +- int irq, ret; +- struct resource res; +- u32 percpu_offset; +- void __iomem *base; +- void __iomem *cpu0_base; +- +- base = of_iomap(np, 0); +- if (!base) { +- pr_err("Failed to map event base\n"); +- return -ENXIO; +- } +- +- /* We use GPT0 for the clockevent */ +- irq = irq_of_parse_and_map(np, 1); +- if (irq <= 0) { +- pr_err("Can't get irq\n"); +- return -EINVAL; +- } +- +- /* We use CPU0's DGT for the clocksource */ +- if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) +- percpu_offset = 0; +- +- ret = of_address_to_resource(np, 0, &res); +- if (ret) { +- pr_err("Failed to parse DGT resource\n"); +- return ret; +- } +- +- cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); +- if (!cpu0_base) { +- pr_err("Failed to map source base\n"); +- return -EINVAL; +- } +- +- if (of_property_read_u32(np, "clock-frequency", &freq)) { +- pr_err("Unknown frequency\n"); +- return -EINVAL; +- } +- +- event_base = base + 0x4; +- sts_base = base + 0x88; +- source_base = cpu0_base + 0x24; +- freq /= 4; +- writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); +- +- return msm_timer_init(freq, 32, irq, !!percpu_offset); +-} +-TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); +-TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); +diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c +deleted file mode 100644 +index edf1a46269f10..0000000000000 +--- a/drivers/clocksource/time-armada-370-xp.c ++++ /dev/null +@@ -1,416 +0,0 @@ +-/* +- * Marvell Armada 370/XP SoC timer handling. +- * +- * Copyright (C) 2012 Marvell +- * +- * Lior Amsalem <alior@marvell.com> +- * Gregory CLEMENT <gregory.clement@free-electrons.com> +- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * +- * Timer 0 is used as free-running clocksource, while timer 1 is +- * used as clock_event_device. +- * +- * --- +- * Clocksource driver for Armada 370 and Armada XP SoC. +- * This driver implements one compatible string for each SoC, given +- * each has its own characteristics: +- * +- * * Armada 370 has no 25 MHz fixed timer. +- * +- * * Armada XP cannot work properly without such 25 MHz fixed timer as +- * doing otherwise leads to using a clocksource whose frequency varies +- * when doing cpufreq frequency changes. +- * +- * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt +- */ +- +-#include <linux/init.h> +-#include <linux/platform_device.h> +-#include <linux/kernel.h> +-#include <linux/clk.h> +-#include <linux/cpu.h> +-#include <linux/timer.h> +-#include <linux/clockchips.h> +-#include <linux/interrupt.h> +-#include <linux/of.h> +-#include <linux/of_irq.h> +-#include <linux/of_address.h> +-#include <linux/irq.h> +-#include <linux/module.h> +-#include <linux/sched_clock.h> +-#include <linux/percpu.h> +-#include <linux/syscore_ops.h> +- +-#include <asm/delay.h> +- +-/* +- * Timer block registers. +- */ +-#define TIMER_CTRL_OFF 0x0000 +-#define TIMER0_EN BIT(0) +-#define TIMER0_RELOAD_EN BIT(1) +-#define TIMER0_25MHZ BIT(11) +-#define TIMER0_DIV(div) ((div) << 19) +-#define TIMER1_EN BIT(2) +-#define TIMER1_RELOAD_EN BIT(3) +-#define TIMER1_25MHZ BIT(12) +-#define TIMER1_DIV(div) ((div) << 22) +-#define TIMER_EVENTS_STATUS 0x0004 +-#define TIMER0_CLR_MASK (~0x1) +-#define TIMER1_CLR_MASK (~0x100) +-#define TIMER0_RELOAD_OFF 0x0010 +-#define TIMER0_VAL_OFF 0x0014 +-#define TIMER1_RELOAD_OFF 0x0018 +-#define TIMER1_VAL_OFF 0x001c +- +-#define LCL_TIMER_EVENTS_STATUS 0x0028 +-/* Global timers are connected to the coherency fabric clock, and the +- below divider reduces their incrementing frequency. */ +-#define TIMER_DIVIDER_SHIFT 5 +-#define TIMER_DIVIDER (1 << TIMER_DIVIDER_SHIFT) +- +-/* +- * SoC-specific data. +- */ +-static void __iomem *timer_base, *local_base; +-static unsigned int timer_clk; +-static bool timer25Mhz = true; +-static u32 enable_mask; +- +-/* +- * Number of timer ticks per jiffy. +- */ +-static u32 ticks_per_jiffy; +- +-static struct clock_event_device __percpu *armada_370_xp_evt; +- +-static void local_timer_ctrl_clrset(u32 clr, u32 set) +-{ +- writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, +- local_base + TIMER_CTRL_OFF); +-} +- +-static u64 notrace armada_370_xp_read_sched_clock(void) +-{ +- return ~readl(timer_base + TIMER0_VAL_OFF); +-} +- +-/* +- * Clockevent handling. +- */ +-static int +-armada_370_xp_clkevt_next_event(unsigned long delta, +- struct clock_event_device *dev) +-{ +- /* +- * Clear clockevent timer interrupt. +- */ +- writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); +- +- /* +- * Setup new clockevent timer value. +- */ +- writel(delta, local_base + TIMER0_VAL_OFF); +- +- /* +- * Enable the timer. +- */ +- local_timer_ctrl_clrset(TIMER0_RELOAD_EN, enable_mask); +- return 0; +-} +- +-static int armada_370_xp_clkevt_shutdown(struct clock_event_device *evt) +-{ +- /* +- * Disable timer. +- */ +- local_timer_ctrl_clrset(TIMER0_EN, 0); +- +- /* +- * ACK pending timer interrupt. +- */ +- writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); +- return 0; +-} +- +-static int armada_370_xp_clkevt_set_periodic(struct clock_event_device *evt) +-{ +- /* +- * Setup timer to fire at 1/HZ intervals. +- */ +- writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF); +- writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF); +- +- /* +- * Enable timer. +- */ +- local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); +- return 0; +-} +- +-static int armada_370_xp_clkevt_irq; +- +-static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) +-{ +- /* +- * ACK timer interrupt and call event handler. +- */ +- struct clock_event_device *evt = dev_id; +- +- writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); +- evt->event_handler(evt); +- +- return IRQ_HANDLED; +-} +- +-/* +- * Setup the local clock events for a CPU. +- */ +-static int armada_370_xp_timer_starting_cpu(unsigned int cpu) +-{ +- struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu); +- u32 clr = 0, set = 0; +- +- if (timer25Mhz) +- set = TIMER0_25MHZ; +- else +- clr = TIMER0_25MHZ; +- local_timer_ctrl_clrset(clr, set); +- +- evt->name = "armada_370_xp_per_cpu_tick", +- evt->features = CLOCK_EVT_FEAT_ONESHOT | +- CLOCK_EVT_FEAT_PERIODIC; +- evt->shift = 32, +- evt->rating = 300, +- evt->set_next_event = armada_370_xp_clkevt_next_event, +- evt->set_state_shutdown = armada_370_xp_clkevt_shutdown; +- evt->set_state_periodic = armada_370_xp_clkevt_set_periodic; +- evt->set_state_oneshot = armada_370_xp_clkevt_shutdown; +- evt->tick_resume = armada_370_xp_clkevt_shutdown; +- evt->irq = armada_370_xp_clkevt_irq; +- evt->cpumask = cpumask_of(cpu); +- +- clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe); +- enable_percpu_irq(evt->irq, 0); +- +- return 0; +-} +- +-static int armada_370_xp_timer_dying_cpu(unsigned int cpu) +-{ +- struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu); +- +- evt->set_state_shutdown(evt); +- disable_percpu_irq(evt->irq); +- return 0; +-} +- +-static u32 timer0_ctrl_reg, timer0_local_ctrl_reg; +- +-static int armada_370_xp_timer_suspend(void) +-{ +- timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF); +- timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF); +- return 0; +-} +- +-static void armada_370_xp_timer_resume(void) +-{ +- writel(0xffffffff, timer_base + TIMER0_VAL_OFF); +- writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); +- writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF); +- writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); +-} +- +-static struct syscore_ops armada_370_xp_timer_syscore_ops = { +- .suspend = armada_370_xp_timer_suspend, +- .resume = armada_370_xp_timer_resume, +-}; +- +-static unsigned long armada_370_delay_timer_read(void) +-{ +- return ~readl(timer_base + TIMER0_VAL_OFF); +-} +- +-static struct delay_timer armada_370_delay_timer = { +- .read_current_timer = armada_370_delay_timer_read, +-}; +- +-static int __init armada_370_xp_timer_common_init(struct device_node *np) +-{ +- u32 clr = 0, set = 0; +- int res; +- +- timer_base = of_iomap(np, 0); +- if (!timer_base) { +- pr_err("Failed to iomap\n"); +- return -ENXIO; +- } +- +- local_base = of_iomap(np, 1); +- if (!local_base) { +- pr_err("Failed to iomap\n"); +- return -ENXIO; +- } +- +- if (timer25Mhz) { +- set = TIMER0_25MHZ; +- enable_mask = TIMER0_EN; +- } else { +- clr = TIMER0_25MHZ; +- enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT); +- } +- atomic_io_modify(timer_base + TIMER_CTRL_OFF, clr | set, set); +- local_timer_ctrl_clrset(clr, set); +- +- /* +- * We use timer 0 as clocksource, and private(local) timer 0 +- * for clockevents +- */ +- armada_370_xp_clkevt_irq = irq_of_parse_and_map(np, 4); +- +- ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; +- +- /* +- * Setup free-running clocksource timer (interrupts +- * disabled). +- */ +- writel(0xffffffff, timer_base + TIMER0_VAL_OFF); +- writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); +- +- atomic_io_modify(timer_base + TIMER_CTRL_OFF, +- TIMER0_RELOAD_EN | enable_mask, +- TIMER0_RELOAD_EN | enable_mask); +- +- armada_370_delay_timer.freq = timer_clk; +- register_current_timer_delay(&armada_370_delay_timer); +- +- /* +- * Set scale and timer for sched_clock. +- */ +- sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk); +- +- res = clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, +- "armada_370_xp_clocksource", +- timer_clk, 300, 32, clocksource_mmio_readl_down); +- if (res) { +- pr_err("Failed to initialize clocksource mmio\n"); +- return res; +- } +- +- armada_370_xp_evt = alloc_percpu(struct clock_event_device); +- if (!armada_370_xp_evt) +- return -ENOMEM; +- +- /* +- * Setup clockevent timer (interrupt-driven). +- */ +- res = request_percpu_irq(armada_370_xp_clkevt_irq, +- armada_370_xp_timer_interrupt, +- "armada_370_xp_per_cpu_tick", +- armada_370_xp_evt); +- /* Immediately configure the timer on the boot CPU */ +- if (res) { +- pr_err("Failed to request percpu irq\n"); +- return res; +- } +- +- res = cpuhp_setup_state(CPUHP_AP_ARMADA_TIMER_STARTING, +- "clockevents/armada:starting", +- armada_370_xp_timer_starting_cpu, +- armada_370_xp_timer_dying_cpu); +- if (res) { +- pr_err("Failed to setup hotplug state and timer\n"); +- return res; +- } +- +- register_syscore_ops(&armada_370_xp_timer_syscore_ops); +- +- return 0; +-} +- +-static int __init armada_xp_timer_init(struct device_node *np) +-{ +- struct clk *clk = of_clk_get_by_name(np, "fixed"); +- int ret; +- +- if (IS_ERR(clk)) { +- pr_err("Failed to get clock\n"); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) +- return ret; +- +- timer_clk = clk_get_rate(clk); +- +- return armada_370_xp_timer_common_init(np); +-} +-TIMER_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", +- armada_xp_timer_init); +- +-static int __init armada_375_timer_init(struct device_node *np) +-{ +- struct clk *clk; +- int ret; +- +- clk = of_clk_get_by_name(np, "fixed"); +- if (!IS_ERR(clk)) { +- ret = clk_prepare_enable(clk); +- if (ret) +- return ret; +- timer_clk = clk_get_rate(clk); +- } else { +- +- /* +- * This fallback is required in order to retain proper +- * devicetree backwards compatibility. +- */ +- clk = of_clk_get(np, 0); +- +- /* Must have at least a clock */ +- if (IS_ERR(clk)) { +- pr_err("Failed to get clock\n"); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) +- return ret; +- +- timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; +- timer25Mhz = false; +- } +- +- return armada_370_xp_timer_common_init(np); +-} +-TIMER_OF_DECLARE(armada_375, "marvell,armada-375-timer", +- armada_375_timer_init); +- +-static int __init armada_370_timer_init(struct device_node *np) +-{ +- struct clk *clk; +- int ret; +- +- clk = of_clk_get(np, 0); +- if (IS_ERR(clk)) { +- pr_err("Failed to get clock\n"); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) +- return ret; +- +- timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; +- timer25Mhz = false; +- +- return armada_370_xp_timer_common_init(np); +-} +-TIMER_OF_DECLARE(armada_370, "marvell,armada-370-timer", +- armada_370_timer_init); +diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c +deleted file mode 100644 +index 257e810ec1ad1..0000000000000 +--- a/drivers/clocksource/time-efm32.c ++++ /dev/null +@@ -1,287 +0,0 @@ +-/* +- * Copyright (C) 2013 Pengutronix +- * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> +- * +- * 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. +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include <linux/kernel.h> +-#include <linux/clocksource.h> +-#include <linux/clockchips.h> +-#include <linux/irq.h> +-#include <linux/interrupt.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/clk.h> +- +-#define TIMERn_CTRL 0x00 +-#define TIMERn_CTRL_PRESC(val) (((val) & 0xf) << 24) +-#define TIMERn_CTRL_PRESC_1024 TIMERn_CTRL_PRESC(10) +-#define TIMERn_CTRL_CLKSEL(val) (((val) & 0x3) << 16) +-#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK TIMERn_CTRL_CLKSEL(0) +-#define TIMERn_CTRL_OSMEN 0x00000010 +-#define TIMERn_CTRL_MODE(val) (((val) & 0x3) << 0) +-#define TIMERn_CTRL_MODE_UP TIMERn_CTRL_MODE(0) +-#define TIMERn_CTRL_MODE_DOWN TIMERn_CTRL_MODE(1) +- +-#define TIMERn_CMD 0x04 +-#define TIMERn_CMD_START 0x00000001 +-#define TIMERn_CMD_STOP 0x00000002 +- +-#define TIMERn_IEN 0x0c +-#define TIMERn_IF 0x10 +-#define TIMERn_IFS 0x14 +-#define TIMERn_IFC 0x18 +-#define TIMERn_IRQ_UF 0x00000002 +- +-#define TIMERn_TOP 0x1c +-#define TIMERn_CNT 0x24 +- +-struct efm32_clock_event_ddata { +- struct clock_event_device evtdev; +- void __iomem *base; +- unsigned periodic_top; +-}; +- +-static int efm32_clock_event_shutdown(struct clock_event_device *evtdev) +-{ +- struct efm32_clock_event_ddata *ddata = +- container_of(evtdev, struct efm32_clock_event_ddata, evtdev); +- +- writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); +- return 0; +-} +- +-static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev) +-{ +- struct efm32_clock_event_ddata *ddata = +- container_of(evtdev, struct efm32_clock_event_ddata, evtdev); +- +- writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); +- writel_relaxed(TIMERn_CTRL_PRESC_1024 | +- TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | +- TIMERn_CTRL_OSMEN | +- TIMERn_CTRL_MODE_DOWN, +- ddata->base + TIMERn_CTRL); +- return 0; +-} +- +-static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev) +-{ +- struct efm32_clock_event_ddata *ddata = +- container_of(evtdev, struct efm32_clock_event_ddata, evtdev); +- +- writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); +- writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP); +- writel_relaxed(TIMERn_CTRL_PRESC_1024 | +- TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | +- TIMERn_CTRL_MODE_DOWN, +- ddata->base + TIMERn_CTRL); +- writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); +- return 0; +-} +- +-static int efm32_clock_event_set_next_event(unsigned long evt, +- struct clock_event_device *evtdev) +-{ +- struct efm32_clock_event_ddata *ddata = +- container_of(evtdev, struct efm32_clock_event_ddata, evtdev); +- +- writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); +- writel_relaxed(evt, ddata->base + TIMERn_CNT); +- writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); +- +- return 0; +-} +- +-static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id) +-{ +- struct efm32_clock_event_ddata *ddata = dev_id; +- +- writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC); +- +- ddata->evtdev.event_handler(&ddata->evtdev); +- +- return IRQ_HANDLED; +-} +- +-static struct efm32_clock_event_ddata clock_event_ddata = { +- .evtdev = { +- .name = "efm32 clockevent", +- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, +- .set_state_shutdown = efm32_clock_event_shutdown, +- .set_state_periodic = efm32_clock_event_set_periodic, +- .set_state_oneshot = efm32_clock_event_set_oneshot, +- .set_next_event = efm32_clock_event_set_next_event, +- .rating = 200, +- }, +-}; +- +-static struct irqaction efm32_clock_event_irq = { +- .name = "efm32 clockevent", +- .flags = IRQF_TIMER, +- .handler = efm32_clock_event_handler, +- .dev_id = &clock_event_ddata, +-}; +- +-static int __init efm32_clocksource_init(struct device_node *np) +-{ +- struct clk *clk; +- void __iomem *base; +- unsigned long rate; +- int ret; +- +- clk = of_clk_get(np, 0); +- if (IS_ERR(clk)) { +- ret = PTR_ERR(clk); +- pr_err("failed to get clock for clocksource (%d)\n", ret); +- goto err_clk_get; +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) { +- pr_err("failed to enable timer clock for clocksource (%d)\n", +- ret); +- goto err_clk_enable; +- } +- rate = clk_get_rate(clk); +- +- base = of_iomap(np, 0); +- if (!base) { +- ret = -EADDRNOTAVAIL; +- pr_err("failed to map registers for clocksource\n"); +- goto err_iomap; +- } +- +- writel_relaxed(TIMERn_CTRL_PRESC_1024 | +- TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | +- TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL); +- writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD); +- +- ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer", +- DIV_ROUND_CLOSEST(rate, 1024), 200, 16, +- clocksource_mmio_readl_up); +- if (ret) { +- pr_err("failed to init clocksource (%d)\n", ret); +- goto err_clocksource_init; +- } +- +- return 0; +- +-err_clocksource_init: +- +- iounmap(base); +-err_iomap: +- +- clk_disable_unprepare(clk); +-err_clk_enable: +- +- clk_put(clk); +-err_clk_get: +- +- return ret; +-} +- +-static int __init efm32_clockevent_init(struct device_node *np) +-{ +- struct clk *clk; +- void __iomem *base; +- unsigned long rate; +- int irq; +- int ret; +- +- clk = of_clk_get(np, 0); +- if (IS_ERR(clk)) { +- ret = PTR_ERR(clk); +- pr_err("failed to get clock for clockevent (%d)\n", ret); +- goto err_clk_get; +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) { +- pr_err("failed to enable timer clock for clockevent (%d)\n", +- ret); +- goto err_clk_enable; +- } +- rate = clk_get_rate(clk); +- +- base = of_iomap(np, 0); +- if (!base) { +- ret = -EADDRNOTAVAIL; +- pr_err("failed to map registers for clockevent\n"); +- goto err_iomap; +- } +- +- irq = irq_of_parse_and_map(np, 0); +- if (!irq) { +- ret = -ENOENT; +- pr_err("failed to get irq for clockevent\n"); +- goto err_get_irq; +- } +- +- writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN); +- +- clock_event_ddata.base = base; +- clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ); +- +- clockevents_config_and_register(&clock_event_ddata.evtdev, +- DIV_ROUND_CLOSEST(rate, 1024), +- 0xf, 0xffff); +- +- ret = setup_irq(irq, &efm32_clock_event_irq); +- if (ret) { +- pr_err("Failed setup irq\n"); +- goto err_setup_irq; +- } +- +- return 0; +- +-err_setup_irq: +-err_get_irq: +- +- iounmap(base); +-err_iomap: +- +- clk_disable_unprepare(clk); +-err_clk_enable: +- +- clk_put(clk); +-err_clk_get: +- +- return ret; +-} +- +-/* +- * This function asserts that we have exactly one clocksource and one +- * clock_event_device in the end. +- */ +-static int __init efm32_timer_init(struct device_node *np) +-{ +- static int has_clocksource, has_clockevent; +- int ret = 0; +- +- if (!has_clocksource) { +- ret = efm32_clocksource_init(np); +- if (!ret) { +- has_clocksource = 1; +- return 0; +- } +- } +- +- if (!has_clockevent) { +- ret = efm32_clockevent_init(np); +- if (!ret) { +- has_clockevent = 1; +- return 0; +- } +- } +- +- return ret; +-} +-TIMER_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); +-TIMER_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init); +diff --git a/drivers/clocksource/time-lpc32xx.c b/drivers/clocksource/time-lpc32xx.c +deleted file mode 100644 +index d51a62a79ef76..0000000000000 +--- a/drivers/clocksource/time-lpc32xx.c ++++ /dev/null +@@ -1,314 +0,0 @@ +-/* +- * Clocksource driver for NXP LPC32xx/18xx/43xx timer +- * +- * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> +- * +- * Based on: +- * time-efm32 Copyright (C) 2013 Pengutronix +- * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * +- */ +- +-#define pr_fmt(fmt) "%s: " fmt, __func__ +- +-#include <linux/clk.h> +-#include <linux/clockchips.h> +-#include <linux/clocksource.h> +-#include <linux/delay.h> +-#include <linux/interrupt.h> +-#include <linux/irq.h> +-#include <linux/kernel.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/sched_clock.h> +- +-#define LPC32XX_TIMER_IR 0x000 +-#define LPC32XX_TIMER_IR_MR0INT BIT(0) +-#define LPC32XX_TIMER_TCR 0x004 +-#define LPC32XX_TIMER_TCR_CEN BIT(0) +-#define LPC32XX_TIMER_TCR_CRST BIT(1) +-#define LPC32XX_TIMER_TC 0x008 +-#define LPC32XX_TIMER_PR 0x00c +-#define LPC32XX_TIMER_MCR 0x014 +-#define LPC32XX_TIMER_MCR_MR0I BIT(0) +-#define LPC32XX_TIMER_MCR_MR0R BIT(1) +-#define LPC32XX_TIMER_MCR_MR0S BIT(2) +-#define LPC32XX_TIMER_MR0 0x018 +-#define LPC32XX_TIMER_CTCR 0x070 +- +-struct lpc32xx_clock_event_ddata { +- struct clock_event_device evtdev; +- void __iomem *base; +- u32 ticks_per_jiffy; +-}; +- +-/* Needed for the sched clock */ +-static void __iomem *clocksource_timer_counter; +- +-static u64 notrace lpc32xx_read_sched_clock(void) +-{ +- return readl(clocksource_timer_counter); +-} +- +-static unsigned long lpc32xx_delay_timer_read(void) +-{ +- return readl(clocksource_timer_counter); +-} +- +-static struct delay_timer lpc32xx_delay_timer = { +- .read_current_timer = lpc32xx_delay_timer_read, +-}; +- +-static int lpc32xx_clkevt_next_event(unsigned long delta, +- struct clock_event_device *evtdev) +-{ +- struct lpc32xx_clock_event_ddata *ddata = +- container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); +- +- /* +- * Place timer in reset and program the delta in the match +- * channel 0 (MR0). When the timer counter matches the value +- * in MR0 register the match will trigger an interrupt. +- * After setup the timer is released from reset and enabled. +- */ +- writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR); +- writel_relaxed(delta, ddata->base + LPC32XX_TIMER_MR0); +- writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR); +- +- return 0; +-} +- +-static int lpc32xx_clkevt_shutdown(struct clock_event_device *evtdev) +-{ +- struct lpc32xx_clock_event_ddata *ddata = +- container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); +- +- /* Disable the timer */ +- writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR); +- +- return 0; +-} +- +-static int lpc32xx_clkevt_oneshot(struct clock_event_device *evtdev) +-{ +- struct lpc32xx_clock_event_ddata *ddata = +- container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); +- +- /* +- * When using oneshot, we must also disable the timer +- * to wait for the first call to set_next_event(). +- */ +- writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR); +- +- /* Enable interrupt, reset on match and stop on match (MCR). */ +- writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R | +- LPC32XX_TIMER_MCR_MR0S, ddata->base + LPC32XX_TIMER_MCR); +- return 0; +-} +- +-static int lpc32xx_clkevt_periodic(struct clock_event_device *evtdev) +-{ +- struct lpc32xx_clock_event_ddata *ddata = +- container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); +- +- /* Enable interrupt and reset on match. */ +- writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R, +- ddata->base + LPC32XX_TIMER_MCR); +- +- /* +- * Place timer in reset and program the delta in the match +- * channel 0 (MR0). +- */ +- writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR); +- writel_relaxed(ddata->ticks_per_jiffy, ddata->base + LPC32XX_TIMER_MR0); +- writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR); +- +- return 0; +-} +- +-static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id) +-{ +- struct lpc32xx_clock_event_ddata *ddata = dev_id; +- +- /* Clear match on channel 0 */ +- writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base + LPC32XX_TIMER_IR); +- +- ddata->evtdev.event_handler(&ddata->evtdev); +- +- return IRQ_HANDLED; +-} +- +-static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = { +- .evtdev = { +- .name = "lpc3220 clockevent", +- .features = CLOCK_EVT_FEAT_ONESHOT | +- CLOCK_EVT_FEAT_PERIODIC, +- .rating = 300, +- .set_next_event = lpc32xx_clkevt_next_event, +- .set_state_shutdown = lpc32xx_clkevt_shutdown, +- .set_state_oneshot = lpc32xx_clkevt_oneshot, +- .set_state_periodic = lpc32xx_clkevt_periodic, +- }, +-}; +- +-static int __init lpc32xx_clocksource_init(struct device_node *np) +-{ +- void __iomem *base; +- unsigned long rate; +- struct clk *clk; +- int ret; +- +- clk = of_clk_get_by_name(np, "timerclk"); +- if (IS_ERR(clk)) { +- pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) { +- pr_err("clock enable failed (%d)\n", ret); +- goto err_clk_enable; +- } +- +- base = of_iomap(np, 0); +- if (!base) { +- pr_err("unable to map registers\n"); +- ret = -EADDRNOTAVAIL; +- goto err_iomap; +- } +- +- /* +- * Disable and reset timer then set it to free running timer +- * mode (CTCR) with no prescaler (PR) or match operations (MCR). +- * After setup the timer is released from reset and enabled. +- */ +- writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR); +- writel_relaxed(0, base + LPC32XX_TIMER_PR); +- writel_relaxed(0, base + LPC32XX_TIMER_MCR); +- writel_relaxed(0, base + LPC32XX_TIMER_CTCR); +- writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR); +- +- rate = clk_get_rate(clk); +- ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer", +- rate, 300, 32, clocksource_mmio_readl_up); +- if (ret) { +- pr_err("failed to init clocksource (%d)\n", ret); +- goto err_clocksource_init; +- } +- +- clocksource_timer_counter = base + LPC32XX_TIMER_TC; +- lpc32xx_delay_timer.freq = rate; +- register_current_timer_delay(&lpc32xx_delay_timer); +- sched_clock_register(lpc32xx_read_sched_clock, 32, rate); +- +- return 0; +- +-err_clocksource_init: +- iounmap(base); +-err_iomap: +- clk_disable_unprepare(clk); +-err_clk_enable: +- clk_put(clk); +- return ret; +-} +- +-static int __init lpc32xx_clockevent_init(struct device_node *np) +-{ +- void __iomem *base; +- unsigned long rate; +- struct clk *clk; +- int ret, irq; +- +- clk = of_clk_get_by_name(np, "timerclk"); +- if (IS_ERR(clk)) { +- pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) { +- pr_err("clock enable failed (%d)\n", ret); +- goto err_clk_enable; +- } +- +- base = of_iomap(np, 0); +- if (!base) { +- pr_err("unable to map registers\n"); +- ret = -EADDRNOTAVAIL; +- goto err_iomap; +- } +- +- irq = irq_of_parse_and_map(np, 0); +- if (!irq) { +- pr_err("get irq failed\n"); +- ret = -ENOENT; +- goto err_irq; +- } +- +- /* +- * Disable timer and clear any pending interrupt (IR) on match +- * channel 0 (MR0). Clear the prescaler as it's not used. +- */ +- writel_relaxed(0, base + LPC32XX_TIMER_TCR); +- writel_relaxed(0, base + LPC32XX_TIMER_PR); +- writel_relaxed(0, base + LPC32XX_TIMER_CTCR); +- writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR); +- +- rate = clk_get_rate(clk); +- lpc32xx_clk_event_ddata.base = base; +- lpc32xx_clk_event_ddata.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); +- clockevents_config_and_register(&lpc32xx_clk_event_ddata.evtdev, +- rate, 1, -1); +- +- ret = request_irq(irq, lpc32xx_clock_event_handler, +- IRQF_TIMER | IRQF_IRQPOLL, "lpc3220 clockevent", +- &lpc32xx_clk_event_ddata); +- if (ret) { +- pr_err("request irq failed\n"); +- goto err_irq; +- } +- +- return 0; +- +-err_irq: +- iounmap(base); +-err_iomap: +- clk_disable_unprepare(clk); +-err_clk_enable: +- clk_put(clk); +- return ret; +-} +- +-/* +- * This function asserts that we have exactly one clocksource and one +- * clock_event_device in the end. +- */ +-static int __init lpc32xx_timer_init(struct device_node *np) +-{ +- static int has_clocksource, has_clockevent; +- int ret = 0; +- +- if (!has_clocksource) { +- ret = lpc32xx_clocksource_init(np); +- if (!ret) { +- has_clocksource = 1; +- return 0; +- } +- } +- +- if (!has_clockevent) { +- ret = lpc32xx_clockevent_init(np); +- if (!ret) { +- has_clockevent = 1; +- return 0; +- } +- } +- +- return ret; +-} +-TIMER_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init); +diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c +deleted file mode 100644 +index 12202067fe4b8..0000000000000 +--- a/drivers/clocksource/time-orion.c ++++ /dev/null +@@ -1,192 +0,0 @@ +-/* +- * Marvell Orion SoC timer handling. +- * +- * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * +- * Timer 0 is used as free-running clocksource, while timer 1 is +- * used as clock_event_device. +- */ +- +-#include <linux/kernel.h> +-#include <linux/bitops.h> +-#include <linux/clk.h> +-#include <linux/clockchips.h> +-#include <linux/delay.h> +-#include <linux/interrupt.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/spinlock.h> +-#include <linux/sched_clock.h> +- +-#define TIMER_CTRL 0x00 +-#define TIMER0_EN BIT(0) +-#define TIMER0_RELOAD_EN BIT(1) +-#define TIMER1_EN BIT(2) +-#define TIMER1_RELOAD_EN BIT(3) +-#define TIMER0_RELOAD 0x10 +-#define TIMER0_VAL 0x14 +-#define TIMER1_RELOAD 0x18 +-#define TIMER1_VAL 0x1c +- +-#define ORION_ONESHOT_MIN 1 +-#define ORION_ONESHOT_MAX 0xfffffffe +- +-static void __iomem *timer_base; +- +-static unsigned long notrace orion_read_timer(void) +-{ +- return ~readl(timer_base + TIMER0_VAL); +-} +- +-static struct delay_timer orion_delay_timer = { +- .read_current_timer = orion_read_timer, +-}; +- +-static void orion_delay_timer_init(unsigned long rate) +-{ +- orion_delay_timer.freq = rate; +- register_current_timer_delay(&orion_delay_timer); +-} +- +-/* +- * Free-running clocksource handling. +- */ +-static u64 notrace orion_read_sched_clock(void) +-{ +- return ~readl(timer_base + TIMER0_VAL); +-} +- +-/* +- * Clockevent handling. +- */ +-static u32 ticks_per_jiffy; +- +-static int orion_clkevt_next_event(unsigned long delta, +- struct clock_event_device *dev) +-{ +- /* setup and enable one-shot timer */ +- writel(delta, timer_base + TIMER1_VAL); +- atomic_io_modify(timer_base + TIMER_CTRL, +- TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN); +- +- return 0; +-} +- +-static int orion_clkevt_shutdown(struct clock_event_device *dev) +-{ +- /* disable timer */ +- atomic_io_modify(timer_base + TIMER_CTRL, +- TIMER1_RELOAD_EN | TIMER1_EN, 0); +- return 0; +-} +- +-static int orion_clkevt_set_periodic(struct clock_event_device *dev) +-{ +- /* setup and enable periodic timer at 1/HZ intervals */ +- writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); +- writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); +- atomic_io_modify(timer_base + TIMER_CTRL, +- TIMER1_RELOAD_EN | TIMER1_EN, +- TIMER1_RELOAD_EN | TIMER1_EN); +- return 0; +-} +- +-static struct clock_event_device orion_clkevt = { +- .name = "orion_event", +- .features = CLOCK_EVT_FEAT_ONESHOT | +- CLOCK_EVT_FEAT_PERIODIC, +- .shift = 32, +- .rating = 300, +- .set_next_event = orion_clkevt_next_event, +- .set_state_shutdown = orion_clkevt_shutdown, +- .set_state_periodic = orion_clkevt_set_periodic, +- .set_state_oneshot = orion_clkevt_shutdown, +- .tick_resume = orion_clkevt_shutdown, +-}; +- +-static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) +-{ +- orion_clkevt.event_handler(&orion_clkevt); +- return IRQ_HANDLED; +-} +- +-static struct irqaction orion_clkevt_irq = { +- .name = "orion_event", +- .flags = IRQF_TIMER, +- .handler = orion_clkevt_irq_handler, +-}; +- +-static int __init orion_timer_init(struct device_node *np) +-{ +- unsigned long rate; +- struct clk *clk; +- int irq, ret; +- +- /* timer registers are shared with watchdog timer */ +- timer_base = of_iomap(np, 0); +- if (!timer_base) { +- pr_err("%s: unable to map resource\n", np->name); +- return -ENXIO; +- } +- +- clk = of_clk_get(np, 0); +- if (IS_ERR(clk)) { +- pr_err("%s: unable to get clk\n", np->name); +- return PTR_ERR(clk); +- } +- +- ret = clk_prepare_enable(clk); +- if (ret) { +- pr_err("Failed to prepare clock\n"); +- return ret; +- } +- +- /* we are only interested in timer1 irq */ +- irq = irq_of_parse_and_map(np, 1); +- if (irq <= 0) { +- pr_err("%s: unable to parse timer1 irq\n", np->name); +- return -EINVAL; +- } +- +- rate = clk_get_rate(clk); +- +- /* setup timer0 as free-running clocksource */ +- writel(~0, timer_base + TIMER0_VAL); +- writel(~0, timer_base + TIMER0_RELOAD); +- atomic_io_modify(timer_base + TIMER_CTRL, +- TIMER0_RELOAD_EN | TIMER0_EN, +- TIMER0_RELOAD_EN | TIMER0_EN); +- +- ret = clocksource_mmio_init(timer_base + TIMER0_VAL, +- "orion_clocksource", rate, 300, 32, +- clocksource_mmio_readl_down); +- if (ret) { +- pr_err("Failed to initialize mmio timer\n"); +- return ret; +- } +- +- sched_clock_register(orion_read_sched_clock, 32, rate); +- +- /* setup timer1 as clockevent timer */ +- ret = setup_irq(irq, &orion_clkevt_irq); +- if (ret) { +- pr_err("%s: unable to setup irq\n", np->name); +- return ret; +- } +- +- ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; +- orion_clkevt.cpumask = cpumask_of(0); +- orion_clkevt.irq = irq; +- clockevents_config_and_register(&orion_clkevt, rate, +- ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); +- +- +- orion_delay_timer_init(rate); +- +- return 0; +-} +-TIMER_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); +diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c +deleted file mode 100644 +index a2dd85d0c1d75..0000000000000 +--- a/drivers/clocksource/time-pistachio.c ++++ /dev/null +@@ -1,218 +0,0 @@ +-/* +- * Pistachio clocksource based on general-purpose timers +- * +- * Copyright (C) 2015 Imagination Technologies +- * +- * This file is subject to the terms and conditions of the GNU General Public +- * License. See the file "COPYING" in the main directory of this archive +- * for more details. +- */ +- +-#define pr_fmt(fmt) "%s: " fmt, __func__ +- +-#include <linux/clk.h> +-#include <linux/clocksource.h> +-#include <linux/clockchips.h> +-#include <linux/delay.h> +-#include <linux/err.h> +-#include <linux/init.h> +-#include <linux/spinlock.h> +-#include <linux/mfd/syscon.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/platform_device.h> +-#include <linux/regmap.h> +-#include <linux/sched_clock.h> +-#include <linux/time.h> +- +-/* Top level reg */ +-#define CR_TIMER_CTRL_CFG 0x00 +-#define TIMER_ME_GLOBAL BIT(0) +-#define CR_TIMER_REV 0x10 +- +-/* Timer specific registers */ +-#define TIMER_CFG 0x20 +-#define TIMER_ME_LOCAL BIT(0) +-#define TIMER_RELOAD_VALUE 0x24 +-#define TIMER_CURRENT_VALUE 0x28 +-#define TIMER_CURRENT_OVERFLOW_VALUE 0x2C +-#define TIMER_IRQ_STATUS 0x30 +-#define TIMER_IRQ_CLEAR 0x34 +-#define TIMER_IRQ_MASK 0x38 +- +-#define PERIP_TIMER_CONTROL 0x90 +- +-/* Timer specific configuration Values */ +-#define RELOAD_VALUE 0xffffffff +- +-struct pistachio_clocksource { +- void __iomem *base; +- raw_spinlock_t lock; +- struct clocksource cs; +-}; +- +-static struct pistachio_clocksource pcs_gpt; +- +-#define to_pistachio_clocksource(cs) \ +- container_of(cs, struct pistachio_clocksource, cs) +- +-static inline u32 gpt_readl(void __iomem *base, u32 offset, u32 gpt_id) +-{ +- return readl(base + 0x20 * gpt_id + offset); +-} +- +-static inline void gpt_writel(void __iomem *base, u32 value, u32 offset, +- u32 gpt_id) +-{ +- writel(value, base + 0x20 * gpt_id + offset); +-} +- +-static u64 notrace +-pistachio_clocksource_read_cycles(struct clocksource *cs) +-{ +- struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); +- u32 counter, overflw; +- unsigned long flags; +- +- /* +- * The counter value is only refreshed after the overflow value is read. +- * And they must be read in strict order, hence raw spin lock added. +- */ +- +- raw_spin_lock_irqsave(&pcs->lock, flags); +- overflw = gpt_readl(pcs->base, TIMER_CURRENT_OVERFLOW_VALUE, 0); +- counter = gpt_readl(pcs->base, TIMER_CURRENT_VALUE, 0); +- raw_spin_unlock_irqrestore(&pcs->lock, flags); +- +- return (u64)~counter; +-} +- +-static u64 notrace pistachio_read_sched_clock(void) +-{ +- return pistachio_clocksource_read_cycles(&pcs_gpt.cs); +-} +- +-static void pistachio_clksrc_set_mode(struct clocksource *cs, int timeridx, +- int enable) +-{ +- struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); +- u32 val; +- +- val = gpt_readl(pcs->base, TIMER_CFG, timeridx); +- if (enable) +- val |= TIMER_ME_LOCAL; +- else +- val &= ~TIMER_ME_LOCAL; +- +- gpt_writel(pcs->base, val, TIMER_CFG, timeridx); +-} +- +-static void pistachio_clksrc_enable(struct clocksource *cs, int timeridx) +-{ +- struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); +- +- /* Disable GPT local before loading reload value */ +- pistachio_clksrc_set_mode(cs, timeridx, false); +- gpt_writel(pcs->base, RELOAD_VALUE, TIMER_RELOAD_VALUE, timeridx); +- pistachio_clksrc_set_mode(cs, timeridx, true); +-} +- +-static void pistachio_clksrc_disable(struct clocksource *cs, int timeridx) +-{ +- /* Disable GPT local */ +- pistachio_clksrc_set_mode(cs, timeridx, false); +-} +- +-static int pistachio_clocksource_enable(struct clocksource *cs) +-{ +- pistachio_clksrc_enable(cs, 0); +- return 0; +-} +- +-static void pistachio_clocksource_disable(struct clocksource *cs) +-{ +- pistachio_clksrc_disable(cs, 0); +-} +- +-/* Desirable clock source for pistachio platform */ +-static struct pistachio_clocksource pcs_gpt = { +- .cs = { +- .name = "gptimer", +- .rating = 300, +- .enable = pistachio_clocksource_enable, +- .disable = pistachio_clocksource_disable, +- .read = pistachio_clocksource_read_cycles, +- .mask = CLOCKSOURCE_MASK(32), +- .flags = CLOCK_SOURCE_IS_CONTINUOUS | +- CLOCK_SOURCE_SUSPEND_NONSTOP, +- }, +-}; +- +-static int __init pistachio_clksrc_of_init(struct device_node *node) +-{ +- struct clk *sys_clk, *fast_clk; +- struct regmap *periph_regs; +- unsigned long rate; +- int ret; +- +- pcs_gpt.base = of_iomap(node, 0); +- if (!pcs_gpt.base) { +- pr_err("cannot iomap\n"); +- return -ENXIO; +- } +- +- periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph"); +- if (IS_ERR(periph_regs)) { +- pr_err("cannot get peripheral regmap (%ld)\n", +- PTR_ERR(periph_regs)); +- return PTR_ERR(periph_regs); +- } +- +- /* Switch to using the fast counter clock */ +- ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL, +- 0xf, 0x0); +- if (ret) +- return ret; +- +- sys_clk = of_clk_get_by_name(node, "sys"); +- if (IS_ERR(sys_clk)) { +- pr_err("clock get failed (%ld)\n", PTR_ERR(sys_clk)); +- return PTR_ERR(sys_clk); +- } +- +- fast_clk = of_clk_get_by_name(node, "fast"); +- if (IS_ERR(fast_clk)) { +- pr_err("clock get failed (%lu)\n", PTR_ERR(fast_clk)); +- return PTR_ERR(fast_clk); +- } +- +- ret = clk_prepare_enable(sys_clk); +- if (ret < 0) { +- pr_err("failed to enable clock (%d)\n", ret); +- return ret; +- } +- +- ret = clk_prepare_enable(fast_clk); +- if (ret < 0) { +- pr_err("failed to enable clock (%d)\n", ret); +- clk_disable_unprepare(sys_clk); +- return ret; +- } +- +- rate = clk_get_rate(fast_clk); +- +- /* Disable irq's for clocksource usage */ +- gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 0); +- gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 1); +- gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 2); +- gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 3); +- +- /* Enable timer block */ +- writel(TIMER_ME_GLOBAL, pcs_gpt.base); +- +- raw_spin_lock_init(&pcs_gpt.lock); +- sched_clock_register(pistachio_read_sched_clock, 32, rate); +- return clocksource_register_hz(&pcs_gpt.cs, rate); +-} +-TIMER_OF_DECLARE(pistachio_gptimer, "img,pistachio-gptimer", +- pistachio_clksrc_of_init); +diff --git a/drivers/clocksource/timer-armada-370-xp.c b/drivers/clocksource/timer-armada-370-xp.c +new file mode 100644 +index 0000000000000..edf1a46269f10 +--- /dev/null ++++ b/drivers/clocksource/timer-armada-370-xp.c +@@ -0,0 +1,416 @@ ++/* ++ * Marvell Armada 370/XP SoC timer handling. ++ * ++ * Copyright (C) 2012 Marvell ++ * ++ * Lior Amsalem <alior@marvell.com> ++ * Gregory CLEMENT <gregory.clement@free-electrons.com> ++ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ * ++ * Timer 0 is used as free-running clocksource, while timer 1 is ++ * used as clock_event_device. ++ * ++ * --- ++ * Clocksource driver for Armada 370 and Armada XP SoC. ++ * This driver implements one compatible string for each SoC, given ++ * each has its own characteristics: ++ * ++ * * Armada 370 has no 25 MHz fixed timer. ++ * ++ * * Armada XP cannot work properly without such 25 MHz fixed timer as ++ * doing otherwise leads to using a clocksource whose frequency varies ++ * when doing cpufreq frequency changes. ++ * ++ * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt ++ */ ++ ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/kernel.h> ++#include <linux/clk.h> ++#include <linux/cpu.h> ++#include <linux/timer.h> ++#include <linux/clockchips.h> ++#include <linux/interrupt.h> ++#include <linux/of.h> ++#include <linux/of_irq.h> ++#include <linux/of_address.h> ++#include <linux/irq.h> ++#include <linux/module.h> ++#include <linux/sched_clock.h> ++#include <linux/percpu.h> ++#include <linux/syscore_ops.h> ++ ++#include <asm/delay.h> ++ ++/* ++ * Timer block registers. ++ */ ++#define TIMER_CTRL_OFF 0x0000 ++#define TIMER0_EN BIT(0) ++#define TIMER0_RELOAD_EN BIT(1) ++#define TIMER0_25MHZ BIT(11) ++#define TIMER0_DIV(div) ((div) << 19) ++#define TIMER1_EN BIT(2) ++#define TIMER1_RELOAD_EN BIT(3) ++#define TIMER1_25MHZ BIT(12) ++#define TIMER1_DIV(div) ((div) << 22) ++#define TIMER_EVENTS_STATUS 0x0004 ++#define TIMER0_CLR_MASK (~0x1) ++#define TIMER1_CLR_MASK (~0x100) ++#define TIMER0_RELOAD_OFF 0x0010 ++#define TIMER0_VAL_OFF 0x0014 ++#define TIMER1_RELOAD_OFF 0x0018 ++#define TIMER1_VAL_OFF 0x001c ++ ++#define LCL_TIMER_EVENTS_STATUS 0x0028 ++/* Global timers are connected to the coherency fabric clock, and the ++ below divider reduces their incrementing frequency. */ ++#define TIMER_DIVIDER_SHIFT 5 ++#define TIMER_DIVIDER (1 << TIMER_DIVIDER_SHIFT) ++ ++/* ++ * SoC-specific data. ++ */ ++static void __iomem *timer_base, *local_base; ++static unsigned int timer_clk; ++static bool timer25Mhz = true; ++static u32 enable_mask; ++ ++/* ++ * Number of timer ticks per jiffy. ++ */ ++static u32 ticks_per_jiffy; ++ ++static struct clock_event_device __percpu *armada_370_xp_evt; ++ ++static void local_timer_ctrl_clrset(u32 clr, u32 set) ++{ ++ writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, ++ local_base + TIMER_CTRL_OFF); ++} ++ ++static u64 notrace armada_370_xp_read_sched_clock(void) ++{ ++ return ~readl(timer_base + TIMER0_VAL_OFF); ++} ++ ++/* ++ * Clockevent handling. ++ */ ++static int ++armada_370_xp_clkevt_next_event(unsigned long delta, ++ struct clock_event_device *dev) ++{ ++ /* ++ * Clear clockevent timer interrupt. ++ */ ++ writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); ++ ++ /* ++ * Setup new clockevent timer value. ++ */ ++ writel(delta, local_base + TIMER0_VAL_OFF); ++ ++ /* ++ * Enable the timer. ++ */ ++ local_timer_ctrl_clrset(TIMER0_RELOAD_EN, enable_mask); ++ return 0; ++} ++ ++static int armada_370_xp_clkevt_shutdown(struct clock_event_device *evt) ++{ ++ /* ++ * Disable timer. ++ */ ++ local_timer_ctrl_clrset(TIMER0_EN, 0); ++ ++ /* ++ * ACK pending timer interrupt. ++ */ ++ writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); ++ return 0; ++} ++ ++static int armada_370_xp_clkevt_set_periodic(struct clock_event_device *evt) ++{ ++ /* ++ * Setup timer to fire at 1/HZ intervals. ++ */ ++ writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF); ++ writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF); ++ ++ /* ++ * Enable timer. ++ */ ++ local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | enable_mask); ++ return 0; ++} ++ ++static int armada_370_xp_clkevt_irq; ++ ++static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) ++{ ++ /* ++ * ACK timer interrupt and call event handler. ++ */ ++ struct clock_event_device *evt = dev_id; ++ ++ writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Setup the local clock events for a CPU. ++ */ ++static int armada_370_xp_timer_starting_cpu(unsigned int cpu) ++{ ++ struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu); ++ u32 clr = 0, set = 0; ++ ++ if (timer25Mhz) ++ set = TIMER0_25MHZ; ++ else ++ clr = TIMER0_25MHZ; ++ local_timer_ctrl_clrset(clr, set); ++ ++ evt->name = "armada_370_xp_per_cpu_tick", ++ evt->features = CLOCK_EVT_FEAT_ONESHOT | ++ CLOCK_EVT_FEAT_PERIODIC; ++ evt->shift = 32, ++ evt->rating = 300, ++ evt->set_next_event = armada_370_xp_clkevt_next_event, ++ evt->set_state_shutdown = armada_370_xp_clkevt_shutdown; ++ evt->set_state_periodic = armada_370_xp_clkevt_set_periodic; ++ evt->set_state_oneshot = armada_370_xp_clkevt_shutdown; ++ evt->tick_resume = armada_370_xp_clkevt_shutdown; ++ evt->irq = armada_370_xp_clkevt_irq; ++ evt->cpumask = cpumask_of(cpu); ++ ++ clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe); ++ enable_percpu_irq(evt->irq, 0); ++ ++ return 0; ++} ++ ++static int armada_370_xp_timer_dying_cpu(unsigned int cpu) ++{ ++ struct clock_event_device *evt = per_cpu_ptr(armada_370_xp_evt, cpu); ++ ++ evt->set_state_shutdown(evt); ++ disable_percpu_irq(evt->irq); ++ return 0; ++} ++ ++static u32 timer0_ctrl_reg, timer0_local_ctrl_reg; ++ ++static int armada_370_xp_timer_suspend(void) ++{ ++ timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF); ++ timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF); ++ return 0; ++} ++ ++static void armada_370_xp_timer_resume(void) ++{ ++ writel(0xffffffff, timer_base + TIMER0_VAL_OFF); ++ writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); ++ writel(timer0_ctrl_reg, timer_base + TIMER_CTRL_OFF); ++ writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); ++} ++ ++static struct syscore_ops armada_370_xp_timer_syscore_ops = { ++ .suspend = armada_370_xp_timer_suspend, ++ .resume = armada_370_xp_timer_resume, ++}; ++ ++static unsigned long armada_370_delay_timer_read(void) ++{ ++ return ~readl(timer_base + TIMER0_VAL_OFF); ++} ++ ++static struct delay_timer armada_370_delay_timer = { ++ .read_current_timer = armada_370_delay_timer_read, ++}; ++ ++static int __init armada_370_xp_timer_common_init(struct device_node *np) ++{ ++ u32 clr = 0, set = 0; ++ int res; ++ ++ timer_base = of_iomap(np, 0); ++ if (!timer_base) { ++ pr_err("Failed to iomap\n"); ++ return -ENXIO; ++ } ++ ++ local_base = of_iomap(np, 1); ++ if (!local_base) { ++ pr_err("Failed to iomap\n"); ++ return -ENXIO; ++ } ++ ++ if (timer25Mhz) { ++ set = TIMER0_25MHZ; ++ enable_mask = TIMER0_EN; ++ } else { ++ clr = TIMER0_25MHZ; ++ enable_mask = TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT); ++ } ++ atomic_io_modify(timer_base + TIMER_CTRL_OFF, clr | set, set); ++ local_timer_ctrl_clrset(clr, set); ++ ++ /* ++ * We use timer 0 as clocksource, and private(local) timer 0 ++ * for clockevents ++ */ ++ armada_370_xp_clkevt_irq = irq_of_parse_and_map(np, 4); ++ ++ ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; ++ ++ /* ++ * Setup free-running clocksource timer (interrupts ++ * disabled). ++ */ ++ writel(0xffffffff, timer_base + TIMER0_VAL_OFF); ++ writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); ++ ++ atomic_io_modify(timer_base + TIMER_CTRL_OFF, ++ TIMER0_RELOAD_EN | enable_mask, ++ TIMER0_RELOAD_EN | enable_mask); ++ ++ armada_370_delay_timer.freq = timer_clk; ++ register_current_timer_delay(&armada_370_delay_timer); ++ ++ /* ++ * Set scale and timer for sched_clock. ++ */ ++ sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk); ++ ++ res = clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, ++ "armada_370_xp_clocksource", ++ timer_clk, 300, 32, clocksource_mmio_readl_down); ++ if (res) { ++ pr_err("Failed to initialize clocksource mmio\n"); ++ return res; ++ } ++ ++ armada_370_xp_evt = alloc_percpu(struct clock_event_device); ++ if (!armada_370_xp_evt) ++ return -ENOMEM; ++ ++ /* ++ * Setup clockevent timer (interrupt-driven). ++ */ ++ res = request_percpu_irq(armada_370_xp_clkevt_irq, ++ armada_370_xp_timer_interrupt, ++ "armada_370_xp_per_cpu_tick", ++ armada_370_xp_evt); ++ /* Immediately configure the timer on the boot CPU */ ++ if (res) { ++ pr_err("Failed to request percpu irq\n"); ++ return res; ++ } ++ ++ res = cpuhp_setup_state(CPUHP_AP_ARMADA_TIMER_STARTING, ++ "clockevents/armada:starting", ++ armada_370_xp_timer_starting_cpu, ++ armada_370_xp_timer_dying_cpu); ++ if (res) { ++ pr_err("Failed to setup hotplug state and timer\n"); ++ return res; ++ } ++ ++ register_syscore_ops(&armada_370_xp_timer_syscore_ops); ++ ++ return 0; ++} ++ ++static int __init armada_xp_timer_init(struct device_node *np) ++{ ++ struct clk *clk = of_clk_get_by_name(np, "fixed"); ++ int ret; ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to get clock\n"); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ return ret; ++ ++ timer_clk = clk_get_rate(clk); ++ ++ return armada_370_xp_timer_common_init(np); ++} ++TIMER_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", ++ armada_xp_timer_init); ++ ++static int __init armada_375_timer_init(struct device_node *np) ++{ ++ struct clk *clk; ++ int ret; ++ ++ clk = of_clk_get_by_name(np, "fixed"); ++ if (!IS_ERR(clk)) { ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ return ret; ++ timer_clk = clk_get_rate(clk); ++ } else { ++ ++ /* ++ * This fallback is required in order to retain proper ++ * devicetree backwards compatibility. ++ */ ++ clk = of_clk_get(np, 0); ++ ++ /* Must have at least a clock */ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to get clock\n"); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ return ret; ++ ++ timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; ++ timer25Mhz = false; ++ } ++ ++ return armada_370_xp_timer_common_init(np); ++} ++TIMER_OF_DECLARE(armada_375, "marvell,armada-375-timer", ++ armada_375_timer_init); ++ ++static int __init armada_370_timer_init(struct device_node *np) ++{ ++ struct clk *clk; ++ int ret; ++ ++ clk = of_clk_get(np, 0); ++ if (IS_ERR(clk)) { ++ pr_err("Failed to get clock\n"); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ return ret; ++ ++ timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; ++ timer25Mhz = false; ++ ++ return armada_370_xp_timer_common_init(np); ++} ++TIMER_OF_DECLARE(armada_370, "marvell,armada-370-timer", ++ armada_370_timer_init); +diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c +new file mode 100644 +index 0000000000000..16b9bfb257564 +--- /dev/null ++++ b/drivers/clocksource/timer-cadence-ttc.c +@@ -0,0 +1,560 @@ ++/* ++ * This file contains driver for the Cadence Triple Timer Counter Rev 06 ++ * ++ * Copyright (C) 2011-2013 Xilinx ++ * ++ * based on arch/mips/kernel/time.c timer driver ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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/interrupt.h> ++#include <linux/clockchips.h> ++#include <linux/clocksource.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/slab.h> ++#include <linux/sched_clock.h> ++#include <linux/module.h> ++#include <linux/of_platform.h> ++ ++/* ++ * This driver configures the 2 16/32-bit count-up timers as follows: ++ * ++ * T1: Timer 1, clocksource for generic timekeeping ++ * T2: Timer 2, clockevent source for hrtimers ++ * T3: Timer 3, <unused> ++ * ++ * The input frequency to the timer module for emulation is 2.5MHz which is ++ * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32, ++ * the timers are clocked at 78.125KHz (12.8 us resolution). ++ ++ * The input frequency to the timer module in silicon is configurable and ++ * obtained from device tree. The pre-scaler of 32 is used. ++ */ ++ ++/* ++ * Timer Register Offset Definitions of Timer 1, Increment base address by 4 ++ * and use same offsets for Timer 2 ++ */ ++#define TTC_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */ ++#define TTC_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */ ++#define TTC_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */ ++#define TTC_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */ ++#define TTC_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */ ++#define TTC_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */ ++ ++#define TTC_CNT_CNTRL_DISABLE_MASK 0x1 ++ ++#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */ ++#define TTC_CLK_CNTRL_PSV_MASK 0x1e ++#define TTC_CLK_CNTRL_PSV_SHIFT 1 ++ ++/* ++ * Setup the timers to use pre-scaling, using a fixed value for now that will ++ * work across most input frequency, but it may need to be more dynamic ++ */ ++#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ ++#define PRESCALE 2048 /* The exponent must match this */ ++#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1) ++#define CLK_CNTRL_PRESCALE_EN 1 ++#define CNT_CNTRL_RESET (1 << 4) ++ ++#define MAX_F_ERR 50 ++ ++/** ++ * struct ttc_timer - This definition defines local timer structure ++ * ++ * @base_addr: Base address of timer ++ * @freq: Timer input clock frequency ++ * @clk: Associated clock source ++ * @clk_rate_change_nb Notifier block for clock rate changes ++ */ ++struct ttc_timer { ++ void __iomem *base_addr; ++ unsigned long freq; ++ struct clk *clk; ++ struct notifier_block clk_rate_change_nb; ++}; ++ ++#define to_ttc_timer(x) \ ++ container_of(x, struct ttc_timer, clk_rate_change_nb) ++ ++struct ttc_timer_clocksource { ++ u32 scale_clk_ctrl_reg_old; ++ u32 scale_clk_ctrl_reg_new; ++ struct ttc_timer ttc; ++ struct clocksource cs; ++}; ++ ++#define to_ttc_timer_clksrc(x) \ ++ container_of(x, struct ttc_timer_clocksource, cs) ++ ++struct ttc_timer_clockevent { ++ struct ttc_timer ttc; ++ struct clock_event_device ce; ++}; ++ ++#define to_ttc_timer_clkevent(x) \ ++ container_of(x, struct ttc_timer_clockevent, ce) ++ ++static void __iomem *ttc_sched_clock_val_reg; ++ ++/** ++ * ttc_set_interval - Set the timer interval value ++ * ++ * @timer: Pointer to the timer instance ++ * @cycles: Timer interval ticks ++ **/ ++static void ttc_set_interval(struct ttc_timer *timer, ++ unsigned long cycles) ++{ ++ u32 ctrl_reg; ++ ++ /* Disable the counter, set the counter value and re-enable counter */ ++ ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; ++ writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ ++ writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); ++ ++ /* ++ * Reset the counter (0x10) so that it starts from 0, one-shot ++ * mode makes this needed for timing to be right. ++ */ ++ ctrl_reg |= CNT_CNTRL_RESET; ++ ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; ++ writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++} ++ ++/** ++ * ttc_clock_event_interrupt - Clock event timer interrupt handler ++ * ++ * @irq: IRQ number of the Timer ++ * @dev_id: void pointer to the ttc_timer instance ++ * ++ * returns: Always IRQ_HANDLED - success ++ **/ ++static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id) ++{ ++ struct ttc_timer_clockevent *ttce = dev_id; ++ struct ttc_timer *timer = &ttce->ttc; ++ ++ /* Acknowledge the interrupt and call event handler */ ++ readl_relaxed(timer->base_addr + TTC_ISR_OFFSET); ++ ++ ttce->ce.event_handler(&ttce->ce); ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * __ttc_clocksource_read - Reads the timer counter register ++ * ++ * returns: Current timer counter register value ++ **/ ++static u64 __ttc_clocksource_read(struct clocksource *cs) ++{ ++ struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; ++ ++ return (u64)readl_relaxed(timer->base_addr + ++ TTC_COUNT_VAL_OFFSET); ++} ++ ++static u64 notrace ttc_sched_clock_read(void) ++{ ++ return readl_relaxed(ttc_sched_clock_val_reg); ++} ++ ++/** ++ * ttc_set_next_event - Sets the time interval for next event ++ * ++ * @cycles: Timer interval ticks ++ * @evt: Address of clock event instance ++ * ++ * returns: Always 0 - success ++ **/ ++static int ttc_set_next_event(unsigned long cycles, ++ struct clock_event_device *evt) ++{ ++ struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); ++ struct ttc_timer *timer = &ttce->ttc; ++ ++ ttc_set_interval(timer, cycles); ++ return 0; ++} ++ ++/** ++ * ttc_set_{shutdown|oneshot|periodic} - Sets the state of timer ++ * ++ * @evt: Address of clock event instance ++ **/ ++static int ttc_shutdown(struct clock_event_device *evt) ++{ ++ struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); ++ struct ttc_timer *timer = &ttce->ttc; ++ u32 ctrl_reg; ++ ++ ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; ++ writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ return 0; ++} ++ ++static int ttc_set_periodic(struct clock_event_device *evt) ++{ ++ struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); ++ struct ttc_timer *timer = &ttce->ttc; ++ ++ ttc_set_interval(timer, ++ DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ)); ++ return 0; ++} ++ ++static int ttc_resume(struct clock_event_device *evt) ++{ ++ struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); ++ struct ttc_timer *timer = &ttce->ttc; ++ u32 ctrl_reg; ++ ++ ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; ++ writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); ++ return 0; ++} ++ ++static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, ++ unsigned long event, void *data) ++{ ++ struct clk_notifier_data *ndata = data; ++ struct ttc_timer *ttc = to_ttc_timer(nb); ++ struct ttc_timer_clocksource *ttccs = container_of(ttc, ++ struct ttc_timer_clocksource, ttc); ++ ++ switch (event) { ++ case PRE_RATE_CHANGE: ++ { ++ u32 psv; ++ unsigned long factor, rate_low, rate_high; ++ ++ if (ndata->new_rate > ndata->old_rate) { ++ factor = DIV_ROUND_CLOSEST(ndata->new_rate, ++ ndata->old_rate); ++ rate_low = ndata->old_rate; ++ rate_high = ndata->new_rate; ++ } else { ++ factor = DIV_ROUND_CLOSEST(ndata->old_rate, ++ ndata->new_rate); ++ rate_low = ndata->new_rate; ++ rate_high = ndata->old_rate; ++ } ++ ++ if (!is_power_of_2(factor)) ++ return NOTIFY_BAD; ++ ++ if (abs(rate_high - (factor * rate_low)) > MAX_F_ERR) ++ return NOTIFY_BAD; ++ ++ factor = __ilog2_u32(factor); ++ ++ /* ++ * store timer clock ctrl register so we can restore it in case ++ * of an abort. ++ */ ++ ttccs->scale_clk_ctrl_reg_old = ++ readl_relaxed(ttccs->ttc.base_addr + ++ TTC_CLK_CNTRL_OFFSET); ++ ++ psv = (ttccs->scale_clk_ctrl_reg_old & ++ TTC_CLK_CNTRL_PSV_MASK) >> ++ TTC_CLK_CNTRL_PSV_SHIFT; ++ if (ndata->new_rate < ndata->old_rate) ++ psv -= factor; ++ else ++ psv += factor; ++ ++ /* prescaler within legal range? */ ++ if (psv & ~(TTC_CLK_CNTRL_PSV_MASK >> TTC_CLK_CNTRL_PSV_SHIFT)) ++ return NOTIFY_BAD; ++ ++ ttccs->scale_clk_ctrl_reg_new = ttccs->scale_clk_ctrl_reg_old & ++ ~TTC_CLK_CNTRL_PSV_MASK; ++ ttccs->scale_clk_ctrl_reg_new |= psv << TTC_CLK_CNTRL_PSV_SHIFT; ++ ++ ++ /* scale down: adjust divider in post-change notification */ ++ if (ndata->new_rate < ndata->old_rate) ++ return NOTIFY_DONE; ++ ++ /* scale up: adjust divider now - before frequency change */ ++ writel_relaxed(ttccs->scale_clk_ctrl_reg_new, ++ ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); ++ break; ++ } ++ case POST_RATE_CHANGE: ++ /* scale up: pre-change notification did the adjustment */ ++ if (ndata->new_rate > ndata->old_rate) ++ return NOTIFY_OK; ++ ++ /* scale down: adjust divider now - after frequency change */ ++ writel_relaxed(ttccs->scale_clk_ctrl_reg_new, ++ ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); ++ break; ++ ++ case ABORT_RATE_CHANGE: ++ /* we have to undo the adjustment in case we scale up */ ++ if (ndata->new_rate < ndata->old_rate) ++ return NOTIFY_OK; ++ ++ /* restore original register value */ ++ writel_relaxed(ttccs->scale_clk_ctrl_reg_old, ++ ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); ++ /* fall through */ ++ default: ++ return NOTIFY_DONE; ++ } ++ ++ return NOTIFY_DONE; ++} ++ ++static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, ++ u32 timer_width) ++{ ++ struct ttc_timer_clocksource *ttccs; ++ int err; ++ ++ ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); ++ if (!ttccs) ++ return -ENOMEM; ++ ++ ttccs->ttc.clk = clk; ++ ++ err = clk_prepare_enable(ttccs->ttc.clk); ++ if (err) { ++ kfree(ttccs); ++ return err; ++ } ++ ++ ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); ++ ++ ttccs->ttc.clk_rate_change_nb.notifier_call = ++ ttc_rate_change_clocksource_cb; ++ ttccs->ttc.clk_rate_change_nb.next = NULL; ++ ++ err = clk_notifier_register(ttccs->ttc.clk, ++ &ttccs->ttc.clk_rate_change_nb); ++ if (err) ++ pr_warn("Unable to register clock notifier.\n"); ++ ++ ttccs->ttc.base_addr = base; ++ ttccs->cs.name = "ttc_clocksource"; ++ ttccs->cs.rating = 200; ++ ttccs->cs.read = __ttc_clocksource_read; ++ ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width); ++ ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; ++ ++ /* ++ * Setup the clock source counter to be an incrementing counter ++ * with no interrupt and it rolls over at 0xFFFF. Pre-scale ++ * it by 32 also. Let it start running now. ++ */ ++ writel_relaxed(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); ++ writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, ++ ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); ++ writel_relaxed(CNT_CNTRL_RESET, ++ ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); ++ ++ err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); ++ if (err) { ++ kfree(ttccs); ++ return err; ++ } ++ ++ ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; ++ sched_clock_register(ttc_sched_clock_read, timer_width, ++ ttccs->ttc.freq / PRESCALE); ++ ++ return 0; ++} ++ ++static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, ++ unsigned long event, void *data) ++{ ++ struct clk_notifier_data *ndata = data; ++ struct ttc_timer *ttc = to_ttc_timer(nb); ++ struct ttc_timer_clockevent *ttcce = container_of(ttc, ++ struct ttc_timer_clockevent, ttc); ++ ++ switch (event) { ++ case POST_RATE_CHANGE: ++ /* update cached frequency */ ++ ttc->freq = ndata->new_rate; ++ ++ clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE); ++ ++ /* fall through */ ++ case PRE_RATE_CHANGE: ++ case ABORT_RATE_CHANGE: ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ ++static int __init ttc_setup_clockevent(struct clk *clk, ++ void __iomem *base, u32 irq) ++{ ++ struct ttc_timer_clockevent *ttcce; ++ int err; ++ ++ ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); ++ if (!ttcce) ++ return -ENOMEM; ++ ++ ttcce->ttc.clk = clk; ++ ++ err = clk_prepare_enable(ttcce->ttc.clk); ++ if (err) ++ goto out_kfree; ++ ++ ttcce->ttc.clk_rate_change_nb.notifier_call = ++ ttc_rate_change_clockevent_cb; ++ ttcce->ttc.clk_rate_change_nb.next = NULL; ++ ++ err = clk_notifier_register(ttcce->ttc.clk, ++ &ttcce->ttc.clk_rate_change_nb); ++ if (err) { ++ pr_warn("Unable to register clock notifier.\n"); ++ goto out_kfree; ++ } ++ ++ ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); ++ ++ ttcce->ttc.base_addr = base; ++ ttcce->ce.name = "ttc_clockevent"; ++ ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; ++ ttcce->ce.set_next_event = ttc_set_next_event; ++ ttcce->ce.set_state_shutdown = ttc_shutdown; ++ ttcce->ce.set_state_periodic = ttc_set_periodic; ++ ttcce->ce.set_state_oneshot = ttc_shutdown; ++ ttcce->ce.tick_resume = ttc_resume; ++ ttcce->ce.rating = 200; ++ ttcce->ce.irq = irq; ++ ttcce->ce.cpumask = cpu_possible_mask; ++ ++ /* ++ * Setup the clock event timer to be an interval timer which ++ * is prescaled by 32 using the interval interrupt. Leave it ++ * disabled for now. ++ */ ++ writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); ++ writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, ++ ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); ++ writel_relaxed(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); ++ ++ err = request_irq(irq, ttc_clock_event_interrupt, ++ IRQF_TIMER, ttcce->ce.name, ttcce); ++ if (err) ++ goto out_kfree; ++ ++ clockevents_config_and_register(&ttcce->ce, ++ ttcce->ttc.freq / PRESCALE, 1, 0xfffe); ++ ++ return 0; ++ ++out_kfree: ++ kfree(ttcce); ++ return err; ++} ++ ++static int __init ttc_timer_probe(struct platform_device *pdev) ++{ ++ unsigned int irq; ++ void __iomem *timer_baseaddr; ++ struct clk *clk_cs, *clk_ce; ++ static int initialized; ++ int clksel, ret; ++ u32 timer_width = 16; ++ struct device_node *timer = pdev->dev.of_node; ++ ++ if (initialized) ++ return 0; ++ ++ initialized = 1; ++ ++ /* ++ * Get the 1st Triple Timer Counter (TTC) block from the device tree ++ * and use it. Note that the event timer uses the interrupt and it's the ++ * 2nd TTC hence the irq_of_parse_and_map(,1) ++ */ ++ timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL); ++ if (IS_ERR(timer_baseaddr)) { ++ pr_err("ERROR: invalid timer base address\n"); ++ return PTR_ERR(timer_baseaddr); ++ } ++ ++ irq = irq_of_parse_and_map(timer, 1); ++ if (irq <= 0) { ++ pr_err("ERROR: invalid interrupt number\n"); ++ return -EINVAL; ++ } ++ ++ of_property_read_u32(timer, "timer-width", &timer_width); ++ ++ clksel = readl_relaxed(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); ++ clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); ++ clk_cs = of_clk_get(timer, clksel); ++ if (IS_ERR(clk_cs)) { ++ pr_err("ERROR: timer input clock not found\n"); ++ return PTR_ERR(clk_cs); ++ } ++ ++ clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); ++ clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); ++ clk_ce = of_clk_get(timer, clksel); ++ if (IS_ERR(clk_ce)) { ++ pr_err("ERROR: timer input clock not found\n"); ++ ret = PTR_ERR(clk_ce); ++ goto put_clk_cs; ++ } ++ ++ ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); ++ if (ret) ++ goto put_clk_ce; ++ ++ ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); ++ if (ret) ++ goto put_clk_ce; ++ ++ pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); ++ ++ return 0; ++ ++put_clk_ce: ++ clk_put(clk_ce); ++put_clk_cs: ++ clk_put(clk_cs); ++ return ret; ++} ++ ++static const struct of_device_id ttc_timer_of_match[] = { ++ {.compatible = "cdns,ttc"}, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, ttc_timer_of_match); ++ ++static struct platform_driver ttc_timer_driver = { ++ .driver = { ++ .name = "cdns_ttc_timer", ++ .of_match_table = ttc_timer_of_match, ++ }, ++}; ++builtin_platform_driver_probe(ttc_timer_driver, ttc_timer_probe); +diff --git a/drivers/clocksource/timer-efm32.c b/drivers/clocksource/timer-efm32.c +new file mode 100644 +index 0000000000000..257e810ec1ad1 +--- /dev/null ++++ b/drivers/clocksource/timer-efm32.c +@@ -0,0 +1,287 @@ ++/* ++ * Copyright (C) 2013 Pengutronix ++ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> ++ * ++ * 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. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include <linux/kernel.h> ++#include <linux/clocksource.h> ++#include <linux/clockchips.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/clk.h> ++ ++#define TIMERn_CTRL 0x00 ++#define TIMERn_CTRL_PRESC(val) (((val) & 0xf) << 24) ++#define TIMERn_CTRL_PRESC_1024 TIMERn_CTRL_PRESC(10) ++#define TIMERn_CTRL_CLKSEL(val) (((val) & 0x3) << 16) ++#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK TIMERn_CTRL_CLKSEL(0) ++#define TIMERn_CTRL_OSMEN 0x00000010 ++#define TIMERn_CTRL_MODE(val) (((val) & 0x3) << 0) ++#define TIMERn_CTRL_MODE_UP TIMERn_CTRL_MODE(0) ++#define TIMERn_CTRL_MODE_DOWN TIMERn_CTRL_MODE(1) ++ ++#define TIMERn_CMD 0x04 ++#define TIMERn_CMD_START 0x00000001 ++#define TIMERn_CMD_STOP 0x00000002 ++ ++#define TIMERn_IEN 0x0c ++#define TIMERn_IF 0x10 ++#define TIMERn_IFS 0x14 ++#define TIMERn_IFC 0x18 ++#define TIMERn_IRQ_UF 0x00000002 ++ ++#define TIMERn_TOP 0x1c ++#define TIMERn_CNT 0x24 ++ ++struct efm32_clock_event_ddata { ++ struct clock_event_device evtdev; ++ void __iomem *base; ++ unsigned periodic_top; ++}; ++ ++static int efm32_clock_event_shutdown(struct clock_event_device *evtdev) ++{ ++ struct efm32_clock_event_ddata *ddata = ++ container_of(evtdev, struct efm32_clock_event_ddata, evtdev); ++ ++ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); ++ return 0; ++} ++ ++static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev) ++{ ++ struct efm32_clock_event_ddata *ddata = ++ container_of(evtdev, struct efm32_clock_event_ddata, evtdev); ++ ++ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); ++ writel_relaxed(TIMERn_CTRL_PRESC_1024 | ++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | ++ TIMERn_CTRL_OSMEN | ++ TIMERn_CTRL_MODE_DOWN, ++ ddata->base + TIMERn_CTRL); ++ return 0; ++} ++ ++static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev) ++{ ++ struct efm32_clock_event_ddata *ddata = ++ container_of(evtdev, struct efm32_clock_event_ddata, evtdev); ++ ++ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); ++ writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP); ++ writel_relaxed(TIMERn_CTRL_PRESC_1024 | ++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | ++ TIMERn_CTRL_MODE_DOWN, ++ ddata->base + TIMERn_CTRL); ++ writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); ++ return 0; ++} ++ ++static int efm32_clock_event_set_next_event(unsigned long evt, ++ struct clock_event_device *evtdev) ++{ ++ struct efm32_clock_event_ddata *ddata = ++ container_of(evtdev, struct efm32_clock_event_ddata, evtdev); ++ ++ writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD); ++ writel_relaxed(evt, ddata->base + TIMERn_CNT); ++ writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD); ++ ++ return 0; ++} ++ ++static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id) ++{ ++ struct efm32_clock_event_ddata *ddata = dev_id; ++ ++ writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC); ++ ++ ddata->evtdev.event_handler(&ddata->evtdev); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct efm32_clock_event_ddata clock_event_ddata = { ++ .evtdev = { ++ .name = "efm32 clockevent", ++ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, ++ .set_state_shutdown = efm32_clock_event_shutdown, ++ .set_state_periodic = efm32_clock_event_set_periodic, ++ .set_state_oneshot = efm32_clock_event_set_oneshot, ++ .set_next_event = efm32_clock_event_set_next_event, ++ .rating = 200, ++ }, ++}; ++ ++static struct irqaction efm32_clock_event_irq = { ++ .name = "efm32 clockevent", ++ .flags = IRQF_TIMER, ++ .handler = efm32_clock_event_handler, ++ .dev_id = &clock_event_ddata, ++}; ++ ++static int __init efm32_clocksource_init(struct device_node *np) ++{ ++ struct clk *clk; ++ void __iomem *base; ++ unsigned long rate; ++ int ret; ++ ++ clk = of_clk_get(np, 0); ++ if (IS_ERR(clk)) { ++ ret = PTR_ERR(clk); ++ pr_err("failed to get clock for clocksource (%d)\n", ret); ++ goto err_clk_get; ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ pr_err("failed to enable timer clock for clocksource (%d)\n", ++ ret); ++ goto err_clk_enable; ++ } ++ rate = clk_get_rate(clk); ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ ret = -EADDRNOTAVAIL; ++ pr_err("failed to map registers for clocksource\n"); ++ goto err_iomap; ++ } ++ ++ writel_relaxed(TIMERn_CTRL_PRESC_1024 | ++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK | ++ TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL); ++ writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD); ++ ++ ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer", ++ DIV_ROUND_CLOSEST(rate, 1024), 200, 16, ++ clocksource_mmio_readl_up); ++ if (ret) { ++ pr_err("failed to init clocksource (%d)\n", ret); ++ goto err_clocksource_init; ++ } ++ ++ return 0; ++ ++err_clocksource_init: ++ ++ iounmap(base); ++err_iomap: ++ ++ clk_disable_unprepare(clk); ++err_clk_enable: ++ ++ clk_put(clk); ++err_clk_get: ++ ++ return ret; ++} ++ ++static int __init efm32_clockevent_init(struct device_node *np) ++{ ++ struct clk *clk; ++ void __iomem *base; ++ unsigned long rate; ++ int irq; ++ int ret; ++ ++ clk = of_clk_get(np, 0); ++ if (IS_ERR(clk)) { ++ ret = PTR_ERR(clk); ++ pr_err("failed to get clock for clockevent (%d)\n", ret); ++ goto err_clk_get; ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ pr_err("failed to enable timer clock for clockevent (%d)\n", ++ ret); ++ goto err_clk_enable; ++ } ++ rate = clk_get_rate(clk); ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ ret = -EADDRNOTAVAIL; ++ pr_err("failed to map registers for clockevent\n"); ++ goto err_iomap; ++ } ++ ++ irq = irq_of_parse_and_map(np, 0); ++ if (!irq) { ++ ret = -ENOENT; ++ pr_err("failed to get irq for clockevent\n"); ++ goto err_get_irq; ++ } ++ ++ writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN); ++ ++ clock_event_ddata.base = base; ++ clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ); ++ ++ clockevents_config_and_register(&clock_event_ddata.evtdev, ++ DIV_ROUND_CLOSEST(rate, 1024), ++ 0xf, 0xffff); ++ ++ ret = setup_irq(irq, &efm32_clock_event_irq); ++ if (ret) { ++ pr_err("Failed setup irq\n"); ++ goto err_setup_irq; ++ } ++ ++ return 0; ++ ++err_setup_irq: ++err_get_irq: ++ ++ iounmap(base); ++err_iomap: ++ ++ clk_disable_unprepare(clk); ++err_clk_enable: ++ ++ clk_put(clk); ++err_clk_get: ++ ++ return ret; ++} ++ ++/* ++ * This function asserts that we have exactly one clocksource and one ++ * clock_event_device in the end. ++ */ ++static int __init efm32_timer_init(struct device_node *np) ++{ ++ static int has_clocksource, has_clockevent; ++ int ret = 0; ++ ++ if (!has_clocksource) { ++ ret = efm32_clocksource_init(np); ++ if (!ret) { ++ has_clocksource = 1; ++ return 0; ++ } ++ } ++ ++ if (!has_clockevent) { ++ ret = efm32_clockevent_init(np); ++ if (!ret) { ++ has_clockevent = 1; ++ return 0; ++ } ++ } ++ ++ return ret; ++} ++TIMER_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init); ++TIMER_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init); +diff --git a/drivers/clocksource/timer-fsl-ftm.c b/drivers/clocksource/timer-fsl-ftm.c +new file mode 100644 +index 0000000000000..846d18daf893b +--- /dev/null ++++ b/drivers/clocksource/timer-fsl-ftm.c +@@ -0,0 +1,376 @@ ++/* ++ * Freescale FlexTimer Module (FTM) timer driver. ++ * ++ * Copyright 2014 Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/clockchips.h> ++#include <linux/clocksource.h> ++#include <linux/err.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/sched_clock.h> ++#include <linux/slab.h> ++ ++#define FTM_SC 0x00 ++#define FTM_SC_CLK_SHIFT 3 ++#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT) ++#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT) ++#define FTM_SC_PS_MASK 0x7 ++#define FTM_SC_TOIE BIT(6) ++#define FTM_SC_TOF BIT(7) ++ ++#define FTM_CNT 0x04 ++#define FTM_MOD 0x08 ++#define FTM_CNTIN 0x4C ++ ++#define FTM_PS_MAX 7 ++ ++struct ftm_clock_device { ++ void __iomem *clksrc_base; ++ void __iomem *clkevt_base; ++ unsigned long periodic_cyc; ++ unsigned long ps; ++ bool big_endian; ++}; ++ ++static struct ftm_clock_device *priv; ++ ++static inline u32 ftm_readl(void __iomem *addr) ++{ ++ if (priv->big_endian) ++ return ioread32be(addr); ++ else ++ return ioread32(addr); ++} ++ ++static inline void ftm_writel(u32 val, void __iomem *addr) ++{ ++ if (priv->big_endian) ++ iowrite32be(val, addr); ++ else ++ iowrite32(val, addr); ++} ++ ++static inline void ftm_counter_enable(void __iomem *base) ++{ ++ u32 val; ++ ++ /* select and enable counter clock source */ ++ val = ftm_readl(base + FTM_SC); ++ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); ++ val |= priv->ps | FTM_SC_CLK(1); ++ ftm_writel(val, base + FTM_SC); ++} ++ ++static inline void ftm_counter_disable(void __iomem *base) ++{ ++ u32 val; ++ ++ /* disable counter clock source */ ++ val = ftm_readl(base + FTM_SC); ++ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK); ++ ftm_writel(val, base + FTM_SC); ++} ++ ++static inline void ftm_irq_acknowledge(void __iomem *base) ++{ ++ u32 val; ++ ++ val = ftm_readl(base + FTM_SC); ++ val &= ~FTM_SC_TOF; ++ ftm_writel(val, base + FTM_SC); ++} ++ ++static inline void ftm_irq_enable(void __iomem *base) ++{ ++ u32 val; ++ ++ val = ftm_readl(base + FTM_SC); ++ val |= FTM_SC_TOIE; ++ ftm_writel(val, base + FTM_SC); ++} ++ ++static inline void ftm_irq_disable(void __iomem *base) ++{ ++ u32 val; ++ ++ val = ftm_readl(base + FTM_SC); ++ val &= ~FTM_SC_TOIE; ++ ftm_writel(val, base + FTM_SC); ++} ++ ++static inline void ftm_reset_counter(void __iomem *base) ++{ ++ /* ++ * The CNT register contains the FTM counter value. ++ * Reset clears the CNT register. Writing any value to COUNT ++ * updates the counter with its initial value, CNTIN. ++ */ ++ ftm_writel(0x00, base + FTM_CNT); ++} ++ ++static u64 notrace ftm_read_sched_clock(void) ++{ ++ return ftm_readl(priv->clksrc_base + FTM_CNT); ++} ++ ++static int ftm_set_next_event(unsigned long delta, ++ struct clock_event_device *unused) ++{ ++ /* ++ * The CNNIN and MOD are all double buffer registers, writing ++ * to the MOD register latches the value into a buffer. The MOD ++ * register is updated with the value of its write buffer with ++ * the following scenario: ++ * a, the counter source clock is diabled. ++ */ ++ ftm_counter_disable(priv->clkevt_base); ++ ++ /* Force the value of CNTIN to be loaded into the FTM counter */ ++ ftm_reset_counter(priv->clkevt_base); ++ ++ /* ++ * The counter increments until the value of MOD is reached, ++ * at which point the counter is reloaded with the value of CNTIN. ++ * The TOF (the overflow flag) bit is set when the FTM counter ++ * changes from MOD to CNTIN. So we should using the delta - 1. ++ */ ++ ftm_writel(delta - 1, priv->clkevt_base + FTM_MOD); ++ ++ ftm_counter_enable(priv->clkevt_base); ++ ++ ftm_irq_enable(priv->clkevt_base); ++ ++ return 0; ++} ++ ++static int ftm_set_oneshot(struct clock_event_device *evt) ++{ ++ ftm_counter_disable(priv->clkevt_base); ++ return 0; ++} ++ ++static int ftm_set_periodic(struct clock_event_device *evt) ++{ ++ ftm_set_next_event(priv->periodic_cyc, evt); ++ return 0; ++} ++ ++static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = dev_id; ++ ++ ftm_irq_acknowledge(priv->clkevt_base); ++ ++ if (likely(clockevent_state_oneshot(evt))) { ++ ftm_irq_disable(priv->clkevt_base); ++ ftm_counter_disable(priv->clkevt_base); ++ } ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct clock_event_device ftm_clockevent = { ++ .name = "Freescale ftm timer", ++ .features = CLOCK_EVT_FEAT_PERIODIC | ++ CLOCK_EVT_FEAT_ONESHOT, ++ .set_state_periodic = ftm_set_periodic, ++ .set_state_oneshot = ftm_set_oneshot, ++ .set_next_event = ftm_set_next_event, ++ .rating = 300, ++}; ++ ++static struct irqaction ftm_timer_irq = { ++ .name = "Freescale ftm timer", ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = ftm_evt_interrupt, ++ .dev_id = &ftm_clockevent, ++}; ++ ++static int __init ftm_clockevent_init(unsigned long freq, int irq) ++{ ++ int err; ++ ++ ftm_writel(0x00, priv->clkevt_base + FTM_CNTIN); ++ ftm_writel(~0u, priv->clkevt_base + FTM_MOD); ++ ++ ftm_reset_counter(priv->clkevt_base); ++ ++ err = setup_irq(irq, &ftm_timer_irq); ++ if (err) { ++ pr_err("ftm: setup irq failed: %d\n", err); ++ return err; ++ } ++ ++ ftm_clockevent.cpumask = cpumask_of(0); ++ ftm_clockevent.irq = irq; ++ ++ clockevents_config_and_register(&ftm_clockevent, ++ freq / (1 << priv->ps), ++ 1, 0xffff); ++ ++ ftm_counter_enable(priv->clkevt_base); ++ ++ return 0; ++} ++ ++static int __init ftm_clocksource_init(unsigned long freq) ++{ ++ int err; ++ ++ ftm_writel(0x00, priv->clksrc_base + FTM_CNTIN); ++ ftm_writel(~0u, priv->clksrc_base + FTM_MOD); ++ ++ ftm_reset_counter(priv->clksrc_base); ++ ++ sched_clock_register(ftm_read_sched_clock, 16, freq / (1 << priv->ps)); ++ err = clocksource_mmio_init(priv->clksrc_base + FTM_CNT, "fsl-ftm", ++ freq / (1 << priv->ps), 300, 16, ++ clocksource_mmio_readl_up); ++ if (err) { ++ pr_err("ftm: init clock source mmio failed: %d\n", err); ++ return err; ++ } ++ ++ ftm_counter_enable(priv->clksrc_base); ++ ++ return 0; ++} ++ ++static int __init __ftm_clk_init(struct device_node *np, char *cnt_name, ++ char *ftm_name) ++{ ++ struct clk *clk; ++ int err; ++ ++ clk = of_clk_get_by_name(np, cnt_name); ++ if (IS_ERR(clk)) { ++ pr_err("ftm: Cannot get \"%s\": %ld\n", cnt_name, PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ err = clk_prepare_enable(clk); ++ if (err) { ++ pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n", ++ cnt_name, err); ++ return err; ++ } ++ ++ clk = of_clk_get_by_name(np, ftm_name); ++ if (IS_ERR(clk)) { ++ pr_err("ftm: Cannot get \"%s\": %ld\n", ftm_name, PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ err = clk_prepare_enable(clk); ++ if (err) ++ pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n", ++ ftm_name, err); ++ ++ return clk_get_rate(clk); ++} ++ ++static unsigned long __init ftm_clk_init(struct device_node *np) ++{ ++ long freq; ++ ++ freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt"); ++ if (freq <= 0) ++ return 0; ++ ++ freq = __ftm_clk_init(np, "ftm-src-counter-en", "ftm-src"); ++ if (freq <= 0) ++ return 0; ++ ++ return freq; ++} ++ ++static int __init ftm_calc_closest_round_cyc(unsigned long freq) ++{ ++ priv->ps = 0; ++ ++ /* The counter register is only using the lower 16 bits, and ++ * if the 'freq' value is to big here, then the periodic_cyc ++ * may exceed 0xFFFF. ++ */ ++ do { ++ priv->periodic_cyc = DIV_ROUND_CLOSEST(freq, ++ HZ * (1 << priv->ps++)); ++ } while (priv->periodic_cyc > 0xFFFF); ++ ++ if (priv->ps > FTM_PS_MAX) { ++ pr_err("ftm: the prescaler is %lu > %d\n", ++ priv->ps, FTM_PS_MAX); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int __init ftm_timer_init(struct device_node *np) ++{ ++ unsigned long freq; ++ int ret, irq; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ ret = -ENXIO; ++ priv->clkevt_base = of_iomap(np, 0); ++ if (!priv->clkevt_base) { ++ pr_err("ftm: unable to map event timer registers\n"); ++ goto err_clkevt; ++ } ++ ++ priv->clksrc_base = of_iomap(np, 1); ++ if (!priv->clksrc_base) { ++ pr_err("ftm: unable to map source timer registers\n"); ++ goto err_clksrc; ++ } ++ ++ ret = -EINVAL; ++ irq = irq_of_parse_and_map(np, 0); ++ if (irq <= 0) { ++ pr_err("ftm: unable to get IRQ from DT, %d\n", irq); ++ goto err; ++ } ++ ++ priv->big_endian = of_property_read_bool(np, "big-endian"); ++ ++ freq = ftm_clk_init(np); ++ if (!freq) ++ goto err; ++ ++ ret = ftm_calc_closest_round_cyc(freq); ++ if (ret) ++ goto err; ++ ++ ret = ftm_clocksource_init(freq); ++ if (ret) ++ goto err; ++ ++ ret = ftm_clockevent_init(freq, irq); ++ if (ret) ++ goto err; ++ ++ return 0; ++ ++err: ++ iounmap(priv->clksrc_base); ++err_clksrc: ++ iounmap(priv->clkevt_base); ++err_clkevt: ++ kfree(priv); ++ return ret; ++} ++TIMER_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init); +diff --git a/drivers/clocksource/timer-lpc32xx.c b/drivers/clocksource/timer-lpc32xx.c +new file mode 100644 +index 0000000000000..d51a62a79ef76 +--- /dev/null ++++ b/drivers/clocksource/timer-lpc32xx.c +@@ -0,0 +1,314 @@ ++/* ++ * Clocksource driver for NXP LPC32xx/18xx/43xx timer ++ * ++ * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com> ++ * ++ * Based on: ++ * time-efm32 Copyright (C) 2013 Pengutronix ++ * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ * ++ */ ++ ++#define pr_fmt(fmt) "%s: " fmt, __func__ ++ ++#include <linux/clk.h> ++#include <linux/clockchips.h> ++#include <linux/clocksource.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/kernel.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/sched_clock.h> ++ ++#define LPC32XX_TIMER_IR 0x000 ++#define LPC32XX_TIMER_IR_MR0INT BIT(0) ++#define LPC32XX_TIMER_TCR 0x004 ++#define LPC32XX_TIMER_TCR_CEN BIT(0) ++#define LPC32XX_TIMER_TCR_CRST BIT(1) ++#define LPC32XX_TIMER_TC 0x008 ++#define LPC32XX_TIMER_PR 0x00c ++#define LPC32XX_TIMER_MCR 0x014 ++#define LPC32XX_TIMER_MCR_MR0I BIT(0) ++#define LPC32XX_TIMER_MCR_MR0R BIT(1) ++#define LPC32XX_TIMER_MCR_MR0S BIT(2) ++#define LPC32XX_TIMER_MR0 0x018 ++#define LPC32XX_TIMER_CTCR 0x070 ++ ++struct lpc32xx_clock_event_ddata { ++ struct clock_event_device evtdev; ++ void __iomem *base; ++ u32 ticks_per_jiffy; ++}; ++ ++/* Needed for the sched clock */ ++static void __iomem *clocksource_timer_counter; ++ ++static u64 notrace lpc32xx_read_sched_clock(void) ++{ ++ return readl(clocksource_timer_counter); ++} ++ ++static unsigned long lpc32xx_delay_timer_read(void) ++{ ++ return readl(clocksource_timer_counter); ++} ++ ++static struct delay_timer lpc32xx_delay_timer = { ++ .read_current_timer = lpc32xx_delay_timer_read, ++}; ++ ++static int lpc32xx_clkevt_next_event(unsigned long delta, ++ struct clock_event_device *evtdev) ++{ ++ struct lpc32xx_clock_event_ddata *ddata = ++ container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); ++ ++ /* ++ * Place timer in reset and program the delta in the match ++ * channel 0 (MR0). When the timer counter matches the value ++ * in MR0 register the match will trigger an interrupt. ++ * After setup the timer is released from reset and enabled. ++ */ ++ writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR); ++ writel_relaxed(delta, ddata->base + LPC32XX_TIMER_MR0); ++ writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR); ++ ++ return 0; ++} ++ ++static int lpc32xx_clkevt_shutdown(struct clock_event_device *evtdev) ++{ ++ struct lpc32xx_clock_event_ddata *ddata = ++ container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); ++ ++ /* Disable the timer */ ++ writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR); ++ ++ return 0; ++} ++ ++static int lpc32xx_clkevt_oneshot(struct clock_event_device *evtdev) ++{ ++ struct lpc32xx_clock_event_ddata *ddata = ++ container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); ++ ++ /* ++ * When using oneshot, we must also disable the timer ++ * to wait for the first call to set_next_event(). ++ */ ++ writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR); ++ ++ /* Enable interrupt, reset on match and stop on match (MCR). */ ++ writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R | ++ LPC32XX_TIMER_MCR_MR0S, ddata->base + LPC32XX_TIMER_MCR); ++ return 0; ++} ++ ++static int lpc32xx_clkevt_periodic(struct clock_event_device *evtdev) ++{ ++ struct lpc32xx_clock_event_ddata *ddata = ++ container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev); ++ ++ /* Enable interrupt and reset on match. */ ++ writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R, ++ ddata->base + LPC32XX_TIMER_MCR); ++ ++ /* ++ * Place timer in reset and program the delta in the match ++ * channel 0 (MR0). ++ */ ++ writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR); ++ writel_relaxed(ddata->ticks_per_jiffy, ddata->base + LPC32XX_TIMER_MR0); ++ writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR); ++ ++ return 0; ++} ++ ++static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id) ++{ ++ struct lpc32xx_clock_event_ddata *ddata = dev_id; ++ ++ /* Clear match on channel 0 */ ++ writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base + LPC32XX_TIMER_IR); ++ ++ ddata->evtdev.event_handler(&ddata->evtdev); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = { ++ .evtdev = { ++ .name = "lpc3220 clockevent", ++ .features = CLOCK_EVT_FEAT_ONESHOT | ++ CLOCK_EVT_FEAT_PERIODIC, ++ .rating = 300, ++ .set_next_event = lpc32xx_clkevt_next_event, ++ .set_state_shutdown = lpc32xx_clkevt_shutdown, ++ .set_state_oneshot = lpc32xx_clkevt_oneshot, ++ .set_state_periodic = lpc32xx_clkevt_periodic, ++ }, ++}; ++ ++static int __init lpc32xx_clocksource_init(struct device_node *np) ++{ ++ void __iomem *base; ++ unsigned long rate; ++ struct clk *clk; ++ int ret; ++ ++ clk = of_clk_get_by_name(np, "timerclk"); ++ if (IS_ERR(clk)) { ++ pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ pr_err("clock enable failed (%d)\n", ret); ++ goto err_clk_enable; ++ } ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ pr_err("unable to map registers\n"); ++ ret = -EADDRNOTAVAIL; ++ goto err_iomap; ++ } ++ ++ /* ++ * Disable and reset timer then set it to free running timer ++ * mode (CTCR) with no prescaler (PR) or match operations (MCR). ++ * After setup the timer is released from reset and enabled. ++ */ ++ writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR); ++ writel_relaxed(0, base + LPC32XX_TIMER_PR); ++ writel_relaxed(0, base + LPC32XX_TIMER_MCR); ++ writel_relaxed(0, base + LPC32XX_TIMER_CTCR); ++ writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR); ++ ++ rate = clk_get_rate(clk); ++ ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer", ++ rate, 300, 32, clocksource_mmio_readl_up); ++ if (ret) { ++ pr_err("failed to init clocksource (%d)\n", ret); ++ goto err_clocksource_init; ++ } ++ ++ clocksource_timer_counter = base + LPC32XX_TIMER_TC; ++ lpc32xx_delay_timer.freq = rate; ++ register_current_timer_delay(&lpc32xx_delay_timer); ++ sched_clock_register(lpc32xx_read_sched_clock, 32, rate); ++ ++ return 0; ++ ++err_clocksource_init: ++ iounmap(base); ++err_iomap: ++ clk_disable_unprepare(clk); ++err_clk_enable: ++ clk_put(clk); ++ return ret; ++} ++ ++static int __init lpc32xx_clockevent_init(struct device_node *np) ++{ ++ void __iomem *base; ++ unsigned long rate; ++ struct clk *clk; ++ int ret, irq; ++ ++ clk = of_clk_get_by_name(np, "timerclk"); ++ if (IS_ERR(clk)) { ++ pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ pr_err("clock enable failed (%d)\n", ret); ++ goto err_clk_enable; ++ } ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ pr_err("unable to map registers\n"); ++ ret = -EADDRNOTAVAIL; ++ goto err_iomap; ++ } ++ ++ irq = irq_of_parse_and_map(np, 0); ++ if (!irq) { ++ pr_err("get irq failed\n"); ++ ret = -ENOENT; ++ goto err_irq; ++ } ++ ++ /* ++ * Disable timer and clear any pending interrupt (IR) on match ++ * channel 0 (MR0). Clear the prescaler as it's not used. ++ */ ++ writel_relaxed(0, base + LPC32XX_TIMER_TCR); ++ writel_relaxed(0, base + LPC32XX_TIMER_PR); ++ writel_relaxed(0, base + LPC32XX_TIMER_CTCR); ++ writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR); ++ ++ rate = clk_get_rate(clk); ++ lpc32xx_clk_event_ddata.base = base; ++ lpc32xx_clk_event_ddata.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); ++ clockevents_config_and_register(&lpc32xx_clk_event_ddata.evtdev, ++ rate, 1, -1); ++ ++ ret = request_irq(irq, lpc32xx_clock_event_handler, ++ IRQF_TIMER | IRQF_IRQPOLL, "lpc3220 clockevent", ++ &lpc32xx_clk_event_ddata); ++ if (ret) { ++ pr_err("request irq failed\n"); ++ goto err_irq; ++ } ++ ++ return 0; ++ ++err_irq: ++ iounmap(base); ++err_iomap: ++ clk_disable_unprepare(clk); ++err_clk_enable: ++ clk_put(clk); ++ return ret; ++} ++ ++/* ++ * This function asserts that we have exactly one clocksource and one ++ * clock_event_device in the end. ++ */ ++static int __init lpc32xx_timer_init(struct device_node *np) ++{ ++ static int has_clocksource, has_clockevent; ++ int ret = 0; ++ ++ if (!has_clocksource) { ++ ret = lpc32xx_clocksource_init(np); ++ if (!ret) { ++ has_clocksource = 1; ++ return 0; ++ } ++ } ++ ++ if (!has_clockevent) { ++ ret = lpc32xx_clockevent_init(np); ++ if (!ret) { ++ has_clockevent = 1; ++ return 0; ++ } ++ } ++ ++ return ret; ++} ++TIMER_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init); +diff --git a/drivers/clocksource/timer-orion.c b/drivers/clocksource/timer-orion.c +new file mode 100644 +index 0000000000000..12202067fe4b8 +--- /dev/null ++++ b/drivers/clocksource/timer-orion.c +@@ -0,0 +1,192 @@ ++/* ++ * Marvell Orion SoC timer handling. ++ * ++ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ * ++ * Timer 0 is used as free-running clocksource, while timer 1 is ++ * used as clock_event_device. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/bitops.h> ++#include <linux/clk.h> ++#include <linux/clockchips.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/spinlock.h> ++#include <linux/sched_clock.h> ++ ++#define TIMER_CTRL 0x00 ++#define TIMER0_EN BIT(0) ++#define TIMER0_RELOAD_EN BIT(1) ++#define TIMER1_EN BIT(2) ++#define TIMER1_RELOAD_EN BIT(3) ++#define TIMER0_RELOAD 0x10 ++#define TIMER0_VAL 0x14 ++#define TIMER1_RELOAD 0x18 ++#define TIMER1_VAL 0x1c ++ ++#define ORION_ONESHOT_MIN 1 ++#define ORION_ONESHOT_MAX 0xfffffffe ++ ++static void __iomem *timer_base; ++ ++static unsigned long notrace orion_read_timer(void) ++{ ++ return ~readl(timer_base + TIMER0_VAL); ++} ++ ++static struct delay_timer orion_delay_timer = { ++ .read_current_timer = orion_read_timer, ++}; ++ ++static void orion_delay_timer_init(unsigned long rate) ++{ ++ orion_delay_timer.freq = rate; ++ register_current_timer_delay(&orion_delay_timer); ++} ++ ++/* ++ * Free-running clocksource handling. ++ */ ++static u64 notrace orion_read_sched_clock(void) ++{ ++ return ~readl(timer_base + TIMER0_VAL); ++} ++ ++/* ++ * Clockevent handling. ++ */ ++static u32 ticks_per_jiffy; ++ ++static int orion_clkevt_next_event(unsigned long delta, ++ struct clock_event_device *dev) ++{ ++ /* setup and enable one-shot timer */ ++ writel(delta, timer_base + TIMER1_VAL); ++ atomic_io_modify(timer_base + TIMER_CTRL, ++ TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN); ++ ++ return 0; ++} ++ ++static int orion_clkevt_shutdown(struct clock_event_device *dev) ++{ ++ /* disable timer */ ++ atomic_io_modify(timer_base + TIMER_CTRL, ++ TIMER1_RELOAD_EN | TIMER1_EN, 0); ++ return 0; ++} ++ ++static int orion_clkevt_set_periodic(struct clock_event_device *dev) ++{ ++ /* setup and enable periodic timer at 1/HZ intervals */ ++ writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD); ++ writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL); ++ atomic_io_modify(timer_base + TIMER_CTRL, ++ TIMER1_RELOAD_EN | TIMER1_EN, ++ TIMER1_RELOAD_EN | TIMER1_EN); ++ return 0; ++} ++ ++static struct clock_event_device orion_clkevt = { ++ .name = "orion_event", ++ .features = CLOCK_EVT_FEAT_ONESHOT | ++ CLOCK_EVT_FEAT_PERIODIC, ++ .shift = 32, ++ .rating = 300, ++ .set_next_event = orion_clkevt_next_event, ++ .set_state_shutdown = orion_clkevt_shutdown, ++ .set_state_periodic = orion_clkevt_set_periodic, ++ .set_state_oneshot = orion_clkevt_shutdown, ++ .tick_resume = orion_clkevt_shutdown, ++}; ++ ++static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id) ++{ ++ orion_clkevt.event_handler(&orion_clkevt); ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction orion_clkevt_irq = { ++ .name = "orion_event", ++ .flags = IRQF_TIMER, ++ .handler = orion_clkevt_irq_handler, ++}; ++ ++static int __init orion_timer_init(struct device_node *np) ++{ ++ unsigned long rate; ++ struct clk *clk; ++ int irq, ret; ++ ++ /* timer registers are shared with watchdog timer */ ++ timer_base = of_iomap(np, 0); ++ if (!timer_base) { ++ pr_err("%s: unable to map resource\n", np->name); ++ return -ENXIO; ++ } ++ ++ clk = of_clk_get(np, 0); ++ if (IS_ERR(clk)) { ++ pr_err("%s: unable to get clk\n", np->name); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ pr_err("Failed to prepare clock\n"); ++ return ret; ++ } ++ ++ /* we are only interested in timer1 irq */ ++ irq = irq_of_parse_and_map(np, 1); ++ if (irq <= 0) { ++ pr_err("%s: unable to parse timer1 irq\n", np->name); ++ return -EINVAL; ++ } ++ ++ rate = clk_get_rate(clk); ++ ++ /* setup timer0 as free-running clocksource */ ++ writel(~0, timer_base + TIMER0_VAL); ++ writel(~0, timer_base + TIMER0_RELOAD); ++ atomic_io_modify(timer_base + TIMER_CTRL, ++ TIMER0_RELOAD_EN | TIMER0_EN, ++ TIMER0_RELOAD_EN | TIMER0_EN); ++ ++ ret = clocksource_mmio_init(timer_base + TIMER0_VAL, ++ "orion_clocksource", rate, 300, 32, ++ clocksource_mmio_readl_down); ++ if (ret) { ++ pr_err("Failed to initialize mmio timer\n"); ++ return ret; ++ } ++ ++ sched_clock_register(orion_read_sched_clock, 32, rate); ++ ++ /* setup timer1 as clockevent timer */ ++ ret = setup_irq(irq, &orion_clkevt_irq); ++ if (ret) { ++ pr_err("%s: unable to setup irq\n", np->name); ++ return ret; ++ } ++ ++ ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; ++ orion_clkevt.cpumask = cpumask_of(0); ++ orion_clkevt.irq = irq; ++ clockevents_config_and_register(&orion_clkevt, rate, ++ ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); ++ ++ ++ orion_delay_timer_init(rate); ++ ++ return 0; ++} ++TIMER_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); +diff --git a/drivers/clocksource/timer-owl.c b/drivers/clocksource/timer-owl.c +new file mode 100644 +index 0000000000000..ea00a5e8f95d2 +--- /dev/null ++++ b/drivers/clocksource/timer-owl.c +@@ -0,0 +1,173 @@ ++/* ++ * Actions Semi Owl timer ++ * ++ * Copyright 2012 Actions Semi Inc. ++ * Author: Actions Semi, Inc. ++ * ++ * Copyright (c) 2017 SUSE Linux GmbH ++ * Author: Andreas Färber ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/clockchips.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/irqreturn.h> ++#include <linux/sched_clock.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++ ++#define OWL_Tx_CTL 0x0 ++#define OWL_Tx_CMP 0x4 ++#define OWL_Tx_VAL 0x8 ++ ++#define OWL_Tx_CTL_PD BIT(0) ++#define OWL_Tx_CTL_INTEN BIT(1) ++#define OWL_Tx_CTL_EN BIT(2) ++ ++static void __iomem *owl_timer_base; ++static void __iomem *owl_clksrc_base; ++static void __iomem *owl_clkevt_base; ++ ++static inline void owl_timer_reset(void __iomem *base) ++{ ++ writel(0, base + OWL_Tx_CTL); ++ writel(0, base + OWL_Tx_VAL); ++ writel(0, base + OWL_Tx_CMP); ++} ++ ++static inline void owl_timer_set_enabled(void __iomem *base, bool enabled) ++{ ++ u32 ctl = readl(base + OWL_Tx_CTL); ++ ++ /* PD bit is cleared when set */ ++ ctl &= ~OWL_Tx_CTL_PD; ++ ++ if (enabled) ++ ctl |= OWL_Tx_CTL_EN; ++ else ++ ctl &= ~OWL_Tx_CTL_EN; ++ ++ writel(ctl, base + OWL_Tx_CTL); ++} ++ ++static u64 notrace owl_timer_sched_read(void) ++{ ++ return (u64)readl(owl_clksrc_base + OWL_Tx_VAL); ++} ++ ++static int owl_timer_set_state_shutdown(struct clock_event_device *evt) ++{ ++ owl_timer_set_enabled(owl_clkevt_base, false); ++ ++ return 0; ++} ++ ++static int owl_timer_set_state_oneshot(struct clock_event_device *evt) ++{ ++ owl_timer_reset(owl_clkevt_base); ++ ++ return 0; ++} ++ ++static int owl_timer_tick_resume(struct clock_event_device *evt) ++{ ++ return 0; ++} ++ ++static int owl_timer_set_next_event(unsigned long evt, ++ struct clock_event_device *ev) ++{ ++ void __iomem *base = owl_clkevt_base; ++ ++ owl_timer_set_enabled(base, false); ++ writel(OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL); ++ writel(0, base + OWL_Tx_VAL); ++ writel(evt, base + OWL_Tx_CMP); ++ owl_timer_set_enabled(base, true); ++ ++ return 0; ++} ++ ++static struct clock_event_device owl_clockevent = { ++ .name = "owl_tick", ++ .rating = 200, ++ .features = CLOCK_EVT_FEAT_ONESHOT | ++ CLOCK_EVT_FEAT_DYNIRQ, ++ .set_state_shutdown = owl_timer_set_state_shutdown, ++ .set_state_oneshot = owl_timer_set_state_oneshot, ++ .tick_resume = owl_timer_tick_resume, ++ .set_next_event = owl_timer_set_next_event, ++}; ++ ++static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = (struct clock_event_device *)dev_id; ++ ++ writel(OWL_Tx_CTL_PD, owl_clkevt_base + OWL_Tx_CTL); ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static int __init owl_timer_init(struct device_node *node) ++{ ++ struct clk *clk; ++ unsigned long rate; ++ int timer1_irq, ret; ++ ++ owl_timer_base = of_io_request_and_map(node, 0, "owl-timer"); ++ if (IS_ERR(owl_timer_base)) { ++ pr_err("Can't map timer registers\n"); ++ return PTR_ERR(owl_timer_base); ++ } ++ ++ owl_clksrc_base = owl_timer_base + 0x08; ++ owl_clkevt_base = owl_timer_base + 0x14; ++ ++ timer1_irq = of_irq_get_byname(node, "timer1"); ++ if (timer1_irq <= 0) { ++ pr_err("Can't parse timer1 IRQ\n"); ++ return -EINVAL; ++ } ++ ++ clk = of_clk_get(node, 0); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ rate = clk_get_rate(clk); ++ ++ owl_timer_reset(owl_clksrc_base); ++ owl_timer_set_enabled(owl_clksrc_base, true); ++ ++ sched_clock_register(owl_timer_sched_read, 32, rate); ++ clocksource_mmio_init(owl_clksrc_base + OWL_Tx_VAL, node->name, ++ rate, 200, 32, clocksource_mmio_readl_up); ++ ++ owl_timer_reset(owl_clkevt_base); ++ ++ ret = request_irq(timer1_irq, owl_timer1_interrupt, IRQF_TIMER, ++ "owl-timer", &owl_clockevent); ++ if (ret) { ++ pr_err("failed to request irq %d\n", timer1_irq); ++ return ret; ++ } ++ ++ owl_clockevent.cpumask = cpumask_of(0); ++ owl_clockevent.irq = timer1_irq; ++ ++ clockevents_config_and_register(&owl_clockevent, rate, ++ 0xf, 0xffffffff); ++ ++ return 0; ++} ++TIMER_OF_DECLARE(owl_s500, "actions,s500-timer", owl_timer_init); ++TIMER_OF_DECLARE(owl_s700, "actions,s700-timer", owl_timer_init); ++TIMER_OF_DECLARE(owl_s900, "actions,s900-timer", owl_timer_init); +diff --git a/drivers/clocksource/timer-pistachio.c b/drivers/clocksource/timer-pistachio.c +new file mode 100644 +index 0000000000000..a2dd85d0c1d75 +--- /dev/null ++++ b/drivers/clocksource/timer-pistachio.c +@@ -0,0 +1,218 @@ ++/* ++ * Pistachio clocksource based on general-purpose timers ++ * ++ * Copyright (C) 2015 Imagination Technologies ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ */ ++ ++#define pr_fmt(fmt) "%s: " fmt, __func__ ++ ++#include <linux/clk.h> ++#include <linux/clocksource.h> ++#include <linux/clockchips.h> ++#include <linux/delay.h> ++#include <linux/err.h> ++#include <linux/init.h> ++#include <linux/spinlock.h> ++#include <linux/mfd/syscon.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/platform_device.h> ++#include <linux/regmap.h> ++#include <linux/sched_clock.h> ++#include <linux/time.h> ++ ++/* Top level reg */ ++#define CR_TIMER_CTRL_CFG 0x00 ++#define TIMER_ME_GLOBAL BIT(0) ++#define CR_TIMER_REV 0x10 ++ ++/* Timer specific registers */ ++#define TIMER_CFG 0x20 ++#define TIMER_ME_LOCAL BIT(0) ++#define TIMER_RELOAD_VALUE 0x24 ++#define TIMER_CURRENT_VALUE 0x28 ++#define TIMER_CURRENT_OVERFLOW_VALUE 0x2C ++#define TIMER_IRQ_STATUS 0x30 ++#define TIMER_IRQ_CLEAR 0x34 ++#define TIMER_IRQ_MASK 0x38 ++ ++#define PERIP_TIMER_CONTROL 0x90 ++ ++/* Timer specific configuration Values */ ++#define RELOAD_VALUE 0xffffffff ++ ++struct pistachio_clocksource { ++ void __iomem *base; ++ raw_spinlock_t lock; ++ struct clocksource cs; ++}; ++ ++static struct pistachio_clocksource pcs_gpt; ++ ++#define to_pistachio_clocksource(cs) \ ++ container_of(cs, struct pistachio_clocksource, cs) ++ ++static inline u32 gpt_readl(void __iomem *base, u32 offset, u32 gpt_id) ++{ ++ return readl(base + 0x20 * gpt_id + offset); ++} ++ ++static inline void gpt_writel(void __iomem *base, u32 value, u32 offset, ++ u32 gpt_id) ++{ ++ writel(value, base + 0x20 * gpt_id + offset); ++} ++ ++static u64 notrace ++pistachio_clocksource_read_cycles(struct clocksource *cs) ++{ ++ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); ++ u32 counter, overflw; ++ unsigned long flags; ++ ++ /* ++ * The counter value is only refreshed after the overflow value is read. ++ * And they must be read in strict order, hence raw spin lock added. ++ */ ++ ++ raw_spin_lock_irqsave(&pcs->lock, flags); ++ overflw = gpt_readl(pcs->base, TIMER_CURRENT_OVERFLOW_VALUE, 0); ++ counter = gpt_readl(pcs->base, TIMER_CURRENT_VALUE, 0); ++ raw_spin_unlock_irqrestore(&pcs->lock, flags); ++ ++ return (u64)~counter; ++} ++ ++static u64 notrace pistachio_read_sched_clock(void) ++{ ++ return pistachio_clocksource_read_cycles(&pcs_gpt.cs); ++} ++ ++static void pistachio_clksrc_set_mode(struct clocksource *cs, int timeridx, ++ int enable) ++{ ++ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); ++ u32 val; ++ ++ val = gpt_readl(pcs->base, TIMER_CFG, timeridx); ++ if (enable) ++ val |= TIMER_ME_LOCAL; ++ else ++ val &= ~TIMER_ME_LOCAL; ++ ++ gpt_writel(pcs->base, val, TIMER_CFG, timeridx); ++} ++ ++static void pistachio_clksrc_enable(struct clocksource *cs, int timeridx) ++{ ++ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); ++ ++ /* Disable GPT local before loading reload value */ ++ pistachio_clksrc_set_mode(cs, timeridx, false); ++ gpt_writel(pcs->base, RELOAD_VALUE, TIMER_RELOAD_VALUE, timeridx); ++ pistachio_clksrc_set_mode(cs, timeridx, true); ++} ++ ++static void pistachio_clksrc_disable(struct clocksource *cs, int timeridx) ++{ ++ /* Disable GPT local */ ++ pistachio_clksrc_set_mode(cs, timeridx, false); ++} ++ ++static int pistachio_clocksource_enable(struct clocksource *cs) ++{ ++ pistachio_clksrc_enable(cs, 0); ++ return 0; ++} ++ ++static void pistachio_clocksource_disable(struct clocksource *cs) ++{ ++ pistachio_clksrc_disable(cs, 0); ++} ++ ++/* Desirable clock source for pistachio platform */ ++static struct pistachio_clocksource pcs_gpt = { ++ .cs = { ++ .name = "gptimer", ++ .rating = 300, ++ .enable = pistachio_clocksource_enable, ++ .disable = pistachio_clocksource_disable, ++ .read = pistachio_clocksource_read_cycles, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS | ++ CLOCK_SOURCE_SUSPEND_NONSTOP, ++ }, ++}; ++ ++static int __init pistachio_clksrc_of_init(struct device_node *node) ++{ ++ struct clk *sys_clk, *fast_clk; ++ struct regmap *periph_regs; ++ unsigned long rate; ++ int ret; ++ ++ pcs_gpt.base = of_iomap(node, 0); ++ if (!pcs_gpt.base) { ++ pr_err("cannot iomap\n"); ++ return -ENXIO; ++ } ++ ++ periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph"); ++ if (IS_ERR(periph_regs)) { ++ pr_err("cannot get peripheral regmap (%ld)\n", ++ PTR_ERR(periph_regs)); ++ return PTR_ERR(periph_regs); ++ } ++ ++ /* Switch to using the fast counter clock */ ++ ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL, ++ 0xf, 0x0); ++ if (ret) ++ return ret; ++ ++ sys_clk = of_clk_get_by_name(node, "sys"); ++ if (IS_ERR(sys_clk)) { ++ pr_err("clock get failed (%ld)\n", PTR_ERR(sys_clk)); ++ return PTR_ERR(sys_clk); ++ } ++ ++ fast_clk = of_clk_get_by_name(node, "fast"); ++ if (IS_ERR(fast_clk)) { ++ pr_err("clock get failed (%lu)\n", PTR_ERR(fast_clk)); ++ return PTR_ERR(fast_clk); ++ } ++ ++ ret = clk_prepare_enable(sys_clk); ++ if (ret < 0) { ++ pr_err("failed to enable clock (%d)\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(fast_clk); ++ if (ret < 0) { ++ pr_err("failed to enable clock (%d)\n", ret); ++ clk_disable_unprepare(sys_clk); ++ return ret; ++ } ++ ++ rate = clk_get_rate(fast_clk); ++ ++ /* Disable irq's for clocksource usage */ ++ gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 0); ++ gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 1); ++ gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 2); ++ gpt_writel(pcs_gpt.base, 0, TIMER_IRQ_MASK, 3); ++ ++ /* Enable timer block */ ++ writel(TIMER_ME_GLOBAL, pcs_gpt.base); ++ ++ raw_spin_lock_init(&pcs_gpt.lock); ++ sched_clock_register(pistachio_read_sched_clock, 32, rate); ++ return clocksource_register_hz(&pcs_gpt.cs, rate); ++} ++TIMER_OF_DECLARE(pistachio_gptimer, "img,pistachio-gptimer", ++ pistachio_clksrc_of_init); +diff --git a/drivers/clocksource/timer-qcom.c b/drivers/clocksource/timer-qcom.c +new file mode 100644 +index 0000000000000..89816f89ff3f4 +--- /dev/null ++++ b/drivers/clocksource/timer-qcom.c +@@ -0,0 +1,258 @@ ++/* ++ * ++ * Copyright (C) 2007 Google, Inc. ++ * Copyright (c) 2009-2012,2014, 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 ++ * may be copied, distributed, and modified under those terms. ++ * ++ * 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/clocksource.h> ++#include <linux/clockchips.h> ++#include <linux/cpu.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/irq.h> ++#include <linux/io.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/sched_clock.h> ++ ++#include <asm/delay.h> ++ ++#define TIMER_MATCH_VAL 0x0000 ++#define TIMER_COUNT_VAL 0x0004 ++#define TIMER_ENABLE 0x0008 ++#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1) ++#define TIMER_ENABLE_EN BIT(0) ++#define TIMER_CLEAR 0x000C ++#define DGT_CLK_CTL 0x10 ++#define DGT_CLK_CTL_DIV_4 0x3 ++#define TIMER_STS_GPT0_CLR_PEND BIT(10) ++ ++#define GPT_HZ 32768 ++ ++static void __iomem *event_base; ++static void __iomem *sts_base; ++ ++static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = dev_id; ++ /* Stop the timer tick */ ++ if (clockevent_state_oneshot(evt)) { ++ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); ++ ctrl &= ~TIMER_ENABLE_EN; ++ writel_relaxed(ctrl, event_base + TIMER_ENABLE); ++ } ++ evt->event_handler(evt); ++ return IRQ_HANDLED; ++} ++ ++static int msm_timer_set_next_event(unsigned long cycles, ++ struct clock_event_device *evt) ++{ ++ u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); ++ ++ ctrl &= ~TIMER_ENABLE_EN; ++ writel_relaxed(ctrl, event_base + TIMER_ENABLE); ++ ++ writel_relaxed(ctrl, event_base + TIMER_CLEAR); ++ writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); ++ ++ if (sts_base) ++ while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND) ++ cpu_relax(); ++ ++ writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); ++ return 0; ++} ++ ++static int msm_timer_shutdown(struct clock_event_device *evt) ++{ ++ u32 ctrl; ++ ++ ctrl = readl_relaxed(event_base + TIMER_ENABLE); ++ ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN); ++ writel_relaxed(ctrl, event_base + TIMER_ENABLE); ++ return 0; ++} ++ ++static struct clock_event_device __percpu *msm_evt; ++ ++static void __iomem *source_base; ++ ++static notrace u64 msm_read_timer_count(struct clocksource *cs) ++{ ++ return readl_relaxed(source_base + TIMER_COUNT_VAL); ++} ++ ++static struct clocksource msm_clocksource = { ++ .name = "dg_timer", ++ .rating = 300, ++ .read = msm_read_timer_count, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++static int msm_timer_irq; ++static int msm_timer_has_ppi; ++ ++static int msm_local_timer_starting_cpu(unsigned int cpu) ++{ ++ struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); ++ int err; ++ ++ evt->irq = msm_timer_irq; ++ evt->name = "msm_timer"; ++ evt->features = CLOCK_EVT_FEAT_ONESHOT; ++ evt->rating = 200; ++ evt->set_state_shutdown = msm_timer_shutdown; ++ evt->set_state_oneshot = msm_timer_shutdown; ++ evt->tick_resume = msm_timer_shutdown; ++ evt->set_next_event = msm_timer_set_next_event; ++ evt->cpumask = cpumask_of(cpu); ++ ++ clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff); ++ ++ if (msm_timer_has_ppi) { ++ enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING); ++ } else { ++ err = request_irq(evt->irq, msm_timer_interrupt, ++ IRQF_TIMER | IRQF_NOBALANCING | ++ IRQF_TRIGGER_RISING, "gp_timer", evt); ++ if (err) ++ pr_err("request_irq failed\n"); ++ } ++ ++ return 0; ++} ++ ++static int msm_local_timer_dying_cpu(unsigned int cpu) ++{ ++ struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu); ++ ++ evt->set_state_shutdown(evt); ++ disable_percpu_irq(evt->irq); ++ return 0; ++} ++ ++static u64 notrace msm_sched_clock_read(void) ++{ ++ return msm_clocksource.read(&msm_clocksource); ++} ++ ++static unsigned long msm_read_current_timer(void) ++{ ++ return msm_clocksource.read(&msm_clocksource); ++} ++ ++static struct delay_timer msm_delay_timer = { ++ .read_current_timer = msm_read_current_timer, ++}; ++ ++static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq, ++ bool percpu) ++{ ++ struct clocksource *cs = &msm_clocksource; ++ int res = 0; ++ ++ msm_timer_irq = irq; ++ msm_timer_has_ppi = percpu; ++ ++ msm_evt = alloc_percpu(struct clock_event_device); ++ if (!msm_evt) { ++ pr_err("memory allocation failed for clockevents\n"); ++ goto err; ++ } ++ ++ if (percpu) ++ res = request_percpu_irq(irq, msm_timer_interrupt, ++ "gp_timer", msm_evt); ++ ++ if (res) { ++ pr_err("request_percpu_irq failed\n"); ++ } else { ++ /* Install and invoke hotplug callbacks */ ++ res = cpuhp_setup_state(CPUHP_AP_QCOM_TIMER_STARTING, ++ "clockevents/qcom/timer:starting", ++ msm_local_timer_starting_cpu, ++ msm_local_timer_dying_cpu); ++ if (res) { ++ free_percpu_irq(irq, msm_evt); ++ goto err; ++ } ++ } ++ ++err: ++ writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); ++ res = clocksource_register_hz(cs, dgt_hz); ++ if (res) ++ pr_err("clocksource_register failed\n"); ++ sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); ++ msm_delay_timer.freq = dgt_hz; ++ register_current_timer_delay(&msm_delay_timer); ++ ++ return res; ++} ++ ++static int __init msm_dt_timer_init(struct device_node *np) ++{ ++ u32 freq; ++ int irq, ret; ++ struct resource res; ++ u32 percpu_offset; ++ void __iomem *base; ++ void __iomem *cpu0_base; ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ pr_err("Failed to map event base\n"); ++ return -ENXIO; ++ } ++ ++ /* We use GPT0 for the clockevent */ ++ irq = irq_of_parse_and_map(np, 1); ++ if (irq <= 0) { ++ pr_err("Can't get irq\n"); ++ return -EINVAL; ++ } ++ ++ /* We use CPU0's DGT for the clocksource */ ++ if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) ++ percpu_offset = 0; ++ ++ ret = of_address_to_resource(np, 0, &res); ++ if (ret) { ++ pr_err("Failed to parse DGT resource\n"); ++ return ret; ++ } ++ ++ cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res)); ++ if (!cpu0_base) { ++ pr_err("Failed to map source base\n"); ++ return -EINVAL; ++ } ++ ++ if (of_property_read_u32(np, "clock-frequency", &freq)) { ++ pr_err("Unknown frequency\n"); ++ return -EINVAL; ++ } ++ ++ event_base = base + 0x4; ++ sts_base = base + 0x88; ++ source_base = cpu0_base + 0x24; ++ freq /= 4; ++ writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); ++ ++ return msm_timer_init(freq, 32, irq, !!percpu_offset); ++} ++TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); ++TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); +diff --git a/drivers/clocksource/timer-versatile.c b/drivers/clocksource/timer-versatile.c +new file mode 100644 +index 0000000000000..39725d38aedee +--- /dev/null ++++ b/drivers/clocksource/timer-versatile.c +@@ -0,0 +1,44 @@ ++/* ++ * 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 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. ++ * ++ * Copyright (C) 2014 ARM Limited ++ */ ++ ++#include <linux/clocksource.h> ++#include <linux/io.h> ++#include <linux/of_address.h> ++#include <linux/sched_clock.h> ++ ++#define SYS_24MHZ 0x05c ++ ++static void __iomem *versatile_sys_24mhz; ++ ++static u64 notrace versatile_sys_24mhz_read(void) ++{ ++ return readl(versatile_sys_24mhz); ++} ++ ++static int __init versatile_sched_clock_init(struct device_node *node) ++{ ++ void __iomem *base = of_iomap(node, 0); ++ ++ if (!base) ++ return -ENXIO; ++ ++ versatile_sys_24mhz = base + SYS_24MHZ; ++ ++ sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); ++ ++ return 0; ++} ++TIMER_OF_DECLARE(vexpress, "arm,vexpress-sysreg", ++ versatile_sched_clock_init); ++TIMER_OF_DECLARE(versatile, "arm,versatile-sysreg", ++ versatile_sched_clock_init); +diff --git a/drivers/clocksource/timer-vf-pit.c b/drivers/clocksource/timer-vf-pit.c +new file mode 100644 +index 0000000000000..0f92089ec08c7 +--- /dev/null ++++ b/drivers/clocksource/timer-vf-pit.c +@@ -0,0 +1,204 @@ ++/* ++ * Copyright 2012-2013 Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ */ ++ ++#include <linux/interrupt.h> ++#include <linux/clockchips.h> ++#include <linux/clk.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/sched_clock.h> ++ ++/* ++ * Each pit takes 0x10 Bytes register space ++ */ ++#define PITMCR 0x00 ++#define PIT0_OFFSET 0x100 ++#define PITn_OFFSET(n) (PIT0_OFFSET + 0x10 * (n)) ++#define PITLDVAL 0x00 ++#define PITCVAL 0x04 ++#define PITTCTRL 0x08 ++#define PITTFLG 0x0c ++ ++#define PITMCR_MDIS (0x1 << 1) ++ ++#define PITTCTRL_TEN (0x1 << 0) ++#define PITTCTRL_TIE (0x1 << 1) ++#define PITCTRL_CHN (0x1 << 2) ++ ++#define PITTFLG_TIF 0x1 ++ ++static void __iomem *clksrc_base; ++static void __iomem *clkevt_base; ++static unsigned long cycle_per_jiffy; ++ ++static inline void pit_timer_enable(void) ++{ ++ __raw_writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL); ++} ++ ++static inline void pit_timer_disable(void) ++{ ++ __raw_writel(0, clkevt_base + PITTCTRL); ++} ++ ++static inline void pit_irq_acknowledge(void) ++{ ++ __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG); ++} ++ ++static u64 notrace pit_read_sched_clock(void) ++{ ++ return ~__raw_readl(clksrc_base + PITCVAL); ++} ++ ++static int __init pit_clocksource_init(unsigned long rate) ++{ ++ /* set the max load value and start the clock source counter */ ++ __raw_writel(0, clksrc_base + PITTCTRL); ++ __raw_writel(~0UL, clksrc_base + PITLDVAL); ++ __raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL); ++ ++ sched_clock_register(pit_read_sched_clock, 32, rate); ++ return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate, ++ 300, 32, clocksource_mmio_readl_down); ++} ++ ++static int pit_set_next_event(unsigned long delta, ++ struct clock_event_device *unused) ++{ ++ /* ++ * set a new value to PITLDVAL register will not restart the timer, ++ * to abort the current cycle and start a timer period with the new ++ * value, the timer must be disabled and enabled again. ++ * and the PITLAVAL should be set to delta minus one according to pit ++ * hardware requirement. ++ */ ++ pit_timer_disable(); ++ __raw_writel(delta - 1, clkevt_base + PITLDVAL); ++ pit_timer_enable(); ++ ++ return 0; ++} ++ ++static int pit_shutdown(struct clock_event_device *evt) ++{ ++ pit_timer_disable(); ++ return 0; ++} ++ ++static int pit_set_periodic(struct clock_event_device *evt) ++{ ++ pit_set_next_event(cycle_per_jiffy, evt); ++ return 0; ++} ++ ++static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = dev_id; ++ ++ pit_irq_acknowledge(); ++ ++ /* ++ * pit hardware doesn't support oneshot, it will generate an interrupt ++ * and reload the counter value from PITLDVAL when PITCVAL reach zero, ++ * and start the counter again. So software need to disable the timer ++ * to stop the counter loop in ONESHOT mode. ++ */ ++ if (likely(clockevent_state_oneshot(evt))) ++ pit_timer_disable(); ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct clock_event_device clockevent_pit = { ++ .name = "VF pit timer", ++ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, ++ .set_state_shutdown = pit_shutdown, ++ .set_state_periodic = pit_set_periodic, ++ .set_next_event = pit_set_next_event, ++ .rating = 300, ++}; ++ ++static struct irqaction pit_timer_irq = { ++ .name = "VF pit timer", ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = pit_timer_interrupt, ++ .dev_id = &clockevent_pit, ++}; ++ ++static int __init pit_clockevent_init(unsigned long rate, int irq) ++{ ++ __raw_writel(0, clkevt_base + PITTCTRL); ++ __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG); ++ ++ BUG_ON(setup_irq(irq, &pit_timer_irq)); ++ ++ clockevent_pit.cpumask = cpumask_of(0); ++ clockevent_pit.irq = irq; ++ /* ++ * The value for the LDVAL register trigger is calculated as: ++ * LDVAL trigger = (period / clock period) - 1 ++ * The pit is a 32-bit down count timer, when the conter value ++ * reaches 0, it will generate an interrupt, thus the minimal ++ * LDVAL trigger value is 1. And then the min_delta is ++ * minimal LDVAL trigger value + 1, and the max_delta is full 32-bit. ++ */ ++ clockevents_config_and_register(&clockevent_pit, rate, 2, 0xffffffff); ++ ++ return 0; ++} ++ ++static int __init pit_timer_init(struct device_node *np) ++{ ++ struct clk *pit_clk; ++ void __iomem *timer_base; ++ unsigned long clk_rate; ++ int irq, ret; ++ ++ timer_base = of_iomap(np, 0); ++ if (!timer_base) { ++ pr_err("Failed to iomap\n"); ++ return -ENXIO; ++ } ++ ++ /* ++ * PIT0 and PIT1 can be chained to build a 64-bit timer, ++ * so choose PIT2 as clocksource, PIT3 as clockevent device, ++ * and leave PIT0 and PIT1 unused for anyone else who needs them. ++ */ ++ clksrc_base = timer_base + PITn_OFFSET(2); ++ clkevt_base = timer_base + PITn_OFFSET(3); ++ ++ irq = irq_of_parse_and_map(np, 0); ++ if (irq <= 0) ++ return -EINVAL; ++ ++ pit_clk = of_clk_get(np, 0); ++ if (IS_ERR(pit_clk)) ++ return PTR_ERR(pit_clk); ++ ++ ret = clk_prepare_enable(pit_clk); ++ if (ret) ++ return ret; ++ ++ clk_rate = clk_get_rate(pit_clk); ++ cycle_per_jiffy = clk_rate / (HZ); ++ ++ /* enable the pit module */ ++ __raw_writel(~PITMCR_MDIS, timer_base + PITMCR); ++ ++ ret = pit_clocksource_init(clk_rate); ++ if (ret) ++ return ret; ++ ++ return pit_clockevent_init(clk_rate, irq); ++} ++TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init); +diff --git a/drivers/clocksource/timer-vt8500.c b/drivers/clocksource/timer-vt8500.c +new file mode 100644 +index 0000000000000..e0f7489cfc8e2 +--- /dev/null ++++ b/drivers/clocksource/timer-vt8500.c +@@ -0,0 +1,168 @@ ++/* ++ * arch/arm/mach-vt8500/timer.c ++ * ++ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> ++ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * This file is copied and modified from the original timer.c provided by ++ * Alexey Charkov. Minor changes have been made for Device Tree Support. ++ */ ++ ++#include <linux/io.h> ++#include <linux/irq.h> ++#include <linux/interrupt.h> ++#include <linux/clocksource.h> ++#include <linux/clockchips.h> ++#include <linux/delay.h> ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++ ++#define VT8500_TIMER_OFFSET 0x0100 ++#define VT8500_TIMER_HZ 3000000 ++#define TIMER_MATCH_VAL 0x0000 ++#define TIMER_COUNT_VAL 0x0010 ++#define TIMER_STATUS_VAL 0x0014 ++#define TIMER_IER_VAL 0x001c /* interrupt enable */ ++#define TIMER_CTRL_VAL 0x0020 ++#define TIMER_AS_VAL 0x0024 /* access status */ ++#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */ ++#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */ ++#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */ ++ ++#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) ++ ++#define MIN_OSCR_DELTA 16 ++ ++static void __iomem *regbase; ++ ++static u64 vt8500_timer_read(struct clocksource *cs) ++{ ++ int loops = msecs_to_loops(10); ++ writel(3, regbase + TIMER_CTRL_VAL); ++ while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE) ++ && --loops) ++ cpu_relax(); ++ return readl(regbase + TIMER_COUNT_VAL); ++} ++ ++static struct clocksource clocksource = { ++ .name = "vt8500_timer", ++ .rating = 200, ++ .read = vt8500_timer_read, ++ .mask = CLOCKSOURCE_MASK(32), ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++}; ++ ++static int vt8500_timer_set_next_event(unsigned long cycles, ++ struct clock_event_device *evt) ++{ ++ int loops = msecs_to_loops(10); ++ u64 alarm = clocksource.read(&clocksource) + cycles; ++ while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE) ++ && --loops) ++ cpu_relax(); ++ writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL); ++ ++ if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA) ++ return -ETIME; ++ ++ writel(1, regbase + TIMER_IER_VAL); ++ ++ return 0; ++} ++ ++static int vt8500_shutdown(struct clock_event_device *evt) ++{ ++ writel(readl(regbase + TIMER_CTRL_VAL) | 1, regbase + TIMER_CTRL_VAL); ++ writel(0, regbase + TIMER_IER_VAL); ++ return 0; ++} ++ ++static struct clock_event_device clockevent = { ++ .name = "vt8500_timer", ++ .features = CLOCK_EVT_FEAT_ONESHOT, ++ .rating = 200, ++ .set_next_event = vt8500_timer_set_next_event, ++ .set_state_shutdown = vt8500_shutdown, ++ .set_state_oneshot = vt8500_shutdown, ++}; ++ ++static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = dev_id; ++ writel(0xf, regbase + TIMER_STATUS_VAL); ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction irq = { ++ .name = "vt8500_timer", ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = vt8500_timer_interrupt, ++ .dev_id = &clockevent, ++}; ++ ++static int __init vt8500_timer_init(struct device_node *np) ++{ ++ int timer_irq, ret; ++ ++ regbase = of_iomap(np, 0); ++ if (!regbase) { ++ pr_err("%s: Missing iobase description in Device Tree\n", ++ __func__); ++ return -ENXIO; ++ } ++ ++ timer_irq = irq_of_parse_and_map(np, 0); ++ if (!timer_irq) { ++ pr_err("%s: Missing irq description in Device Tree\n", ++ __func__); ++ return -EINVAL; ++ } ++ ++ writel(1, regbase + TIMER_CTRL_VAL); ++ writel(0xf, regbase + TIMER_STATUS_VAL); ++ writel(~0, regbase + TIMER_MATCH_VAL); ++ ++ ret = clocksource_register_hz(&clocksource, VT8500_TIMER_HZ); ++ if (ret) { ++ pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n", ++ __func__, clocksource.name); ++ return ret; ++ } ++ ++ clockevent.cpumask = cpumask_of(0); ++ ++ ret = setup_irq(timer_irq, &irq); ++ if (ret) { ++ pr_err("%s: setup_irq failed for %s\n", __func__, ++ clockevent.name); ++ return ret; ++ } ++ ++ clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, ++ MIN_OSCR_DELTA * 2, 0xf0000000); ++ ++ return 0; ++} ++ ++TIMER_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); +diff --git a/drivers/clocksource/timer-zevio.c b/drivers/clocksource/timer-zevio.c +new file mode 100644 +index 0000000000000..f74689334f7cb +--- /dev/null ++++ b/drivers/clocksource/timer-zevio.c +@@ -0,0 +1,218 @@ ++/* ++ * linux/drivers/clocksource/zevio-timer.c ++ * ++ * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> ++ * ++ * 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. ++ * ++ */ ++ ++#include <linux/io.h> ++#include <linux/irq.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/clk.h> ++#include <linux/clockchips.h> ++#include <linux/cpumask.h> ++#include <linux/interrupt.h> ++#include <linux/slab.h> ++ ++#define IO_CURRENT_VAL 0x00 ++#define IO_DIVIDER 0x04 ++#define IO_CONTROL 0x08 ++ ++#define IO_TIMER1 0x00 ++#define IO_TIMER2 0x0C ++ ++#define IO_MATCH_BEGIN 0x18 ++#define IO_MATCH(x) (IO_MATCH_BEGIN + ((x) << 2)) ++ ++#define IO_INTR_STS 0x00 ++#define IO_INTR_ACK 0x00 ++#define IO_INTR_MSK 0x04 ++ ++#define CNTL_STOP_TIMER (1 << 4) ++#define CNTL_RUN_TIMER (0 << 4) ++ ++#define CNTL_INC (1 << 3) ++#define CNTL_DEC (0 << 3) ++ ++#define CNTL_TOZERO 0 ++#define CNTL_MATCH(x) ((x) + 1) ++#define CNTL_FOREVER 7 ++ ++/* There are 6 match registers but we only use one. */ ++#define TIMER_MATCH 0 ++ ++#define TIMER_INTR_MSK (1 << (TIMER_MATCH)) ++#define TIMER_INTR_ALL 0x3F ++ ++struct zevio_timer { ++ void __iomem *base; ++ void __iomem *timer1, *timer2; ++ void __iomem *interrupt_regs; ++ ++ struct clk *clk; ++ struct clock_event_device clkevt; ++ struct irqaction clkevt_irq; ++ ++ char clocksource_name[64]; ++ char clockevent_name[64]; ++}; ++ ++static int zevio_timer_set_event(unsigned long delta, ++ struct clock_event_device *dev) ++{ ++ struct zevio_timer *timer = container_of(dev, struct zevio_timer, ++ clkevt); ++ ++ writel(delta, timer->timer1 + IO_CURRENT_VAL); ++ writel(CNTL_RUN_TIMER | CNTL_DEC | CNTL_MATCH(TIMER_MATCH), ++ timer->timer1 + IO_CONTROL); ++ ++ return 0; ++} ++ ++static int zevio_timer_shutdown(struct clock_event_device *dev) ++{ ++ struct zevio_timer *timer = container_of(dev, struct zevio_timer, ++ clkevt); ++ ++ /* Disable timer interrupts */ ++ writel(0, timer->interrupt_regs + IO_INTR_MSK); ++ writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); ++ /* Stop timer */ ++ writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); ++ return 0; ++} ++ ++static int zevio_timer_set_oneshot(struct clock_event_device *dev) ++{ ++ struct zevio_timer *timer = container_of(dev, struct zevio_timer, ++ clkevt); ++ ++ /* Enable timer interrupts */ ++ writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK); ++ writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); ++ return 0; ++} ++ ++static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id) ++{ ++ struct zevio_timer *timer = dev_id; ++ u32 intr; ++ ++ intr = readl(timer->interrupt_regs + IO_INTR_ACK); ++ if (!(intr & TIMER_INTR_MSK)) ++ return IRQ_NONE; ++ ++ writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_ACK); ++ writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); ++ ++ if (timer->clkevt.event_handler) ++ timer->clkevt.event_handler(&timer->clkevt); ++ ++ return IRQ_HANDLED; ++} ++ ++static int __init zevio_timer_add(struct device_node *node) ++{ ++ struct zevio_timer *timer; ++ struct resource res; ++ int irqnr, ret; ++ ++ timer = kzalloc(sizeof(*timer), GFP_KERNEL); ++ if (!timer) ++ return -ENOMEM; ++ ++ timer->base = of_iomap(node, 0); ++ if (!timer->base) { ++ ret = -EINVAL; ++ goto error_free; ++ } ++ timer->timer1 = timer->base + IO_TIMER1; ++ timer->timer2 = timer->base + IO_TIMER2; ++ ++ timer->clk = of_clk_get(node, 0); ++ if (IS_ERR(timer->clk)) { ++ ret = PTR_ERR(timer->clk); ++ pr_err("Timer clock not found! (error %d)\n", ret); ++ goto error_unmap; ++ } ++ ++ timer->interrupt_regs = of_iomap(node, 1); ++ irqnr = irq_of_parse_and_map(node, 0); ++ ++ of_address_to_resource(node, 0, &res); ++ scnprintf(timer->clocksource_name, sizeof(timer->clocksource_name), ++ "%llx.%s_clocksource", ++ (unsigned long long)res.start, node->name); ++ ++ scnprintf(timer->clockevent_name, sizeof(timer->clockevent_name), ++ "%llx.%s_clockevent", ++ (unsigned long long)res.start, node->name); ++ ++ if (timer->interrupt_regs && irqnr) { ++ timer->clkevt.name = timer->clockevent_name; ++ timer->clkevt.set_next_event = zevio_timer_set_event; ++ timer->clkevt.set_state_shutdown = zevio_timer_shutdown; ++ timer->clkevt.set_state_oneshot = zevio_timer_set_oneshot; ++ timer->clkevt.tick_resume = zevio_timer_set_oneshot; ++ timer->clkevt.rating = 200; ++ timer->clkevt.cpumask = cpu_possible_mask; ++ timer->clkevt.features = CLOCK_EVT_FEAT_ONESHOT; ++ timer->clkevt.irq = irqnr; ++ ++ writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); ++ writel(0, timer->timer1 + IO_DIVIDER); ++ ++ /* Start with timer interrupts disabled */ ++ writel(0, timer->interrupt_regs + IO_INTR_MSK); ++ writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); ++ ++ /* Interrupt to occur when timer value matches 0 */ ++ writel(0, timer->base + IO_MATCH(TIMER_MATCH)); ++ ++ timer->clkevt_irq.name = timer->clockevent_name; ++ timer->clkevt_irq.handler = zevio_timer_interrupt; ++ timer->clkevt_irq.dev_id = timer; ++ timer->clkevt_irq.flags = IRQF_TIMER | IRQF_IRQPOLL; ++ ++ setup_irq(irqnr, &timer->clkevt_irq); ++ ++ clockevents_config_and_register(&timer->clkevt, ++ clk_get_rate(timer->clk), 0x0001, 0xffff); ++ pr_info("Added %s as clockevent\n", timer->clockevent_name); ++ } ++ ++ writel(CNTL_STOP_TIMER, timer->timer2 + IO_CONTROL); ++ writel(0, timer->timer2 + IO_CURRENT_VAL); ++ writel(0, timer->timer2 + IO_DIVIDER); ++ writel(CNTL_RUN_TIMER | CNTL_FOREVER | CNTL_INC, ++ timer->timer2 + IO_CONTROL); ++ ++ clocksource_mmio_init(timer->timer2 + IO_CURRENT_VAL, ++ timer->clocksource_name, ++ clk_get_rate(timer->clk), ++ 200, 16, ++ clocksource_mmio_readw_up); ++ ++ pr_info("Added %s as clocksource\n", timer->clocksource_name); ++ ++ return 0; ++error_unmap: ++ iounmap(timer->base); ++error_free: ++ kfree(timer); ++ return ret; ++} ++ ++static int __init zevio_timer_init(struct device_node *node) ++{ ++ return zevio_timer_add(node); ++} ++ ++TIMER_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init); +diff --git a/drivers/clocksource/versatile.c b/drivers/clocksource/versatile.c +deleted file mode 100644 +index 39725d38aedee..0000000000000 +--- a/drivers/clocksource/versatile.c ++++ /dev/null +@@ -1,44 +0,0 @@ +-/* +- * 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 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. +- * +- * Copyright (C) 2014 ARM Limited +- */ +- +-#include <linux/clocksource.h> +-#include <linux/io.h> +-#include <linux/of_address.h> +-#include <linux/sched_clock.h> +- +-#define SYS_24MHZ 0x05c +- +-static void __iomem *versatile_sys_24mhz; +- +-static u64 notrace versatile_sys_24mhz_read(void) +-{ +- return readl(versatile_sys_24mhz); +-} +- +-static int __init versatile_sched_clock_init(struct device_node *node) +-{ +- void __iomem *base = of_iomap(node, 0); +- +- if (!base) +- return -ENXIO; +- +- versatile_sys_24mhz = base + SYS_24MHZ; +- +- sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); +- +- return 0; +-} +-TIMER_OF_DECLARE(vexpress, "arm,vexpress-sysreg", +- versatile_sched_clock_init); +-TIMER_OF_DECLARE(versatile, "arm,versatile-sysreg", +- versatile_sched_clock_init); +diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c +deleted file mode 100644 +index 0f92089ec08c7..0000000000000 +--- a/drivers/clocksource/vf_pit_timer.c ++++ /dev/null +@@ -1,204 +0,0 @@ +-/* +- * Copyright 2012-2013 Freescale Semiconductor, Inc. +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version 2 +- * of the License, or (at your option) any later version. +- */ +- +-#include <linux/interrupt.h> +-#include <linux/clockchips.h> +-#include <linux/clk.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/sched_clock.h> +- +-/* +- * Each pit takes 0x10 Bytes register space +- */ +-#define PITMCR 0x00 +-#define PIT0_OFFSET 0x100 +-#define PITn_OFFSET(n) (PIT0_OFFSET + 0x10 * (n)) +-#define PITLDVAL 0x00 +-#define PITCVAL 0x04 +-#define PITTCTRL 0x08 +-#define PITTFLG 0x0c +- +-#define PITMCR_MDIS (0x1 << 1) +- +-#define PITTCTRL_TEN (0x1 << 0) +-#define PITTCTRL_TIE (0x1 << 1) +-#define PITCTRL_CHN (0x1 << 2) +- +-#define PITTFLG_TIF 0x1 +- +-static void __iomem *clksrc_base; +-static void __iomem *clkevt_base; +-static unsigned long cycle_per_jiffy; +- +-static inline void pit_timer_enable(void) +-{ +- __raw_writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL); +-} +- +-static inline void pit_timer_disable(void) +-{ +- __raw_writel(0, clkevt_base + PITTCTRL); +-} +- +-static inline void pit_irq_acknowledge(void) +-{ +- __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG); +-} +- +-static u64 notrace pit_read_sched_clock(void) +-{ +- return ~__raw_readl(clksrc_base + PITCVAL); +-} +- +-static int __init pit_clocksource_init(unsigned long rate) +-{ +- /* set the max load value and start the clock source counter */ +- __raw_writel(0, clksrc_base + PITTCTRL); +- __raw_writel(~0UL, clksrc_base + PITLDVAL); +- __raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL); +- +- sched_clock_register(pit_read_sched_clock, 32, rate); +- return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate, +- 300, 32, clocksource_mmio_readl_down); +-} +- +-static int pit_set_next_event(unsigned long delta, +- struct clock_event_device *unused) +-{ +- /* +- * set a new value to PITLDVAL register will not restart the timer, +- * to abort the current cycle and start a timer period with the new +- * value, the timer must be disabled and enabled again. +- * and the PITLAVAL should be set to delta minus one according to pit +- * hardware requirement. +- */ +- pit_timer_disable(); +- __raw_writel(delta - 1, clkevt_base + PITLDVAL); +- pit_timer_enable(); +- +- return 0; +-} +- +-static int pit_shutdown(struct clock_event_device *evt) +-{ +- pit_timer_disable(); +- return 0; +-} +- +-static int pit_set_periodic(struct clock_event_device *evt) +-{ +- pit_set_next_event(cycle_per_jiffy, evt); +- return 0; +-} +- +-static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) +-{ +- struct clock_event_device *evt = dev_id; +- +- pit_irq_acknowledge(); +- +- /* +- * pit hardware doesn't support oneshot, it will generate an interrupt +- * and reload the counter value from PITLDVAL when PITCVAL reach zero, +- * and start the counter again. So software need to disable the timer +- * to stop the counter loop in ONESHOT mode. +- */ +- if (likely(clockevent_state_oneshot(evt))) +- pit_timer_disable(); +- +- evt->event_handler(evt); +- +- return IRQ_HANDLED; +-} +- +-static struct clock_event_device clockevent_pit = { +- .name = "VF pit timer", +- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, +- .set_state_shutdown = pit_shutdown, +- .set_state_periodic = pit_set_periodic, +- .set_next_event = pit_set_next_event, +- .rating = 300, +-}; +- +-static struct irqaction pit_timer_irq = { +- .name = "VF pit timer", +- .flags = IRQF_TIMER | IRQF_IRQPOLL, +- .handler = pit_timer_interrupt, +- .dev_id = &clockevent_pit, +-}; +- +-static int __init pit_clockevent_init(unsigned long rate, int irq) +-{ +- __raw_writel(0, clkevt_base + PITTCTRL); +- __raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG); +- +- BUG_ON(setup_irq(irq, &pit_timer_irq)); +- +- clockevent_pit.cpumask = cpumask_of(0); +- clockevent_pit.irq = irq; +- /* +- * The value for the LDVAL register trigger is calculated as: +- * LDVAL trigger = (period / clock period) - 1 +- * The pit is a 32-bit down count timer, when the conter value +- * reaches 0, it will generate an interrupt, thus the minimal +- * LDVAL trigger value is 1. And then the min_delta is +- * minimal LDVAL trigger value + 1, and the max_delta is full 32-bit. +- */ +- clockevents_config_and_register(&clockevent_pit, rate, 2, 0xffffffff); +- +- return 0; +-} +- +-static int __init pit_timer_init(struct device_node *np) +-{ +- struct clk *pit_clk; +- void __iomem *timer_base; +- unsigned long clk_rate; +- int irq, ret; +- +- timer_base = of_iomap(np, 0); +- if (!timer_base) { +- pr_err("Failed to iomap\n"); +- return -ENXIO; +- } +- +- /* +- * PIT0 and PIT1 can be chained to build a 64-bit timer, +- * so choose PIT2 as clocksource, PIT3 as clockevent device, +- * and leave PIT0 and PIT1 unused for anyone else who needs them. +- */ +- clksrc_base = timer_base + PITn_OFFSET(2); +- clkevt_base = timer_base + PITn_OFFSET(3); +- +- irq = irq_of_parse_and_map(np, 0); +- if (irq <= 0) +- return -EINVAL; +- +- pit_clk = of_clk_get(np, 0); +- if (IS_ERR(pit_clk)) +- return PTR_ERR(pit_clk); +- +- ret = clk_prepare_enable(pit_clk); +- if (ret) +- return ret; +- +- clk_rate = clk_get_rate(pit_clk); +- cycle_per_jiffy = clk_rate / (HZ); +- +- /* enable the pit module */ +- __raw_writel(~PITMCR_MDIS, timer_base + PITMCR); +- +- ret = pit_clocksource_init(clk_rate); +- if (ret) +- return ret; +- +- return pit_clockevent_init(clk_rate, irq); +-} +-TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init); +diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c +deleted file mode 100644 +index e0f7489cfc8e2..0000000000000 +--- a/drivers/clocksource/vt8500_timer.c ++++ /dev/null +@@ -1,168 +0,0 @@ +-/* +- * arch/arm/mach-vt8500/timer.c +- * +- * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz> +- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +- */ +- +-/* +- * This file is copied and modified from the original timer.c provided by +- * Alexey Charkov. Minor changes have been made for Device Tree Support. +- */ +- +-#include <linux/io.h> +-#include <linux/irq.h> +-#include <linux/interrupt.h> +-#include <linux/clocksource.h> +-#include <linux/clockchips.h> +-#include <linux/delay.h> +- +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +- +-#define VT8500_TIMER_OFFSET 0x0100 +-#define VT8500_TIMER_HZ 3000000 +-#define TIMER_MATCH_VAL 0x0000 +-#define TIMER_COUNT_VAL 0x0010 +-#define TIMER_STATUS_VAL 0x0014 +-#define TIMER_IER_VAL 0x001c /* interrupt enable */ +-#define TIMER_CTRL_VAL 0x0020 +-#define TIMER_AS_VAL 0x0024 /* access status */ +-#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */ +-#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */ +-#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */ +- +-#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) +- +-#define MIN_OSCR_DELTA 16 +- +-static void __iomem *regbase; +- +-static u64 vt8500_timer_read(struct clocksource *cs) +-{ +- int loops = msecs_to_loops(10); +- writel(3, regbase + TIMER_CTRL_VAL); +- while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE) +- && --loops) +- cpu_relax(); +- return readl(regbase + TIMER_COUNT_VAL); +-} +- +-static struct clocksource clocksource = { +- .name = "vt8500_timer", +- .rating = 200, +- .read = vt8500_timer_read, +- .mask = CLOCKSOURCE_MASK(32), +- .flags = CLOCK_SOURCE_IS_CONTINUOUS, +-}; +- +-static int vt8500_timer_set_next_event(unsigned long cycles, +- struct clock_event_device *evt) +-{ +- int loops = msecs_to_loops(10); +- u64 alarm = clocksource.read(&clocksource) + cycles; +- while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE) +- && --loops) +- cpu_relax(); +- writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL); +- +- if ((signed)(alarm - clocksource.read(&clocksource)) <= MIN_OSCR_DELTA) +- return -ETIME; +- +- writel(1, regbase + TIMER_IER_VAL); +- +- return 0; +-} +- +-static int vt8500_shutdown(struct clock_event_device *evt) +-{ +- writel(readl(regbase + TIMER_CTRL_VAL) | 1, regbase + TIMER_CTRL_VAL); +- writel(0, regbase + TIMER_IER_VAL); +- return 0; +-} +- +-static struct clock_event_device clockevent = { +- .name = "vt8500_timer", +- .features = CLOCK_EVT_FEAT_ONESHOT, +- .rating = 200, +- .set_next_event = vt8500_timer_set_next_event, +- .set_state_shutdown = vt8500_shutdown, +- .set_state_oneshot = vt8500_shutdown, +-}; +- +-static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id) +-{ +- struct clock_event_device *evt = dev_id; +- writel(0xf, regbase + TIMER_STATUS_VAL); +- evt->event_handler(evt); +- +- return IRQ_HANDLED; +-} +- +-static struct irqaction irq = { +- .name = "vt8500_timer", +- .flags = IRQF_TIMER | IRQF_IRQPOLL, +- .handler = vt8500_timer_interrupt, +- .dev_id = &clockevent, +-}; +- +-static int __init vt8500_timer_init(struct device_node *np) +-{ +- int timer_irq, ret; +- +- regbase = of_iomap(np, 0); +- if (!regbase) { +- pr_err("%s: Missing iobase description in Device Tree\n", +- __func__); +- return -ENXIO; +- } +- +- timer_irq = irq_of_parse_and_map(np, 0); +- if (!timer_irq) { +- pr_err("%s: Missing irq description in Device Tree\n", +- __func__); +- return -EINVAL; +- } +- +- writel(1, regbase + TIMER_CTRL_VAL); +- writel(0xf, regbase + TIMER_STATUS_VAL); +- writel(~0, regbase + TIMER_MATCH_VAL); +- +- ret = clocksource_register_hz(&clocksource, VT8500_TIMER_HZ); +- if (ret) { +- pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n", +- __func__, clocksource.name); +- return ret; +- } +- +- clockevent.cpumask = cpumask_of(0); +- +- ret = setup_irq(timer_irq, &irq); +- if (ret) { +- pr_err("%s: setup_irq failed for %s\n", __func__, +- clockevent.name); +- return ret; +- } +- +- clockevents_config_and_register(&clockevent, VT8500_TIMER_HZ, +- MIN_OSCR_DELTA * 2, 0xf0000000); +- +- return 0; +-} +- +-TIMER_OF_DECLARE(vt8500, "via,vt8500-timer", vt8500_timer_init); +diff --git a/drivers/clocksource/zevio-timer.c b/drivers/clocksource/zevio-timer.c +deleted file mode 100644 +index f74689334f7cb..0000000000000 +--- a/drivers/clocksource/zevio-timer.c ++++ /dev/null +@@ -1,218 +0,0 @@ +-/* +- * linux/drivers/clocksource/zevio-timer.c +- * +- * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> +- * +- * 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. +- * +- */ +- +-#include <linux/io.h> +-#include <linux/irq.h> +-#include <linux/of.h> +-#include <linux/of_address.h> +-#include <linux/of_irq.h> +-#include <linux/clk.h> +-#include <linux/clockchips.h> +-#include <linux/cpumask.h> +-#include <linux/interrupt.h> +-#include <linux/slab.h> +- +-#define IO_CURRENT_VAL 0x00 +-#define IO_DIVIDER 0x04 +-#define IO_CONTROL 0x08 +- +-#define IO_TIMER1 0x00 +-#define IO_TIMER2 0x0C +- +-#define IO_MATCH_BEGIN 0x18 +-#define IO_MATCH(x) (IO_MATCH_BEGIN + ((x) << 2)) +- +-#define IO_INTR_STS 0x00 +-#define IO_INTR_ACK 0x00 +-#define IO_INTR_MSK 0x04 +- +-#define CNTL_STOP_TIMER (1 << 4) +-#define CNTL_RUN_TIMER (0 << 4) +- +-#define CNTL_INC (1 << 3) +-#define CNTL_DEC (0 << 3) +- +-#define CNTL_TOZERO 0 +-#define CNTL_MATCH(x) ((x) + 1) +-#define CNTL_FOREVER 7 +- +-/* There are 6 match registers but we only use one. */ +-#define TIMER_MATCH 0 +- +-#define TIMER_INTR_MSK (1 << (TIMER_MATCH)) +-#define TIMER_INTR_ALL 0x3F +- +-struct zevio_timer { +- void __iomem *base; +- void __iomem *timer1, *timer2; +- void __iomem *interrupt_regs; +- +- struct clk *clk; +- struct clock_event_device clkevt; +- struct irqaction clkevt_irq; +- +- char clocksource_name[64]; +- char clockevent_name[64]; +-}; +- +-static int zevio_timer_set_event(unsigned long delta, +- struct clock_event_device *dev) +-{ +- struct zevio_timer *timer = container_of(dev, struct zevio_timer, +- clkevt); +- +- writel(delta, timer->timer1 + IO_CURRENT_VAL); +- writel(CNTL_RUN_TIMER | CNTL_DEC | CNTL_MATCH(TIMER_MATCH), +- timer->timer1 + IO_CONTROL); +- +- return 0; +-} +- +-static int zevio_timer_shutdown(struct clock_event_device *dev) +-{ +- struct zevio_timer *timer = container_of(dev, struct zevio_timer, +- clkevt); +- +- /* Disable timer interrupts */ +- writel(0, timer->interrupt_regs + IO_INTR_MSK); +- writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); +- /* Stop timer */ +- writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); +- return 0; +-} +- +-static int zevio_timer_set_oneshot(struct clock_event_device *dev) +-{ +- struct zevio_timer *timer = container_of(dev, struct zevio_timer, +- clkevt); +- +- /* Enable timer interrupts */ +- writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK); +- writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); +- return 0; +-} +- +-static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id) +-{ +- struct zevio_timer *timer = dev_id; +- u32 intr; +- +- intr = readl(timer->interrupt_regs + IO_INTR_ACK); +- if (!(intr & TIMER_INTR_MSK)) +- return IRQ_NONE; +- +- writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_ACK); +- writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); +- +- if (timer->clkevt.event_handler) +- timer->clkevt.event_handler(&timer->clkevt); +- +- return IRQ_HANDLED; +-} +- +-static int __init zevio_timer_add(struct device_node *node) +-{ +- struct zevio_timer *timer; +- struct resource res; +- int irqnr, ret; +- +- timer = kzalloc(sizeof(*timer), GFP_KERNEL); +- if (!timer) +- return -ENOMEM; +- +- timer->base = of_iomap(node, 0); +- if (!timer->base) { +- ret = -EINVAL; +- goto error_free; +- } +- timer->timer1 = timer->base + IO_TIMER1; +- timer->timer2 = timer->base + IO_TIMER2; +- +- timer->clk = of_clk_get(node, 0); +- if (IS_ERR(timer->clk)) { +- ret = PTR_ERR(timer->clk); +- pr_err("Timer clock not found! (error %d)\n", ret); +- goto error_unmap; +- } +- +- timer->interrupt_regs = of_iomap(node, 1); +- irqnr = irq_of_parse_and_map(node, 0); +- +- of_address_to_resource(node, 0, &res); +- scnprintf(timer->clocksource_name, sizeof(timer->clocksource_name), +- "%llx.%s_clocksource", +- (unsigned long long)res.start, node->name); +- +- scnprintf(timer->clockevent_name, sizeof(timer->clockevent_name), +- "%llx.%s_clockevent", +- (unsigned long long)res.start, node->name); +- +- if (timer->interrupt_regs && irqnr) { +- timer->clkevt.name = timer->clockevent_name; +- timer->clkevt.set_next_event = zevio_timer_set_event; +- timer->clkevt.set_state_shutdown = zevio_timer_shutdown; +- timer->clkevt.set_state_oneshot = zevio_timer_set_oneshot; +- timer->clkevt.tick_resume = zevio_timer_set_oneshot; +- timer->clkevt.rating = 200; +- timer->clkevt.cpumask = cpu_possible_mask; +- timer->clkevt.features = CLOCK_EVT_FEAT_ONESHOT; +- timer->clkevt.irq = irqnr; +- +- writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL); +- writel(0, timer->timer1 + IO_DIVIDER); +- +- /* Start with timer interrupts disabled */ +- writel(0, timer->interrupt_regs + IO_INTR_MSK); +- writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK); +- +- /* Interrupt to occur when timer value matches 0 */ +- writel(0, timer->base + IO_MATCH(TIMER_MATCH)); +- +- timer->clkevt_irq.name = timer->clockevent_name; +- timer->clkevt_irq.handler = zevio_timer_interrupt; +- timer->clkevt_irq.dev_id = timer; +- timer->clkevt_irq.flags = IRQF_TIMER | IRQF_IRQPOLL; +- +- setup_irq(irqnr, &timer->clkevt_irq); +- +- clockevents_config_and_register(&timer->clkevt, +- clk_get_rate(timer->clk), 0x0001, 0xffff); +- pr_info("Added %s as clockevent\n", timer->clockevent_name); +- } +- +- writel(CNTL_STOP_TIMER, timer->timer2 + IO_CONTROL); +- writel(0, timer->timer2 + IO_CURRENT_VAL); +- writel(0, timer->timer2 + IO_DIVIDER); +- writel(CNTL_RUN_TIMER | CNTL_FOREVER | CNTL_INC, +- timer->timer2 + IO_CONTROL); +- +- clocksource_mmio_init(timer->timer2 + IO_CURRENT_VAL, +- timer->clocksource_name, +- clk_get_rate(timer->clk), +- 200, 16, +- clocksource_mmio_readw_up); +- +- pr_info("Added %s as clocksource\n", timer->clocksource_name); +- +- return 0; +-error_unmap: +- iounmap(timer->base); +-error_free: +- kfree(timer); +- return ret; +-} +- +-static int __init zevio_timer_init(struct device_node *node) +-{ +- return zevio_timer_add(node); +-} +- +-TIMER_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init); +diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile +index 015155da59c29..76139865d7fa1 100644 +--- a/drivers/crypto/nx/Makefile ++++ b/drivers/crypto/nx/Makefile +@@ -1,7 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o + nx-crypto-objs := nx.o \ +- nx_debugfs.o \ + nx-aes-cbc.o \ + nx-aes-ecb.o \ + nx-aes-gcm.o \ +@@ -11,6 +10,7 @@ nx-crypto-objs := nx.o \ + nx-sha256.o \ + nx-sha512.o + ++nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o + obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o + obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o + nx-compress-objs := nx-842.o +diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h +index c3e54af18645c..ebad937a9545c 100644 +--- a/drivers/crypto/nx/nx.h ++++ b/drivers/crypto/nx/nx.h +@@ -180,8 +180,8 @@ struct nx_sg *nx_walk_and_build(struct nx_sg *, unsigned int, + int nx_debugfs_init(struct nx_crypto_driver *); + void nx_debugfs_fini(struct nx_crypto_driver *); + #else +-#define NX_DEBUGFS_INIT(drv) (0) +-#define NX_DEBUGFS_FINI(drv) (0) ++#define NX_DEBUGFS_INIT(drv) do {} while (0) ++#define NX_DEBUGFS_FINI(drv) do {} while (0) + #endif + + #define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL) +diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c +index 4c70136c7aa3c..84fc0e48bb0e8 100644 +--- a/drivers/extcon/extcon.c ++++ b/drivers/extcon/extcon.c +@@ -204,6 +204,14 @@ static const struct __extcon_info { + * @attr_name: "name" sysfs entry + * @attr_state: "state" sysfs entry + * @attrs: the array pointing to attr_name and attr_state for attr_g ++ * @usb_propval: the array of USB connector properties ++ * @chg_propval: the array of charger connector properties ++ * @jack_propval: the array of jack connector properties ++ * @disp_propval: the array of display connector properties ++ * @usb_bits: the bit array of the USB connector property capabilities ++ * @chg_bits: the bit array of the charger connector property capabilities ++ * @jack_bits: the bit array of the jack connector property capabilities ++ * @disp_bits: the bit array of the display connector property capabilities + */ + struct extcon_cable { + struct extcon_dev *edev; +diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c +index 45c048751f3bd..9e7abc86de8c2 100644 +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -1112,7 +1112,7 @@ static void context_tasklet(unsigned long data) + static int context_add_buffer(struct context *ctx) + { + struct descriptor_buffer *desc; +- dma_addr_t uninitialized_var(bus_addr); ++ dma_addr_t bus_addr; + int offset; + + /* +@@ -1302,7 +1302,7 @@ static int at_context_queue_packet(struct context *ctx, + struct fw_packet *packet) + { + struct fw_ohci *ohci = ctx->ohci; +- dma_addr_t d_bus, uninitialized_var(payload_bus); ++ dma_addr_t d_bus, payload_bus; + struct driver_data *driver_data; + struct descriptor *d, *last; + __le32 *header; +@@ -2458,7 +2458,7 @@ static int ohci_set_config_rom(struct fw_card *card, + { + struct fw_ohci *ohci; + __be32 *next_config_rom; +- dma_addr_t uninitialized_var(next_config_rom_bus); ++ dma_addr_t next_config_rom_bus; + + ohci = fw_ohci(card); + +@@ -2947,10 +2947,10 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, + int type, int channel, size_t header_size) + { + struct fw_ohci *ohci = fw_ohci(card); +- struct iso_context *uninitialized_var(ctx); +- descriptor_callback_t uninitialized_var(callback); +- u64 *uninitialized_var(channels); +- u32 *uninitialized_var(mask), uninitialized_var(regs); ++ struct iso_context *ctx; ++ descriptor_callback_t callback; ++ u64 *channels; ++ u32 *mask, regs; + int index, ret = -EBUSY; + + spin_lock_irq(&ohci->lock); +diff --git a/drivers/gpio/gpio-tps68470.c b/drivers/gpio/gpio-tps68470.c +index aff6e504c6668..9704cff9b4aa3 100644 +--- a/drivers/gpio/gpio-tps68470.c ++++ b/drivers/gpio/gpio-tps68470.c +@@ -91,13 +91,13 @@ static int tps68470_gpio_output(struct gpio_chip *gc, unsigned int offset, + struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); + struct regmap *regmap = tps68470_gpio->tps68470_regmap; + ++ /* Set the initial value */ ++ tps68470_gpio_set(gc, offset, value); ++ + /* rest are always outputs */ + if (offset >= TPS68470_N_REGULAR_GPIO) + return 0; + +- /* Set the initial value */ +- tps68470_gpio_set(gc, offset, value); +- + return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), + TPS68470_GPIO_MODE_MASK, + TPS68470_GPIO_MODE_OUT_CMOS); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index 6a1f5df4bc07e..cdcf9e697c398 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -2989,6 +2989,10 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + struct amdgpu_fpriv *fpriv = filp->driver_priv; + int r; + ++ /* No valid flags defined yet */ ++ if (args->in.flags) ++ return -EINVAL; ++ + switch (args->in.op) { + case AMDGPU_VM_OP_RESERVE_VMID: + /* current, we only have requirement to reserve vmid from gfxhub */ +diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c +index c72092319a533..214cd2028cd57 100644 +--- a/drivers/gpu/drm/bridge/sil-sii8620.c ++++ b/drivers/gpu/drm/bridge/sil-sii8620.c +@@ -988,7 +988,7 @@ static void sii8620_set_auto_zone(struct sii8620 *ctx) + + static void sii8620_stop_video(struct sii8620 *ctx) + { +- u8 uninitialized_var(val); ++ u8 val; + + sii8620_write_seq_static(ctx, + REG_TPI_INTR_EN, 0, +diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c +index 281cf9cbb44c4..70b26487de79c 100644 +--- a/drivers/gpu/drm/drm_atomic.c ++++ b/drivers/gpu/drm/drm_atomic.c +@@ -91,6 +91,12 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) + if (!state->planes) + goto fail; + ++ /* ++ * Because drm_atomic_state can be committed asynchronously we need our ++ * own reference and cannot rely on the on implied by drm_file in the ++ * ioctl call. ++ */ ++ drm_dev_get(dev); + state->dev = dev; + + DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state); +@@ -250,7 +256,8 @@ EXPORT_SYMBOL(drm_atomic_state_clear); + void __drm_atomic_state_free(struct kref *ref) + { + struct drm_atomic_state *state = container_of(ref, typeof(*state), ref); +- struct drm_mode_config *config = &state->dev->mode_config; ++ struct drm_device *dev = state->dev; ++ struct drm_mode_config *config = &dev->mode_config; + + drm_atomic_state_clear(state); + +@@ -262,6 +269,8 @@ void __drm_atomic_state_free(struct kref *ref) + drm_atomic_state_default_release(state); + kfree(state); + } ++ ++ drm_dev_put(dev); + } + EXPORT_SYMBOL(__drm_atomic_state_free); + +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 28ea3d260bea1..8b7b107cf2ce3 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -2778,7 +2778,7 @@ static int drm_cvt_modes(struct drm_connector *connector, + const u8 empty[3] = { 0, 0, 0 }; + + for (i = 0; i < 4; i++) { +- int uninitialized_var(width), height; ++ int width, height; + cvt = &(timing->data.other_data.data.cvt[i]); + + if (!memcmp(cvt->code, empty, 3)) +@@ -2786,6 +2786,8 @@ static int drm_cvt_modes(struct drm_connector *connector, + + height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; + switch (cvt->code[1] & 0x0c) { ++ /* default - because compiler doesn't see that we've enumerated all cases */ ++ default: + case 0x00: + width = height * 4 / 3; + break; +diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c +index fbe9156c9e7c1..ee6801fa36ad1 100644 +--- a/drivers/gpu/drm/drm_fb_helper.c ++++ b/drivers/gpu/drm/drm_fb_helper.c +@@ -2233,6 +2233,9 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, + can_clone = true; + dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); + ++ if (!dmt_mode) ++ goto fail; ++ + drm_fb_helper_for_each_connector(fb_helper, i) { + if (!enabled[i]) + continue; +@@ -2249,11 +2252,13 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, + if (!modes[i]) + can_clone = false; + } ++ kfree(dmt_mode); + + if (can_clone) { + DRM_DEBUG_KMS("can clone using 1024x768\n"); + return true; + } ++fail: + DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); + return false; + } +diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c +index 8d776070913da..8610589299fc6 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c +@@ -544,9 +544,9 @@ static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi, + unsigned long best_freq = 0; + u32 min_delta = 0xffffffff; + u8 p_min, p_max; +- u8 _p, uninitialized_var(best_p); +- u16 _m, uninitialized_var(best_m); +- u8 _s, uninitialized_var(best_s); ++ u8 _p, best_p; ++ u16 _m, best_m; ++ u8 _s, best_s; + + p_min = DIV_ROUND_UP(fin, (12 * MHZ)); + p_max = fin / (6 * MHZ); +diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +index ba513018534e3..1bdba8cc25d3e 100644 +--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +@@ -173,7 +173,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit + * since we've already mapped it once in + * submit_reloc() + */ +- if (WARN_ON(!ptr)) ++ if (WARN_ON(IS_ERR_OR_NULL(ptr))) + return; + + for (i = 0; i < dwords; i++) { +diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c +index a424afdcc77a1..35771e0e69fa6 100644 +--- a/drivers/gpu/drm/panel/panel-simple.c ++++ b/drivers/gpu/drm/panel/panel-simple.c +@@ -405,8 +405,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = { + .num_modes = 1, + .bpc = 8, + .size = { +- .width = 105, +- .height = 67, ++ .width = 99, ++ .height = 58, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + }; +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index 90c1afe498bea..ce8b14592b69b 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -5552,6 +5552,7 @@ static int ci_parse_power_table(struct radeon_device *rdev) + u8 frev, crev; + u8 *power_state_offset; + struct ci_ps *ps; ++ int ret; + + if (!atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) +@@ -5581,11 +5582,15 @@ static int ci_parse_power_table(struct radeon_device *rdev) + non_clock_array_index = power_state->v2.nonClockInfoIndex; + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; +- if (!rdev->pm.power_state[i].clock_info) +- return -EINVAL; ++ if (!rdev->pm.power_state[i].clock_info) { ++ ret = -EINVAL; ++ goto err_free_ps; ++ } + ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); +- if (ps == NULL) +- return -ENOMEM; ++ if (ps == NULL) { ++ ret = -ENOMEM; ++ goto err_free_ps; ++ } + rdev->pm.dpm.ps[i].ps_priv = ps; + ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], + non_clock_info, +@@ -5625,6 +5630,12 @@ static int ci_parse_power_table(struct radeon_device *rdev) + } + + return 0; ++ ++err_free_ps: ++ for (i = 0; i < rdev->pm.dpm.num_ps; i++) ++ kfree(rdev->pm.dpm.ps[i].ps_priv); ++ kfree(rdev->pm.dpm.ps); ++ return ret; + } + + static int ci_get_vbios_boot_values(struct radeon_device *rdev, +@@ -5713,25 +5724,26 @@ int ci_dpm_init(struct radeon_device *rdev) + + ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); + if (ret) { +- ci_dpm_fini(rdev); ++ kfree(rdev->pm.dpm.priv); + return ret; + } + + ret = r600_get_platform_caps(rdev); + if (ret) { +- ci_dpm_fini(rdev); ++ kfree(rdev->pm.dpm.priv); + return ret; + } + + ret = r600_parse_extended_power_table(rdev); + if (ret) { +- ci_dpm_fini(rdev); ++ kfree(rdev->pm.dpm.priv); + return ret; + } + + ret = ci_parse_power_table(rdev); + if (ret) { +- ci_dpm_fini(rdev); ++ kfree(rdev->pm.dpm.priv); ++ r600_free_extended_power_table(rdev); + return ret; + } + +diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c +index 3eb7899a4035b..2c637e04dfebc 100644 +--- a/drivers/gpu/drm/radeon/cypress_dpm.c ++++ b/drivers/gpu/drm/radeon/cypress_dpm.c +@@ -558,8 +558,12 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev, + ASIC_INTERNAL_MEMORY_SS, vco_freq)) { + u32 reference_clock = rdev->clock.mpll.reference_freq; + u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); +- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); +- u32 clk_v = ss.percentage * ++ u32 clk_s, clk_v; ++ ++ if (!decoded_ref) ++ return -EINVAL; ++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate); ++ clk_v = ss.percentage * + (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); + + mpll_ss1 &= ~CLKV_MASK; +diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c +index a7273c01de34b..2a9d415400f79 100644 +--- a/drivers/gpu/drm/radeon/ni_dpm.c ++++ b/drivers/gpu/drm/radeon/ni_dpm.c +@@ -2239,8 +2239,12 @@ static int ni_populate_mclk_value(struct radeon_device *rdev, + ASIC_INTERNAL_MEMORY_SS, vco_freq)) { + u32 reference_clock = rdev->clock.mpll.reference_freq; + u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); +- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); +- u32 clk_v = ss.percentage * ++ u32 clk_s, clk_v; ++ ++ if (!decoded_ref) ++ return -EINVAL; ++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate); ++ clk_v = ss.percentage * + (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); + + mpll_ss1 &= ~CLKV_MASK; +diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c b/drivers/gpu/drm/radeon/rv740_dpm.c +index afd597ec50858..50290e93c79dc 100644 +--- a/drivers/gpu/drm/radeon/rv740_dpm.c ++++ b/drivers/gpu/drm/radeon/rv740_dpm.c +@@ -251,8 +251,12 @@ int rv740_populate_mclk_value(struct radeon_device *rdev, + ASIC_INTERNAL_MEMORY_SS, vco_freq)) { + u32 reference_clock = rdev->clock.mpll.reference_freq; + u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); +- u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); +- u32 clk_v = 0x40000 * ss.percentage * ++ u32 clk_s, clk_v; ++ ++ if (!decoded_ref) ++ return -EINVAL; ++ clk_s = reference_clock * 5 / (decoded_ref * ss.rate); ++ clk_v = 0x40000 * ss.percentage * + (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000); + + mpll_ss1 &= ~CLKV_MASK; +diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c +index 779ec8fdfae08..56dd2d6ba9e49 100644 +--- a/drivers/hwmon/nct7802.c ++++ b/drivers/hwmon/nct7802.c +@@ -698,7 +698,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, + if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ + return 0; + +- if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ ++ if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ + return 0; + + return attr->mode; +diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c +index 61ab462fd94cf..fe7642b916cfc 100644 +--- a/drivers/i2c/busses/i2c-rk3x.c ++++ b/drivers/i2c/busses/i2c-rk3x.c +@@ -421,7 +421,7 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) + { + unsigned int i; + unsigned int len = i2c->msg->len - i2c->processed; +- u32 uninitialized_var(val); ++ u32 val; + u8 byte; + + /* we only care for MBRF here. */ +diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c +index 03ce9b7d6456a..c1f85114ab812 100644 +--- a/drivers/i2c/busses/i2c-xiic.c ++++ b/drivers/i2c/busses/i2c-xiic.c +@@ -362,6 +362,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id) + struct xiic_i2c *i2c = dev_id; + u32 pend, isr, ier; + u32 clr = 0; ++ int xfer_more = 0; ++ int wakeup_req = 0; ++ int wakeup_code = 0; + + /* Get the interrupt Status from the IPIF. There is no clearing of + * interrupts in the IPIF. Interrupts must be cleared at the source. +@@ -398,10 +401,16 @@ static irqreturn_t xiic_process(int irq, void *dev_id) + */ + xiic_reinit(i2c); + +- if (i2c->rx_msg) +- xiic_wakeup(i2c, STATE_ERROR); +- if (i2c->tx_msg) +- xiic_wakeup(i2c, STATE_ERROR); ++ if (i2c->rx_msg) { ++ wakeup_req = 1; ++ wakeup_code = STATE_ERROR; ++ } ++ if (i2c->tx_msg) { ++ wakeup_req = 1; ++ wakeup_code = STATE_ERROR; ++ } ++ /* don't try to handle other events */ ++ goto out; + } + if (pend & XIIC_INTR_RX_FULL_MASK) { + /* Receive register/FIFO is full */ +@@ -435,8 +444,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) + i2c->tx_msg++; + dev_dbg(i2c->adap.dev.parent, + "%s will start next...\n", __func__); +- +- __xiic_start_xfer(i2c); ++ xfer_more = 1; + } + } + } +@@ -450,11 +458,13 @@ static irqreturn_t xiic_process(int irq, void *dev_id) + if (!i2c->tx_msg) + goto out; + +- if ((i2c->nmsgs == 1) && !i2c->rx_msg && +- xiic_tx_space(i2c) == 0) +- xiic_wakeup(i2c, STATE_DONE); ++ wakeup_req = 1; ++ ++ if (i2c->nmsgs == 1 && !i2c->rx_msg && ++ xiic_tx_space(i2c) == 0) ++ wakeup_code = STATE_DONE; + else +- xiic_wakeup(i2c, STATE_ERROR); ++ wakeup_code = STATE_ERROR; + } + if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) { + /* Transmit register/FIFO is empty or ½ empty */ +@@ -478,7 +488,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) + if (i2c->nmsgs > 1) { + i2c->nmsgs--; + i2c->tx_msg++; +- __xiic_start_xfer(i2c); ++ xfer_more = 1; + } else { + xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); + +@@ -496,6 +506,13 @@ out: + dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); + + xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); ++ if (xfer_more) ++ __xiic_start_xfer(i2c); ++ if (wakeup_req) ++ xiic_wakeup(i2c, wakeup_code); ++ ++ WARN_ON(xfer_more && wakeup_req); ++ + mutex_unlock(&i2c->lock); + return IRQ_HANDLED; + } +diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c +index 7d4e5c08f133e..05e18d6581416 100644 +--- a/drivers/ide/ide-acpi.c ++++ b/drivers/ide/ide-acpi.c +@@ -180,7 +180,7 @@ err: + static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) + { + struct device *dev = hwif->gendev.parent; +- acpi_handle uninitialized_var(dev_handle); ++ acpi_handle dev_handle; + u64 pcidevfn; + acpi_handle chan_handle; + int err; +diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c +index 4224c4dd89635..9a4c094c897c3 100644 +--- a/drivers/ide/ide-atapi.c ++++ b/drivers/ide/ide-atapi.c +@@ -591,7 +591,7 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive) + + static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) + { +- struct ide_atapi_pc *uninitialized_var(pc); ++ struct ide_atapi_pc *pc; + ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->rq; + ide_expiry_t *expiry; +diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c +index 19763977568c5..508f98ca3fe87 100644 +--- a/drivers/ide/ide-io-std.c ++++ b/drivers/ide/ide-io-std.c +@@ -172,7 +172,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + + if (io_32bit) { +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + + if ((io_32bit & 2) && !mmio) { + local_irq_save(flags); +@@ -216,7 +216,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, + u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + + if (io_32bit) { +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + + if ((io_32bit & 2) && !mmio) { + local_irq_save(flags); +diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c +index 4381760846109..a01cc01244422 100644 +--- a/drivers/ide/ide-io.c ++++ b/drivers/ide/ide-io.c +@@ -605,12 +605,12 @@ static int drive_is_ready(ide_drive_t *drive) + void ide_timer_expiry (struct timer_list *t) + { + ide_hwif_t *hwif = from_timer(hwif, t, timer); +- ide_drive_t *uninitialized_var(drive); ++ ide_drive_t *drive; + ide_handler_t *handler; + unsigned long flags; + int wait = -1; + int plug_device = 0; +- struct request *uninitialized_var(rq_in_flight); ++ struct request *rq_in_flight; + + spin_lock_irqsave(&hwif->lock, flags); + +@@ -763,13 +763,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) + { + ide_hwif_t *hwif = (ide_hwif_t *)dev_id; + struct ide_host *host = hwif->host; +- ide_drive_t *uninitialized_var(drive); ++ ide_drive_t *drive; + ide_handler_t *handler; + unsigned long flags; + ide_startstop_t startstop; + irqreturn_t irq_ret = IRQ_NONE; + int plug_device = 0; +- struct request *uninitialized_var(rq_in_flight); ++ struct request *rq_in_flight; + + if (host->host_flags & IDE_HFLAG_SERIALIZE) { + if (hwif != host->cur_port) +diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c +index b9dfeb2e8bd66..c08a8a0916e22 100644 +--- a/drivers/ide/ide-sysfs.c ++++ b/drivers/ide/ide-sysfs.c +@@ -131,7 +131,7 @@ static struct device_attribute *ide_port_attrs[] = { + + int ide_sysfs_register_port(ide_hwif_t *hwif) + { +- int i, uninitialized_var(rc); ++ int i, rc; + + for (i = 0; ide_port_attrs[i]; i++) { + rc = device_create_file(hwif->portdev, ide_port_attrs[i]); +diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c +index 3aa0fea0f3d9c..1414caa97b401 100644 +--- a/drivers/ide/umc8672.c ++++ b/drivers/ide/umc8672.c +@@ -107,7 +107,7 @@ static void umc_set_speeds(u8 speeds[]) + static void umc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) + { + ide_hwif_t *mate = hwif->mate; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + const u8 pio = drive->pio_mode - XFER_PIO_0; + + printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", +diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c +index 6e0ef9bb2497f..c448769357501 100644 +--- a/drivers/iio/adc/meson_saradc.c ++++ b/drivers/iio/adc/meson_saradc.c +@@ -75,7 +75,7 @@ + #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) + #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) + #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 +- #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 ++ #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 6 + #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) + #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0) + +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index d28e6f6ad497c..3b287a51cd626 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -1726,7 +1726,7 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file, + struct ib_udata udata; + struct ib_uqp_object *obj; + struct ib_xrcd *xrcd; +- struct ib_uobject *uninitialized_var(xrcd_uobj); ++ struct ib_uobject *xrcd_uobj; + struct ib_qp *qp; + struct ib_qp_open_attr attr; + int ret; +@@ -3694,7 +3694,7 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file, + struct ib_usrq_object *obj; + struct ib_pd *pd; + struct ib_srq *srq; +- struct ib_uobject *uninitialized_var(xrcd_uobj); ++ struct ib_uobject *xrcd_uobj; + struct ib_srq_init_attr attr; + int ret; + struct ib_device *ib_dev; +diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c +index 6c1a093b164e0..a252b13958b3b 100644 +--- a/drivers/infiniband/hw/cxgb4/cm.c ++++ b/drivers/infiniband/hw/cxgb4/cm.c +@@ -3195,7 +3195,7 @@ static int get_lladdr(struct net_device *dev, struct in6_addr *addr, + + static int pick_local_ip6addrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id) + { +- struct in6_addr uninitialized_var(addr); ++ struct in6_addr addr; + struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&cm_id->m_local_addr; + struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr; + +diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c +index 43c611aa068c7..8f30d477ab769 100644 +--- a/drivers/infiniband/hw/cxgb4/cq.c ++++ b/drivers/infiniband/hw/cxgb4/cq.c +@@ -755,7 +755,7 @@ skip_cqe: + static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp, + struct ib_wc *wc, struct c4iw_srq *srq) + { +- struct t4_cqe uninitialized_var(cqe); ++ struct t4_cqe cqe; + struct t4_wq *wq = qhp ? &qhp->wq : NULL; + u32 credit = 0; + u8 cqe_flushed; +diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c +index 33ff9eca28f69..245f9505a9aca 100644 +--- a/drivers/infiniband/hw/hfi1/sdma.c ++++ b/drivers/infiniband/hw/hfi1/sdma.c +@@ -3202,8 +3202,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) + { + int rval = 0; + +- tx->num_desc++; +- if ((unlikely(tx->num_desc == tx->desc_limit))) { ++ if ((unlikely(tx->num_desc + 1 == tx->desc_limit))) { + rval = _extend_sdma_tx_descs(dd, tx); + if (rval) { + __sdma_txclean(dd, tx); +@@ -3216,6 +3215,7 @@ int _pad_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) + SDMA_MAP_NONE, + dd->sdma_pad_phys, + sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); ++ tx->num_desc++; + _sdma_close_tx(dd, tx); + return rval; + } +diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h +index 46c775f255d14..a3dd2f3d56cca 100644 +--- a/drivers/infiniband/hw/hfi1/sdma.h ++++ b/drivers/infiniband/hw/hfi1/sdma.h +@@ -680,14 +680,13 @@ static inline void sdma_txclean(struct hfi1_devdata *dd, struct sdma_txreq *tx) + static inline void _sdma_close_tx(struct hfi1_devdata *dd, + struct sdma_txreq *tx) + { +- tx->descp[tx->num_desc].qw[0] |= +- SDMA_DESC0_LAST_DESC_FLAG; +- tx->descp[tx->num_desc].qw[1] |= +- dd->default_desc1; ++ u16 last_desc = tx->num_desc - 1; ++ ++ tx->descp[last_desc].qw[0] |= SDMA_DESC0_LAST_DESC_FLAG; ++ tx->descp[last_desc].qw[1] |= dd->default_desc1; + if (tx->flags & SDMA_TXREQ_F_URGENT) +- tx->descp[tx->num_desc].qw[1] |= +- (SDMA_DESC1_HEAD_TO_HOST_FLAG | +- SDMA_DESC1_INT_REQ_FLAG); ++ tx->descp[last_desc].qw[1] |= (SDMA_DESC1_HEAD_TO_HOST_FLAG | ++ SDMA_DESC1_INT_REQ_FLAG); + } + + static inline int _sdma_txadd_daddr( +@@ -704,6 +703,7 @@ static inline int _sdma_txadd_daddr( + type, + addr, len); + WARN_ON(len > tx->tlen); ++ tx->num_desc++; + tx->tlen -= len; + /* special cases for last */ + if (!tx->tlen) { +@@ -715,7 +715,6 @@ static inline int _sdma_txadd_daddr( + _sdma_close_tx(dd, tx); + } + } +- tx->num_desc++; + return rval; + } + +diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c +index 87358b8c45589..b48596e174d65 100644 +--- a/drivers/infiniband/hw/mlx4/qp.c ++++ b/drivers/infiniband/hw/mlx4/qp.c +@@ -554,15 +554,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, + return (-EOPNOTSUPP); + } + +- if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | +- MLX4_IB_RX_HASH_DST_IPV4 | +- MLX4_IB_RX_HASH_SRC_IPV6 | +- MLX4_IB_RX_HASH_DST_IPV6 | +- MLX4_IB_RX_HASH_SRC_PORT_TCP | +- MLX4_IB_RX_HASH_DST_PORT_TCP | +- MLX4_IB_RX_HASH_SRC_PORT_UDP | +- MLX4_IB_RX_HASH_DST_PORT_UDP | +- MLX4_IB_RX_HASH_INNER)) { ++ if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | ++ MLX4_IB_RX_HASH_DST_IPV4 | ++ MLX4_IB_RX_HASH_SRC_IPV6 | ++ MLX4_IB_RX_HASH_DST_IPV6 | ++ MLX4_IB_RX_HASH_SRC_PORT_TCP | ++ MLX4_IB_RX_HASH_DST_PORT_TCP | ++ MLX4_IB_RX_HASH_SRC_PORT_UDP | ++ MLX4_IB_RX_HASH_DST_PORT_UDP | ++ MLX4_IB_RX_HASH_INNER)) { + pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", + ucmd->rx_hash_fields_mask); + return (-EOPNOTSUPP); +@@ -3463,11 +3463,11 @@ static int _mlx4_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, + int nreq; + int err = 0; + unsigned ind; +- int uninitialized_var(size); +- unsigned uninitialized_var(seglen); ++ int size; ++ unsigned seglen; + __be32 dummy; + __be32 *lso_wqe; +- __be32 uninitialized_var(lso_hdr_sz); ++ __be32 lso_hdr_sz; + __be32 blh; + int i; + struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); +diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c +index 872985e4eebec..c5d3fe256182f 100644 +--- a/drivers/infiniband/hw/mlx5/cq.c ++++ b/drivers/infiniband/hw/mlx5/cq.c +@@ -1333,7 +1333,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata) + __be64 *pas; + int page_shift; + int inlen; +- int uninitialized_var(cqe_size); ++ int cqe_size; + unsigned long flags; + + if (!MLX5_CAP_GEN(dev->mdev, cq_resize)) { +diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c +index 3d37f2373d63a..a336f69c2653a 100644 +--- a/drivers/infiniband/hw/mthca/mthca_qp.c ++++ b/drivers/infiniband/hw/mthca/mthca_qp.c +@@ -1630,8 +1630,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, + * without initializing f0 and size0, and they are in fact + * never used uninitialized. + */ +- int uninitialized_var(size0); +- u32 uninitialized_var(f0); ++ int size0; ++ u32 f0; + int ind; + u8 op0 = 0; + +@@ -1831,7 +1831,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, const struct ib_recv_wr *wr, + * without initializing size0, and it is in fact never used + * uninitialized. + */ +- int uninitialized_var(size0); ++ int size0; + int ind; + void *wqe; + void *prev_wqe; +@@ -1945,8 +1945,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, + * without initializing f0 and size0, and they are in fact + * never used uninitialized. + */ +- int uninitialized_var(size0); +- u32 uninitialized_var(f0); ++ int size0; ++ u32 f0; + int ind; + u8 op0 = 0; + +diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c +index 3695dd7dbb9b4..ec0c91ec52277 100644 +--- a/drivers/input/misc/adxl34x.c ++++ b/drivers/input/misc/adxl34x.c +@@ -811,8 +811,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, + AC_WRITE(ac, POWER_CTL, 0); + + err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, +- IRQF_TRIGGER_HIGH | IRQF_ONESHOT, +- dev_name(dev), ac); ++ IRQF_ONESHOT, dev_name(dev), ac); + if (err) { + dev_err(dev, "irq %d busy?\n", ac->irq); + goto err_free_mem; +diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c +index 17eb84ab4c0b7..fe3fbde989be2 100644 +--- a/drivers/input/misc/drv260x.c ++++ b/drivers/input/misc/drv260x.c +@@ -443,6 +443,7 @@ static int drv260x_init(struct drv260x_data *haptics) + } + + do { ++ usleep_range(15000, 15500); + error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); + if (error) { + dev_err(&haptics->client->dev, +diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c +index 17b7fbecd9fe7..d25059672323d 100644 +--- a/drivers/input/serio/serio_raw.c ++++ b/drivers/input/serio/serio_raw.c +@@ -162,7 +162,7 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer, + { + struct serio_raw_client *client = file->private_data; + struct serio_raw *serio_raw = client->serio_raw; +- char uninitialized_var(c); ++ char c; + ssize_t read = 0; + int error; + +diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c +index 31ea6332ecb83..60dc64b4ac6d2 100644 +--- a/drivers/irqchip/irq-bcm6345-l1.c ++++ b/drivers/irqchip/irq-bcm6345-l1.c +@@ -85,6 +85,7 @@ struct bcm6345_l1_chip { + }; + + struct bcm6345_l1_cpu { ++ struct bcm6345_l1_chip *intc; + void __iomem *map_base; + unsigned int parent_irq; + u32 enable_cache[]; +@@ -118,17 +119,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc, + + static void bcm6345_l1_irq_handle(struct irq_desc *desc) + { +- struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); +- struct bcm6345_l1_cpu *cpu; ++ struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); ++ struct bcm6345_l1_chip *intc = cpu->intc; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int idx; + +-#ifdef CONFIG_SMP +- cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; +-#else +- cpu = intc->cpus[0]; +-#endif +- + chained_irq_enter(chip, desc); + + for (idx = 0; idx < intc->n_words; idx++) { +@@ -260,6 +255,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + if (!cpu) + return -ENOMEM; + ++ cpu->intc = intc; + cpu->map_base = ioremap(res.start, sz); + if (!cpu->map_base) + return -ENOMEM; +@@ -275,7 +271,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, + return -EINVAL; + } + irq_set_chained_handler_and_data(cpu->parent_irq, +- bcm6345_l1_irq_handle, intc); ++ bcm6345_l1_irq_handle, cpu); + + return 0; + } +diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c +index 033bccb41455c..b9dcc8e78c750 100644 +--- a/drivers/irqchip/irq-jcore-aic.c ++++ b/drivers/irqchip/irq-jcore-aic.c +@@ -68,6 +68,7 @@ static int __init aic_irq_of_init(struct device_node *node, + unsigned min_irq = JCORE_AIC2_MIN_HWIRQ; + unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1; + struct irq_domain *domain; ++ int ret; + + pr_info("Initializing J-Core AIC\n"); + +@@ -100,11 +101,17 @@ static int __init aic_irq_of_init(struct device_node *node, + jcore_aic.irq_unmask = noop; + jcore_aic.name = "AIC"; + +- domain = irq_domain_add_linear(node, dom_sz, &jcore_aic_irqdomain_ops, ++ ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq, ++ of_node_to_nid(node)); ++ ++ if (ret < 0) ++ return ret; ++ ++ domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq, ++ &jcore_aic_irqdomain_ops, + &jcore_aic); + if (!domain) + return -ENOMEM; +- irq_create_strict_mappings(domain, min_irq, min_irq, dom_sz - min_irq); + + return 0; + } +diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c +index 01e9e462512b7..eb1e9771037f2 100644 +--- a/drivers/mailbox/ti-msgmgr.c ++++ b/drivers/mailbox/ti-msgmgr.c +@@ -385,14 +385,20 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) + /* Ensure all unused data is 0 */ + data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); + writel(data_trail, data_reg); +- data_reg++; ++ data_reg += sizeof(u32); + } ++ + /* + * 'data_reg' indicates next register to write. If we did not already + * write on tx complete reg(last reg), we must do so for transmit ++ * In addition, we also need to make sure all intermediate data ++ * registers(if any required), are reset to 0 for TISCI backward ++ * compatibility to be maintained. + */ +- if (data_reg <= qinst->queue_buff_end) +- writel(0, qinst->queue_buff_end); ++ while (data_reg <= qinst->queue_buff_end) { ++ writel(0, data_reg); ++ data_reg += sizeof(u32); ++ } + + return 0; + } +diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c +index 46794cac167e7..5310e1f4a2826 100644 +--- a/drivers/md/bcache/alloc.c ++++ b/drivers/md/bcache/alloc.c +@@ -49,7 +49,7 @@ + * + * bch_bucket_alloc() allocates a single bucket from a specific cache. + * +- * bch_bucket_alloc_set() allocates one or more buckets from different caches ++ * bch_bucket_alloc_set() allocates one bucket from different caches + * out of a cache set. + * + * free_some_buckets() drives all the processes described above. It's called +@@ -488,34 +488,29 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k) + } + + int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait) ++ struct bkey *k, bool wait) + { +- int i; ++ struct cache *ca; ++ long b; + + /* No allocation if CACHE_SET_IO_DISABLE bit is set */ + if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) + return -1; + + lockdep_assert_held(&c->bucket_lock); +- BUG_ON(!n || n > c->caches_loaded || n > 8); + + bkey_init(k); + +- /* sort by free space/prio of oldest data in caches */ +- +- for (i = 0; i < n; i++) { +- struct cache *ca = c->cache_by_alloc[i]; +- long b = bch_bucket_alloc(ca, reserve, wait); ++ ca = c->cache_by_alloc[0]; ++ b = bch_bucket_alloc(ca, reserve, wait); ++ if (b == -1) ++ goto err; + +- if (b == -1) +- goto err; ++ k->ptr[0] = MAKE_PTR(ca->buckets[b].gen, ++ bucket_to_sector(c, b), ++ ca->sb.nr_this_dev); + +- k->ptr[i] = MAKE_PTR(ca->buckets[b].gen, +- bucket_to_sector(c, b), +- ca->sb.nr_this_dev); +- +- SET_KEY_PTRS(k, i + 1); +- } ++ SET_KEY_PTRS(k, 1); + + return 0; + err: +@@ -525,12 +520,12 @@ err: + } + + int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait) ++ struct bkey *k, bool wait) + { + int ret; + + mutex_lock(&c->bucket_lock); +- ret = __bch_bucket_alloc_set(c, reserve, k, n, wait); ++ ret = __bch_bucket_alloc_set(c, reserve, k, wait); + mutex_unlock(&c->bucket_lock); + return ret; + } +@@ -638,7 +633,7 @@ bool bch_alloc_sectors(struct cache_set *c, + + spin_unlock(&c->data_bucket_lock); + +- if (bch_bucket_alloc_set(c, watermark, &alloc.key, 1, wait)) ++ if (bch_bucket_alloc_set(c, watermark, &alloc.key, wait)) + return false; + + spin_lock(&c->data_bucket_lock); +diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h +index 6a380ed4919a0..e81d783109847 100644 +--- a/drivers/md/bcache/bcache.h ++++ b/drivers/md/bcache/bcache.h +@@ -952,9 +952,9 @@ void bch_bucket_free(struct cache_set *c, struct bkey *k); + + long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait); + int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait); ++ struct bkey *k, bool wait); + int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, +- struct bkey *k, int n, bool wait); ++ struct bkey *k, bool wait); + bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, + unsigned int sectors, unsigned int write_point, + unsigned int write_prio, bool wait); +diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c +index e388e7bb7b5db..71d670934a07e 100644 +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -1125,11 +1125,13 @@ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, + struct btree *parent) + { + BKEY_PADDED(key) k; +- struct btree *b = ERR_PTR(-EAGAIN); ++ struct btree *b; + + mutex_lock(&c->bucket_lock); + retry: +- if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, wait)) ++ /* return ERR_PTR(-EAGAIN) when it fails */ ++ b = ERR_PTR(-EAGAIN); ++ if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) + goto err; + + bkey_put(c, &k.key); +@@ -1174,7 +1176,7 @@ static struct btree *btree_node_alloc_replacement(struct btree *b, + { + struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent); + +- if (!IS_ERR_OR_NULL(n)) { ++ if (!IS_ERR(n)) { + mutex_lock(&n->write_lock); + bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort); + bkey_copy_key(&n->key, &b->key); +@@ -1377,7 +1379,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, + memset(new_nodes, 0, sizeof(new_nodes)); + closure_init_stack(&cl); + +- while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b)) ++ while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b)) + keys += r[nodes++].keys; + + blocks = btree_default_blocks(b->c) * 2 / 3; +@@ -1389,7 +1391,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, + + for (i = 0; i < nodes; i++) { + new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL); +- if (IS_ERR_OR_NULL(new_nodes[i])) ++ if (IS_ERR(new_nodes[i])) + goto out_nocoalesce; + } + +@@ -1524,7 +1526,7 @@ out_nocoalesce: + atomic_dec(&b->c->prio_blocked); + + for (i = 0; i < nodes; i++) +- if (!IS_ERR_OR_NULL(new_nodes[i])) { ++ if (!IS_ERR(new_nodes[i])) { + btree_node_free(new_nodes[i]); + rw_unlock(true, new_nodes[i]); + } +@@ -1706,7 +1708,7 @@ static int bch_btree_gc_root(struct btree *b, struct btree_op *op, + if (should_rewrite) { + n = btree_node_alloc_replacement(b, NULL); + +- if (!IS_ERR_OR_NULL(n)) { ++ if (!IS_ERR(n)) { + bch_btree_node_write_sync(n); + + bch_btree_set_root(n); +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 2df75db52e917..4b076f7f184be 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -423,7 +423,7 @@ static int __uuid_write(struct cache_set *c) + closure_init_stack(&cl); + lockdep_assert_held(&bch_register_lock); + +- if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, true)) ++ if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, true)) + return 1; + + SET_KEY_SIZE(&k.key, c->sb.bucket_size); +@@ -1576,7 +1576,7 @@ static void cache_set_flush(struct closure *cl) + if (!IS_ERR_OR_NULL(c->gc_thread)) + kthread_stop(c->gc_thread); + +- if (!IS_ERR_OR_NULL(c->root)) ++ if (!IS_ERR(c->root)) + list_add(&c->root->list, &c->btree_cache); + + /* Should skip this if we're unregistering because of an error */ +@@ -1921,7 +1921,7 @@ static int run_cache_set(struct cache_set *c) + + err = "cannot allocate new btree root"; + c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL); +- if (IS_ERR_OR_NULL(c->root)) ++ if (IS_ERR(c->root)) + goto err; + + mutex_lock(&c->root->write_lock); +diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c +index 1b5b9ad9e492f..6030193b216eb 100644 +--- a/drivers/md/dm-cache-policy-smq.c ++++ b/drivers/md/dm-cache-policy-smq.c +@@ -854,7 +854,13 @@ struct smq_policy { + + struct background_tracker *bg_work; + +- bool migrations_allowed; ++ bool migrations_allowed:1; ++ ++ /* ++ * If this is set the policy will try and clean the whole cache ++ * even if the device is not idle. ++ */ ++ bool cleaner:1; + }; + + /*----------------------------------------------------------------*/ +@@ -1133,7 +1139,7 @@ static bool clean_target_met(struct smq_policy *mq, bool idle) + * Cache entries may not be populated. So we cannot rely on the + * size of the clean queue. + */ +- if (idle) { ++ if (idle || mq->cleaner) { + /* + * We'd like to clean everything. + */ +@@ -1716,11 +1722,9 @@ static void calc_hotspot_params(sector_t origin_size, + *hotspot_block_size /= 2u; + } + +-static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, +- sector_t origin_size, +- sector_t cache_block_size, +- bool mimic_mq, +- bool migrations_allowed) ++static struct dm_cache_policy * ++__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size, ++ bool mimic_mq, bool migrations_allowed, bool cleaner) + { + unsigned i; + unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; +@@ -1807,6 +1811,7 @@ static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, + goto bad_btracker; + + mq->migrations_allowed = migrations_allowed; ++ mq->cleaner = cleaner; + + return &mq->policy; + +@@ -1830,21 +1835,24 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, false, true); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ false, true, false); + } + + static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, true, true); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ true, true, false); + } + + static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size, + sector_t origin_size, + sector_t cache_block_size) + { +- return __smq_create(cache_size, origin_size, cache_block_size, false, false); ++ return __smq_create(cache_size, origin_size, cache_block_size, ++ false, false, true); + } + + /*----------------------------------------------------------------*/ +diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c +index 81ffc59d05c90..4312007d2d34b 100644 +--- a/drivers/md/dm-io.c ++++ b/drivers/md/dm-io.c +@@ -306,7 +306,7 @@ static void do_region(int op, int op_flags, unsigned region, + struct request_queue *q = bdev_get_queue(where->bdev); + unsigned short logical_block_size = queue_logical_block_size(q); + sector_t num_sectors; +- unsigned int uninitialized_var(special_cmd_max_sectors); ++ unsigned int special_cmd_max_sectors; + + /* + * Reject unsupported discard and write same requests. +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index e1603c17e346f..88e89796ccbff 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1822,7 +1822,7 @@ static int ctl_ioctl(struct file *file, uint command, struct dm_ioctl __user *us + int ioctl_flags; + int param_flags; + unsigned int cmd; +- struct dm_ioctl *uninitialized_var(param); ++ struct dm_ioctl *param; + ioctl_fn fn = NULL; + size_t input_param_size; + struct dm_ioctl param_kernel; +diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c +index 5c45100f6d53e..72aa5097b68ff 100644 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -3289,15 +3289,19 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) + /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ + if (rs_is_raid456(rs)) { + r = rs_set_raid456_stripe_cache(rs); +- if (r) ++ if (r) { ++ mddev_unlock(&rs->md); + goto bad_stripe_cache; ++ } + } + + /* Now do an early reshape check */ + if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { + r = rs_check_reshape(rs); +- if (r) ++ if (r) { ++ mddev_unlock(&rs->md); + goto bad_check_reshape; ++ } + + /* Restore new, ctr requested layout to perform check */ + rs_config_restore(rs, &rs_layout); +@@ -3306,6 +3310,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) + r = rs->md.pers->check_reshape(&rs->md); + if (r) { + ti->error = "Reshape check failed"; ++ mddev_unlock(&rs->md); + goto bad_check_reshape; + } + } +diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c +index 963d3774c93e2..247089c2be256 100644 +--- a/drivers/md/dm-snap-persistent.c ++++ b/drivers/md/dm-snap-persistent.c +@@ -613,7 +613,7 @@ static int persistent_read_metadata(struct dm_exception_store *store, + chunk_t old, chunk_t new), + void *callback_context) + { +- int r, uninitialized_var(new_snapshot); ++ int r, new_snapshot; + struct pstore *ps = get_info(store); + + /* +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index 71d3fdbce50a3..3faaf21be5b65 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -671,7 +671,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table, + */ + unsigned short remaining = 0; + +- struct dm_target *uninitialized_var(ti); ++ struct dm_target *ti; + struct queue_limits ti_limits; + unsigned i; + +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index 1c4c462787198..7ca81e917aef4 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -53,14 +53,7 @@ __acquires(bitmap->lock) + { + unsigned char *mappage; + +- if (page >= bitmap->pages) { +- /* This can happen if bitmap_start_sync goes beyond +- * End-of-device while looking for a whole page. +- * It is harmless. +- */ +- return -EINVAL; +- } +- ++ WARN_ON_ONCE(page >= bitmap->pages); + if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ + return 0; + +@@ -1368,6 +1361,14 @@ __acquires(bitmap->lock) + sector_t csize; + int err; + ++ if (page >= bitmap->pages) { ++ /* ++ * This can happen if bitmap_start_sync goes beyond ++ * End-of-device while looking for a whole page or ++ * user set a huge number to sysfs bitmap_set_bits. ++ */ ++ return NULL; ++ } + err = md_bitmap_checkpage(bitmap, page, create, 0); + + if (bitmap->bp[page].hijacked || +diff --git a/drivers/md/md.c b/drivers/md/md.c +index f8c111b369928..6b074c2202d5a 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -3671,8 +3671,9 @@ int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale) + static ssize_t + safe_delay_show(struct mddev *mddev, char *page) + { +- int msec = (mddev->safemode_delay*1000)/HZ; +- return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); ++ unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ; ++ ++ return sprintf(page, "%u.%03u\n", msec/1000, msec%1000); + } + static ssize_t + safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) +@@ -3684,7 +3685,7 @@ safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) + return -EINVAL; + } + +- if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) ++ if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) + return -EINVAL; + if (msec == 0) + mddev->safemode_delay = 0; +@@ -4336,6 +4337,8 @@ max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len + rv = kstrtouint(buf, 10, &n); + if (rv < 0) + return rv; ++ if (n > INT_MAX) ++ return -EINVAL; + atomic_set(&mddev->max_corr_read_errors, n); + return len; + } +@@ -4636,11 +4639,21 @@ action_store(struct mddev *mddev, const char *page, size_t len) + return -EINVAL; + err = mddev_lock(mddev); + if (!err) { +- if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) ++ if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { + err = -EBUSY; +- else { ++ } else if (mddev->reshape_position == MaxSector || ++ mddev->pers->check_reshape == NULL || ++ mddev->pers->check_reshape(mddev)) { + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + err = mddev->pers->start_reshape(mddev); ++ } else { ++ /* ++ * If reshape is still in progress, and ++ * md_check_recovery() can continue to reshape, ++ * don't restart reshape because data can be ++ * corrupted for raid456. ++ */ ++ clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + } + mddev_unlock(mddev); + } +diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c +index 252ef0eab41cb..6f5710e833c1b 100644 +--- a/drivers/md/raid0.c ++++ b/drivers/md/raid0.c +@@ -296,6 +296,18 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) + goto abort; + } + ++ if (conf->layout == RAID0_ORIG_LAYOUT) { ++ for (i = 1; i < conf->nr_strip_zones; i++) { ++ sector_t first_sector = conf->strip_zone[i-1].zone_end; ++ ++ sector_div(first_sector, mddev->chunk_sectors); ++ zone = conf->strip_zone + i; ++ /* disk_shift is first disk index used in the zone */ ++ zone->disk_shift = sector_div(first_sector, ++ zone->nb_dev); ++ } ++ } ++ + pr_debug("md/raid0:%s: done.\n", mdname(mddev)); + *private_conf = conf; + +@@ -482,6 +494,20 @@ static inline int is_io_in_chunk_boundary(struct mddev *mddev, + } + } + ++/* ++ * Convert disk_index to the disk order in which it is read/written. ++ * For example, if we have 4 disks, they are numbered 0,1,2,3. If we ++ * write the disks starting at disk 3, then the read/write order would ++ * be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift() ++ * to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map ++ * to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in ++ * that 'output' space to understand the read/write disk ordering. ++ */ ++static int map_disk_shift(int disk_index, int num_disks, int disk_shift) ++{ ++ return ((disk_index + num_disks - disk_shift) % num_disks); ++} ++ + static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + { + struct r0conf *conf = mddev->private; +@@ -495,7 +521,9 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + sector_t end_disk_offset; + unsigned int end_disk_index; + unsigned int disk; ++ sector_t orig_start, orig_end; + ++ orig_start = start; + zone = find_zone(conf, &start); + + if (bio_end_sector(bio) > zone->zone_end) { +@@ -509,6 +537,7 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + } else + end = bio_end_sector(bio); + ++ orig_end = end; + if (zone != conf->strip_zone) + end = end - zone[-1].zone_end; + +@@ -520,13 +549,26 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + last_stripe_index = end; + sector_div(last_stripe_index, stripe_size); + +- start_disk_index = (int)(start - first_stripe_index * stripe_size) / +- mddev->chunk_sectors; ++ /* In the first zone the original and alternate layouts are the same */ ++ if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) { ++ sector_div(orig_start, mddev->chunk_sectors); ++ start_disk_index = sector_div(orig_start, zone->nb_dev); ++ start_disk_index = map_disk_shift(start_disk_index, ++ zone->nb_dev, ++ zone->disk_shift); ++ sector_div(orig_end, mddev->chunk_sectors); ++ end_disk_index = sector_div(orig_end, zone->nb_dev); ++ end_disk_index = map_disk_shift(end_disk_index, ++ zone->nb_dev, zone->disk_shift); ++ } else { ++ start_disk_index = (int)(start - first_stripe_index * stripe_size) / ++ mddev->chunk_sectors; ++ end_disk_index = (int)(end - last_stripe_index * stripe_size) / ++ mddev->chunk_sectors; ++ } + start_disk_offset = ((int)(start - first_stripe_index * stripe_size) % + mddev->chunk_sectors) + + first_stripe_index * mddev->chunk_sectors; +- end_disk_index = (int)(end - last_stripe_index * stripe_size) / +- mddev->chunk_sectors; + end_disk_offset = ((int)(end - last_stripe_index * stripe_size) % + mddev->chunk_sectors) + + last_stripe_index * mddev->chunk_sectors; +@@ -535,18 +577,22 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + sector_t dev_start, dev_end; + struct bio *discard_bio = NULL; + struct md_rdev *rdev; ++ int compare_disk; ++ ++ compare_disk = map_disk_shift(disk, zone->nb_dev, ++ zone->disk_shift); + +- if (disk < start_disk_index) ++ if (compare_disk < start_disk_index) + dev_start = (first_stripe_index + 1) * + mddev->chunk_sectors; +- else if (disk > start_disk_index) ++ else if (compare_disk > start_disk_index) + dev_start = first_stripe_index * mddev->chunk_sectors; + else + dev_start = start_disk_offset; + +- if (disk < end_disk_index) ++ if (compare_disk < end_disk_index) + dev_end = (last_stripe_index + 1) * mddev->chunk_sectors; +- else if (disk > end_disk_index) ++ else if (compare_disk > end_disk_index) + dev_end = last_stripe_index * mddev->chunk_sectors; + else + dev_end = end_disk_offset; +diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h +index 3816e5477db1e..8cc761ca74230 100644 +--- a/drivers/md/raid0.h ++++ b/drivers/md/raid0.h +@@ -6,6 +6,7 @@ struct strip_zone { + sector_t zone_end; /* Start of the next zone (in sectors) */ + sector_t dev_start; /* Zone offset in real dev (in sectors) */ + int nb_dev; /* # of devices attached to the zone */ ++ int disk_shift; /* start disk for the original layout */ + }; + + /* Linux 3.14 (20d0189b101) made an unintended change to +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index f6d2be1d23864..bee694be20132 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -781,8 +781,16 @@ static struct md_rdev *read_balance(struct r10conf *conf, + disk = r10_bio->devs[slot].devnum; + rdev = rcu_dereference(conf->mirrors[disk].replacement); + if (rdev == NULL || test_bit(Faulty, &rdev->flags) || +- r10_bio->devs[slot].addr + sectors > rdev->recovery_offset) ++ r10_bio->devs[slot].addr + sectors > ++ rdev->recovery_offset) { ++ /* ++ * Read replacement first to prevent reading both rdev ++ * and replacement as NULL during replacement replace ++ * rdev. ++ */ ++ smp_mb(); + rdev = rcu_dereference(conf->mirrors[disk].rdev); ++ } + if (rdev == NULL || + test_bit(Faulty, &rdev->flags)) + continue; +@@ -934,6 +942,7 @@ static void flush_pending_writes(struct r10conf *conf) + else + generic_make_request(bio); + bio = next; ++ cond_resched(); + } + blk_finish_plug(&plug); + } else +@@ -1119,6 +1128,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) + else + generic_make_request(bio); + bio = next; ++ cond_resched(); + } + kfree(plug); + } +@@ -1400,9 +1410,15 @@ retry_write: + + for (i = 0; i < conf->copies; i++) { + int d = r10_bio->devs[i].devnum; +- struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev); +- struct md_rdev *rrdev = rcu_dereference( +- conf->mirrors[d].replacement); ++ struct md_rdev *rdev, *rrdev; ++ ++ rrdev = rcu_dereference(conf->mirrors[d].replacement); ++ /* ++ * Read replacement first to prevent reading both rdev and ++ * replacement as NULL during replacement replace rdev. ++ */ ++ smp_mb(); ++ rdev = rcu_dereference(conf->mirrors[d].rdev); + if (rdev == rrdev) + rrdev = NULL; + if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 7eeae0301ccc6..b98abe927d06b 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -2603,7 +2603,7 @@ static void raid5_end_write_request(struct bio *bi) + struct stripe_head *sh = bi->bi_private; + struct r5conf *conf = sh->raid_conf; + int disks = sh->disks, i; +- struct md_rdev *uninitialized_var(rdev); ++ struct md_rdev *rdev; + sector_t first_bad; + int bad_sectors; + int replacement = 0; +diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c +index 2f1f5cbaf03c4..7cad4e985315a 100644 +--- a/drivers/media/dvb-frontends/rtl2832.c ++++ b/drivers/media/dvb-frontends/rtl2832.c +@@ -653,7 +653,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) + struct i2c_client *client = dev->client; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + int ret; +- u32 uninitialized_var(tmp); ++ u32 tmp; + u8 u8tmp, buf[2]; + u16 u16tmp; + +diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c +index 4565c06b16176..6d397cc85428d 100644 +--- a/drivers/media/tuners/qt1010.c ++++ b/drivers/media/tuners/qt1010.c +@@ -224,7 +224,7 @@ static int qt1010_set_params(struct dvb_frontend *fe) + static int qt1010_init_meas1(struct qt1010_priv *priv, + u8 oper, u8 reg, u8 reg_init_val, u8 *retval) + { +- u8 i, val1, uninitialized_var(val2); ++ u8 i, val1, val2; + int err; + + qt1010_i2c_oper_t i2c_data[] = { +@@ -259,7 +259,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, + static int qt1010_init_meas2(struct qt1010_priv *priv, + u8 reg_init_val, u8 *retval) + { +- u8 i, uninitialized_var(val); ++ u8 i, val; + int err; + qt1010_i2c_oper_t i2c_data[] = { + { QT1010_WR, 0x07, reg_init_val }, +diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c +index 746926364535d..8e914be5b7c5e 100644 +--- a/drivers/media/usb/dvb-usb-v2/az6007.c ++++ b/drivers/media/usb/dvb-usb-v2/az6007.c +@@ -210,7 +210,8 @@ static int az6007_rc_query(struct dvb_usb_device *d) + unsigned code; + enum rc_proto proto; + +- az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); ++ if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0) ++ return -EIO; + + if (st->data[1] == 0x44) + return 0; +diff --git a/drivers/media/usb/gspca/vicam.c b/drivers/media/usb/gspca/vicam.c +index 8562bda0ef886..624fdcfdc85a6 100644 +--- a/drivers/media/usb/gspca/vicam.c ++++ b/drivers/media/usb/gspca/vicam.c +@@ -234,7 +234,7 @@ static int sd_init(struct gspca_dev *gspca_dev) + { + int ret; + const struct ihex_binrec *rec; +- const struct firmware *uninitialized_var(fw); ++ const struct firmware *fw; + u8 *firmware_buf; + + ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, +diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c +index 2df3d730ea768..cd706874899c3 100644 +--- a/drivers/media/usb/siano/smsusb.c ++++ b/drivers/media/usb/siano/smsusb.c +@@ -190,7 +190,8 @@ static void smsusb_stop_streaming(struct smsusb_device_t *dev) + + for (i = 0; i < MAX_URBS; i++) { + usb_kill_urb(&dev->surbs[i].urb); +- cancel_work_sync(&dev->surbs[i].wq); ++ if (dev->surbs[i].wq.func) ++ cancel_work_sync(&dev->surbs[i].wq); + + if (dev->surbs[i].cb) { + smscore_putbuffer(dev->coredev, dev->surbs[i].cb); +diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c +index 1c0249df52566..c57bc62251bb8 100644 +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -802,9 +802,9 @@ static void uvc_video_stats_decode(struct uvc_streaming *stream, + unsigned int header_size; + bool has_pts = false; + bool has_scr = false; +- u16 uninitialized_var(scr_sof); +- u32 uninitialized_var(scr_stc); +- u32 uninitialized_var(pts); ++ u16 scr_sof; ++ u32 scr_stc; ++ u32 pts; + + if (stream->stats.stream.nb_frames == 0 && + stream->stats.frame.nb_packets == 0) +@@ -1801,7 +1801,7 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) + struct usb_host_endpoint *best_ep = NULL; + unsigned int best_psize = UINT_MAX; + unsigned int bandwidth; +- unsigned int uninitialized_var(altsetting); ++ unsigned int altsetting; + int intfnum = stream->intfnum; + + /* Isochronous endpoint, select the alternate setting. */ +diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c +index 0610d3c9f1318..9f65db9a69b3d 100644 +--- a/drivers/memstick/host/jmb38x_ms.c ++++ b/drivers/memstick/host/jmb38x_ms.c +@@ -316,7 +316,7 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) + } + + while (length) { +- unsigned int uninitialized_var(p_off); ++ unsigned int p_off; + + if (host->req->long_data) { + pg = nth_page(sg_page(&host->req->sg), +diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c +index edb1b5588b7a0..6360f5c6d3958 100644 +--- a/drivers/memstick/host/r592.c ++++ b/drivers/memstick/host/r592.c +@@ -47,12 +47,10 @@ static const char *tpc_names[] = { + * memstick_debug_get_tpc_name - debug helper that returns string for + * a TPC number + */ +-const char *memstick_debug_get_tpc_name(int tpc) ++static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc) + { + return tpc_names[tpc-1]; + } +-EXPORT_SYMBOL(memstick_debug_get_tpc_name); +- + + /* Read a register*/ + static inline u32 r592_read_reg(struct r592_device *dev, int address) +diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c +index bed205849d027..ecd8d71f8a398 100644 +--- a/drivers/memstick/host/tifm_ms.c ++++ b/drivers/memstick/host/tifm_ms.c +@@ -200,7 +200,7 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) + host->block_pos); + + while (length) { +- unsigned int uninitialized_var(p_off); ++ unsigned int p_off; + + if (host->req->long_data) { + pg = nth_page(sg_page(&host->req->sg), +diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c +index fc44fb7c595bc..281ef5f52eb55 100644 +--- a/drivers/mfd/intel-lpss-acpi.c ++++ b/drivers/mfd/intel-lpss-acpi.c +@@ -92,6 +92,9 @@ static int intel_lpss_acpi_probe(struct platform_device *pdev) + return -ENOMEM; + + info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!info->mem) ++ return -ENODEV; ++ + info->irq = platform_get_irq(pdev, 0); + + ret = intel_lpss_probe(&pdev->dev, info); +diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c +index 9bd089c563753..94cdad91c0657 100644 +--- a/drivers/mfd/rt5033.c ++++ b/drivers/mfd/rt5033.c +@@ -44,9 +44,6 @@ static const struct mfd_cell rt5033_devs[] = { + { + .name = "rt5033-charger", + .of_compatible = "richtek,rt5033-charger", +- }, { +- .name = "rt5033-battery", +- .of_compatible = "richtek,rt5033-battery", + }, { + .name = "rt5033-led", + .of_compatible = "richtek,rt5033-led", +diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c +index 722ad2c368a56..d752c56d60e42 100644 +--- a/drivers/mfd/stmpe.c ++++ b/drivers/mfd/stmpe.c +@@ -1428,9 +1428,9 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) + + int stmpe_remove(struct stmpe *stmpe) + { +- if (!IS_ERR(stmpe->vio)) ++ if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) + regulator_disable(stmpe->vio); +- if (!IS_ERR(stmpe->vcc)) ++ if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) + regulator_disable(stmpe->vcc); + + mfd_remove_devices(stmpe->dev); +diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c +index 7d166f57f6242..e5b05e11675b4 100644 +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -601,6 +601,10 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, + struct pci_dev *pdev = test->pdev; + + mutex_lock(&test->mutex); ++ ++ reinit_completion(&test->irq_raised); ++ test->last_irq = -ENODATA; ++ + switch (cmd) { + case PCITEST_BAR: + bar = arg; +@@ -785,6 +789,9 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) + if (id < 0) + return; + ++ pci_endpoint_test_release_irq(test); ++ pci_endpoint_test_free_irq_vectors(test); ++ + misc_deregister(&test->miscdev); + kfree(misc_device->name); + ida_simple_remove(&pci_endpoint_test_ida, id); +@@ -793,9 +800,6 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) + pci_iounmap(pdev, test->bar[bar]); + } + +- pci_endpoint_test_release_irq(test); +- pci_endpoint_test_free_irq_vectors(test); +- + pci_release_regions(pdev); + pci_disable_device(pdev); + } +diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h +index d5bbe8e544de7..e35c204cdac11 100644 +--- a/drivers/mmc/core/quirks.h ++++ b/drivers/mmc/core/quirks.h +@@ -90,6 +90,20 @@ static const struct mmc_fixup mmc_blk_fixups[] = { + MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, + MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), + ++ /* ++ * Kingston EMMC04G-M627 advertises TRIM but it does not seems to ++ * support being used to offload WRITE_ZEROES. ++ */ ++ MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc, ++ MMC_QUIRK_TRIM_BROKEN), ++ ++ /* ++ * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to ++ * support being used to offload WRITE_ZEROES. ++ */ ++ MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc, ++ MMC_QUIRK_TRIM_BROKEN), ++ + /* + * On Some Kingston eMMCs, performing trim can result in + * unrecoverable data conrruption occasionally due to a firmware bug. +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index 57be129fe4f33..b7afbeeca08a3 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -374,7 +374,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) + { + unsigned long flags; + size_t blksize, len, chunk; +- u32 uninitialized_var(scratch); ++ u32 scratch; + u8 *buf; + + DBG("PIO reading\n"); +diff --git a/drivers/mtd/nand/raw/nand_ecc.c b/drivers/mtd/nand/raw/nand_ecc.c +index 8e132edbc5ce9..d1066f635e4c8 100644 +--- a/drivers/mtd/nand/raw/nand_ecc.c ++++ b/drivers/mtd/nand/raw/nand_ecc.c +@@ -144,7 +144,7 @@ void __nand_calculate_ecc(const unsigned char *buf, unsigned int eccsize, + /* rp0..rp15..rp17 are the various accumulated parities (per byte) */ + uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; + uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16; +- uint32_t uninitialized_var(rp17); /* to make compiler happy */ ++ uint32_t rp17; + uint32_t par; /* the cumulative parity for all data */ + uint32_t tmppar; /* the cumulative parity for this iteration; + for rp12, rp14 and rp16 at the end of the +diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c +index 6736777a41567..02d1740383120 100644 +--- a/drivers/mtd/nand/raw/omap_elm.c ++++ b/drivers/mtd/nand/raw/omap_elm.c +@@ -184,17 +184,17 @@ static void elm_load_syndrome(struct elm_info *info, + switch (info->bch_type) { + case BCH8_ECC: + /* syndrome fragment 0 = ecc[9-12B] */ +- val = cpu_to_be32(*(u32 *) &ecc[9]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 1 = ecc[5-8B] */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[5]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 2 = ecc[1-4B] */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[1]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]); + elm_write_reg(info, offset, val); + + /* syndrome fragment 3 = ecc[0B] */ +@@ -204,35 +204,35 @@ static void elm_load_syndrome(struct elm_info *info, + break; + case BCH4_ECC: + /* syndrome fragment 0 = ecc[20-52b] bits */ +- val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | ++ val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) | + ((ecc[2] & 0xf) << 28); + elm_write_reg(info, offset, val); + + /* syndrome fragment 1 = ecc[0-20b] bits */ + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12; + elm_write_reg(info, offset, val); + break; + case BCH16_ECC: +- val = cpu_to_be32(*(u32 *) &ecc[22]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[18]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[14]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[10]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[6]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[2]); ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]); + elm_write_reg(info, offset, val); + offset += 4; +- val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; ++ val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16; + elm_write_reg(info, offset, val); + break; + default: +diff --git a/drivers/mtd/nand/raw/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c +index cf045813c160a..83d3e3cb77ded 100644 +--- a/drivers/mtd/nand/raw/s3c2410.c ++++ b/drivers/mtd/nand/raw/s3c2410.c +@@ -304,7 +304,7 @@ static int s3c2410_nand_setrate(struct s3c2410_nand_info *info) + int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; + int tacls, twrph0, twrph1; + unsigned long clkrate = clk_get_rate(info->clk); +- unsigned long uninitialized_var(set), cfg, uninitialized_var(mask); ++ unsigned long set, cfg, mask; + unsigned long flags; + + /* calculate the timing information for the controller */ +diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c +index 3e25421f22a27..fa6ff75459c6e 100644 +--- a/drivers/mtd/ubi/eba.c ++++ b/drivers/mtd/ubi/eba.c +@@ -612,7 +612,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, + int err, pnum, scrub = 0, vol_id = vol->vol_id; + struct ubi_vid_io_buf *vidb; + struct ubi_vid_hdr *vid_hdr; +- uint32_t uninitialized_var(crc); ++ uint32_t crc; + + err = leb_read_lock(ubi, vol_id, lnum); + if (err) +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 4e4adacb5c2c1..47e02c5342b28 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1128,6 +1128,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev, + + memcpy(bond_dev->broadcast, slave_dev->broadcast, + slave_dev->addr_len); ++ ++ if (slave_dev->flags & IFF_POINTOPOINT) { ++ bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); ++ } + } + + /* On bonding slaves other than the currently active slave, suppress +diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c +index 02042cb09bd29..0e939a4cd9998 100644 +--- a/drivers/net/can/janz-ican3.c ++++ b/drivers/net/can/janz-ican3.c +@@ -1455,7 +1455,7 @@ static int ican3_napi(struct napi_struct *napi, int budget) + + /* process all communication messages */ + while (true) { +- struct ican3_msg uninitialized_var(msg); ++ struct ican3_msg msg; + ret = ican3_recv_msg(mod, &msg); + if (ret) + break; +diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c +index 62ca4964a863a..b2e48c8595f0f 100644 +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -740,6 +740,8 @@ static int gs_can_close(struct net_device *netdev) + usb_kill_anchored_urbs(&dev->tx_submitted); + atomic_set(&dev->active_tx_urbs, 0); + ++ dev->can.state = CAN_STATE_STOPPED; ++ + /* reset the device */ + rc = gs_cmd_reset(dev); + if (rc < 0) +diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +index 3164aad29bcf8..e4d58c7aeaf82 100644 +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -1651,8 +1651,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter, + real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + + ntohs(ip_hdr(skb)->tot_len)); + +- if (real_len < skb->len) +- pskb_trim(skb, real_len); ++ if (real_len < skb->len) { ++ err = pskb_trim(skb, real_len); ++ if (err) ++ return err; ++ } + + hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); + if (unlikely(skb->len == hdr_len)) { +diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c +index 9993f1162ac68..c69700088082d 100644 +--- a/drivers/net/ethernet/broadcom/bnx2.c ++++ b/drivers/net/ethernet/broadcom/bnx2.c +@@ -1461,7 +1461,7 @@ bnx2_test_and_disable_2g5(struct bnx2 *bp) + static void + bnx2_enable_forced_2g5(struct bnx2 *bp) + { +- u32 uninitialized_var(bmcr); ++ u32 bmcr; + int err; + + if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) +@@ -1505,7 +1505,7 @@ bnx2_enable_forced_2g5(struct bnx2 *bp) + static void + bnx2_disable_forced_2g5(struct bnx2 *bp) + { +- u32 uninitialized_var(bmcr); ++ u32 bmcr; + int err; + + if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) +diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c +index 494601c39b847..9041a422dd15a 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c +@@ -620,5 +620,7 @@ void bcmgenet_mii_exit(struct net_device *dev) + if (of_phy_is_fixed_link(dn)) + of_phy_deregister_fixed_link(dn); + of_node_put(priv->phy_dn); ++ clk_prepare_enable(priv->clk); + platform_device_unregister(priv->mii_pdev); ++ clk_disable_unprepare(priv->clk); + } +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index 2cf144bbef3ee..43b83a3a28049 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -235,6 +235,7 @@ MODULE_DESCRIPTION("Broadcom Tigon3 ethernet driver"); + MODULE_LICENSE("GPL"); + MODULE_VERSION(DRV_MODULE_VERSION); + MODULE_FIRMWARE(FIRMWARE_TG3); ++MODULE_FIRMWARE(FIRMWARE_TG357766); + MODULE_FIRMWARE(FIRMWARE_TG3TSO); + MODULE_FIRMWARE(FIRMWARE_TG3TSO5); + +diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c +index 8603df2ae1736..d0d9a420f557e 100644 +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -1139,7 +1139,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, + (lancer_chip(adapter) || BE3_chip(adapter) || + skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { + ip = (struct iphdr *)ip_hdr(skb); +- pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); ++ if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)))) ++ goto tx_drop; + } + + /* If vlan tag is already inlined in the packet, skip HW VLAN +diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +index a66492b9403c4..5b82c89330e30 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +@@ -1798,7 +1798,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf) + void i40e_dbg_init(void) + { + i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); +- if (!i40e_dbg_root) ++ if (IS_ERR(i40e_dbg_root)) + pr_info("init of debugfs failed\n"); + } + +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 6f9d563deb6ba..be51179089852 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -9059,6 +9059,11 @@ static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev, + struct net_device *netdev = pci_get_drvdata(pdev); + struct igb_adapter *adapter = netdev_priv(netdev); + ++ if (state == pci_channel_io_normal) { ++ dev_warn(&pdev->dev, "Non-correctable non-fatal error reported.\n"); ++ return PCI_ERS_RESULT_CAN_RECOVER; ++ } ++ + netif_device_detach(netdev); + + if (state == pci_channel_io_perm_failure) +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index f1a4b11ce0d19..512f9cd68070a 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -1415,7 +1415,7 @@ static void mvneta_defaults_set(struct mvneta_port *pp) + */ + if (txq_number == 1) + txq_map = (cpu == pp->rxq_def) ? +- MVNETA_CPU_TXQ_ACCESS(1) : 0; ++ MVNETA_CPU_TXQ_ACCESS(0) : 0; + + } else { + txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; +@@ -3665,7 +3665,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp) + */ + if (txq_number == 1) + txq_map = (cpu == elected_cpu) ? +- MVNETA_CPU_TXQ_ACCESS(1) : 0; ++ MVNETA_CPU_TXQ_ACCESS(0) : 0; + else + txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & + MVNETA_CPU_TXQ_ACCESS_ALL_MASK; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +index 128a82b1dbfc6..ad9db70eb879e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +@@ -121,7 +121,9 @@ static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x) + + trailer_len = alen + plen + 2; + +- pskb_trim(skb, skb->len - trailer_len); ++ ret = pskb_trim(skb, skb->len - trailer_len); ++ if (unlikely(ret)) ++ return ret; + if (skb->protocol == htons(ETH_P_IP)) { + ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); + ip_send_check(ipv4hdr); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +index fc880c02459db..c9ba97b400fa1 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +@@ -471,8 +471,8 @@ void mlx5_core_req_pages_handler(struct mlx5_core_dev *dev, u16 func_id, + + int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot) + { +- u16 uninitialized_var(func_id); +- s32 uninitialized_var(npages); ++ u16 func_id; ++ s32 npages; + int err; + + err = mlx5_cmd_query_pages(dev, &func_id, &npages, boot); +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index e734bc5e3ceb4..112d374e71663 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -80,6 +80,18 @@ static int lan743x_csr_light_reset(struct lan743x_adapter *adapter) + !(data & HW_CFG_LRST_), 100000, 10000000); + } + ++static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter, ++ int offset, u32 bit_mask, ++ int target_value, int udelay_min, ++ int udelay_max, int count) ++{ ++ u32 data; ++ ++ return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data, ++ target_value == !!(data & bit_mask), ++ udelay_max, udelay_min * count); ++} ++ + static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter, + int offset, u32 bit_mask, + int target_value, int usleep_min, +@@ -675,8 +687,8 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter, + u32 dp_sel; + int i; + +- if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, +- 1, 40, 100, 100)) ++ if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_, ++ 1, 40, 100, 100)) + return -EIO; + dp_sel = lan743x_csr_read(adapter, DP_SEL); + dp_sel &= ~DP_SEL_MASK_; +@@ -687,8 +699,9 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter, + lan743x_csr_write(adapter, DP_ADDR, addr + i); + lan743x_csr_write(adapter, DP_DATA_0, buf[i]); + lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_); +- if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, +- 1, 40, 100, 100)) ++ if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, ++ DP_SEL_DPRDY_, ++ 1, 40, 100, 100)) + return -EIO; + } + +diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c +index b42f81d0c6f05..f5272d2fcc7e4 100644 +--- a/drivers/net/ethernet/neterion/s2io.c ++++ b/drivers/net/ethernet/neterion/s2io.c +@@ -7291,7 +7291,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) + int ring_no = ring_data->ring_no; + u16 l3_csum, l4_csum; + unsigned long long err = rxdp->Control_1 & RXD_T_CODE; +- struct lro *uninitialized_var(lro); ++ struct lro *lro; + u8 err_mask; + struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; + +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index 7a65a1534e41a..d545593354c63 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -3771,7 +3771,7 @@ static int ql3xxx_probe(struct pci_dev *pdev, + struct net_device *ndev = NULL; + struct ql3_adapter *qdev = NULL; + static int cards_found; +- int uninitialized_var(pci_using_dac), err; ++ int pci_using_dac, err; + + err = pci_enable_device(pdev); + if (err) { +diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c +index 909f6d1605f7a..861d1f6d7508f 100644 +--- a/drivers/net/ethernet/sun/cassini.c ++++ b/drivers/net/ethernet/sun/cassini.c +@@ -2291,7 +2291,7 @@ static int cas_rx_ringN(struct cas *cp, int ring, int budget) + drops = 0; + while (1) { + struct cas_rx_comp *rxc = rxcs + entry; +- struct sk_buff *uninitialized_var(skb); ++ struct sk_buff *skb; + int type, len; + u64 words[4]; + int i, dring; +diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c +index 1693a70325c50..1c13c08c4f965 100644 +--- a/drivers/net/ethernet/sun/niu.c ++++ b/drivers/net/ethernet/sun/niu.c +@@ -429,7 +429,7 @@ static int serdes_init_niu_1g_serdes(struct niu *np) + struct niu_link_config *lp = &np->link_config; + u16 pll_cfg, pll_sts; + int max_retry = 100; +- u64 uninitialized_var(sig), mask, val; ++ u64 sig, mask, val; + u32 tx_cfg, rx_cfg; + unsigned long i; + int err; +@@ -526,7 +526,7 @@ static int serdes_init_niu_10g_serdes(struct niu *np) + struct niu_link_config *lp = &np->link_config; + u32 tx_cfg, rx_cfg, pll_cfg, pll_sts; + int max_retry = 100; +- u64 uninitialized_var(sig), mask, val; ++ u64 sig, mask, val; + unsigned long i; + int err; + +@@ -714,7 +714,7 @@ static int esr_write_glue0(struct niu *np, unsigned long chan, u32 val) + + static int esr_reset(struct niu *np) + { +- u32 uninitialized_var(reset); ++ u32 reset; + int err; + + err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, +diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c +index c245629a38c76..6cb98760bc84e 100644 +--- a/drivers/net/ethernet/ti/cpsw_ale.c ++++ b/drivers/net/ethernet/ti/cpsw_ale.c +@@ -67,23 +67,37 @@ + + static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) + { +- int idx; ++ int idx, idx2; ++ u32 hi_val = 0; + + idx = start / 32; ++ idx2 = (start + bits - 1) / 32; ++ /* Check if bits to be fetched exceed a word */ ++ if (idx != idx2) { ++ idx2 = 2 - idx2; /* flip */ ++ hi_val = ale_entry[idx2] << ((idx2 * 32) - start); ++ } + start -= idx * 32; + idx = 2 - idx; /* flip */ +- return (ale_entry[idx] >> start) & BITMASK(bits); ++ return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits); + } + + static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, + u32 value) + { +- int idx; ++ int idx, idx2; + + value &= BITMASK(bits); +- idx = start / 32; ++ idx = start / 32; ++ idx2 = (start + bits - 1) / 32; ++ /* Check if bits to be set exceed a word */ ++ if (idx != idx2) { ++ idx2 = 2 - idx2; /* flip */ ++ ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); ++ ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); ++ } + start -= idx * 32; +- idx = 2 - idx; /* flip */ ++ idx = 2 - idx; /* flip */ + ale_entry[idx] &= ~(BITMASK(bits) << start); + ale_entry[idx] |= (value << start); + } +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index e18d06cb2173c..2718b0507f713 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -301,7 +301,9 @@ static void __gtp_encap_destroy(struct sock *sk) + gtp->sk1u = NULL; + udp_sk(sk)->encap_type = 0; + rcu_assign_sk_user_data(sk, NULL); ++ release_sock(sk); + sock_put(sk); ++ return; + } + release_sock(sk); + } +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index eb80d277b56f5..6b6c5a7250a65 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -592,7 +592,8 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) + consume_skb(skb); + return NET_XMIT_DROP; + } +- return ipvlan_rcv_frame(addr, &skb, true); ++ ipvlan_rcv_frame(addr, &skb, true); ++ return NET_XMIT_SUCCESS; + } + } + out: +@@ -618,7 +619,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) + consume_skb(skb); + return NET_XMIT_DROP; + } +- return ipvlan_rcv_frame(addr, &skb, true); ++ ipvlan_rcv_frame(addr, &skb, true); ++ return NET_XMIT_SUCCESS; + } + } + skb = skb_share_check(skb, GFP_ATOMIC); +@@ -630,7 +632,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) + * the skb for the main-dev. At the RX side we just return + * RX_PASS for it to be processed further on the stack. + */ +- return dev_forward_skb(ipvlan->phy_dev, skb); ++ dev_forward_skb(ipvlan->phy_dev, skb); ++ return NET_XMIT_SUCCESS; + + } else if (is_multicast_ether_addr(eth->h_dest)) { + skb_reset_mac_header(skb); +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 2410f08e2bb5c..d80bc5f59b3fc 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2103,6 +2103,15 @@ static void team_setup_by_port(struct net_device *dev, + dev->mtu = port_dev->mtu; + memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); + eth_hw_addr_inherit(dev, port_dev); ++ ++ if (port_dev->flags & IFF_POINTOPOINT) { ++ dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); ++ dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); ++ } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == ++ (IFF_BROADCAST | IFF_MULTICAST)) { ++ dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); ++ dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); ++ } + } + + static int team_dev_type_check_change(struct net_device *dev, +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 17b932505be0c..e2ce3c5541baa 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -618,9 +618,23 @@ static const struct usb_device_id products[] = { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, ++ .idProduct = 0x8005, /* A-300 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8006, /* B-500/SL-5600 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +@@ -628,6 +642,13 @@ static const struct usb_device_id products[] = { + .idProduct = 0x8007, /* C-700 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = 0, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8007, /* C-700 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = 0, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index 2263a66f6314e..f7f037b399a75 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1767,6 +1767,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + } else if (!info->in || !info->out) + status = usbnet_get_endpoints (dev, udev); + else { ++ u8 ep_addrs[3] = { ++ info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 ++ }; ++ + dev->in = usb_rcvbulkpipe (xdev, info->in); + dev->out = usb_sndbulkpipe (xdev, info->out); + if (!(info->flags & FLAG_NO_SETINT)) +@@ -1776,6 +1780,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) + else + status = 0; + ++ if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) ++ status = -EINVAL; + } + if (status >= 0 && dev->status) + status = init_status (dev, udev); +diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c +index 1f19fc5e6117e..9a6ab75752e16 100644 +--- a/drivers/net/usb/zaurus.c ++++ b/drivers/net/usb/zaurus.c +@@ -301,9 +301,23 @@ static const struct usb_device_id products [] = { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, ++ .idProduct = 0x8005, /* A-300 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8006, /* B-500/SL-5600 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +@@ -311,6 +325,13 @@ static const struct usb_device_id products [] = { + .idProduct = 0x8007, /* C-700 */ + ZAURUS_MASTER_INTERFACE, + .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8007, /* C-700 */ ++ ZAURUS_FAKE_INTERFACE, ++ .driver_info = (unsigned long)&bogus_mdlm_info, + }, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index d45e8de79f286..03e0f8060cc2e 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3120,6 +3120,8 @@ static int virtnet_probe(struct virtio_device *vdev) + } + } + ++ _virtnet_set_queues(vi, vi->curr_queue_pairs); ++ + /* serialize netdev register + virtio_device_ready() with ndo_open() */ + rtnl_lock(); + +@@ -3140,8 +3142,6 @@ static int virtnet_probe(struct virtio_device *vdev) + goto free_unregister_netdev; + } + +- virtnet_set_queues(vi, vi->curr_queue_pairs); +- + /* Assume link up if device can't report link status, + otherwise get link status from config. */ + netif_carrier_off(dev); +diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c +index deea41e96f018..96025d42b0eea 100644 +--- a/drivers/net/wan/z85230.c ++++ b/drivers/net/wan/z85230.c +@@ -705,7 +705,7 @@ EXPORT_SYMBOL(z8530_nop); + irqreturn_t z8530_interrupt(int irq, void *dev_id) + { + struct z8530_dev *dev=dev_id; +- u8 uninitialized_var(intr); ++ u8 intr; + static volatile int locker=0; + int work=0; + struct z8530_irqhandler *irqs; +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 436eac342b622..7e43d449131dd 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -1891,7 +1891,7 @@ static int ath10k_init_uart(struct ath10k *ar) + + static int ath10k_init_hw_params(struct ath10k *ar) + { +- const struct ath10k_hw_params *uninitialized_var(hw_params); ++ const struct ath10k_hw_params *hw_params; + int i; + + for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) { +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index 58fb227a849f6..49b93a5b7a72a 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -1575,7 +1575,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) + + int ath6kl_init_hw_params(struct ath6kl *ar) + { +- const struct ath6kl_hw *uninitialized_var(hw); ++ const struct ath6kl_hw *hw; + int i; + + for (i = 0; i < ARRAY_SIZE(hw_list); i++) { +diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c +index 2fe12b0de5b4f..dea8a998fb622 100644 +--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c +@@ -1099,17 +1099,22 @@ static bool ath9k_hw_verify_hang(struct ath_hw *ah, unsigned int queue) + { + u32 dma_dbg_chain, dma_dbg_complete; + u8 dcu_chain_state, dcu_complete_state; ++ unsigned int dbg_reg, reg_offset; + int i; + +- for (i = 0; i < NUM_STATUS_READS; i++) { +- if (queue < 6) +- dma_dbg_chain = REG_READ(ah, AR_DMADBG_4); +- else +- dma_dbg_chain = REG_READ(ah, AR_DMADBG_5); ++ if (queue < 6) { ++ dbg_reg = AR_DMADBG_4; ++ reg_offset = queue * 5; ++ } else { ++ dbg_reg = AR_DMADBG_5; ++ reg_offset = (queue - 6) * 5; ++ } + ++ for (i = 0; i < NUM_STATUS_READS; i++) { ++ dma_dbg_chain = REG_READ(ah, dbg_reg); + dma_dbg_complete = REG_READ(ah, AR_DMADBG_6); + +- dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f; ++ dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f; + dcu_complete_state = dma_dbg_complete & 0x3; + + if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1)) +@@ -1128,6 +1133,7 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) + u8 dcu_chain_state, dcu_complete_state; + bool dcu_wait_frdone = false; + unsigned long chk_dcu = 0; ++ unsigned int reg_offset; + unsigned int i = 0; + + dma_dbg_4 = REG_READ(ah, AR_DMADBG_4); +@@ -1139,12 +1145,15 @@ static bool ar9003_hw_detect_mac_hang(struct ath_hw *ah) + goto exit; + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { +- if (i < 6) ++ if (i < 6) { + chk_dbg = dma_dbg_4; +- else ++ reg_offset = i * 5; ++ } else { + chk_dbg = dma_dbg_5; ++ reg_offset = (i - 6) * 5; ++ } + +- dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f; ++ dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f; + if (dcu_chain_state == 0x6) { + dcu_wait_frdone = true; + chk_dcu |= BIT(i); +diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c +index 6331c98088e03..d5e5f9cf4ca86 100644 +--- a/drivers/net/wireless/ath/ath9k/htc_hst.c ++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c +@@ -114,7 +114,13 @@ static void htc_process_conn_rsp(struct htc_target *target, + + if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { + epid = svc_rspmsg->endpoint_id; +- if (epid < 0 || epid >= ENDPOINT_MAX) ++ ++ /* Check that the received epid for the endpoint to attach ++ * a new service is valid. ENDPOINT0 can't be used here as it ++ * is already reserved for HTC_CTRL_RSVD_SVC service and thus ++ * should not be modified. ++ */ ++ if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX) + return; + + service_id = be16_to_cpu(svc_rspmsg->service_id); +diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c +index fae572b384169..922a3f208837e 100644 +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -230,7 +230,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl + struct ath_hw *ah = hw_priv; + struct ath_common *common = ath9k_hw_common(ah); + struct ath_softc *sc = (struct ath_softc *) common->priv; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + u32 val; + + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index ee1b9c39bad7a..2fdf9858a73d9 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -200,7 +200,7 @@ void ath_cancel_work(struct ath_softc *sc) + void ath_restart_work(struct ath_softc *sc) + { + ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, +- ATH_HW_CHECK_POLL_INT); ++ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); + + if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, +@@ -847,7 +847,7 @@ static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) + static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) + { + struct ath_hw *ah = sc->sc_ah; +- int i; ++ int i, j; + struct ath_txq *txq; + bool key_in_use = false; + +@@ -865,8 +865,9 @@ static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + int idx = txq->txq_tailidx; + +- while (!key_in_use && +- !list_empty(&txq->txq_fifo[idx])) { ++ for (j = 0; !key_in_use && ++ !list_empty(&txq->txq_fifo[idx]) && ++ j < ATH_TXFIFO_DEPTH; j++) { + key_in_use = ath9k_txq_list_has_key( + &txq->txq_fifo[idx], keyix); + INCR(idx, ATH_TXFIFO_DEPTH); +@@ -2227,7 +2228,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop, + } + + ieee80211_queue_delayed_work(hw, &sc->hw_check_work, +- ATH_HW_CHECK_POLL_INT); ++ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); + } + + static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) +diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c +index e4ea6f5cc78ab..5e2a610df61cf 100644 +--- a/drivers/net/wireless/ath/ath9k/wmi.c ++++ b/drivers/net/wireless/ath/ath9k/wmi.c +@@ -218,6 +218,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, + if (unlikely(wmi->stopped)) + goto free_skb; + ++ /* Validate the obtained SKB. */ ++ if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr))) ++ goto free_skb; ++ + hdr = (struct wmi_cmd_hdr *) skb->data; + cmd_id = be16_to_cpu(hdr->command_id); + +diff --git a/drivers/net/wireless/atmel/atmel_cs.c b/drivers/net/wireless/atmel/atmel_cs.c +index 7afc9c5329fb1..f5fa1a95b0c15 100644 +--- a/drivers/net/wireless/atmel/atmel_cs.c ++++ b/drivers/net/wireless/atmel/atmel_cs.c +@@ -73,6 +73,7 @@ struct local_info { + static int atmel_probe(struct pcmcia_device *p_dev) + { + struct local_info *local; ++ int ret; + + dev_dbg(&p_dev->dev, "atmel_attach()\n"); + +@@ -83,8 +84,16 @@ static int atmel_probe(struct pcmcia_device *p_dev) + + p_dev->priv = local; + +- return atmel_config(p_dev); +-} /* atmel_attach */ ++ ret = atmel_config(p_dev); ++ if (ret) ++ goto err_free_priv; ++ ++ return 0; ++ ++err_free_priv: ++ kfree(p_dev->priv); ++ return ret; ++} + + static void atmel_detach(struct pcmcia_device *link) + { +diff --git a/drivers/net/wireless/broadcom/b43/debugfs.c b/drivers/net/wireless/broadcom/b43/debugfs.c +index 77046384dd800..70b02d6641709 100644 +--- a/drivers/net/wireless/broadcom/b43/debugfs.c ++++ b/drivers/net/wireless/broadcom/b43/debugfs.c +@@ -506,7 +506,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, + struct b43_wldev *dev; + struct b43_debugfs_fops *dfops; + struct b43_dfs_file *dfile; +- ssize_t uninitialized_var(ret); ++ ssize_t ret; + char *buf; + const size_t bufsize = 1024 * 16; /* 16 kiB buffer */ + const size_t buforder = get_order(bufsize); +diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c +index d46d57b989aec..06139835055fa 100644 +--- a/drivers/net/wireless/broadcom/b43/dma.c ++++ b/drivers/net/wireless/broadcom/b43/dma.c +@@ -50,7 +50,7 @@ + static u32 b43_dma_address(struct b43_dma *dma, dma_addr_t dmaaddr, + enum b43_addrtype addrtype) + { +- u32 uninitialized_var(addr); ++ u32 addr; + + switch (addrtype) { + case B43_DMA_ADDR_LOW: +diff --git a/drivers/net/wireless/broadcom/b43/lo.c b/drivers/net/wireless/broadcom/b43/lo.c +index a335f94c72ff7..10cc0c0d70c3a 100644 +--- a/drivers/net/wireless/broadcom/b43/lo.c ++++ b/drivers/net/wireless/broadcom/b43/lo.c +@@ -742,7 +742,7 @@ struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev, + }; + int max_rx_gain; + struct b43_lo_calib *cal; +- struct lo_g_saved_values uninitialized_var(saved_regs); ++ struct lo_g_saved_values saved_regs; + /* Values from the "TXCTL Register and Value Table" */ + u16 txctl_reg; + u16 txctl_value; +diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c +index 3508a78226193..3a74e82c9fb68 100644 +--- a/drivers/net/wireless/broadcom/b43/phy_n.c ++++ b/drivers/net/wireless/broadcom/b43/phy_n.c +@@ -5655,7 +5655,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, + u8 rfctl[2]; + u8 afectl_core; + u16 tmp[6]; +- u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna; ++ u16 cur_hpf1, cur_hpf2, cur_lna; + u32 real, imag; + enum nl80211_band band; + +diff --git a/drivers/net/wireless/broadcom/b43/xmit.c b/drivers/net/wireless/broadcom/b43/xmit.c +index 1b9c191e2a229..c123e22046637 100644 +--- a/drivers/net/wireless/broadcom/b43/xmit.c ++++ b/drivers/net/wireless/broadcom/b43/xmit.c +@@ -435,10 +435,10 @@ int b43_generate_txhdr(struct b43_wldev *dev, + if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || + (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { + unsigned int len; +- struct ieee80211_hdr *uninitialized_var(hdr); ++ struct ieee80211_hdr *hdr; + int rts_rate, rts_rate_fb; + int rts_rate_ofdm, rts_rate_fb_ofdm; +- struct b43_plcp_hdr6 *uninitialized_var(plcp); ++ struct b43_plcp_hdr6 *plcp; + struct ieee80211_rate *rts_cts_rate; + + rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info); +@@ -449,7 +449,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, + rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); + + if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { +- struct ieee80211_cts *uninitialized_var(cts); ++ struct ieee80211_cts *cts; + + switch (dev->fw.hdr_format) { + case B43_FW_HDR_598: +@@ -471,7 +471,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, + mac_ctl |= B43_TXH_MAC_SENDCTS; + len = sizeof(struct ieee80211_cts); + } else { +- struct ieee80211_rts *uninitialized_var(rts); ++ struct ieee80211_rts *rts; + + switch (dev->fw.hdr_format) { + case B43_FW_HDR_598: +@@ -663,8 +663,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) + const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; + __le16 fctl; + u16 phystat0, phystat3; +- u16 uninitialized_var(chanstat), uninitialized_var(mactime); +- u32 uninitialized_var(macstat); ++ u16 chanstat, mactime; ++ u32 macstat; + u16 chanid; + int padding, rate_idx; + +diff --git a/drivers/net/wireless/broadcom/b43legacy/debugfs.c b/drivers/net/wireless/broadcom/b43legacy/debugfs.c +index 82ef56ed7ca1b..d3c9a916b44c5 100644 +--- a/drivers/net/wireless/broadcom/b43legacy/debugfs.c ++++ b/drivers/net/wireless/broadcom/b43legacy/debugfs.c +@@ -203,7 +203,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, + struct b43legacy_wldev *dev; + struct b43legacy_debugfs_fops *dfops; + struct b43legacy_dfs_file *dfile; +- ssize_t uninitialized_var(ret); ++ ssize_t ret; + char *buf; + const size_t bufsize = 1024 * 16; /* 16 KiB buffer */ + const size_t buforder = get_order(bufsize); +diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c +index ef1f1b5d63b10..a147c93583b26 100644 +--- a/drivers/net/wireless/broadcom/b43legacy/main.c ++++ b/drivers/net/wireless/broadcom/b43legacy/main.c +@@ -2612,7 +2612,7 @@ static void b43legacy_put_phy_into_reset(struct b43legacy_wldev *dev) + static int b43legacy_switch_phymode(struct b43legacy_wl *wl, + unsigned int new_mode) + { +- struct b43legacy_wldev *uninitialized_var(up_dev); ++ struct b43legacy_wldev *up_dev; + struct b43legacy_wldev *down_dev; + int err; + bool gmode = false; +diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c +index 5a6ee0b014da0..a01b42c7c07ac 100644 +--- a/drivers/net/wireless/cisco/airo.c ++++ b/drivers/net/wireless/cisco/airo.c +@@ -6100,8 +6100,11 @@ static int airo_get_rate(struct net_device *dev, + { + struct airo_info *local = dev->ml_priv; + StatusRid status_rid; /* Card status info */ ++ int ret; + +- readStatusRid(local, &status_rid, 1); ++ ret = readStatusRid(local, &status_rid, 1); ++ if (ret) ++ return -EBUSY; + + vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000; + /* If more than one rate, set auto */ +diff --git a/drivers/net/wireless/intel/iwlegacy/3945.c b/drivers/net/wireless/intel/iwlegacy/3945.c +index 3e568ce2fb208..6703ce95e640e 100644 +--- a/drivers/net/wireless/intel/iwlegacy/3945.c ++++ b/drivers/net/wireless/intel/iwlegacy/3945.c +@@ -2115,7 +2115,7 @@ il3945_txpower_set_from_eeprom(struct il_priv *il) + + /* set tx power value for all OFDM rates */ + for (rate_idx = 0; rate_idx < IL_OFDM_RATES; rate_idx++) { +- s32 uninitialized_var(power_idx); ++ s32 power_idx; + int rc; + + /* use channel group's clip-power table, +diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c +index 4970c19df582e..2b60473e7bf9c 100644 +--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c ++++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c +@@ -2784,7 +2784,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) + struct ieee80211_tx_info *info; + struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); +- int uninitialized_var(tid); ++ int tid; + int sta_id; + int freed; + u8 *qc = NULL; +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +index 373ace38edab7..83883ce7f55dc 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +@@ -2237,7 +2237,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, + } + + if (iwl_mvm_has_new_rx_api(mvm) && start) { +- u16 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); ++ u32 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); + + /* sparse doesn't like the __align() so don't check */ + #ifndef __CHECKER__ +diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c +index a956f965a1e5e..03bfd2482656c 100644 +--- a/drivers/net/wireless/intersil/orinoco/orinoco_cs.c ++++ b/drivers/net/wireless/intersil/orinoco/orinoco_cs.c +@@ -96,6 +96,7 @@ orinoco_cs_probe(struct pcmcia_device *link) + { + struct orinoco_private *priv; + struct orinoco_pccard *card; ++ int ret; + + priv = alloc_orinocodev(sizeof(*card), &link->dev, + orinoco_cs_hard_reset, NULL); +@@ -107,8 +108,16 @@ orinoco_cs_probe(struct pcmcia_device *link) + card->p_dev = link; + link->priv = priv; + +- return orinoco_cs_config(link); +-} /* orinoco_cs_attach */ ++ ret = orinoco_cs_config(link); ++ if (ret) ++ goto err_free_orinocodev; ++ ++ return 0; ++ ++err_free_orinocodev: ++ free_orinocodev(priv); ++ return ret; ++} + + static void orinoco_cs_detach(struct pcmcia_device *link) + { +diff --git a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c +index b60048c95e0a8..011c86e55923e 100644 +--- a/drivers/net/wireless/intersil/orinoco/spectrum_cs.c ++++ b/drivers/net/wireless/intersil/orinoco/spectrum_cs.c +@@ -157,6 +157,7 @@ spectrum_cs_probe(struct pcmcia_device *link) + { + struct orinoco_private *priv; + struct orinoco_pccard *card; ++ int ret; + + priv = alloc_orinocodev(sizeof(*card), &link->dev, + spectrum_cs_hard_reset, +@@ -169,8 +170,16 @@ spectrum_cs_probe(struct pcmcia_device *link) + card->p_dev = link; + link->priv = priv; + +- return spectrum_cs_config(link); +-} /* spectrum_cs_attach */ ++ ret = spectrum_cs_config(link); ++ if (ret) ++ goto err_free_orinocodev; ++ ++ return 0; ++ ++err_free_orinocodev: ++ free_orinocodev(priv); ++ return ret; ++} + + static void spectrum_cs_detach(struct pcmcia_device *link) + { +diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c +index c9f6cd2919699..4f0e78ae3dbd0 100644 +--- a/drivers/net/wireless/marvell/mwifiex/scan.c ++++ b/drivers/net/wireless/marvell/mwifiex/scan.c +@@ -2208,9 +2208,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, + + if (nd_config) { + adapter->nd_info = +- kzalloc(sizeof(struct cfg80211_wowlan_nd_match) + +- sizeof(struct cfg80211_wowlan_nd_match *) * +- scan_rsp->number_of_sets, GFP_ATOMIC); ++ kzalloc(struct_size(adapter->nd_info, matches, ++ scan_rsp->number_of_sets), ++ GFP_ATOMIC); + + if (adapter->nd_info) + adapter->nd_info->n_matches = scan_rsp->number_of_sets; +diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c +index 8704bae39e1bf..edc990d099789 100644 +--- a/drivers/net/wireless/ray_cs.c ++++ b/drivers/net/wireless/ray_cs.c +@@ -282,13 +282,14 @@ static int ray_probe(struct pcmcia_device *p_dev) + { + ray_dev_t *local; + struct net_device *dev; ++ int ret; + + dev_dbg(&p_dev->dev, "ray_attach()\n"); + + /* Allocate space for private device-specific data */ + dev = alloc_etherdev(sizeof(ray_dev_t)); + if (!dev) +- goto fail_alloc_dev; ++ return -ENOMEM; + + local = netdev_priv(dev); + local->finder = p_dev; +@@ -325,11 +326,16 @@ static int ray_probe(struct pcmcia_device *p_dev) + timer_setup(&local->timer, NULL, 0); + + this_device = p_dev; +- return ray_config(p_dev); ++ ret = ray_config(p_dev); ++ if (ret) ++ goto err_free_dev; ++ ++ return 0; + +-fail_alloc_dev: +- return -ENOMEM; +-} /* ray_attach */ ++err_free_dev: ++ free_netdev(dev); ++ return ret; ++} + + static void ray_detach(struct pcmcia_device *link) + { +@@ -1651,38 +1657,34 @@ static void authenticate_timeout(struct timer_list *t) + /*===========================================================================*/ + static int parse_addr(char *in_str, UCHAR *out) + { ++ int i, k; + int len; +- int i, j, k; +- int status; + + if (in_str == NULL) + return 0; +- if ((len = strlen(in_str)) < 2) ++ len = strnlen(in_str, ADDRLEN * 2 + 1) - 1; ++ if (len < 1) + return 0; + memset(out, 0, ADDRLEN); + +- status = 1; +- j = len - 1; +- if (j > 12) +- j = 12; + i = 5; + +- while (j > 0) { +- if ((k = hex_to_bin(in_str[j--])) != -1) ++ while (len > 0) { ++ if ((k = hex_to_bin(in_str[len--])) != -1) + out[i] = k; + else + return 0; + +- if (j == 0) ++ if (len == 0) + break; +- if ((k = hex_to_bin(in_str[j--])) != -1) ++ if ((k = hex_to_bin(in_str[len--])) != -1) + out[i] += k << 4; + else + return 0; + if (!i--) + break; + } +- return status; ++ return 1; + } + + /*===========================================================================*/ +diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c +index 48efe83c58d89..409a3e8305763 100644 +--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c ++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c +@@ -1368,9 +1368,6 @@ static void rsi_shutdown(struct device *dev) + if (sdev->write_fail) + rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n"); + +- if (rsi_set_sdio_pm_caps(adapter)) +- rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); +- + rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); + } + +diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c +index cfde9b94b4b60..4380c5d8fdd27 100644 +--- a/drivers/net/wireless/wl3501_cs.c ++++ b/drivers/net/wireless/wl3501_cs.c +@@ -133,8 +133,8 @@ static const struct { + + /** + * iw_valid_channel - validate channel in regulatory domain +- * @reg_comain - regulatory domain +- * @channel - channel to validate ++ * @reg_domain: regulatory domain ++ * @channel: channel to validate + * + * Returns 0 if invalid in the specified regulatory domain, non-zero if valid. + */ +@@ -153,7 +153,7 @@ static int iw_valid_channel(int reg_domain, int channel) + + /** + * iw_default_channel - get default channel for a regulatory domain +- * @reg_comain - regulatory domain ++ * @reg_domain: regulatory domain + * + * Returns the default channel for a regulatory domain + */ +@@ -236,6 +236,7 @@ static int wl3501_get_flash_mac_addr(struct wl3501_card *this) + + /** + * wl3501_set_to_wla - Move 'size' bytes from PC to card ++ * @this: Card + * @dest: Card addressing space + * @src: PC addressing space + * @size: Bytes to move +@@ -258,6 +259,7 @@ static void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, + + /** + * wl3501_get_from_wla - Move 'size' bytes from card to PC ++ * @this: Card + * @src: Card addressing space + * @dest: PC addressing space + * @size: Bytes to move +@@ -454,12 +456,10 @@ out: + + /** + * wl3501_send_pkt - Send a packet. +- * @this - card +- * +- * Send a packet. +- * +- * data = Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr, ++ * @this: Card ++ * @data: Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr, + * data[6] - data[11] is Src MAC Addr) ++ * @len: Packet length + * Ref: IEEE 802.11 + */ + static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len) +@@ -722,7 +722,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr) + + /** + * wl3501_block_interrupt - Mask interrupt from SUTRO +- * @this - card ++ * @this: Card + * + * Mask interrupt from SUTRO. (i.e. SUTRO cannot interrupt the HOST) + * Return: 1 if interrupt is originally enabled +@@ -739,7 +739,7 @@ static int wl3501_block_interrupt(struct wl3501_card *this) + + /** + * wl3501_unblock_interrupt - Enable interrupt from SUTRO +- * @this - card ++ * @this: Card + * + * Enable interrupt from SUTRO. (i.e. SUTRO can interrupt the HOST) + * Return: 1 if interrupt is originally enabled +@@ -1113,8 +1113,8 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this) + + /** + * wl3501_interrupt - Hardware interrupt from card. +- * @irq - Interrupt number +- * @dev_id - net_device ++ * @irq: Interrupt number ++ * @dev_id: net_device + * + * We must acknowledge the interrupt as soon as possible, and block the + * interrupt from the same card immediately to prevent re-entry. +@@ -1252,7 +1252,7 @@ static int wl3501_close(struct net_device *dev) + + /** + * wl3501_reset - Reset the SUTRO. +- * @dev - network device ++ * @dev: network device + * + * It is almost the same as wl3501_open(). In fact, we may just wl3501_close() + * and wl3501_open() again, but I wouldn't like to free_irq() when the driver +@@ -1415,7 +1415,7 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) + + /** + * wl3501_detach - deletes a driver "instance" +- * @link - FILL_IN ++ * @link: FILL_IN + * + * This deletes a driver "instance". The device is de-registered with Card + * Services. If it has been released, all local data structures are freed. +@@ -1436,9 +1436,7 @@ static void wl3501_detach(struct pcmcia_device *link) + wl3501_release(link); + + unregister_netdev(dev); +- +- if (link->priv) +- free_netdev(link->priv); ++ free_netdev(dev); + } + + static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info, +@@ -1865,6 +1863,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev) + { + struct net_device *dev; + struct wl3501_card *this; ++ int ret; + + /* The io structure describes IO port mapping */ + p_dev->resource[0]->end = 16; +@@ -1876,8 +1875,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev) + + dev = alloc_etherdev(sizeof(struct wl3501_card)); + if (!dev) +- goto out_link; +- ++ return -ENOMEM; + + dev->netdev_ops = &wl3501_netdev_ops; + dev->watchdog_timeo = 5 * HZ; +@@ -1890,9 +1888,15 @@ static int wl3501_probe(struct pcmcia_device *p_dev) + netif_stop_queue(dev); + p_dev->priv = dev; + +- return wl3501_config(p_dev); +-out_link: +- return -ENOMEM; ++ ret = wl3501_config(p_dev); ++ if (ret) ++ goto out_free_etherdev; ++ ++ return 0; ++ ++out_free_etherdev: ++ free_netdev(dev); ++ return ret; + } + + static int wl3501_config(struct pcmcia_device *link) +@@ -1948,8 +1952,7 @@ static int wl3501_config(struct pcmcia_device *link) + goto failed; + } + +- for (i = 0; i < 6; i++) +- dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; ++ eth_hw_addr_set(dev, this->mac_addr); + + /* print probe information */ + printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, " +diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c +index 0b1fbb5dba9b6..7de7616803935 100644 +--- a/drivers/ntb/hw/amd/ntb_hw_amd.c ++++ b/drivers/ntb/hw/amd/ntb_hw_amd.c +@@ -1139,12 +1139,17 @@ static struct pci_driver amd_ntb_pci_driver = { + + static int __init amd_ntb_pci_driver_init(void) + { ++ int ret; + pr_info("%s %s\n", NTB_DESC, NTB_VER); + + if (debugfs_initialized()) + debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); + +- return pci_register_driver(&amd_ntb_pci_driver); ++ ret = pci_register_driver(&amd_ntb_pci_driver); ++ if (ret) ++ debugfs_remove_recursive(debugfs_dir); ++ ++ return ret; + } + module_init(amd_ntb_pci_driver_init); + +diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c +index a67ef23e81bca..82e08f583980b 100644 +--- a/drivers/ntb/hw/idt/ntb_hw_idt.c ++++ b/drivers/ntb/hw/idt/ntb_hw_idt.c +@@ -2692,6 +2692,7 @@ static struct pci_driver idt_pci_driver = { + + static int __init idt_pci_driver_init(void) + { ++ int ret; + pr_info("%s %s\n", NTB_DESC, NTB_VER); + + /* Create the top DebugFS directory if the FS is initialized */ +@@ -2699,7 +2700,11 @@ static int __init idt_pci_driver_init(void) + dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL); + + /* Register the NTB hardware driver to handle the PCI device */ +- return pci_register_driver(&idt_pci_driver); ++ ret = pci_register_driver(&idt_pci_driver); ++ if (ret) ++ debugfs_remove_recursive(dbgfs_topdir); ++ ++ return ret; + } + module_init(idt_pci_driver_init); + +diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c +index 2ad263f708da7..084bd1d1ac1dc 100644 +--- a/drivers/ntb/hw/intel/ntb_hw_gen1.c ++++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c +@@ -2052,12 +2052,17 @@ static struct pci_driver intel_ntb_pci_driver = { + + static int __init intel_ntb_pci_driver_init(void) + { ++ int ret; + pr_info("%s %s\n", NTB_DESC, NTB_VER); + + if (debugfs_initialized()) + debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); + +- return pci_register_driver(&intel_ntb_pci_driver); ++ ret = pci_register_driver(&intel_ntb_pci_driver); ++ if (ret) ++ debugfs_remove_recursive(debugfs_dir); ++ ++ return ret; + } + module_init(intel_ntb_pci_driver_init); + +diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c +index 9398959664769..2d647a1cd0ee5 100644 +--- a/drivers/ntb/ntb_transport.c ++++ b/drivers/ntb/ntb_transport.c +@@ -393,7 +393,7 @@ int ntb_transport_register_client_dev(char *device_name) + + rc = device_register(dev); + if (rc) { +- kfree(client_dev); ++ put_device(dev); + goto err; + } + +diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c +index 6301aa413c3b8..1f64146546221 100644 +--- a/drivers/ntb/test/ntb_tool.c ++++ b/drivers/ntb/test/ntb_tool.c +@@ -998,6 +998,8 @@ static int tool_init_mws(struct tool_ctx *tc) + tc->peers[pidx].outmws = + devm_kcalloc(&tc->ntb->dev, tc->peers[pidx].outmw_cnt, + sizeof(*tc->peers[pidx].outmws), GFP_KERNEL); ++ if (tc->peers[pidx].outmws == NULL) ++ return -ENOMEM; + + for (widx = 0; widx < tc->peers[pidx].outmw_cnt; widx++) { + tc->peers[pidx].outmws[widx].pidx = pidx; +diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c +index 133fad284c9fa..ea0cd2401d6b7 100644 +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -758,6 +758,8 @@ static int qcom_pcie_get_resources_2_4_0(struct qcom_pcie *pcie) + if (IS_ERR(res->phy_ahb_reset)) + return PTR_ERR(res->phy_ahb_reset); + ++ dw_pcie_dbi_ro_wr_dis(pci); ++ + return 0; + } + +diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c +index 06dd2ab73b6ee..4d3a589af1296 100644 +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -124,6 +124,7 @@ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, + static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, + struct pci_epf_header *hdr) + { ++ u32 reg; + struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); + struct rockchip_pcie *rockchip = &ep->rockchip; + +@@ -136,8 +137,9 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, + PCIE_CORE_CONFIG_VENDOR); + } + +- rockchip_pcie_write(rockchip, hdr->deviceid << 16, +- ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID); ++ reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID); ++ reg = (reg & 0xFFFF) | (hdr->deviceid << 16); ++ rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID); + + rockchip_pcie_write(rockchip, + hdr->revid | +@@ -311,15 +313,15 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, + { + struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); + struct rockchip_pcie *rockchip = &ep->rockchip; +- u16 flags; ++ u32 flags; + + flags = rockchip_pcie_read(rockchip, + ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + + ROCKCHIP_PCIE_EP_MSI_CTRL_REG); + flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK; + flags |= +- ((multi_msg_cap << 1) << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | +- PCI_MSI_FLAGS_64BIT; ++ (multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | ++ (PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET); + flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP; + rockchip_pcie_write(rockchip, flags, + ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + +@@ -331,7 +333,7 @@ static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn) + { + struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); + struct rockchip_pcie *rockchip = &ep->rockchip; +- u16 flags; ++ u32 flags; + + flags = rockchip_pcie_read(rockchip, + ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + +@@ -344,48 +346,25 @@ static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn) + } + + static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn, +- u8 intx, bool is_asserted) ++ u8 intx, bool do_assert) + { + struct rockchip_pcie *rockchip = &ep->rockchip; +- u32 r = ep->max_regions - 1; +- u32 offset; +- u32 status; +- u8 msg_code; +- +- if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR || +- ep->irq_pci_fn != fn)) { +- rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r, +- AXI_WRAPPER_NOR_MSG, +- ep->irq_phys_addr, 0, 0); +- ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR; +- ep->irq_pci_fn = fn; +- } + + intx &= 3; +- if (is_asserted) { ++ ++ if (do_assert) { + ep->irq_pending |= BIT(intx); +- msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx; ++ rockchip_pcie_write(rockchip, ++ PCIE_CLIENT_INT_IN_ASSERT | ++ PCIE_CLIENT_INT_PEND_ST_PEND, ++ PCIE_CLIENT_LEGACY_INT_CTRL); + } else { + ep->irq_pending &= ~BIT(intx); +- msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx; ++ rockchip_pcie_write(rockchip, ++ PCIE_CLIENT_INT_IN_DEASSERT | ++ PCIE_CLIENT_INT_PEND_ST_NORMAL, ++ PCIE_CLIENT_LEGACY_INT_CTRL); + } +- +- status = rockchip_pcie_read(rockchip, +- ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + +- ROCKCHIP_PCIE_EP_CMD_STATUS); +- status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; +- +- if ((status != 0) ^ (ep->irq_pending != 0)) { +- status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; +- rockchip_pcie_write(rockchip, status, +- ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + +- ROCKCHIP_PCIE_EP_CMD_STATUS); +- } +- +- offset = +- ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) | +- ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA; +- writel(0, ep->irq_cpu_addr + offset); + } + + static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn, +@@ -415,7 +394,7 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn, + u8 interrupt_num) + { + struct rockchip_pcie *rockchip = &ep->rockchip; +- u16 flags, mme, data, data_mask; ++ u32 flags, mme, data, data_mask; + u8 msi_count; + u64 pci_addr, pci_addr_mask = 0xff; + +@@ -620,6 +599,9 @@ static int rockchip_pcie_ep_probe(struct platform_device *pdev) + + ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR; + ++ rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE, ++ PCIE_CLIENT_CONFIG); ++ + return 0; + err_epc_mem_exit: + pci_epc_mem_exit(epc); +diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c +index c53d1322a3d6c..b047437605cb2 100644 +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -14,6 +14,7 @@ + #include <linux/clk.h> + #include <linux/delay.h> + #include <linux/gpio/consumer.h> ++#include <linux/iopoll.h> + #include <linux/of_pci.h> + #include <linux/phy/phy.h> + #include <linux/platform_device.h> +@@ -154,6 +155,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) + } + EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt); + ++#define rockchip_pcie_read_addr(addr) rockchip_pcie_read(rockchip, addr) ++/* 100 ms max wait time for PHY PLLs to lock */ ++#define RK_PHY_PLL_LOCK_TIMEOUT_US 100000 ++/* Sleep should be less than 20ms */ ++#define RK_PHY_PLL_LOCK_SLEEP_US 1000 ++ + int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + { + struct device *dev = rockchip->dev; +@@ -255,6 +262,16 @@ int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) + } + } + ++ err = readx_poll_timeout(rockchip_pcie_read_addr, ++ PCIE_CLIENT_SIDE_BAND_STATUS, ++ regs, !(regs & PCIE_CLIENT_PHY_ST), ++ RK_PHY_PLL_LOCK_SLEEP_US, ++ RK_PHY_PLL_LOCK_TIMEOUT_US); ++ if (err) { ++ dev_err(dev, "PHY PLLs could not lock, %d\n", err); ++ goto err_power_off_phy; ++ } ++ + /* + * Please don't reorder the deassert sequence of the following + * four reset pins. +diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h +index 8e87a059ce73d..1c45b3c32151c 100644 +--- a/drivers/pci/controller/pcie-rockchip.h ++++ b/drivers/pci/controller/pcie-rockchip.h +@@ -37,6 +37,13 @@ + #define PCIE_CLIENT_MODE_EP HIWORD_UPDATE(0x0040, 0) + #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) + #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) ++#define PCIE_CLIENT_LEGACY_INT_CTRL (PCIE_CLIENT_BASE + 0x0c) ++#define PCIE_CLIENT_INT_IN_ASSERT HIWORD_UPDATE_BIT(0x0002) ++#define PCIE_CLIENT_INT_IN_DEASSERT HIWORD_UPDATE(0x0002, 0) ++#define PCIE_CLIENT_INT_PEND_ST_PEND HIWORD_UPDATE_BIT(0x0001) ++#define PCIE_CLIENT_INT_PEND_ST_NORMAL HIWORD_UPDATE(0x0001, 0) ++#define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20) ++#define PCIE_CLIENT_PHY_ST BIT(12) + #define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c) + #define PCIE_CLIENT_DEBUG_LTSSM_MASK GENMASK(5, 0) + #define PCIE_CLIENT_DEBUG_LTSSM_L1 0x18 +@@ -132,6 +139,8 @@ + #define PCIE_RC_RP_ATS_BASE 0x400000 + #define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 + #define PCIE_RC_CONFIG_BASE 0xa00000 ++#define PCIE_EP_CONFIG_BASE 0xa00000 ++#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00) + #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) + #define PCIE_RC_CONFIG_SCC_SHIFT 16 + #define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) +@@ -223,6 +232,7 @@ + #define ROCKCHIP_PCIE_EP_CMD_STATUS 0x4 + #define ROCKCHIP_PCIE_EP_CMD_STATUS_IS BIT(19) + #define ROCKCHIP_PCIE_EP_MSI_CTRL_REG 0x90 ++#define ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET 16 + #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET 17 + #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK GENMASK(19, 17) + #define ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET 20 +@@ -230,7 +240,6 @@ + #define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16) + #define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24) + #define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1 +-#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3 + #define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12)) + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ + (PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008) +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 7ac6f4710908b..c8326c7b468fa 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -2521,13 +2521,13 @@ static const struct dmi_system_id bridge_d3_blacklist[] = { + { + /* + * Downstream device is not accessible after putting a root port +- * into D3cold and back into D0 on Elo i2. ++ * into D3cold and back into D0 on Elo Continental Z2 board + */ +- .ident = "Elo i2", ++ .ident = "Elo Continental Z2", + .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Elo Touch Solutions"), +- DMI_MATCH(DMI_PRODUCT_NAME, "Elo i2"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "RevB"), ++ DMI_MATCH(DMI_BOARD_VENDOR, "Elo Touch Solutions"), ++ DMI_MATCH(DMI_BOARD_NAME, "Geminilake"), ++ DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), + }, + }, + #endif +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index 279f9f0197b01..eec62f7377f48 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -203,12 +203,39 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) + link->clkpm_disable = blacklist ? 1 : 0; + } + +-static bool pcie_retrain_link(struct pcie_link_state *link) ++static int pcie_wait_for_retrain(struct pci_dev *pdev) ++{ ++ unsigned long end_jiffies; ++ u16 reg16; ++ ++ /* Wait for Link Training to be cleared by hardware */ ++ end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; ++ do { ++ pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, ®16); ++ if (!(reg16 & PCI_EXP_LNKSTA_LT)) ++ return 0; ++ msleep(1); ++ } while (time_before(jiffies, end_jiffies)); ++ ++ return -ETIMEDOUT; ++} ++ ++static int pcie_retrain_link(struct pcie_link_state *link) + { + struct pci_dev *parent = link->pdev; +- unsigned long start_jiffies; ++ int rc; + u16 reg16; + ++ /* ++ * Ensure the updated LNKCTL parameters are used during link ++ * training by checking that there is no ongoing link training to ++ * avoid LTSSM race as recommended in Implementation Note at the ++ * end of PCIe r6.0.1 sec 7.5.3.7. ++ */ ++ rc = pcie_wait_for_retrain(parent); ++ if (rc) ++ return rc; ++ + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + reg16 |= PCI_EXP_LNKCTL_RL; + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); +@@ -222,17 +249,7 @@ static bool pcie_retrain_link(struct pcie_link_state *link) + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + } + +- /* Wait for link training end. Break out after waiting for timeout */ +- start_jiffies = jiffies; +- for (;;) { +- pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); +- if (!(reg16 & PCI_EXP_LNKSTA_LT)) +- break; +- if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) +- break; +- msleep(1); +- } +- return !(reg16 & PCI_EXP_LNKSTA_LT); ++ return pcie_wait_for_retrain(parent); + } + + /* +@@ -301,15 +318,15 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) + reg16 &= ~PCI_EXP_LNKCTL_CCC; + pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + +- if (pcie_retrain_link(link)) +- return; ++ if (pcie_retrain_link(link)) { + +- /* Training failed. Restore common clock configurations */ +- pci_err(parent, "ASPM: Could not configure common clock\n"); +- list_for_each_entry(child, &linkbus->devices, bus_list) +- pcie_capability_write_word(child, PCI_EXP_LNKCTL, ++ /* Training failed. Restore common clock configurations */ ++ pci_err(parent, "ASPM: Could not configure common clock\n"); ++ list_for_each_entry(child, &linkbus->devices, bus_list) ++ pcie_capability_write_word(child, PCI_EXP_LNKCTL, + child_reg[PCI_FUNC(child->devfn)]); +- pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); ++ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); ++ } + } + + /* Convert L0s latency encoding to ns */ +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index afa6acb58eec8..fa9d6c8f1cf89 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -4074,6 +4074,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, + /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */ + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230, + quirk_dma_func1_alias); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9235, ++ quirk_dma_func1_alias); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, + quirk_dma_func1_alias); + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645, +diff --git a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +index 524381249a2b8..b51e19402ab0c 100644 +--- a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c ++++ b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +@@ -167,7 +167,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) + phy_set_drvdata(phy, &priv->ports[i]); + i++; + +- if (i > INNO_PHY_PORT_NUM) { ++ if (i >= INNO_PHY_PORT_NUM) { + dev_warn(dev, "Support %d ports in maximum\n", i); + break; + } +diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c +index 25932d2a71547..ef8eb42e4d383 100644 +--- a/drivers/pinctrl/intel/pinctrl-cherryview.c ++++ b/drivers/pinctrl/intel/pinctrl-cherryview.c +@@ -1032,11 +1032,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin, + + break; + +- case PIN_CONFIG_DRIVE_OPEN_DRAIN: +- if (!(ctrl1 & CHV_PADCTRL1_ODEN)) +- return -EINVAL; +- break; +- + case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { + u32 cfg; + +@@ -1046,6 +1041,16 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin, + return -EINVAL; + + break; ++ ++ case PIN_CONFIG_DRIVE_PUSH_PULL: ++ if (ctrl1 & CHV_PADCTRL1_ODEN) ++ return -EINVAL; ++ break; ++ ++ case PIN_CONFIG_DRIVE_OPEN_DRAIN: ++ if (!(ctrl1 & CHV_PADCTRL1_ODEN)) ++ return -EINVAL; ++ break; + } + + default: +diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c +index a44902b140879..c140ee16fe7c8 100644 +--- a/drivers/pinctrl/pinctrl-amd.c ++++ b/drivers/pinctrl/pinctrl-amd.c +@@ -127,6 +127,14 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, + struct amd_gpio *gpio_dev = gpiochip_get_data(gc); + + raw_spin_lock_irqsave(&gpio_dev->lock, flags); ++ ++ /* Use special handling for Pin0 debounce */ ++ if (offset == 0) { ++ pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); ++ if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) ++ debounce = 0; ++ } ++ + pin_reg = readl(gpio_dev->base + offset * 4); + + if (debounce) { +@@ -182,18 +190,6 @@ static int amd_gpio_set_debounce(struct gpio_chip *gc, unsigned offset, + return ret; + } + +-static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset, +- unsigned long config) +-{ +- u32 debounce; +- +- if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) +- return -ENOTSUPP; +- +- debounce = pinconf_to_config_argument(config); +- return amd_gpio_set_debounce(gc, offset, debounce); +-} +- + #ifdef CONFIG_DEBUG_FS + static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) + { +@@ -216,6 +212,7 @@ static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) + char *output_value; + char *output_enable; + ++ seq_printf(s, "WAKE_INT_MASTER_REG: 0x%08x\n", readl(gpio_dev->base + WAKE_INT_MASTER_REG)); + for (bank = 0; bank < gpio_dev->hwbank_num; bank++) { + seq_printf(s, "GPIO bank%d\t", bank); + +@@ -677,7 +674,7 @@ static int amd_pinconf_get(struct pinctrl_dev *pctldev, + } + + static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, +- unsigned long *configs, unsigned num_configs) ++ unsigned long *configs, unsigned int num_configs) + { + int i; + u32 arg; +@@ -767,6 +764,20 @@ static int amd_pinconf_group_set(struct pinctrl_dev *pctldev, + return 0; + } + ++static int amd_gpio_set_config(struct gpio_chip *gc, unsigned int pin, ++ unsigned long config) ++{ ++ struct amd_gpio *gpio_dev = gpiochip_get_data(gc); ++ ++ if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) { ++ u32 debounce = pinconf_to_config_argument(config); ++ ++ return amd_gpio_set_debounce(gc, pin, debounce); ++ } ++ ++ return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1); ++} ++ + static const struct pinconf_ops amd_pinconf_ops = { + .pin_config_get = amd_pinconf_get, + .pin_config_set = amd_pinconf_set, +@@ -794,9 +805,9 @@ static void amd_gpio_irq_init(struct amd_gpio *gpio_dev) + + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + +- pin_reg = readl(gpio_dev->base + i * 4); ++ pin_reg = readl(gpio_dev->base + pin * 4); + pin_reg &= ~mask; +- writel(pin_reg, gpio_dev->base + i * 4); ++ writel(pin_reg, gpio_dev->base + pin * 4); + + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); + } +diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h +index 91da7527f0020..0f7c02bc9044a 100644 +--- a/drivers/pinctrl/pinctrl-amd.h ++++ b/drivers/pinctrl/pinctrl-amd.h +@@ -21,6 +21,7 @@ + #define AMD_GPIO_PINS_BANK3 32 + + #define WAKE_INT_MASTER_REG 0xfc ++#define INTERNAL_GPIO0_DEBOUNCE (1 << 15) + #define EOI_MASK (1 << 29) + + #define WAKE_INT_STATUS_REG0 0x2f8 +diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c +index 5b883eb49ce92..cbbda24bf6a80 100644 +--- a/drivers/pinctrl/pinctrl-at91-pio4.c ++++ b/drivers/pinctrl/pinctrl-at91-pio4.c +@@ -1024,6 +1024,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) + /* Pin naming convention: P(bank_name)(bank_pin_number). */ + pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d", + bank + 'A', line); ++ if (!pin_desc[i].name) ++ return -ENOMEM; + + group->name = group_names[i] = pin_desc[i].name; + group->pin = pin_desc[i].number; +diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c +index c26baf77938ea..96cc87d123292 100644 +--- a/drivers/platform/x86/hdaps.c ++++ b/drivers/platform/x86/hdaps.c +@@ -378,7 +378,7 @@ static ssize_t hdaps_variance_show(struct device *dev, + static ssize_t hdaps_temp1_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- u8 uninitialized_var(temp); ++ u8 temp; + int ret; + + ret = hdaps_readb_one(HDAPS_PORT_TEMP1, &temp); +@@ -391,7 +391,7 @@ static ssize_t hdaps_temp1_show(struct device *dev, + static ssize_t hdaps_temp2_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +- u8 uninitialized_var(temp); ++ u8 temp; + int ret; + + ret = hdaps_readb_one(HDAPS_PORT_TEMP2, &temp); +diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c +index 42b31c549db00..1781e67781a55 100644 +--- a/drivers/platform/x86/msi-laptop.c ++++ b/drivers/platform/x86/msi-laptop.c +@@ -223,7 +223,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask) + return -EINVAL; + + if (quirks->ec_read_only) +- return -EOPNOTSUPP; ++ return 0; + + /* read current device state */ + result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); +@@ -854,15 +854,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, + static void msi_init_rfkill(struct work_struct *ignored) + { + if (rfk_wlan) { +- rfkill_set_sw_state(rfk_wlan, !wlan_s); ++ msi_rfkill_set_state(rfk_wlan, !wlan_s); + rfkill_wlan_set(NULL, !wlan_s); + } + if (rfk_bluetooth) { +- rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); ++ msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); + rfkill_bluetooth_set(NULL, !bluetooth_s); + } + if (rfk_threeg) { +- rfkill_set_sw_state(rfk_threeg, !threeg_s); ++ msi_rfkill_set_state(rfk_threeg, !threeg_s); + rfkill_threeg_set(NULL, !threeg_s); + } + } +diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c +index e66439b6247a4..e8a8ca3545f00 100644 +--- a/drivers/rtc/rtc-st-lpc.c ++++ b/drivers/rtc/rtc-st-lpc.c +@@ -239,7 +239,7 @@ static int st_rtc_probe(struct platform_device *pdev) + enable_irq_wake(rtc->irq); + disable_irq(rtc->irq); + +- rtc->clk = clk_get(&pdev->dev, NULL); ++ rtc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(rtc->clk)) { + dev_err(&pdev->dev, "Unable to request clock\n"); + return PTR_ERR(rtc->clk); +diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c +index 2016e0ed58657..9f3f483137598 100644 +--- a/drivers/s390/block/dasd_ioctl.c ++++ b/drivers/s390/block/dasd_ioctl.c +@@ -137,6 +137,7 @@ static int dasd_ioctl_resume(struct dasd_block *block) + spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); + + dasd_schedule_block_bh(block); ++ dasd_schedule_device_bh(base); + return 0; + } + +diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c +index dc87a6b84d739..72e9e2945ee09 100644 +--- a/drivers/s390/scsi/zfcp_fc.c ++++ b/drivers/s390/scsi/zfcp_fc.c +@@ -534,8 +534,7 @@ static void zfcp_fc_adisc_handler(void *data) + + /* re-init to undo drop from zfcp_fc_adisc() */ + port->d_id = ntoh24(adisc_resp->adisc_port_id); +- /* port is good, unblock rport without going through erp */ +- zfcp_scsi_schedule_rport_register(port); ++ /* port is still good, nothing to do */ + out: + atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); + put_device(&port->dev); +@@ -595,9 +594,6 @@ void zfcp_fc_link_test_work(struct work_struct *work) + int retval; + + set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ +- get_device(&port->dev); +- port->rport_task = RPORT_DEL; +- zfcp_scsi_rport_work(&port->rport_work); + + /* only issue one test command at one time per port */ + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) +diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c +index 471366945bd4f..8a61e832607eb 100644 +--- a/drivers/scsi/3w-xxxx.c ++++ b/drivers/scsi/3w-xxxx.c +@@ -2303,8 +2303,10 @@ static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) + TW_DISABLE_INTERRUPTS(tw_dev); + + /* Initialize the card */ +- if (tw_reset_sequence(tw_dev)) ++ if (tw_reset_sequence(tw_dev)) { ++ retval = -EINVAL; + goto out_release_mem_region; ++ } + + /* Set host specific parameters */ + host->max_id = TW_MAX_UNITS; +diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c +index 8b5a07503d5f0..fdfa88e0d1d07 100644 +--- a/drivers/scsi/dc395x.c ++++ b/drivers/scsi/dc395x.c +@@ -4275,7 +4275,7 @@ static int adapter_sg_tables_alloc(struct AdapterCtlBlk *acb) + const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; + int srb_idx = 0; + unsigned i = 0; +- struct SGentry *uninitialized_var(ptr); ++ struct SGentry *ptr; + + for (i = 0; i < DC395x_MAX_SRB_CNT; i++) + acb->srb_array[i].segment_x = NULL; +diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c +index d532230c62f3e..69695bb99925b 100644 +--- a/drivers/scsi/pm8001/pm8001_hwi.c ++++ b/drivers/scsi/pm8001/pm8001_hwi.c +@@ -4174,7 +4174,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) + { + struct outbound_queue_table *circularQ; + void *pMsg1 = NULL; +- u8 uninitialized_var(bc); ++ u8 bc; + u32 ret = MPI_IO_STATUS_FAIL; + unsigned long flags; + +diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c +index d655f72db51d5..067be417e251b 100644 +--- a/drivers/scsi/pm8001/pm80xx_hwi.c ++++ b/drivers/scsi/pm8001/pm80xx_hwi.c +@@ -3811,7 +3811,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) + { + struct outbound_queue_table *circularQ; + void *pMsg1 = NULL; +- u8 uninitialized_var(bc); ++ u8 bc; + u32 ret = MPI_IO_STATUS_FAIL; + unsigned long flags; + u32 regval; +diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c +index d46a10d24ed4b..6c9095d0aa0f4 100644 +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -1800,6 +1800,7 @@ static void + qla2x00_terminate_rport_io(struct fc_rport *rport) + { + fc_port_t *fcport = *(fc_port_t **)rport->dd_data; ++ scsi_qla_host_t *vha; + + if (!fcport) + return; +@@ -1809,9 +1810,12 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) + + if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) + return; ++ vha = fcport->vha; + + if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { + qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); ++ qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, ++ 0, WAIT_TARGET); + return; + } + /* +@@ -1826,6 +1830,15 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) + else + qla2x00_port_logout(fcport->vha, fcport); + } ++ ++ /* check for any straggling io left behind */ ++ if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) { ++ ql_log(ql_log_warn, vha, 0x300b, ++ "IO not return. Resetting. \n"); ++ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); ++ qla2xxx_wake_dpc(vha); ++ qla2x00_wait_for_chip_reset(vha); ++ } + } + + static int +diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c +index eae1665729643..430dfe3d5416a 100644 +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -264,6 +264,10 @@ qla2x00_process_els(struct bsg_job *bsg_job) + + if (bsg_request->msgcode == FC_BSG_RPT_ELS) { + rport = fc_bsg_to_rport(bsg_job); ++ if (!rport) { ++ rval = -ENOMEM; ++ goto done; ++ } + fcport = *(fc_port_t **) rport->dd_data; + host = rport_to_shost(rport); + vha = shost_priv(host); +@@ -2484,6 +2488,8 @@ qla24xx_bsg_request(struct bsg_job *bsg_job) + + if (bsg_request->msgcode == FC_BSG_RPT_ELS) { + rport = fc_bsg_to_rport(bsg_job); ++ if (!rport) ++ return ret; + host = rport_to_shost(rport); + vha = shost_priv(host); + } else { +diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c +index 7e47321e003c8..23cd9ff824789 100644 +--- a/drivers/scsi/qla2xxx/qla_iocb.c ++++ b/drivers/scsi/qla2xxx/qla_iocb.c +@@ -603,7 +603,8 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, + *((uint32_t *)(&cmd_pkt->entry_type)) = cpu_to_le32(COMMAND_TYPE_6); + + /* No data transfer */ +- if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { ++ if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE || ++ tot_dsds == 0) { + cmd_pkt->byte_count = cpu_to_le32(0); + return 0; + } +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 7863ad1390f8a..4580774b2c3e7 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4604,7 +4604,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, + } + INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); + +- sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); ++ snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", ++ QLA2XXX_DRIVER_NAME, vha->host_no); + ql_dbg(ql_dbg_init, vha, 0x0041, + "Allocated the host=%p hw=%p vha=%p dev_name=%s", + vha->host, vha->hw, vha, +@@ -4735,7 +4736,7 @@ qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code) + + switch (code) { + case QLA_UEVENT_CODE_FW_DUMP: +- snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", ++ snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", + vha->host_no); + break; + default: +diff --git a/drivers/soc/fsl/qe/Kconfig b/drivers/soc/fsl/qe/Kconfig +index fabba17e9d65b..7ec158e2acf91 100644 +--- a/drivers/soc/fsl/qe/Kconfig ++++ b/drivers/soc/fsl/qe/Kconfig +@@ -37,6 +37,7 @@ config QE_TDM + + config QE_USB + bool ++ depends on QUICC_ENGINE + default y if USB_FSL_QE + help + QE USB Controller support +diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c +index 3f291db7b39a0..e3c69b6237708 100644 +--- a/drivers/spi/spi-bcm-qspi.c ++++ b/drivers/spi/spi-bcm-qspi.c +@@ -1255,13 +1255,9 @@ int bcm_qspi_probe(struct platform_device *pdev, + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "mspi"); + +- if (res) { +- qspi->base[MSPI] = devm_ioremap_resource(dev, res); +- if (IS_ERR(qspi->base[MSPI])) +- return PTR_ERR(qspi->base[MSPI]); +- } else { +- return 0; +- } ++ qspi->base[MSPI] = devm_ioremap_resource(dev, res); ++ if (IS_ERR(qspi->base[MSPI])) ++ return PTR_ERR(qspi->base[MSPI]); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); + if (res) { +diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c +index bfe5754768f97..cc6ec3fb5bfdf 100644 +--- a/drivers/spi/spi-bcm63xx.c ++++ b/drivers/spi/spi-bcm63xx.c +@@ -134,7 +134,7 @@ enum bcm63xx_regs_spi { + SPI_MSG_DATA_SIZE, + }; + +-#define BCM63XX_SPI_MAX_PREPEND 15 ++#define BCM63XX_SPI_MAX_PREPEND 7 + + #define BCM63XX_SPI_MAX_CS 8 + #define BCM63XX_SPI_BUS_NUM 0 +diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c +index 5e49fed487f8a..fd15b030b3815 100644 +--- a/drivers/spi/spi-fsl-spi.c ++++ b/drivers/spi/spi-fsl-spi.c +@@ -339,7 +339,7 @@ static int fsl_spi_do_one_msg(struct spi_master *master, + struct spi_transfer *t, *first; + unsigned int cs_change; + const int nsecs = 50; +- int status; ++ int status, last_bpw; + + /* + * In CPU mode, optimize large byte transfers to use larger +@@ -373,26 +373,27 @@ static int fsl_spi_do_one_msg(struct spi_master *master, + } + + /* Don't allow changes if CS is active */ +- first = list_first_entry(&m->transfers, struct spi_transfer, +- transfer_list); ++ cs_change = 1; + list_for_each_entry(t, &m->transfers, transfer_list) { +- if ((first->bits_per_word != t->bits_per_word) || +- (first->speed_hz != t->speed_hz)) { ++ if (cs_change) ++ first = t; ++ cs_change = t->cs_change; ++ if (first->speed_hz != t->speed_hz) { + dev_err(&spi->dev, +- "bits_per_word/speed_hz should be same for the same SPI transfer\n"); ++ "speed_hz cannot change while CS is active\n"); + return -EINVAL; + } + } + ++ last_bpw = -1; + cs_change = 1; + status = -EINVAL; + list_for_each_entry(t, &m->transfers, transfer_list) { +- if (t->bits_per_word || t->speed_hz) { +- if (cs_change) +- status = fsl_spi_setup_transfer(spi, t); +- if (status < 0) +- break; +- } ++ if (cs_change || last_bpw != t->bits_per_word) ++ status = fsl_spi_setup_transfer(spi, t); ++ if (status < 0) ++ break; ++ last_bpw = t->bits_per_word; + + if (cs_change) { + fsl_spi_chipselect(spi, BITBANG_CS_ACTIVE); +diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c +index 99a4656d113d5..832ee69f45f52 100644 +--- a/drivers/ssb/driver_chipcommon.c ++++ b/drivers/ssb/driver_chipcommon.c +@@ -119,7 +119,7 @@ void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, + static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc) + { + struct ssb_bus *bus = cc->dev->bus; +- u32 uninitialized_var(tmp); ++ u32 tmp; + + if (cc->dev->id.revision < 6) { + if (bus->bustype == SSB_BUSTYPE_SSB || +@@ -149,7 +149,7 @@ static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc) + /* Get maximum or minimum (depending on get_max flag) slowclock frequency. */ + static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max) + { +- int uninitialized_var(limit); ++ int limit; + enum ssb_clksrc clocksrc; + int divisor = 1; + u32 tmp; +diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c +index f624d0d53a8f2..1b6226efe15eb 100644 +--- a/drivers/staging/ks7010/ks_wlan_net.c ++++ b/drivers/staging/ks7010/ks_wlan_net.c +@@ -1584,8 +1584,10 @@ static int ks_wlan_set_encode_ext(struct net_device *dev, + commit |= SME_WEP_FLAG; + } + if (enc->key_len) { +- memcpy(&key->key_val[0], &enc->key[0], enc->key_len); +- key->key_len = enc->key_len; ++ int key_len = clamp_val(enc->key_len, 0, IW_ENCODING_TOKEN_MAX); ++ ++ memcpy(&key->key_val[0], &enc->key[0], key_len); ++ key->key_len = key_len; + commit |= (SME_WEP_VAL1 << index); + } + break; +diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c +index db048dbe9f785..6fec20c01ef15 100644 +--- a/drivers/tty/cyclades.c ++++ b/drivers/tty/cyclades.c +@@ -3648,7 +3648,7 @@ static int cy_pci_probe(struct pci_dev *pdev, + struct cyclades_card *card; + void __iomem *addr0 = NULL, *addr2 = NULL; + char *card_name = NULL; +- u32 uninitialized_var(mailbox); ++ u32 mailbox; + unsigned int device_id, nchan = 0, card_no, i, j; + unsigned char plx_ver; + int retval, irq; +diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c +index 8d96e86966f1b..274480a3c4b97 100644 +--- a/drivers/tty/isicom.c ++++ b/drivers/tty/isicom.c +@@ -1537,7 +1537,7 @@ static unsigned int card_count; + static int isicom_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +- unsigned int uninitialized_var(signature), index; ++ unsigned int signature, index; + int retval = -EPERM; + struct isi_board *board = NULL; + +diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h +index 8c8aa3b9c2989..b0c5f0dba6fcc 100644 +--- a/drivers/tty/serial/8250/8250.h ++++ b/drivers/tty/serial/8250/8250.h +@@ -85,7 +85,6 @@ struct serial8250_config { + #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ + #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ + #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ +-#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ + + + #ifdef CONFIG_SERIAL_8250_SHARE_IRQ +diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c +new file mode 100644 +index 0000000000000..1cf229cca5928 +--- /dev/null ++++ b/drivers/tty/serial/8250/8250_dwlib.c +@@ -0,0 +1,128 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* Synopsys DesignWare 8250 library. */ ++ ++#include <linux/bitops.h> ++#include <linux/device.h> ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <linux/serial_8250.h> ++#include <linux/serial_core.h> ++ ++#include "8250_dwlib.h" ++ ++/* Offsets for the DesignWare specific registers */ ++#define DW_UART_DLF 0xc0 /* Divisor Latch Fraction Register */ ++#define DW_UART_CPR 0xf4 /* Component Parameter Register */ ++#define DW_UART_UCV 0xf8 /* UART Component Version */ ++ ++/* Component Parameter Register bits */ ++#define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) ++#define DW_UART_CPR_AFCE_MODE (1 << 4) ++#define DW_UART_CPR_THRE_MODE (1 << 5) ++#define DW_UART_CPR_SIR_MODE (1 << 6) ++#define DW_UART_CPR_SIR_LP_MODE (1 << 7) ++#define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) ++#define DW_UART_CPR_FIFO_ACCESS (1 << 9) ++#define DW_UART_CPR_FIFO_STAT (1 << 10) ++#define DW_UART_CPR_SHADOW (1 << 11) ++#define DW_UART_CPR_ENCODED_PARMS (1 << 12) ++#define DW_UART_CPR_DMA_EXTRA (1 << 13) ++#define DW_UART_CPR_FIFO_MODE (0xff << 16) ++ ++/* Helper for FIFO size calculation */ ++#define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) ++ ++static inline u32 dw8250_readl_ext(struct uart_port *p, int offset) ++{ ++ if (p->iotype == UPIO_MEM32BE) ++ return ioread32be(p->membase + offset); ++ return readl(p->membase + offset); ++} ++ ++static inline void dw8250_writel_ext(struct uart_port *p, int offset, u32 reg) ++{ ++ if (p->iotype == UPIO_MEM32BE) ++ iowrite32be(reg, p->membase + offset); ++ else ++ writel(reg, p->membase + offset); ++} ++ ++/* ++ * divisor = div(I) + div(F) ++ * "I" means integer, "F" means fractional ++ * quot = div(I) = clk / (16 * baud) ++ * frac = div(F) * 2^dlf_size ++ * ++ * let rem = clk % (16 * baud) ++ * we have: div(F) * (16 * baud) = rem ++ * so frac = 2^dlf_size * rem / (16 * baud) = (rem << dlf_size) / (16 * baud) ++ */ ++static unsigned int dw8250_get_divisor(struct uart_port *p, unsigned int baud, ++ unsigned int *frac) ++{ ++ unsigned int quot, rem, base_baud = baud * 16; ++ struct dw8250_port_data *d = p->private_data; ++ ++ quot = p->uartclk / base_baud; ++ rem = p->uartclk % base_baud; ++ *frac = DIV_ROUND_CLOSEST(rem << d->dlf_size, base_baud); ++ ++ return quot; ++} ++ ++static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, ++ unsigned int quot, unsigned int quot_frac) ++{ ++ dw8250_writel_ext(p, DW_UART_DLF, quot_frac); ++ serial8250_do_set_divisor(p, baud, quot, quot_frac); ++} ++ ++void dw8250_setup_port(struct uart_port *p) ++{ ++ struct uart_8250_port *up = up_to_u8250p(p); ++ u32 reg, old_dlf; ++ ++ /* ++ * If the Component Version Register returns zero, we know that ++ * ADDITIONAL_FEATURES are not enabled. No need to go any further. ++ */ ++ reg = dw8250_readl_ext(p, DW_UART_UCV); ++ if (!reg) ++ return; ++ ++ dev_dbg(p->dev, "Designware UART version %c.%c%c\n", ++ (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); ++ ++ /* Preserve value written by firmware or bootloader */ ++ old_dlf = dw8250_readl_ext(p, DW_UART_DLF); ++ dw8250_writel_ext(p, DW_UART_DLF, ~0U); ++ reg = dw8250_readl_ext(p, DW_UART_DLF); ++ dw8250_writel_ext(p, DW_UART_DLF, old_dlf); ++ ++ if (reg) { ++ struct dw8250_port_data *d = p->private_data; ++ ++ d->dlf_size = fls(reg); ++ p->get_divisor = dw8250_get_divisor; ++ p->set_divisor = dw8250_set_divisor; ++ } ++ ++ reg = dw8250_readl_ext(p, DW_UART_CPR); ++ if (!reg) ++ return; ++ ++ /* Select the type based on FIFO */ ++ if (reg & DW_UART_CPR_FIFO_MODE) { ++ p->type = PORT_16550A; ++ p->flags |= UPF_FIXED_TYPE; ++ p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); ++ up->capabilities = UART_CAP_FIFO; ++ } ++ ++ if (reg & DW_UART_CPR_AFCE_MODE) ++ up->capabilities |= UART_CAP_AFE; ++ ++ if (reg & DW_UART_CPR_SIR_MODE) ++ up->capabilities |= UART_CAP_IRDA; ++} ++EXPORT_SYMBOL_GPL(dw8250_setup_port); +diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h +new file mode 100644 +index 0000000000000..87a4db2a8aba6 +--- /dev/null ++++ b/drivers/tty/serial/8250/8250_dwlib.h +@@ -0,0 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* Synopsys DesignWare 8250 library header file. */ ++ ++#include <linux/types.h> ++ ++#include "8250.h" ++ ++struct dw8250_port_data { ++ /* Port properties */ ++ int line; ++ ++ /* DMA operations */ ++ struct uart_8250_dma dma; ++ ++ /* Hardware configuration */ ++ u8 dlf_size; ++}; ++ ++void dw8250_setup_port(struct uart_port *p); +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 274e644f34f27..2c224bf70cfd0 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -1049,14 +1049,6 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev) + return number_uarts; + } + +-static int pci_asix_setup(struct serial_private *priv, +- const struct pciserial_board *board, +- struct uart_8250_port *port, int idx) +-{ +- port->bugs |= UART_BUG_PARITY; +- return pci_default_setup(priv, board, port, idx); +-} +- + /* Quatech devices have their own extra interface features */ + + struct quatech_feature { +@@ -1683,7 +1675,6 @@ pci_wch_ch38x_setup(struct serial_private *priv, + #define PCI_DEVICE_ID_WCH_CH355_4S 0x7173 + #define PCI_VENDOR_ID_AGESTAR 0x5372 + #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 +-#define PCI_VENDOR_ID_ASIX 0x9710 + #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a + #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e + +@@ -2454,16 +2445,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch38x_setup, + }, +- /* +- * ASIX devices with FIFO bug +- */ +- { +- .vendor = PCI_VENDOR_ID_ASIX, +- .device = PCI_ANY_ID, +- .subvendor = PCI_ANY_ID, +- .subdevice = PCI_ANY_ID, +- .setup = pci_asix_setup, +- }, + /* + * Broadcom TruManage (NetXtreme) + */ +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index cba4888bc4824..66de3a59f5779 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -2617,11 +2617,8 @@ static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, + + if (c_cflag & CSTOPB) + cval |= UART_LCR_STOP; +- if (c_cflag & PARENB) { ++ if (c_cflag & PARENB) + cval |= UART_LCR_PARITY; +- if (up->bugs & UART_BUG_PARITY) +- up->fifo_bug = true; +- } + if (!(c_cflag & PARODD)) + cval |= UART_LCR_EPAR; + #ifdef CMSPAR +@@ -2735,8 +2732,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + up->lcr = cval; /* Save computed LCR */ + + if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { +- /* NOTE: If fifo_bug is not set, a user can set RX_trigger. */ +- if ((baud < 2400 && !up->dma) || up->fifo_bug) { ++ if (baud < 2400 && !up->dma) { + up->fcr &= ~UART_FCR_TRIGGER_MASK; + up->fcr |= UART_FCR_TRIGGER_1; + } +@@ -3072,8 +3068,7 @@ static int do_set_rxtrig(struct tty_port *port, unsigned char bytes) + struct uart_8250_port *up = up_to_u8250p(uport); + int rxtrig; + +- if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1 || +- up->fifo_bug) ++ if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1) + return -EINVAL; + + rxtrig = bytes_to_fcr_rxtrig(up, bytes); +diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig +index a9ddd76d41701..733ac320938c1 100644 +--- a/drivers/tty/serial/8250/Kconfig ++++ b/drivers/tty/serial/8250/Kconfig +@@ -312,6 +312,9 @@ config SERIAL_8250_RSA + + If you don't have such card, or if unsure, say N. + ++config SERIAL_8250_DWLIB ++ bool ++ + config SERIAL_8250_ACORN + tristate "Acorn expansion card serial port support" + depends on ARCH_ACORN && SERIAL_8250 +diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile +index 18751bc63a848..9b451d81588b2 100644 +--- a/drivers/tty/serial/8250/Makefile ++++ b/drivers/tty/serial/8250/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o + 8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o + 8250_base-y := 8250_port.o + 8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o ++8250_base-$(CONFIG_SERIAL_8250_DWLIB) += 8250_dwlib.o + 8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o + obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o + obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index 50c4058a00e6a..1688c190fc7d8 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -791,11 +791,11 @@ static void atmel_complete_tx_dma(void *arg) + + port->icount.tx += atmel_port->tx_len; + +- spin_lock_irq(&atmel_port->lock_tx); ++ spin_lock(&atmel_port->lock_tx); + async_tx_ack(atmel_port->desc_tx); + atmel_port->cookie_tx = -EINVAL; + atmel_port->desc_tx = NULL; +- spin_unlock_irq(&atmel_port->lock_tx); ++ spin_unlock(&atmel_port->lock_tx); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); +diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c +index 964d6d33b6097..5f1f52cc63951 100644 +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -1199,8 +1199,12 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, + continue; + + rate = clk_get_rate(clk); +- if (!rate) ++ if (!rate) { ++ dev_err(ourport->port.dev, ++ "Failed to get clock rate for %s.\n", clkname); ++ clk_put(clk); + continue; ++ } + + if (ourport->info->has_divslot) { + unsigned long div = rate / req_baud; +@@ -1226,10 +1230,18 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, + calc_deviation = -calc_deviation; + + if (calc_deviation < deviation) { ++ /* ++ * If we find a better clk, release the previous one, if ++ * any. ++ */ ++ if (!IS_ERR(*best_clk)) ++ clk_put(*best_clk); + *best_clk = clk; + best_quot = quot; + *clk_num = cnt; + deviation = calc_deviation; ++ } else { ++ clk_put(clk); + } + } + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 1346c600ebedf..48cda9b7a8f24 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = { + /* novation SoundControl XL */ + { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Focusrite Scarlett Solo USB */ ++ { USB_DEVICE(0x1235, 0x8211), .driver_info = ++ USB_QUIRK_DISCONNECT_SUSPEND }, ++ + /* Huawei 4G LTE module */ + { USB_DEVICE(0x12d1, 0x15bb), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index 81a5ca15b9c7a..d31cc8d75595d 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -242,9 +242,9 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) + /* + * We're resetting only the device side because, if we're in host mode, + * XHCI driver will reset the host block. If dwc3 was configured for +- * host-only mode, then we can return early. ++ * host-only mode or current role is host, then we can return early. + */ +- if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) ++ if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) + return 0; + + reg = dwc3_readl(dwc->regs, DWC3_DCTL); +@@ -993,22 +993,6 @@ static int dwc3_core_init(struct dwc3 *dwc) + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + } + +- if (dwc->dr_mode == USB_DR_MODE_HOST || +- dwc->dr_mode == USB_DR_MODE_OTG) { +- reg = dwc3_readl(dwc->regs, DWC3_GUCTL); +- +- /* +- * Enable Auto retry Feature to make the controller operating in +- * Host mode on seeing transaction errors(CRC errors or internal +- * overrun scenerios) on IN transfers to reply to the device +- * with a non-terminating retry ACK (i.e, an ACK transcation +- * packet with Retry=1 & Nump != 0) +- */ +- reg |= DWC3_GUCTL_HSTINAUTORETRY; +- +- dwc3_writel(dwc->regs, DWC3_GUCTL, reg); +- } +- + /* + * Must config both number of packets and max burst settings to enable + * RX and/or TX threshold. +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index 55ee41283f395..a1d65e36a4d41 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -238,9 +238,6 @@ + #define DWC3_GCTL_GBLHIBERNATIONEN BIT(1) + #define DWC3_GCTL_DSBLCLKGTNG BIT(0) + +-/* Global User Control Register */ +-#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) +- + /* Global User Control 1 Register */ + #define DWC3_GUCTL1_PARKMODE_DISABLE_SS BIT(17) + #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index 955bf820f4102..8d4f1b13f4157 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -171,10 +171,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) + + /* + * A lot of BYT devices lack ACPI resource entries for +- * the GPIOs, add a fallback mapping to the reference ++ * the GPIOs. If the ACPI entry for the GPIO controller ++ * is present add a fallback mapping to the reference + * design GPIOs which all boards seem to use. + */ +- gpiod_add_lookup_table(&platform_bytcr_gpios); ++ if (acpi_dev_present("INT33FC", NULL, -1)) ++ gpiod_add_lookup_table(&platform_bytcr_gpios); + + /* + * These GPIOs will turn on the USB2 PHY. Note that we have to +diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c +index ec6739ef3129e..687aeab64e4db 100644 +--- a/drivers/usb/host/ohci-at91.c ++++ b/drivers/usb/host/ohci-at91.c +@@ -642,7 +642,13 @@ ohci_hcd_at91_drv_resume(struct device *dev) + + at91_start_clock(ohci_at91); + +- ohci_resume(hcd, false); ++ /* ++ * According to the comment in ohci_hcd_at91_drv_suspend() ++ * we need to do a reset if the 48Mhz clock was stopped, ++ * that is, if ohci_at91->wakeup is clear. Tell ohci_resume() ++ * to reset in this case by setting its "hibernated" flag. ++ */ ++ ohci_resume(hcd, !ohci_at91->wakeup); + + ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); + +diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c +index f4b2e766f195b..cb22beb55f7e0 100644 +--- a/drivers/usb/host/xhci-mtk.c ++++ b/drivers/usb/host/xhci-mtk.c +@@ -538,6 +538,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) + } + + device_init_wakeup(dev, true); ++ dma_set_max_seg_size(dev, UINT_MAX); + + xhci = hcd_to_xhci(hcd); + xhci->main_hcd = hcd; +diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c +index b4d6d9bb32395..c545b27ea5681 100644 +--- a/drivers/usb/musb/cppi_dma.c ++++ b/drivers/usb/musb/cppi_dma.c +@@ -1146,7 +1146,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) + struct musb_hw_ep *hw_ep = NULL; + u32 rx, tx; + int i, index; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + + cppi = container_of(musb->dma_controller, struct cppi, controller); + if (cppi->irq) +diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c +index 60d390e28289f..2923a7f6952dc 100644 +--- a/drivers/usb/phy/phy-tahvo.c ++++ b/drivers/usb/phy/phy-tahvo.c +@@ -398,7 +398,7 @@ static int tahvo_usb_probe(struct platform_device *pdev) + + tu->irq = ret = platform_get_irq(pdev, 0); + if (ret < 0) +- return ret; ++ goto err_remove_phy; + ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, + IRQF_ONESHOT, + "tahvo-vbus", tu); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 126e276edd2ed..cf68a422e75e4 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -251,6 +251,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_EM061K_LTA 0x0123 + #define QUECTEL_PRODUCT_EM061K_LMS 0x0124 + #define QUECTEL_PRODUCT_EC25 0x0125 ++#define QUECTEL_PRODUCT_EM060K_128 0x0128 + #define QUECTEL_PRODUCT_EG91 0x0191 + #define QUECTEL_PRODUCT_EG95 0x0195 + #define QUECTEL_PRODUCT_BG96 0x0296 +@@ -268,6 +269,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_RM520N 0x0801 + #define QUECTEL_PRODUCT_EC200U 0x0901 + #define QUECTEL_PRODUCT_EC200S_CN 0x6002 ++#define QUECTEL_PRODUCT_EC200A 0x6005 + #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 + #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 + #define QUECTEL_PRODUCT_EC200T 0x6026 +@@ -1151,6 +1153,10 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa), + .driver_info = RSVD(3) }, + /* u-blox products */ ++ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1311) }, /* u-blox LARA-R6 01B */ ++ { USB_DEVICE(UBLOX_VENDOR_ID, 0x1312), /* u-blox LARA-R6 01B (RMNET) */ ++ .driver_info = RSVD(4) }, ++ { USB_DEVICE_INTERFACE_CLASS(UBLOX_VENDOR_ID, 0x1313, 0xff) }, /* u-blox LARA-R6 01B (ECM) */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) }, /* u-blox LARA-L6 */ + { USB_DEVICE(UBLOX_VENDOR_ID, 0x1342), /* u-blox LARA-L6 (RMNET) */ + .driver_info = RSVD(4) }, +@@ -1193,6 +1199,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) }, +@@ -1221,6 +1230,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */ + .driver_info = ZLP }, ++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, +diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c +index 4c6747889a194..24b8772a345e2 100644 +--- a/drivers/usb/serial/usb-serial-simple.c ++++ b/drivers/usb/serial/usb-serial-simple.c +@@ -38,16 +38,6 @@ static struct usb_serial_driver vendor##_device = { \ + { USB_DEVICE(0x0a21, 0x8001) } /* MMT-7305WW */ + DEVICE(carelink, CARELINK_IDS); + +-/* ZIO Motherboard USB driver */ +-#define ZIO_IDS() \ +- { USB_DEVICE(0x1CBE, 0x0103) } +-DEVICE(zio, ZIO_IDS); +- +-/* Funsoft Serial USB driver */ +-#define FUNSOFT_IDS() \ +- { USB_DEVICE(0x1404, 0xcddc) } +-DEVICE(funsoft, FUNSOFT_IDS); +- + /* Infineon Flashloader driver */ + #define FLASHLOADER_IDS() \ + { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \ +@@ -55,6 +45,11 @@ DEVICE(funsoft, FUNSOFT_IDS); + { USB_DEVICE(0x8087, 0x0801) } + DEVICE(flashloader, FLASHLOADER_IDS); + ++/* Funsoft Serial USB driver */ ++#define FUNSOFT_IDS() \ ++ { USB_DEVICE(0x1404, 0xcddc) } ++DEVICE(funsoft, FUNSOFT_IDS); ++ + /* Google Serial USB SubClass */ + #define GOOGLE_IDS() \ + { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \ +@@ -63,16 +58,21 @@ DEVICE(flashloader, FLASHLOADER_IDS); + 0x01) } + DEVICE(google, GOOGLE_IDS); + ++/* HP4x (48/49) Generic Serial driver */ ++#define HP4X_IDS() \ ++ { USB_DEVICE(0x03f0, 0x0121) } ++DEVICE(hp4x, HP4X_IDS); ++ ++/* KAUFMANN RKS+CAN VCP */ ++#define KAUFMANN_IDS() \ ++ { USB_DEVICE(0x16d0, 0x0870) } ++DEVICE(kaufmann, KAUFMANN_IDS); ++ + /* Libtransistor USB console */ + #define LIBTRANSISTOR_IDS() \ + { USB_DEVICE(0x1209, 0x8b00) } + DEVICE(libtransistor, LIBTRANSISTOR_IDS); + +-/* ViVOpay USB Serial Driver */ +-#define VIVOPAY_IDS() \ +- { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ +-DEVICE(vivopay, VIVOPAY_IDS); +- + /* Motorola USB Phone driver */ + #define MOTO_IDS() \ + { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ \ +@@ -101,10 +101,10 @@ DEVICE(nokia, NOKIA_IDS); + { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */ + DEVICE_N(novatel_gps, NOVATEL_IDS, 3); + +-/* HP4x (48/49) Generic Serial driver */ +-#define HP4X_IDS() \ +- { USB_DEVICE(0x03f0, 0x0121) } +-DEVICE(hp4x, HP4X_IDS); ++/* Siemens USB/MPI adapter */ ++#define SIEMENS_IDS() \ ++ { USB_DEVICE(0x908, 0x0004) } ++DEVICE(siemens_mpi, SIEMENS_IDS); + + /* Suunto ANT+ USB Driver */ + #define SUUNTO_IDS() \ +@@ -112,45 +112,52 @@ DEVICE(hp4x, HP4X_IDS); + { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */ + DEVICE(suunto, SUUNTO_IDS); + +-/* Siemens USB/MPI adapter */ +-#define SIEMENS_IDS() \ +- { USB_DEVICE(0x908, 0x0004) } +-DEVICE(siemens_mpi, SIEMENS_IDS); ++/* ViVOpay USB Serial Driver */ ++#define VIVOPAY_IDS() \ ++ { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ ++DEVICE(vivopay, VIVOPAY_IDS); ++ ++/* ZIO Motherboard USB driver */ ++#define ZIO_IDS() \ ++ { USB_DEVICE(0x1CBE, 0x0103) } ++DEVICE(zio, ZIO_IDS); + + /* All of the above structures mushed into two lists */ + static struct usb_serial_driver * const serial_drivers[] = { + &carelink_device, +- &zio_device, +- &funsoft_device, + &flashloader_device, ++ &funsoft_device, + &google_device, ++ &hp4x_device, ++ &kaufmann_device, + &libtransistor_device, +- &vivopay_device, + &moto_modem_device, + &motorola_tetra_device, + &nokia_device, + &novatel_gps_device, +- &hp4x_device, +- &suunto_device, + &siemens_mpi_device, ++ &suunto_device, ++ &vivopay_device, ++ &zio_device, + NULL + }; + + static const struct usb_device_id id_table[] = { + CARELINK_IDS(), +- ZIO_IDS(), +- FUNSOFT_IDS(), + FLASHLOADER_IDS(), ++ FUNSOFT_IDS(), + GOOGLE_IDS(), ++ HP4X_IDS(), ++ KAUFMANN_IDS(), + LIBTRANSISTOR_IDS(), +- VIVOPAY_IDS(), + MOTO_IDS(), + MOTOROLA_TETRA_IDS(), + NOKIA_IDS(), + NOVATEL_IDS(), +- HP4X_IDS(), +- SUUNTO_IDS(), + SIEMENS_IDS(), ++ SUUNTO_IDS(), ++ VIVOPAY_IDS(), ++ ZIO_IDS(), + { }, + }; + MODULE_DEVICE_TABLE(usb, id_table); +diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c +index b8527c55335b6..35306c0559622 100644 +--- a/drivers/usb/storage/sddr55.c ++++ b/drivers/usb/storage/sddr55.c +@@ -553,8 +553,8 @@ static int sddr55_reset(struct us_data *us) + + static unsigned long sddr55_get_capacity(struct us_data *us) { + +- unsigned char uninitialized_var(manufacturerID); +- unsigned char uninitialized_var(deviceID); ++ unsigned char manufacturerID; ++ unsigned char deviceID; + int result; + struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; + +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 5ea7b0a94fe38..4dc1842e3e8e1 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -828,7 +828,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, + /* len is always initialized before use since we are always called with + * datalen > 0. + */ +- u32 uninitialized_var(len); ++ u32 len; + + while (datalen > 0 && headcount < quota) { + if (unlikely(seg >= UIO_MAXIOV)) { +@@ -885,7 +885,7 @@ static void handle_rx(struct vhost_net *net) + { + struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_RX]; + struct vhost_virtqueue *vq = &nvq->vq; +- unsigned uninitialized_var(in), log; ++ unsigned in, log; + struct vhost_log *vq_log; + struct msghdr msg = { + .msg_name = NULL, +diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c +index f8e83a9519189..593c390e98629 100644 +--- a/drivers/video/fbdev/au1200fb.c ++++ b/drivers/video/fbdev/au1200fb.c +@@ -1744,6 +1744,9 @@ static int au1200fb_drv_probe(struct platform_device *dev) + + /* Now hook interrupt too */ + irq = platform_get_irq(dev, 0); ++ if (irq < 0) ++ return irq; ++ + ret = request_irq(irq, au1200fb_handle_irq, + IRQF_SHARED, "lcd", (void *)dev); + if (ret) { +diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c +index ecdcf358ad5ea..4a3f89b223600 100644 +--- a/drivers/video/fbdev/imsttfb.c ++++ b/drivers/video/fbdev/imsttfb.c +@@ -1348,7 +1348,7 @@ static struct fb_ops imsttfb_ops = { + .fb_ioctl = imsttfb_ioctl, + }; + +-static void init_imstt(struct fb_info *info) ++static int init_imstt(struct fb_info *info) + { + struct imstt_par *par = info->par; + __u32 i, tmp, *ip, *end; +@@ -1420,7 +1420,7 @@ static void init_imstt(struct fb_info *info) + || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { + printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); + framebuffer_release(info); +- return; ++ return -ENODEV; + } + + sprintf(info->fix.id, "IMS TT (%s)", par->ramdac == IBM ? "IBM" : "TVP"); +@@ -1456,12 +1456,13 @@ static void init_imstt(struct fb_info *info) + + if (register_framebuffer(info) < 0) { + framebuffer_release(info); +- return; ++ return -ENODEV; + } + + tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8; + fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n", + info->fix.id, info->fix.smem_len >> 20, tmp); ++ return 0; + } + + static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +@@ -1470,6 +1471,7 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + struct imstt_par *par; + struct fb_info *info; + struct device_node *dp; ++ int ret = -ENOMEM; + + dp = pci_device_to_OF_node(pdev); + if(dp) +@@ -1508,23 +1510,37 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + default: + printk(KERN_INFO "imsttfb: Device 0x%x unknown, " + "contact maintainer.\n", pdev->device); +- release_mem_region(addr, size); +- framebuffer_release(info); +- return -ENODEV; ++ ret = -ENODEV; ++ goto error; + } + + info->fix.smem_start = addr; + info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? + 0x400000 : 0x800000); ++ if (!info->screen_base) ++ goto error; + info->fix.mmio_start = addr + 0x800000; + par->dc_regs = ioremap(addr + 0x800000, 0x1000); ++ if (!par->dc_regs) ++ goto error; + par->cmap_regs_phys = addr + 0x840000; + par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); ++ if (!par->cmap_regs) ++ goto error; + info->pseudo_palette = par->palette; +- init_imstt(info); +- +- pci_set_drvdata(pdev, info); +- return 0; ++ ret = init_imstt(info); ++ if (!ret) ++ pci_set_drvdata(pdev, info); ++ return ret; ++ ++error: ++ if (par->dc_regs) ++ iounmap(par->dc_regs); ++ if (info->screen_base) ++ iounmap(info->screen_base); ++ release_mem_region(addr, size); ++ framebuffer_release(info); ++ return ret; + } + + static void imsttfb_remove(struct pci_dev *pdev) +diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c +index c4eb8661f7516..8ec260ed9a6f6 100644 +--- a/drivers/video/fbdev/imxfb.c ++++ b/drivers/video/fbdev/imxfb.c +@@ -601,10 +601,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf + if (var->hsync_len < 1 || var->hsync_len > 64) + printk(KERN_ERR "%s: invalid hsync_len %d\n", + info->fix.id, var->hsync_len); +- if (var->left_margin > 255) ++ if (var->left_margin < 3 || var->left_margin > 255) + printk(KERN_ERR "%s: invalid left_margin %d\n", + info->fix.id, var->left_margin); +- if (var->right_margin > 255) ++ if (var->right_margin < 1 || var->right_margin > 255) + printk(KERN_ERR "%s: invalid right_margin %d\n", + info->fix.id, var->right_margin); + if (var->yres < 1 || var->yres > ymax_mask) +diff --git a/drivers/video/fbdev/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c +index bf5ce04f9aea5..267b31ddb02d3 100644 +--- a/drivers/video/fbdev/matrox/matroxfb_maven.c ++++ b/drivers/video/fbdev/matrox/matroxfb_maven.c +@@ -299,7 +299,7 @@ static int matroxfb_mavenclock(const struct matrox_pll_ctl *ctl, + unsigned int* in, unsigned int* feed, unsigned int* post, + unsigned int* htotal2) { + unsigned int fvco; +- unsigned int uninitialized_var(p); ++ unsigned int p; + + fvco = matroxfb_PLL_mavenclock(&maven1000_pll, ctl, htotal, vtotal, in, feed, &p, htotal2); + if (!fvco) +@@ -731,8 +731,8 @@ static int maven_find_exact_clocks(unsigned int ht, unsigned int vt, + + for (x = 0; x < 8; x++) { + unsigned int c; +- unsigned int uninitialized_var(a), uninitialized_var(b), +- uninitialized_var(h2); ++ unsigned int a, b, ++ h2; + unsigned int h = ht + 2 + x; + + if (!matroxfb_mavenclock((m->mode == MATROXFB_OUTPUT_MODE_PAL) ? &maven_PAL : &maven_NTSC, h, vt, &a, &b, &c, &h2)) { +diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c +index e3a85432f9266..5730355ee5986 100644 +--- a/drivers/video/fbdev/omap/lcd_mipid.c ++++ b/drivers/video/fbdev/omap/lcd_mipid.c +@@ -576,11 +576,15 @@ static int mipid_spi_probe(struct spi_device *spi) + + r = mipid_detect(md); + if (r < 0) +- return r; ++ goto free_md; + + omapfb_register_panel(&md->panel); + + return 0; ++ ++free_md: ++ kfree(md); ++ return r; + } + + static int mipid_spi_remove(struct spi_device *spi) +diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c +index 6130aa56a1e93..7bd45334dcac4 100644 +--- a/drivers/video/fbdev/pm3fb.c ++++ b/drivers/video/fbdev/pm3fb.c +@@ -821,9 +821,9 @@ static void pm3fb_write_mode(struct fb_info *info) + + wmb(); + { +- unsigned char uninitialized_var(m); /* ClkPreScale */ +- unsigned char uninitialized_var(n); /* ClkFeedBackScale */ +- unsigned char uninitialized_var(p); /* ClkPostScale */ ++ unsigned char m; /* ClkPreScale */ ++ unsigned char n; /* ClkFeedBackScale */ ++ unsigned char p; /* ClkPostScale */ + unsigned long pixclock = PICOS2KHZ(info->var.pixclock); + + (void)pm3fb_calculate_clock(pixclock, &m, &n, &p); +diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c +index 0601c13f21050..f90b9327bae73 100644 +--- a/drivers/video/fbdev/riva/riva_hw.c ++++ b/drivers/video/fbdev/riva/riva_hw.c +@@ -1245,8 +1245,7 @@ int CalcStateExt + ) + { + int pixelDepth; +- int uninitialized_var(VClk),uninitialized_var(m), +- uninitialized_var(n), uninitialized_var(p); ++ int VClk, m, n, p; + + /* + * Save mode parameters. +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 0cc0cfd3a3cb7..8acfbe420b5a0 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -268,7 +268,7 @@ static inline int virtqueue_add(struct virtqueue *_vq, + struct vring_virtqueue *vq = to_vvq(_vq); + struct scatterlist *sg; + struct vring_desc *desc; +- unsigned int i, n, avail, descs_used, uninitialized_var(prev), err_idx; ++ unsigned int i, n, avail, descs_used, prev, err_idx; + int head; + bool indirect; + +diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c +index cb3650efc29cd..8db9ca241d99c 100644 +--- a/drivers/w1/w1.c ++++ b/drivers/w1/w1.c +@@ -1237,10 +1237,10 @@ err_out_exit_init: + + static void __exit w1_fini(void) + { +- struct w1_master *dev; ++ struct w1_master *dev, *n; + + /* Set netlink removal messages and some cleanup */ +- list_for_each_entry(dev, &w1_masters, w1_master_entry) ++ list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) + __w1_remove_master_device(dev); + + w1_fini_netlink(); +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index 59eb924840518..31055d71b7882 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -887,7 +887,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, + static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + { + struct afs_vnode *vnode, *dir; +- struct afs_fid uninitialized_var(fid); ++ struct afs_fid fid; + struct dentry *parent; + struct inode *inode; + struct key *key; +diff --git a/fs/afs/security.c b/fs/afs/security.c +index 66042b432baa8..e12e532069eef 100644 +--- a/fs/afs/security.c ++++ b/fs/afs/security.c +@@ -340,7 +340,7 @@ int afs_check_permit(struct afs_vnode *vnode, struct key *key, + int afs_permission(struct inode *inode, int mask) + { + struct afs_vnode *vnode = AFS_FS_I(inode); +- afs_access_t uninitialized_var(access); ++ afs_access_t access; + struct key *key; + int ret; + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 34d56f0fa7501..e48c6d7a860f4 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -3590,6 +3590,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, + + ret = tree_mod_log_eb_copy(fs_info, split, c, 0, mid, c_nritems - mid); + if (ret) { ++ btrfs_tree_unlock(split); ++ free_extent_buffer(split); + btrfs_abort_transaction(trans, ret); + return ret; + } +diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c +index 69b43df186a89..ef95525fa6cdf 100644 +--- a/fs/btrfs/qgroup.c ++++ b/fs/btrfs/qgroup.c +@@ -1115,7 +1115,9 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) + goto end_trans; + } + ++ spin_lock(&fs_info->trans_lock); + list_del("a_root->dirty_list); ++ spin_unlock(&fs_info->trans_lock); + + btrfs_tree_lock(quota_root->node); + clean_tree_block(fs_info, quota_root->node); +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index 049535115c9dc..1f31861453d9f 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -703,8 +703,13 @@ btrfs_attach_transaction_barrier(struct btrfs_root *root) + + trans = start_transaction(root, 0, TRANS_ATTACH, + BTRFS_RESERVE_NO_FLUSH, true); +- if (trans == ERR_PTR(-ENOENT)) +- btrfs_wait_for_commit(root->fs_info, 0); ++ if (trans == ERR_PTR(-ENOENT)) { ++ int ret; ++ ++ ret = btrfs_wait_for_commit(root->fs_info, 0); ++ if (ret) ++ return ERR_PTR(ret); ++ } + + return trans; + } +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index ba65b4bd7c0ac..fcfba2af5f98a 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -3285,6 +3285,15 @@ static void handle_cap_grant(struct inode *inode, + } + BUG_ON(cap->issued & ~cap->implemented); + ++ /* don't let check_caps skip sending a response to MDS for revoke msgs */ ++ if (le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) { ++ cap->mds_wanted = 0; ++ if (cap == ci->i_auth_cap) ++ check_caps = 1; /* check auth cap only */ ++ else ++ check_caps = 2; /* check all caps */ ++ } ++ + if (extra_info->inline_version > 0 && + extra_info->inline_version >= ci->i_inline_version) { + ci->i_inline_version = extra_info->inline_version; +diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c +index 43a96c330570d..ea50f59610e52 100644 +--- a/fs/dlm/netlink.c ++++ b/fs/dlm/netlink.c +@@ -115,7 +115,7 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) + + void dlm_timeout_warn(struct dlm_lkb *lkb) + { +- struct sk_buff *uninitialized_var(send_skb); ++ struct sk_buff *send_skb; + struct dlm_lock_data *data; + size_t size; + int rv; +diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c +index e0c05e08d8bfe..9fef426ce6f41 100644 +--- a/fs/dlm/plock.c ++++ b/fs/dlm/plock.c +@@ -22,20 +22,20 @@ static struct list_head recv_list; + static wait_queue_head_t send_wq; + static wait_queue_head_t recv_wq; + +-struct plock_op { +- struct list_head list; +- int done; +- struct dlm_plock_info info; +- int (*callback)(struct file_lock *fl, int result); +-}; +- +-struct plock_xop { +- struct plock_op xop; ++struct plock_async_data { + void *fl; + void *file; + struct file_lock flc; ++ int (*callback)(struct file_lock *fl, int result); + }; + ++struct plock_op { ++ struct list_head list; ++ int done; ++ struct dlm_plock_info info; ++ /* if set indicates async handling */ ++ struct plock_async_data *data; ++}; + + static inline void set_version(struct dlm_plock_info *info) + { +@@ -61,6 +61,12 @@ static int check_version(struct dlm_plock_info *info) + return 0; + } + ++static void dlm_release_plock_op(struct plock_op *op) ++{ ++ kfree(op->data); ++ kfree(op); ++} ++ + static void send_op(struct plock_op *op) + { + set_version(&op->info); +@@ -104,22 +110,21 @@ static void do_unlock_close(struct dlm_ls *ls, u64 number, + int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + int cmd, struct file_lock *fl) + { ++ struct plock_async_data *op_data; + struct dlm_ls *ls; + struct plock_op *op; +- struct plock_xop *xop; + int rv; + + ls = dlm_find_lockspace_local(lockspace); + if (!ls) + return -EINVAL; + +- xop = kzalloc(sizeof(*xop), GFP_NOFS); +- if (!xop) { ++ op = kzalloc(sizeof(*op), GFP_NOFS); ++ if (!op) { + rv = -ENOMEM; + goto out; + } + +- op = &xop->xop; + op->info.optype = DLM_PLOCK_OP_LOCK; + op->info.pid = fl->fl_pid; + op->info.ex = (fl->fl_type == F_WRLCK); +@@ -128,35 +133,44 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + op->info.number = number; + op->info.start = fl->fl_start; + op->info.end = fl->fl_end; ++ /* async handling */ + if (fl->fl_lmops && fl->fl_lmops->lm_grant) { ++ op_data = kzalloc(sizeof(*op_data), GFP_NOFS); ++ if (!op_data) { ++ dlm_release_plock_op(op); ++ rv = -ENOMEM; ++ goto out; ++ } ++ + /* fl_owner is lockd which doesn't distinguish + processes on the nfs client */ + op->info.owner = (__u64) fl->fl_pid; +- op->callback = fl->fl_lmops->lm_grant; +- locks_init_lock(&xop->flc); +- locks_copy_lock(&xop->flc, fl); +- xop->fl = fl; +- xop->file = file; ++ op_data->callback = fl->fl_lmops->lm_grant; ++ locks_init_lock(&op_data->flc); ++ locks_copy_lock(&op_data->flc, fl); ++ op_data->fl = fl; ++ op_data->file = file; ++ ++ op->data = op_data; ++ ++ send_op(op); ++ rv = FILE_LOCK_DEFERRED; ++ goto out; + } else { + op->info.owner = (__u64)(long) fl->fl_owner; + } + + send_op(op); + +- if (!op->callback) { +- rv = wait_event_interruptible(recv_wq, (op->done != 0)); +- if (rv == -ERESTARTSYS) { +- log_debug(ls, "dlm_posix_lock: wait killed %llx", +- (unsigned long long)number); +- spin_lock(&ops_lock); +- list_del(&op->list); +- spin_unlock(&ops_lock); +- kfree(xop); +- do_unlock_close(ls, number, file, fl); +- goto out; +- } +- } else { +- rv = FILE_LOCK_DEFERRED; ++ rv = wait_event_killable(recv_wq, (op->done != 0)); ++ if (rv == -ERESTARTSYS) { ++ log_debug(ls, "%s: wait killed %llx", __func__, ++ (unsigned long long)number); ++ spin_lock(&ops_lock); ++ list_del(&op->list); ++ spin_unlock(&ops_lock); ++ dlm_release_plock_op(op); ++ do_unlock_close(ls, number, file, fl); + goto out; + } + +@@ -176,7 +190,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + (unsigned long long)number); + } + +- kfree(xop); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + return rv; +@@ -186,11 +200,11 @@ EXPORT_SYMBOL_GPL(dlm_posix_lock); + /* Returns failure iff a successful lock operation should be canceled */ + static int dlm_plock_callback(struct plock_op *op) + { ++ struct plock_async_data *op_data = op->data; + struct file *file; + struct file_lock *fl; + struct file_lock *flc; + int (*notify)(struct file_lock *fl, int result) = NULL; +- struct plock_xop *xop = (struct plock_xop *)op; + int rv = 0; + + spin_lock(&ops_lock); +@@ -202,10 +216,10 @@ static int dlm_plock_callback(struct plock_op *op) + spin_unlock(&ops_lock); + + /* check if the following 2 are still valid or make a copy */ +- file = xop->file; +- flc = &xop->flc; +- fl = xop->fl; +- notify = op->callback; ++ file = op_data->file; ++ flc = &op_data->flc; ++ fl = op_data->fl; ++ notify = op_data->callback; + + if (op->info.rv) { + notify(fl, op->info.rv); +@@ -236,7 +250,7 @@ static int dlm_plock_callback(struct plock_op *op) + } + + out: +- kfree(xop); ++ dlm_release_plock_op(op); + return rv; + } + +@@ -306,7 +320,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, + rv = 0; + + out_free: +- kfree(op); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + fl->fl_flags = fl_flags; +@@ -366,13 +380,15 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, + locks_init_lock(fl); + fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; + fl->fl_flags = FL_POSIX; +- fl->fl_pid = -op->info.pid; ++ fl->fl_pid = op->info.pid; ++ if (op->info.nodeid != dlm_our_nodeid()) ++ fl->fl_pid = -fl->fl_pid; + fl->fl_start = op->info.start; + fl->fl_end = op->info.end; + rv = 0; + } + +- kfree(op); ++ dlm_release_plock_op(op); + out: + dlm_put_lockspace(ls); + return rv; +@@ -408,7 +424,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, + (the process did not make an unlock call). */ + + if (op->info.flags & DLM_PLOCK_FL_CLOSE) +- kfree(op); ++ dlm_release_plock_op(op); + + if (copy_to_user(u, &info, sizeof(info))) + return -EFAULT; +@@ -440,7 +456,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, + op->info.owner == info.owner) { + list_del_init(&op->list); + memcpy(&op->info, &info, sizeof(info)); +- if (op->callback) ++ if (op->data) + do_callback = 1; + else + op->done = 1; +diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h +index a203a5723e2c0..598dc28748086 100644 +--- a/fs/ext2/ext2.h ++++ b/fs/ext2/ext2.h +@@ -68,10 +68,7 @@ struct mb_cache; + * second extended-fs super-block data in memory + */ + struct ext2_sb_info { +- unsigned long s_frag_size; /* Size of a fragment in bytes */ +- unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ +- unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ +@@ -185,15 +182,6 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) + #define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) + #define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) + +-/* +- * Macro-instructions used to manage fragments +- */ +-#define EXT2_MIN_FRAG_SIZE 1024 +-#define EXT2_MAX_FRAG_SIZE 4096 +-#define EXT2_MIN_FRAG_LOG_SIZE 10 +-#define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) +-#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) +- + /* + * Structure of a blocks group descriptor + */ +diff --git a/fs/ext2/super.c b/fs/ext2/super.c +index 3349ce85d27cb..5c0af53f2e8fc 100644 +--- a/fs/ext2/super.c ++++ b/fs/ext2/super.c +@@ -691,10 +691,9 @@ static int ext2_setup_super (struct super_block * sb, + es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); + le16_add_cpu(&es->s_mnt_count, 1); + if (test_opt (sb, DEBUG)) +- ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " ++ ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, " + "bpg=%lu, ipg=%lu, mo=%04lx]", + EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, +- sbi->s_frag_size, + sbi->s_groups_count, + EXT2_BLOCKS_PER_GROUP(sb), + EXT2_INODES_PER_GROUP(sb), +@@ -1040,14 +1039,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + } + } + +- sbi->s_frag_size = EXT2_MIN_FRAG_SIZE << +- le32_to_cpu(es->s_log_frag_size); +- if (sbi->s_frag_size == 0) +- goto cantfind_ext2; +- sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size; +- + sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); +- sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); + sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); + + if (EXT2_INODE_SIZE(sb) == 0) +@@ -1075,11 +1067,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + goto failed_mount; + } + +- if (sb->s_blocksize != sbi->s_frag_size) { ++ if (es->s_log_frag_size != es->s_log_block_size) { + ext2_msg(sb, KERN_ERR, +- "error: fragsize %lu != blocksize %lu" +- "(not supported yet)", +- sbi->s_frag_size, sb->s_blocksize); ++ "error: fragsize log %u != blocksize log %u", ++ le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits); + goto failed_mount; + } + +@@ -1089,12 +1080,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + sbi->s_blocks_per_group); + goto failed_mount; + } +- if (sbi->s_frags_per_group > sb->s_blocksize * 8) { +- ext2_msg(sb, KERN_ERR, +- "error: #fragments per group too big: %lu", +- sbi->s_frags_per_group); +- goto failed_mount; +- } + if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || + sbi->s_inodes_per_group > sb->s_blocksize * 8) { + ext2_msg(sb, KERN_ERR, +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 19e2a52d1e5a1..909f231a387d7 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1412,7 +1412,7 @@ struct ext4_sb_info { + unsigned long s_commit_interval; + u32 s_max_batch_time; + u32 s_min_batch_time; +- struct block_device *journal_bdev; ++ struct block_device *s_journal_bdev; + #ifdef CONFIG_QUOTA + /* Names of quota files with journalled quota */ + char __rcu *s_qf_names[EXT4_MAXQUOTAS]; +diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c +index 6b52ace1463c2..69c76327792e0 100644 +--- a/fs/ext4/fsmap.c ++++ b/fs/ext4/fsmap.c +@@ -576,8 +576,8 @@ static bool ext4_getfsmap_is_valid_device(struct super_block *sb, + if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX || + fm->fmr_device == new_encode_dev(sb->s_bdev->bd_dev)) + return true; +- if (EXT4_SB(sb)->journal_bdev && +- fm->fmr_device == new_encode_dev(EXT4_SB(sb)->journal_bdev->bd_dev)) ++ if (EXT4_SB(sb)->s_journal_bdev && ++ fm->fmr_device == new_encode_dev(EXT4_SB(sb)->s_journal_bdev->bd_dev)) + return true; + return false; + } +@@ -647,9 +647,9 @@ int ext4_getfsmap(struct super_block *sb, struct ext4_fsmap_head *head, + memset(handlers, 0, sizeof(handlers)); + handlers[0].gfd_dev = new_encode_dev(sb->s_bdev->bd_dev); + handlers[0].gfd_fn = ext4_getfsmap_datadev; +- if (EXT4_SB(sb)->journal_bdev) { ++ if (EXT4_SB(sb)->s_journal_bdev) { + handlers[1].gfd_dev = new_encode_dev( +- EXT4_SB(sb)->journal_bdev->bd_dev); ++ EXT4_SB(sb)->s_journal_bdev->bd_dev); + handlers[1].gfd_fn = ext4_getfsmap_logdev; + } + +diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c +index 0cc0d22c08569..9bf711d63368c 100644 +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -642,6 +642,14 @@ int ext4_ind_map_blocks(handle_t *handle, struct inode *inode, + + ext4_update_inode_fsync_trans(handle, inode, 1); + count = ar.len; ++ ++ /* ++ * Update reserved blocks/metadata blocks after successful block ++ * allocation which had been deferred till now. ++ */ ++ if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) ++ ext4_da_update_reserve_space(inode, count, 1); ++ + got_it: + map->m_flags |= EXT4_MAP_MAPPED; + map->m_pblk = le32_to_cpu(chain[depth-1].key); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 7aaf4dafd3e78..646285fbc9fc0 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -668,16 +668,6 @@ found: + */ + ext4_clear_inode_state(inode, EXT4_STATE_EXT_MIGRATE); + } +- +- /* +- * Update reserved blocks/metadata blocks after successful +- * block allocation which had been deferred till now. We don't +- * support fallocate for non extent files. So we can update +- * reserve space here. +- */ +- if ((retval > 0) && +- (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)) +- ext4_da_update_reserve_space(inode, retval, 1); + } + + if (retval > 0) { +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index b930e8d559d41..43e036f0b661d 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -561,6 +561,7 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + __u32 flags; ++ struct super_block *ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; +@@ -579,7 +580,9 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg) + + switch (flags) { + case EXT4_GOING_FLAGS_DEFAULT: +- freeze_bdev(sb->s_bdev); ++ ret = freeze_bdev(sb->s_bdev); ++ if (IS_ERR(ret)) ++ return PTR_ERR(ret); + set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); + thaw_bdev(sb->s_bdev, sb); + break; +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 23e56c1ffc1bf..7692c12b85285 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4948,8 +4948,8 @@ do_more: + * them with group lock_held + */ + if (test_opt(sb, DISCARD)) { +- err = ext4_issue_discard(sb, block_group, bit, count, +- NULL); ++ err = ext4_issue_discard(sb, block_group, bit, ++ count_clusters, NULL); + if (err && err != -EOPNOTSUPP) + ext4_msg(sb, KERN_WARNING, "discard request in" + " group:%d block:%d count:%lu failed" +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index ce5abd25eb99c..926063a6d2321 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -905,10 +905,16 @@ static void ext4_blkdev_put(struct block_device *bdev) + static void ext4_blkdev_remove(struct ext4_sb_info *sbi) + { + struct block_device *bdev; +- bdev = sbi->journal_bdev; ++ bdev = sbi->s_journal_bdev; + if (bdev) { ++ /* ++ * Invalidate the journal device's buffers. We don't want them ++ * floating about in memory - the physical journal device may ++ * hotswapped, and it breaks the `ro-after' testing code. ++ */ ++ invalidate_bdev(bdev); + ext4_blkdev_put(bdev); +- sbi->journal_bdev = NULL; ++ sbi->s_journal_bdev = NULL; + } + } + +@@ -1032,14 +1038,8 @@ static void ext4_put_super(struct super_block *sb) + + sync_blockdev(sb->s_bdev); + invalidate_bdev(sb->s_bdev); +- if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { +- /* +- * Invalidate the journal device's buffers. We don't want them +- * floating about in memory - the physical journal device may +- * hotswapped, and it breaks the `ro-after' testing code. +- */ +- sync_blockdev(sbi->journal_bdev); +- invalidate_bdev(sbi->journal_bdev); ++ if (sbi->s_journal_bdev && sbi->s_journal_bdev != sb->s_bdev) { ++ sync_blockdev(sbi->s_journal_bdev); + ext4_blkdev_remove(sbi); + } + if (sbi->s_ea_inode_cache) { +@@ -3537,7 +3537,7 @@ int ext4_calculate_overhead(struct super_block *sb) + * Add the internal journal blocks whether the journal has been + * loaded or not + */ +- if (sbi->s_journal && !sbi->journal_bdev) ++ if (sbi->s_journal && !sbi->s_journal_bdev) + overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen); + else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) { + /* j_inum for internal journal is non-zero */ +@@ -4673,6 +4673,7 @@ failed_mount: + ext4_blkdev_remove(sbi); + brelse(bh); + out_fail: ++ invalidate_bdev(sb->s_bdev); + sb->s_fs_info = NULL; + kfree(sbi->s_blockgroup_lock); + out_free_base: +@@ -4848,7 +4849,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, + be32_to_cpu(journal->j_superblock->s_nr_users)); + goto out_journal; + } +- EXT4_SB(sb)->journal_bdev = bdev; ++ EXT4_SB(sb)->s_journal_bdev = bdev; + ext4_init_journal_params(sb, journal); + return journal; + +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index f8a8807c20977..88bdb2714e519 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1767,6 +1767,20 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, + memmove(here, (void *)here + size, + (void *)last - (void *)here + sizeof(__u32)); + memset(last, 0, size); ++ ++ /* ++ * Update i_inline_off - moved ibody region might contain ++ * system.data attribute. Handling a failure here won't ++ * cause other complications for setting an xattr. ++ */ ++ if (!is_block && ext4_has_inline_data(inode)) { ++ ret = ext4_find_inline_data_nolock(inode); ++ if (ret) { ++ ext4_warning_inode(inode, ++ "unable to update i_inline_off"); ++ goto out; ++ } ++ } + } else if (s->not_found) { + /* Insert new name. */ + size_t size = EXT4_XATTR_LEN(name_len); +diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c +index 2c28f488ac2f0..9911f780e0136 100644 +--- a/fs/f2fs/node.c ++++ b/fs/f2fs/node.c +@@ -879,8 +879,10 @@ static int truncate_dnode(struct dnode_of_data *dn) + dn->ofs_in_node = 0; + f2fs_truncate_data_blocks(dn); + err = truncate_node(dn); +- if (err) ++ if (err) { ++ f2fs_put_page(page, 1); + return err; ++ } + + return 1; + } +diff --git a/fs/fat/dir.c b/fs/fat/dir.c +index de60c05c0ca1d..10769b2e4d468 100644 +--- a/fs/fat/dir.c ++++ b/fs/fat/dir.c +@@ -1287,7 +1287,7 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, + struct super_block *sb = dir->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); + struct buffer_head *bh, *prev, *bhs[3]; /* 32*slots (672bytes) */ +- struct msdos_dir_entry *uninitialized_var(de); ++ struct msdos_dir_entry *de; + int err, free_slots, i, nr_bhs; + loff_t pos, i_pos; + +diff --git a/fs/fuse/control.c b/fs/fuse/control.c +index acc35819aae64..af253127b309a 100644 +--- a/fs/fuse/control.c ++++ b/fs/fuse/control.c +@@ -117,7 +117,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file, + const char __user *buf, + size_t count, loff_t *ppos) + { +- unsigned uninitialized_var(val); ++ unsigned val; + ssize_t ret; + + ret = fuse_conn_limit_write(file, buf, count, ppos, &val, +diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c +index e10e2b62ccf45..acd985aa2cbab 100644 +--- a/fs/fuse/cuse.c ++++ b/fs/fuse/cuse.c +@@ -269,7 +269,7 @@ static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp) + static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo) + { + char *end = p + len; +- char *uninitialized_var(key), *uninitialized_var(val); ++ char *key, *val; + int rc; + + while (true) { +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index 6098e0c7f87b3..0e03adbcf9423 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -232,7 +232,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) + spin_unlock(&fc->lock); + } + kfree(forget); +- if (ret == -ENOMEM) ++ if (ret == -ENOMEM || ret == -EINTR) + goto out; + if (ret || fuse_invalid_attr(&outarg.attr) || + (outarg.attr.mode ^ inode->i_mode) & S_IFMT) +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 599a6eeed02e0..c629ccafb2b0e 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -2774,7 +2774,7 @@ static void fuse_register_polled_file(struct fuse_conn *fc, + { + spin_lock(&fc->lock); + if (RB_EMPTY_NODE(&ff->polled_node)) { +- struct rb_node **link, *uninitialized_var(parent); ++ struct rb_node **link, *parent; + + link = fuse_find_polled_node(fc, ff->kh, &parent); + BUG_ON(*link); +diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c +index d9866d89f2fb9..910bfc39dc4b4 100644 +--- a/fs/gfs2/aops.c ++++ b/fs/gfs2/aops.c +@@ -359,7 +359,7 @@ static int gfs2_write_cache_jdata(struct address_space *mapping, + int done = 0; + struct pagevec pvec; + int nr_pages; +- pgoff_t uninitialized_var(writeback_index); ++ pgoff_t writeback_index; + pgoff_t index; + pgoff_t end; + pgoff_t done_index; +diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c +index ccafd45b63f69..729f36fdced1f 100644 +--- a/fs/gfs2/bmap.c ++++ b/fs/gfs2/bmap.c +@@ -1754,7 +1754,7 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length) + u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift; + __u16 start_list[GFS2_MAX_META_HEIGHT]; + __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL; +- unsigned int start_aligned, uninitialized_var(end_aligned); ++ unsigned int start_aligned, end_aligned; + unsigned int strip_h = ip->i_height - 1; + u32 btotal = 0; + int ret, state; +diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c +index 3cc2237e58967..bb0eaa4638e3c 100644 +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1586,6 +1586,14 @@ static void gfs2_evict_inode(struct inode *inode) + if (inode->i_nlink || sb_rdonly(sb)) + goto out; + ++ /* ++ * In case of an incomplete mount, gfs2_evict_inode() may be called for ++ * system files without having an active journal to write to. In that ++ * case, skip the filesystem evict. ++ */ ++ if (!sdp->sd_jdesc) ++ goto out; ++ + if (test_bit(GIF_ALLOC_FAILED, &ip->i_flags)) { + BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl)); + gfs2_holder_mark_uninitialized(&gh); +diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c +index c8d1b2be7854e..73342c925a4b6 100644 +--- a/fs/hfsplus/unicode.c ++++ b/fs/hfsplus/unicode.c +@@ -398,7 +398,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str) + astr = str->name; + len = str->len; + while (len > 0) { +- int uninitialized_var(dsize); ++ int dsize; + size = asc2unichar(sb, astr, len, &c); + astr += size; + len -= size; +diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c +index 558e7c51ce0d4..58f80e1b3ac0d 100644 +--- a/fs/isofs/namei.c ++++ b/fs/isofs/namei.c +@@ -153,8 +153,8 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, + struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) + { + int found; +- unsigned long uninitialized_var(block); +- unsigned long uninitialized_var(offset); ++ unsigned long block; ++ unsigned long offset; + struct inode *inode; + struct page *page; + +diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c +index 837cd55fd4c5e..6ae9d6fefb861 100644 +--- a/fs/jffs2/build.c ++++ b/fs/jffs2/build.c +@@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c) + ic->scan_dents = NULL; + cond_resched(); + } +- jffs2_build_xattr_subsystem(c); ++ ret = jffs2_build_xattr_subsystem(c); ++ if (ret) ++ goto exit; ++ + c->flags &= ~JFFS2_SB_FLAG_BUILDING; + + dbg_fsbuild("FS build complete\n"); +diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c +index 83b8f06b4a642..7e9abdb897122 100644 +--- a/fs/jffs2/erase.c ++++ b/fs/jffs2/erase.c +@@ -401,7 +401,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb + { + size_t retlen; + int ret; +- uint32_t uninitialized_var(bad_offset); ++ uint32_t bad_offset; + + switch (jffs2_block_check_erase(c, jeb, &bad_offset)) { + case -EAGAIN: goto refile; +diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c +index da3e18503c658..acb4492f5970c 100644 +--- a/fs/jffs2/xattr.c ++++ b/fs/jffs2/xattr.c +@@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c) + } + + #define XREF_TMPHASH_SIZE (128) +-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) ++int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) + { + struct jffs2_xattr_ref *ref, *_ref; +- struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; ++ struct jffs2_xattr_ref **xref_tmphash; + struct jffs2_xattr_datum *xd, *_xd; + struct jffs2_inode_cache *ic; + struct jffs2_raw_node_ref *raw; +@@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) + + BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); + ++ xref_tmphash = kcalloc(XREF_TMPHASH_SIZE, ++ sizeof(struct jffs2_xattr_ref *), GFP_KERNEL); ++ if (!xref_tmphash) ++ return -ENOMEM; ++ + /* Phase.1 : Merge same xref */ +- for (i=0; i < XREF_TMPHASH_SIZE; i++) +- xref_tmphash[i] = NULL; + for (ref=c->xref_temp; ref; ref=_ref) { + struct jffs2_xattr_ref *tmp; + +@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) + "%u of xref (%u dead, %u orphan) found.\n", + xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, + xref_count, xref_dead_count, xref_orphan_count); ++ kfree(xref_tmphash); ++ return 0; + } + + struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h +index 720007b2fd65d..1b5030a3349db 100644 +--- a/fs/jffs2/xattr.h ++++ b/fs/jffs2/xattr.h +@@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(struct jffs2_xattr_ref *ref) + #ifdef CONFIG_JFFS2_FS_XATTR + + extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); +-extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); ++extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); + extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); + + extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, +@@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t); + #else + + #define jffs2_init_xattr_subsystem(c) +-#define jffs2_build_xattr_subsystem(c) ++#define jffs2_build_xattr_subsystem(c) (0) + #define jffs2_clear_xattr_subsystem(c) + + #define jffs2_xattr_do_crccheck_inode(c, ic) +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 3ad0a33e0443b..07b9df8938f29 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -191,7 +191,13 @@ int dbMount(struct inode *ipbmap) + dbmp_le = (struct dbmap_disk *) mp->data; + bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize); + bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); ++ + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); ++ if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { ++ err = -EINVAL; ++ goto err_release_metapage; ++ } ++ + bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag); + if (!bmp->db_numag) { + err = -EINVAL; +diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h +index 415bfa90607a2..0c36ce6318d53 100644 +--- a/fs/jfs/jfs_filsys.h ++++ b/fs/jfs/jfs_filsys.h +@@ -135,7 +135,9 @@ + #define NUM_INODE_PER_IAG INOSPERIAG + + #define MINBLOCKSIZE 512 ++#define L2MINBLOCKSIZE 9 + #define MAXBLOCKSIZE 4096 ++#define L2MAXBLOCKSIZE 12 + #define MAXFILESIZE ((s64)1 << 52) + + #define JFS_LINK_MAX 0xffffffff +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index c82f898325c1c..74ab20c89e752 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -3403,7 +3403,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op + p = xdr_reserve_space(xdr, 32); + if (!p) + return nfserr_resource; +- *p++ = cpu_to_be32(0); ++ *p++ = cpu_to_be32(open->op_recall); + + /* + * TODO: space_limit's in delegations +diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c +index ff9899cc9913f..7af48d306f20c 100644 +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -347,7 +347,7 @@ static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size) + static ssize_t write_filehandle(struct file *file, char *buf, size_t size) + { + char *dname, *path; +- int uninitialized_var(maxsize); ++ int maxsize; + char *mesg = buf; + int len; + struct auth_domain *dom; +diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c +index 046f5e3c9622d..c7cf0913229cb 100644 +--- a/fs/ocfs2/alloc.c ++++ b/fs/ocfs2/alloc.c +@@ -4722,7 +4722,7 @@ int ocfs2_insert_extent(handle_t *handle, + struct ocfs2_alloc_context *meta_ac) + { + int status; +- int uninitialized_var(free_records); ++ int free_records; + struct buffer_head *last_eb_bh = NULL; + struct ocfs2_insert_type insert = {0, }; + struct ocfs2_extent_rec rec; +@@ -7052,7 +7052,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, + int need_free = 0; + u32 bit_off, num; + handle_t *handle; +- u64 uninitialized_var(block); ++ u64 block; + struct ocfs2_inode_info *oi = OCFS2_I(inode); + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; +diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c +index c121abbdfc7db..13f4bb4e174c4 100644 +--- a/fs/ocfs2/dir.c ++++ b/fs/ocfs2/dir.c +@@ -866,9 +866,9 @@ static int ocfs2_dx_dir_lookup(struct inode *inode, + u64 *ret_phys_blkno) + { + int ret = 0; +- unsigned int cend, uninitialized_var(clen); +- u32 uninitialized_var(cpos); +- u64 uninitialized_var(blkno); ++ unsigned int cend, clen; ++ u32 cpos; ++ u64 blkno; + u32 name_hash = hinfo->major_hash; + + ret = ocfs2_dx_dir_lookup_rec(inode, el, name_hash, &cpos, &blkno, +@@ -912,7 +912,7 @@ static int ocfs2_dx_dir_search(const char *name, int namelen, + struct ocfs2_dir_lookup_result *res) + { + int ret, i, found; +- u64 uninitialized_var(phys); ++ u64 phys; + struct buffer_head *dx_leaf_bh = NULL; + struct ocfs2_dx_leaf *dx_leaf; + struct ocfs2_dx_entry *dx_entry = NULL; +@@ -4420,9 +4420,9 @@ out: + int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh) + { + int ret; +- unsigned int uninitialized_var(clen); +- u32 major_hash = UINT_MAX, p_cpos, uninitialized_var(cpos); +- u64 uninitialized_var(blkno); ++ unsigned int clen; ++ u32 major_hash = UINT_MAX, p_cpos, cpos; ++ u64 blkno; + struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); + struct buffer_head *dx_root_bh = NULL; + struct ocfs2_dx_root_block *dx_root; +diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c +index 06cb96462bf99..1f41171c14687 100644 +--- a/fs/ocfs2/extent_map.c ++++ b/fs/ocfs2/extent_map.c +@@ -416,7 +416,7 @@ static int ocfs2_get_clusters_nocache(struct inode *inode, + { + int i, ret, tree_height, len; + struct ocfs2_dinode *di; +- struct ocfs2_extent_block *uninitialized_var(eb); ++ struct ocfs2_extent_block *eb; + struct ocfs2_extent_list *el; + struct ocfs2_extent_rec *rec; + struct buffer_head *eb_bh = NULL; +@@ -613,7 +613,7 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, + unsigned int *extent_flags) + { + int ret; +- unsigned int uninitialized_var(hole_len), flags = 0; ++ unsigned int hole_len, flags = 0; + struct buffer_head *di_bh = NULL; + struct ocfs2_extent_rec rec; + +diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c +index d437b21925228..bd8d742adf65a 100644 +--- a/fs/ocfs2/namei.c ++++ b/fs/ocfs2/namei.c +@@ -2506,7 +2506,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, + struct buffer_head *new_di_bh = NULL; + struct ocfs2_alloc_context *inode_ac = NULL; + struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; +- u64 uninitialized_var(di_blkno), suballoc_loc; ++ u64 di_blkno, suballoc_loc; + u16 suballoc_bit; + + status = ocfs2_inode_lock(dir, &parent_di_bh, 1); +diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c +index fc197e599e8ce..e184b36f8dd33 100644 +--- a/fs/ocfs2/refcounttree.c ++++ b/fs/ocfs2/refcounttree.c +@@ -1069,7 +1069,7 @@ static int ocfs2_get_refcount_rec(struct ocfs2_caching_info *ci, + struct buffer_head **ret_bh) + { + int ret = 0, i, found; +- u32 low_cpos, uninitialized_var(cpos_end); ++ u32 low_cpos, cpos_end; + struct ocfs2_extent_list *el; + struct ocfs2_extent_rec *rec = NULL; + struct ocfs2_extent_block *eb = NULL; +diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c +index c146e12a8601f..54d881c9ac81e 100644 +--- a/fs/ocfs2/xattr.c ++++ b/fs/ocfs2/xattr.c +@@ -1219,7 +1219,7 @@ static int ocfs2_xattr_block_get(struct inode *inode, + struct ocfs2_xattr_value_root *xv; + size_t size; + int ret = -ENODATA, name_offset, name_len, i; +- int uninitialized_var(block_off); ++ int block_off; + + xs->bucket = ocfs2_xattr_bucket_new(inode); + if (!xs->bucket) { +diff --git a/fs/omfs/file.c b/fs/omfs/file.c +index bf83e6644333f..ce59b2fb50c74 100644 +--- a/fs/omfs/file.c ++++ b/fs/omfs/file.c +@@ -220,7 +220,7 @@ static int omfs_get_block(struct inode *inode, sector_t block, + struct buffer_head *bh; + sector_t next, offset; + int ret; +- u64 uninitialized_var(new_block); ++ u64 new_block; + u32 max_extents; + int extent_count; + struct omfs_extent *oe; +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 30abafcd4ecce..3d7a700350c1d 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -713,7 +713,7 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) + struct path upperpath, datapath; + int err; + char *capability = NULL; +- ssize_t uninitialized_var(cap_size); ++ ssize_t cap_size; + + ovl_path_upper(c->dentry, &upperpath); + if (WARN_ON(upperpath.dentry == NULL)) +diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c +index 31f66053e2393..e3d1673b8ec97 100644 +--- a/fs/sysv/itree.c ++++ b/fs/sysv/itree.c +@@ -145,6 +145,10 @@ static int alloc_branch(struct inode *inode, + */ + parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key); + bh = sb_getblk(inode->i_sb, parent); ++ if (!bh) { ++ sysv_free_block(inode->i_sb, branch[n].key); ++ break; ++ } + lock_buffer(bh); + memset(bh->b_data, 0, blocksize); + branch[n].bh = bh; +diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c +index 591f2c7a48f07..583e20787689b 100644 +--- a/fs/ubifs/commit.c ++++ b/fs/ubifs/commit.c +@@ -564,11 +564,11 @@ out: + */ + int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) + { +- int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt; ++ int lnum, offs, len, err = 0, last_level, child_cnt; + int first = 1, iip; + struct ubifs_debug_info *d = c->dbg; +- union ubifs_key uninitialized_var(lower_key), upper_key, l_key, u_key; +- unsigned long long uninitialized_var(last_sqnum); ++ union ubifs_key lower_key, upper_key, l_key, u_key; ++ unsigned long long last_sqnum; + struct ubifs_idx_node *idx; + struct list_head list; + struct idx_node *i; +diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c +index cb52aa9ea276c..39296e8012421 100644 +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -1294,7 +1294,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + struct ubifs_budget_req ino_req = { .dirtied_ino = 1, + .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; + struct timespec64 time; +- unsigned int uninitialized_var(saved_nlink); ++ unsigned int saved_nlink; + struct fscrypt_name old_nm, new_nm; + + /* +diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c +index ae836e8bb2933..fca3b7f483c79 100644 +--- a/fs/ubifs/file.c ++++ b/fs/ubifs/file.c +@@ -234,7 +234,7 @@ static int write_begin_slow(struct address_space *mapping, + struct ubifs_info *c = inode->i_sb->s_fs_info; + pgoff_t index = pos >> PAGE_SHIFT; + struct ubifs_budget_req req = { .new_page = 1 }; +- int uninitialized_var(err), appending = !!(pos + len > inode->i_size); ++ int err, appending = !!(pos + len > inode->i_size); + struct page *page; + + dbg_gen("ino %lu, pos %llu, len %u, i_size %lld", +@@ -438,7 +438,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, + struct ubifs_info *c = inode->i_sb->s_fs_info; + struct ubifs_inode *ui = ubifs_inode(inode); + pgoff_t index = pos >> PAGE_SHIFT; +- int uninitialized_var(err), appending = !!(pos + len > inode->i_size); ++ int err, appending = !!(pos + len > inode->i_size); + int skipped_read = 0; + struct page *page; + +diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c +index 802565a17733c..0a60a065c7e8b 100644 +--- a/fs/ubifs/journal.c ++++ b/fs/ubifs/journal.c +@@ -1355,7 +1355,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, + union ubifs_key key, to_key; + struct ubifs_ino_node *ino; + struct ubifs_trun_node *trun; +- struct ubifs_data_node *uninitialized_var(dn); ++ struct ubifs_data_node *dn; + int err, dlen, len, lnum, offs, bit, sz, sync = IS_SYNC(inode); + struct ubifs_inode *ui = ubifs_inode(inode); + ino_t inum = inode->i_ino; +diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c +index 31393370e3348..433bfcddc497c 100644 +--- a/fs/ubifs/lpt.c ++++ b/fs/ubifs/lpt.c +@@ -287,7 +287,7 @@ uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, + const int k = 32 - nrbits; + uint8_t *p = *addr; + int b = *pos; +- uint32_t uninitialized_var(val); ++ uint32_t val; + const int bytes = (nrbits + b + 7) >> 3; + + ubifs_assert(c, nrbits > 0); +diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c +index 08ed942b76271..330ccf72745bb 100644 +--- a/fs/ubifs/tnc.c ++++ b/fs/ubifs/tnc.c +@@ -936,7 +936,7 @@ static int fallible_resolve_collision(struct ubifs_info *c, + int adding) + { + struct ubifs_znode *o_znode = NULL, *znode = *zn; +- int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n; ++ int o_n, err, cmp, unsure = 0, nn = *n; + + cmp = fallible_matches_name(c, &znode->zbranch[nn], nm); + if (unlikely(cmp < 0)) +@@ -1558,8 +1558,8 @@ out: + */ + int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) + { +- int n, err = 0, lnum = -1, uninitialized_var(offs); +- int uninitialized_var(len); ++ int n, err = 0, lnum = -1, offs; ++ int len; + unsigned int block = key_block(c, &bu->key); + struct ubifs_znode *znode; + +diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c +index d90ee01076a9e..fe3b52d2749b4 100644 +--- a/fs/ubifs/tnc_misc.c ++++ b/fs/ubifs/tnc_misc.c +@@ -138,8 +138,8 @@ int ubifs_search_zbranch(const struct ubifs_info *c, + const struct ubifs_znode *znode, + const union ubifs_key *key, int *n) + { +- int beg = 0, end = znode->child_cnt, uninitialized_var(mid); +- int uninitialized_var(cmp); ++ int beg = 0, end = znode->child_cnt, mid; ++ int cmp; + const struct ubifs_zbranch *zbr = &znode->zbranch[0]; + + ubifs_assert(c, end > beg); +diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c +index fcda0fc97b90a..4c0307f378d72 100644 +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -555,7 +555,7 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb, + udf_pblk_t newblock = 0; + uint32_t adsize; + uint32_t elen, goal_elen = 0; +- struct kernel_lb_addr eloc, uninitialized_var(goal_eloc); ++ struct kernel_lb_addr eloc, goal_eloc; + struct extent_position epos, goal_epos; + int8_t etype; + struct udf_inode_info *iinfo = UDF_I(table); +diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c +index 3e1dd66bd6769..734b80a4220c1 100644 +--- a/fs/xfs/xfs_bmap_util.c ++++ b/fs/xfs/xfs_bmap_util.c +@@ -130,7 +130,7 @@ xfs_bmap_rtalloc( + * pick an extent that will space things out in the rt area. + */ + if (ap->eof && ap->offset == 0) { +- xfs_rtblock_t uninitialized_var(rtx); /* realtime extent no */ ++ xfs_rtblock_t rtx; /* realtime extent no */ + + error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); + if (error) +diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h +index 20c93f08c9933..95a1d214108a5 100644 +--- a/include/asm-generic/word-at-a-time.h ++++ b/include/asm-generic/word-at-a-time.h +@@ -38,7 +38,7 @@ static inline long find_zero(unsigned long mask) + return (mask >> 8) ? byte : byte + 1; + } + +-static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) ++static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) + { + unsigned long rhs = val | c->low_bits; + *data = rhs; +diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h +index e1e9eff096d05..2932a40060c1d 100644 +--- a/include/linux/etherdevice.h ++++ b/include/linux/etherdevice.h +@@ -291,6 +291,18 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src) + #endif + } + ++/** ++ * eth_hw_addr_set - Assign Ethernet address to a net_device ++ * @dev: pointer to net_device structure ++ * @addr: address to assign ++ * ++ * Assign given address to the net_device, addr_assign_type is not changed. ++ */ ++static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr) ++{ ++ ether_addr_copy(dev->dev_addr, addr); ++} ++ + /** + * eth_hw_addr_inherit - Copy dev_addr from another net_device + * @dst: pointer to net_device to copy dev_addr to +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 90827d85265b0..7e9df3854420a 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -4079,6 +4079,24 @@ void __hw_addr_unsync_dev(struct netdev_hw_addr_list *list, + void __hw_addr_init(struct netdev_hw_addr_list *list); + + /* Functions used for device addresses handling */ ++static inline void ++__dev_addr_set(struct net_device *dev, const u8 *addr, size_t len) ++{ ++ memcpy(dev->dev_addr, addr, len); ++} ++ ++static inline void dev_addr_set(struct net_device *dev, const u8 *addr) ++{ ++ __dev_addr_set(dev, addr, dev->addr_len); ++} ++ ++static inline void ++dev_addr_mod(struct net_device *dev, unsigned int offset, ++ const u8 *addr, size_t len) ++{ ++ memcpy(&dev->dev_addr[offset], addr, len); ++} ++ + int dev_addr_add(struct net_device *dev, const unsigned char *addr, + unsigned char addr_type); + int dev_addr_del(struct net_device *dev, const unsigned char *addr, +diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h +index a806803fbe37a..de206e410ee23 100644 +--- a/include/linux/netfilter/nfnetlink.h ++++ b/include/linux/netfilter/nfnetlink.h +@@ -49,6 +49,33 @@ static inline u16 nfnl_msg_type(u8 subsys, u8 msg_type) + return subsys << 8 | msg_type; + } + ++static inline void nfnl_fill_hdr(struct nlmsghdr *nlh, u8 family, u8 version, ++ __be16 res_id) ++{ ++ struct nfgenmsg *nfmsg; ++ ++ nfmsg = nlmsg_data(nlh); ++ nfmsg->nfgen_family = family; ++ nfmsg->version = version; ++ nfmsg->res_id = res_id; ++} ++ ++static inline struct nlmsghdr *nfnl_msg_put(struct sk_buff *skb, u32 portid, ++ u32 seq, int type, int flags, ++ u8 family, u8 version, ++ __be16 res_id) ++{ ++ struct nlmsghdr *nlh; ++ ++ nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags); ++ if (!nlh) ++ return NULL; ++ ++ nfnl_fill_hdr(nlh, family, version, res_id); ++ ++ return nlh; ++} ++ + void nfnl_lock(__u8 subsys_id); + void nfnl_unlock(__u8 subsys_id); + #ifdef CONFIG_PROVE_LOCKING +diff --git a/include/linux/nmi.h b/include/linux/nmi.h +index e972d1ae1ee63..6cb593d9ed08a 100644 +--- a/include/linux/nmi.h ++++ b/include/linux/nmi.h +@@ -197,7 +197,7 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh); + #endif + + #if defined(CONFIG_HARDLOCKUP_CHECK_TIMESTAMP) && \ +- defined(CONFIG_HARDLOCKUP_DETECTOR) ++ defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) + void watchdog_update_hrtimer_threshold(u64 period); + #else + static inline void watchdog_update_hrtimer_threshold(u64 period) { } +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 3e06e9790c255..1d1b0bfd51968 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1643,6 +1643,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, + #define pci_dev_put(dev) do { } while (0) + + static inline void pci_set_master(struct pci_dev *dev) { } ++static inline void pci_clear_master(struct pci_dev *dev) { } + static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } + static inline void pci_disable_device(struct pci_dev *dev) { } + static inline int pci_assign_resource(struct pci_dev *dev, int i) +diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h +index cd5b62db90845..e63a63aa47a37 100644 +--- a/include/linux/pm_wakeirq.h ++++ b/include/linux/pm_wakeirq.h +@@ -17,8 +17,8 @@ + #ifdef CONFIG_PM + + extern int dev_pm_set_wake_irq(struct device *dev, int irq); +-extern int dev_pm_set_dedicated_wake_irq(struct device *dev, +- int irq); ++extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq); ++extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq); + extern void dev_pm_clear_wake_irq(struct device *dev); + extern void dev_pm_enable_wake_irq(struct device *dev); + extern void dev_pm_disable_wake_irq(struct device *dev); +@@ -35,6 +35,11 @@ static inline int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + return 0; + } + ++static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return 0; ++} ++ + static inline void dev_pm_clear_wake_irq(struct device *dev) + { + } +diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h +index 660d78c9af6c8..6a55b30ae742b 100644 +--- a/include/linux/sched/signal.h ++++ b/include/linux/sched/signal.h +@@ -127,7 +127,7 @@ struct signal_struct { + #ifdef CONFIG_POSIX_TIMERS + + /* POSIX.1b Interval Timers */ +- int posix_timer_id; ++ unsigned int next_posix_timer_id; + struct list_head posix_timers; + + /* ITIMER_REAL timer for the process */ +diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h +index 5a655ba8d2730..bfde7f1a7674d 100644 +--- a/include/linux/serial_8250.h ++++ b/include/linux/serial_8250.h +@@ -99,7 +99,6 @@ struct uart_8250_port { + struct list_head list; /* ports on this IRQ */ + u32 capabilities; /* port capabilities */ + unsigned short bugs; /* port bugs */ +- bool fifo_bug; /* min RX trigger if enabled */ + unsigned int tx_loadsz; /* transmit fifo load size */ + unsigned char acr; + unsigned char fcr; +diff --git a/include/linux/tcp.h b/include/linux/tcp.h +index 621ab5a7fb8fa..0d63a428e6f9c 100644 +--- a/include/linux/tcp.h ++++ b/include/linux/tcp.h +@@ -460,7 +460,7 @@ static inline void fastopen_queue_tune(struct sock *sk, int backlog) + struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; + int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn); + +- queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn); ++ WRITE_ONCE(queue->fastopenq.max_qlen, min_t(unsigned int, backlog, somaxconn)); + } + + static inline void tcp_move_syn(struct tcp_sock *tp, +diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h +index 60d673e156321..a7224fec99a7a 100644 +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -73,7 +73,6 @@ enum { + WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, + + __WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, +- WORK_OFFQ_CANCELING = (1 << __WORK_OFFQ_CANCELING), + + /* + * When a work item is off queue, its high bits point to the last +@@ -84,12 +83,6 @@ enum { + WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS, + WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, + WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, +- WORK_OFFQ_POOL_NONE = (1LU << WORK_OFFQ_POOL_BITS) - 1, +- +- /* convenience constants */ +- WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, +- WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, +- WORK_STRUCT_NO_POOL = (unsigned long)WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT, + + /* bit mask for work_busy() return values */ + WORK_BUSY_PENDING = 1 << 0, +@@ -99,6 +92,14 @@ enum { + WORKER_DESC_LEN = 24, + }; + ++/* Convenience constants - of type 'unsigned long', not 'enum'! */ ++#define WORK_OFFQ_CANCELING (1ul << __WORK_OFFQ_CANCELING) ++#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1) ++#define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT) ++ ++#define WORK_STRUCT_FLAG_MASK ((1ul << WORK_STRUCT_FLAG_BITS) - 1) ++#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) ++ + struct work_struct { + atomic_long_t data; + struct list_head entry; +diff --git a/include/net/addrconf.h b/include/net/addrconf.h +index db2a87981dd46..9583d3bbab039 100644 +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -340,6 +340,22 @@ static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev) + return rcu_dereference_rtnl(dev->ip6_ptr); + } + ++/** ++ * __in6_dev_stats_get - get inet6_dev pointer for stats ++ * @dev: network device ++ * @skb: skb for original incoming interface if neeeded ++ * ++ * Caller must hold rcu_read_lock or RTNL, because this function ++ * does not take a reference on the inet6_dev. ++ */ ++static inline struct inet6_dev *__in6_dev_stats_get(const struct net_device *dev, ++ const struct sk_buff *skb) ++{ ++ if (netif_is_l3_master(dev)) ++ dev = dev_get_by_index_rcu(dev_net(dev), inet6_iif(skb)); ++ return __in6_dev_get(dev); ++} ++ + /** + * __in6_dev_get_safely - get inet6_dev pointer from netdevice + * @dev: network device +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index 0c883249814cc..3a55a0931ed86 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -602,12 +602,8 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a) + /* more secured version of ipv6_addr_hash() */ + static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval) + { +- u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; +- +- return jhash_3words(v, +- (__force u32)a->s6_addr32[2], +- (__force u32)a->s6_addr32[3], +- initval); ++ return jhash2((__force const u32 *)a->s6_addr32, ++ ARRAY_SIZE(a->s6_addr32), initval); + } + + static inline bool ipv6_addr_loopback(const struct in6_addr *a) +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 1b4f47a878060..4719440873723 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -736,6 +736,7 @@ struct nft_expr_type { + + enum nft_trans_phase { + NFT_TRANS_PREPARE, ++ NFT_TRANS_PREPARE_ERROR, + NFT_TRANS_ABORT, + NFT_TRANS_COMMIT, + NFT_TRANS_RELEASE +@@ -1319,12 +1320,14 @@ static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) + * struct nft_trans - nf_tables object update in transaction + * + * @list: used internally ++ * @binding_list: list of objects with possible bindings + * @msg_type: message type + * @ctx: transaction context + * @data: internal information related to the transaction + */ + struct nft_trans { + struct list_head list; ++ struct list_head binding_list; + int msg_type; + struct nft_ctx ctx; + char data[0]; +@@ -1409,4 +1412,15 @@ struct nft_trans_flowtable { + int __init nft_chain_filter_init(void); + void nft_chain_filter_fini(void); + ++struct nftables_pernet { ++ struct list_head tables; ++ struct list_head commit_list; ++ struct list_head binding_list; ++ struct list_head module_list; ++ struct list_head notify_list; ++ struct mutex commit_mutex; ++ unsigned int base_seq; ++ u8 validate_state; ++}; ++ + #endif /* _NET_NF_TABLES_H */ +diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h +index 286fd960896fd..8c77832d02404 100644 +--- a/include/net/netns/nftables.h ++++ b/include/net/netns/nftables.h +@@ -5,12 +5,7 @@ + #include <linux/list.h> + + struct netns_nftables { +- struct list_head tables; +- struct list_head commit_list; +- struct mutex commit_mutex; +- unsigned int base_seq; + u8 gencursor; +- u8 validate_state; + }; + + #endif +diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h +index bbdc73a3239df..8b86560b5cfb1 100644 +--- a/include/net/nfc/nfc.h ++++ b/include/net/nfc/nfc.h +@@ -278,7 +278,7 @@ struct sk_buff *nfc_alloc_send_skb(struct nfc_dev *dev, struct sock *sk, + struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp); + + int nfc_set_remote_general_bytes(struct nfc_dev *dev, +- u8 *gt, u8 gt_len); ++ const u8 *gt, u8 gt_len); + u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len); + + int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name, +@@ -292,7 +292,7 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, + u8 comm_mode, u8 rf_mode); + + int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, +- u8 *gb, size_t gb_len); ++ const u8 *gb, size_t gb_len); + int nfc_tm_deactivated(struct nfc_dev *dev); + int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb); + +diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h +index e09ea6917c061..83a16f3bd6e6a 100644 +--- a/include/net/pkt_sched.h ++++ b/include/net/pkt_sched.h +@@ -131,7 +131,7 @@ extern const struct nla_policy rtm_tca_policy[TCA_MAX + 1]; + */ + static inline unsigned int psched_mtu(const struct net_device *dev) + { +- return dev->mtu + dev->hard_header_len; ++ return READ_ONCE(dev->mtu) + dev->hard_header_len; + } + + static inline struct net *qdisc_net(struct Qdisc *q) +diff --git a/include/net/sock.h b/include/net/sock.h +index 616e84d1670df..72739f72e4b90 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1840,6 +1840,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) + } + + kuid_t sock_i_uid(struct sock *sk); ++unsigned long __sock_i_ino(struct sock *sk); + unsigned long sock_i_ino(struct sock *sk); + + static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk) +diff --git a/include/net/tcp.h b/include/net/tcp.h +index 81300a04b5808..c6c48409e7b42 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -128,6 +128,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); + * to combine FIN-WAIT-2 timeout with + * TIME-WAIT timer. + */ ++#define TCP_FIN_TIMEOUT_MAX (120 * HZ) /* max TCP_LINGER2 value (two minutes) */ + + #define TCP_DELACK_MAX ((unsigned)(HZ/5)) /* maximal time to delay before sending an ACK */ + #if HZ >= 100 +@@ -1882,7 +1883,11 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr); + static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) + { + struct net *net = sock_net((struct sock *)tp); +- return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); ++ u32 val; ++ ++ val = READ_ONCE(tp->notsent_lowat); ++ ++ return val ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); + } + + /* @wake is one when sk_stream_write_space() calls us. +diff --git a/include/uapi/linux/affs_hardblocks.h b/include/uapi/linux/affs_hardblocks.h +index 5e2fb8481252a..a5aff2eb5f708 100644 +--- a/include/uapi/linux/affs_hardblocks.h ++++ b/include/uapi/linux/affs_hardblocks.h +@@ -7,42 +7,42 @@ + /* Just the needed definitions for the RDB of an Amiga HD. */ + + struct RigidDiskBlock { +- __u32 rdb_ID; ++ __be32 rdb_ID; + __be32 rdb_SummedLongs; +- __s32 rdb_ChkSum; +- __u32 rdb_HostID; ++ __be32 rdb_ChkSum; ++ __be32 rdb_HostID; + __be32 rdb_BlockBytes; +- __u32 rdb_Flags; +- __u32 rdb_BadBlockList; ++ __be32 rdb_Flags; ++ __be32 rdb_BadBlockList; + __be32 rdb_PartitionList; +- __u32 rdb_FileSysHeaderList; +- __u32 rdb_DriveInit; +- __u32 rdb_Reserved1[6]; +- __u32 rdb_Cylinders; +- __u32 rdb_Sectors; +- __u32 rdb_Heads; +- __u32 rdb_Interleave; +- __u32 rdb_Park; +- __u32 rdb_Reserved2[3]; +- __u32 rdb_WritePreComp; +- __u32 rdb_ReducedWrite; +- __u32 rdb_StepRate; +- __u32 rdb_Reserved3[5]; +- __u32 rdb_RDBBlocksLo; +- __u32 rdb_RDBBlocksHi; +- __u32 rdb_LoCylinder; +- __u32 rdb_HiCylinder; +- __u32 rdb_CylBlocks; +- __u32 rdb_AutoParkSeconds; +- __u32 rdb_HighRDSKBlock; +- __u32 rdb_Reserved4; ++ __be32 rdb_FileSysHeaderList; ++ __be32 rdb_DriveInit; ++ __be32 rdb_Reserved1[6]; ++ __be32 rdb_Cylinders; ++ __be32 rdb_Sectors; ++ __be32 rdb_Heads; ++ __be32 rdb_Interleave; ++ __be32 rdb_Park; ++ __be32 rdb_Reserved2[3]; ++ __be32 rdb_WritePreComp; ++ __be32 rdb_ReducedWrite; ++ __be32 rdb_StepRate; ++ __be32 rdb_Reserved3[5]; ++ __be32 rdb_RDBBlocksLo; ++ __be32 rdb_RDBBlocksHi; ++ __be32 rdb_LoCylinder; ++ __be32 rdb_HiCylinder; ++ __be32 rdb_CylBlocks; ++ __be32 rdb_AutoParkSeconds; ++ __be32 rdb_HighRDSKBlock; ++ __be32 rdb_Reserved4; + char rdb_DiskVendor[8]; + char rdb_DiskProduct[16]; + char rdb_DiskRevision[4]; + char rdb_ControllerVendor[8]; + char rdb_ControllerProduct[16]; + char rdb_ControllerRevision[4]; +- __u32 rdb_Reserved5[10]; ++ __be32 rdb_Reserved5[10]; + }; + + #define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ +@@ -50,16 +50,16 @@ struct RigidDiskBlock { + struct PartitionBlock { + __be32 pb_ID; + __be32 pb_SummedLongs; +- __s32 pb_ChkSum; +- __u32 pb_HostID; ++ __be32 pb_ChkSum; ++ __be32 pb_HostID; + __be32 pb_Next; +- __u32 pb_Flags; +- __u32 pb_Reserved1[2]; +- __u32 pb_DevFlags; ++ __be32 pb_Flags; ++ __be32 pb_Reserved1[2]; ++ __be32 pb_DevFlags; + __u8 pb_DriveName[32]; +- __u32 pb_Reserved2[15]; ++ __be32 pb_Reserved2[15]; + __be32 pb_Environment[17]; +- __u32 pb_EReserved[15]; ++ __be32 pb_EReserved[15]; + }; + + #define IDNAME_PARTITION 0x50415254 /* "PART" */ +diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h +index ff5a5db8906a7..2f3a0cca4b78b 100644 +--- a/include/uapi/linux/blkzoned.h ++++ b/include/uapi/linux/blkzoned.h +@@ -51,13 +51,13 @@ enum blk_zone_type { + * + * The Zone Condition state machine in the ZBC/ZAC standards maps the above + * deinitions as: +- * - ZC1: Empty | BLK_ZONE_EMPTY ++ * - ZC1: Empty | BLK_ZONE_COND_EMPTY + * - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN + * - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN +- * - ZC4: Closed | BLK_ZONE_CLOSED +- * - ZC5: Full | BLK_ZONE_FULL +- * - ZC6: Read Only | BLK_ZONE_READONLY +- * - ZC7: Offline | BLK_ZONE_OFFLINE ++ * - ZC4: Closed | BLK_ZONE_COND_CLOSED ++ * - ZC5: Full | BLK_ZONE_COND_FULL ++ * - ZC6: Read Only | BLK_ZONE_COND_READONLY ++ * - ZC7: Offline | BLK_ZONE_COND_OFFLINE + * + * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should + * be considered invalid. +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index ad6a633f5848a..ac22e7f062399 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -1510,7 +1510,7 @@ struct v4l2_input { + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ +- __u32 tuner; /* enum v4l2_tuner_type */ ++ __u32 tuner; /* Tuner index */ + v4l2_std_id std; + __u32 status; + __u32 capabilities; +diff --git a/kernel/async.c b/kernel/async.c +index 4bf1b00a28d86..e59bd2240cb86 100644 +--- a/kernel/async.c ++++ b/kernel/async.c +@@ -115,7 +115,7 @@ static void async_run_entry_fn(struct work_struct *work) + struct async_entry *entry = + container_of(work, struct async_entry, work); + unsigned long flags; +- ktime_t uninitialized_var(calltime), delta, rettime; ++ ktime_t calltime, delta, rettime; + + /* 1) run (and print duration) */ + if (initcall_debug && system_state < SYSTEM_RUNNING) { +@@ -283,7 +283,7 @@ EXPORT_SYMBOL_GPL(async_synchronize_full_domain); + */ + void async_synchronize_cookie_domain(async_cookie_t cookie, struct async_domain *domain) + { +- ktime_t uninitialized_var(starttime), delta, endtime; ++ ktime_t starttime, delta, endtime; + + if (initcall_debug && system_state < SYSTEM_RUNNING) { + pr_debug("async_waiting @ %i\n", task_pid_nr(current)); +diff --git a/kernel/audit.c b/kernel/audit.c +index 7dc14a4d9e3cf..471d3ad910aa5 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -1796,7 +1796,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, + { + struct audit_buffer *ab; + struct timespec64 t; +- unsigned int uninitialized_var(serial); ++ unsigned int serial; + + if (audit_initialized != AUDIT_INITIALIZED) + return NULL; +diff --git a/kernel/bpf/bpf_lru_list.c b/kernel/bpf/bpf_lru_list.c +index 9b5eeff72fd37..39a0e768adc39 100644 +--- a/kernel/bpf/bpf_lru_list.c ++++ b/kernel/bpf/bpf_lru_list.c +@@ -44,7 +44,12 @@ static struct list_head *local_pending_list(struct bpf_lru_locallist *loc_l) + /* bpf_lru_node helpers */ + static bool bpf_lru_node_is_ref(const struct bpf_lru_node *node) + { +- return node->ref; ++ return READ_ONCE(node->ref); ++} ++ ++static void bpf_lru_node_clear_ref(struct bpf_lru_node *node) ++{ ++ WRITE_ONCE(node->ref, 0); + } + + static void bpf_lru_list_count_inc(struct bpf_lru_list *l, +@@ -92,7 +97,7 @@ static void __bpf_lru_node_move_in(struct bpf_lru_list *l, + + bpf_lru_list_count_inc(l, tgt_type); + node->type = tgt_type; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + list_move(&node->list, &l->lists[tgt_type]); + } + +@@ -113,7 +118,7 @@ static void __bpf_lru_node_move(struct bpf_lru_list *l, + bpf_lru_list_count_inc(l, tgt_type); + node->type = tgt_type; + } +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + + /* If the moving node is the next_inactive_rotation candidate, + * move the next_inactive_rotation pointer also. +@@ -356,7 +361,7 @@ static void __local_list_add_pending(struct bpf_lru *lru, + *(u32 *)((void *)node + lru->hash_offset) = hash; + node->cpu = cpu; + node->type = BPF_LRU_LOCAL_LIST_T_PENDING; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + list_add(&node->list, local_pending_list(loc_l)); + } + +@@ -422,7 +427,7 @@ static struct bpf_lru_node *bpf_percpu_lru_pop_free(struct bpf_lru *lru, + if (!list_empty(free_list)) { + node = list_first_entry(free_list, struct bpf_lru_node, list); + *(u32 *)((void *)node + lru->hash_offset) = hash; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + __bpf_lru_node_move(l, node, BPF_LRU_LIST_T_INACTIVE); + } + +@@ -525,7 +530,7 @@ static void bpf_common_lru_push_free(struct bpf_lru *lru, + } + + node->type = BPF_LRU_LOCAL_LIST_T_FREE; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + list_move(&node->list, local_free_list(loc_l)); + + raw_spin_unlock_irqrestore(&loc_l->lock, flags); +@@ -571,7 +576,7 @@ static void bpf_common_lru_populate(struct bpf_lru *lru, void *buf, + + node = (struct bpf_lru_node *)(buf + node_offset); + node->type = BPF_LRU_LIST_T_FREE; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + list_add(&node->list, &l->lists[BPF_LRU_LIST_T_FREE]); + buf += elem_size; + } +@@ -597,7 +602,7 @@ again: + node = (struct bpf_lru_node *)(buf + node_offset); + node->cpu = cpu; + node->type = BPF_LRU_LIST_T_FREE; +- node->ref = 0; ++ bpf_lru_node_clear_ref(node); + list_add(&node->list, &l->lists[BPF_LRU_LIST_T_FREE]); + i++; + buf += elem_size; +diff --git a/kernel/bpf/bpf_lru_list.h b/kernel/bpf/bpf_lru_list.h +index 7d4f89b7cb841..08da78b59f0b9 100644 +--- a/kernel/bpf/bpf_lru_list.h ++++ b/kernel/bpf/bpf_lru_list.h +@@ -66,11 +66,8 @@ struct bpf_lru { + + static inline void bpf_lru_node_set_ref(struct bpf_lru_node *node) + { +- /* ref is an approximation on access frequency. It does not +- * have to be very accurate. Hence, no protection is used. +- */ +- if (!node->ref) +- node->ref = 1; ++ if (!READ_ONCE(node->ref)) ++ WRITE_ONCE(node->ref, 1); + } + + int bpf_lru_init(struct bpf_lru *lru, bool percpu, u32 hash_offset, +diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c +index 7c6cd00d0fca9..c345a6e2f7b7e 100644 +--- a/kernel/dma/debug.c ++++ b/kernel/dma/debug.c +@@ -963,7 +963,7 @@ static int device_dma_allocations(struct device *dev, struct dma_debug_entry **o + static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) + { + struct device *dev = data; +- struct dma_debug_entry *uninitialized_var(entry); ++ struct dma_debug_entry *entry; + int count; + + if (dma_debug_disabled()) +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 2bf4b6b109bf4..cb2b717666cee 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1133,6 +1133,11 @@ static int perf_mux_hrtimer_restart(struct perf_cpu_context *cpuctx) + return 0; + } + ++static int perf_mux_hrtimer_restart_ipi(void *arg) ++{ ++ return perf_mux_hrtimer_restart(arg); ++} ++ + void perf_pmu_disable(struct pmu *pmu) + { + int *count = this_cpu_ptr(pmu->pmu_disable_count); +@@ -9644,8 +9649,7 @@ perf_event_mux_interval_ms_store(struct device *dev, + cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); + cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * timer); + +- cpu_function_call(cpu, +- (remote_function_f)perf_mux_hrtimer_restart, cpuctx); ++ cpu_function_call(cpu, perf_mux_hrtimer_restart_ipi, cpuctx); + } + cpus_read_unlock(); + mutex_unlock(&mux_interval_mutex); +@@ -10575,7 +10579,7 @@ SYSCALL_DEFINE5(perf_event_open, + struct perf_event *group_leader = NULL, *output_event = NULL; + struct perf_event *event, *sibling; + struct perf_event_attr attr; +- struct perf_event_context *ctx, *uninitialized_var(gctx); ++ struct perf_event_context *ctx, *gctx; + struct file *event_file = NULL; + struct fd group = {NULL, 0}; + struct task_struct *task = NULL; +diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c +index 24342bca11f2f..72ae05d650661 100644 +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -1887,7 +1887,7 @@ static void handle_swbp(struct pt_regs *regs) + { + struct uprobe *uprobe; + unsigned long bp_vaddr; +- int uninitialized_var(is_swbp); ++ int is_swbp; + + bp_vaddr = uprobe_get_swbp_addr(regs); + if (bp_vaddr == get_trampoline_vaddr()) +diff --git a/kernel/exit.c b/kernel/exit.c +index 02360ec3b1225..0d1cca15e66fe 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -140,7 +140,7 @@ static void __exit_signal(struct task_struct *tsk) + struct signal_struct *sig = tsk->signal; + bool group_dead = thread_group_leader(tsk); + struct sighand_struct *sighand; +- struct tty_struct *uninitialized_var(tty); ++ struct tty_struct *tty; + u64 utime, stime; + + sighand = rcu_dereference_check(tsk->sighand, +diff --git a/kernel/futex.c b/kernel/futex.c +index 3c67da9b84086..ca2a2a8948395 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1398,7 +1398,7 @@ static int lookup_pi_state(u32 __user *uaddr, u32 uval, + static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval) + { + int err; +- u32 uninitialized_var(curval); ++ u32 curval; + + if (unlikely(should_fail_futex(true))) + return -EFAULT; +@@ -1569,7 +1569,7 @@ static void mark_wake_futex(struct wake_q_head *wake_q, struct futex_q *q) + */ + static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_state) + { +- u32 uninitialized_var(curval), newval; ++ u32 curval, newval; + struct task_struct *new_owner; + bool postunlock = false; + DEFINE_WAKE_Q(wake_q); +@@ -3083,7 +3083,7 @@ uaddr_faulted: + */ + static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) + { +- u32 uninitialized_var(curval), uval, vpid = task_pid_vnr(current); ++ u32 curval, uval, vpid = task_pid_vnr(current); + union futex_key key = FUTEX_KEY_INIT; + struct futex_hash_bucket *hb; + struct futex_q *top_waiter; +@@ -3558,7 +3558,7 @@ err_unlock: + static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, + bool pi, bool pending_op) + { +- u32 uval, uninitialized_var(nval), mval; ++ u32 uval, nval, mval; + int err; + + /* Futex address must be 32bit aligned */ +@@ -3688,7 +3688,7 @@ static void exit_robust_list(struct task_struct *curr) + struct robust_list_head __user *head = curr->robust_list; + struct robust_list __user *entry, *next_entry, *pending; + unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; +- unsigned int uninitialized_var(next_pi); ++ unsigned int next_pi; + unsigned long futex_offset; + int rc; + +@@ -3987,7 +3987,7 @@ static void compat_exit_robust_list(struct task_struct *curr) + struct compat_robust_list_head __user *head = curr->compat_robust_list; + struct robust_list __user *entry, *next_entry, *pending; + unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; +- unsigned int uninitialized_var(next_pi); ++ unsigned int next_pi; + compat_uptr_t uentry, next_uentry, upending; + compat_long_t futex_offset; + int rc; +diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c +index 6b3d7f7211dd6..3666d434a8f59 100644 +--- a/kernel/kexec_core.c ++++ b/kernel/kexec_core.c +@@ -1020,6 +1020,7 @@ int crash_shrink_memory(unsigned long new_size) + start = crashk_res.start; + end = crashk_res.end; + old_size = (end == 0) ? 0 : end - start + 1; ++ new_size = roundup(new_size, KEXEC_CRASH_MEM_ALIGN); + if (new_size >= old_size) { + ret = (new_size == old_size) ? 0 : -EINVAL; + goto unlock; +@@ -1031,9 +1032,7 @@ int crash_shrink_memory(unsigned long new_size) + goto unlock; + } + +- start = roundup(start, KEXEC_CRASH_MEM_ALIGN); +- end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); +- ++ end = start + new_size; + crash_free_reserved_phys_range(end, crashk_res.end); + + if ((start == end) && (crashk_res.parent != NULL)) +diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c +index 4dc79f57af827..46a6d1f7c351d 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -1246,7 +1246,7 @@ static int noop_count(struct lock_list *entry, void *data) + static unsigned long __lockdep_count_forward_deps(struct lock_list *this) + { + unsigned long count = 0; +- struct lock_list *uninitialized_var(target_entry); ++ struct lock_list *target_entry; + + __bfs_forwards(this, (void *)&count, noop_count, &target_entry); + +@@ -1274,7 +1274,7 @@ unsigned long lockdep_count_forward_deps(struct lock_class *class) + static unsigned long __lockdep_count_backward_deps(struct lock_list *this) + { + unsigned long count = 0; +- struct lock_list *uninitialized_var(target_entry); ++ struct lock_list *target_entry; + + __bfs_backwards(this, (void *)&count, noop_count, &target_entry); + +@@ -2662,7 +2662,7 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this, + { + int ret; + struct lock_list root; +- struct lock_list *uninitialized_var(target_entry); ++ struct lock_list *target_entry; + + root.parent = NULL; + root.class = hlock_class(this); +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index eb67f42fb96ba..09f82c84474b8 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8721,7 +8721,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, + .sd = sd, + .dst_cpu = this_cpu, + .dst_rq = this_rq, +- .dst_grpmask = sched_group_span(sd->groups), ++ .dst_grpmask = group_balance_mask(sd->groups), + .idle = idle, + .loop_break = sched_nr_migrate_break, + .cpus = cpus, +diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c +index 1234868b3b03e..8768ce2c4bf52 100644 +--- a/kernel/time/posix-timers.c ++++ b/kernel/time/posix-timers.c +@@ -159,25 +159,30 @@ static struct k_itimer *posix_timer_by_id(timer_t id) + static int posix_timer_add(struct k_itimer *timer) + { + struct signal_struct *sig = current->signal; +- int first_free_id = sig->posix_timer_id; + struct hlist_head *head; +- int ret = -ENOENT; ++ unsigned int cnt, id; + +- do { ++ /* ++ * FIXME: Replace this by a per signal struct xarray once there is ++ * a plan to handle the resulting CRIU regression gracefully. ++ */ ++ for (cnt = 0; cnt <= INT_MAX; cnt++) { + spin_lock(&hash_lock); +- head = &posix_timers_hashtable[hash(sig, sig->posix_timer_id)]; +- if (!__posix_timers_find(head, sig, sig->posix_timer_id)) { ++ id = sig->next_posix_timer_id; ++ ++ /* Write the next ID back. Clamp it to the positive space */ ++ sig->next_posix_timer_id = (id + 1) & INT_MAX; ++ ++ head = &posix_timers_hashtable[hash(sig, id)]; ++ if (!__posix_timers_find(head, sig, id)) { + hlist_add_head_rcu(&timer->t_hash, head); +- ret = sig->posix_timer_id; ++ spin_unlock(&hash_lock); ++ return id; + } +- if (++sig->posix_timer_id < 0) +- sig->posix_timer_id = 0; +- if ((sig->posix_timer_id == first_free_id) && (ret == -ENOENT)) +- /* Loop over all possible ids completed */ +- ret = -EAGAIN; + spin_unlock(&hash_lock); +- } while (ret == -ENOENT); +- return ret; ++ } ++ /* POSIX return code when no timer ID could be allocated */ ++ return -EAGAIN; + } + + static inline void unlock_timer(struct k_itimer *timr, unsigned long flags) +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 5c0463dbe16ee..81f5c9c85d066 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -1124,7 +1124,7 @@ struct ftrace_page { + struct ftrace_page *next; + struct dyn_ftrace *records; + int index; +- int size; ++ int order; + }; + + #define ENTRY_SIZE sizeof(struct dyn_ftrace) +@@ -2915,6 +2915,8 @@ static void ftrace_shutdown_sysctl(void) + + static u64 ftrace_update_time; + unsigned long ftrace_update_tot_cnt; ++unsigned long ftrace_number_of_pages; ++unsigned long ftrace_number_of_groups; + + static inline int ops_traces_mod(struct ftrace_ops *ops) + { +@@ -3039,8 +3041,11 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count) + goto again; + } + ++ ftrace_number_of_pages += 1 << order; ++ ftrace_number_of_groups++; ++ + cnt = (PAGE_SIZE << order) / ENTRY_SIZE; +- pg->size = cnt; ++ pg->order = order; + + if (cnt > count) + cnt = count; +@@ -3048,12 +3053,27 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count) + return cnt; + } + ++static void ftrace_free_pages(struct ftrace_page *pages) ++{ ++ struct ftrace_page *pg = pages; ++ ++ while (pg) { ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } ++ pages = pg->next; ++ kfree(pg); ++ pg = pages; ++ ftrace_number_of_groups--; ++ } ++} ++ + static struct ftrace_page * + ftrace_allocate_pages(unsigned long num_to_init) + { + struct ftrace_page *start_pg; + struct ftrace_page *pg; +- int order; + int cnt; + + if (!num_to_init) +@@ -3087,14 +3107,7 @@ ftrace_allocate_pages(unsigned long num_to_init) + return start_pg; + + free_pages: +- pg = start_pg; +- while (pg) { +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); +- start_pg = pg->next; +- kfree(pg); +- pg = start_pg; +- } ++ ftrace_free_pages(start_pg); + pr_info("ftrace: FAILED to allocate memory for functions\n"); + return NULL; + } +@@ -5586,9 +5599,11 @@ static int ftrace_process_locs(struct module *mod, + unsigned long *start, + unsigned long *end) + { ++ struct ftrace_page *pg_unuse = NULL; + struct ftrace_page *start_pg; + struct ftrace_page *pg; + struct dyn_ftrace *rec; ++ unsigned long skipped = 0; + unsigned long count; + unsigned long *p; + unsigned long addr; +@@ -5634,6 +5649,7 @@ static int ftrace_process_locs(struct module *mod, + p = start; + pg = start_pg; + while (p < end) { ++ unsigned long end_offset; + addr = ftrace_call_adjust(*p++); + /* + * Some architecture linkers will pad between +@@ -5641,10 +5657,13 @@ static int ftrace_process_locs(struct module *mod, + * object files to satisfy alignments. + * Skip any NULL pointers. + */ +- if (!addr) ++ if (!addr) { ++ skipped++; + continue; ++ } + +- if (pg->index == pg->size) { ++ end_offset = (pg->index+1) * sizeof(pg->records[0]); ++ if (end_offset > PAGE_SIZE << pg->order) { + /* We should have allocated enough */ + if (WARN_ON(!pg->next)) + break; +@@ -5655,8 +5674,10 @@ static int ftrace_process_locs(struct module *mod, + rec->ip = addr; + } + +- /* We should have used all pages */ +- WARN_ON(pg->next); ++ if (pg->next) { ++ pg_unuse = pg->next; ++ pg->next = NULL; ++ } + + /* Assign the last page to ftrace_pages */ + ftrace_pages = pg; +@@ -5678,6 +5699,11 @@ static int ftrace_process_locs(struct module *mod, + out: + mutex_unlock(&ftrace_lock); + ++ /* We should have used all pages unless we skipped some */ ++ if (pg_unuse) { ++ WARN_ON(!skipped); ++ ftrace_free_pages(pg_unuse); ++ } + return ret; + } + +@@ -5784,7 +5810,6 @@ void ftrace_release_mod(struct module *mod) + struct ftrace_page **last_pg; + struct ftrace_page *tmp_page = NULL; + struct ftrace_page *pg; +- int order; + + mutex_lock(&ftrace_lock); + +@@ -5835,10 +5860,13 @@ void ftrace_release_mod(struct module *mod) + /* Needs to be called outside of ftrace_lock */ + clear_mod_from_hashes(pg); + +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } + tmp_page = pg->next; + kfree(pg); ++ ftrace_number_of_groups--; + } + } + +@@ -6144,7 +6172,6 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + struct ftrace_mod_map *mod_map = NULL; + struct ftrace_init_func *func, *func_next; + struct list_head clear_hash; +- int order; + + INIT_LIST_HEAD(&clear_hash); + +@@ -6182,8 +6209,11 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) + ftrace_update_tot_cnt--; + if (!pg->index) { + *last_pg = pg->next; +- order = get_count_order(pg->size / ENTRIES_PER_PAGE); +- free_pages((unsigned long)pg->records, order); ++ if (pg->records) { ++ free_pages((unsigned long)pg->records, pg->order); ++ ftrace_number_of_pages -= 1 << pg->order; ++ } ++ ftrace_number_of_groups--; + kfree(pg); + pg = container_of(last_pg, struct ftrace_page, next); + if (!(*last_pg)) +@@ -6239,6 +6269,9 @@ void __init ftrace_init(void) + __start_mcount_loc, + __stop_mcount_loc); + ++ pr_info("ftrace: allocated %ld pages with %ld groups\n", ++ ftrace_number_of_pages, ftrace_number_of_groups); ++ + set_ftrace_early_filters(); + + return; +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index ba8b72f9cdc0b..c8a7de7a1d635 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -493,6 +493,8 @@ struct ring_buffer_per_cpu { + unsigned long read_bytes; + u64 write_stamp; + u64 read_stamp; ++ /* pages removed since last reset */ ++ unsigned long pages_removed; + /* ring buffer pages to update, > 0 to add, < 0 to remove */ + long nr_pages_to_update; + struct list_head new_pages; /* new pages to add */ +@@ -528,6 +530,7 @@ struct ring_buffer_iter { + struct buffer_page *head_page; + struct buffer_page *cache_reader_page; + unsigned long cache_read; ++ unsigned long cache_pages_removed; + u64 read_stamp; + }; + +@@ -561,7 +564,7 @@ static void rb_wake_up_waiters(struct irq_work *work) + */ + int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) + { +- struct ring_buffer_per_cpu *uninitialized_var(cpu_buffer); ++ struct ring_buffer_per_cpu *cpu_buffer; + DEFINE_WAIT(wait); + struct rb_irq_work *work; + int ret = 0; +@@ -1514,6 +1517,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) + to_remove = rb_list_head(to_remove)->next; + head_bit |= (unsigned long)to_remove & RB_PAGE_HEAD; + } ++ /* Read iterators need to reset themselves when some pages removed */ ++ cpu_buffer->pages_removed += nr_removed; + + next_page = rb_list_head(to_remove)->next; + +@@ -1535,12 +1540,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) + cpu_buffer->head_page = list_entry(next_page, + struct buffer_page, list); + +- /* +- * change read pointer to make sure any read iterators reset +- * themselves +- */ +- cpu_buffer->read = 0; +- + /* pages are removed, resume tracing and then free the pages */ + atomic_dec(&cpu_buffer->record_disabled); + raw_spin_unlock_irq(&cpu_buffer->reader_lock); +@@ -3582,6 +3581,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter) + + iter->cache_reader_page = iter->head_page; + iter->cache_read = cpu_buffer->read; ++ iter->cache_pages_removed = cpu_buffer->pages_removed; + + if (iter->head) + iter->read_stamp = cpu_buffer->read_stamp; +@@ -4022,12 +4022,13 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) + buffer = cpu_buffer->buffer; + + /* +- * Check if someone performed a consuming read to +- * the buffer. A consuming read invalidates the iterator +- * and we need to reset the iterator in this case. ++ * Check if someone performed a consuming read to the buffer ++ * or removed some pages from the buffer. In these cases, ++ * iterator was invalidated and we need to reset it. + */ + if (unlikely(iter->cache_read != cpu_buffer->read || +- iter->cache_reader_page != cpu_buffer->reader_page)) ++ iter->cache_reader_page != cpu_buffer->reader_page || ++ iter->cache_pages_removed != cpu_buffer->pages_removed)) + rb_iter_reset(iter); + + again: +@@ -4408,28 +4409,34 @@ unsigned long ring_buffer_size(struct ring_buffer *buffer, int cpu) + } + EXPORT_SYMBOL_GPL(ring_buffer_size); + ++static void rb_clear_buffer_page(struct buffer_page *page) ++{ ++ local_set(&page->write, 0); ++ local_set(&page->entries, 0); ++ rb_init_page(page->page); ++ page->read = 0; ++} ++ + static void + rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) + { ++ struct buffer_page *page; ++ + rb_head_page_deactivate(cpu_buffer); + + cpu_buffer->head_page + = list_entry(cpu_buffer->pages, struct buffer_page, list); +- local_set(&cpu_buffer->head_page->write, 0); +- local_set(&cpu_buffer->head_page->entries, 0); +- local_set(&cpu_buffer->head_page->page->commit, 0); +- +- cpu_buffer->head_page->read = 0; ++ rb_clear_buffer_page(cpu_buffer->head_page); ++ list_for_each_entry(page, cpu_buffer->pages, list) { ++ rb_clear_buffer_page(page); ++ } + + cpu_buffer->tail_page = cpu_buffer->head_page; + cpu_buffer->commit_page = cpu_buffer->head_page; + + INIT_LIST_HEAD(&cpu_buffer->reader_page->list); + INIT_LIST_HEAD(&cpu_buffer->new_pages); +- local_set(&cpu_buffer->reader_page->write, 0); +- local_set(&cpu_buffer->reader_page->entries, 0); +- local_set(&cpu_buffer->reader_page->page->commit, 0); +- cpu_buffer->reader_page->read = 0; ++ rb_clear_buffer_page(cpu_buffer->reader_page); + + local_set(&cpu_buffer->entries_bytes, 0); + local_set(&cpu_buffer->overrun, 0); +@@ -4448,6 +4455,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) + cpu_buffer->last_overrun = 0; + + rb_head_page_activate(cpu_buffer); ++ cpu_buffer->pages_removed = 0; + } + + /** +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 98abff0462366..9da7b10e56d23 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -7107,14 +7107,23 @@ static ssize_t + tracing_read_dyn_info(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) + { +- unsigned long *p = filp->private_data; +- char buf[64]; /* Not too big for a shallow stack */ ++ ssize_t ret; ++ char *buf; + int r; + +- r = scnprintf(buf, 63, "%ld", *p); +- buf[r++] = '\n'; ++ /* 256 should be plenty to hold the amount needed */ ++ buf = kmalloc(256, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; + +- return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); ++ r = scnprintf(buf, 256, "%ld pages:%ld groups: %ld\n", ++ ftrace_update_tot_cnt, ++ ftrace_number_of_pages, ++ ftrace_number_of_groups); ++ ++ ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); ++ kfree(buf); ++ return ret; + } + + static const struct file_operations tracing_dyn_info_fops = { +@@ -8246,7 +8255,7 @@ static __init int tracer_init_tracefs(void) + + #ifdef CONFIG_DYNAMIC_FTRACE + trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, +- &ftrace_update_tot_cnt, &tracing_dyn_info_fops); ++ NULL, &tracing_dyn_info_fops); + #endif + + create_trace_instances(d_tracer); +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index 0923d1b18d1fb..f4d83b552a477 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -748,6 +748,8 @@ extern void trace_event_follow_fork(struct trace_array *tr, bool enable); + + #ifdef CONFIG_DYNAMIC_FTRACE + extern unsigned long ftrace_update_tot_cnt; ++extern unsigned long ftrace_number_of_pages; ++extern unsigned long ftrace_number_of_groups; + void ftrace_init_trace_array(struct trace_array *tr); + #else + static inline void ftrace_init_trace_array(struct trace_array *tr) { } +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index d2f9146d1ad74..a3dc6c126b3ee 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -372,7 +372,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + { + struct trace_event_call *call = file->event_call; + struct trace_array *tr = file->tr; +- unsigned long file_flags = file->flags; + int ret = 0; + int disable; + +@@ -396,6 +395,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + break; + disable = file->flags & EVENT_FILE_FL_SOFT_DISABLED; + clear_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags); ++ /* Disable use of trace_buffered_event */ ++ trace_buffered_event_disable(); + } else + disable = !(file->flags & EVENT_FILE_FL_SOFT_MODE); + +@@ -434,6 +435,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + if (atomic_inc_return(&file->sm_ref) > 1) + break; + set_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags); ++ /* Enable use of trace_buffered_event */ ++ trace_buffered_event_enable(); + } + + if (!(file->flags & EVENT_FILE_FL_ENABLED)) { +@@ -473,15 +476,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file, + break; + } + +- /* Enable or disable use of trace_buffered_event */ +- if ((file_flags & EVENT_FILE_FL_SOFT_DISABLED) != +- (file->flags & EVENT_FILE_FL_SOFT_DISABLED)) { +- if (file->flags & EVENT_FILE_FL_SOFT_DISABLED) +- trace_buffered_event_enable(); +- else +- trace_buffered_event_disable(); +- } +- + return ret; + } + +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index 455cf41aedbbc..e004daf8cad57 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -5787,13 +5787,16 @@ static int event_hist_trigger_func(struct event_command *cmd_ops, + if (get_named_trigger_data(trigger_data)) + goto enable; + +- if (has_hist_vars(hist_data)) +- save_hist_vars(hist_data); +- + ret = create_actions(hist_data, file); + if (ret) + goto out_unreg; + ++ if (has_hist_vars(hist_data) || hist_data->n_var_refs) { ++ ret = save_hist_vars(hist_data); ++ if (ret) ++ goto out_unreg; ++ } ++ + ret = tracing_map_init(hist_data->map); + if (ret) + goto out_unreg; +diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c +index 71381168dedef..f8e460b4a59d5 100644 +--- a/kernel/watchdog_hld.c ++++ b/kernel/watchdog_hld.c +@@ -114,14 +114,14 @@ static void watchdog_overflow_callback(struct perf_event *event, + /* Ensure the watchdog never gets throttled */ + event->hw.interrupts = 0; + ++ if (!watchdog_check_timestamp()) ++ return; ++ + if (__this_cpu_read(watchdog_nmi_touch) == true) { + __this_cpu_write(watchdog_nmi_touch, false); + return; + } + +- if (!watchdog_check_timestamp()) +- return; +- + /* check for a hardlockup + * This is done by making sure our timer interrupt + * is incrementing. The timer interrupt should have +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 4ea2f7fd20ceb..5533206cb6f48 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -680,12 +680,17 @@ static void clear_work_data(struct work_struct *work) + set_work_data(work, WORK_STRUCT_NO_POOL, 0); + } + ++static inline struct pool_workqueue *work_struct_pwq(unsigned long data) ++{ ++ return (struct pool_workqueue *)(data & WORK_STRUCT_WQ_DATA_MASK); ++} ++ + static struct pool_workqueue *get_work_pwq(struct work_struct *work) + { + unsigned long data = atomic_long_read(&work->data); + + if (data & WORK_STRUCT_PWQ) +- return (void *)(data & WORK_STRUCT_WQ_DATA_MASK); ++ return work_struct_pwq(data); + else + return NULL; + } +@@ -713,8 +718,7 @@ static struct worker_pool *get_work_pool(struct work_struct *work) + assert_rcu_or_pool_mutex(); + + if (data & WORK_STRUCT_PWQ) +- return ((struct pool_workqueue *) +- (data & WORK_STRUCT_WQ_DATA_MASK))->pool; ++ return work_struct_pwq(data)->pool; + + pool_id = data >> WORK_OFFQ_POOL_SHIFT; + if (pool_id == WORK_OFFQ_POOL_NONE) +@@ -735,8 +739,7 @@ static int get_work_pool_id(struct work_struct *work) + unsigned long data = atomic_long_read(&work->data); + + if (data & WORK_STRUCT_PWQ) +- return ((struct pool_workqueue *) +- (data & WORK_STRUCT_WQ_DATA_MASK))->pool->id; ++ return work_struct_pwq(data)->pool->id; + + return data >> WORK_OFFQ_POOL_SHIFT; + } +diff --git a/lib/debugobjects.c b/lib/debugobjects.c +index 5f23d896df55a..62d095fd0c52a 100644 +--- a/lib/debugobjects.c ++++ b/lib/debugobjects.c +@@ -371,6 +371,15 @@ static void debug_print_object(struct debug_obj *obj, char *msg) + struct debug_obj_descr *descr = obj->descr; + static int limit; + ++ /* ++ * Don't report if lookup_object_or_alloc() by the current thread ++ * failed because lookup_object_or_alloc()/debug_objects_oom() by a ++ * concurrent thread turned off debug_objects_enabled and cleared ++ * the hash buckets. ++ */ ++ if (!debug_objects_enabled) ++ return; ++ + if (limit < 5 && descr != descr_test) { + void *hint = descr->debug_hint ? + descr->debug_hint(obj->object) : NULL; +diff --git a/lib/radix-tree.c b/lib/radix-tree.c +index e5cab5c4e3830..8d29fa5b26957 100644 +--- a/lib/radix-tree.c ++++ b/lib/radix-tree.c +@@ -1498,7 +1498,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root, + { + struct radix_tree_node *node, *parent; + unsigned long maxindex; +- int uninitialized_var(offset); ++ int offset; + + radix_tree_load_root(root, &node, &maxindex); + if (index > maxindex) +diff --git a/lib/test_firmware.c b/lib/test_firmware.c +index f4cc874021da2..b5e779bcfb343 100644 +--- a/lib/test_firmware.c ++++ b/lib/test_firmware.c +@@ -160,7 +160,7 @@ static int __kstrncpy(char **dst, const char *name, size_t count, gfp_t gfp) + { + *dst = kstrndup(name, count, gfp); + if (!*dst) +- return -ENOSPC; ++ return -ENOMEM; + return count; + } + +@@ -456,7 +456,7 @@ static ssize_t trigger_request_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s'\n", name); + +@@ -497,7 +497,7 @@ static ssize_t trigger_async_request_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s'\n", name); + +@@ -540,7 +540,7 @@ static ssize_t trigger_custom_fallback_store(struct device *dev, + + name = kstrndup(buf, count, GFP_KERNEL); + if (!name) +- return -ENOSPC; ++ return -ENOMEM; + + pr_info("loading '%s' using custom fallback mechanism\n", name); + +@@ -618,6 +618,11 @@ static ssize_t trigger_batched_requests_store(struct device *dev, + + mutex_lock(&test_fw_mutex); + ++ if (test_fw_config->reqs) { ++ rc = -EBUSY; ++ goto out_bail; ++ } ++ + test_fw_config->reqs = + vzalloc(array3_size(sizeof(struct test_batched_req), + test_fw_config->num_requests, 2)); +@@ -721,6 +726,11 @@ ssize_t trigger_batched_requests_async_store(struct device *dev, + + mutex_lock(&test_fw_mutex); + ++ if (test_fw_config->reqs) { ++ rc = -EBUSY; ++ goto out_bail; ++ } ++ + test_fw_config->reqs = + vzalloc(array3_size(sizeof(struct test_batched_req), + test_fw_config->num_requests, 2)); +diff --git a/lib/ts_bm.c b/lib/ts_bm.c +index 9e66ee4020e90..5de382e79a45a 100644 +--- a/lib/ts_bm.c ++++ b/lib/ts_bm.c +@@ -64,10 +64,12 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) + struct ts_bm *bm = ts_config_priv(conf); + unsigned int i, text_len, consumed = state->offset; + const u8 *text; +- int shift = bm->patlen - 1, bs; ++ int bs; + const u8 icase = conf->flags & TS_IGNORECASE; + + for (;;) { ++ int shift = bm->patlen - 1; ++ + text_len = conf->get_next_block(consumed, &text, conf, state); + + if (unlikely(text_len == 0)) +diff --git a/mm/frontswap.c b/mm/frontswap.c +index 157e5bf635042..80bf870d881a0 100644 +--- a/mm/frontswap.c ++++ b/mm/frontswap.c +@@ -447,7 +447,7 @@ static int __frontswap_shrink(unsigned long target_pages, + void frontswap_shrink(unsigned long target_pages) + { + unsigned long pages_to_unuse = 0; +- int uninitialized_var(type), ret; ++ int type, ret; + + /* + * we don't want to hold swap_lock while doing a very +diff --git a/mm/ksm.c b/mm/ksm.c +index 87a541ab1474f..9693aadec6e26 100644 +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -2381,7 +2381,7 @@ next_mm: + static void ksm_do_scan(unsigned int scan_npages) + { + struct rmap_item *rmap_item; +- struct page *uninitialized_var(page); ++ struct page *page; + + while (scan_npages-- && likely(!freezing(current))) { + cond_resched(); +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index bc4c61dcf95c7..5a366cf798214 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -919,7 +919,7 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, + struct mem_cgroup *prev, + struct mem_cgroup_reclaim_cookie *reclaim) + { +- struct mem_cgroup_reclaim_iter *uninitialized_var(iter); ++ struct mem_cgroup_reclaim_iter *iter; + struct cgroup_subsys_state *css = NULL; + struct mem_cgroup *memcg = NULL; + struct mem_cgroup *pos = NULL; +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 35088e830bff8..86fd6bedaff4d 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -1147,7 +1147,7 @@ int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from, + static struct page *new_page(struct page *page, unsigned long start) + { + struct vm_area_struct *vma; +- unsigned long uninitialized_var(address); ++ unsigned long address; + + vma = find_vma(current->mm, start); + while (vma) { +@@ -1545,7 +1545,7 @@ static int kernel_get_mempolicy(int __user *policy, + unsigned long flags) + { + int err; +- int uninitialized_var(pval); ++ int pval; + nodemask_t nodes; + + if (nmask != NULL && maxnode < nr_node_ids) +diff --git a/mm/percpu.c b/mm/percpu.c +index 0151f276ae680..6ae4993214b4d 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -2283,7 +2283,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( + const size_t static_size = __per_cpu_end - __per_cpu_start; + int nr_groups = 1, nr_units = 0; + size_t size_sum, min_unit_size, alloc_size; +- int upa, max_upa, uninitialized_var(best_upa); /* units_per_alloc */ ++ int upa, max_upa, best_upa; /* units_per_alloc */ + int last_allocs, group, unit; + unsigned int cpu, tcpu; + struct pcpu_alloc_info *ai; +diff --git a/mm/slub.c b/mm/slub.c +index ef730ea8263cb..edf766f1de63f 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -1179,7 +1179,7 @@ static noinline int free_debug_processing( + struct kmem_cache_node *n = get_node(s, page_to_nid(page)); + void *object = head; + int cnt = 0; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&n->list_lock, flags); +@@ -2826,7 +2826,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, + struct page new; + unsigned long counters; + struct kmem_cache_node *n = NULL; +- unsigned long uninitialized_var(flags); ++ unsigned long flags; + + stat(s, FREE_SLOWPATH); + +diff --git a/mm/swap.c b/mm/swap.c +index 45fdbfb6b2a60..ce13e428380e9 100644 +--- a/mm/swap.c ++++ b/mm/swap.c +@@ -721,8 +721,8 @@ void release_pages(struct page **pages, int nr) + LIST_HEAD(pages_to_free); + struct pglist_data *locked_pgdat = NULL; + struct lruvec *lruvec; +- unsigned long uninitialized_var(flags); +- unsigned int uninitialized_var(lock_batch); ++ unsigned long flags; ++ unsigned int lock_batch; + + for (i = 0; i < nr; i++) { + struct page *page = pages[i]; +diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c +index 1c6d01a27e0e8..b831e5fe3ebc1 100644 +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -45,6 +45,7 @@ static const struct proto_ops l2cap_sock_ops; + static void l2cap_sock_init(struct sock *sk, struct sock *parent); + static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, + int proto, gfp_t prio, int kern); ++static void l2cap_sock_cleanup_listen(struct sock *parent); + + bool l2cap_is_socket(struct socket *sock) + { +@@ -1205,6 +1206,7 @@ static int l2cap_sock_release(struct socket *sock) + if (!sk) + return 0; + ++ l2cap_sock_cleanup_listen(sk); + bt_sock_unlink(&l2cap_sk_list, sk); + + err = l2cap_sock_shutdown(sock, 2); +diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c +index b5fb2b682e191..ab539551b7d39 100644 +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -161,8 +161,9 @@ void br_manage_promisc(struct net_bridge *br) + * This lets us disable promiscuous mode and write + * this config to hw. + */ +- if (br->auto_cnt == 0 || +- (br->auto_cnt == 1 && br_auto_port(p))) ++ if ((p->dev->priv_flags & IFF_UNICAST_FLT) && ++ (br->auto_cnt == 0 || ++ (br->auto_cnt == 1 && br_auto_port(p)))) + br_port_clear_promisc(p); + else + br_port_set_promisc(p); +diff --git a/net/can/bcm.c b/net/can/bcm.c +index 61269cc2fa828..1c9953c68f095 100644 +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -1520,6 +1520,12 @@ static int bcm_release(struct socket *sock) + + lock_sock(sk); + ++#if IS_ENABLED(CONFIG_PROC_FS) ++ /* remove procfs entry */ ++ if (net->can.bcmproc_dir && bo->bcm_proc_read) ++ remove_proc_entry(bo->procname, net->can.bcmproc_dir); ++#endif /* CONFIG_PROC_FS */ ++ + list_for_each_entry_safe(op, next, &bo->tx_ops, list) + bcm_remove_op(op); + +@@ -1555,12 +1561,6 @@ static int bcm_release(struct socket *sock) + list_for_each_entry_safe(op, next, &bo->rx_ops, list) + bcm_remove_op(op); + +-#if IS_ENABLED(CONFIG_PROC_FS) +- /* remove procfs entry */ +- if (net->can.bcmproc_dir && bo->bcm_proc_read) +- remove_proc_entry(bo->procname, net->can.bcmproc_dir); +-#endif /* CONFIG_PROC_FS */ +- + /* remove device reference */ + if (bo->bound) { + bo->bound = 0; +diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c +index 713fe1fbcb181..90ebb0ba927cd 100644 +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -3137,17 +3137,24 @@ static int linger_reg_commit_wait(struct ceph_osd_linger_request *lreq) + int ret; + + dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); +- ret = wait_for_completion_interruptible(&lreq->reg_commit_wait); ++ ret = wait_for_completion_killable(&lreq->reg_commit_wait); + return ret ?: lreq->reg_commit_error; + } + +-static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq) ++static int linger_notify_finish_wait(struct ceph_osd_linger_request *lreq, ++ unsigned long timeout) + { +- int ret; ++ long left; + + dout("%s lreq %p linger_id %llu\n", __func__, lreq, lreq->linger_id); +- ret = wait_for_completion_interruptible(&lreq->notify_finish_wait); +- return ret ?: lreq->notify_finish_error; ++ left = wait_for_completion_killable_timeout(&lreq->notify_finish_wait, ++ ceph_timeout_jiffies(timeout)); ++ if (left <= 0) ++ left = left ?: -ETIMEDOUT; ++ else ++ left = lreq->notify_finish_error; /* completed */ ++ ++ return left; + } + + /* +@@ -4760,7 +4767,8 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc, + + ret = linger_reg_commit_wait(lreq); + if (!ret) +- ret = linger_notify_finish_wait(lreq); ++ ret = linger_notify_finish_wait(lreq, ++ msecs_to_jiffies(2 * timeout * MSEC_PER_SEC)); + else + dout("lreq %p failed to initiate notify %d\n", lreq, ret); + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 2837cc03f69e2..79f62517e24a5 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -3436,7 +3436,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, + ndm->ndm_ifindex = dev->ifindex; + ndm->ndm_state = ndm_state; + +- if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) ++ if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr)) + goto nla_put_failure; + if (vid) + if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid)) +@@ -3450,10 +3450,10 @@ nla_put_failure: + return -EMSGSIZE; + } + +-static inline size_t rtnl_fdb_nlmsg_size(void) ++static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev) + { + return NLMSG_ALIGN(sizeof(struct ndmsg)) + +- nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ ++ nla_total_size(dev->addr_len) + /* NDA_LLADDR */ + nla_total_size(sizeof(u16)) + /* NDA_VLAN */ + 0; + } +@@ -3465,7 +3465,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, + struct sk_buff *skb; + int err = -ENOBUFS; + +- skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC); ++ skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC); + if (!skb) + goto errout; + +diff --git a/net/core/sock.c b/net/core/sock.c +index 347a55519d0a5..3e6da3694a5a5 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1319,7 +1319,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + if (!sock->ops->set_peek_off) + return -EOPNOTSUPP; + +- v.val = sk->sk_peek_off; ++ v.val = READ_ONCE(sk->sk_peek_off); + break; + case SO_NOFCS: + v.val = sock_flag(sk, SOCK_NOFCS); +@@ -1349,7 +1349,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, + + #ifdef CONFIG_NET_RX_BUSY_POLL + case SO_BUSY_POLL: +- v.val = sk->sk_ll_usec; ++ v.val = READ_ONCE(sk->sk_ll_usec); + break; + #endif + +@@ -1939,13 +1939,24 @@ kuid_t sock_i_uid(struct sock *sk) + } + EXPORT_SYMBOL(sock_i_uid); + +-unsigned long sock_i_ino(struct sock *sk) ++unsigned long __sock_i_ino(struct sock *sk) + { + unsigned long ino; + +- read_lock_bh(&sk->sk_callback_lock); ++ read_lock(&sk->sk_callback_lock); + ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; +- read_unlock_bh(&sk->sk_callback_lock); ++ read_unlock(&sk->sk_callback_lock); ++ return ino; ++} ++EXPORT_SYMBOL(__sock_i_ino); ++ ++unsigned long sock_i_ino(struct sock *sk) ++{ ++ unsigned long ino; ++ ++ local_bh_disable(); ++ ino = __sock_i_ino(sk); ++ local_bh_enable(); + return ino; + } + EXPORT_SYMBOL(sock_i_ino); +@@ -2548,7 +2559,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim); + + int sk_set_peek_off(struct sock *sk, int val) + { +- sk->sk_peek_off = val; ++ WRITE_ONCE(sk->sk_peek_off, val); + return 0; + } + EXPORT_SYMBOL_GPL(sk_set_peek_off); +diff --git a/net/dccp/options.c b/net/dccp/options.c +index 4e40db017e198..3c464d63b0bb3 100644 +--- a/net/dccp/options.c ++++ b/net/dccp/options.c +@@ -60,7 +60,7 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, + (dh->dccph_doff * 4); + struct dccp_options_received *opt_recv = &dp->dccps_options_received; + unsigned char opt, len; +- unsigned char *uninitialized_var(value); ++ unsigned char *value; + u32 elapsed_time; + __be32 opt_val; + int rc; +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 5a272d09b8248..c6d670cd872f0 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -579,20 +579,8 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_hashed(osk); +- if (ret) { +- /* Before deleting the node, we insert a new one to make +- * sure that the look-up-sk process would not miss either +- * of them and that at least one node would exist in ehash +- * table all the time. Otherwise there's a tiny chance +- * that lookup process could find nothing in ehash table. +- */ +- __sk_nulls_add_node_tail_rcu(sk, list); +- sk_nulls_del_node_init_rcu(osk); +- } +- goto unlock; +- } +- if (found_dup_sk) { ++ ret = sk_nulls_del_node_init_rcu(osk); ++ } else if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -601,7 +589,6 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + +-unlock: + spin_unlock(lock); + + return ret; +diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c +index fedd19c22b392..88c5069b5d20c 100644 +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -80,10 +80,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw) + } + EXPORT_SYMBOL_GPL(inet_twsk_put); + +-static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw, +- struct hlist_nulls_head *list) ++static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, ++ struct hlist_nulls_head *list) + { +- hlist_nulls_add_tail_rcu(&tw->tw_node, list); ++ hlist_nulls_add_head_rcu(&tw->tw_node, list); + } + + static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, +@@ -119,7 +119,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, + + spin_lock(lock); + +- inet_twsk_add_node_tail_rcu(tw, &ehead->chain); ++ inet_twsk_add_node_rcu(tw, &ehead->chain); + + /* Step 3: Remove SK from hash chain */ + if (__sk_nulls_del_node_init_rcu(sk)) +diff --git a/net/ipv4/netfilter/nf_socket_ipv4.c b/net/ipv4/netfilter/nf_socket_ipv4.c +index 4824b1e183a1d..bff2b85c5fd6b 100644 +--- a/net/ipv4/netfilter/nf_socket_ipv4.c ++++ b/net/ipv4/netfilter/nf_socket_ipv4.c +@@ -96,11 +96,11 @@ nf_socket_get_sock_v4(struct net *net, struct sk_buff *skb, const int doff, + struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb, + const struct net_device *indev) + { +- __be32 uninitialized_var(daddr), uninitialized_var(saddr); +- __be16 uninitialized_var(dport), uninitialized_var(sport); ++ __be32 daddr, saddr; ++ __be16 dport, sport; + const struct iphdr *iph = ip_hdr(skb); + struct sk_buff *data_skb = NULL; +- u8 uninitialized_var(protocol); ++ u8 protocol; + #if IS_ENABLED(CONFIG_NF_CONNTRACK) + enum ip_conntrack_info ctinfo; + struct nf_conn const *ct; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index cb96775fc86f6..00648a478c6a5 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3000,18 +3000,18 @@ static int do_tcp_setsockopt(struct sock *sk, int level, + + case TCP_LINGER2: + if (val < 0) +- tp->linger2 = -1; +- else if (val > net->ipv4.sysctl_tcp_fin_timeout / HZ) +- tp->linger2 = 0; ++ WRITE_ONCE(tp->linger2, -1); ++ else if (val > TCP_FIN_TIMEOUT_MAX / HZ) ++ WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX); + else +- tp->linger2 = val * HZ; ++ WRITE_ONCE(tp->linger2, val * HZ); + break; + + case TCP_DEFER_ACCEPT: + /* Translate value in seconds to number of retransmits */ +- icsk->icsk_accept_queue.rskq_defer_accept = +- secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, +- TCP_RTO_MAX / HZ); ++ WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept, ++ secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, ++ TCP_RTO_MAX / HZ)); + break; + + case TCP_WINDOW_CLAMP: +@@ -3099,7 +3099,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, + err = tcp_repair_set_window(tp, optval, optlen); + break; + case TCP_NOTSENT_LOWAT: +- tp->notsent_lowat = val; ++ WRITE_ONCE(tp->notsent_lowat, val); + sk->sk_write_space(sk); + break; + case TCP_INQ: +@@ -3401,13 +3401,14 @@ static int do_tcp_getsockopt(struct sock *sk, int level, + val = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; + break; + case TCP_LINGER2: +- val = tp->linger2; ++ val = READ_ONCE(tp->linger2); + if (val >= 0) + val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ; + break; + case TCP_DEFER_ACCEPT: +- val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, +- TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); ++ val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept); ++ val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ, ++ TCP_RTO_MAX / HZ); + break; + case TCP_WINDOW_CLAMP: + val = tp->window_clamp; +@@ -3553,7 +3554,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level, + break; + + case TCP_FASTOPEN: +- val = icsk->icsk_accept_queue.fastopenq.max_qlen; ++ val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen); + break; + + case TCP_FASTOPEN_CONNECT: +@@ -3568,7 +3569,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level, + val = tcp_time_stamp_raw() + tp->tsoffset; + break; + case TCP_NOTSENT_LOWAT: +- val = tp->notsent_lowat; ++ val = READ_ONCE(tp->notsent_lowat); + break; + case TCP_INQ: + val = tp->recvmsg_inq; +diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c +index f726591de7c7a..f7bb78b443fa9 100644 +--- a/net/ipv4/tcp_fastopen.c ++++ b/net/ipv4/tcp_fastopen.c +@@ -276,6 +276,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, + static bool tcp_fastopen_queue_check(struct sock *sk) + { + struct fastopen_queue *fastopenq; ++ int max_qlen; + + /* Make sure the listener has enabled fastopen, and we don't + * exceed the max # of pending TFO requests allowed before trying +@@ -288,10 +289,11 @@ static bool tcp_fastopen_queue_check(struct sock *sk) + * temporarily vs a server not supporting Fast Open at all. + */ + fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq; +- if (fastopenq->max_qlen == 0) ++ max_qlen = READ_ONCE(fastopenq->max_qlen); ++ if (max_qlen == 0) + return false; + +- if (fastopenq->qlen >= fastopenq->max_qlen) { ++ if (fastopenq->qlen >= max_qlen) { + struct request_sock *req1; + spin_lock(&fastopenq->lock); + req1 = fastopenq->rskq_rst_head; +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index bd921fa7b9ab4..281f7799aeafc 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3429,8 +3429,11 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32 + static bool __tcp_oow_rate_limited(struct net *net, int mib_idx, + u32 *last_oow_ack_time) + { +- if (*last_oow_ack_time) { +- s32 elapsed = (s32)(tcp_jiffies32 - *last_oow_ack_time); ++ /* Paired with the WRITE_ONCE() in this function. */ ++ u32 val = READ_ONCE(*last_oow_ack_time); ++ ++ if (val) { ++ s32 elapsed = (s32)(tcp_jiffies32 - val); + + if (0 <= elapsed && + elapsed < READ_ONCE(net->ipv4.sysctl_tcp_invalid_ratelimit)) { +@@ -3439,7 +3442,10 @@ static bool __tcp_oow_rate_limited(struct net *net, int mib_idx, + } + } + +- *last_oow_ack_time = tcp_jiffies32; ++ /* Paired with the prior READ_ONCE() and with itself, ++ * as we might be lockless. ++ */ ++ WRITE_ONCE(*last_oow_ack_time, tcp_jiffies32); + + return false; /* not rate-limited: go ahead, send dupack now! */ + } +diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c +index 4960e2b6bd7f7..7bbd9125b5000 100644 +--- a/net/ipv4/tcp_metrics.c ++++ b/net/ipv4/tcp_metrics.c +@@ -40,7 +40,7 @@ struct tcp_fastopen_metrics { + + struct tcp_metrics_block { + struct tcp_metrics_block __rcu *tcpm_next; +- possible_net_t tcpm_net; ++ struct net *tcpm_net; + struct inetpeer_addr tcpm_saddr; + struct inetpeer_addr tcpm_daddr; + unsigned long tcpm_stamp; +@@ -51,34 +51,38 @@ struct tcp_metrics_block { + struct rcu_head rcu_head; + }; + +-static inline struct net *tm_net(struct tcp_metrics_block *tm) ++static inline struct net *tm_net(const struct tcp_metrics_block *tm) + { +- return read_pnet(&tm->tcpm_net); ++ /* Paired with the WRITE_ONCE() in tcpm_new() */ ++ return READ_ONCE(tm->tcpm_net); + } + + static bool tcp_metric_locked(struct tcp_metrics_block *tm, + enum tcp_metric_index idx) + { +- return tm->tcpm_lock & (1 << idx); ++ /* Paired with WRITE_ONCE() in tcpm_suck_dst() */ ++ return READ_ONCE(tm->tcpm_lock) & (1 << idx); + } + +-static u32 tcp_metric_get(struct tcp_metrics_block *tm, ++static u32 tcp_metric_get(const struct tcp_metrics_block *tm, + enum tcp_metric_index idx) + { +- return tm->tcpm_vals[idx]; ++ /* Paired with WRITE_ONCE() in tcp_metric_set() */ ++ return READ_ONCE(tm->tcpm_vals[idx]); + } + + static void tcp_metric_set(struct tcp_metrics_block *tm, + enum tcp_metric_index idx, + u32 val) + { +- tm->tcpm_vals[idx] = val; ++ /* Paired with READ_ONCE() in tcp_metric_get() */ ++ WRITE_ONCE(tm->tcpm_vals[idx], val); + } + + static bool addr_same(const struct inetpeer_addr *a, + const struct inetpeer_addr *b) + { +- return inetpeer_addr_cmp(a, b) == 0; ++ return (a->family == b->family) && !inetpeer_addr_cmp(a, b); + } + + struct tcpm_hash_bucket { +@@ -89,6 +93,7 @@ static struct tcpm_hash_bucket *tcp_metrics_hash __read_mostly; + static unsigned int tcp_metrics_hash_log __read_mostly; + + static DEFINE_SPINLOCK(tcp_metrics_lock); ++static DEFINE_SEQLOCK(fastopen_seqlock); + + static void tcpm_suck_dst(struct tcp_metrics_block *tm, + const struct dst_entry *dst, +@@ -97,7 +102,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, + u32 msval; + u32 val; + +- tm->tcpm_stamp = jiffies; ++ WRITE_ONCE(tm->tcpm_stamp, jiffies); + + val = 0; + if (dst_metric_locked(dst, RTAX_RTT)) +@@ -110,30 +115,42 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, + val |= 1 << TCP_METRIC_CWND; + if (dst_metric_locked(dst, RTAX_REORDERING)) + val |= 1 << TCP_METRIC_REORDERING; +- tm->tcpm_lock = val; ++ /* Paired with READ_ONCE() in tcp_metric_locked() */ ++ WRITE_ONCE(tm->tcpm_lock, val); + + msval = dst_metric_raw(dst, RTAX_RTT); +- tm->tcpm_vals[TCP_METRIC_RTT] = msval * USEC_PER_MSEC; ++ tcp_metric_set(tm, TCP_METRIC_RTT, msval * USEC_PER_MSEC); + + msval = dst_metric_raw(dst, RTAX_RTTVAR); +- tm->tcpm_vals[TCP_METRIC_RTTVAR] = msval * USEC_PER_MSEC; +- tm->tcpm_vals[TCP_METRIC_SSTHRESH] = dst_metric_raw(dst, RTAX_SSTHRESH); +- tm->tcpm_vals[TCP_METRIC_CWND] = dst_metric_raw(dst, RTAX_CWND); +- tm->tcpm_vals[TCP_METRIC_REORDERING] = dst_metric_raw(dst, RTAX_REORDERING); ++ tcp_metric_set(tm, TCP_METRIC_RTTVAR, msval * USEC_PER_MSEC); ++ tcp_metric_set(tm, TCP_METRIC_SSTHRESH, ++ dst_metric_raw(dst, RTAX_SSTHRESH)); ++ tcp_metric_set(tm, TCP_METRIC_CWND, ++ dst_metric_raw(dst, RTAX_CWND)); ++ tcp_metric_set(tm, TCP_METRIC_REORDERING, ++ dst_metric_raw(dst, RTAX_REORDERING)); + if (fastopen_clear) { ++ write_seqlock(&fastopen_seqlock); + tm->tcpm_fastopen.mss = 0; + tm->tcpm_fastopen.syn_loss = 0; + tm->tcpm_fastopen.try_exp = 0; + tm->tcpm_fastopen.cookie.exp = false; + tm->tcpm_fastopen.cookie.len = 0; ++ write_sequnlock(&fastopen_seqlock); + } + } + + #define TCP_METRICS_TIMEOUT (60 * 60 * HZ) + +-static void tcpm_check_stamp(struct tcp_metrics_block *tm, struct dst_entry *dst) ++static void tcpm_check_stamp(struct tcp_metrics_block *tm, ++ const struct dst_entry *dst) + { +- if (tm && unlikely(time_after(jiffies, tm->tcpm_stamp + TCP_METRICS_TIMEOUT))) ++ unsigned long limit; ++ ++ if (!tm) ++ return; ++ limit = READ_ONCE(tm->tcpm_stamp) + TCP_METRICS_TIMEOUT; ++ if (unlikely(time_after(jiffies, limit))) + tcpm_suck_dst(tm, dst, false); + } + +@@ -174,20 +191,23 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, + oldest = deref_locked(tcp_metrics_hash[hash].chain); + for (tm = deref_locked(oldest->tcpm_next); tm; + tm = deref_locked(tm->tcpm_next)) { +- if (time_before(tm->tcpm_stamp, oldest->tcpm_stamp)) ++ if (time_before(READ_ONCE(tm->tcpm_stamp), ++ READ_ONCE(oldest->tcpm_stamp))) + oldest = tm; + } + tm = oldest; + } else { +- tm = kmalloc(sizeof(*tm), GFP_ATOMIC); ++ tm = kzalloc(sizeof(*tm), GFP_ATOMIC); + if (!tm) + goto out_unlock; + } +- write_pnet(&tm->tcpm_net, net); ++ /* Paired with the READ_ONCE() in tm_net() */ ++ WRITE_ONCE(tm->tcpm_net, net); ++ + tm->tcpm_saddr = *saddr; + tm->tcpm_daddr = *daddr; + +- tcpm_suck_dst(tm, dst, true); ++ tcpm_suck_dst(tm, dst, reclaim); + + if (likely(!reclaim)) { + tm->tcpm_next = tcp_metrics_hash[hash].chain; +@@ -431,7 +451,7 @@ void tcp_update_metrics(struct sock *sk) + tp->reordering); + } + } +- tm->tcpm_stamp = jiffies; ++ WRITE_ONCE(tm->tcpm_stamp, jiffies); + out_unlock: + rcu_read_unlock(); + } +@@ -544,8 +564,6 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst) + return ret; + } + +-static DEFINE_SEQLOCK(fastopen_seqlock); +- + void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, + struct tcp_fastopen_cookie *cookie) + { +@@ -652,7 +670,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, + } + + if (nla_put_msecs(msg, TCP_METRICS_ATTR_AGE, +- jiffies - tm->tcpm_stamp, ++ jiffies - READ_ONCE(tm->tcpm_stamp), + TCP_METRICS_ATTR_PAD) < 0) + goto nla_put_failure; + +@@ -663,7 +681,7 @@ static int tcp_metrics_fill_info(struct sk_buff *msg, + if (!nest) + goto nla_put_failure; + for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) { +- u32 val = tm->tcpm_vals[i]; ++ u32 val = tcp_metric_get(tm, i); + + if (!val) + continue; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index f261c6d7f1f28..5c5c5736f6892 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -316,9 +316,8 @@ static void addrconf_del_dad_work(struct inet6_ifaddr *ifp) + static void addrconf_mod_rs_timer(struct inet6_dev *idev, + unsigned long when) + { +- if (!timer_pending(&idev->rs_timer)) ++ if (!mod_timer(&idev->rs_timer, jiffies + when)) + in6_dev_hold(idev); +- mod_timer(&idev->rs_timer, jiffies + when); + } + + static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp, +@@ -2489,12 +2488,18 @@ static void manage_tempaddrs(struct inet6_dev *idev, + ipv6_ifa_notify(0, ift); + } + +- if ((create || list_empty(&idev->tempaddr_list)) && +- idev->cnf.use_tempaddr > 0) { ++ /* Also create a temporary address if it's enabled but no temporary ++ * address currently exists. ++ * However, we get called with valid_lft == 0, prefered_lft == 0, create == false ++ * as part of cleanup (ie. deleting the mngtmpaddr). ++ * We don't want that to result in creating a new temporary ip address. ++ */ ++ if (list_empty(&idev->tempaddr_list) && (valid_lft || prefered_lft)) ++ create = true; ++ ++ if (create && idev->cnf.use_tempaddr > 0) { + /* When a new public address is created as described + * in [ADDRCONF], also create a new temporary address. +- * Also create a temporary address if it's enabled but +- * no temporary address currently exists. + */ + read_unlock_bh(&idev->lock); + ipv6_create_tempaddr(ifp, NULL, false); +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index fbc8746371b6d..bfafd7649ccb3 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -395,23 +395,31 @@ relookup_failed: + return ERR_PTR(err); + } + +-static int icmp6_iif(const struct sk_buff *skb) ++static struct net_device *icmp6_dev(const struct sk_buff *skb) + { +- int iif = skb->dev->ifindex; ++ struct net_device *dev = skb->dev; + + /* for local traffic to local address, skb dev is the loopback + * device. Check if there is a dst attached to the skb and if so + * get the real device index. Same is needed for replies to a link + * local address on a device enslaved to an L3 master device + */ +- if (unlikely(iif == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) { ++ if (unlikely(dev->ifindex == LOOPBACK_IFINDEX || netif_is_l3_master(skb->dev))) { + const struct rt6_info *rt6 = skb_rt6_info(skb); + +- if (rt6) +- iif = rt6->rt6i_idev->dev->ifindex; ++ /* The destination could be an external IP in Ext Hdr (SRv6, RPL, etc.), ++ * and ip6_null_entry could be set to skb if no route is found. ++ */ ++ if (rt6 && rt6->rt6i_idev) ++ dev = rt6->rt6i_idev->dev; + } + +- return iif; ++ return dev; ++} ++ ++static int icmp6_iif(const struct sk_buff *skb) ++{ ++ return icmp6_dev(skb)->ifindex; + } + + /* +@@ -800,7 +808,7 @@ out: + static int icmpv6_rcv(struct sk_buff *skb) + { + struct net *net = dev_net(skb->dev); +- struct net_device *dev = skb->dev; ++ struct net_device *dev = icmp6_dev(skb); + struct inet6_dev *idev = __in6_dev_get(dev); + const struct in6_addr *saddr, *daddr; + struct icmp6hdr *hdr; +diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c +index f994f50e15162..1858cf783a4ff 100644 +--- a/net/ipv6/ip6_flowlabel.c ++++ b/net/ipv6/ip6_flowlabel.c +@@ -518,7 +518,7 @@ int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq, + + int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) + { +- int uninitialized_var(err); ++ int err; + struct net *net = sock_net(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + struct in6_flowlabel_req freq; +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index 45c304b51b2b7..aa8ada354a399 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -960,7 +960,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, + goto tx_err; + + if (skb->len > dev->mtu + dev->hard_header_len) { +- pskb_trim(skb, dev->mtu + dev->hard_header_len); ++ if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) ++ goto tx_err; + truncate = true; + } + +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index e9eb917342b85..329bad6cbb768 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -1064,7 +1064,7 @@ static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt, + And all this only to mangle msg->im6_msgtype and + to set msg->im6_mbz to "mbz" :-) + */ +- skb_push(skb, -skb_network_offset(pkt)); ++ __skb_pull(skb, skb_network_offset(pkt)); + + skb_push(skb, sizeof(*msg)); + skb_reset_transport_header(skb); +diff --git a/net/ipv6/netfilter/nf_socket_ipv6.c b/net/ipv6/netfilter/nf_socket_ipv6.c +index 58e839e2ce1d3..5e5463459563f 100644 +--- a/net/ipv6/netfilter/nf_socket_ipv6.c ++++ b/net/ipv6/netfilter/nf_socket_ipv6.c +@@ -102,7 +102,7 @@ nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, + struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb, + const struct net_device *indev) + { +- __be16 uninitialized_var(dport), uninitialized_var(sport); ++ __be16 dport, sport; + const struct in6_addr *daddr = NULL, *saddr = NULL; + struct ipv6hdr *iph = ipv6_hdr(skb), ipv6_var; + struct sk_buff *data_skb = NULL; +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index 60dfd0d118512..b596727f04978 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -302,7 +302,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *skb, + skb_network_header_len(skb)); + + rcu_read_lock(); +- __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS); ++ __IP6_INC_STATS(net, __in6_dev_stats_get(dev, skb), IPSTATS_MIB_REASMOKS); + rcu_read_unlock(); + fq->q.fragments = NULL; + fq->q.rb_fragments = RB_ROOT; +@@ -317,7 +317,7 @@ out_oom: + net_dbg_ratelimited("ip6_frag_reasm: no memory for reassembly\n"); + out_fail: + rcu_read_lock(); +- __IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); ++ __IP6_INC_STATS(net, __in6_dev_stats_get(dev, skb), IPSTATS_MIB_REASMFAILS); + rcu_read_unlock(); + inet_frag_kill(&fq->q); + return -1; +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index 9274603514e54..cf0bbe2e3a79f 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -99,7 +99,7 @@ static u32 udp6_ehashfn(const struct net *net, + fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret); + + return __inet6_ehashfn(lhash, lport, fhash, fport, +- udp_ipv6_hash_secret + net_hash_mix(net)); ++ udp6_ehash_secret + net_hash_mix(net)); + } + + int udp_v6_get_port(struct sock *sk, unsigned short snum) +diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c +index 82cb93f66b9bd..f9e801cc50f5e 100644 +--- a/net/llc/llc_input.c ++++ b/net/llc/llc_input.c +@@ -162,9 +162,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, + void (*sta_handler)(struct sk_buff *skb); + void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); + +- if (!net_eq(dev_net(dev), &init_net)) +- goto drop; +- + /* + * When the interface is in promisc. mode, drop all the crap that it + * receives, do not try to analyse it. +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 0427e66bc4786..31756d1bf83e7 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -791,20 +791,9 @@ static struct nlmsghdr * + start_msg(struct sk_buff *skb, u32 portid, u32 seq, unsigned int flags, + enum ipset_cmd cmd) + { +- struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; +- +- nlh = nlmsg_put(skb, portid, seq, nfnl_msg_type(NFNL_SUBSYS_IPSET, cmd), +- sizeof(*nfmsg), flags); +- if (!nlh) +- return NULL; +- +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = NFPROTO_IPV4; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- +- return nlh; ++ return nfnl_msg_put(skb, portid, seq, ++ nfnl_msg_type(NFNL_SUBSYS_IPSET, cmd), flags, ++ NFPROTO_IPV4, NFNETLINK_V0, 0); + } + + /* Create a set */ +diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c +index efc14c7b4f8ef..c2fece0593eaa 100644 +--- a/net/netfilter/nf_conntrack_ftp.c ++++ b/net/netfilter/nf_conntrack_ftp.c +@@ -383,7 +383,7 @@ static int help(struct sk_buff *skb, + int ret; + u32 seq; + int dir = CTINFO2DIR(ctinfo); +- unsigned int uninitialized_var(matchlen), uninitialized_var(matchoff); ++ unsigned int matchlen, matchoff; + struct nf_ct_ftp_master *ct_ftp_info = nfct_help_data(ct); + struct nf_conntrack_expect *exp; + union nf_inet_addr *daddr; +diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c +index e24b762ffa1d4..06c70d4584cfe 100644 +--- a/net/netfilter/nf_conntrack_helper.c ++++ b/net/netfilter/nf_conntrack_helper.c +@@ -400,6 +400,9 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me) + BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); + BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1); + ++ if (!nf_ct_helper_hash) ++ return -ENOENT; ++ + if (me->expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT) + return -EINVAL; + +@@ -570,4 +573,5 @@ void nf_conntrack_helper_fini(void) + { + nf_ct_extend_unregister(&helper_extend); + kvfree(nf_ct_helper_hash); ++ nf_ct_helper_hash = NULL; + } +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index b710889a90f6f..83e8566ec3f05 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -517,20 +517,15 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + { + const struct nf_conntrack_zone *zone; + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + struct nlattr *nest_parms; + unsigned int flags = portid ? NLM_F_MULTI : 0, event; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_NEW); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, nf_ct_l3num(ct), ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = nf_ct_l3num(ct); +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + zone = nf_ct_zone(ct); + + nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); +@@ -687,7 +682,6 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) + const struct nf_conntrack_zone *zone; + struct net *net; + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + struct nlattr *nest_parms; + struct nf_conn *ct = item->ct; + struct sk_buff *skb; +@@ -717,15 +711,11 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) + goto errout; + + type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, type); +- nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, item->portid, 0, type, flags, nf_ct_l3num(ct), ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = nf_ct_l3num(ct); +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + zone = nf_ct_zone(ct); + + nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED); +@@ -2170,20 +2160,15 @@ ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq, + __u16 cpu, const struct ip_conntrack_stat *st) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0, event; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, + IPCTNL_MSG_CT_GET_STATS_CPU); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, htons(cpu)); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(cpu); +- + if (nla_put_be32(skb, CTA_STATS_FOUND, htonl(st->found)) || + nla_put_be32(skb, CTA_STATS_INVALID, htonl(st->invalid)) || + nla_put_be32(skb, CTA_STATS_IGNORE, htonl(st->ignore)) || +@@ -2254,20 +2239,15 @@ ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + struct net *net) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0, event; + unsigned int nr_conntracks = atomic_read(&net->ct.count); + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET_STATS); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_be32(skb, CTA_STATS_GLOBAL_ENTRIES, htonl(nr_conntracks))) + goto nla_put_failure; + +@@ -2780,19 +2760,14 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq, + int event, const struct nf_conntrack_expect *exp) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, ++ exp->tuple.src.l3num, NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = exp->tuple.src.l3num; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (ctnetlink_exp_dump_expect(skb, exp) < 0) + goto nla_put_failure; + +@@ -2812,7 +2787,6 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) + struct nf_conntrack_expect *exp = item->exp; + struct net *net = nf_ct_exp_net(exp); + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + struct sk_buff *skb; + unsigned int type, group; + int flags = 0; +@@ -2835,15 +2809,11 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) + goto errout; + + type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, type); +- nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, item->portid, 0, type, flags, ++ exp->tuple.src.l3num, NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = exp->tuple.src.l3num; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (ctnetlink_exp_dump_expect(skb, exp) < 0) + goto nla_put_failure; + +@@ -3413,20 +3383,15 @@ ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu, + const struct ip_conntrack_stat *st) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0, event; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, + IPCTNL_MSG_EXP_GET_STATS_CPU); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, htons(cpu)); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(cpu); +- + if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) || + nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) || + nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete))) +diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c +index 046f118dea06b..d16aa43ebd4d6 100644 +--- a/net/netfilter/nf_conntrack_sip.c ++++ b/net/netfilter/nf_conntrack_sip.c +@@ -605,7 +605,7 @@ int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, + start += strlen(name); + *val = simple_strtoul(start, &end, 0); + if (start == end) +- return 0; ++ return -1; + if (matchoff && matchlen) { + *matchoff = start - dptr; + *matchlen = end - start; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 2968f21915ddf..115bc79ec9055 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -22,10 +22,13 @@ + #include <net/netfilter/nf_tables_core.h> + #include <net/netfilter/nf_tables.h> + #include <net/net_namespace.h> ++#include <net/netns/generic.h> + #include <net/sock.h> + + #define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-")) + ++unsigned int nf_tables_net_id __read_mostly; ++ + static LIST_HEAD(nf_tables_expressions); + static LIST_HEAD(nf_tables_objects); + static LIST_HEAD(nf_tables_flowtables); +@@ -53,7 +56,9 @@ static const struct rhashtable_params nft_chain_ht_params = { + + static void nft_validate_state_update(struct net *net, u8 new_validate_state) + { +- switch (net->nft.validate_state) { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ ++ switch (nft_net->validate_state) { + case NFT_VALIDATE_SKIP: + WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO); + break; +@@ -64,7 +69,7 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state) + return; + } + +- net->nft.validate_state = new_validate_state; ++ nft_net->validate_state = new_validate_state; + } + + static void nft_ctx_init(struct nft_ctx *ctx, +@@ -97,6 +102,7 @@ static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx, + return NULL; + + INIT_LIST_HEAD(&trans->list); ++ INIT_LIST_HEAD(&trans->binding_list); + trans->msg_type = msg_type; + trans->ctx = *ctx; + +@@ -109,34 +115,68 @@ static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx, + return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL); + } + +-static void nft_trans_destroy(struct nft_trans *trans) ++static void nft_trans_list_del(struct nft_trans *trans) + { + list_del(&trans->list); ++ list_del(&trans->binding_list); ++} ++ ++static void nft_trans_destroy(struct nft_trans *trans) ++{ ++ nft_trans_list_del(trans); + kfree(trans); + } + +-static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set) ++static void __nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set, ++ bool bind) + { ++ struct nftables_pernet *nft_net; + struct net *net = ctx->net; + struct nft_trans *trans; + + if (!nft_set_is_anonymous(set)) + return; + +- list_for_each_entry_reverse(trans, &net->nft.commit_list, list) { ++ nft_net = net_generic(net, nf_tables_net_id); ++ list_for_each_entry_reverse(trans, &nft_net->commit_list, list) { + switch (trans->msg_type) { + case NFT_MSG_NEWSET: + if (nft_trans_set(trans) == set) +- nft_trans_set_bound(trans) = true; ++ nft_trans_set_bound(trans) = bind; + break; + case NFT_MSG_NEWSETELEM: + if (nft_trans_elem_set(trans) == set) +- nft_trans_elem_set_bound(trans) = true; ++ nft_trans_elem_set_bound(trans) = bind; + break; + } + } + } + ++static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set) ++{ ++ return __nft_set_trans_bind(ctx, set, true); ++} ++ ++static void nft_set_trans_unbind(const struct nft_ctx *ctx, struct nft_set *set) ++{ ++ return __nft_set_trans_bind(ctx, set, false); ++} ++ ++static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *trans) ++{ ++ struct nftables_pernet *nft_net; ++ ++ nft_net = net_generic(net, nf_tables_net_id); ++ switch (trans->msg_type) { ++ case NFT_MSG_NEWSET: ++ if (nft_set_is_anonymous(nft_trans_set(trans))) ++ list_add_tail(&trans->binding_list, &nft_net->binding_list); ++ break; ++ } ++ ++ list_add_tail(&trans->list, &nft_net->commit_list); ++} ++ + static int nf_tables_register_hook(struct net *net, + const struct nft_table *table, + struct nft_chain *chain) +@@ -187,7 +227,7 @@ static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) + if (msg_type == NFT_MSG_NEWTABLE) + nft_activate_next(ctx->net, ctx->table); + +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + return 0; + } + +@@ -214,7 +254,7 @@ static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type) + if (msg_type == NFT_MSG_NEWCHAIN) + nft_activate_next(ctx->net, ctx->chain); + +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + return 0; + } + +@@ -287,7 +327,7 @@ static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type, + ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID])); + } + nft_trans_rule(trans) = rule; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return trans; + } +@@ -342,7 +382,7 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type, + nft_activate_next(ctx->net, set); + } + nft_trans_set(trans) = set; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return 0; + } +@@ -374,7 +414,7 @@ static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type, + nft_activate_next(ctx->net, obj); + + nft_trans_obj(trans) = obj; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return 0; + } +@@ -407,7 +447,7 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, + nft_activate_next(ctx->net, flowtable); + + nft_trans_flowtable(trans) = flowtable; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return 0; + } +@@ -435,12 +475,14 @@ static struct nft_table *nft_table_lookup(const struct net *net, + const struct nlattr *nla, + u8 family, u8 genmask) + { ++ struct nftables_pernet *nft_net; + struct nft_table *table; + + if (nla == NULL) + return ERR_PTR(-EINVAL); + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ nft_net = net_generic(net, nf_tables_net_id); ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (!nla_strcmp(nla, table->name) && + table->family == family && + nft_active_genmask(table, genmask)) +@@ -454,9 +496,11 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net, + const struct nlattr *nla, + u8 genmask) + { ++ struct nftables_pernet *nft_net; + struct nft_table *table; + +- list_for_each_entry(table, &net->nft.tables, list) { ++ nft_net = net_generic(net, nf_tables_net_id); ++ list_for_each_entry(table, &nft_net->tables, list) { + if (be64_to_cpu(nla_get_be64(nla)) == table->handle && + nft_active_genmask(table, genmask)) + return table; +@@ -509,11 +553,13 @@ __nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family) + static void nft_request_module(struct net *net, const char *fmt, ...) + { + char module_name[MODULE_NAME_LEN]; ++ struct nftables_pernet *nft_net; + LIST_HEAD(commit_list); + va_list args; + int ret; + +- list_splice_init(&net->nft.commit_list, &commit_list); ++ nft_net = net_generic(net, nf_tables_net_id); ++ list_splice_init(&nft_net->commit_list, &commit_list); + + va_start(args, fmt); + ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); +@@ -521,12 +567,12 @@ static void nft_request_module(struct net *net, const char *fmt, ...) + if (ret >= MODULE_NAME_LEN) + return; + +- mutex_unlock(&net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + request_module("%s", module_name); +- mutex_lock(&net->nft.commit_mutex); ++ mutex_lock(&nft_net->commit_mutex); + +- WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); +- list_splice(&commit_list, &net->nft.commit_list); ++ WARN_ON_ONCE(!list_empty(&nft_net->commit_list)); ++ list_splice(&commit_list, &nft_net->commit_list); + } + #endif + +@@ -561,6 +607,13 @@ nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla, + return ERR_PTR(-ENOENT); + } + ++static __be16 nft_base_seq(const struct net *net) ++{ ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ ++ return htons(nft_net->base_seq & 0xffff); ++} ++ + static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { + [NFTA_TABLE_NAME] = { .type = NLA_STRING, + .len = NFT_TABLE_MAXNAMELEN - 1 }, +@@ -573,18 +626,13 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, + int family, const struct nft_table *table) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, family, ++ NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) || + nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) || + nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) || +@@ -631,15 +679,17 @@ static int nf_tables_dump_tables(struct sk_buff *skb, + struct netlink_callback *cb) + { + const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); ++ struct nftables_pernet *nft_net; + const struct nft_table *table; + unsigned int idx = 0, s_idx = cb->args[0]; + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (family != NFPROTO_UNSPEC && family != table->family) + continue; + +@@ -743,7 +793,7 @@ static void nft_table_disable(struct net *net, struct nft_table *table, u32 cnt) + if (cnt && i++ == cnt) + break; + +- nf_unregister_net_hook(net, &nft_base_chain(chain)->ops); ++ nf_tables_unregister_hook(net, table, chain); + } + } + +@@ -758,7 +808,7 @@ static int nf_tables_table_enable(struct net *net, struct nft_table *table) + if (!nft_is_base_chain(chain)) + continue; + +- err = nf_register_net_hook(net, &nft_base_chain(chain)->ops); ++ err = nf_tables_register_hook(net, table, chain); + if (err < 0) + goto err; + +@@ -802,17 +852,18 @@ static int nf_tables_updtable(struct nft_ctx *ctx) + nft_trans_table_enable(trans) = false; + } else if (!(flags & NFT_TABLE_F_DORMANT) && + ctx->table->flags & NFT_TABLE_F_DORMANT) { ++ ctx->table->flags &= ~NFT_TABLE_F_DORMANT; + ret = nf_tables_table_enable(ctx->net, ctx->table); +- if (ret >= 0) { +- ctx->table->flags &= ~NFT_TABLE_F_DORMANT; ++ if (ret >= 0) + nft_trans_table_enable(trans) = true; +- } ++ else ++ ctx->table->flags |= NFT_TABLE_F_DORMANT; + } + if (ret < 0) + goto err; + + nft_trans_table_update(trans) = true; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + return 0; + err: + nft_trans_destroy(trans); +@@ -847,6 +898,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + u8 genmask = nft_genmask_next(net); + int family = nfmsg->nfgen_family; +@@ -856,7 +908,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, + struct nft_ctx ctx; + int err; + +- lockdep_assert_held(&net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + attr = nla[NFTA_TABLE_NAME]; + table = nft_table_lookup(net, attr, family, genmask); + if (IS_ERR(table)) { +@@ -906,7 +958,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, + if (err < 0) + goto err_trans; + +- list_add_tail_rcu(&table->list, &net->nft.tables); ++ list_add_tail_rcu(&table->list, &nft_net->tables); + return 0; + err_trans: + rhltable_destroy(&table->chains_ht); +@@ -986,11 +1038,12 @@ out: + + static int nft_flush(struct nft_ctx *ctx, int family) + { ++ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id); + struct nft_table *table, *nt; + const struct nlattr * const *nla = ctx->nla; + int err = 0; + +- list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) { ++ list_for_each_entry_safe(table, nt, &nft_net->tables, list) { + if (family != AF_UNSPEC && table->family != family) + continue; + +@@ -1104,7 +1157,9 @@ nft_chain_lookup_byhandle(const struct nft_table *table, u64 handle, u8 genmask) + static bool lockdep_commit_lock_is_held(struct net *net) + { + #ifdef CONFIG_PROVE_LOCKING +- return lockdep_is_held(&net->nft.commit_mutex); ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ ++ return lockdep_is_held(&nft_net->commit_mutex); + #else + return true; + #endif +@@ -1207,18 +1262,13 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, + const struct nft_chain *chain) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, family, ++ NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name)) + goto nla_put_failure; + if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle), +@@ -1306,11 +1356,13 @@ static int nf_tables_dump_chains(struct sk_buff *skb, + unsigned int idx = 0, s_idx = cb->args[0]; + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; ++ struct nftables_pernet *nft_net; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (family != NFPROTO_UNSPEC && family != table->family) + continue; + +@@ -1503,12 +1555,13 @@ static int nft_chain_parse_hook(struct net *net, + struct nft_chain_hook *hook, u8 family, + bool autoload) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nlattr *ha[NFTA_HOOK_MAX + 1]; + const struct nft_chain_type *type; + struct net_device *dev; + int err; + +- lockdep_assert_held(&net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + lockdep_nfnl_nft_mutex_not_held(); + + err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK], +@@ -1777,6 +1830,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy) + + if (nla[NFTA_CHAIN_HANDLE] && + nla[NFTA_CHAIN_NAME]) { ++ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id); + struct nft_trans *tmp; + char *name; + +@@ -1786,7 +1840,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy) + goto err; + + err = -EEXIST; +- list_for_each_entry(tmp, &ctx->net->nft.commit_list, list) { ++ list_for_each_entry(tmp, &nft_net->commit_list, list) { + if (tmp->msg_type == NFT_MSG_NEWCHAIN && + tmp->ctx.table == table && + nft_trans_chain_update(tmp) && +@@ -1799,7 +1853,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy) + + nft_trans_chain_name(trans) = name; + } +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return 0; + err: +@@ -1813,6 +1867,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + u8 genmask = nft_genmask_next(net); + int family = nfmsg->nfgen_family; +@@ -1823,7 +1878,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, + struct nft_ctx ctx; + u64 handle = 0; + +- lockdep_assert_held(&net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + + table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask); + if (IS_ERR(table)) { +@@ -2251,21 +2306,16 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, + const struct nft_rule *rule) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + const struct nft_expr *expr, *next; + struct nlattr *list; + const struct nft_rule *prule; + u16 type = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); + +- nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, type, flags, family, NFNETLINK_V0, ++ nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_RULE_TABLE, table->name)) + goto nla_put_failure; + if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name)) +@@ -2351,11 +2401,13 @@ static int nf_tables_dump_rules(struct sk_buff *skb, + unsigned int idx = 0, s_idx = cb->args[0]; + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; ++ struct nftables_pernet *nft_net; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (family != NFPROTO_UNSPEC && family != table->family) + continue; + +@@ -2508,7 +2560,6 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx, + { + struct nft_expr *expr, *next; + +- lockdep_assert_held(&ctx->net->nft.commit_mutex); + /* + * Careful: some expressions might not be initialized in case this + * is called on error from nf_tables_newrule(). +@@ -2574,6 +2625,8 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + err = nft_chain_validate(&ctx, chain); + if (err < 0) + return err; ++ ++ cond_resched(); + } + + return 0; +@@ -2586,6 +2639,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + u8 genmask = nft_genmask_next(net); + struct nft_expr_info *info = NULL; +@@ -2602,7 +2656,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, + int err, rem; + u64 handle, pos_handle; + +- lockdep_assert_held(&net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + + table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask); + if (IS_ERR(table)) { +@@ -2750,12 +2804,13 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, + kvfree(info); + chain->use++; + +- if (net->nft.validate_state == NFT_VALIDATE_DO) ++ if (nft_net->validate_state == NFT_VALIDATE_DO) + return nft_table_validate(net, table); + + return 0; + err2: +- nf_tables_rule_release(&ctx, rule); ++ nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE_ERROR); ++ nf_tables_rule_destroy(&ctx, rule); + err1: + for (i = 0; i < n; i++) { + if (info[i].ops) { +@@ -2772,10 +2827,11 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net, + const struct nft_chain *chain, + const struct nlattr *nla) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + u32 id = ntohl(nla_get_be32(nla)); + struct nft_trans *trans; + +- list_for_each_entry(trans, &net->nft.commit_list, list) { ++ list_for_each_entry(trans, &nft_net->commit_list, list) { + struct nft_rule *rule = nft_trans_rule(trans); + + if (trans->msg_type == NFT_MSG_NEWRULE && +@@ -2894,12 +2950,13 @@ nft_select_set_ops(const struct nft_ctx *ctx, + const struct nft_set_desc *desc, + enum nft_set_policies policy) + { ++ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id); + const struct nft_set_ops *ops, *bops; + struct nft_set_estimate est, best; + const struct nft_set_type *type; + u32 flags = 0; + +- lockdep_assert_held(&ctx->net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + lockdep_nfnl_nft_mutex_not_held(); + #ifdef CONFIG_MODULES + if (list_empty(&nf_tables_set_types)) { +@@ -3045,10 +3102,11 @@ static struct nft_set *nft_set_lookup_byid(const struct net *net, + const struct nft_table *table, + const struct nlattr *nla, u8 genmask) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_trans *trans; + u32 id = ntohl(nla_get_be32(nla)); + +- list_for_each_entry(trans, &net->nft.commit_list, list) { ++ list_for_each_entry(trans, &nft_net->commit_list, list) { + if (trans->msg_type == NFT_MSG_NEWSET) { + struct nft_set *set = nft_trans_set(trans); + +@@ -3158,23 +3216,17 @@ static __be64 nf_jiffies64_to_msecs(u64 input) + static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, + const struct nft_set *set, u16 event, u16 flags) + { +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + struct nlattr *desc; + u32 portid = ctx->portid; + u32 seq = ctx->seq; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), +- flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, ctx->family, ++ NFNETLINK_V0, nft_base_seq(ctx->net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = ctx->family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name)) + goto nla_put_failure; + if (nla_put_string(skb, NFTA_SET_NAME, set->name)) +@@ -3270,14 +3322,16 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) + struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2]; + struct net *net = sock_net(skb->sk); + struct nft_ctx *ctx = cb->data, ctx_set; ++ struct nftables_pernet *nft_net; + + if (cb->args[1]) + return skb->len; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (ctx->family != NFPROTO_UNSPEC && + ctx->family != table->family) + continue; +@@ -3780,6 +3834,15 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, + enum nft_trans_phase phase) + { + switch (phase) { ++ case NFT_TRANS_PREPARE_ERROR: ++ nft_set_trans_unbind(ctx, set); ++ if (nft_set_is_anonymous(set)) ++ nft_deactivate_next(ctx->net, set); ++ else ++ list_del_rcu(&binding->list); ++ ++ set->use--; ++ break; + case NFT_TRANS_PREPARE: + if (nft_set_is_anonymous(set)) + nft_deactivate_next(ctx->net, set); +@@ -3984,18 +4047,19 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) + { + struct nft_set_dump_ctx *dump_ctx = cb->data; + struct net *net = sock_net(skb->sk); ++ struct nftables_pernet *nft_net; + struct nft_table *table; + struct nft_set *set; + struct nft_set_dump_args args; + bool set_found = false; +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + struct nlattr *nest; + u32 portid, seq; + int event; + + rcu_read_lock(); +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ nft_net = net_generic(net, nf_tables_net_id); ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (dump_ctx->ctx.family != NFPROTO_UNSPEC && + dump_ctx->ctx.family != table->family) + continue; +@@ -4021,16 +4085,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) + portid = NETLINK_CB(cb->skb).portid; + seq = cb->nlh->nlmsg_seq; + +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), +- NLM_F_MULTI); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, NLM_F_MULTI, ++ table->family, NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = table->family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name)) + goto nla_put_failure; + if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name)) +@@ -4087,22 +4146,16 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb, + const struct nft_set *set, + const struct nft_set_elem *elem) + { +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + struct nlattr *nest; + int err; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), +- flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, ctx->family, ++ NFNETLINK_V0, nft_base_seq(ctx->net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = ctx->family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name)) + goto nla_put_failure; + if (nla_put_string(skb, NFTA_SET_NAME, set->name)) +@@ -4596,7 +4649,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + } + + nft_trans_elem(trans) = elem; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + return 0; + + err6: +@@ -4621,6 +4674,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + u8 genmask = nft_genmask_next(net); + const struct nlattr *attr; + struct nft_set *set; +@@ -4650,7 +4704,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, + return err; + } + +- if (net->nft.validate_state == NFT_VALIDATE_DO) ++ if (nft_net->validate_state == NFT_VALIDATE_DO) + return nft_table_validate(net, ctx.table); + + return 0; +@@ -4763,7 +4817,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, + nft_set_elem_deactivate(ctx->net, set, &elem); + + nft_trans_elem(trans) = elem; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + return 0; + + fail_ops: +@@ -4797,7 +4851,7 @@ static int nft_flush_set(const struct nft_ctx *ctx, + nft_set_elem_deactivate(ctx->net, set, elem); + nft_trans_elem_set(trans) = set; + nft_trans_elem(trans) = *elem; +- list_add_tail(&trans->list, &ctx->net->nft.commit_list); ++ nft_trans_commit_list_add_tail(ctx->net, trans); + + return 0; + err1: +@@ -5138,19 +5192,14 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, + int family, const struct nft_table *table, + struct nft_object *obj, bool reset) + { +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, family, ++ NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) || + nla_put_string(skb, NFTA_OBJ_NAME, obj->name) || + nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) || +@@ -5181,6 +5230,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) + struct nft_obj_filter *filter = cb->data; + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; ++ struct nftables_pernet *nft_net; + struct nft_object *obj; + bool reset = false; + +@@ -5188,9 +5238,10 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) + reset = true; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (family != NFPROTO_UNSPEC && family != table->family) + continue; + +@@ -5798,20 +5849,15 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, + struct nft_flowtable *flowtable) + { + struct nlattr *nest, *nest_devs; +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + int i; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, family, ++ NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- + if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || + nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || + nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) || +@@ -5861,12 +5907,14 @@ static int nf_tables_dump_flowtable(struct sk_buff *skb, + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; + struct nft_flowtable *flowtable; ++ struct nftables_pernet *nft_net; + const struct nft_table *table; + + rcu_read_lock(); +- cb->seq = net->nft.base_seq; ++ nft_net = net_generic(net, nf_tables_net_id); ++ cb->seq = nft_net->base_seq; + +- list_for_each_entry_rcu(table, &net->nft.tables, list) { ++ list_for_each_entry_rcu(table, &nft_net->tables, list) { + if (family != NFPROTO_UNSPEC && family != table->family) + continue; + +@@ -6036,21 +6084,17 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) + static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, + u32 portid, u32 seq) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + char buf[TASK_COMM_LEN]; + int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN); + +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, 0, AF_UNSPEC, ++ NFNETLINK_V0, nft_base_seq(net)); ++ if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(net->nft.base_seq & 0xffff); +- +- if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) || ++ if (nla_put_be32(skb, NFTA_GEN_ID, htonl(nft_net->base_seq)) || + nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) || + nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current))) + goto nla_put_failure; +@@ -6083,6 +6127,7 @@ static int nf_tables_flowtable_event(struct notifier_block *this, + { + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct nft_flowtable *flowtable; ++ struct nftables_pernet *nft_net; + struct nft_table *table; + struct net *net; + +@@ -6090,13 +6135,14 @@ static int nf_tables_flowtable_event(struct notifier_block *this, + return 0; + + net = dev_net(dev); +- mutex_lock(&net->nft.commit_mutex); +- list_for_each_entry(table, &net->nft.tables, list) { ++ nft_net = net_generic(net, nf_tables_net_id); ++ mutex_lock(&nft_net->commit_mutex); ++ list_for_each_entry(table, &nft_net->tables, list) { + list_for_each_entry(flowtable, &table->flowtables, list) { + nft_flowtable_event(event, dev, flowtable); + } + } +- mutex_unlock(&net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + + return NOTIFY_DONE; + } +@@ -6277,16 +6323,17 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { + + static int nf_tables_validate(struct net *net) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_table *table; + +- switch (net->nft.validate_state) { ++ switch (nft_net->validate_state) { + case NFT_VALIDATE_SKIP: + break; + case NFT_VALIDATE_NEED: + nft_validate_state_update(net, NFT_VALIDATE_DO); + /* fall through */ + case NFT_VALIDATE_DO: +- list_for_each_entry(table, &net->nft.tables, list) { ++ list_for_each_entry(table, &nft_net->tables, list) { + if (nft_table_validate(net, table) < 0) + return -EAGAIN; + } +@@ -6363,15 +6410,16 @@ static void nft_commit_release(struct nft_trans *trans) + + static void nf_tables_commit_release(struct net *net) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_trans *trans, *next; + +- if (list_empty(&net->nft.commit_list)) ++ if (list_empty(&nft_net->commit_list)) + return; + + synchronize_rcu(); + +- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { +- list_del(&trans->list); ++ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) { ++ nft_trans_list_del(trans); + nft_commit_release(trans); + } + } +@@ -6409,9 +6457,10 @@ static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *cha + + static void nf_tables_commit_chain_prepare_cancel(struct net *net) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_trans *trans, *next; + +- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { ++ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) { + struct nft_chain *chain = trans->ctx.chain; + + if (trans->msg_type == NFT_MSG_NEWRULE || +@@ -6503,17 +6552,30 @@ static void nft_chain_del(struct nft_chain *chain) + + static int nf_tables_commit(struct net *net, struct sk_buff *skb) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_trans *trans, *next; + struct nft_trans_elem *te; + struct nft_chain *chain; + struct nft_table *table; + ++ list_for_each_entry(trans, &nft_net->binding_list, binding_list) { ++ switch (trans->msg_type) { ++ case NFT_MSG_NEWSET: ++ if (nft_set_is_anonymous(nft_trans_set(trans)) && ++ !nft_trans_set_bound(trans)) { ++ pr_warn_once("nftables ruleset with unbound set\n"); ++ return -EINVAL; ++ } ++ break; ++ } ++ } ++ + /* 0. Validate ruleset, otherwise roll back for error reporting. */ + if (nf_tables_validate(net) < 0) + return -EAGAIN; + + /* 1. Allocate space for next generation rules_gen_X[] */ +- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { ++ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) { + int ret; + + if (trans->msg_type == NFT_MSG_NEWRULE || +@@ -6529,7 +6591,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + } + + /* step 2. Make rules_gen_X visible to packet path */ +- list_for_each_entry(table, &net->nft.tables, list) { ++ list_for_each_entry(table, &nft_net->tables, list) { + list_for_each_entry(chain, &table->chains, list) + nf_tables_commit_chain(net, chain); + } +@@ -6538,12 +6600,13 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + * Bump generation counter, invalidate any dump in progress. + * Cannot fail after this point. + */ +- while (++net->nft.base_seq == 0); ++ while (++nft_net->base_seq == 0) ++ ; + + /* step 3. Start new generation, rules_gen_X now in use. */ + net->nft.gencursor = nft_gencursor_next(net); + +- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { ++ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) { + switch (trans->msg_type) { + case NFT_MSG_NEWTABLE: + if (nft_trans_table_update(trans)) { +@@ -6664,7 +6727,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) + + nf_tables_commit_release(net); + nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); +- mutex_unlock(&net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + + return 0; + } +@@ -6700,10 +6763,11 @@ static void nf_tables_abort_release(struct nft_trans *trans) + + static int __nf_tables_abort(struct net *net) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + struct nft_trans *trans, *next; + struct nft_trans_elem *te; + +- list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list, ++ list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list, + list) { + switch (trans->msg_type) { + case NFT_MSG_NEWTABLE: +@@ -6810,8 +6874,8 @@ static int __nf_tables_abort(struct net *net) + synchronize_rcu(); + + list_for_each_entry_safe_reverse(trans, next, +- &net->nft.commit_list, list) { +- list_del(&trans->list); ++ &nft_net->commit_list, list) { ++ nft_trans_list_del(trans); + nf_tables_abort_release(trans); + } + +@@ -6820,22 +6884,24 @@ static int __nf_tables_abort(struct net *net) + + static int nf_tables_abort(struct net *net, struct sk_buff *skb) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + int ret = __nf_tables_abort(net); + +- mutex_unlock(&net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + + return ret; + } + + static bool nf_tables_valid_genid(struct net *net, u32 genid) + { ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); + bool genid_ok; + +- mutex_lock(&net->nft.commit_mutex); ++ mutex_lock(&nft_net->commit_mutex); + +- genid_ok = genid == 0 || net->nft.base_seq == genid; ++ genid_ok = genid == 0 || nft_net->base_seq == genid; + if (!genid_ok) +- mutex_unlock(&net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + + /* else, commit mutex has to be released by commit or abort function */ + return genid_ok; +@@ -7182,6 +7248,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, + + if (!tb[NFTA_VERDICT_CODE]) + return -EINVAL; ++ ++ /* zero padding hole for memcmp */ ++ memset(data, 0, sizeof(*data)); + data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); + + switch (data->verdict.code) { +@@ -7389,10 +7458,9 @@ int __nft_release_basechain(struct nft_ctx *ctx) + } + EXPORT_SYMBOL_GPL(__nft_release_basechain); + +-static void __nft_release_tables(struct net *net) ++static void __nft_release_table(struct net *net, struct nft_table *table) + { + struct nft_flowtable *flowtable, *nf; +- struct nft_table *table, *nt; + struct nft_chain *chain, *nc; + struct nft_object *obj, *ne; + struct nft_rule *rule, *nr; +@@ -7402,71 +7470,85 @@ static void __nft_release_tables(struct net *net) + .family = NFPROTO_NETDEV, + }; + +- list_for_each_entry_safe(table, nt, &net->nft.tables, list) { +- ctx.family = table->family; ++ ctx.family = table->family; + +- list_for_each_entry(chain, &table->chains, list) +- nf_tables_unregister_hook(net, table, chain); +- /* No packets are walking on these chains anymore. */ +- ctx.table = table; +- list_for_each_entry(chain, &table->chains, list) { +- ctx.chain = chain; +- list_for_each_entry_safe(rule, nr, &chain->rules, list) { +- list_del(&rule->list); +- chain->use--; +- nf_tables_rule_release(&ctx, rule); +- } +- } +- list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) { +- list_del(&flowtable->list); +- table->use--; +- nf_tables_flowtable_destroy(flowtable); +- } +- list_for_each_entry_safe(set, ns, &table->sets, list) { +- list_del(&set->list); +- table->use--; +- nft_set_destroy(set); +- } +- list_for_each_entry_safe(obj, ne, &table->objects, list) { +- list_del(&obj->list); +- table->use--; +- nft_obj_destroy(&ctx, obj); +- } +- list_for_each_entry_safe(chain, nc, &table->chains, list) { +- ctx.chain = chain; +- nft_chain_del(chain); +- table->use--; +- nf_tables_chain_destroy(&ctx); ++ list_for_each_entry(chain, &table->chains, list) ++ nf_tables_unregister_hook(net, table, chain); ++ /* No packets are walking on these chains anymore. */ ++ ctx.table = table; ++ list_for_each_entry(chain, &table->chains, list) { ++ ctx.chain = chain; ++ list_for_each_entry_safe(rule, nr, &chain->rules, list) { ++ list_del(&rule->list); ++ chain->use--; ++ nf_tables_rule_release(&ctx, rule); + } +- list_del(&table->list); +- nf_tables_table_destroy(&ctx); + } ++ list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) { ++ list_del(&flowtable->list); ++ table->use--; ++ nf_tables_flowtable_destroy(flowtable); ++ } ++ list_for_each_entry_safe(set, ns, &table->sets, list) { ++ list_del(&set->list); ++ table->use--; ++ nft_set_destroy(set); ++ } ++ list_for_each_entry_safe(obj, ne, &table->objects, list) { ++ list_del(&obj->list); ++ table->use--; ++ nft_obj_destroy(&ctx, obj); ++ } ++ list_for_each_entry_safe(chain, nc, &table->chains, list) { ++ ctx.chain = chain; ++ nft_chain_del(chain); ++ table->use--; ++ nf_tables_chain_destroy(&ctx); ++ } ++ list_del(&table->list); ++ nf_tables_table_destroy(&ctx); ++} ++ ++static void __nft_release_tables(struct net *net) ++{ ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ struct nft_table *table, *nt; ++ ++ list_for_each_entry_safe(table, nt, &nft_net->tables, list) ++ __nft_release_table(net, table); + } + + static int __net_init nf_tables_init_net(struct net *net) + { +- INIT_LIST_HEAD(&net->nft.tables); +- INIT_LIST_HEAD(&net->nft.commit_list); +- mutex_init(&net->nft.commit_mutex); +- net->nft.base_seq = 1; +- net->nft.validate_state = NFT_VALIDATE_SKIP; ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ ++ INIT_LIST_HEAD(&nft_net->tables); ++ INIT_LIST_HEAD(&nft_net->commit_list); ++ INIT_LIST_HEAD(&nft_net->binding_list); ++ mutex_init(&nft_net->commit_mutex); ++ nft_net->base_seq = 1; ++ nft_net->validate_state = NFT_VALIDATE_SKIP; + + return 0; + } + + static void __net_exit nf_tables_exit_net(struct net *net) + { +- mutex_lock(&net->nft.commit_mutex); +- if (!list_empty(&net->nft.commit_list)) ++ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id); ++ ++ mutex_lock(&nft_net->commit_mutex); ++ if (!list_empty(&nft_net->commit_list)) + __nf_tables_abort(net); + __nft_release_tables(net); +- mutex_unlock(&net->nft.commit_mutex); +- WARN_ON_ONCE(!list_empty(&net->nft.tables)); ++ mutex_unlock(&nft_net->commit_mutex); ++ WARN_ON_ONCE(!list_empty(&nft_net->tables)); + } + + static struct pernet_operations nf_tables_net_ops = { + .init = nf_tables_init_net, + .exit = nf_tables_exit_net, ++ .id = &nf_tables_net_id, ++ .size = sizeof(struct nftables_pernet), + }; + + static int __init nf_tables_module_init(void) +diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c +index e1dc527a493b8..7a19c517b1918 100644 +--- a/net/netfilter/nf_tables_trace.c ++++ b/net/netfilter/nf_tables_trace.c +@@ -186,7 +186,6 @@ static bool nft_trace_have_verdict_chain(struct nft_traceinfo *info) + void nft_trace_notify(struct nft_traceinfo *info) + { + const struct nft_pktinfo *pkt = info->pkt; +- struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + struct sk_buff *skb; + unsigned int size; +@@ -222,15 +221,11 @@ void nft_trace_notify(struct nft_traceinfo *info) + return; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_TRACE); +- nlh = nlmsg_put(skb, 0, 0, event, sizeof(struct nfgenmsg), 0); ++ nlh = nfnl_msg_put(skb, 0, 0, event, 0, info->basechain->type->family, ++ NFNETLINK_V0, 0); + if (!nlh) + goto nla_put_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = info->basechain->type->family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_be32(skb, NFTA_TRACE_NFPROTO, htonl(nft_pf(pkt)))) + goto nla_put_failure; + +diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c +index 8fa8bf7c48e64..7c5f428dc5c91 100644 +--- a/net/netfilter/nfnetlink_acct.c ++++ b/net/netfilter/nfnetlink_acct.c +@@ -135,21 +135,16 @@ nfnl_acct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + int event, struct nf_acct *acct) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + u64 pkts, bytes; + u32 old_flags; + + event = nfnl_msg_type(NFNL_SUBSYS_ACCT, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_string(skb, NFACCT_NAME, acct->name)) + goto nla_put_failure; + +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index c8b0f1122c44d..720177721e3c0 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -532,20 +532,15 @@ nfnl_cthelper_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + int event, struct nf_conntrack_helper *helper) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + int status; + + event = nfnl_msg_type(NFNL_SUBSYS_CTHELPER, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_string(skb, NFCTH_NAME, helper->name)) + goto nla_put_failure; + +diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c +index 70a7382b9787c..ae01e9ad55464 100644 +--- a/net/netfilter/nfnetlink_cttimeout.c ++++ b/net/netfilter/nfnetlink_cttimeout.c +@@ -164,20 +164,15 @@ ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + int event, struct ctnl_timeout *timeout) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + const struct nf_conntrack_l4proto *l4proto = timeout->timeout.l4proto; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) || + nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, + htons(timeout->timeout.l3num)) || +@@ -396,19 +391,14 @@ cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid, + const unsigned int *timeouts) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + + event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = AF_UNSPEC; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l4proto->l3proto)) || + nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto)) + goto nla_put_failure; +diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c +index 17ca9a681d47b..da05c4d82b944 100644 +--- a/net/netfilter/nfnetlink_log.c ++++ b/net/netfilter/nfnetlink_log.c +@@ -404,20 +404,15 @@ __build_packet_message(struct nfnl_log_net *log, + { + struct nfulnl_msg_packet_hdr pmsg; + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + sk_buff_data_t old_tail = inst->skb->tail; + struct sock *sk; + const unsigned char *hwhdrp; + +- nlh = nlmsg_put(inst->skb, 0, 0, +- nfnl_msg_type(NFNL_SUBSYS_ULOG, NFULNL_MSG_PACKET), +- sizeof(struct nfgenmsg), 0); ++ nlh = nfnl_msg_put(inst->skb, 0, 0, ++ nfnl_msg_type(NFNL_SUBSYS_ULOG, NFULNL_MSG_PACKET), ++ 0, pf, NFNETLINK_V0, htons(inst->group_num)); + if (!nlh) + return -1; +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = pf; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(inst->group_num); + + memset(&pmsg, 0, sizeof(pmsg)); + pmsg.hw_protocol = skb->protocol; +@@ -637,7 +632,7 @@ nfulnl_log_packet(struct net *net, + struct nfnl_log_net *log = nfnl_log_pernet(net); + const struct nfnl_ct_hook *nfnl_ct = NULL; + struct nf_conn *ct = NULL; +- enum ip_conntrack_info uninitialized_var(ctinfo); ++ enum ip_conntrack_info ctinfo; + + if (li_user && li_user->type == NF_LOG_TYPE_ULOG) + li = li_user; +diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c +index cd496b074a71b..1aacc31a6bf92 100644 +--- a/net/netfilter/nfnetlink_queue.c ++++ b/net/netfilter/nfnetlink_queue.c +@@ -387,12 +387,11 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, + struct nlattr *nla; + struct nfqnl_msg_packet_hdr *pmsg; + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + struct sk_buff *entskb = entry->skb; + struct net_device *indev; + struct net_device *outdev; + struct nf_conn *ct = NULL; +- enum ip_conntrack_info uninitialized_var(ctinfo); ++ enum ip_conntrack_info ctinfo; + struct nfnl_ct_hook *nfnl_ct; + bool csum_verify; + char *secdata = NULL; +@@ -473,18 +472,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, + goto nlmsg_failure; + } + +- nlh = nlmsg_put(skb, 0, 0, +- nfnl_msg_type(NFNL_SUBSYS_QUEUE, NFQNL_MSG_PACKET), +- sizeof(struct nfgenmsg), 0); ++ nlh = nfnl_msg_put(skb, 0, 0, ++ nfnl_msg_type(NFNL_SUBSYS_QUEUE, NFQNL_MSG_PACKET), ++ 0, entry->state.pf, NFNETLINK_V0, ++ htons(queue->queue_num)); + if (!nlh) { + skb_tx_error(entskb); + kfree_skb(skb); + goto nlmsg_failure; + } +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = entry->state.pf; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = htons(queue->queue_num); + + nla = __nla_reserve(skb, NFQA_PACKET_HDR, sizeof(*pmsg)); + pmsg = nla_data(nla); +@@ -1191,7 +1187,7 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl, + struct nfqnl_instance *queue; + unsigned int verdict; + struct nf_queue_entry *entry; +- enum ip_conntrack_info uninitialized_var(ctinfo); ++ enum ip_conntrack_info ctinfo; + struct nfnl_ct_hook *nfnl_ct; + struct nf_conn *ct = NULL; + struct nfnl_queue_net *q = nfnl_queue_pernet(net); +diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c +index 5e1fbdd7b2846..dba16126c7eec 100644 +--- a/net/netfilter/nft_byteorder.c ++++ b/net/netfilter/nft_byteorder.c +@@ -33,11 +33,11 @@ static void nft_byteorder_eval(const struct nft_expr *expr, + const struct nft_byteorder *priv = nft_expr_priv(expr); + u32 *src = ®s->data[priv->sreg]; + u32 *dst = ®s->data[priv->dreg]; +- union { u32 u32; u16 u16; } *s, *d; ++ u16 *s16, *d16; + unsigned int i; + +- s = (void *)src; +- d = (void *)dst; ++ s16 = (void *)src; ++ d16 = (void *)dst; + + switch (priv->size) { + case 8: { +@@ -63,11 +63,11 @@ static void nft_byteorder_eval(const struct nft_expr *expr, + switch (priv->op) { + case NFT_BYTEORDER_NTOH: + for (i = 0; i < priv->len / 4; i++) +- d[i].u32 = ntohl((__force __be32)s[i].u32); ++ dst[i] = ntohl((__force __be32)src[i]); + break; + case NFT_BYTEORDER_HTON: + for (i = 0; i < priv->len / 4; i++) +- d[i].u32 = (__force __u32)htonl(s[i].u32); ++ dst[i] = (__force __u32)htonl(src[i]); + break; + } + break; +@@ -75,11 +75,11 @@ static void nft_byteorder_eval(const struct nft_expr *expr, + switch (priv->op) { + case NFT_BYTEORDER_NTOH: + for (i = 0; i < priv->len / 2; i++) +- d[i].u16 = ntohs((__force __be16)s[i].u16); ++ d16[i] = ntohs((__force __be16)s16[i]); + break; + case NFT_BYTEORDER_HTON: + for (i = 0; i < priv->len / 2; i++) +- d[i].u16 = (__force __u16)htons(s[i].u16); ++ d16[i] = (__force __u16)htons(s16[i]); + break; + } + break; +diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c +index 3fd540b2c6baf..a308d45ee95e1 100644 +--- a/net/netfilter/nft_chain_filter.c ++++ b/net/netfilter/nft_chain_filter.c +@@ -2,6 +2,7 @@ + #include <linux/kernel.h> + #include <linux/netdevice.h> + #include <net/net_namespace.h> ++#include <net/netns/generic.h> + #include <net/netfilter/nf_tables.h> + #include <linux/netfilter_ipv4.h> + #include <linux/netfilter_ipv6.h> +@@ -10,6 +11,8 @@ + #include <net/netfilter/nf_tables_ipv4.h> + #include <net/netfilter/nf_tables_ipv6.h> + ++extern unsigned int nf_tables_net_id; ++ + #ifdef CONFIG_NF_TABLES_IPV4 + static unsigned int nft_do_chain_ipv4(void *priv, + struct sk_buff *skb, +@@ -315,6 +318,7 @@ static int nf_tables_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) + { + struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ struct nftables_pernet *nft_net; + struct nft_table *table; + struct nft_chain *chain, *nr; + struct nft_ctx ctx = { +@@ -325,8 +329,9 @@ static int nf_tables_netdev_event(struct notifier_block *this, + event != NETDEV_CHANGENAME) + return NOTIFY_DONE; + +- mutex_lock(&ctx.net->nft.commit_mutex); +- list_for_each_entry(table, &ctx.net->nft.tables, list) { ++ nft_net = net_generic(ctx.net, nf_tables_net_id); ++ mutex_lock(&nft_net->commit_mutex); ++ list_for_each_entry(table, &nft_net->tables, list) { + if (table->family != NFPROTO_NETDEV) + continue; + +@@ -340,7 +345,7 @@ static int nf_tables_netdev_event(struct notifier_block *this, + nft_netdev_event(event, dev, &ctx); + } + } +- mutex_unlock(&ctx.net->nft.commit_mutex); ++ mutex_unlock(&nft_net->commit_mutex); + + return NOTIFY_DONE; + } +diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c +index 469f9da5073bf..2846d64659f2f 100644 +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -575,19 +575,14 @@ nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type, + int rev, int target) + { + struct nlmsghdr *nlh; +- struct nfgenmsg *nfmsg; + unsigned int flags = portid ? NLM_F_MULTI : 0; + + event = nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT, event); +- nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags); +- if (nlh == NULL) ++ nlh = nfnl_msg_put(skb, portid, seq, event, flags, family, ++ NFNETLINK_V0, 0); ++ if (!nlh) + goto nlmsg_failure; + +- nfmsg = nlmsg_data(nlh); +- nfmsg->nfgen_family = family; +- nfmsg->version = NFNETLINK_V0; +- nfmsg->res_id = 0; +- + if (nla_put_string(skb, NFTA_COMPAT_NAME, name) || + nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) || + nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target))) +diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c +index c5d42e704f043..651c9784904cb 100644 +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -15,6 +15,9 @@ + #include <linux/netfilter/nf_tables.h> + #include <net/netfilter/nf_tables.h> + #include <net/netfilter/nf_tables_core.h> ++#include <net/netns/generic.h> ++ ++extern unsigned int nf_tables_net_id; + + struct nft_dynset { + struct nft_set *set; +@@ -112,13 +115,14 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) + { ++ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id); + struct nft_dynset *priv = nft_expr_priv(expr); + u8 genmask = nft_genmask_next(ctx->net); + struct nft_set *set; + u64 timeout; + int err; + +- lockdep_assert_held(&ctx->net->nft.commit_mutex); ++ lockdep_assert_held(&nft_net->commit_mutex); + + if (tb[NFTA_DYNSET_SET_NAME] == NULL || + tb[NFTA_DYNSET_OP] == NULL || +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 57fd9b7cfc75f..35ecaa93f213a 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1603,6 +1603,7 @@ out: + int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) + { + struct netlink_set_err_data info; ++ unsigned long flags; + struct sock *sk; + int ret = 0; + +@@ -1612,12 +1613,12 @@ int netlink_set_err(struct sock *ssk, u32 portid, u32 group, int code) + /* sk->sk_err wants a positive error value */ + info.code = -code; + +- read_lock(&nl_table_lock); ++ read_lock_irqsave(&nl_table_lock, flags); + + sk_for_each_bound(sk, &nl_table[ssk->sk_protocol].mc_list) + ret += do_one_set_err(sk, &info); + +- read_unlock(&nl_table_lock); ++ read_unlock_irqrestore(&nl_table_lock, flags); + return ret; + } + EXPORT_SYMBOL(netlink_set_err); +diff --git a/net/netlink/diag.c b/net/netlink/diag.c +index 7dda33b9b7849..85ee4891c2c7f 100644 +--- a/net/netlink/diag.c ++++ b/net/netlink/diag.c +@@ -93,6 +93,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + struct net *net = sock_net(skb->sk); + struct netlink_diag_req *req; + struct netlink_sock *nlsk; ++ unsigned long flags; + struct sock *sk; + int num = 2; + int ret = 0; +@@ -151,7 +152,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, + num++; + + mc_list: +- read_lock(&nl_table_lock); ++ read_lock_irqsave(&nl_table_lock, flags); + sk_for_each_bound(sk, &tbl->mc_list) { + if (sk_hashed(sk)) + continue; +@@ -166,13 +167,13 @@ mc_list: + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + NLM_F_MULTI, +- sock_i_ino(sk)) < 0) { ++ __sock_i_ino(sk)) < 0) { + ret = 1; + break; + } + num++; + } +- read_unlock(&nl_table_lock); ++ read_unlock_irqrestore(&nl_table_lock, flags); + + done: + cb->args[0] = num; +diff --git a/net/nfc/core.c b/net/nfc/core.c +index a84f824da051d..dd12ee46ac730 100644 +--- a/net/nfc/core.c ++++ b/net/nfc/core.c +@@ -646,7 +646,7 @@ error: + return rc; + } + +-int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) ++int nfc_set_remote_general_bytes(struct nfc_dev *dev, const u8 *gb, u8 gb_len) + { + pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); + +@@ -675,7 +675,7 @@ int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb) + EXPORT_SYMBOL(nfc_tm_data_received); + + int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, +- u8 *gb, size_t gb_len) ++ const u8 *gb, size_t gb_len) + { + int rc; + +diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c +index fe988936ad923..e6863c71f566d 100644 +--- a/net/nfc/hci/llc_shdlc.c ++++ b/net/nfc/hci/llc_shdlc.c +@@ -134,7 +134,7 @@ static bool llc_shdlc_x_lteq_y_lt_z(int x, int y, int z) + return ((y >= x) || (y < z)) ? true : false; + } + +-static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc, ++static struct sk_buff *llc_shdlc_alloc_skb(const struct llc_shdlc *shdlc, + int payload_len) + { + struct sk_buff *skb; +@@ -148,7 +148,7 @@ static struct sk_buff *llc_shdlc_alloc_skb(struct llc_shdlc *shdlc, + } + + /* immediately sends an S frame. */ +-static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc, ++static int llc_shdlc_send_s_frame(const struct llc_shdlc *shdlc, + enum sframe_type sframe_type, int nr) + { + int r; +@@ -170,7 +170,7 @@ static int llc_shdlc_send_s_frame(struct llc_shdlc *shdlc, + } + + /* immediately sends an U frame. skb may contain optional payload */ +-static int llc_shdlc_send_u_frame(struct llc_shdlc *shdlc, ++static int llc_shdlc_send_u_frame(const struct llc_shdlc *shdlc, + struct sk_buff *skb, + enum uframe_modifier uframe_modifier) + { +@@ -372,7 +372,7 @@ static void llc_shdlc_connect_complete(struct llc_shdlc *shdlc, int r) + wake_up(shdlc->connect_wq); + } + +-static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc) ++static int llc_shdlc_connect_initiate(const struct llc_shdlc *shdlc) + { + struct sk_buff *skb; + +@@ -388,7 +388,7 @@ static int llc_shdlc_connect_initiate(struct llc_shdlc *shdlc) + return llc_shdlc_send_u_frame(shdlc, skb, U_FRAME_RSET); + } + +-static int llc_shdlc_connect_send_ua(struct llc_shdlc *shdlc) ++static int llc_shdlc_connect_send_ua(const struct llc_shdlc *shdlc) + { + struct sk_buff *skb; + +diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h +index 1f68724d44d3b..a070a57fc1516 100644 +--- a/net/nfc/llcp.h ++++ b/net/nfc/llcp.h +@@ -233,15 +233,15 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock); + + /* TLV API */ + int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, +- u8 *tlv_array, u16 tlv_array_len); ++ const u8 *tlv_array, u16 tlv_array_len); + int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, +- u8 *tlv_array, u16 tlv_array_len); ++ const u8 *tlv_array, u16 tlv_array_len); + + /* Commands API */ + void nfc_llcp_recv(void *data, struct sk_buff *skb, int err); +-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length); ++u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length); + struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap); +-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri, ++struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri, + size_t uri_len); + void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp); + void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head); +diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c +index d1fc019e932e0..737c7aa384f44 100644 +--- a/net/nfc/llcp_commands.c ++++ b/net/nfc/llcp_commands.c +@@ -27,7 +27,7 @@ + #include "nfc.h" + #include "llcp.h" + +-static u8 llcp_tlv_length[LLCP_TLV_MAX] = { ++static const u8 llcp_tlv_length[LLCP_TLV_MAX] = { + 0, + 1, /* VERSION */ + 2, /* MIUX */ +@@ -41,7 +41,7 @@ static u8 llcp_tlv_length[LLCP_TLV_MAX] = { + + }; + +-static u8 llcp_tlv8(u8 *tlv, u8 type) ++static u8 llcp_tlv8(const u8 *tlv, u8 type) + { + if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]]) + return 0; +@@ -49,7 +49,7 @@ static u8 llcp_tlv8(u8 *tlv, u8 type) + return tlv[2]; + } + +-static u16 llcp_tlv16(u8 *tlv, u8 type) ++static u16 llcp_tlv16(const u8 *tlv, u8 type) + { + if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]]) + return 0; +@@ -58,37 +58,37 @@ static u16 llcp_tlv16(u8 *tlv, u8 type) + } + + +-static u8 llcp_tlv_version(u8 *tlv) ++static u8 llcp_tlv_version(const u8 *tlv) + { + return llcp_tlv8(tlv, LLCP_TLV_VERSION); + } + +-static u16 llcp_tlv_miux(u8 *tlv) ++static u16 llcp_tlv_miux(const u8 *tlv) + { + return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7ff; + } + +-static u16 llcp_tlv_wks(u8 *tlv) ++static u16 llcp_tlv_wks(const u8 *tlv) + { + return llcp_tlv16(tlv, LLCP_TLV_WKS); + } + +-static u16 llcp_tlv_lto(u8 *tlv) ++static u16 llcp_tlv_lto(const u8 *tlv) + { + return llcp_tlv8(tlv, LLCP_TLV_LTO); + } + +-static u8 llcp_tlv_opt(u8 *tlv) ++static u8 llcp_tlv_opt(const u8 *tlv) + { + return llcp_tlv8(tlv, LLCP_TLV_OPT); + } + +-static u8 llcp_tlv_rw(u8 *tlv) ++static u8 llcp_tlv_rw(const u8 *tlv) + { + return llcp_tlv8(tlv, LLCP_TLV_RW) & 0xf; + } + +-u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length) ++u8 *nfc_llcp_build_tlv(u8 type, const u8 *value, u8 value_length, u8 *tlv_length) + { + u8 *tlv, length; + +@@ -142,7 +142,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap) + return sdres; + } + +-struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri, ++struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri, + size_t uri_len) + { + struct nfc_llcp_sdp_tlv *sdreq; +@@ -202,9 +202,10 @@ void nfc_llcp_free_sdp_tlv_list(struct hlist_head *head) + } + + int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, +- u8 *tlv_array, u16 tlv_array_len) ++ const u8 *tlv_array, u16 tlv_array_len) + { +- u8 *tlv = tlv_array, type, length, offset = 0; ++ const u8 *tlv = tlv_array; ++ u8 type, length, offset = 0; + + pr_debug("TLV array length %d\n", tlv_array_len); + +@@ -251,9 +252,10 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local, + } + + int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock, +- u8 *tlv_array, u16 tlv_array_len) ++ const u8 *tlv_array, u16 tlv_array_len) + { +- u8 *tlv = tlv_array, type, length, offset = 0; ++ const u8 *tlv = tlv_array; ++ u8 type, length, offset = 0; + + pr_debug("TLV array length %d\n", tlv_array_len); + +@@ -307,7 +309,7 @@ static struct sk_buff *llcp_add_header(struct sk_buff *pdu, + return pdu; + } + +-static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv, ++static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, const u8 *tlv, + u8 tlv_length) + { + /* XXX Add an skb length check */ +@@ -401,9 +403,11 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) + { + struct nfc_llcp_local *local; + struct sk_buff *skb; +- u8 *service_name_tlv = NULL, service_name_tlv_length; +- u8 *miux_tlv = NULL, miux_tlv_length; +- u8 *rw_tlv = NULL, rw_tlv_length, rw; ++ const u8 *service_name_tlv = NULL; ++ const u8 *miux_tlv = NULL; ++ const u8 *rw_tlv = NULL; ++ u8 service_name_tlv_length = 0; ++ u8 miux_tlv_length, rw_tlv_length, rw; + int err; + u16 size = 0; + __be16 miux; +@@ -477,8 +481,9 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) + { + struct nfc_llcp_local *local; + struct sk_buff *skb; +- u8 *miux_tlv = NULL, miux_tlv_length; +- u8 *rw_tlv = NULL, rw_tlv_length, rw; ++ const u8 *miux_tlv = NULL; ++ const u8 *rw_tlv = NULL; ++ u8 miux_tlv_length, rw_tlv_length, rw; + int err; + u16 size = 0; + __be16 miux; +diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c +index 3290f2275b857..bdc1a9d0965af 100644 +--- a/net/nfc/llcp_core.c ++++ b/net/nfc/llcp_core.c +@@ -314,7 +314,7 @@ static char *wks[] = { + "urn:nfc:sn:snep", + }; + +-static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) ++static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len) + { + int sap, num_wks; + +@@ -338,7 +338,7 @@ static int nfc_llcp_wks_sap(char *service_name, size_t service_name_len) + + static + struct nfc_llcp_sock *nfc_llcp_sock_from_sn(struct nfc_llcp_local *local, +- u8 *sn, size_t sn_len) ++ const u8 *sn, size_t sn_len) + { + struct sock *sk; + struct nfc_llcp_sock *llcp_sock, *tmp_sock; +@@ -535,7 +535,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) + { + u8 *gb_cur, version, version_length; + u8 lto_length, wks_length, miux_length; +- u8 *version_tlv = NULL, *lto_tlv = NULL, ++ const u8 *version_tlv = NULL, *lto_tlv = NULL, + *wks_tlv = NULL, *miux_tlv = NULL; + __be16 wks = cpu_to_be16(local->local_wks); + u8 gb_len = 0; +@@ -625,7 +625,7 @@ u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len) + return local->gb; + } + +-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) ++int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len) + { + struct nfc_llcp_local *local; + +@@ -652,27 +652,27 @@ int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len) + local->remote_gb_len - 3); + } + +-static u8 nfc_llcp_dsap(struct sk_buff *pdu) ++static u8 nfc_llcp_dsap(const struct sk_buff *pdu) + { + return (pdu->data[0] & 0xfc) >> 2; + } + +-static u8 nfc_llcp_ptype(struct sk_buff *pdu) ++static u8 nfc_llcp_ptype(const struct sk_buff *pdu) + { + return ((pdu->data[0] & 0x03) << 2) | ((pdu->data[1] & 0xc0) >> 6); + } + +-static u8 nfc_llcp_ssap(struct sk_buff *pdu) ++static u8 nfc_llcp_ssap(const struct sk_buff *pdu) + { + return pdu->data[1] & 0x3f; + } + +-static u8 nfc_llcp_ns(struct sk_buff *pdu) ++static u8 nfc_llcp_ns(const struct sk_buff *pdu) + { + return pdu->data[2] >> 4; + } + +-static u8 nfc_llcp_nr(struct sk_buff *pdu) ++static u8 nfc_llcp_nr(const struct sk_buff *pdu) + { + return pdu->data[2] & 0xf; + } +@@ -814,7 +814,7 @@ out: + } + + static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local, +- u8 *sn, size_t sn_len) ++ const u8 *sn, size_t sn_len) + { + struct nfc_llcp_sock *llcp_sock; + +@@ -828,9 +828,10 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local, + return llcp_sock; + } + +-static u8 *nfc_llcp_connect_sn(struct sk_buff *skb, size_t *sn_len) ++static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len) + { +- u8 *tlv = &skb->data[2], type, length; ++ u8 type, length; ++ const u8 *tlv = &skb->data[2]; + size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0; + + while (offset < tlv_array_len) { +@@ -888,7 +889,7 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, + } + + static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, +- struct sk_buff *skb) ++ const struct sk_buff *skb) + { + struct sock *new_sk, *parent; + struct nfc_llcp_sock *sock, *new_sock; +@@ -906,7 +907,7 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local, + goto fail; + } + } else { +- u8 *sn; ++ const u8 *sn; + size_t sn_len; + + sn = nfc_llcp_connect_sn(skb, &sn_len); +@@ -1125,7 +1126,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, + } + + static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, +- struct sk_buff *skb) ++ const struct sk_buff *skb) + { + struct nfc_llcp_sock *llcp_sock; + struct sock *sk; +@@ -1168,7 +1169,8 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local, + nfc_llcp_sock_put(llcp_sock); + } + +-static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) ++static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, ++ const struct sk_buff *skb) + { + struct nfc_llcp_sock *llcp_sock; + struct sock *sk; +@@ -1201,7 +1203,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local, struct sk_buff *skb) + nfc_llcp_sock_put(llcp_sock); + } + +-static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) ++static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, ++ const struct sk_buff *skb) + { + struct nfc_llcp_sock *llcp_sock; + struct sock *sk; +@@ -1239,12 +1242,13 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, struct sk_buff *skb) + } + + static void nfc_llcp_recv_snl(struct nfc_llcp_local *local, +- struct sk_buff *skb) ++ const struct sk_buff *skb) + { + struct nfc_llcp_sock *llcp_sock; +- u8 dsap, ssap, *tlv, type, length, tid, sap; ++ u8 dsap, ssap, type, length, tid, sap; ++ const u8 *tlv; + u16 tlv_len, offset; +- char *service_name; ++ const char *service_name; + size_t service_name_len; + struct nfc_llcp_sdp_tlv *sdp; + HLIST_HEAD(llc_sdres_list); +diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h +index 6c6f76b370b1e..c792165f523f1 100644 +--- a/net/nfc/nfc.h ++++ b/net/nfc/nfc.h +@@ -60,7 +60,7 @@ void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, + u8 comm_mode, u8 rf_mode); + int nfc_llcp_register_device(struct nfc_dev *dev); + void nfc_llcp_unregister_device(struct nfc_dev *dev); +-int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); ++int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len); + u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); + int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); + struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); +diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c +index aeb8f84cbd9e2..255d4ecf62522 100644 +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -29,6 +29,7 @@ static struct tc_action_ops act_pedit_ops; + + static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { + [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) }, ++ [TCA_PEDIT_PARMS_EX] = { .len = sizeof(struct tc_pedit) }, + [TCA_PEDIT_KEYS_EX] = { .type = NLA_NESTED }, + }; + +diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c +index 55bf75cb1f16b..164049d20f4d3 100644 +--- a/net/sched/cls_flow.c ++++ b/net/sched/cls_flow.c +@@ -229,7 +229,7 @@ static u32 flow_get_skgid(const struct sk_buff *skb) + + static u32 flow_get_vlan_tag(const struct sk_buff *skb) + { +- u16 uninitialized_var(tag); ++ u16 tag; + + if (vlan_get_tag(skb, &tag) < 0) + return 0; +diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c +index cb2c62605fc76..5284a473c697f 100644 +--- a/net/sched/cls_fw.c ++++ b/net/sched/cls_fw.c +@@ -221,11 +221,6 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp, + if (err < 0) + return err; + +- if (tb[TCA_FW_CLASSID]) { +- f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); +- tcf_bind_filter(tp, &f->res, base); +- } +- + #ifdef CONFIG_NET_CLS_IND + if (tb[TCA_FW_INDEV]) { + int ret; +@@ -244,6 +239,11 @@ static int fw_set_parms(struct net *net, struct tcf_proto *tp, + } else if (head->mask != 0xFFFFFFFF) + return err; + ++ if (tb[TCA_FW_CLASSID]) { ++ f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); ++ tcf_bind_filter(tp, &f->res, base); ++ } ++ + return 0; + } + +diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c +index 4c7fa1cfd8e38..a924292623ecf 100644 +--- a/net/sched/cls_route.c ++++ b/net/sched/cls_route.c +@@ -513,7 +513,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, + if (fold) { + f->id = fold->id; + f->iif = fold->iif; +- f->res = fold->res; + f->handle = fold->handle; + + f->tp = fold->tp; +diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c +index d30256ac35372..1e71ff093c91d 100644 +--- a/net/sched/cls_u32.c ++++ b/net/sched/cls_u32.c +@@ -778,11 +778,22 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, + struct netlink_ext_ack *extack) + { + int err; ++#ifdef CONFIG_NET_CLS_IND ++ int ifindex = -1; ++#endif + + err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, extack); + if (err < 0) + return err; + ++#ifdef CONFIG_NET_CLS_IND ++ if (tb[TCA_U32_INDEV]) { ++ ifindex = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); ++ if (ifindex < 0) ++ return -EINVAL; ++ } ++#endif ++ + if (tb[TCA_U32_LINK]) { + u32 handle = nla_get_u32(tb[TCA_U32_LINK]); + struct tc_u_hnode *ht_down = NULL, *ht_old; +@@ -814,13 +825,8 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, + } + + #ifdef CONFIG_NET_CLS_IND +- if (tb[TCA_U32_INDEV]) { +- int ret; +- ret = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); +- if (ret < 0) +- return -EINVAL; +- n->ifindex = ret; +- } ++ if (ifindex >= 0) ++ n->ifindex = ifindex; + #endif + return 0; + } +@@ -873,7 +879,6 @@ static struct tc_u_knode *u32_init_knode(struct tcf_proto *tp, + new->ifindex = n->ifindex; + #endif + new->fshift = n->fshift; +- new->res = n->res; + new->flags = n->flags; + RCU_INIT_POINTER(new->ht_down, ht); + +@@ -1061,18 +1066,62 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, + return -EINVAL; + } + ++ /* At this point, we need to derive the new handle that will be used to ++ * uniquely map the identity of this table match entry. The ++ * identity of the entry that we need to construct is 32 bits made of: ++ * htid(12b):bucketid(8b):node/entryid(12b) ++ * ++ * At this point _we have the table(ht)_ in which we will insert this ++ * entry. We carry the table's id in variable "htid". ++ * Note that earlier code picked the ht selection either by a) the user ++ * providing the htid specified via TCA_U32_HASH attribute or b) when ++ * no such attribute is passed then the root ht, is default to at ID ++ * 0x[800][00][000]. Rule: the root table has a single bucket with ID 0. ++ * If OTOH the user passed us the htid, they may also pass a bucketid of ++ * choice. 0 is fine. For example a user htid is 0x[600][01][000] it is ++ * indicating hash bucketid of 1. Rule: the entry/node ID _cannot_ be ++ * passed via the htid, so even if it was non-zero it will be ignored. ++ * ++ * We may also have a handle, if the user passed one. The handle also ++ * carries the same addressing of htid(12b):bucketid(8b):node/entryid(12b). ++ * Rule: the bucketid on the handle is ignored even if one was passed; ++ * rather the value on "htid" is always assumed to be the bucketid. ++ */ + if (handle) { ++ /* Rule: The htid from handle and tableid from htid must match */ + if (TC_U32_HTID(handle) && TC_U32_HTID(handle ^ htid)) { + NL_SET_ERR_MSG_MOD(extack, "Handle specified hash table address mismatch"); + return -EINVAL; + } +- handle = htid | TC_U32_NODE(handle); +- err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, handle, +- GFP_KERNEL); +- if (err) +- return err; +- } else ++ /* Ok, so far we have a valid htid(12b):bucketid(8b) but we ++ * need to finalize the table entry identification with the last ++ * part - the node/entryid(12b)). Rule: Nodeid _cannot be 0_ for ++ * entries. Rule: nodeid of 0 is reserved only for tables(see ++ * earlier code which processes TC_U32_DIVISOR attribute). ++ * Rule: The nodeid can only be derived from the handle (and not ++ * htid). ++ * Rule: if the handle specified zero for the node id example ++ * 0x60000000, then pick a new nodeid from the pool of IDs ++ * this hash table has been allocating from. ++ * If OTOH it is specified (i.e for example the user passed a ++ * handle such as 0x60000123), then we use it generate our final ++ * handle which is used to uniquely identify the match entry. ++ */ ++ if (!TC_U32_NODE(handle)) { ++ handle = gen_new_kid(ht, htid); ++ } else { ++ handle = htid | TC_U32_NODE(handle); ++ err = idr_alloc_u32(&ht->handle_idr, NULL, &handle, ++ handle, GFP_KERNEL); ++ if (err) ++ return err; ++ } ++ } else { ++ /* The user did not give us a handle; lets just generate one ++ * from the table's pool of nodeids. ++ */ + handle = gen_new_kid(ht, htid); ++ } + + if (tb[TCA_U32_SEL] == NULL) { + NL_SET_ERR_MSG_MOD(extack, "Selector not specified"); +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 01a177cfa5333..d91665ea7b14d 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1649,7 +1649,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + { + struct cake_sched_data *q = qdisc_priv(sch); + int len = qdisc_pkt_len(skb); +- int uninitialized_var(ret); ++ int ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; +diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c +index 2974f7262f882..7f0a5d22deaf6 100644 +--- a/net/sched/sch_cbq.c ++++ b/net/sched/sch_cbq.c +@@ -365,7 +365,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { + struct cbq_sched_data *q = qdisc_priv(sch); +- int uninitialized_var(ret); ++ int ret; + struct cbq_class *cl = cbq_classify(skb, sch, &ret); + + #ifdef CONFIG_NET_CLS_ACT +diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c +index e4f69c779b8cf..7a4777ee0536e 100644 +--- a/net/sched/sch_fq_codel.c ++++ b/net/sched/sch_fq_codel.c +@@ -192,7 +192,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct fq_codel_sched_data *q = qdisc_priv(sch); + unsigned int idx, prev_backlog, prev_qlen; + struct fq_codel_flow *flow; +- int uninitialized_var(ret); ++ int ret; + unsigned int pkt_len; + bool memory_limited; + +diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c +index 64d7f876d7de2..c0ab1e38e80c6 100644 +--- a/net/sched/sch_mqprio.c ++++ b/net/sched/sch_mqprio.c +@@ -132,6 +132,97 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, + return 0; + } + ++static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt, ++ struct nlattr *opt, ++ struct netlink_ext_ack *extack) ++{ ++ struct mqprio_sched *priv = qdisc_priv(sch); ++ struct nlattr *tb[TCA_MQPRIO_MAX + 1]; ++ struct nlattr *attr; ++ int i, rem, err; ++ ++ err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy, ++ sizeof(*qopt)); ++ if (err < 0) ++ return err; ++ ++ if (!qopt->hw) { ++ NL_SET_ERR_MSG(extack, ++ "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode"); ++ return -EINVAL; ++ } ++ ++ if (tb[TCA_MQPRIO_MODE]) { ++ priv->flags |= TC_MQPRIO_F_MODE; ++ priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]); ++ } ++ ++ if (tb[TCA_MQPRIO_SHAPER]) { ++ priv->flags |= TC_MQPRIO_F_SHAPER; ++ priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]); ++ } ++ ++ if (tb[TCA_MQPRIO_MIN_RATE64]) { ++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { ++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64], ++ "min_rate accepted only when shaper is in bw_rlimit mode"); ++ return -EINVAL; ++ } ++ i = 0; ++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], ++ rem) { ++ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64"); ++ return -EINVAL; ++ } ++ ++ if (nla_len(attr) != sizeof(u64)) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length"); ++ return -EINVAL; ++ } ++ ++ if (i >= qopt->num_tc) ++ break; ++ priv->min_rate[i] = *(u64 *)nla_data(attr); ++ i++; ++ } ++ priv->flags |= TC_MQPRIO_F_MIN_RATE; ++ } ++ ++ if (tb[TCA_MQPRIO_MAX_RATE64]) { ++ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) { ++ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64], ++ "max_rate accepted only when shaper is in bw_rlimit mode"); ++ return -EINVAL; ++ } ++ i = 0; ++ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], ++ rem) { ++ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64"); ++ return -EINVAL; ++ } ++ ++ if (nla_len(attr) != sizeof(u64)) { ++ NL_SET_ERR_MSG_ATTR(extack, attr, ++ "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length"); ++ return -EINVAL; ++ } ++ ++ if (i >= qopt->num_tc) ++ break; ++ priv->max_rate[i] = *(u64 *)nla_data(attr); ++ i++; ++ } ++ priv->flags |= TC_MQPRIO_F_MAX_RATE; ++ } ++ ++ return 0; ++} ++ + static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) + { +@@ -141,9 +232,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + struct Qdisc *qdisc; + int i, err = -EOPNOTSUPP; + struct tc_mqprio_qopt *qopt = NULL; +- struct nlattr *tb[TCA_MQPRIO_MAX + 1]; +- struct nlattr *attr; +- int rem; + int len; + + BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE); +@@ -168,55 +256,9 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, + + len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt)); + if (len > 0) { +- err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy, +- sizeof(*qopt)); +- if (err < 0) ++ err = mqprio_parse_nlattr(sch, qopt, opt, extack); ++ if (err) + return err; +- +- if (!qopt->hw) +- return -EINVAL; +- +- if (tb[TCA_MQPRIO_MODE]) { +- priv->flags |= TC_MQPRIO_F_MODE; +- priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]); +- } +- +- if (tb[TCA_MQPRIO_SHAPER]) { +- priv->flags |= TC_MQPRIO_F_SHAPER; +- priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]); +- } +- +- if (tb[TCA_MQPRIO_MIN_RATE64]) { +- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) +- return -EINVAL; +- i = 0; +- nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], +- rem) { +- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) +- return -EINVAL; +- if (i >= qopt->num_tc) +- break; +- priv->min_rate[i] = *(u64 *)nla_data(attr); +- i++; +- } +- priv->flags |= TC_MQPRIO_F_MIN_RATE; +- } +- +- if (tb[TCA_MQPRIO_MAX_RATE64]) { +- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) +- return -EINVAL; +- i = 0; +- nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], +- rem) { +- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) +- return -EINVAL; +- if (i >= qopt->num_tc) +- break; +- priv->max_rate[i] = *(u64 *)nla_data(attr); +- i++; +- } +- priv->flags |= TC_MQPRIO_F_MAX_RATE; +- } + } + + /* pre-allocate qdisc, attachment can't fail */ +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index c2a68f6e427ed..e9420ca261d61 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -387,8 +387,13 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight, + u32 lmax) + { + struct qfq_sched *q = qdisc_priv(sch); +- struct qfq_aggregate *new_agg = qfq_find_agg(q, lmax, weight); ++ struct qfq_aggregate *new_agg; + ++ /* 'lmax' can range from [QFQ_MIN_LMAX, pktlen + stab overhead] */ ++ if (lmax > (1UL << QFQ_MTU_SHIFT)) ++ return -EINVAL; ++ ++ new_agg = qfq_find_agg(q, lmax, weight); + if (new_agg == NULL) { /* create new aggregate */ + new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC); + if (new_agg == NULL) +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index 1bfdf90fa0cce..07721a1e98d8a 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -353,7 +353,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free) + unsigned int hash, dropped; + sfq_index x, qlen; + struct sfq_slot *slot; +- int uninitialized_var(ret); ++ int ret; + struct sk_buff *head; + int delta; + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index a68f3d6b72335..baa825751c393 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -380,9 +380,9 @@ static void sctp_auto_asconf_init(struct sctp_sock *sp) + struct net *net = sock_net(&sp->inet.sk); + + if (net->sctp.default_auto_asconf) { +- spin_lock(&net->sctp.addr_wq_lock); ++ spin_lock_bh(&net->sctp.addr_wq_lock); + list_add_tail(&sp->auto_asconf_list, &net->sctp.auto_asconf_splist); +- spin_unlock(&net->sctp.addr_wq_lock); ++ spin_unlock_bh(&net->sctp.addr_wq_lock); + sp->do_auto_asconf = 1; + } + } +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index d0b5a1c47a324..b5ee21d5d1f3a 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -757,12 +757,6 @@ static void svc_tcp_listen_data_ready(struct sock *sk) + dprintk("svc: socket %p TCP (listen) state change %d\n", + sk, sk->sk_state); + +- if (svsk) { +- /* Refer to svc_setup_socket() for details. */ +- rmb(); +- svsk->sk_odata(sk); +- } +- + /* + * This callback may called twice when a new connection + * is established as a child socket inherits everything +@@ -771,15 +765,20 @@ static void svc_tcp_listen_data_ready(struct sock *sk) + * when one of child sockets become ESTABLISHED. + * 2) data_ready method of the child socket may be called + * when it receives data before the socket is accepted. +- * In case of 2, we should ignore it silently. ++ * In case of 2, we should ignore it silently and DO NOT ++ * dereference svsk. + */ +- if (sk->sk_state == TCP_LISTEN) { +- if (svsk) { +- set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); +- svc_xprt_enqueue(&svsk->sk_xprt); +- } else +- printk("svc: socket %p: no user data\n", sk); +- } ++ if (sk->sk_state != TCP_LISTEN) ++ return; ++ ++ if (svsk) { ++ /* Refer to svc_setup_socket() for details. */ ++ rmb(); ++ svsk->sk_odata(sk); ++ set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); ++ svc_xprt_enqueue(&svsk->sk_xprt); ++ } else ++ printk("svc: socket %p: no user data\n", sk); + } + + /* +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index b0dcbb08e60db..8971341c4f8af 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -706,7 +706,7 @@ static int unix_set_peek_off(struct sock *sk, int val) + if (mutex_lock_interruptible(&u->iolock)) + return -EINTR; + +- sk->sk_peek_off = val; ++ WRITE_ONCE(sk->sk_peek_off, val); + mutex_unlock(&u->iolock); + + return 0; +diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c +index 76a80a41615be..a57f54bc0e1a7 100644 +--- a/net/wireless/wext-core.c ++++ b/net/wireless/wext-core.c +@@ -796,6 +796,12 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, + } + } + ++ /* Sanity-check to ensure we never end up _allocating_ zero ++ * bytes of data for extra. ++ */ ++ if (extra_size <= 0) ++ return -EFAULT; ++ + /* kzalloc() ensures NULL-termination for essid_compat. */ + extra = kzalloc(extra_size, GFP_KERNEL); + if (!extra) +diff --git a/samples/bpf/tcp_basertt_kern.c b/samples/bpf/tcp_basertt_kern.c +index 4bf4fc597db9a..653d233714ad0 100644 +--- a/samples/bpf/tcp_basertt_kern.c ++++ b/samples/bpf/tcp_basertt_kern.c +@@ -54,7 +54,7 @@ int bpf_basertt(struct bpf_sock_ops *skops) + case BPF_SOCK_OPS_BASE_RTT: + n = bpf_getsockopt(skops, SOL_TCP, TCP_CONGESTION, + cong, sizeof(cong)); +- if (!n && !__builtin_memcmp(cong, nv, sizeof(nv)+1)) { ++ if (!n && !__builtin_memcmp(cong, nv, sizeof(nv))) { + /* Set base_rtt to 80us */ + rv = 80; + } else if (n) { +diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c +index 8c2847ef4e422..2060a3fe9691d 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -1260,6 +1260,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, + if (relsym->st_name != 0) + return relsym; + ++ /* ++ * Strive to find a better symbol name, but the resulting name may not ++ * match the symbol referenced in the original code. ++ */ + relsym_secindex = get_secindex(elf, relsym); + for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { + if (get_secindex(elf, sym) != relsym_secindex) +@@ -1747,19 +1751,33 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) + #define R_ARM_THM_JUMP19 51 + #endif + ++static int32_t sign_extend32(int32_t value, int index) ++{ ++ uint8_t shift = 31 - index; ++ ++ return (int32_t)(value << shift) >> shift; ++} ++ + static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) + { + unsigned int r_typ = ELF_R_TYPE(r->r_info); ++ Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); ++ void *loc = reloc_location(elf, sechdr, r); ++ uint32_t inst; ++ int32_t offset; + + switch (r_typ) { + case R_ARM_ABS32: +- /* From ARM ABI: (S + A) | T */ +- r->r_addend = (int)(long) +- (elf->symtab_start + ELF_R_SYM(r->r_info)); ++ inst = TO_NATIVE(*(uint32_t *)loc); ++ r->r_addend = inst + sym->st_value; + break; + case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: ++ inst = TO_NATIVE(*(uint32_t *)loc); ++ offset = sign_extend32((inst & 0x00ffffff) << 2, 25); ++ r->r_addend = offset + sym->st_value + 8; ++ break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: +diff --git a/scripts/tags.sh b/scripts/tags.sh +index 26de7d5aa5c89..de02c44549f73 100755 +--- a/scripts/tags.sh ++++ b/scripts/tags.sh +@@ -28,6 +28,13 @@ fi + # ignore userspace tools + ignore="$ignore ( -path ${tree}tools ) -prune -o" + ++# gtags(1) refuses to index any file outside of its current working dir. ++# If gtags indexing is requested and the build output directory is not ++# the kernel source tree, index all files in absolute-path form. ++if [[ "$1" == "gtags" && -n "${tree}" ]]; then ++ tree=$(realpath "$tree")/ ++fi ++ + # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH + if [ "${ALLSOURCE_ARCHS}" = "" ]; then + ALLSOURCE_ARCHS=${SRCARCH} +@@ -136,7 +143,7 @@ docscope() + + dogtags() + { +- all_target_sources | gtags -i -f - ++ all_target_sources | gtags -i -C "${tree:-.}" -f - "$PWD" + } + + # Basic regular expressions with an optional /kind-spec/ for ctags and +diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c +index 6d1efe1359f17..9c036a41e7347 100644 +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -474,7 +474,9 @@ void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name) + + /** + * evm_inode_setattr - prevent updating an invalid EVM extended attribute ++ * @idmap: idmap of the mount + * @dentry: pointer to the affected dentry ++ * @attr: iattr structure containing the new file attributes + * + * Permit update of file attributes when files have a valid EVM signature, + * except in the case of them having an immutable portable signature. +diff --git a/security/integrity/iint.c b/security/integrity/iint.c +index 5a6810041e5c0..d5b9253ebd12b 100644 +--- a/security/integrity/iint.c ++++ b/security/integrity/iint.c +@@ -46,12 +46,10 @@ static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode) + else if (inode > iint->inode) + n = n->rb_right; + else +- break; ++ return iint; + } +- if (!n) +- return NULL; + +- return iint; ++ return NULL; + } + + /* +@@ -116,10 +114,15 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode) + parent = *p; + test_iint = rb_entry(parent, struct integrity_iint_cache, + rb_node); +- if (inode < test_iint->inode) ++ if (inode < test_iint->inode) { + p = &(*p)->rb_left; +- else ++ } else if (inode > test_iint->inode) { + p = &(*p)->rb_right; ++ } else { ++ write_unlock(&integrity_iint_lock); ++ kmem_cache_free(iint_cache, iint); ++ return test_iint; ++ } + } + + iint->inode = inode; +diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c +index 00d826b048c4a..eb6735f16b933 100644 +--- a/sound/core/control_compat.c ++++ b/sound/core/control_compat.c +@@ -236,7 +236,7 @@ static int copy_ctl_value_from_user(struct snd_card *card, + { + struct snd_ctl_elem_value32 __user *data32 = userdata; + int i, type, size; +- int uninitialized_var(count); ++ int count; + unsigned int indirect; + + if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) +diff --git a/sound/core/jack.c b/sound/core/jack.c +index 074b15fcb0ac4..06e0fc7b64179 100644 +--- a/sound/core/jack.c ++++ b/sound/core/jack.c +@@ -378,6 +378,7 @@ void snd_jack_report(struct snd_jack *jack, int status) + { + struct snd_jack_kctl *jack_kctl; + #ifdef CONFIG_SND_JACK_INPUT_DEV ++ struct input_dev *idev; + int i; + #endif + +@@ -389,30 +390,28 @@ void snd_jack_report(struct snd_jack *jack, int status) + status & jack_kctl->mask_bits); + + #ifdef CONFIG_SND_JACK_INPUT_DEV +- mutex_lock(&jack->input_dev_lock); +- if (!jack->input_dev) { +- mutex_unlock(&jack->input_dev_lock); ++ idev = input_get_device(jack->input_dev); ++ if (!idev) + return; +- } + + for (i = 0; i < ARRAY_SIZE(jack->key); i++) { + int testbit = SND_JACK_BTN_0 >> i; + + if (jack->type & testbit) +- input_report_key(jack->input_dev, jack->key[i], ++ input_report_key(idev, jack->key[i], + status & testbit); + } + + for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { + int testbit = 1 << i; + if (jack->type & testbit) +- input_report_switch(jack->input_dev, ++ input_report_switch(idev, + jack_switch_types[i], + status & testbit); + } + +- input_sync(jack->input_dev); +- mutex_unlock(&jack->input_dev_lock); ++ input_sync(idev); ++ input_put_device(idev); + #endif /* CONFIG_SND_JACK_INPUT_DEV */ + } + EXPORT_SYMBOL(snd_jack_report); +diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c +index c16c8151160c3..970aef2cf513a 100644 +--- a/sound/isa/sb/sb16_csp.c ++++ b/sound/isa/sb/sb16_csp.c +@@ -116,7 +116,7 @@ static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buff + int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) + { + struct snd_sb_csp *p; +- int uninitialized_var(version); ++ int version; + int err; + struct snd_hwdep *hw; + +diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c +index a276c4283c7bb..3f13666a01904 100644 +--- a/sound/pci/ac97/ac97_codec.c ++++ b/sound/pci/ac97/ac97_codec.c +@@ -2026,8 +2026,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, + .dev_disconnect = snd_ac97_dev_disconnect, + }; + +- if (rac97) +- *rac97 = NULL; ++ if (!rac97) ++ return -EINVAL; + if (snd_BUG_ON(!bus || !template)) + return -EINVAL; + if (snd_BUG_ON(template->num >= 4)) +diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c +index 4b5731a418762..cd93e93a59832 100644 +--- a/sound/soc/codecs/cs42l51-i2c.c ++++ b/sound/soc/codecs/cs42l51-i2c.c +@@ -23,6 +23,12 @@ static struct i2c_device_id cs42l51_i2c_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); + ++const struct of_device_id cs42l51_of_match[] = { ++ { .compatible = "cirrus,cs42l51", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cs42l51_of_match); ++ + static int cs42l51_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) + { +diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c +index 5080d7a3c2798..662f1f85ba36f 100644 +--- a/sound/soc/codecs/cs42l51.c ++++ b/sound/soc/codecs/cs42l51.c +@@ -563,13 +563,6 @@ error: + } + EXPORT_SYMBOL_GPL(cs42l51_probe); + +-const struct of_device_id cs42l51_of_match[] = { +- { .compatible = "cirrus,cs42l51", }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, cs42l51_of_match); +-EXPORT_SYMBOL_GPL(cs42l51_of_match); +- + MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); + MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); + MODULE_LICENSE("GPL"); +diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h +index 0ca805492ac4b..8c55bf384bc65 100644 +--- a/sound/soc/codecs/cs42l51.h ++++ b/sound/soc/codecs/cs42l51.h +@@ -22,7 +22,6 @@ struct device; + + extern const struct regmap_config cs42l51_regmap; + int cs42l51_probe(struct device *dev, struct regmap *regmap); +-extern const struct of_device_id cs42l51_of_match[]; + + #define CS42L51_CHIP_ID 0x1B + #define CS42L51_CHIP_REV_A 0x00 +diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c +index 57130edaf3aba..834e542021fee 100644 +--- a/sound/soc/codecs/es8316.c ++++ b/sound/soc/codecs/es8316.c +@@ -45,7 +45,12 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1); + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1); + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0); + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0); +-static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0); ++ ++static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(alc_target_tlv, ++ 0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0), ++ 11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0), ++); ++ + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv, + 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0), + 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0), +@@ -107,7 +112,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = { + alc_max_gain_tlv), + SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0, + alc_min_gain_tlv), +- SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0, ++ SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 11, 0, + alc_target_tlv), + SOC_SINGLE("ALC Capture Hold Time", ES8316_ADC_ALC3, 0, 10, 0), + SOC_SINGLE("ALC Capture Decay Time", ES8316_ADC_ALC4, 4, 10, 0), +diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c +index d14e851b91605..03d3b0f17f877 100644 +--- a/sound/soc/codecs/wm8904.c ++++ b/sound/soc/codecs/wm8904.c +@@ -2264,6 +2264,9 @@ static int wm8904_i2c_probe(struct i2c_client *i2c, + regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0, + WM8904_POBCTRL, 0); + ++ /* Fill the cache for the ADC test register */ ++ regmap_read(wm8904->regmap, WM8904_ADC_TEST_0, &val); ++ + /* Can leave the device powered off until we need it */ + regcache_cache_only(wm8904->regmap, true); + regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); +diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c +index 740b90df44bb5..0a1ba64ed63cf 100644 +--- a/sound/soc/fsl/fsl_spdif.c ++++ b/sound/soc/fsl/fsl_spdif.c +@@ -614,6 +614,8 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream, + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0); + regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0); ++ regmap_write(regmap, REG_SPDIF_STL, 0x0); ++ regmap_write(regmap, REG_SPDIF_STR, 0x0); + break; + default: + return -EINVAL; +diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c +index e428d8b36c00a..56119a96d3509 100644 +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -324,7 +324,7 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) + while (test_bit(EP_FLAG_RUNNING, &ep->flags)) { + + unsigned long flags; +- struct snd_usb_packet_info *uninitialized_var(packet); ++ struct snd_usb_packet_info *packet; + struct snd_urb_ctx *ctx = NULL; + int err, i; + +diff --git a/tools/perf/tests/shell/test_uprobe_from_different_cu.sh b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh +new file mode 100644 +index 0000000000000..319f36ebb9a40 +--- /dev/null ++++ b/tools/perf/tests/shell/test_uprobe_from_different_cu.sh +@@ -0,0 +1,83 @@ ++#!/bin/bash ++# test perf probe of function from different CU ++# SPDX-License-Identifier: GPL-2.0 ++ ++set -e ++ ++# skip if there's no gcc ++if ! [ -x "$(command -v gcc)" ]; then ++ echo "failed: no gcc compiler" ++ exit 2 ++fi ++ ++temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX) ++ ++cleanup() ++{ ++ trap - EXIT TERM INT ++ if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then ++ echo "--- Cleaning up ---" ++ perf probe -x ${temp_dir}/testfile -d foo || true ++ rm -f "${temp_dir}/"* ++ rmdir "${temp_dir}" ++ fi ++} ++ ++trap_cleanup() ++{ ++ cleanup ++ exit 1 ++} ++ ++trap trap_cleanup EXIT TERM INT ++ ++cat > ${temp_dir}/testfile-foo.h << EOF ++struct t ++{ ++ int *p; ++ int c; ++}; ++ ++extern int foo (int i, struct t *t); ++EOF ++ ++cat > ${temp_dir}/testfile-foo.c << EOF ++#include "testfile-foo.h" ++ ++int ++foo (int i, struct t *t) ++{ ++ int j, res = 0; ++ for (j = 0; j < i && j < t->c; j++) ++ res += t->p[j]; ++ ++ return res; ++} ++EOF ++ ++cat > ${temp_dir}/testfile-main.c << EOF ++#include "testfile-foo.h" ++ ++static struct t g; ++ ++int ++main (int argc, char **argv) ++{ ++ int i; ++ int j[argc]; ++ g.c = argc; ++ g.p = j; ++ for (i = 0; i < argc; i++) ++ j[i] = (int) argv[i][0]; ++ return foo (3, &g); ++} ++EOF ++ ++gcc -g -Og -flto -c ${temp_dir}/testfile-foo.c -o ${temp_dir}/testfile-foo.o ++gcc -g -Og -c ${temp_dir}/testfile-main.c -o ${temp_dir}/testfile-main.o ++gcc -g -Og -o ${temp_dir}/testfile ${temp_dir}/testfile-foo.o ${temp_dir}/testfile-main.o ++ ++perf probe -x ${temp_dir}/testfile --funcs foo ++perf probe -x ${temp_dir}/testfile foo ++ ++cleanup +diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c +index 6de57d9ee7cc2..db099dc20a682 100644 +--- a/tools/perf/util/dwarf-aux.c ++++ b/tools/perf/util/dwarf-aux.c +@@ -1020,7 +1020,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) + ret = die_get_typename(vr_die, buf); + if (ret < 0) { + pr_debug("Failed to get type, make it unknown.\n"); +- ret = strbuf_add(buf, " (unknown_type)", 14); ++ ret = strbuf_add(buf, "(unknown_type)", 14); + } + + return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +index e2a6c22959f26..aabd423785520 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +@@ -1499,6 +1499,8 @@ static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder) + + decoder->cbr = cbr; + decoder->cbr_cyc_to_tsc = decoder->max_non_turbo_ratio_fp / cbr; ++ decoder->cyc_ref_timestamp = decoder->timestamp; ++ decoder->cycle_cnt = 0; + } + + static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder) |