diff options
335 files changed, 2409 insertions, 1806 deletions
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index baef432e8369..0ac23f2ed104 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -15,6 +15,17 @@ Optional properties for main touchpad device: keycode generated by each GPIO. Linux keycodes are defined in <dt-bindings/input/input.h>. +- linux,gpio-keymap: When enabled, the SPT_GPIOPWN_T19 object sends messages + on GPIO bit changes. An array of up to 8 entries can be provided + indicating the Linux keycode mapped to each bit of the status byte, + starting at the LSB. Linux keycodes are defined in + <dt-bindings/input/input.h>. + + Note: the numbering of the GPIOs and the bit they start at varies between + maXTouch devices. You must either refer to the documentation, or + experiment to determine which bit corresponds to which input. Use + KEY_RESERVED for unused padding values. + Example: touch@4b { diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index 65f4f7c43136..ee654e95d8ad 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -22,7 +22,7 @@ Optional properties: width of 8 is assumed. - ti,nand-ecc-opt: A string setting the ECC layout to use. One of: - "sw" <deprecated> use "ham1" instead + "sw" 1-bit Hamming ecc code via software "hw" <deprecated> use "ham1" instead "hw-romcode" <deprecated> use "ham1" instead "ham1" 1-bit Hamming ecc code diff --git a/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt index 46f344965313..4eb7997674a0 100644 --- a/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt +++ b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt @@ -1,7 +1,7 @@ ADI AXI-SPDIF controller Required properties: - - compatible : Must be "adi,axi-spdif-1.00.a" + - compatible : Must be "adi,axi-spdif-tx-1.00.a" - reg : Must contain SPDIF core's registers location and length - clocks : Pairs of phandle and specifier referencing the controller's clocks. The controller expects two clocks, the clock used for the AXI interface and diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index 88d5a863712a..6c0b9f27e465 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt @@ -18,7 +18,7 @@ memory image to a dump file on the local disk, or across the network to a remote system. Kdump and kexec are currently supported on the x86, x86_64, ppc64, ia64, -and s390x architectures. +s390x and arm architectures. When the system kernel boots, it reserves a small section of memory for the dump-capture kernel. This ensures that ongoing Direct Memory Access @@ -112,7 +112,7 @@ There are two possible methods of using Kdump. 2) Or use the system kernel binary itself as dump-capture kernel and there is no need to build a separate dump-capture kernel. This is possible only with the architectures which support a relocatable kernel. As - of today, i386, x86_64, ppc64 and ia64 architectures support relocatable + of today, i386, x86_64, ppc64, ia64 and arm architectures support relocatable kernel. Building a relocatable kernel is advantageous from the point of view that @@ -241,6 +241,13 @@ Dump-capture kernel config options (Arch Dependent, ia64) kernel will be aligned to 64Mb, so if the start address is not then any space below the alignment point will be wasted. +Dump-capture kernel config options (Arch Dependent, arm) +---------------------------------------------------------- + +- To use a relocatable kernel, + Enable "AUTO_ZRELADDR" support under "Boot" options: + + AUTO_ZRELADDR=y Extended crashkernel syntax =========================== @@ -256,6 +263,10 @@ The syntax is: crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset] range=start-[end] +Please note, on arm, the offset is required. + crashkernel=<range1>:<size1>[,<range2>:<size2>,...]@offset + range=start-[end] + 'start' is inclusive and 'end' is exclusive. For example: @@ -296,6 +307,12 @@ Boot into System Kernel on the memory consumption of the kdump system. In general this is not dependent on the memory size of the production system. + On arm, use "crashkernel=Y@X". Note that the start address of the kernel + will be aligned to 128MiB (0x08000000), so if the start address is not then + any space below the alignment point may be overwritten by the dump-capture kernel, + which means it is possible that the vmcore is not that precise as expected. + + Load the Dump-capture Kernel ============================ @@ -315,7 +332,8 @@ For ia64: - Use vmlinux or vmlinuz.gz For s390x: - Use image or bzImage - +For arm: + - Use zImage If you are using a uncompressed vmlinux image then use following command to load dump-capture kernel. @@ -331,6 +349,15 @@ to load dump-capture kernel. --initrd=<initrd-for-dump-capture-kernel> \ --append="root=<root-dev> <arch-specific-options>" +If you are using a compressed zImage, then use following command +to load dump-capture kernel. + + kexec --type zImage -p <dump-capture-kernel-bzImage> \ + --initrd=<initrd-for-dump-capture-kernel> \ + --dtb=<dtb-for-dump-capture-kernel> \ + --append="root=<root-dev> <arch-specific-options>" + + Please note, that --args-linux does not need to be specified for ia64. It is planned to make this a no-op on that architecture, but for now it should be omitted @@ -347,6 +374,9 @@ For ppc64: For s390x: "1 maxcpus=1 cgroup_disable=memory" +For arm: + "1 maxcpus=1 reset_devices" + Notes on loading the dump-capture kernel: * By default, the ELF headers are stored in ELF64 format to support diff --git a/MAINTAINERS b/MAINTAINERS index 1ff06dee651d..5e7866a486b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1279,8 +1279,13 @@ M: Heiko Stuebner <heiko@sntech.de> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-rockchip@lists.infradead.org S: Maintained +F: arch/arm/boot/dts/rk3* F: arch/arm/mach-rockchip/ +F: drivers/clk/rockchip/ +F: drivers/i2c/busses/i2c-rk3x.c F: drivers/*/*rockchip* +F: drivers/*/*/*rockchip* +F: sound/soc/rockchip/ ARM/SAMSUNG ARM ARCHITECTURES M: Ben Dooks <ben-linux@fluff.org> @@ -9557,6 +9562,14 @@ S: Maintained F: Documentation/usb/ohci.txt F: drivers/usb/host/ohci* +USB OVER IP DRIVER +M: Valentina Manea <valentina.manea.m@gmail.com> +M: Shuah Khan <shuah.kh@samsung.com> +L: linux-usb@vger.kernel.org +S: Maintained +F: drivers/usb/usbip/ +F: tools/usb/usbip/ + USB PEGASUS DRIVER M: Petko Manolov <petkan@nucleusys.com> L: linux-usb@vger.kernel.org @@ -10057,9 +10070,9 @@ F: Documentation/x86/ F: arch/x86/ X86 PLATFORM DRIVERS -M: Matthew Garrett <matthew.garrett@nebula.com> +M: Darren Hart <dvhart@infradead.org> L: platform-driver-x86@vger.kernel.org -T: git git://cavan.codon.org.uk/platform-drivers-x86.git +T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git S: Maintained F: drivers/platform/x86/ @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 17 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Shuffling Zombie Juror # *DOCUMENTATION* diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h index 5ebab5895edb..f05bdb4b1cb9 100644 --- a/arch/alpha/include/asm/io.h +++ b/arch/alpha/include/asm/io.h @@ -500,10 +500,14 @@ extern inline void writeq(u64 b, volatile void __iomem *addr) #define outb_p outb #define outw_p outw #define outl_p outl -#define readb_relaxed(addr) __raw_readb(addr) -#define readw_relaxed(addr) __raw_readw(addr) -#define readl_relaxed(addr) __raw_readl(addr) -#define readq_relaxed(addr) __raw_readq(addr) +#define readb_relaxed(addr) __raw_readb(addr) +#define readw_relaxed(addr) __raw_readw(addr) +#define readl_relaxed(addr) __raw_readl(addr) +#define readq_relaxed(addr) __raw_readq(addr) +#define writeb_relaxed(b, addr) __raw_writeb(b, addr) +#define writew_relaxed(b, addr) __raw_writew(b, addr) +#define writel_relaxed(b, addr) __raw_writel(b, addr) +#define writeq_relaxed(b, addr) __raw_writeq(b, addr) #define mmiowb() diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index f2c94402e2c8..c509d306db45 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -3,7 +3,7 @@ #include <uapi/asm/unistd.h> -#define NR_SYSCALLS 508 +#define NR_SYSCALLS 511 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/arch/alpha/include/uapi/asm/unistd.h b/arch/alpha/include/uapi/asm/unistd.h index 53ae7bb1bfd1..d214a0358100 100644 --- a/arch/alpha/include/uapi/asm/unistd.h +++ b/arch/alpha/include/uapi/asm/unistd.h @@ -469,5 +469,8 @@ #define __NR_process_vm_writev 505 #define __NR_kcmp 506 #define __NR_finit_module 507 +#define __NR_sched_setattr 508 +#define __NR_sched_getattr 509 +#define __NR_renameat2 510 #endif /* _UAPI_ALPHA_UNISTD_H */ diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index dca9b3fb0071..24789713f1ea 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -526,6 +526,9 @@ sys_call_table: .quad sys_process_vm_writev /* 505 */ .quad sys_kcmp .quad sys_finit_module + .quad sys_sched_setattr + .quad sys_sched_getattr + .quad sys_renameat2 /* 510 */ .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c index 4670afc3b971..9e1142729fd1 100644 --- a/arch/arc/mm/cache_arc700.c +++ b/arch/arc/mm/cache_arc700.c @@ -427,7 +427,7 @@ struct ic_inv_args { static void __ic_line_inv_vaddr_helper(void *info) { - struct ic_inv *ic_inv_args = (struct ic_inv_args *) info; + struct ic_inv_args *ic_inv = info; __ic_line_inv_vaddr_local(ic_inv->paddr, ic_inv->vaddr, ic_inv->sz); } @@ -581,6 +581,7 @@ void flush_icache_range(unsigned long kstart, unsigned long kend) tot_sz -= sz; } } +EXPORT_SYMBOL(flush_icache_range); /* * General purpose helper to make I and D cache lines consistent. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c49a775937db..32cbbd565902 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1983,8 +1983,6 @@ config XIP_PHYS_ADDR config KEXEC bool "Kexec system call (EXPERIMENTAL)" depends on (!SMP || PM_SLEEP_SMP) - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 97f603c4483d..d678152db4cb 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -245,7 +245,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio2: gpio@48055000 { @@ -256,7 +256,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio3: gpio@48057000 { @@ -267,7 +267,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio4: gpio@48059000 { @@ -278,7 +278,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio5: gpio@4805b000 { @@ -289,7 +289,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio6: gpio@4805d000 { @@ -300,7 +300,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio7: gpio@48051000 { @@ -311,7 +311,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; gpio8: gpio@48053000 { @@ -322,7 +322,7 @@ gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; }; uart1: serial@4806a000 { diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts index f1bbf9a32991..82d623d05915 100644 --- a/arch/arm/boot/dts/imx53-qsrb.dts +++ b/arch/arm/boot/dts/imx53-qsrb.dts @@ -28,6 +28,12 @@ MX53_PAD_CSI0_DAT9__I2C1_SCL 0x400001ec >; }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX53_PAD_CSI0_DAT5__GPIO5_23 0x1e4 /* IRQ */ + >; + }; }; }; @@ -38,6 +44,8 @@ pmic: mc34708@8 { compatible = "fsl,mc34708"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; reg = <0x08>; interrupt-parent = <&gpio5>; interrupts = <23 0x8>; diff --git a/arch/arm/boot/dts/imx6dl-hummingboard.dts b/arch/arm/boot/dts/imx6dl-hummingboard.dts index c8e51dd41b8f..71598546087f 100644 --- a/arch/arm/boot/dts/imx6dl-hummingboard.dts +++ b/arch/arm/boot/dts/imx6dl-hummingboard.dts @@ -58,7 +58,7 @@ sound-spdif { compatible = "fsl,imx-audio-spdif"; - model = "imx-spdif"; + model = "On-board SPDIF"; /* IMX6 doesn't implement this yet */ spdif-controller = <&spdif>; spdif-out; @@ -181,11 +181,13 @@ }; &usbh1 { + disable-over-current; vbus-supply = <®_usbh1_vbus>; status = "okay"; }; &usbotg { + disable-over-current; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_usbotg_id>; vbus-supply = <®_usbotg_vbus>; diff --git a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi index e8e781656b3f..6a524ca011e7 100644 --- a/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi +++ b/arch/arm/boot/dts/imx6qdl-cubox-i.dtsi @@ -61,7 +61,7 @@ sound-spdif { compatible = "fsl,imx-audio-spdif"; - model = "imx-spdif"; + model = "Integrated SPDIF"; /* IMX6 doesn't implement this yet */ spdif-controller = <&spdif>; spdif-out; @@ -130,16 +130,23 @@ fsl,pins = <MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x13091>; }; + pinctrl_cubox_i_usbh1: cubox-i-usbh1 { + fsl,pins = <MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0>; + }; + pinctrl_cubox_i_usbh1_vbus: cubox-i-usbh1-vbus { fsl,pins = <MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x4001b0b0>; }; - pinctrl_cubox_i_usbotg_id: cubox-i-usbotg-id { + pinctrl_cubox_i_usbotg: cubox-i-usbotg { /* - * The Cubox-i pulls this low, but as it's pointless + * The Cubox-i pulls ID low, but as it's pointless * leaving it as a pull-up, even if it is just 10uA. */ - fsl,pins = <MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059>; + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13059 + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0 + >; }; pinctrl_cubox_i_usbotg_vbus: cubox-i-usbotg-vbus { @@ -173,13 +180,15 @@ }; &usbh1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cubox_i_usbh1>; vbus-supply = <®_usbh1_vbus>; status = "okay"; }; &usbotg { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_cubox_i_usbotg_id>; + pinctrl-0 = <&pinctrl_cubox_i_usbotg>; vbus-supply = <®_usbotg_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi index d16066608e21..db9f45b2c573 100644 --- a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi +++ b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi @@ -17,7 +17,7 @@ enet { pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 { fsl,pins = < - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0 MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 /* AR8035 reset */ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0 diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 3c3e6da1deac..a9aae88b74f5 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -292,6 +292,7 @@ &uart3 { pinctrl-names = "default"; pinctrl-0 = <&uart3_pins>; + interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>; }; &gpio1 { diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 02f69f4a8fd3..9bad94efe1c8 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -107,7 +107,7 @@ #address-cells = <1>; #size-cells = <1>; reg = <1 0 0x08000000>; - ti,nand-ecc-opt = "ham1"; + ti,nand-ecc-opt = "sw"; nand-bus-width = <8>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <36>; diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi index e67a23b5d788..58c27466f012 100644 --- a/arch/arm/boot/dts/omap54xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi @@ -367,10 +367,12 @@ l3_iclk_div: l3_iclk_div { #clock-cells = <0>; - compatible = "fixed-factor-clock"; + compatible = "ti,divider-clock"; + ti,max-div = <2>; + ti,bit-shift = <4>; + reg = <0x100>; clocks = <&dpll_core_h12x2_ck>; - clock-mult = <1>; - clock-div = <1>; + ti,index-power-of-two; }; gpu_l3_iclk: gpu_l3_iclk { @@ -383,10 +385,12 @@ l4_root_clk_div: l4_root_clk_div { #clock-cells = <0>; - compatible = "fixed-factor-clock"; + compatible = "ti,divider-clock"; + ti,max-div = <2>; + ti,bit-shift = <8>; + reg = <0x100>; clocks = <&l3_iclk_div>; - clock-mult = <1>; - clock-div = <1>; + ti,index-power-of-two; }; slimbus1_slimbus_clk: slimbus1_slimbus_clk { diff --git a/arch/arm/boot/dts/twl6030.dtsi b/arch/arm/boot/dts/twl6030.dtsi index 2e3bd3172b23..55eb35f068fb 100644 --- a/arch/arm/boot/dts/twl6030.dtsi +++ b/arch/arm/boot/dts/twl6030.dtsi @@ -83,10 +83,6 @@ regulator-always-on; }; - clk32kg: regulator-clk32kg { - compatible = "ti,twl6030-clk32kg"; - }; - twl_usb_comparator: usb-comparator { compatible = "ti,twl6030-usb"; interrupts = <4>, <10>; diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index fd43f7f55b70..79ecb4f34ffb 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -472,7 +472,6 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size) "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \ "isb \n\t" \ "bl v7_flush_dcache_"__stringify(level)" \n\t" \ - "clrex \n\t" \ "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR \n\t" \ "bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \ "mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \ diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 963a2515906d..819777d0e91f 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -74,6 +74,7 @@ #define ARM_CPU_PART_CORTEX_A12 0x4100c0d0 #define ARM_CPU_PART_CORTEX_A17 0x4100c0e0 #define ARM_CPU_PART_CORTEX_A15 0x4100c0f0 +#define ARM_CPU_PART_MASK 0xff00fff0 #define ARM_CPU_XSCALE_ARCH_MASK 0xe000 #define ARM_CPU_XSCALE_ARCH_V1 0x2000 @@ -179,7 +180,7 @@ static inline unsigned int __attribute_const__ read_cpuid_implementor(void) */ static inline unsigned int __attribute_const__ read_cpuid_part(void) { - return read_cpuid_id() & 0xff00fff0; + return read_cpuid_id() & ARM_CPU_PART_MASK; } static inline unsigned int __attribute_const__ __deprecated read_cpuid_part_number(void) diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index f4b46d39b9cf..afb9cafd3786 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t; #define R_ARM_ABS32 2 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 +#define R_ARM_TARGET1 38 #define R_ARM_V4BX 40 #define R_ARM_PREL31 42 #define R_ARM_MOVW_ABS_NC 43 diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index a252c0bfacf5..0ad7d490ee6f 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h @@ -8,6 +8,7 @@ #include <linux/cpumask.h> #include <linux/err.h> +#include <asm/cpu.h> #include <asm/cputype.h> /* @@ -25,6 +26,20 @@ static inline bool is_smp(void) #endif } +/** + * smp_cpuid_part() - return part id for a given cpu + * @cpu: logical cpu id. + * + * Return: part id of logical cpu passed as argument. + */ +static inline unsigned int smp_cpuid_part(int cpu) +{ + struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpu); + + return is_smp() ? cpu_info->cpuid & ARM_CPU_PART_MASK : + read_cpuid_part(); +} + /* all SMP configurations have the extended CPUID registers */ #ifndef CONFIG_MMU #define tlb_ops_need_broadcast() 0 diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 8db307d0954b..2fdf8679b46e 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -208,26 +208,21 @@ #endif .endif msr spsr_cxsf, \rpsr -#if defined(CONFIG_CPU_V6) - ldr r0, [sp] - strex r1, r2, [sp] @ clear the exclusive monitor - ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr -#elif defined(CONFIG_CPU_32v6K) - clrex @ clear the exclusive monitor - ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr -#else - ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K) + @ We must avoid clrex due to Cortex-A15 erratum #830321 + sub r0, sp, #4 @ uninhabited address + strex r1, r2, [r0] @ clear the exclusive monitor #endif + ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .endm .macro restore_user_regs, fast = 0, offset = 0 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr ldr lr, [sp, #\offset + S_PC]! @ get pc msr spsr_cxsf, r1 @ save in spsr_svc -#if defined(CONFIG_CPU_V6) +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K) + @ We must avoid clrex due to Cortex-A15 erratum #830321 strex r1, r2, [sp] @ clear the exclusive monitor -#elif defined(CONFIG_CPU_32v6K) - clrex @ clear the exclusive monitor #endif .if \fast ldmdb sp, {r1 - lr}^ @ get calling r1 - lr @@ -261,7 +256,10 @@ .endif ldr lr, [sp, #S_SP] @ top of the stack ldrd r0, r1, [sp, #S_LR] @ calling lr and pc - clrex @ clear the exclusive monitor + + @ We must avoid clrex due to Cortex-A15 erratum #830321 + strex r2, r1, [sp, #S_LR] @ clear the exclusive monitor + stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context ldmia sp, {r0 - r12} mov sp, lr @@ -282,13 +280,16 @@ .endm #else /* ifdef CONFIG_CPU_V7M */ .macro restore_user_regs, fast = 0, offset = 0 - clrex @ clear the exclusive monitor mov r2, sp load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr ldr lr, [sp, #\offset + S_PC] @ get pc add sp, sp, #\offset + S_SP msr spsr_cxsf, r1 @ save in spsr_svc + + @ We must avoid clrex due to Cortex-A15 erratum #830321 + strex r1, r2, [sp] @ clear the exclusive monitor + .if \fast ldmdb sp, {r1 - r12} @ get calling r1 - r12 .else diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 45e478157278..6a4dffefd357 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -91,6 +91,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, break; case R_ARM_ABS32: + case R_ARM_TARGET1: *(u32 *)loc += sym->st_value; break; diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index 67c492aabf4d..b19a39652545 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile @@ -36,5 +36,4 @@ obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o ifeq ($(CONFIG_ARCH_BRCMSTB),y) obj-y += brcmstb.o -obj-$(CONFIG_SMP) += headsmp-brcmstb.o platsmp-brcmstb.o endif diff --git a/arch/arm/mach-bcm/brcmstb.h b/arch/arm/mach-bcm/brcmstb.h deleted file mode 100644 index ec0c3d112b36..000000000000 --- a/arch/arm/mach-bcm/brcmstb.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2013-2014 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __BRCMSTB_H__ -#define __BRCMSTB_H__ - -void brcmstb_secondary_startup(void); - -#endif /* __BRCMSTB_H__ */ diff --git a/arch/arm/mach-bcm/headsmp-brcmstb.S b/arch/arm/mach-bcm/headsmp-brcmstb.S deleted file mode 100644 index 199c1ea58248..000000000000 --- a/arch/arm/mach-bcm/headsmp-brcmstb.S +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SMP boot code for secondary CPUs - * Based on arch/arm/mach-tegra/headsmp.S - * - * Copyright (C) 2010 NVIDIA, Inc. - * Copyright (C) 2013-2014 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <asm/assembler.h> -#include <linux/linkage.h> -#include <linux/init.h> - - .section ".text.head", "ax" - -ENTRY(brcmstb_secondary_startup) - /* - * Ensure CPU is in a sane state by disabling all IRQs and switching - * into SVC mode. - */ - setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r0 - - bl v7_invalidate_l1 - b secondary_startup -ENDPROC(brcmstb_secondary_startup) diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c deleted file mode 100644 index af780e9c23a6..000000000000 --- a/arch/arm/mach-bcm/platsmp-brcmstb.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Broadcom STB CPU SMP and hotplug support for ARM - * - * Copyright (C) 2013-2014 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> -#include <linux/printk.h> -#include <linux/regmap.h> -#include <linux/smp.h> -#include <linux/mfd/syscon.h> -#include <linux/spinlock.h> - -#include <asm/cacheflush.h> -#include <asm/cp15.h> -#include <asm/mach-types.h> -#include <asm/smp_plat.h> - -#include "brcmstb.h" - -enum { - ZONE_MAN_CLKEN_MASK = BIT(0), - ZONE_MAN_RESET_CNTL_MASK = BIT(1), - ZONE_MAN_MEM_PWR_MASK = BIT(4), - ZONE_RESERVED_1_MASK = BIT(5), - ZONE_MAN_ISO_CNTL_MASK = BIT(6), - ZONE_MANUAL_CONTROL_MASK = BIT(7), - ZONE_PWR_DN_REQ_MASK = BIT(9), - ZONE_PWR_UP_REQ_MASK = BIT(10), - ZONE_BLK_RST_ASSERT_MASK = BIT(12), - ZONE_PWR_OFF_STATE_MASK = BIT(25), - ZONE_PWR_ON_STATE_MASK = BIT(26), - ZONE_DPG_PWR_STATE_MASK = BIT(28), - ZONE_MEM_PWR_STATE_MASK = BIT(29), - ZONE_RESET_STATE_MASK = BIT(31), - CPU0_PWR_ZONE_CTRL_REG = 1, - CPU_RESET_CONFIG_REG = 2, -}; - -static void __iomem *cpubiuctrl_block; -static void __iomem *hif_cont_block; -static u32 cpu0_pwr_zone_ctrl_reg; -static u32 cpu_rst_cfg_reg; -static u32 hif_cont_reg; - -#ifdef CONFIG_HOTPLUG_CPU -static DEFINE_PER_CPU_ALIGNED(int, per_cpu_sw_state); - -static int per_cpu_sw_state_rd(u32 cpu) -{ - sync_cache_r(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu))); - return per_cpu(per_cpu_sw_state, cpu); -} - -static void per_cpu_sw_state_wr(u32 cpu, int val) -{ - per_cpu(per_cpu_sw_state, cpu) = val; - dmb(); - sync_cache_w(SHIFT_PERCPU_PTR(&per_cpu_sw_state, per_cpu_offset(cpu))); - dsb_sev(); -} -#else -static inline void per_cpu_sw_state_wr(u32 cpu, int val) { } -#endif - -static void __iomem *pwr_ctrl_get_base(u32 cpu) -{ - void __iomem *base = cpubiuctrl_block + cpu0_pwr_zone_ctrl_reg; - base += (cpu_logical_map(cpu) * 4); - return base; -} - -static u32 pwr_ctrl_rd(u32 cpu) -{ - void __iomem *base = pwr_ctrl_get_base(cpu); - return readl_relaxed(base); -} - -static void pwr_ctrl_wr(u32 cpu, u32 val) -{ - void __iomem *base = pwr_ctrl_get_base(cpu); - writel(val, base); -} - -static void cpu_rst_cfg_set(u32 cpu, int set) -{ - u32 val; - val = readl_relaxed(cpubiuctrl_block + cpu_rst_cfg_reg); - if (set) - val |= BIT(cpu_logical_map(cpu)); - else - val &= ~BIT(cpu_logical_map(cpu)); - writel_relaxed(val, cpubiuctrl_block + cpu_rst_cfg_reg); -} - -static void cpu_set_boot_addr(u32 cpu, unsigned long boot_addr) -{ - const int reg_ofs = cpu_logical_map(cpu) * 8; - writel_relaxed(0, hif_cont_block + hif_cont_reg + reg_ofs); - writel_relaxed(boot_addr, hif_cont_block + hif_cont_reg + 4 + reg_ofs); -} - -static void brcmstb_cpu_boot(u32 cpu) -{ - pr_info("SMP: Booting CPU%d...\n", cpu); - - /* - * set the reset vector to point to the secondary_startup - * routine - */ - cpu_set_boot_addr(cpu, virt_to_phys(brcmstb_secondary_startup)); - - /* unhalt the cpu */ - cpu_rst_cfg_set(cpu, 0); -} - -static void brcmstb_cpu_power_on(u32 cpu) -{ - /* - * The secondary cores power was cut, so we must go through - * power-on initialization. - */ - u32 tmp; - - pr_info("SMP: Powering up CPU%d...\n", cpu); - - /* Request zone power up */ - pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK); - - /* Wait for the power up FSM to complete */ - do { - tmp = pwr_ctrl_rd(cpu); - } while (!(tmp & ZONE_PWR_ON_STATE_MASK)); - - per_cpu_sw_state_wr(cpu, 1); -} - -static int brcmstb_cpu_get_power_state(u32 cpu) -{ - int tmp = pwr_ctrl_rd(cpu); - return (tmp & ZONE_RESET_STATE_MASK) ? 0 : 1; -} - -#ifdef CONFIG_HOTPLUG_CPU - -static void brcmstb_cpu_die(u32 cpu) -{ - v7_exit_coherency_flush(all); - - /* Prevent all interrupts from reaching this CPU. */ - arch_local_irq_disable(); - - /* - * Final full barrier to ensure everything before this instruction has - * quiesced. - */ - isb(); - dsb(); - - per_cpu_sw_state_wr(cpu, 0); - - /* Sit and wait to die */ - wfi(); - - /* We should never get here... */ - panic("Spurious interrupt on CPU %d received!\n", cpu); -} - -static int brcmstb_cpu_kill(u32 cpu) -{ - u32 tmp; - - pr_info("SMP: Powering down CPU%d...\n", cpu); - - while (per_cpu_sw_state_rd(cpu)) - ; - - /* Program zone reset */ - pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK | - ZONE_PWR_DN_REQ_MASK); - - /* Verify zone reset */ - tmp = pwr_ctrl_rd(cpu); - if (!(tmp & ZONE_RESET_STATE_MASK)) - pr_err("%s: Zone reset bit for CPU %d not asserted!\n", - __func__, cpu); - - /* Wait for power down */ - do { - tmp = pwr_ctrl_rd(cpu); - } while (!(tmp & ZONE_PWR_OFF_STATE_MASK)); - - /* Settle-time from Broadcom-internal DVT reference code */ - udelay(7); - - /* Assert reset on the CPU */ - cpu_rst_cfg_set(cpu, 1); - - return 1; -} - -#endif /* CONFIG_HOTPLUG_CPU */ - -static int __init setup_hifcpubiuctrl_regs(struct device_node *np) -{ - int rc = 0; - char *name; - struct device_node *syscon_np = NULL; - - name = "syscon-cpu"; - - syscon_np = of_parse_phandle(np, name, 0); - if (!syscon_np) { - pr_err("can't find phandle %s\n", name); - rc = -EINVAL; - goto cleanup; - } - - cpubiuctrl_block = of_iomap(syscon_np, 0); - if (!cpubiuctrl_block) { - pr_err("iomap failed for cpubiuctrl_block\n"); - rc = -EINVAL; - goto cleanup; - } - - rc = of_property_read_u32_index(np, name, CPU0_PWR_ZONE_CTRL_REG, - &cpu0_pwr_zone_ctrl_reg); - if (rc) { - pr_err("failed to read 1st entry from %s property (%d)\n", name, - rc); - rc = -EINVAL; - goto cleanup; - } - - rc = of_property_read_u32_index(np, name, CPU_RESET_CONFIG_REG, - &cpu_rst_cfg_reg); - if (rc) { - pr_err("failed to read 2nd entry from %s property (%d)\n", name, - rc); - rc = -EINVAL; - goto cleanup; - } - -cleanup: - if (syscon_np) - of_node_put(syscon_np); - - return rc; -} - -static int __init setup_hifcont_regs(struct device_node *np) -{ - int rc = 0; - char *name; - struct device_node *syscon_np = NULL; - - name = "syscon-cont"; - - syscon_np = of_parse_phandle(np, name, 0); - if (!syscon_np) { - pr_err("can't find phandle %s\n", name); - rc = -EINVAL; - goto cleanup; - } - - hif_cont_block = of_iomap(syscon_np, 0); - if (!hif_cont_block) { - pr_err("iomap failed for hif_cont_block\n"); - rc = -EINVAL; - goto cleanup; - } - - /* offset is at top of hif_cont_block */ - hif_cont_reg = 0; - -cleanup: - if (syscon_np) - of_node_put(syscon_np); - - return rc; -} - -static void __init brcmstb_cpu_ctrl_setup(unsigned int max_cpus) -{ - int rc; - struct device_node *np; - char *name; - - name = "brcm,brcmstb-smpboot"; - np = of_find_compatible_node(NULL, NULL, name); - if (!np) { - pr_err("can't find compatible node %s\n", name); - return; - } - - rc = setup_hifcpubiuctrl_regs(np); - if (rc) - return; - - rc = setup_hifcont_regs(np); - if (rc) - return; -} - -static DEFINE_SPINLOCK(boot_lock); - -static void brcmstb_secondary_init(unsigned int cpu) -{ - /* - * Synchronise with the boot thread. - */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); -} - -static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - /* - * set synchronisation state between this boot processor - * and the secondary one - */ - spin_lock(&boot_lock); - - /* Bring up power to the core if necessary */ - if (brcmstb_cpu_get_power_state(cpu) == 0) - brcmstb_cpu_power_on(cpu); - - brcmstb_cpu_boot(cpu); - - /* - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ - spin_unlock(&boot_lock); - - return 0; -} - -static struct smp_operations brcmstb_smp_ops __initdata = { - .smp_prepare_cpus = brcmstb_cpu_ctrl_setup, - .smp_secondary_init = brcmstb_secondary_init, - .smp_boot_secondary = brcmstb_boot_secondary, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = brcmstb_cpu_kill, - .cpu_die = brcmstb_cpu_die, -#endif -}; - -CPU_METHOD_OF_DECLARE(brcmstb_smp, "brcm,brahma-b15", &brcmstb_smp_ops); diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index b2f8b60cf0e9..dc9a764a7c37 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -43,7 +43,6 @@ "mcr p15, 0, r0, c1, c0, 0 @ set SCTLR\n\t" \ "isb\n\t"\ "bl v7_flush_dcache_"__stringify(level)"\n\t" \ - "clrex\n\t"\ "mrc p15, 0, r0, c1, c0, 1 @ get ACTLR\n\t" \ "bic r0, r0, #(1 << 6) @ disable local coherency\n\t" \ /* Dummy Load of a device register to avoid Erratum 799270 */ \ diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index e87f2a83d6bf..2d245c2e641c 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, board_nand_data.nr_parts = nr_parts; board_nand_data.devsize = nand_type; - board_nand_data.ecc_opt = OMAP_ECC_HAM1_CODE_HW; + board_nand_data.ecc_opt = OMAP_ECC_HAM1_CODE_SW; gpmc_nand_init(&board_nand_data, gpmc_t); } #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 8897ad7035fd..cb7764314f17 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -49,7 +49,8 @@ static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt) return 0; /* legacy platforms support only HAM1 (1-bit Hamming) ECC scheme */ - if (ecc_opt == OMAP_ECC_HAM1_CODE_HW) + if (ecc_opt == OMAP_ECC_HAM1_CODE_HW || + ecc_opt == OMAP_ECC_HAM1_CODE_SW) return 1; else return 0; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8bc13380f0a0..9f42d5437fcc 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1403,8 +1403,11 @@ static int gpmc_probe_nand_child(struct platform_device *pdev, pr_err("%s: ti,nand-ecc-opt not found\n", __func__); return -ENODEV; } - if (!strcmp(s, "ham1") || !strcmp(s, "sw") || - !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) + + if (!strcmp(s, "sw")) + gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW; + else if (!strcmp(s, "ham1") || + !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_HW; else if (!strcmp(s, "bch4")) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index d42022f2a71e..53841dea80ea 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -663,7 +663,7 @@ void __init dra7xxx_check_revision(void) default: /* Unknown default to latest silicon rev as default*/ - pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%d)\n", + pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n", __func__, idcode, hawkeye, rev); omap_revision = DRA752_REV_ES1_1; } diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 01ef59def44b..d22c30d3ccfa 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -56,7 +56,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias); if (!IS_ERR(r)) { - dev_warn(&od->pdev->dev, + dev_dbg(&od->pdev->dev, "alias %s already exists\n", clk_alias); clk_put(r); return; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6c074f37cdd2..8fd87a3055bf 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2185,6 +2185,8 @@ static int _enable(struct omap_hwmod *oh) oh->mux->pads_dynamic))) { omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); _reconfigure_io_chain(); + } else if (oh->flags & HWMOD_FORCE_MSTANDBY) { + _reconfigure_io_chain(); } _add_initiator_dep(oh, mpu_oh); @@ -2291,6 +2293,8 @@ static int _idle(struct omap_hwmod *oh) if (oh->mux && oh->mux->pads_dynamic) { omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); _reconfigure_io_chain(); + } else if (oh->flags & HWMOD_FORCE_MSTANDBY) { + _reconfigure_io_chain(); } oh->_state = _HWMOD_STATE_IDLE; @@ -3345,6 +3349,9 @@ int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) if (!ois) return 0; + if (ois[0] == NULL) /* Empty list */ + return 0; + if (!linkspace) { if (_alloc_linkspace(ois)) { pr_err("omap_hwmod: could not allocate link space\n"); diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 2757abf87fbc..5684f112654b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -35,6 +35,7 @@ #include "i2c.h" #include "mmc.h" #include "wd_timer.h" +#include "soc.h" /* Base offset for all DRA7XX interrupts external to MPUSS */ #define DRA7XX_IRQ_GIC_START 32 @@ -3261,7 +3262,6 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l4_per3__usb_otg_ss1, &dra7xx_l4_per3__usb_otg_ss2, &dra7xx_l4_per3__usb_otg_ss3, - &dra7xx_l4_per3__usb_otg_ss4, &dra7xx_l3_main_1__vcp1, &dra7xx_l4_per2__vcp1, &dra7xx_l3_main_1__vcp2, @@ -3270,8 +3270,26 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { NULL, }; +static struct omap_hwmod_ocp_if *dra74x_hwmod_ocp_ifs[] __initdata = { + &dra7xx_l4_per3__usb_otg_ss4, + NULL, +}; + +static struct omap_hwmod_ocp_if *dra72x_hwmod_ocp_ifs[] __initdata = { + NULL, +}; + int __init dra7xx_hwmod_init(void) { + int ret; + omap_hwmod_init(); - return omap_hwmod_register_links(dra7xx_hwmod_ocp_ifs); + ret = omap_hwmod_register_links(dra7xx_hwmod_ocp_ifs); + + if (!ret && soc_is_dra74x()) + return omap_hwmod_register_links(dra74x_hwmod_ocp_ifs); + else if (!ret && soc_is_dra72x()) + return omap_hwmod_register_links(dra72x_hwmod_ocp_ifs); + + return ret; } diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 01ca8086fb6c..4376f59626d1 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -245,6 +245,8 @@ IS_AM_SUBCLASS(437x, 0x437) #define soc_is_omap54xx() 0 #define soc_is_omap543x() 0 #define soc_is_dra7xx() 0 +#define soc_is_dra74x() 0 +#define soc_is_dra72x() 0 #if defined(MULTI_OMAP2) # if defined(CONFIG_ARCH_OMAP2) @@ -393,7 +395,11 @@ IS_OMAP_TYPE(3430, 0x3430) #if defined(CONFIG_SOC_DRA7XX) #undef soc_is_dra7xx +#undef soc_is_dra74x +#undef soc_is_dra72x #define soc_is_dra7xx() (of_machine_is_compatible("ti,dra7")) +#define soc_is_dra74x() (of_machine_is_compatible("ti,dra74")) +#define soc_is_dra72x() (of_machine_is_compatible("ti,dra72")) #endif /* Various silicon revisions for omap2 */ diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 17435c1aa2fe..126ddafad526 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -183,8 +183,8 @@ enum { static struct clk div4_clks[DIV4_NR] = { [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT), - [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT), - [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1de0, CLK_ENABLE_ON_INIT), + [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1df0, CLK_ENABLE_ON_INIT), + [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1df0, CLK_ENABLE_ON_INIT), }; /* DIV6 clocks */ diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index 10e193d707f5..453b23129cfa 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -152,7 +152,7 @@ enum { static struct clk div4_clks[DIV4_NR] = { [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT), - [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT), + [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1df0, CLK_ENABLE_ON_INIT), }; /* DIV6 clocks */ diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index d8c4048b9e33..02a6f45a0b9e 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -644,7 +644,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("e6cb0000.serial", &mstp_clks[MSTP207]), /* SCIFA5 */ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */ - CLKDEV_DEV_ID("0xe6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */ + CLKDEV_DEV_ID("e6c3000.serial", &mstp_clks[MSTP206]), /* SCIFB */ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), /* SCIFA0 */ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c index 2c2754e79cb3..f61158c6ce71 100644 --- a/arch/arm/mach-vexpress/spc.c +++ b/arch/arm/mach-vexpress/spc.c @@ -426,9 +426,15 @@ static int ve_spc_populate_opps(uint32_t cluster) static int ve_init_opp_table(struct device *cpu_dev) { - int cluster = topology_physical_package_id(cpu_dev->id); - int idx, ret = 0, max_opp = info->num_opps[cluster]; - struct ve_spc_opp *opps = info->opps[cluster]; + int cluster; + int idx, ret = 0, max_opp; + struct ve_spc_opp *opps; + + cluster = topology_physical_package_id(cpu_dev->id); + cluster = cluster < 0 ? 0 : cluster; + + max_opp = info->num_opps[cluster]; + opps = info->opps[cluster]; for (idx = 0; idx < max_opp; idx++, opps++) { ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt); @@ -537,6 +543,8 @@ static struct clk *ve_spc_clk_register(struct device *cpu_dev) spc->hw.init = &init; spc->cluster = topology_physical_package_id(cpu_dev->id); + spc->cluster = spc->cluster < 0 ? 0 : spc->cluster; + init.name = dev_name(cpu_dev); init.ops = &clk_spc_ops; init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE; diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 3815a8262af0..8c48c5c22a33 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -17,12 +17,6 @@ */ .align 5 ENTRY(v6_early_abort) -#ifdef CONFIG_CPU_V6 - sub r1, sp, #4 @ Get unused stack location - strex r0, r1, [r1] @ Clear the exclusive monitor -#elif defined(CONFIG_CPU_32v6K) - clrex -#endif mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR /* diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index 703375277ba6..4812ad054214 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S @@ -13,12 +13,6 @@ */ .align 5 ENTRY(v7_early_abort) - /* - * The effect of data aborts on on the exclusive access monitor are - * UNPREDICTABLE. Do a CLREX to clear the state - */ - clrex - mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index c294e67d3925..ae67e88c28b9 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -150,7 +150,6 @@ static void sha2_finup(struct shash_desc *desc, const u8 *data, kernel_neon_begin_partial(28); sha2_ce_transform(blocks, data, sctx->state, NULL, len); kernel_neon_end(); - data += blocks * SHA256_BLOCK_SIZE; } static int sha224_finup(struct shash_desc *desc, const u8 *data, diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h index d064047612b1..52b484b6aa1a 100644 --- a/arch/arm64/include/asm/hw_breakpoint.h +++ b/arch/arm64/include/asm/hw_breakpoint.h @@ -79,7 +79,6 @@ static inline void decode_ctrl_reg(u32 reg, */ #define ARM_MAX_BRP 16 #define ARM_MAX_WRP 16 -#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP) /* Virtual debug register bases. */ #define AARCH64_DBG_REG_BVR 0 diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 3df21feeabdd..286b1bec547c 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -139,7 +139,7 @@ extern struct task_struct *cpu_switch_to(struct task_struct *prev, ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) #define KSTK_EIP(tsk) ((unsigned long)task_pt_regs(tsk)->pc) -#define KSTK_ESP(tsk) ((unsigned long)task_pt_regs(tsk)->sp) +#define KSTK_ESP(tsk) user_stack_pointer(task_pt_regs(tsk)) /* * Prefetching support diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 501000fadb6f..41ed9e13795e 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -137,7 +137,7 @@ struct pt_regs { (!((regs)->pstate & PSR_F_BIT)) #define user_stack_pointer(regs) \ - (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp) + (!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp) static inline unsigned long regs_return_value(struct pt_regs *regs) { diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index ad8aebb1cdef..3dca15634e69 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -270,6 +270,7 @@ static int fpsimd_cpu_pm_notifier(struct notifier_block *self, case CPU_PM_ENTER: if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_save_state(¤t->thread.fpsimd_state); + this_cpu_write(fpsimd_last_state, NULL); break; case CPU_PM_EXIT: if (current->mm) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index bed028364a93..873069056229 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -373,10 +373,6 @@ ENTRY(__boot_cpu_mode) .long 0 .popsection - .align 3 -2: .quad . - .quad PAGE_OFFSET - #ifdef CONFIG_SMP .align 3 1: .quad . diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index 422ebd63b619..6762ad705587 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -24,6 +24,12 @@ u64 perf_reg_value(struct pt_regs *regs, int idx) return regs->compat_lr; } + if ((u32)idx == PERF_REG_ARM64_SP) + return regs->sp; + + if ((u32)idx == PERF_REG_ARM64_PC) + return regs->pc; + return regs->regs[idx]; } diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 70526cfda056..fe63ac5e9bf5 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -87,7 +87,8 @@ static void ptrace_hbptriggered(struct perf_event *bp, break; } } - for (i = ARM_MAX_BRP; i < ARM_MAX_HBP_SLOTS && !bp; ++i) { + + for (i = 0; i < ARM_MAX_WRP; ++i) { if (current->thread.debug.hbp_watch[i] == bp) { info.si_errno = -((i << 1) + 1); break; @@ -662,8 +663,10 @@ static int compat_gpr_get(struct task_struct *target, kbuf += sizeof(reg); } else { ret = copy_to_user(ubuf, ®, sizeof(reg)); - if (ret) + if (ret) { + ret = -EFAULT; break; + } ubuf += sizeof(reg); } @@ -701,8 +704,10 @@ static int compat_gpr_set(struct task_struct *target, kbuf += sizeof(reg); } else { ret = copy_from_user(®, ubuf, sizeof(reg)); - if (ret) - return ret; + if (ret) { + ret = -EFAULT; + break; + } ubuf += sizeof(reg); } diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index f6f0ccf35ae6..edb146d01857 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -78,6 +78,7 @@ unsigned int compat_elf_hwcap2 __read_mostly; #endif static const char *cpu_name; +static const char *machine_name; phys_addr_t __fdt_pointer __initdata; /* @@ -309,6 +310,8 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys) while (true) cpu_relax(); } + + machine_name = of_flat_dt_get_machine_name(); } /* @@ -447,21 +450,10 @@ static int c_show(struct seq_file *m, void *v) { int i; - /* - * Dump out the common processor features in a single line. Userspace - * should read the hwcaps with getauxval(AT_HWCAP) rather than - * attempting to parse this. - */ - seq_puts(m, "features\t:"); - for (i = 0; hwcap_str[i]; i++) - if (elf_hwcap & (1 << i)) - seq_printf(m, " %s", hwcap_str[i]); - seq_puts(m, "\n\n"); + seq_printf(m, "Processor\t: %s rev %d (%s)\n", + cpu_name, read_cpuid_id() & 15, ELF_PLATFORM); for_each_online_cpu(i) { - struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); - u32 midr = cpuinfo->reg_midr; - /* * glibc reads /proc/cpuinfo to determine the number of * online processors, looking for lines beginning with @@ -470,13 +462,25 @@ static int c_show(struct seq_file *m, void *v) #ifdef CONFIG_SMP seq_printf(m, "processor\t: %d\n", i); #endif - seq_printf(m, "implementer\t: 0x%02x\n", - MIDR_IMPLEMENTOR(midr)); - seq_printf(m, "variant\t\t: 0x%x\n", MIDR_VARIANT(midr)); - seq_printf(m, "partnum\t\t: 0x%03x\n", MIDR_PARTNUM(midr)); - seq_printf(m, "revision\t: 0x%x\n\n", MIDR_REVISION(midr)); } + /* dump out the processor features */ + seq_puts(m, "Features\t: "); + + for (i = 0; hwcap_str[i]; i++) + if (elf_hwcap & (1 << i)) + seq_printf(m, "%s ", hwcap_str[i]); + + seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24); + seq_printf(m, "CPU architecture: AArch64\n"); + seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15); + seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff); + seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15); + + seq_puts(m, "\n"); + + seq_printf(m, "Hardware\t: %s\n", machine_name); + return 0; } diff --git a/arch/hexagon/mm/cache.c b/arch/hexagon/mm/cache.c index fe14ccf28561..0c76c802e31c 100644 --- a/arch/hexagon/mm/cache.c +++ b/arch/hexagon/mm/cache.c @@ -68,6 +68,7 @@ void flush_icache_range(unsigned long start, unsigned long end) ); local_irq_restore(flags); } +EXPORT_SYMBOL(flush_icache_range); void hexagon_clean_dcache_range(unsigned long start, unsigned long end) { diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 64aefb76bd69..c84c88bbbbd7 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -549,8 +549,6 @@ source "drivers/sn/Kconfig" config KEXEC bool "kexec system call" depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU) - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 3ff8c9a25335..87b7c7581b1d 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -91,8 +91,6 @@ config MMU_SUN3 config KEXEC bool "kexec system call" depends on M68KCLASSIC - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index df51e78a72cc..900c7e5333b6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2396,8 +2396,6 @@ source "kernel/Kconfig.preempt" config KEXEC bool "Kexec system call" - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a577609f8ed6..4bc7b62fb4b6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -399,8 +399,6 @@ config PPC64_SUPPORTS_MEMORY_FAILURE config KEXEC bool "kexec system call" depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index ab39ceb89ecf..05c78bb5f570 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -48,8 +48,6 @@ config ARCH_SUPPORTS_DEBUG_PAGEALLOC config KEXEC def_bool y - select CRYPTO - select CRYPTO_SHA256 config AUDIT_ARCH def_bool y diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b319846ad97f..244fb4c81e25 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -598,8 +598,6 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on SUPERH32 && MMU - select CRYPTO - select CRYPTO_SHA256 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 097c2cdd117f..f770e3992620 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -229,6 +229,7 @@ void flush_icache_range(unsigned long start, unsigned long end) cacheop_on_each_cpu(local_flush_icache_range, (void *)&data, 1); } +EXPORT_SYMBOL(flush_icache_range); void flush_icache_page(struct vm_area_struct *vma, struct page *page) { diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index a3ffe2dd4832..7fcd492adbfc 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -191,8 +191,6 @@ source "kernel/Kconfig.hz" config KEXEC bool "kexec system call" - select CRYPTO - select CRYPTO_SHA256 ---help--- kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index 01e8ab29f43a..19eaa62d456a 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c @@ -183,6 +183,7 @@ void flush_icache_range(unsigned long start, unsigned long end) preempt_enable(); } } +EXPORT_SYMBOL(flush_icache_range); /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */ diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c index 780d77388dec..7c8fb7018dc6 100644 --- a/arch/unicore32/kernel/signal.c +++ b/arch/unicore32/kernel/signal.c @@ -254,7 +254,8 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, err |= setup_sigframe(frame, regs, set); if (err == 0) - err |= setup_return(regs, &ksig->ka, frame->retcode, frame, usig); + err |= setup_return(regs, &ksig->ka, frame->retcode, frame, + ksig->sig); return err; } @@ -276,7 +277,8 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp); err |= setup_sigframe(&frame->sig, regs, set); if (err == 0) - err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig); + err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame, + ksig->sig); if (err == 0) { /* @@ -303,7 +305,6 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall) { struct thread_info *thread = current_thread_info(); - struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = ksig->sig; int ret; @@ -373,7 +374,7 @@ static void do_signal(struct pt_regs *regs, int syscall) if (!user_mode(regs)) return; - if (get_signsl(&ksig)) { + if (get_signal(&ksig)) { handle_signal(&ksig, regs, syscall); return; } diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index 61b6d51866f8..3942f74c92d7 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -17,6 +17,4 @@ obj-$(CONFIG_IA32_EMULATION) += ia32/ obj-y += platform/ obj-y += net/ -ifeq ($(CONFIG_X86_64),y) -obj-$(CONFIG_KEXEC) += purgatory/ -endif +obj-$(CONFIG_KEXEC_FILE) += purgatory/ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5d0bf1aa9dcb..778178f4c7d1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1585,9 +1585,6 @@ source kernel/Kconfig.hz config KEXEC bool "kexec system call" - select BUILD_BIN2C - select CRYPTO - select CRYPTO_SHA256 ---help--- kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -1602,9 +1599,22 @@ config KEXEC interface is strongly in flux, so no good recommendation can be made. +config KEXEC_FILE + bool "kexec file based system call" + select BUILD_BIN2C + depends on KEXEC + depends on X86_64 + depends on CRYPTO=y + depends on CRYPTO_SHA256=y + ---help--- + This is new version of kexec system call. This system call is + file based and takes file descriptors as system call argument + for kernel and initramfs as opposed to list of segments as + accepted by previous system call. + config KEXEC_VERIFY_SIG bool "Verify kernel signature during kexec_file_load() syscall" - depends on KEXEC + depends on KEXEC_FILE ---help--- This option makes kernel signature verification mandatory for kexec_file_load() syscall. If kernel is signature can not be diff --git a/arch/x86/Makefile b/arch/x86/Makefile index c1aa36887843..60087ca37679 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -184,11 +184,8 @@ archheaders: $(Q)$(MAKE) $(build)=arch/x86/syscalls all archprepare: -ifeq ($(CONFIG_KEXEC),y) -# Build only for 64bit. No loaders for 32bit yet. - ifeq ($(CONFIG_X86_64),y) +ifeq ($(CONFIG_KEXEC_FILE),y) $(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c - endif endif ### @@ -254,6 +251,7 @@ archclean: $(Q)rm -rf $(objtree)/arch/x86_64 $(Q)$(MAKE) $(clean)=$(boot) $(Q)$(MAKE) $(clean)=arch/x86/tools + $(Q)$(MAKE) $(clean)=arch/x86/purgatory PHONY += kvmconfig kvmconfig: diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 0aeed5ca356e..478c490f3654 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -227,6 +227,8 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned extern void io_apic_eoi(unsigned int apic, unsigned int vector); +extern bool mp_should_keep_irq(struct device *dev); + #else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0 diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 0ec056012618..aa97a070f09f 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -131,8 +131,13 @@ static inline int pte_exec(pte_t pte) static inline int pte_special(pte_t pte) { - return (pte_flags(pte) & (_PAGE_PRESENT|_PAGE_SPECIAL)) == - (_PAGE_PRESENT|_PAGE_SPECIAL); + /* + * See CONFIG_NUMA_BALANCING pte_numa in include/asm-generic/pgtable.h. + * On x86 we have _PAGE_BIT_NUMA == _PAGE_BIT_GLOBAL+1 == + * __PAGE_BIT_SOFTW1 == _PAGE_BIT_SPECIAL. + */ + return (pte_flags(pte) & _PAGE_SPECIAL) && + (pte_flags(pte) & (_PAGE_PRESENT|_PAGE_PROTNONE)); } static inline unsigned long pte_pfn(pte_t pte) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index b5ea75c4a4b4..ada2e2d6be3e 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_X86_TSC) += trace_clock.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o +obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o obj-y += kprobes/ obj-$(CONFIG_MODULES) += module.o @@ -118,5 +119,4 @@ ifeq ($(CONFIG_X86_64),y) obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o obj-y += vsmp_64.o - obj-$(CONFIG_KEXEC) += kexec-bzimage64.o endif diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 29290f554e79..337ce5a9b15c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1070,6 +1070,11 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, } if (flags & IOAPIC_MAP_ALLOC) { + /* special handling for legacy IRQs */ + if (irq < nr_legacy_irqs() && info->count == 1 && + mp_irqdomain_map(domain, irq, pin) != 0) + irq = -1; + if (irq > 0) info->count++; else if (info->count == 0) @@ -3896,7 +3901,15 @@ int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq, info->polarity = 1; } info->node = NUMA_NO_NODE; - info->set = 1; + + /* + * setup_IO_APIC_irqs() programs all legacy IRQs with default + * trigger and polarity attributes. Don't set the flag for that + * case so the first legacy IRQ user could reprogram the pin + * with real trigger and polarity attributes. + */ + if (virq >= nr_legacy_irqs() || info->count) + info->set = 1; } set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger, info->polarity); @@ -3946,6 +3959,18 @@ int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node) return ret; } +bool mp_should_keep_irq(struct device *dev) +{ + if (dev->power.is_prepared) + return true; +#ifdef CONFIG_PM_RUNTIME + if (dev->power.runtime_status == RPM_SUSPENDING) + return true; +#endif + + return false; +} + /* Enable IOAPIC early just for system timer */ void __init pre_init_apic_IRQ0(void) { diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 0553a34fa0df..a618fcd2c07d 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -182,8 +182,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs) crash_save_cpu(regs, safe_smp_processor_id()); } -#ifdef CONFIG_X86_64 - +#ifdef CONFIG_KEXEC_FILE static int get_nr_ram_ranges_callback(unsigned long start_pfn, unsigned long nr_pfn, void *arg) { @@ -696,5 +695,4 @@ int crash_load_segments(struct kimage *image) return ret; } - -#endif /* CONFIG_X86_64 */ +#endif /* CONFIG_KEXEC_FILE */ diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 1e6cff5814fa..44f1ed42fdf2 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -203,7 +203,7 @@ void __init native_init_IRQ(void) set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); } - if (!acpi_ioapic && !of_ioapic) + if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) setup_irq(2, &irq2); #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 8b04018e5d1f..485981059a40 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -25,9 +25,11 @@ #include <asm/debugreg.h> #include <asm/kexec-bzimage64.h> +#ifdef CONFIG_KEXEC_FILE static struct kexec_file_ops *kexec_file_loaders[] = { &kexec_bzImage64_ops, }; +#endif static void free_transition_pgtable(struct kimage *image) { @@ -178,6 +180,7 @@ static void load_segments(void) ); } +#ifdef CONFIG_KEXEC_FILE /* Update purgatory as needed after various image segments have been prepared */ static int arch_update_purgatory(struct kimage *image) { @@ -209,6 +212,12 @@ static int arch_update_purgatory(struct kimage *image) return ret; } +#else /* !CONFIG_KEXEC_FILE */ +static inline int arch_update_purgatory(struct kimage *image) +{ + return 0; +} +#endif /* CONFIG_KEXEC_FILE */ int machine_kexec_prepare(struct kimage *image) { @@ -329,6 +338,7 @@ void arch_crash_save_vmcoreinfo(void) /* arch-dependent functionality related to kexec file-based syscall */ +#ifdef CONFIG_KEXEC_FILE int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len) { @@ -522,3 +532,4 @@ overflow: (int)ELF64_R_TYPE(rel[i].r_info), value); return -ENOEXEC; } +#endif /* CONFIG_KEXEC_FILE */ diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index bf7ef5ce29df..0fa29609b2c4 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -68,6 +68,8 @@ static struct irqaction irq0 = { void __init setup_default_timer_irq(void) { + if (!nr_legacy_irqs()) + return; setup_irq(0, &irq0); } diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index 3865116c51fb..b9958c364075 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c @@ -229,7 +229,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) static void intel_mid_pci_irq_disable(struct pci_dev *dev) { - if (!dev->dev.power.is_prepared && dev->irq > 0) + if (!mp_should_keep_irq(&dev->dev) && dev->irq > 0) mp_unmap_irq(dev->irq); } diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index bc1a2c341891..eb500c2592ad 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -1256,7 +1256,7 @@ static int pirq_enable_irq(struct pci_dev *dev) static void pirq_disable_irq(struct pci_dev *dev) { - if (io_apic_assign_pci_irqs && !dev->dev.power.is_prepared && + if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && dev->irq) { mp_unmap_irq(dev->irq); dev->irq = 0; diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 7fde9ee438a4..899dd2454256 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -11,6 +11,7 @@ targets += purgatory.ro # sure how to relocate those. Like kexec-tools, use custom flags. KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large +KBUILD_CFLAGS += -m$(BITS) $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE $(call if_changed,ld) @@ -24,7 +25,4 @@ $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE $(call if_changed,bin2c) -# No loaders for 32bits yet. -ifeq ($(CONFIG_X86_64),y) - obj-$(CONFIG_KEXEC) += kexec-purgatory.o -endif +obj-$(CONFIG_KEXEC_FILE) += kexec-purgatory.o diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3a617af60d46..49c6c3d94449 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -4,24 +4,23 @@ config ZONE_DMA config XTENSA def_bool y select ARCH_WANT_FRAME_POINTERS - select HAVE_IDE - select GENERIC_ATOMIC64 - select GENERIC_CLOCKEVENTS - select VIRT_TO_BUS - select GENERIC_IRQ_SHOW - select GENERIC_SCHED_CLOCK - select MODULES_USE_ELF_RELA - select GENERIC_PCI_IOMAP select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_OPTIONAL_GPIOLIB select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS - select IRQ_DOMAIN - select HAVE_OPROFILE + select COMMON_CLK + select GENERIC_ATOMIC64 + select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_SHOW + select GENERIC_PCI_IOMAP + select GENERIC_SCHED_CLOCK select HAVE_FUNCTION_TRACER select HAVE_IRQ_TIME_ACCOUNTING + select HAVE_OPROFILE select HAVE_PERF_EVENTS - select COMMON_CLK + select IRQ_DOMAIN + select MODULES_USE_ELF_RELA + select VIRT_TO_BUS help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both @@ -62,7 +61,9 @@ config TRACE_IRQFLAGS_SUPPORT def_bool y config MMU - def_bool n + bool + default n if !XTENSA_VARIANT_CUSTOM + default XTENSA_VARIANT_MMU if XTENSA_VARIANT_CUSTOM config VARIANT_IRQ_SWITCH def_bool n @@ -102,8 +103,40 @@ config XTENSA_VARIANT_S6000 select VARIANT_IRQ_SWITCH select ARCH_REQUIRE_GPIOLIB select XTENSA_CALIBRATE_CCOUNT + +config XTENSA_VARIANT_CUSTOM + bool "Custom Xtensa processor configuration" + select MAY_HAVE_SMP + select HAVE_XTENSA_GPIO32 + help + Select this variant to use a custom Xtensa processor configuration. + You will be prompted for a processor variant CORENAME. endchoice +config XTENSA_VARIANT_CUSTOM_NAME + string "Xtensa Processor Custom Core Variant Name" + depends on XTENSA_VARIANT_CUSTOM + help + Provide the name of a custom Xtensa processor variant. + This CORENAME selects arch/xtensa/variant/CORENAME. + Dont forget you have to select MMU if you have one. + +config XTENSA_VARIANT_NAME + string + default "dc232b" if XTENSA_VARIANT_DC232B + default "dc233c" if XTENSA_VARIANT_DC233C + default "fsf" if XTENSA_VARIANT_FSF + default "s6000" if XTENSA_VARIANT_S6000 + default XTENSA_VARIANT_CUSTOM_NAME if XTENSA_VARIANT_CUSTOM + +config XTENSA_VARIANT_MMU + bool "Core variant has a Full MMU (TLB, Pages, Protection, etc)" + depends on XTENSA_VARIANT_CUSTOM + default y + help + Build a Conventional Kernel with full MMU support, + ie: it supports a TLB with auto-loading, page protection. + config XTENSA_UNALIGNED_USER bool "Unaligned memory access in use space" help @@ -156,13 +189,9 @@ config HOTPLUG_CPU Say N if you want to disable CPU hotplug. -config MATH_EMULATION - bool "Math emulation" - help - Can we use information of configuration file? - config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX bool "Initialize Xtensa MMU inside the Linux kernel code" + depends on MMU default y help Earlier version initialized the MMU in the exception vector @@ -192,6 +221,7 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX config HIGHMEM bool "High Memory Support" + depends on MMU help Linux can use the full amount of RAM in the system by default. However, the default MMUv2 setup only maps the @@ -208,6 +238,32 @@ config HIGHMEM If unsure, say Y. +config FAST_SYSCALL_XTENSA + bool "Enable fast atomic syscalls" + default n + help + fast_syscall_xtensa is a syscall that can make atomic operations + on UP kernel when processor has no s32c1i support. + + This syscall is deprecated. It may have issues when called with + invalid arguments. It is provided only for backwards compatibility. + Only enable it if your userspace software requires it. + + If unsure, say N. + +config FAST_SYSCALL_SPILL_REGISTERS + bool "Enable spill registers syscall" + default n + help + fast_syscall_spill_registers is a syscall that spills all active + register windows of a calling userspace task onto its stack. + + This syscall is deprecated. It may have issues when called with + invalid arguments. It is provided only for backwards compatibility. + Only enable it if your userspace software requires it. + + If unsure, say N. + endmenu config XTENSA_CALIBRATE_CCOUNT @@ -250,12 +306,14 @@ config XTENSA_PLATFORM_ISS config XTENSA_PLATFORM_XT2000 bool "XT2000" + select HAVE_IDE help XT2000 is the name of Tensilica's feature-rich emulation platform. This hardware is capable of running a full Linux distribution. config XTENSA_PLATFORM_S6105 bool "S6105" + select HAVE_IDE select SERIAL_CONSOLE select NO_IOPORT_MAP diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 81250ece3062..472533064b46 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -4,6 +4,7 @@ # for more details. # # Copyright (C) 2001 - 2005 Tensilica Inc. +# Copyright (C) 2014 Cadence Design Systems Inc. # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -13,11 +14,7 @@ # Core configuration. # (Use VAR=<xtensa_config> to use another default compiler.) -variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf -variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b -variant-$(CONFIG_XTENSA_VARIANT_DC233C) := dc233c -variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000 -variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom +variant-y := $(patsubst "%",%,$(CONFIG_XTENSA_VARIANT_NAME)) VARIANT = $(variant-y) export VARIANT diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts index 742a347be67a..c4d17a34ab86 100644 --- a/arch/xtensa/boot/dts/kc705.dts +++ b/arch/xtensa/boot/dts/kc705.dts @@ -4,8 +4,11 @@ / { compatible = "cdns,xtensa-kc705"; + chosen { + bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000"; + }; memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000>; + reg = <0x00000000 0x38000000>; }; }; diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig index f6000fe05119..721df1214bc3 100644 --- a/arch/xtensa/configs/common_defconfig +++ b/arch/xtensa/configs/common_defconfig @@ -66,7 +66,6 @@ CONFIG_XTENSA_ARCH_LINUX_BE=y CONFIG_MMU=y # CONFIG_XTENSA_UNALIGNED_USER is not set # CONFIG_PREEMPT is not set -# CONFIG_MATH_EMULATION is not set # CONFIG_HIGHMEM is not set # diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index 1493c68352d1..b966baf82cae 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig @@ -146,7 +146,6 @@ CONFIG_XTENSA_VARIANT_FSF=y # CONFIG_XTENSA_VARIANT_S6000 is not set # CONFIG_XTENSA_UNALIGNED_USER is not set # CONFIG_PREEMPT is not set -# CONFIG_MATH_EMULATION is not set CONFIG_XTENSA_CALIBRATE_CCOUNT=y CONFIG_SERIAL_CONSOLE=y CONFIG_XTENSA_ISS_NETWORK=y @@ -308,7 +307,7 @@ CONFIG_MISC_DEVICES=y # EEPROM support # # CONFIG_EEPROM_93CX6 is not set -CONFIG_HAVE_IDE=y +# CONFIG_HAVE_IDE is not set # CONFIG_IDE is not set # diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig index 12a492ab6d17..9471265b8ca6 100644 --- a/arch/xtensa/configs/s6105_defconfig +++ b/arch/xtensa/configs/s6105_defconfig @@ -109,7 +109,6 @@ CONFIG_VARIANT_IRQ_SWITCH=y CONFIG_XTENSA_VARIANT_S6000=y # CONFIG_XTENSA_UNALIGNED_USER is not set CONFIG_PREEMPT=y -# CONFIG_MATH_EMULATION is not set # CONFIG_HIGHMEM is not set CONFIG_XTENSA_CALIBRATE_CCOUNT=y CONFIG_SERIAL_CONSOLE=y diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 555a98a18453..e72aaca7a77f 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -37,6 +37,7 @@ * specials for cache aliasing: * * __flush_invalidate_dcache_page_alias(vaddr,paddr) + * __invalidate_dcache_page_alias(vaddr,paddr) * __invalidate_icache_page_alias(vaddr,paddr) */ @@ -62,6 +63,7 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long); #if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); +extern void __invalidate_dcache_page_alias(unsigned long, unsigned long); #else static inline void __flush_invalidate_dcache_page_alias(unsigned long virt, unsigned long phys) { } diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h index 9f6c33d0428a..62b507deea9d 100644 --- a/arch/xtensa/include/asm/fixmap.h +++ b/arch/xtensa/include/asm/fixmap.h @@ -23,8 +23,8 @@ * Here we define all the compile-time 'special' virtual * addresses. The point is to have a constant address at * compile time, but to set the physical address only - * in the boot process. We allocate these special addresses - * from the end of the consistent memory region backwards. + * in the boot process. We allocate these special addresses + * from the start of the consistent memory region upwards. * Also this lets us do fail-safe vmalloc(), we * can guarantee that these special addresses and * vmalloc()-ed addresses never overlap. @@ -38,7 +38,8 @@ enum fixed_addresses { #ifdef CONFIG_HIGHMEM /* reserved pte's for temporary kernel mappings */ FIX_KMAP_BEGIN, - FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, + FIX_KMAP_END = FIX_KMAP_BEGIN + + (KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1, #endif __end_of_fixed_addresses }; @@ -47,7 +48,28 @@ enum fixed_addresses { #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) -#include <asm-generic/fixmap.h> +#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) +#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) + +#ifndef __ASSEMBLY__ +/* + * 'index to address' translation. If anyone tries to use the idx + * directly without translation, we catch the bug with a NULL-deference + * kernel oops. Illegal ranges of incoming indices are caught too. + */ +static __always_inline unsigned long fix_to_virt(const unsigned int idx) +{ + BUILD_BUG_ON(idx >= __end_of_fixed_addresses); + return __fix_to_virt(idx); +} + +static inline unsigned long virt_to_fix(const unsigned long vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + return __virt_to_fix(vaddr); +} + +#endif #define kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel( \ diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 2653ef5d55f1..2c7901edffaf 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h @@ -12,19 +12,55 @@ #ifndef _XTENSA_HIGHMEM_H #define _XTENSA_HIGHMEM_H +#include <linux/wait.h> #include <asm/cacheflush.h> #include <asm/fixmap.h> #include <asm/kmap_types.h> #include <asm/pgtable.h> -#define PKMAP_BASE (FIXADDR_START - PMD_SIZE) -#define LAST_PKMAP PTRS_PER_PTE +#define PKMAP_BASE ((FIXADDR_START - \ + (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK) +#define LAST_PKMAP (PTRS_PER_PTE * DCACHE_N_COLORS) #define LAST_PKMAP_MASK (LAST_PKMAP - 1) #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) #define kmap_prot PAGE_KERNEL +#if DCACHE_WAY_SIZE > PAGE_SIZE +#define get_pkmap_color get_pkmap_color +static inline int get_pkmap_color(struct page *page) +{ + return DCACHE_ALIAS(page_to_phys(page)); +} + +extern unsigned int last_pkmap_nr_arr[]; + +static inline unsigned int get_next_pkmap_nr(unsigned int color) +{ + last_pkmap_nr_arr[color] = + (last_pkmap_nr_arr[color] + DCACHE_N_COLORS) & LAST_PKMAP_MASK; + return last_pkmap_nr_arr[color] + color; +} + +static inline int no_more_pkmaps(unsigned int pkmap_nr, unsigned int color) +{ + return pkmap_nr < DCACHE_N_COLORS; +} + +static inline int get_pkmap_entries_count(unsigned int color) +{ + return LAST_PKMAP / DCACHE_N_COLORS; +} + +extern wait_queue_head_t pkmap_map_wait_arr[]; + +static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) +{ + return pkmap_map_wait_arr + color; +} +#endif + extern pte_t *pkmap_page_table; void *kmap_high(struct page *page); diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 47f582333f6b..abe24c6f8b2f 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -78,7 +78,9 @@ # define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) #else # define DCACHE_ALIAS_ORDER 0 +# define DCACHE_ALIAS(a) ((void)(a), 0) #endif +#define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER) #if ICACHE_WAY_SIZE > PAGE_SIZE # define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT) @@ -134,6 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size) #endif struct page; +struct vm_area_struct; extern void clear_page(void *page); extern void copy_page(void *to, void *from); @@ -143,8 +146,15 @@ extern void copy_page(void *to, void *from); */ #if DCACHE_WAY_SIZE > PAGE_SIZE -extern void clear_user_page(void*, unsigned long, struct page*); -extern void copy_user_page(void*, void*, unsigned long, struct page*); +extern void clear_page_alias(void *vaddr, unsigned long paddr); +extern void copy_page_alias(void *to, void *from, + unsigned long to_paddr, unsigned long from_paddr); + +#define clear_user_highpage clear_user_highpage +void clear_user_highpage(struct page *page, unsigned long vaddr); +#define __HAVE_ARCH_COPY_USER_HIGHPAGE +void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma); #else # define clear_user_page(page, vaddr, pg) clear_page(page) # define copy_user_page(to, from, vaddr, pg) copy_page(to, from) diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 4b0ca35a93b1..b2173e5da601 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -67,7 +67,12 @@ #define VMALLOC_START 0xC0000000 #define VMALLOC_END 0xC7FEFFFF #define TLBTEMP_BASE_1 0xC7FF0000 -#define TLBTEMP_BASE_2 0xC7FF8000 +#define TLBTEMP_BASE_2 (TLBTEMP_BASE_1 + DCACHE_WAY_SIZE) +#if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE +#define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE) +#else +#define TLBTEMP_SIZE ICACHE_WAY_SIZE +#endif /* * For the Xtensa architecture, the PTE layout is as follows: diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index fd686dc45d1a..c7211e7e182d 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -52,7 +52,12 @@ */ .macro get_fs ad, sp GET_CURRENT(\ad,\sp) +#if THREAD_CURRENT_DS > 1020 + addi \ad, \ad, TASK_THREAD + l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD +#else l32i \ad, \ad, THREAD_CURRENT_DS +#endif .endm /* diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h index b4cb1100c0fb..a47909f0c34b 100644 --- a/arch/xtensa/include/uapi/asm/ioctls.h +++ b/arch/xtensa/include/uapi/asm/ioctls.h @@ -28,17 +28,17 @@ #define TCSETSW 0x5403 #define TCSETSF 0x5404 -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) +#define TCGETA 0x80127417 /* _IOR('t', 23, struct termio) */ +#define TCSETA 0x40127418 /* _IOW('t', 24, struct termio) */ +#define TCSETAW 0x40127419 /* _IOW('t', 25, struct termio) */ +#define TCSETAF 0x4012741C /* _IOW('t', 28, struct termio) */ #define TCSBRK _IO('t', 29) #define TCXONC _IO('t', 30) #define TCFLSH _IO('t', 31) -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSWINSZ 0x40087467 /* _IOW('t', 103, struct winsize) */ +#define TIOCGWINSZ 0x80087468 /* _IOR('t', 104, struct winsize) */ #define TIOCSTART _IO('t', 110) /* start output, like ^Q */ #define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ #define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ @@ -88,7 +88,6 @@ #define TIOCSETD _IOW('T', 35, int) #define TIOCGETD _IOR('T', 36, int) #define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/ -#define TIOCTTYGSTRUCT _IOR('T', 38, struct tty_struct) /* For debugging only*/ #define TIOCSBRK _IO('T', 39) /* BSD compatibility */ #define TIOCCBRK _IO('T', 40) /* BSD compatibility */ #define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/ @@ -114,8 +113,10 @@ #define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ # define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config */ -#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ +#define TIOCSERGETMULTI 0x80a8545a /* Get multiport config */ + /* _IOR('T', 90, struct serial_multiport_struct) */ +#define TIOCSERSETMULTI 0x40a8545b /* Set multiport config */ + /* _IOW('T', 91, struct serial_multiport_struct) */ #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index b9395529f02d..8883fc877c5c 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -739,7 +739,10 @@ __SYSCALL(334, sys_sched_setattr, 2) #define __NR_sched_getattr 335 __SYSCALL(335, sys_sched_getattr, 3) -#define __NR_syscall_count 336 +#define __NR_renameat2 336 +__SYSCALL(336, sys_renameat2, 5) + +#define __NR_syscall_count 337 /* * sysxtensa syscall handler diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index d4cef6039a5c..890004af03a9 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -8,6 +8,7 @@ * this archive for more details. * * Copyright (C) 2001 - 2005 Tensilica, Inc. + * Copyright (C) 2014 Cadence Design Systems Inc. * * Rewritten by Chris Zankel <chris@zankel.net> * @@ -174,6 +175,10 @@ ENTRY(fast_unaligned) s32i a0, a2, PT_AREG2 s32i a3, a2, PT_AREG3 + rsr a3, excsave1 + movi a4, fast_unaligned_fixup + s32i a4, a3, EXC_TABLE_FIXUP + /* Keep value of SAR in a0 */ rsr a0, sar @@ -225,10 +230,6 @@ ENTRY(fast_unaligned) addx8 a5, a6, a5 jx a5 # jump into table - /* Invalid instruction, CRITICAL! */ -.Linvalid_instruction_load: - j .Linvalid_instruction - /* Load: Load memory address. */ .Lload: movi a3, ~3 @@ -272,18 +273,6 @@ ENTRY(fast_unaligned) /* Set target register. */ 1: - -#if XCHAL_HAVE_LOOPS - rsr a5, lend # check if we reached LEND - bne a7, a5, 1f - rsr a5, lcount # and LCOUNT != 0 - beqz a5, 1f - addi a5, a5, -1 # decrement LCOUNT and set - rsr a7, lbeg # set PC to LBEGIN - wsr a5, lcount -#endif - -1: wsr a7, epc1 # skip load instruction extui a4, a4, INSN_T, 4 # extract target register movi a5, .Lload_table addx8 a4, a4, a5 @@ -326,6 +315,35 @@ ENTRY(fast_unaligned) mov a3, a14 ; _j 1f; .align 8 mov a3, a15 ; _j 1f; .align 8 + /* We cannot handle this exception. */ + + .extern _kernel_exception +.Linvalid_instruction_load: +.Linvalid_instruction_store: + + movi a4, 0 + rsr a3, excsave1 + s32i a4, a3, EXC_TABLE_FIXUP + + /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ + + l32i a8, a2, PT_AREG8 + l32i a7, a2, PT_AREG7 + l32i a6, a2, PT_AREG6 + l32i a5, a2, PT_AREG5 + l32i a4, a2, PT_AREG4 + wsr a0, sar + mov a1, a2 + + rsr a0, ps + bbsi.l a0, PS_UM_BIT, 2f # jump if user mode + + movi a0, _kernel_exception + jx a0 + +2: movi a0, _user_exception + jx a0 + 1: # a7: instruction pointer, a4: instruction, a3: value movi a6, 0 # mask: ffffffff:00000000 @@ -353,17 +371,6 @@ ENTRY(fast_unaligned) /* Get memory address */ 1: -#if XCHAL_HAVE_LOOPS - rsr a4, lend # check if we reached LEND - bne a7, a4, 1f - rsr a4, lcount # and LCOUNT != 0 - beqz a4, 1f - addi a4, a4, -1 # decrement LCOUNT and set - rsr a7, lbeg # set PC to LBEGIN - wsr a4, lcount -#endif - -1: wsr a7, epc1 # skip store instruction movi a4, ~3 and a4, a4, a8 # align memory address @@ -375,25 +382,25 @@ ENTRY(fast_unaligned) #endif __ssa8r a8 - __src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) + __src_b a8, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE) #ifdef UNALIGNED_USER_EXCEPTION l32e a5, a4, -8 #else l32i a5, a4, 0 # load lower address word #endif - and a5, a5, a7 # mask - __sh a7, a3 # shift value - or a5, a5, a7 # or with original value + and a5, a5, a8 # mask + __sh a8, a3 # shift value + or a5, a5, a8 # or with original value #ifdef UNALIGNED_USER_EXCEPTION s32e a5, a4, -8 - l32e a7, a4, -4 + l32e a8, a4, -4 #else s32i a5, a4, 0 # store - l32i a7, a4, 4 # same for upper address word + l32i a8, a4, 4 # same for upper address word #endif __sl a5, a3 - and a6, a7, a6 + and a6, a8, a6 or a6, a6, a5 #ifdef UNALIGNED_USER_EXCEPTION s32e a6, a4, -4 @@ -401,9 +408,27 @@ ENTRY(fast_unaligned) s32i a6, a4, 4 #endif - /* Done. restore stack and return */ - .Lexit: +#if XCHAL_HAVE_LOOPS + rsr a4, lend # check if we reached LEND + bne a7, a4, 1f + rsr a4, lcount # and LCOUNT != 0 + beqz a4, 1f + addi a4, a4, -1 # decrement LCOUNT and set + rsr a7, lbeg # set PC to LBEGIN + wsr a4, lcount +#endif + +1: wsr a7, epc1 # skip emulated instruction + + /* Update icount if we're single-stepping in userspace. */ + rsr a4, icountlevel + beqz a4, 1f + bgeui a4, LOCKLEVEL + 1, 1f + rsr a4, icount + addi a4, a4, 1 + wsr a4, icount +1: movi a4, 0 rsr a3, excsave1 s32i a4, a3, EXC_TABLE_FIXUP @@ -424,31 +449,40 @@ ENTRY(fast_unaligned) l32i a2, a2, PT_AREG2 rfe - /* We cannot handle this exception. */ +ENDPROC(fast_unaligned) - .extern _kernel_exception -.Linvalid_instruction_store: -.Linvalid_instruction: +ENTRY(fast_unaligned_fixup) - /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ + l32i a2, a3, EXC_TABLE_DOUBLE_SAVE + wsr a3, excsave1 l32i a8, a2, PT_AREG8 l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 l32i a5, a2, PT_AREG5 l32i a4, a2, PT_AREG4 + l32i a0, a2, PT_AREG2 + xsr a0, depc # restore depc and a0 wsr a0, sar - mov a1, a2 + + rsr a0, exccause + s32i a0, a2, PT_DEPC # mark as a regular exception rsr a0, ps - bbsi.l a2, PS_UM_BIT, 1f # jump if user mode + bbsi.l a0, PS_UM_BIT, 1f # jump if user mode - movi a0, _kernel_exception + rsr a0, exccause + addx4 a0, a0, a3 # find entry in table + l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler + l32i a3, a2, PT_AREG3 jx a0 - -1: movi a0, _user_exception +1: + rsr a0, exccause + addx4 a0, a0, a3 # find entry in table + l32i a0, a0, EXC_TABLE_FAST_USER # load handler + l32i a3, a2, PT_AREG3 jx a0 -ENDPROC(fast_unaligned) +ENDPROC(fast_unaligned_fixup) #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index ef7f4990722b..82bbfa5a05b3 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -986,6 +986,8 @@ ENDPROC(fast_syscall_unrecoverable) * j done */ +#ifdef CONFIG_FAST_SYSCALL_XTENSA + #define TRY \ .section __ex_table, "a"; \ .word 66f, 67f; \ @@ -1001,9 +1003,8 @@ ENTRY(fast_syscall_xtensa) movi a7, 4 # sizeof(unsigned int) access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp - addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 - _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill - _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp + _bgeui a6, SYS_XTENSA_COUNT, .Lill + _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP, .Lnswp /* Fall through for ATOMIC_CMP_SWP. */ @@ -1015,27 +1016,26 @@ TRY s32i a5, a3, 0 # different, modify value l32i a7, a2, PT_AREG7 # restore a7 l32i a0, a2, PT_AREG0 # restore a0 movi a2, 1 # and return 1 - addi a6, a6, 1 # restore a6 (really necessary?) rfe 1: l32i a7, a2, PT_AREG7 # restore a7 l32i a0, a2, PT_AREG0 # restore a0 movi a2, 0 # return 0 (note that we cannot set - addi a6, a6, 1 # restore a6 (really necessary?) rfe .Lnswp: /* Atomic set, add, and exg_add. */ TRY l32i a7, a3, 0 # orig + addi a6, a6, -SYS_XTENSA_ATOMIC_SET add a0, a4, a7 # + arg moveqz a0, a4, a6 # set + addi a6, a6, SYS_XTENSA_ATOMIC_SET TRY s32i a0, a3, 0 # write new value mov a0, a2 mov a2, a7 l32i a7, a0, PT_AREG7 # restore a7 l32i a0, a0, PT_AREG0 # restore a0 - addi a6, a6, 1 # restore a6 (really necessary?) rfe CATCH @@ -1044,13 +1044,25 @@ CATCH movi a2, -EFAULT rfe -.Lill: l32i a7, a2, PT_AREG0 # restore a7 +.Lill: l32i a7, a2, PT_AREG7 # restore a7 l32i a0, a2, PT_AREG0 # restore a0 movi a2, -EINVAL rfe ENDPROC(fast_syscall_xtensa) +#else /* CONFIG_FAST_SYSCALL_XTENSA */ + +ENTRY(fast_syscall_xtensa) + + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -ENOSYS + rfe + +ENDPROC(fast_syscall_xtensa) + +#endif /* CONFIG_FAST_SYSCALL_XTENSA */ + /* fast_syscall_spill_registers. * @@ -1066,6 +1078,8 @@ ENDPROC(fast_syscall_xtensa) * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. */ +#ifdef CONFIG_FAST_SYSCALL_SPILL_REGISTERS + ENTRY(fast_syscall_spill_registers) /* Register a FIXUP handler (pass current wb as a parameter) */ @@ -1400,6 +1414,18 @@ ENTRY(fast_syscall_spill_registers_fixup_return) ENDPROC(fast_syscall_spill_registers_fixup_return) +#else /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */ + +ENTRY(fast_syscall_spill_registers) + + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -ENOSYS + rfe + +ENDPROC(fast_syscall_spill_registers) + +#endif /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */ + #ifdef CONFIG_MMU /* * We should never get here. Bail out! @@ -1565,7 +1591,7 @@ ENTRY(fast_second_level_miss) rsr a0, excvaddr bltu a0, a3, 2f - addi a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT)) + addi a1, a0, -TLBTEMP_SIZE bgeu a1, a3, 2f /* Check if we have to restore an ITLB mapping. */ @@ -1820,7 +1846,6 @@ ENTRY(_switch_to) entry a1, 16 - mov a10, a2 # preserve 'prev' (a2) mov a11, a3 # and 'next' (a3) l32i a4, a2, TASK_THREAD_INFO @@ -1828,8 +1853,14 @@ ENTRY(_switch_to) save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER - s32i a0, a10, THREAD_RA # save return address - s32i a1, a10, THREAD_SP # save stack pointer +#if THREAD_RA > 1020 || THREAD_SP > 1020 + addi a10, a2, TASK_THREAD + s32i a0, a10, THREAD_RA - TASK_THREAD # save return address + s32i a1, a10, THREAD_SP - TASK_THREAD # save stack pointer +#else + s32i a0, a2, THREAD_RA # save return address + s32i a1, a2, THREAD_SP # save stack pointer +#endif /* Disable ints while we manipulate the stack pointer. */ @@ -1870,7 +1901,6 @@ ENTRY(_switch_to) load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER wsr a14, ps - mov a2, a10 # return 'prev' rsync retw diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 2d9cc6dbfd78..e8b76b8e4b29 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -49,9 +49,8 @@ dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag) /* We currently don't support coherent memory outside KSEG */ - if (ret < XCHAL_KSEG_CACHED_VADDR - || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) - BUG(); + BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR || + ret > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1); if (ret != 0) { @@ -68,10 +67,11 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; + unsigned long addr = (unsigned long)vaddr + + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; - if (addr < 0 || addr >= XCHAL_KSEG_SIZE) - BUG(); + BUG_ON(addr < XCHAL_KSEG_CACHED_VADDR || + addr > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1); free_pages(addr, get_order(size)); } diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index 40b5a3771fb0..4d02e38514f5 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -571,6 +571,7 @@ void flush_icache_range(unsigned long start, unsigned long end) }; on_each_cpu(ipi_flush_icache_range, &fd, 1); } +EXPORT_SYMBOL(flush_icache_range); /* ------------------------------------------------------------------------- */ diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index eebbfd8c26fc..9d2f45f010ef 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -101,9 +101,8 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = { #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION #ifdef CONFIG_XTENSA_UNALIGNED_USER { EXCCAUSE_UNALIGNED, USER, fast_unaligned }, -#else -{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, #endif +{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, { EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, #endif #ifdef CONFIG_MMU @@ -264,7 +263,6 @@ do_illegal_instruction(struct pt_regs *regs) */ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION -#ifndef CONFIG_XTENSA_UNALIGNED_USER void do_unaligned_user (struct pt_regs *regs) { @@ -286,7 +284,6 @@ do_unaligned_user (struct pt_regs *regs) } #endif -#endif void do_debug(struct pt_regs *regs) diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 8453e6e39895..1b397a902292 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -454,8 +454,14 @@ _DoubleExceptionVector_WindowOverflow: s32i a0, a2, PT_DEPC _DoubleExceptionVector_handle_exception: + addi a0, a0, -EXCCAUSE_UNALIGNED + beqz a0, 2f addx4 a0, a0, a3 - l32i a0, a0, EXC_TABLE_FAST_USER + l32i a0, a0, EXC_TABLE_FAST_USER + 4 * EXCCAUSE_UNALIGNED + xsr a3, excsave1 + jx a0 +2: + movi a0, user_exception xsr a3, excsave1 jx a0 diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index d16db6df86f8..fc1bc2ba8d5d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -269,13 +269,13 @@ SECTIONS .UserExceptionVector.literal) SECTION_VECTOR (_DoubleExceptionVector_literal, .DoubleExceptionVector.literal, - DOUBLEEXC_VECTOR_VADDR - 40, + DOUBLEEXC_VECTOR_VADDR - 48, SIZEOF(.UserExceptionVector.text), .UserExceptionVector.text) SECTION_VECTOR (_DoubleExceptionVector_text, .DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR, - 40, + 48, .DoubleExceptionVector.literal) . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 63cbb867dadd..d75aa1476da7 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -59,9 +59,68 @@ * */ -#if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) -#error "HIGHMEM is not supported on cores with aliasing cache." -#endif +#if (DCACHE_WAY_SIZE > PAGE_SIZE) +static inline void kmap_invalidate_coherent(struct page *page, + unsigned long vaddr) +{ + if (!DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) { + unsigned long kvaddr; + + if (!PageHighMem(page)) { + kvaddr = (unsigned long)page_to_virt(page); + + __invalidate_dcache_page(kvaddr); + } else { + kvaddr = TLBTEMP_BASE_1 + + (page_to_phys(page) & DCACHE_ALIAS_MASK); + + __invalidate_dcache_page_alias(kvaddr, + page_to_phys(page)); + } + } +} + +static inline void *coherent_kvaddr(struct page *page, unsigned long base, + unsigned long vaddr, unsigned long *paddr) +{ + if (PageHighMem(page) || !DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) { + *paddr = page_to_phys(page); + return (void *)(base + (vaddr & DCACHE_ALIAS_MASK)); + } else { + *paddr = 0; + return page_to_virt(page); + } +} + +void clear_user_highpage(struct page *page, unsigned long vaddr) +{ + unsigned long paddr; + void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr); + + pagefault_disable(); + kmap_invalidate_coherent(page, vaddr); + set_bit(PG_arch_1, &page->flags); + clear_page_alias(kvaddr, paddr); + pagefault_enable(); +} + +void copy_user_highpage(struct page *dst, struct page *src, + unsigned long vaddr, struct vm_area_struct *vma) +{ + unsigned long dst_paddr, src_paddr; + void *dst_vaddr = coherent_kvaddr(dst, TLBTEMP_BASE_1, vaddr, + &dst_paddr); + void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr, + &src_paddr); + + pagefault_disable(); + kmap_invalidate_coherent(dst, vaddr); + set_bit(PG_arch_1, &dst->flags); + copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr); + pagefault_enable(); +} + +#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */ #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK @@ -103,7 +162,8 @@ void flush_dcache_page(struct page *page) if (!alias && !mapping) return; - __flush_invalidate_dcache_page((long)page_address(page)); + virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(virt, phys); virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK); @@ -168,13 +228,12 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { - - unsigned long paddr = (unsigned long) page_address(page); unsigned long phys = page_to_phys(page); - unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); - - __flush_invalidate_dcache_page(paddr); + unsigned long tmp; + tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(tmp, phys); + tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); __flush_invalidate_dcache_page_alias(tmp, phys); __invalidate_icache_page_alias(tmp, phys); diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c index 17a8c0d6fd17..8cfb71ec0937 100644 --- a/arch/xtensa/mm/highmem.c +++ b/arch/xtensa/mm/highmem.c @@ -14,23 +14,45 @@ static pte_t *kmap_pte; +#if DCACHE_WAY_SIZE > PAGE_SIZE +unsigned int last_pkmap_nr_arr[DCACHE_N_COLORS]; +wait_queue_head_t pkmap_map_wait_arr[DCACHE_N_COLORS]; + +static void __init kmap_waitqueues_init(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i) + init_waitqueue_head(pkmap_map_wait_arr + i); +} +#else +static inline void kmap_waitqueues_init(void) +{ +} +#endif + +static inline enum fixed_addresses kmap_idx(int type, unsigned long color) +{ + return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS + + color; +} + void *kmap_atomic(struct page *page) { enum fixed_addresses idx; unsigned long vaddr; - int type; pagefault_disable(); if (!PageHighMem(page)) return page_address(page); - type = kmap_atomic_idx_push(); - idx = type + KM_TYPE_NR * smp_processor_id(); + idx = kmap_idx(kmap_atomic_idx_push(), + DCACHE_ALIAS(page_to_phys(page))); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(kmap_pte - idx))); + BUG_ON(!pte_none(*(kmap_pte + idx))); #endif - set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); + set_pte(kmap_pte + idx, mk_pte(page, PAGE_KERNEL_EXEC)); return (void *)vaddr; } @@ -38,12 +60,10 @@ EXPORT_SYMBOL(kmap_atomic); void __kunmap_atomic(void *kvaddr) { - int idx, type; - if (kvaddr >= (void *)FIXADDR_START && kvaddr < (void *)FIXADDR_TOP) { - type = kmap_atomic_idx(); - idx = type + KM_TYPE_NR * smp_processor_id(); + int idx = kmap_idx(kmap_atomic_idx(), + DCACHE_ALIAS((unsigned long)kvaddr)); /* * Force other mappings to Oops if they'll try to access this @@ -51,7 +71,7 @@ void __kunmap_atomic(void *kvaddr) * is a bad idea also, in case the page changes cacheability * attributes or becomes a protected page in a hypervisor. */ - pte_clear(&init_mm, kvaddr, kmap_pte - idx); + pte_clear(&init_mm, kvaddr, kmap_pte + idx); local_flush_tlb_kernel_range((unsigned long)kvaddr, (unsigned long)kvaddr + PAGE_SIZE); @@ -69,4 +89,5 @@ void __init kmap_init(void) /* cache the first kmap pte */ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); kmap_pte = kmap_get_fixmap_pte(kmap_vstart); + kmap_waitqueues_init(); } diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index 1f68558dbcc2..11a01c3e9cea 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -110,41 +110,24 @@ ENTRY(__tlbtemp_mapping_start) #if (DCACHE_WAY_SIZE > PAGE_SIZE) /* - * clear_user_page (void *addr, unsigned long vaddr, struct page *page) - * a2 a3 a4 + * clear_page_alias(void *addr, unsigned long paddr) + * a2 a3 */ -ENTRY(clear_user_page) +ENTRY(clear_page_alias) entry a1, 32 - /* Mark page dirty and determine alias. */ + /* Skip setting up a temporary DTLB if not aliased low page. */ - movi a7, (1 << PG_ARCH_1) - l32i a5, a4, PAGE_FLAGS - xor a6, a2, a3 - extui a3, a3, PAGE_SHIFT, DCACHE_ALIAS_ORDER - extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER - or a5, a5, a7 - slli a3, a3, PAGE_SHIFT - s32i a5, a4, PAGE_FLAGS + movi a5, PAGE_OFFSET + movi a6, 0 + beqz a3, 1f - /* Skip setting up a temporary DTLB if not aliased. */ - - beqz a6, 1f - - /* Invalidate kernel page. */ - - mov a10, a2 - call8 __invalidate_dcache_page - - /* Setup a temporary DTLB with the color of the VPN */ - - movi a4, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff - movi a5, TLBTEMP_BASE_1 # virt - add a6, a2, a4 # ppn - add a2, a5, a3 # add 'color' + /* Setup a temporary DTLB for the addr. */ + addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) + mov a4, a2 wdtlb a6, a2 dsync @@ -165,62 +148,43 @@ ENTRY(clear_user_page) /* We need to invalidate the temporary idtlb entry, if any. */ -1: addi a2, a2, -PAGE_SIZE - idtlb a2 +1: idtlb a4 dsync retw -ENDPROC(clear_user_page) +ENDPROC(clear_page_alias) /* - * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) - * a2 a3 a4 a5 + * copy_page_alias(void *to, void *from, + * a2 a3 + * unsigned long to_paddr, unsigned long from_paddr) + * a4 a5 */ -ENTRY(copy_user_page) +ENTRY(copy_page_alias) entry a1, 32 - /* Mark page dirty and determine alias for destination. */ - - movi a8, (1 << PG_ARCH_1) - l32i a9, a5, PAGE_FLAGS - xor a6, a2, a4 - xor a7, a3, a4 - extui a4, a4, PAGE_SHIFT, DCACHE_ALIAS_ORDER - extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER - extui a7, a7, PAGE_SHIFT, DCACHE_ALIAS_ORDER - or a9, a9, a8 - slli a4, a4, PAGE_SHIFT - s32i a9, a5, PAGE_FLAGS - movi a5, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff - - beqz a6, 1f - - /* Invalidate dcache */ - - mov a10, a2 - call8 __invalidate_dcache_page + /* Skip setting up a temporary DTLB for destination if not aliased. */ - /* Setup a temporary DTLB with a matching color. */ + movi a6, 0 + movi a7, 0 + beqz a4, 1f - movi a8, TLBTEMP_BASE_1 # base - add a6, a2, a5 # ppn - add a2, a8, a4 # add 'color' + /* Setup a temporary DTLB for destination. */ + addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE) wdtlb a6, a2 dsync - /* Skip setting up a temporary DTLB for destination if not aliased. */ + /* Skip setting up a temporary DTLB for source if not aliased. */ -1: beqz a7, 1f +1: beqz a5, 1f - /* Setup a temporary DTLB with a matching color. */ + /* Setup a temporary DTLB for source. */ - movi a8, TLBTEMP_BASE_2 # base - add a7, a3, a5 # ppn - add a3, a8, a4 + addi a7, a5, PAGE_KERNEL addi a8, a3, 1 # way1 wdtlb a7, a8 @@ -271,7 +235,7 @@ ENTRY(copy_user_page) retw -ENDPROC(copy_user_page) +ENDPROC(copy_page_alias) #endif @@ -300,6 +264,30 @@ ENTRY(__flush_invalidate_dcache_page_alias) retw ENDPROC(__flush_invalidate_dcache_page_alias) + +/* + * void __invalidate_dcache_page_alias (addr, phys) + * a2 a3 + */ + +ENTRY(__invalidate_dcache_page_alias) + + entry sp, 16 + + movi a7, 0 # required for exception handler + addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) + mov a4, a2 + wdtlb a6, a2 + dsync + + ___invalidate_dcache_page a2 a3 + + idtlb a4 + dsync + + retw + +ENDPROC(__invalidate_dcache_page_alias) #endif ENTRY(__tlbtemp_mapping_itlb) diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 3429b483d9f8..abe4513eb0dd 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -18,32 +18,38 @@ #include <asm/io.h> #if defined(CONFIG_HIGHMEM) -static void * __init init_pmd(unsigned long vaddr) +static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages) { pgd_t *pgd = pgd_offset_k(vaddr); pmd_t *pmd = pmd_offset(pgd, vaddr); + pte_t *pte; + unsigned long i; - if (pmd_none(*pmd)) { - unsigned i; - pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); + n_pages = ALIGN(n_pages, PTRS_PER_PTE); - for (i = 0; i < 1024; i++) - pte_clear(NULL, 0, pte + i); + pr_debug("%s: vaddr: 0x%08lx, n_pages: %ld\n", + __func__, vaddr, n_pages); - set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); - BUG_ON(pte != pte_offset_kernel(pmd, 0)); - pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", - __func__, vaddr, pmd, pte); - return pte; - } else { - return pte_offset_kernel(pmd, 0); + pte = alloc_bootmem_low_pages(n_pages * sizeof(pte_t)); + + for (i = 0; i < n_pages; ++i) + pte_clear(NULL, 0, pte + i); + + for (i = 0; i < n_pages; i += PTRS_PER_PTE, ++pmd) { + pte_t *cur_pte = pte + i; + + BUG_ON(!pmd_none(*pmd)); + set_pmd(pmd, __pmd(((unsigned long)cur_pte) & PAGE_MASK)); + BUG_ON(cur_pte != pte_offset_kernel(pmd, 0)); + pr_debug("%s: pmd: 0x%p, pte: 0x%p\n", + __func__, pmd, cur_pte); } + return pte; } static void __init fixedrange_init(void) { - BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); - init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); + init_pmd(__fix_to_virt(0), __end_of_fixed_addresses); } #endif @@ -52,7 +58,7 @@ void __init paging_init(void) memset(swapper_pg_dir, 0, PAGE_SIZE); #ifdef CONFIG_HIGHMEM fixedrange_init(); - pkmap_page_table = init_pmd(PKMAP_BASE); + pkmap_page_table = init_pmd(PKMAP_BASE, LAST_PKMAP); kmap_init(); #endif } diff --git a/block/bio-integrity.c b/block/bio-integrity.c index bc423f7b02da..f14b4abbebd8 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -520,7 +520,7 @@ void bio_integrity_endio(struct bio *bio, int error) */ if (error) { bio->bi_end_io = bip->bip_end_io; - bio_endio(bio, error); + bio_endio_nodec(bio, error); return; } diff --git a/block/blk-core.c b/block/blk-core.c index c359d72e9d76..bf930f481d43 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1252,7 +1252,6 @@ void blk_rq_set_block_pc(struct request *rq) rq->__sector = (sector_t) -1; rq->bio = rq->biotail = NULL; memset(rq->__cmd, 0, sizeof(rq->__cmd)); - rq->cmd = rq->__cmd; } EXPORT_SYMBOL(blk_rq_set_block_pc); diff --git a/block/blk-mq.c b/block/blk-mq.c index 5189cb1e478a..4aac82615a46 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -112,18 +112,22 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref) */ void blk_mq_freeze_queue(struct request_queue *q) { + bool freeze; + spin_lock_irq(q->queue_lock); - q->mq_freeze_depth++; + freeze = !q->mq_freeze_depth++; spin_unlock_irq(q->queue_lock); - percpu_ref_kill(&q->mq_usage_counter); - blk_mq_run_queues(q, false); + if (freeze) { + percpu_ref_kill(&q->mq_usage_counter); + blk_mq_run_queues(q, false); + } wait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->mq_usage_counter)); } static void blk_mq_unfreeze_queue(struct request_queue *q) { - bool wake = false; + bool wake; spin_lock_irq(q->queue_lock); wake = !--q->mq_freeze_depth; @@ -172,6 +176,8 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx, /* tag was already set */ rq->errors = 0; + rq->cmd = rq->__cmd; + rq->extra_len = 0; rq->sense_len = 0; rq->resid_len = 0; @@ -1068,13 +1074,17 @@ static void blk_mq_bio_to_request(struct request *rq, struct bio *bio) blk_account_io_start(rq, 1); } +static inline bool hctx_allow_merges(struct blk_mq_hw_ctx *hctx) +{ + return (hctx->flags & BLK_MQ_F_SHOULD_MERGE) && + !blk_queue_nomerges(hctx->queue); +} + static inline bool blk_mq_merge_queue_io(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, struct request *rq, struct bio *bio) { - struct request_queue *q = hctx->queue; - - if (!(hctx->flags & BLK_MQ_F_SHOULD_MERGE)) { + if (!hctx_allow_merges(hctx)) { blk_mq_bio_to_request(rq, bio); spin_lock(&ctx->lock); insert_rq: @@ -1082,6 +1092,8 @@ insert_rq: spin_unlock(&ctx->lock); return false; } else { + struct request_queue *q = hctx->queue; + spin_lock(&ctx->lock); if (!blk_mq_attempt_merge(q, ctx, bio)) { blk_mq_bio_to_request(rq, bio); @@ -1574,7 +1586,7 @@ static int blk_mq_init_hw_queues(struct request_queue *q, hctx->tags = set->tags[i]; /* - * Allocate space for all possible cpus to avoid allocation in + * Allocate space for all possible cpus to avoid allocation at * runtime */ hctx->ctxs = kmalloc_node(nr_cpu_ids * sizeof(void *), @@ -1662,8 +1674,8 @@ static void blk_mq_map_swqueue(struct request_queue *q) queue_for_each_hw_ctx(q, hctx, i) { /* - * If not software queues are mapped to this hardware queue, - * disable it and free the request entries + * If no software queues are mapped to this hardware queue, + * disable it and free the request entries. */ if (!hctx->nr_ctx) { struct blk_mq_tag_set *set = q->tag_set; @@ -1713,14 +1725,10 @@ static void blk_mq_del_queue_tag_set(struct request_queue *q) { struct blk_mq_tag_set *set = q->tag_set; - blk_mq_freeze_queue(q); - mutex_lock(&set->tag_list_lock); list_del_init(&q->tag_set_list); blk_mq_update_tag_set_depth(set); mutex_unlock(&set->tag_list_lock); - - blk_mq_unfreeze_queue(q); } static void blk_mq_add_queue_tag_set(struct blk_mq_tag_set *set, diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index cadc37841744..3f31cf9508e6 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1272,15 +1272,22 @@ __cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg) rb_insert_color(&cfqg->rb_node, &st->rb); } +/* + * This has to be called only on activation of cfqg + */ static void cfq_update_group_weight(struct cfq_group *cfqg) { - BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); - if (cfqg->new_weight) { cfqg->weight = cfqg->new_weight; cfqg->new_weight = 0; } +} + +static void +cfq_update_group_leaf_weight(struct cfq_group *cfqg) +{ + BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); if (cfqg->new_leaf_weight) { cfqg->leaf_weight = cfqg->new_leaf_weight; @@ -1299,7 +1306,12 @@ cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg) /* add to the service tree */ BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); - cfq_update_group_weight(cfqg); + /* + * Update leaf_weight. We cannot update weight at this point + * because cfqg might already have been activated and is + * contributing its current weight to the parent's child_weight. + */ + cfq_update_group_leaf_weight(cfqg); __cfq_group_service_tree_add(st, cfqg); /* @@ -1323,6 +1335,7 @@ cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg) */ while ((parent = cfqg_parent(pos))) { if (propagate) { + cfq_update_group_weight(pos); propagate = !parent->nr_active++; parent->children_weight += pos->weight; } diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 51bf5155ee75..9b8eaeca6a79 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -279,7 +279,6 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, r = blk_rq_unmap_user(bio); if (!ret) ret = r; - blk_put_request(rq); return ret; } @@ -297,8 +296,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->interface_id != 'S') return -EINVAL; - if (hdr->cmd_len > BLK_MAX_CDB) - return -EINVAL; if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) return -EIO; @@ -317,16 +314,23 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->flags & SG_FLAG_Q_AT_HEAD) at_head = 1; + ret = -ENOMEM; rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); if (!rq) - return -ENOMEM; + goto out; blk_rq_set_block_pc(rq); - if (blk_fill_sghdr_rq(q, rq, hdr, mode)) { - blk_put_request(rq); - return -EFAULT; + if (hdr->cmd_len > BLK_MAX_CDB) { + rq->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); + if (!rq->cmd) + goto out_put_request; } + ret = -EFAULT; + if (blk_fill_sghdr_rq(q, rq, hdr, mode)) + goto out_free_cdb; + + ret = 0; if (hdr->iovec_count) { size_t iov_data_len; struct iovec *iov = NULL; @@ -335,7 +339,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, 0, NULL, &iov); if (ret < 0) { kfree(iov); - goto out; + goto out_free_cdb; } iov_data_len = ret; @@ -358,7 +362,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, GFP_KERNEL); if (ret) - goto out; + goto out_free_cdb; bio = rq->bio; memset(sense, 0, sizeof(sense)); @@ -376,9 +380,14 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, hdr->duration = jiffies_to_msecs(jiffies - start_time); - return blk_complete_sghdr_rq(rq, hdr, bio); -out: + ret = blk_complete_sghdr_rq(rq, hdr, bio); + +out_free_cdb: + if (rq->cmd != rq->__cmd) + kfree(rq->cmd); +out_put_request: blk_put_request(rq); +out: return ret; } @@ -448,6 +457,11 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, } rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT); + if (!rq) { + err = -ENOMEM; + goto error; + } + blk_rq_set_block_pc(rq); cmdlen = COMMAND_SIZE(opcode); @@ -501,7 +515,6 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, memset(sense, 0, sizeof(sense)); rq->sense = sense; rq->sense_len = 0; - blk_rq_set_block_pc(rq); blk_execute_rq(q, disk, rq, 0); @@ -521,7 +534,8 @@ out: error: kfree(buffer); - blk_put_request(rq); + if (rq) + blk_put_request(rq); return err; } EXPORT_SYMBOL_GPL(sg_scsi_ioctl); diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 97eb001960b9..2f6e4fb1a1ea 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -121,6 +121,7 @@ static int public_key_verify_signature_2(const struct key *key, struct asymmetric_key_subtype public_key_subtype = { .owner = THIS_MODULE, .name = "public_key", + .name_len = sizeof("public_key") - 1, .describe = public_key_describe, .destroy = public_key_destroy, .verify_signature = public_key_verify_signature_2, diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 79175e6ea0b2..2421f46184ce 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -128,6 +128,7 @@ static int pefile_strip_sig_wrapper(const void *pebuf, { struct win_certificate wrapper; const u8 *pkcs7; + unsigned len; if (ctx->sig_len < sizeof(wrapper)) { pr_debug("Signature wrapper too short\n"); @@ -154,33 +155,49 @@ static int pefile_strip_sig_wrapper(const void *pebuf, return -ENOTSUPP; } - /* Looks like actual pkcs signature length is in wrapper->length. - * size obtained from data dir entries lists the total size of - * certificate table which is also aligned to octawrod boundary. - * - * So set signature length field appropriately. + /* It looks like the pkcs signature length in wrapper->length and the + * size obtained from the data dir entries, which lists the total size + * of certificate table, are both aligned to an octaword boundary, so + * we may have to deal with some padding. */ ctx->sig_len = wrapper.length; ctx->sig_offset += sizeof(wrapper); ctx->sig_len -= sizeof(wrapper); - if (ctx->sig_len == 0) { + if (ctx->sig_len < 4) { pr_debug("Signature data missing\n"); return -EKEYREJECTED; } - /* What's left should a PKCS#7 cert */ + /* What's left should be a PKCS#7 cert */ pkcs7 = pebuf + ctx->sig_offset; - if (pkcs7[0] == (ASN1_CONS_BIT | ASN1_SEQ)) { - if (pkcs7[1] == 0x82 && - pkcs7[2] == (((ctx->sig_len - 4) >> 8) & 0xff) && - pkcs7[3] == ((ctx->sig_len - 4) & 0xff)) - return 0; - if (pkcs7[1] == 0x80) - return 0; - if (pkcs7[1] > 0x82) - return -EMSGSIZE; + if (pkcs7[0] != (ASN1_CONS_BIT | ASN1_SEQ)) + goto not_pkcs7; + + switch (pkcs7[1]) { + case 0 ... 0x7f: + len = pkcs7[1] + 2; + goto check_len; + case ASN1_INDEFINITE_LENGTH: + return 0; + case 0x81: + len = pkcs7[2] + 3; + goto check_len; + case 0x82: + len = ((pkcs7[2] << 8) | pkcs7[3]) + 4; + goto check_len; + case 0x83 ... 0xff: + return -EMSGSIZE; + default: + goto not_pkcs7; } +check_len: + if (len <= ctx->sig_len) { + /* There may be padding */ + ctx->sig_len = len; + return 0; + } +not_pkcs7: pr_debug("Signature data not PKCS#7\n"); return -ELIBBAD; } diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index ce06149088c5..9dfec48dd4e5 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -196,6 +196,17 @@ static struct lpss_device_desc byt_i2c_dev_desc = { .setup = lpss_i2c_setup, }; +static struct lpss_shared_clock bsw_pwm_clock = { + .name = "pwm_clk", + .rate = 19200000, +}; + +static struct lpss_device_desc bsw_pwm_dev_desc = { + .clk_required = true, + .save_ctx = true, + .shared_clock = &bsw_pwm_clock, +}; + #else #define LPSS_ADDR(desc) (0UL) @@ -225,6 +236,12 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { { "INT33B2", }, { "INT33FC", }, + /* Braswell LPSS devices */ + { "80862288", LPSS_ADDR(bsw_pwm_dev_desc) }, + { "8086228A", LPSS_ADDR(byt_uart_dev_desc) }, + { "8086228E", LPSS_ADDR(byt_spi_dev_desc) }, + { "808622C1", LPSS_ADDR(byt_i2c_dev_desc) }, + { "INT3430", LPSS_ADDR(lpt_dev_desc) }, { "INT3431", LPSS_ADDR(lpt_dev_desc) }, { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a66ab658abbc..9922cc46b15c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -197,6 +197,8 @@ static bool advance_transaction(struct acpi_ec *ec) t->rdata[t->ri++] = acpi_ec_read_data(ec); if (t->rlen == t->ri) { t->flags |= ACPI_EC_COMMAND_COMPLETE; + if (t->command == ACPI_EC_COMMAND_QUERY) + pr_debug("hardware QR_EC completion\n"); wakeup = true; } } else @@ -208,7 +210,20 @@ static bool advance_transaction(struct acpi_ec *ec) } return wakeup; } else { - if ((status & ACPI_EC_FLAG_IBF) == 0) { + /* + * There is firmware refusing to respond QR_EC when SCI_EVT + * is not set, for which case, we complete the QR_EC + * without issuing it to the firmware. + * https://bugzilla.kernel.org/show_bug.cgi?id=86211 + */ + if (!(status & ACPI_EC_FLAG_SCI) && + (t->command == ACPI_EC_COMMAND_QUERY)) { + t->flags |= ACPI_EC_COMMAND_POLL; + t->rdata[t->ri++] = 0x00; + t->flags |= ACPI_EC_COMMAND_COMPLETE; + pr_debug("software QR_EC completion\n"); + wakeup = true; + } else if ((status & ACPI_EC_FLAG_IBF) == 0) { acpi_ec_write_cmd(ec, t->command); t->flags |= ACPI_EC_COMMAND_POLL; } else @@ -288,11 +303,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, /* following two actions should be kept atomic */ ec->curr = t; start_transaction(ec); - if (ec->curr->command == ACPI_EC_COMMAND_QUERY) - clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); spin_unlock_irqrestore(&ec->lock, tmp); ret = ec_poll(ec); spin_lock_irqsave(&ec->lock, tmp); + if (ec->curr->command == ACPI_EC_COMMAND_QUERY) + clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); ec->curr = NULL; spin_unlock_irqrestore(&ec->lock, tmp); return ret; diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index c96887d5289e..6e6b80eb0bba 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -484,6 +484,10 @@ void acpi_pci_irq_disable(struct pci_dev *dev) /* Keep IOAPIC pin configuration when suspending */ if (dev->dev.power.is_prepared) return; +#ifdef CONFIG_PM_RUNTIME + if (dev->dev.power.runtime_status == RPM_SUSPENDING) + return; +#endif entry = acpi_pci_irq_lookup(dev, pin); if (!entry) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0a817ad24f16..9a9298994e26 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -922,12 +922,17 @@ static void acpi_device_notify(acpi_handle handle, u32 event, void *data) device->driver->ops.notify(device, event); } -static acpi_status acpi_device_notify_fixed(void *data) +static void acpi_device_notify_fixed(void *data) { struct acpi_device *device = data; /* Fixed hardware devices have no handles */ acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); +} + +static acpi_status acpi_device_fixed_event(void *data) +{ + acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); return AE_OK; } @@ -938,12 +943,12 @@ static int acpi_device_install_notify_handler(struct acpi_device *device) if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_notify_fixed, + acpi_device_fixed_event, device); else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_notify_fixed, + acpi_device_fixed_event, device); else status = acpi_install_notify_handler(device->handle, @@ -960,10 +965,10 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) { if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_notify_fixed); + acpi_device_fixed_event); else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_notify_fixed); + acpi_device_fixed_event); else acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_device_notify); @@ -975,7 +980,7 @@ static int acpi_device_probe(struct device *dev) struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); int ret; - if (acpi_dev->handler) + if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) return -EINVAL; if (!acpi_drv->ops.add) diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 7d1326985bee..bfc90b8547f2 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -146,6 +146,9 @@ struct regcache_ops { enum regcache_type type; int (*init)(struct regmap *map); int (*exit)(struct regmap *map); +#ifdef CONFIG_DEBUG_FS + void (*debugfs_init)(struct regmap *map); +#endif int (*read)(struct regmap *map, unsigned int reg, unsigned int *value); int (*write)(struct regmap *map, unsigned int reg, unsigned int value); int (*sync)(struct regmap *map, unsigned int min, unsigned int max); diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 6a7e4fa12854..f3e8fe0cc650 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -194,10 +194,6 @@ static void rbtree_debugfs_init(struct regmap *map) { debugfs_create_file("rbtree", 0400, map->debugfs, map, &rbtree_fops); } -#else -static void rbtree_debugfs_init(struct regmap *map) -{ -} #endif static int regcache_rbtree_init(struct regmap *map) @@ -222,8 +218,6 @@ static int regcache_rbtree_init(struct regmap *map) goto err; } - rbtree_debugfs_init(map); - return 0; err: @@ -532,6 +526,9 @@ struct regcache_ops regcache_rbtree_ops = { .name = "rbtree", .init = regcache_rbtree_init, .exit = regcache_rbtree_exit, +#ifdef CONFIG_DEBUG_FS + .debugfs_init = rbtree_debugfs_init, +#endif .read = regcache_rbtree_read, .write = regcache_rbtree_write, .sync = regcache_rbtree_sync, diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 29b4128da0b0..5617da6dc898 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -698,7 +698,7 @@ int regcache_sync_block(struct regmap *map, void *block, unsigned int block_base, unsigned int start, unsigned int end) { - if (regmap_can_raw_write(map)) + if (regmap_can_raw_write(map) && !map->use_single_rw) return regcache_sync_block_raw(map, block, cache_present, block_base, start, end); else diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 45d812c0ea77..65ea7b256b3e 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -538,6 +538,9 @@ void regmap_debugfs_init(struct regmap *map, const char *name) next = rb_next(&range_node->node); } + + if (map->cache_ops && map->cache_ops->debugfs_init) + map->cache_ops->debugfs_init(map); } void regmap_debugfs_exit(struct regmap *map) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 78f43fb2fe84..1cf427bc0d4a 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -109,7 +109,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) bool regmap_volatile(struct regmap *map, unsigned int reg) { - if (!regmap_readable(map, reg)) + if (!map->format.format_write && !regmap_readable(map, reg)) return false; if (map->volatile_reg) diff --git a/drivers/block/brd.c b/drivers/block/brd.c index c7d138eca731..3598110d2cef 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -442,12 +442,15 @@ static int rd_nr; int rd_size = CONFIG_BLK_DEV_RAM_SIZE; static int max_part; static int part_shift; +static int part_show = 0; module_param(rd_nr, int, S_IRUGO); MODULE_PARM_DESC(rd_nr, "Maximum number of brd devices"); module_param(rd_size, int, S_IRUGO); MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes."); module_param(max_part, int, S_IRUGO); MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); +module_param(part_show, int, S_IRUGO); +MODULE_PARM_DESC(part_show, "Control RAM disk visibility in /proc/partitions"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); MODULE_ALIAS("rd"); @@ -501,7 +504,8 @@ static struct brd_device *brd_alloc(int i) disk->fops = &brd_fops; disk->private_data = brd; disk->queue = brd->brd_queue; - disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; + if (!part_show) + disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; sprintf(disk->disk_name, "ram%d", i); set_capacity(disk, rd_size * 2); diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index ab3ea62e5dfc..c4328d9d9981 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1203,7 +1203,6 @@ static struct platform_driver ace_platform_driver = { .probe = ace_probe, .remove = ace_remove, .driver = { - .owner = THIS_MODULE, .name = "xsysace", .of_match_table = ace_of_match, }, diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index dfa4024c448a..d00831c3d731 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -378,7 +378,6 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret)) { pr_err("Decompression failed! err=%d, page=%u\n", ret, index); - atomic64_inc(&zram->stats.failed_reads); return ret; } @@ -547,8 +546,6 @@ out: zcomp_strm_release(zram->comp, zstrm); if (is_partial_io(bvec)) kfree(uncmem); - if (ret) - atomic64_inc(&zram->stats.failed_writes); return ret; } @@ -566,6 +563,13 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, ret = zram_bvec_write(zram, bvec, index, offset); } + if (unlikely(ret)) { + if (rw == READ) + atomic64_inc(&zram->stats.failed_reads); + else + atomic64_inc(&zram->stats.failed_writes); + } + return ret; } diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 5b0afde729cd..e0f725c87cc6 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -84,7 +84,7 @@ struct zram_stats { atomic64_t compr_data_size; /* compressed size of pages stored */ atomic64_t num_reads; /* failed + successful */ atomic64_t num_writes; /* --do-- */ - atomic64_t failed_reads; /* should NEVER! happen */ + atomic64_t failed_reads; /* can happen when memory is too low */ atomic64_t failed_writes; /* can happen when memory is too low */ atomic64_t invalid_io; /* non-page-aligned I/O requests */ atomic64_t notify_free; /* no. of swap slot free notifications */ diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index c5eac949760d..e396ad3f8f3f 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -660,6 +660,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { ICPU(0x3f, core_params), ICPU(0x45, core_params), ICPU(0x46, core_params), + ICPU(0x4c, byt_params), ICPU(0x4f, core_params), ICPU(0x56, core_params), {} @@ -688,7 +689,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) add_timer_on(&cpu->timer, cpunum); - pr_info("Intel pstate controlling: cpu %d\n", cpunum); + pr_debug("Intel pstate controlling: cpu %d\n", cpunum); return 0; } diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 9a68225a757e..3f9791f07b8e 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -501,7 +501,7 @@ static int check_mem_type(void __iomem *dmc_reg) return val >> 8; } -static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) +static int s5pv210_cpu_init(struct cpufreq_policy *policy) { unsigned long mem_type; int ret; diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index 344d79fa3407..ef94c3b81f18 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c @@ -138,25 +138,18 @@ static int bl_enter_powerdown(struct cpuidle_device *dev, return idx; } -static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id) +static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int part_id) { - struct cpuinfo_arm *cpu_info; struct cpumask *cpumask; - unsigned long cpuid; int cpu; cpumask = kzalloc(cpumask_size(), GFP_KERNEL); if (!cpumask) return -ENOMEM; - for_each_possible_cpu(cpu) { - cpu_info = &per_cpu(cpu_data, cpu); - cpuid = is_smp() ? cpu_info->cpuid : read_cpuid_id(); - - /* read cpu id part number */ - if ((cpuid & 0xFFF0) == cpu_id) + for_each_possible_cpu(cpu) + if (smp_cpuid_part(cpu) == part_id) cpumask_set_cpu(cpu, cpumask); - } drv->cpumask = cpumask; diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index fc6f5d54e7f7..8890870309e4 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -309,6 +309,7 @@ static ssize_t set_convrate(struct device *dev, struct device_attribute *da, data->conf |= (resol << DS1621_REG_CONFIG_RESOL_SHIFT); i2c_smbus_write_byte_data(client, DS1621_REG_CONF, data->conf); data->update_interval = ds1721_convrates[resol]; + data->zbits = 7 - resol; mutex_unlock(&data->update_lock); return count; diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c30204f2fa30..fbe29fcb15c5 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -236,6 +236,18 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) } EXPORT_SYMBOL(input_mt_report_pointer_emulation); +static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt) +{ + int i; + + for (i = 0; i < mt->num_slots; i++) { + if (!input_mt_is_used(mt, &mt->slots[i])) { + input_mt_slot(dev, i); + input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); + } + } +} + /** * input_mt_drop_unused() - Inactivate slots not seen in this frame * @dev: input device with allocated MT slots @@ -245,19 +257,11 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation); void input_mt_drop_unused(struct input_dev *dev) { struct input_mt *mt = dev->mt; - int i; - if (!mt) - return; - - for (i = 0; i < mt->num_slots; i++) { - if (!input_mt_is_used(mt, &mt->slots[i])) { - input_mt_slot(dev, i); - input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); - } + if (mt) { + __input_mt_drop_unused(dev, mt); + mt->frame++; } - - mt->frame++; } EXPORT_SYMBOL(input_mt_drop_unused); @@ -278,12 +282,14 @@ void input_mt_sync_frame(struct input_dev *dev) return; if (mt->flags & INPUT_MT_DROP_UNUSED) - input_mt_drop_unused(dev); + __input_mt_drop_unused(dev, mt); if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) use_count = true; input_mt_report_pointer_emulation(dev, use_count); + + mt->frame++; } EXPORT_SYMBOL(input_mt_sync_frame); diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a59a1a64b674..a956b980ee73 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -2234,8 +2234,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) return 0; } - psmouse_info(psmouse, - "Unknown ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); + psmouse_dbg(psmouse, + "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec); return -EINVAL; } diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ee2a04d90d20..da51738eb59e 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -18,6 +18,7 @@ #include <linux/input/mt.h> #include <linux/serio.h> #include <linux/libps2.h> +#include <asm/unaligned.h> #include "psmouse.h" #include "elantech.h" @@ -403,6 +404,68 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) input_sync(dev); } +static void elantech_report_trackpoint(struct psmouse *psmouse, + int packet_type) +{ + /* + * byte 0: 0 0 sx sy 0 M R L + * byte 1:~sx 0 0 0 0 0 0 0 + * byte 2:~sy 0 0 0 0 0 0 0 + * byte 3: 0 0 ~sy ~sx 0 1 1 0 + * byte 4: x7 x6 x5 x4 x3 x2 x1 x0 + * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 + * + * x and y are written in two's complement spread + * over 9 bits with sx/sy the relative top bit and + * x7..x0 and y7..y0 the lower bits. + * The sign of y is opposite to what the input driver + * expects for a relative movement + */ + + struct elantech_data *etd = psmouse->private; + struct input_dev *tp_dev = etd->tp_dev; + unsigned char *packet = psmouse->packet; + int x, y; + u32 t; + + if (dev_WARN_ONCE(&psmouse->ps2dev.serio->dev, + !tp_dev, + psmouse_fmt("Unexpected trackpoint message\n"))) { + if (etd->debug == 1) + elantech_packet_dump(psmouse); + return; + } + + t = get_unaligned_le32(&packet[0]); + + switch (t & ~7U) { + case 0x06000030U: + case 0x16008020U: + case 0x26800010U: + case 0x36808000U: + x = packet[4] - (int)((packet[1]^0x80) << 1); + y = (int)((packet[2]^0x80) << 1) - packet[5]; + + input_report_key(tp_dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(tp_dev, BTN_RIGHT, packet[0] & 0x02); + input_report_key(tp_dev, BTN_MIDDLE, packet[0] & 0x04); + + input_report_rel(tp_dev, REL_X, x); + input_report_rel(tp_dev, REL_Y, y); + + input_sync(tp_dev); + + break; + + default: + /* Dump unexpected packet sequences if debug=1 (default) */ + if (etd->debug == 1) + elantech_packet_dump(psmouse); + + break; + } +} + /* * Interpret complete data packets and report absolute mode input events for * hardware version 3. (12 byte packets for two fingers) @@ -715,6 +778,8 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) return PACKET_V3_TAIL; + if ((packet[3] & 0x0f) == 0x06) + return PACKET_TRACKPOINT; } return PACKET_UNKNOWN; @@ -791,14 +856,23 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) case 3: packet_type = elantech_packet_check_v3(psmouse); - /* ignore debounce */ - if (packet_type == PACKET_DEBOUNCE) - return PSMOUSE_FULL_PACKET; - - if (packet_type == PACKET_UNKNOWN) + switch (packet_type) { + case PACKET_UNKNOWN: return PSMOUSE_BAD_DATA; - elantech_report_absolute_v3(psmouse, packet_type); + case PACKET_DEBOUNCE: + /* ignore debounce */ + break; + + case PACKET_TRACKPOINT: + elantech_report_trackpoint(psmouse, packet_type); + break; + + default: + elantech_report_absolute_v3(psmouse, packet_type); + break; + } + break; case 4: @@ -1018,8 +1092,10 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, * Asus UX31 0x361f00 20, 15, 0e clickpad * Asus UX32VD 0x361f02 00, 15, 0e clickpad * Avatar AVIU-145A2 0x361f00 ? clickpad + * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) + * Lenovo L530 0x350f02 b9, 15, 0c 2 hw buttons (*) * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad @@ -1029,6 +1105,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, * Samsung RF710 0x450f00 ? 2 hw buttons * System76 Pangolin 0x250f01 ? 2 hw buttons * (*) + 3 trackpoint buttons + * (**) + 0 trackpoint buttons + * Note: Lenovo L430 and Lenovo L430 have the same fw_version/caps */ static void elantech_set_buttonpad_prop(struct psmouse *psmouse) { @@ -1324,6 +1402,10 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) */ static void elantech_disconnect(struct psmouse *psmouse) { + struct elantech_data *etd = psmouse->private; + + if (etd->tp_dev) + input_unregister_device(etd->tp_dev); sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &elantech_attr_group); kfree(psmouse->private); @@ -1438,8 +1520,10 @@ static int elantech_set_properties(struct elantech_data *etd) int elantech_init(struct psmouse *psmouse) { struct elantech_data *etd; - int i, error; + int i; + int error = -EINVAL; unsigned char param[3]; + struct input_dev *tp_dev; psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); if (!etd) @@ -1498,14 +1582,49 @@ int elantech_init(struct psmouse *psmouse) goto init_fail; } + /* The MSB indicates the presence of the trackpoint */ + if ((etd->capabilities[0] & 0x80) == 0x80) { + tp_dev = input_allocate_device(); + + if (!tp_dev) { + error = -ENOMEM; + goto init_fail_tp_alloc; + } + + etd->tp_dev = tp_dev; + snprintf(etd->tp_phys, sizeof(etd->tp_phys), "%s/input1", + psmouse->ps2dev.serio->phys); + tp_dev->phys = etd->tp_phys; + tp_dev->name = "Elantech PS/2 TrackPoint"; + tp_dev->id.bustype = BUS_I8042; + tp_dev->id.vendor = 0x0002; + tp_dev->id.product = PSMOUSE_ELANTECH; + tp_dev->id.version = 0x0000; + tp_dev->dev.parent = &psmouse->ps2dev.serio->dev; + tp_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + tp_dev->relbit[BIT_WORD(REL_X)] = + BIT_MASK(REL_X) | BIT_MASK(REL_Y); + tp_dev->keybit[BIT_WORD(BTN_LEFT)] = + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | + BIT_MASK(BTN_RIGHT); + error = input_register_device(etd->tp_dev); + if (error < 0) + goto init_fail_tp_reg; + } + psmouse->protocol_handler = elantech_process_byte; psmouse->disconnect = elantech_disconnect; psmouse->reconnect = elantech_reconnect; psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; return 0; - + init_fail_tp_reg: + input_free_device(tp_dev); + init_fail_tp_alloc: + sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, + &elantech_attr_group); init_fail: + psmouse_reset(psmouse); kfree(etd); - return -1; + return error; } diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 9e0e2a1f340d..6f3afec02f03 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h @@ -94,6 +94,7 @@ #define PACKET_V4_HEAD 0x05 #define PACKET_V4_MOTION 0x06 #define PACKET_V4_STATUS 0x07 +#define PACKET_TRACKPOINT 0x08 /* * track up to 5 fingers for v4 hardware @@ -114,6 +115,8 @@ struct finger_pos { }; struct elantech_data { + struct input_dev *tp_dev; /* Relative device for trackpoint */ + char tp_phys[32]; unsigned char reg_07; unsigned char reg_10; unsigned char reg_11; diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index d6aa4c67dbb6..93cb7912703c 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -17,7 +17,6 @@ static int i8042_aux_irq = -1; #define I8042_MUX_PHYS_DESC "sparcps2/serio%d" static void __iomem *kbd_iobase; -static struct resource *kbd_res; #define I8042_COMMAND_REG (kbd_iobase + 0x64UL) #define I8042_DATA_REG (kbd_iobase + 0x60UL) @@ -44,6 +43,8 @@ static inline void i8042_write_command(int val) #ifdef CONFIG_PCI +static struct resource *kbd_res; + #define OBP_PS2KBD_NAME1 "kb_ps2" #define OBP_PS2KBD_NAME2 "keyboard" #define OBP_PS2MS_NAME1 "kdmouse" diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 129729d35478..aa29198fca3e 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -15,10 +15,10 @@ #include <linux/list.h> #include <linux/spinlock.h> #include <linux/device.h> +#include <linux/timer.h> #include <linux/err.h> #include <linux/ctype.h> #include <linux/leds.h> -#include <linux/workqueue.h> #include "leds.h" static struct class *leds_class; @@ -97,10 +97,9 @@ static const struct attribute_group *led_groups[] = { NULL, }; -static void led_work_function(struct work_struct *ws) +static void led_timer_function(unsigned long data) { - struct led_classdev *led_cdev = - container_of(ws, struct led_classdev, blink_work.work); + struct led_classdev *led_cdev = (void *)data; unsigned long brightness; unsigned long delay; @@ -144,8 +143,7 @@ static void led_work_function(struct work_struct *ws) } } - queue_delayed_work(system_wq, &led_cdev->blink_work, - msecs_to_jiffies(delay)); + mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); } static void set_brightness_delayed(struct work_struct *ws) @@ -233,7 +231,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); - INIT_DELAYED_WORK(&led_cdev->blink_work, led_work_function); + init_timer(&led_cdev->blink_timer); + led_cdev->blink_timer.function = led_timer_function; + led_cdev->blink_timer.data = (unsigned long)led_cdev; #ifdef CONFIG_LEDS_TRIGGERS led_trigger_set_default(led_cdev); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 4bb116867b88..71b40d3bf776 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -16,7 +16,6 @@ #include <linux/module.h> #include <linux/rwsem.h> #include <linux/leds.h> -#include <linux/workqueue.h> #include "leds.h" DECLARE_RWSEM(leds_list_lock); @@ -52,7 +51,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev, return; } - queue_delayed_work(system_wq, &led_cdev->blink_work, 1); + mod_timer(&led_cdev->blink_timer, jiffies + 1); } @@ -76,7 +75,7 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - cancel_delayed_work_sync(&led_cdev->blink_work); + del_timer_sync(&led_cdev->blink_timer); led_cdev->flags &= ~LED_BLINK_ONESHOT; led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; @@ -91,7 +90,7 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev, int invert) { if ((led_cdev->flags & LED_BLINK_ONESHOT) && - delayed_work_pending(&led_cdev->blink_work)) + timer_pending(&led_cdev->blink_timer)) return; led_cdev->flags |= LED_BLINK_ONESHOT; @@ -108,7 +107,7 @@ EXPORT_SYMBOL(led_blink_set_oneshot); void led_stop_software_blink(struct led_classdev *led_cdev) { - cancel_delayed_work_sync(&led_cdev->blink_work); + del_timer_sync(&led_cdev->blink_timer); led_cdev->blink_delay_on = 0; led_cdev->blink_delay_off = 0; } @@ -117,7 +116,7 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink); void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - /* delay brightness setting if need to stop soft-blink work */ + /* delay brightness setting if need to stop soft-blink timer */ if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { led_cdev->delayed_set_value = brightness; schedule_work(&led_cdev->set_brightness_work); diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 2785007e0e46..cd15e0801228 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1688,6 +1688,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) unsigned int key_size, opt_params; unsigned long long tmpll; int ret; + size_t iv_size_padding; struct dm_arg_set as; const char *opt_string; char dummy; @@ -1724,20 +1725,32 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->dmreq_start = sizeof(struct ablkcipher_request); cc->dmreq_start += crypto_ablkcipher_reqsize(any_tfm(cc)); - cc->dmreq_start = ALIGN(cc->dmreq_start, crypto_tfm_ctx_alignment()); - cc->dmreq_start += crypto_ablkcipher_alignmask(any_tfm(cc)) & - ~(crypto_tfm_ctx_alignment() - 1); + cc->dmreq_start = ALIGN(cc->dmreq_start, __alignof__(struct dm_crypt_request)); + + if (crypto_ablkcipher_alignmask(any_tfm(cc)) < CRYPTO_MINALIGN) { + /* Allocate the padding exactly */ + iv_size_padding = -(cc->dmreq_start + sizeof(struct dm_crypt_request)) + & crypto_ablkcipher_alignmask(any_tfm(cc)); + } else { + /* + * If the cipher requires greater alignment than kmalloc + * alignment, we don't know the exact position of the + * initialization vector. We must assume worst case. + */ + iv_size_padding = crypto_ablkcipher_alignmask(any_tfm(cc)); + } cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start + - sizeof(struct dm_crypt_request) + cc->iv_size); + sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size); if (!cc->req_pool) { ti->error = "Cannot allocate crypt request mempool"; goto bad; } cc->per_bio_data_size = ti->per_bio_data_size = - sizeof(struct dm_crypt_io) + cc->dmreq_start + - sizeof(struct dm_crypt_request) + cc->iv_size; + ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + + sizeof(struct dm_crypt_request) + iv_size_padding + cc->iv_size, + ARCH_KMALLOC_MINALIGN); cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0); if (!cc->page_pool) { diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 324e1de93687..2da05c0e113d 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -601,6 +601,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) cl->timer_count = MEI_CONNECT_TIMEOUT; list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } else { + cl->state = MEI_FILE_INITIALIZING; list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 3095fc514a65..5ccc23bc7690 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -342,9 +342,10 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) ndev = (struct mei_nfc_dev *) cldev->priv_data; dev = ndev->cl->dev; + err = -ENOMEM; mei_buf = kzalloc(length + MEI_NFC_HEADER_SIZE, GFP_KERNEL); if (!mei_buf) - return -ENOMEM; + goto out; hdr = (struct mei_nfc_hci_hdr *) mei_buf; hdr->cmd = MEI_NFC_CMD_HCI_SEND; @@ -354,12 +355,9 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) hdr->data_size = length; memcpy(mei_buf + MEI_NFC_HEADER_SIZE, buf, length); - err = __mei_cl_send(ndev->cl, mei_buf, length + MEI_NFC_HEADER_SIZE); if (err < 0) - return err; - - kfree(mei_buf); + goto out; if (!wait_event_interruptible_timeout(ndev->send_wq, ndev->recv_req_id == ndev->req_id, HZ)) { @@ -368,7 +366,8 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) } else { ndev->req_id++; } - +out: + kfree(mei_buf); return err; } diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f0ed92e210a1..5967b385141b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -931,7 +931,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u32 val; val = readl(info->reg.gpmc_ecc_config); - if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) + if (((val >> ECC_CONFIG_CS_SHIFT) & CS_MASK) != info->gpmc_cs) return -EINVAL; /* read ecc result */ @@ -1794,9 +1794,12 @@ static int omap_nand_probe(struct platform_device *pdev) } /* populate MTD interface based on ECC scheme */ - nand_chip->ecc.layout = &omap_oobinfo; ecclayout = &omap_oobinfo; switch (info->ecc_opt) { + case OMAP_ECC_HAM1_CODE_SW: + nand_chip->ecc.mode = NAND_ECC_SOFT; + break; + case OMAP_ECC_HAM1_CODE_HW: pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n"); nand_chip->ecc.mode = NAND_ECC_HW; @@ -1848,7 +1851,7 @@ static int omap_nand_probe(struct platform_device *pdev) nand_chip->ecc.priv = nand_bch_init(mtd, nand_chip->ecc.size, nand_chip->ecc.bytes, - &nand_chip->ecc.layout); + &ecclayout); if (!nand_chip->ecc.priv) { pr_err("nand: error: unable to use s/w BCH library\n"); err = -EINVAL; @@ -1923,7 +1926,7 @@ static int omap_nand_probe(struct platform_device *pdev) nand_chip->ecc.priv = nand_bch_init(mtd, nand_chip->ecc.size, nand_chip->ecc.bytes, - &nand_chip->ecc.layout); + &ecclayout); if (!nand_chip->ecc.priv) { pr_err("nand: error: unable to use s/w BCH library\n"); err = -EINVAL; @@ -2012,6 +2015,9 @@ static int omap_nand_probe(struct platform_device *pdev) goto return_error; } + if (info->ecc_opt == OMAP_ECC_HAM1_CODE_SW) + goto scan_tail; + /* all OOB bytes from oobfree->offset till end off OOB are free */ ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; /* check if NAND device's OOB is enough to store ECC signatures */ @@ -2021,7 +2027,9 @@ static int omap_nand_probe(struct platform_device *pdev) err = -EINVAL; goto return_error; } + nand_chip->ecc.layout = ecclayout; +scan_tail: /* second phase scan */ if (nand_scan_tail(mtd)) { err = -ENXIO; diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 8922c376456a..90f5ccacce4b 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -56,7 +56,7 @@ config PCI_HOST_GENERIC controller, such as the one emulated by kvmtool. config PCIE_SPEAR13XX - tristate "STMicroelectronics SPEAr PCIe controller" + bool "STMicroelectronics SPEAr PCIe controller" depends on ARCH_SPEAR13XX select PCIEPORTBUS select PCIE_DW diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index fc468a3d95ce..02152de135b5 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -88,7 +88,6 @@ struct ideapad_private { struct dentry *debug; unsigned long cfg; bool has_hw_rfkill_switch; - bool has_touchpad_control; }; static bool no_bt_rfkill; @@ -456,7 +455,7 @@ struct ideapad_rfk_data { int type; }; -const const struct ideapad_rfk_data ideapad_rfk_data[] = { +static const struct ideapad_rfk_data ideapad_rfk_data[] = { { "ideapad_wlan", CFG_WIFI_BIT, VPCCMD_W_WIFI, RFKILL_TYPE_WLAN }, { "ideapad_bluetooth", CFG_BT_BIT, VPCCMD_W_BT, RFKILL_TYPE_BLUETOOTH }, { "ideapad_3g", CFG_3G_BIT, VPCCMD_W_3G, RFKILL_TYPE_WWAN }, @@ -767,9 +766,6 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { unsigned long value; - if (!priv->has_touchpad_control) - return; - /* Without reading from EC touchpad LED doesn't switch state */ if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only @@ -833,29 +829,7 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) * always results in 0 on these models, causing ideapad_laptop to wrongly * report all radios as hardware-blocked. */ -static struct dmi_system_id no_hw_rfkill_list[] = { - { - .ident = "Lenovo Yoga 2 11 / 13 / Pro", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), - }, - }, - {} -}; - -/* - * Some models don't offer touchpad ctrl through the ideapad interface, causing - * ideapad_sync_touchpad_state to send wrong touchpad enable/disable events. - */ -static struct dmi_system_id no_touchpad_ctrl_list[] = { - { - .ident = "Lenovo Yoga 1 series", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga"), - }, - }, +static const struct dmi_system_id no_hw_rfkill_list[] = { { .ident = "Lenovo Yoga 2 11 / 13 / Pro", .matches = { @@ -889,7 +863,6 @@ static int ideapad_acpi_add(struct platform_device *pdev) priv->adev = adev; priv->platform_device = pdev; priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); - priv->has_touchpad_control = !dmi_check_system(no_touchpad_ctrl_list); ret = ideapad_sysfs_init(priv); if (ret) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index b062d3d7b373..d0dce734b2ed 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1255,10 +1255,15 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, const char *buf, size_t count) { struct toshiba_acpi_dev *toshiba = dev_get_drvdata(dev); - int mode = -1; - int time = -1; + int mode; + int time; + int ret; - if (sscanf(buf, "%i", &mode) != 1 && (mode != 2 || mode != 1)) + + ret = kstrtoint(buf, 0, &mode); + if (ret) + return ret; + if (mode != SCI_KBD_MODE_FNZ && mode != SCI_KBD_MODE_AUTO) return -EINVAL; /* Set the Keyboard Backlight Mode where: @@ -1266,11 +1271,12 @@ static ssize_t toshiba_kbd_bl_mode_store(struct device *dev, * Auto - KBD backlight turns off automatically in given time * FN-Z - KBD backlight "toggles" when hotkey pressed */ - if (mode != -1 && toshiba->kbd_mode != mode) { + if (toshiba->kbd_mode != mode) { time = toshiba->kbd_time << HCI_MISC_SHIFT; time = time + toshiba->kbd_mode; - if (toshiba_kbd_illum_status_set(toshiba, time) < 0) - return -EIO; + ret = toshiba_kbd_illum_status_set(toshiba, time); + if (ret) + return ret; toshiba->kbd_mode = mode; } @@ -1857,9 +1863,16 @@ static int toshiba_acpi_resume(struct device *device) { struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); u32 result; + acpi_status status; + + if (dev->hotkey_dev) { + status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", + NULL, NULL); + if (ACPI_FAILURE(status)) + pr_info("Unable to re-enable hotkeys\n"); - if (dev->hotkey_dev) hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result); + } return 0; } diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 8f06250a0389..8754c33361e8 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -717,12 +717,14 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->device_type = s5m87xx->device_type; info->wtsr_smpl = s5m87xx->wtsr_smpl; - info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); - if (info->irq <= 0) { - ret = -EINVAL; - dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", + if (s5m87xx->irq_data) { + info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); + if (info->irq <= 0) { + ret = -EINVAL; + dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", alarm_irq); - goto err; + goto err; + } } platform_set_drvdata(pdev, info); @@ -744,6 +746,11 @@ static int s5m_rtc_probe(struct platform_device *pdev) goto err; } + if (!info->irq) { + dev_info(&pdev->dev, "Alarm IRQ not available\n"); + return 0; + } + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, s5m_rtc_alarm_irq, 0, "rtc-alarm0", info); @@ -802,7 +809,7 @@ static int s5m_rtc_resume(struct device *dev) struct s5m_rtc_info *info = dev_get_drvdata(dev); int ret = 0; - if (device_may_wakeup(dev)) + if (info->irq && device_may_wakeup(dev)) ret = disable_irq_wake(info->irq); return ret; @@ -813,7 +820,7 @@ static int s5m_rtc_suspend(struct device *dev) struct s5m_rtc_info *info = dev_get_drvdata(dev); int ret = 0; - if (device_may_wakeup(dev)) + if (info->irq && device_may_wakeup(dev)) ret = enable_irq_wake(info->irq); return ret; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ce62e8798cc8..d837dc180522 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1808,7 +1808,6 @@ static int scsi_mq_prep_fn(struct request *req) cmd->tag = req->tag; - req->cmd = req->__cmd; cmd->cmnd = req->cmd; cmd->prot_op = SCSI_PROT_NORMAL; diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 40c3d43c9292..f40b34cdf2fc 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -945,7 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev) spi_bitbang_stop(&hw->bitbang); free_irq(hw->irq, hw); iounmap((void __iomem *)hw->regs); - release_mem_region(r->start, sizeof(psc_spi_t)); + release_mem_region(hw->ioarea->start, sizeof(psc_spi_t)); if (hw->usedma) { au1550_spi_dma_rxtmp_free(hw); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 276a3884fb3c..48f1d26e6ad9 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -417,16 +417,16 @@ static int davinci_spi_setup(struct spi_device *spi) flags, dev_name(&spi->dev)); internal_cs = false; } - } - if (retval) { - dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", - spi->cs_gpio, retval); - return retval; - } + if (retval) { + dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", + spi->cs_gpio, retval); + return retval; + } - if (internal_cs) - set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); + if (internal_cs) + set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); + } if (spi->mode & SPI_READY) set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK); diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index 3f3dc1226edf..e14960470d8d 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c @@ -62,6 +62,8 @@ static int spi_pci_probe(struct pci_dev *pdev, if (ret) return ret; + dws->regs = pcim_iomap_table(pdev)[pci_bar]; + dws->bus_num = 0; dws->num_cs = 4; dws->irq = pdev->irq; diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 29f33143b795..670f0627f3bf 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -271,7 +271,7 @@ static void giveback(struct dw_spi *dws) transfer_list); if (!last_transfer->cs_change) - spi_chip_sel(dws, dws->cur_msg->spi, 0); + spi_chip_sel(dws, msg->spi, 0); spi_finalize_current_message(dws->master); } diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 68441fa448de..352eed7463ac 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -329,7 +329,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, disable_fifo: if (t->rx_buf != NULL) chconf &= ~OMAP2_MCSPI_CHCONF_FFER; - else + + if (t->tx_buf != NULL) chconf &= ~OMAP2_MCSPI_CHCONF_FFET; mcspi_write_chconf0(spi, chconf); diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index fe792106bdc5..46f45ca2c694 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1074,6 +1074,7 @@ static struct acpi_device_id pxa2xx_spi_acpi_match[] = { { "INT3430", 0 }, { "INT3431", 0 }, { "80860F0E", 0 }, + { "8086228E", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match); diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index c0743604b906..cd0e08b0c9f6 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -499,7 +499,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs) } /* div doesn't support odd number */ - div = rs->max_freq / rs->speed; + div = max_t(u32, rs->max_freq / rs->speed, 1); div = (div + 1) & 0xfffe; spi_enable_chip(rs, 0); @@ -678,7 +678,7 @@ static int rockchip_spi_probe(struct platform_device *pdev) rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); rs->dma_tx.direction = DMA_MEM_TO_DEV; - rs->dma_tx.direction = DMA_DEV_TO_MEM; + rs->dma_rx.direction = DMA_DEV_TO_MEM; master->can_dma = rockchip_spi_can_dma; master->dma_tx = rs->dma_tx.ch; diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index c850dfdfa9e3..ad87a98f8f68 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -472,25 +472,52 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, dma_cookie_t cookie; int ret; - if (tx) { - desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, - tx->sgl, tx->nents, DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_tx) - goto no_dma; - - irq_mask |= SPCR_SPTIE; - } + /* First prepare and submit the DMA request(s), as this may fail */ if (rx) { desc_rx = dmaengine_prep_slave_sg(rspi->master->dma_rx, rx->sgl, rx->nents, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_rx) - goto no_dma; + if (!desc_rx) { + ret = -EAGAIN; + goto no_dma_rx; + } + + desc_rx->callback = rspi_dma_complete; + desc_rx->callback_param = rspi; + cookie = dmaengine_submit(desc_rx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_rx; + } irq_mask |= SPCR_SPRIE; } + if (tx) { + desc_tx = dmaengine_prep_slave_sg(rspi->master->dma_tx, + tx->sgl, tx->nents, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_tx) { + ret = -EAGAIN; + goto no_dma_tx; + } + + if (rx) { + /* No callback */ + desc_tx->callback = NULL; + } else { + desc_tx->callback = rspi_dma_complete; + desc_tx->callback_param = rspi; + } + cookie = dmaengine_submit(desc_tx); + if (dma_submit_error(cookie)) { + ret = cookie; + goto no_dma_tx; + } + + irq_mask |= SPCR_SPTIE; + } + /* * DMAC needs SPxIE, but if SPxIE is set, the IRQ routine will be * called. So, this driver disables the IRQ while DMA transfer. @@ -503,34 +530,24 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, rspi_enable_irq(rspi, irq_mask); rspi->dma_callbacked = 0; - if (rx) { - desc_rx->callback = rspi_dma_complete; - desc_rx->callback_param = rspi; - cookie = dmaengine_submit(desc_rx); - if (dma_submit_error(cookie)) - return cookie; + /* Now start DMA */ + if (rx) dma_async_issue_pending(rspi->master->dma_rx); - } - if (tx) { - if (rx) { - /* No callback */ - desc_tx->callback = NULL; - } else { - desc_tx->callback = rspi_dma_complete; - desc_tx->callback_param = rspi; - } - cookie = dmaengine_submit(desc_tx); - if (dma_submit_error(cookie)) - return cookie; + if (tx) dma_async_issue_pending(rspi->master->dma_tx); - } ret = wait_event_interruptible_timeout(rspi->wait, rspi->dma_callbacked, HZ); if (ret > 0 && rspi->dma_callbacked) ret = 0; - else if (!ret) + else if (!ret) { + dev_err(&rspi->master->dev, "DMA timeout\n"); ret = -ETIMEDOUT; + if (tx) + dmaengine_terminate_all(rspi->master->dma_tx); + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); + } rspi_disable_irq(rspi, irq_mask); @@ -541,11 +558,16 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, return ret; -no_dma: - pr_warn_once("%s %s: DMA not available, falling back to PIO\n", - dev_driver_string(&rspi->master->dev), - dev_name(&rspi->master->dev)); - return -EAGAIN; +no_dma_tx: + if (rx) + dmaengine_terminate_all(rspi->master->dma_rx); +no_dma_rx: + if (ret == -EAGAIN) { + pr_warn_once("%s %s: DMA not available, falling back to PIO\n", + dev_driver_string(&rspi->master->dev), + dev_name(&rspi->master->dev)); + } + return ret; } static void rspi_receive_init(const struct rspi_data *rspi) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 2a4354dcd661..543075b80f16 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -636,48 +636,38 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, dma_cookie_t cookie; int ret; - if (tx) { - ier_bits |= IER_TDREQE | IER_TDMAE; - dma_sync_single_for_device(p->master->dma_tx->device->dev, - p->tx_dma_addr, len, DMA_TO_DEVICE); - desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, - p->tx_dma_addr, len, DMA_TO_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_tx) - return -EAGAIN; - } - + /* First prepare and submit the DMA request(s), as this may fail */ if (rx) { ier_bits |= IER_RDREQE | IER_RDMAE; desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, p->rx_dma_addr, len, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_rx) - return -EAGAIN; - } - - /* 1 stage FIFO watermarks for DMA */ - sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1); - - /* setup msiof transfer mode registers (32-bit words) */ - sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4); - - sh_msiof_write(p, IER, ier_bits); - - reinit_completion(&p->done); + if (!desc_rx) { + ret = -EAGAIN; + goto no_dma_rx; + } - if (rx) { desc_rx->callback = sh_msiof_dma_complete; desc_rx->callback_param = p; cookie = dmaengine_submit(desc_rx); if (dma_submit_error(cookie)) { ret = cookie; - goto stop_ier; + goto no_dma_rx; } - dma_async_issue_pending(p->master->dma_rx); } if (tx) { + ier_bits |= IER_TDREQE | IER_TDMAE; + dma_sync_single_for_device(p->master->dma_tx->device->dev, + p->tx_dma_addr, len, DMA_TO_DEVICE); + desc_tx = dmaengine_prep_slave_single(p->master->dma_tx, + p->tx_dma_addr, len, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc_tx) { + ret = -EAGAIN; + goto no_dma_tx; + } + if (rx) { /* No callback */ desc_tx->callback = NULL; @@ -688,15 +678,30 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, cookie = dmaengine_submit(desc_tx); if (dma_submit_error(cookie)) { ret = cookie; - goto stop_rx; + goto no_dma_tx; } - dma_async_issue_pending(p->master->dma_tx); } + /* 1 stage FIFO watermarks for DMA */ + sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1); + + /* setup msiof transfer mode registers (32-bit words) */ + sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4); + + sh_msiof_write(p, IER, ier_bits); + + reinit_completion(&p->done); + + /* Now start DMA */ + if (rx) + dma_async_issue_pending(p->master->dma_rx); + if (tx) + dma_async_issue_pending(p->master->dma_tx); + ret = sh_msiof_spi_start(p, rx); if (ret) { dev_err(&p->pdev->dev, "failed to start hardware\n"); - goto stop_tx; + goto stop_dma; } /* wait for tx fifo to be emptied / rx fifo to be filled */ @@ -726,14 +731,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, stop_reset: sh_msiof_reset_str(p); sh_msiof_spi_stop(p, rx); -stop_tx: +stop_dma: if (tx) dmaengine_terminate_all(p->master->dma_tx); -stop_rx: +no_dma_tx: if (rx) dmaengine_terminate_all(p->master->dma_rx); -stop_ier: sh_msiof_write(p, IER, 0); +no_dma_rx: return ret; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e0531baf2782..ca935df80c88 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -848,6 +848,7 @@ out: /** * spi_finalize_current_transfer - report completion of a transfer + * @master: the master reporting completion * * Called by SPI drivers using the core transfer_one_message() * implementation to notify it that the current interrupt driven diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2c486ea6236b..35b494f5667f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -28,8 +28,6 @@ source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" -source "drivers/staging/usbip/Kconfig" - source "drivers/staging/wlan-ng/Kconfig" source "drivers/staging/comedi/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 1e1a3a10faf7..e66a5dbd9b02 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o obj-y += media/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ -obj-$(CONFIG_USBIP_CORE) += usbip/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index 9b47e66599a3..0bf0d24d12d5 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -790,7 +790,7 @@ static int __init create_log(char *log_name, int size) if (unlikely(ret)) { pr_err("failed to register misc device for log '%s'!\n", log->misc.name); - goto out_free_log; + goto out_free_misc_name; } pr_info("created %luK log '%s'\n", @@ -798,6 +798,9 @@ static int __init create_log(char *log_name, int size) return 0; +out_free_misc_name: + kfree(log->misc.name); + out_free_log: kfree(log); diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 8bf1eb485163..831b7c6fe494 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1421,22 +1421,16 @@ static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value) * @reg: the register to read * @value: 16-bit value to write */ -static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) +static int et131x_mii_write(struct et131x_adapter *adapter, u8 addr, u8 reg, + u16 value) { struct mac_regs __iomem *mac = &adapter->regs->mac; - struct phy_device *phydev = adapter->phydev; int status = 0; - u8 addr; u32 delay = 0; u32 mii_addr; u32 mii_cmd; u32 mii_indicator; - if (!phydev) - return -EIO; - - addr = phydev->addr; - /* Save a local copy of the registers we are dealing with so we can * set them back */ @@ -1631,17 +1625,7 @@ static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, struct net_device *netdev = bus->priv; struct et131x_adapter *adapter = netdev_priv(netdev); - return et131x_mii_write(adapter, reg, value); -} - -static int et131x_mdio_reset(struct mii_bus *bus) -{ - struct net_device *netdev = bus->priv; - struct et131x_adapter *adapter = netdev_priv(netdev); - - et131x_mii_write(adapter, MII_BMCR, BMCR_RESET); - - return 0; + return et131x_mii_write(adapter, phy_addr, reg, value); } /* et1310_phy_power_switch - PHY power control @@ -1656,18 +1640,20 @@ static int et131x_mdio_reset(struct mii_bus *bus) static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) { u16 data; + struct phy_device *phydev = adapter->phydev; et131x_mii_read(adapter, MII_BMCR, &data); data &= ~BMCR_PDOWN; if (down) data |= BMCR_PDOWN; - et131x_mii_write(adapter, MII_BMCR, data); + et131x_mii_write(adapter, phydev->addr, MII_BMCR, data); } /* et131x_xcvr_init - Init the phy if we are setting it into force mode */ static void et131x_xcvr_init(struct et131x_adapter *adapter) { u16 lcr2; + struct phy_device *phydev = adapter->phydev; /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates @@ -1688,7 +1674,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) else lcr2 |= (LED_VAL_LINKON << LED_TXRX_SHIFT); - et131x_mii_write(adapter, PHY_LED_2, lcr2); + et131x_mii_write(adapter, phydev->addr, PHY_LED_2, lcr2); } } @@ -3643,14 +3629,14 @@ static void et131x_adjust_link(struct net_device *netdev) et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, + et131x_mii_write(adapter, phydev->addr, + PHY_MPHY_CONTROL_REG, register18 | 0x4); + et131x_mii_write(adapter, phydev->addr, PHY_INDEX_REG, register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, + et131x_mii_write(adapter, phydev->addr, PHY_DATA_REG, register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); + et131x_mii_write(adapter, phydev->addr, + PHY_MPHY_CONTROL_REG, register18); } et1310_config_flow_control(adapter); @@ -3662,7 +3648,8 @@ static void et131x_adjust_link(struct net_device *netdev) et131x_mii_read(adapter, PHY_CONFIG, ®); reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; - et131x_mii_write(adapter, PHY_CONFIG, reg); + et131x_mii_write(adapter, phydev->addr, PHY_CONFIG, + reg); } et131x_set_rx_dma_timer(adapter); @@ -3675,14 +3662,14 @@ static void et131x_adjust_link(struct net_device *netdev) et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, - register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, - register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); + et131x_mii_write(adapter, phydev->addr, + PHY_MPHY_CONTROL_REG, register18 | 0x4); + et131x_mii_write(adapter, phydev->addr, + PHY_INDEX_REG, register18 | 0x8402); + et131x_mii_write(adapter, phydev->addr, + PHY_DATA_REG, register18 | 511); + et131x_mii_write(adapter, phydev->addr, + PHY_MPHY_CONTROL_REG, register18); } /* Free the packets being actively sent & stopped */ @@ -4644,10 +4631,6 @@ static int et131x_pci_setup(struct pci_dev *pdev, /* Copy address into the net_device struct */ memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); - /* Init variable for counting how long we do not have link status */ - adapter->boot_coma = 0; - et1310_disable_phy_coma(adapter); - rc = -ENOMEM; /* Setup the mii_bus struct */ @@ -4663,7 +4646,6 @@ static int et131x_pci_setup(struct pci_dev *pdev, adapter->mii_bus->priv = netdev; adapter->mii_bus->read = et131x_mdio_read; adapter->mii_bus->write = et131x_mdio_write; - adapter->mii_bus->reset = et131x_mdio_reset; adapter->mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); if (!adapter->mii_bus->irq) @@ -4687,6 +4669,10 @@ static int et131x_pci_setup(struct pci_dev *pdev, /* Setup et1310 as per the documentation */ et131x_adapter_setup(adapter); + /* Init variable for counting how long we do not have link status */ + adapter->boot_coma = 0; + et1310_disable_phy_coma(adapter); + /* We can enable interrupts now * * NOTE - Because registration of interrupt handler is done in the diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 65629579bd7d..03ab9e046784 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -365,6 +365,7 @@ cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, return -ENOMEM; strncpy(sched->ws_name, name, CFS_WS_NAME_LEN); + sched->ws_name[CFS_WS_NAME_LEN - 1] = '\0'; sched->ws_cptab = cptab; sched->ws_cpt = cpt; diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 8b19f3caa68f..701c6a776524 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -35,7 +35,7 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -# include <asm/atomic.h> +# include <linux/atomic.h> #include "../include/obd_support.h" #include "../include/obd_class.h" diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index b8676ac77b0c..407a318b09db 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c @@ -43,9 +43,11 @@ static struct usb_device_id rtw_usb_id_tbl[] = { {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ /*=== Customer ID ===*/ /****** 8188EUS ********/ + {USB_DEVICE(0x056e, 0x4008)}, /* Elecom WDC-150SU2M */ {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ + {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ {} /* Terminating entry */ }; diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index 8fcf8a7b6c22..9562cd026dc0 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -150,7 +150,26 @@ int tb_path_activate(struct tb_path *path) /* Activate hops. */ for (i = path->path_length - 1; i >= 0; i--) { - struct tb_regs_hop hop; + struct tb_regs_hop hop = { 0 }; + + /* + * We do (currently) not tear down paths setup by the firmeware. + * If a firmware device is unplugged and plugged in again then + * it can happen that we reuse some of the hops from the (now + * defunct) firmeware path. This causes the hotplug operation to + * fail (the pci device does not show up). Clearing the hop + * before overwriting it fixes the problem. + * + * Should be removed once we discover and tear down firmeware + * paths. + */ + res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS, + 2 * path->hops[i].in_hop_index, 2); + if (res) { + __tb_path_deactivate_hops(path, i); + __tb_path_deallocate_nfc(path, 0); + goto err; + } /* dword 0 */ hop.next_hop = path->hops[i].next_hop_index; diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index e0cad4418085..cf1b19bca306 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -92,6 +92,8 @@ source "drivers/usb/storage/Kconfig" source "drivers/usb/image/Kconfig" +source "drivers/usb/usbip/Kconfig" + endif source "drivers/usb/musb/Kconfig" diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 3cba892b83a2..d7be71778059 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -60,3 +60,5 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ obj-$(CONFIG_USB_COMMON) += common/ + +obj-$(CONFIG_USBIP_CORE) += usbip/ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8a4dcbc7a75f..46f5161c7891 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1728,8 +1728,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) * - Change autosuspend delay of hub can avoid unnecessary auto * suspend timer for hub, also may decrease power consumption * of USB bus. + * + * - If user has indicated to prevent autosuspend by passing + * usbcore.autosuspend = -1 then keep autosuspend disabled. */ - pm_runtime_set_autosuspend_delay(&hdev->dev, 0); +#ifdef CONFIG_PM_RUNTIME + if (hdev->dev.power.autosuspend_delay >= 0) + pm_runtime_set_autosuspend_delay(&hdev->dev, 0); +#endif /* * Hubs have proper suspend/resume support, except for root hubs @@ -2107,8 +2113,8 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_port *port_dev = NULL; struct usb_device *udev = *pdev; - struct usb_hub *hub; - int port1; + struct usb_hub *hub = NULL; + int port1 = 1; /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -4631,9 +4637,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, if (status != -ENODEV && port1 != unreliable_port && printk_ratelimit()) - dev_err(&udev->dev, "connect-debounce failed, port %d disabled\n", - port1); - + dev_err(&port_dev->dev, "connect-debounce failed\n"); portstatus &= ~USB_PORT_STAT_CONNECTION; unreliable_port = port1; } else { diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0ba9c335b584..7c9618e916e2 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1901,7 +1901,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg) { u32 dsts = readl(hsotg->regs + DSTS); - int ep0_mps = 0, ep_mps; + int ep0_mps = 0, ep_mps = 8; /* * This should signal the finish of the enumeration phase diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ef4936ff626c..9dcfbe7cd5f5 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -425,7 +425,7 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) static int dwc3_omap_extcon_register(struct dwc3_omap *omap) { - u32 ret; + int ret; struct device_node *node = omap->dev->of_node; struct extcon_dev *edev; diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index a186afeaa700..9add915d41f7 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -3,7 +3,7 @@ # subdir-ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG subdir-ccflags-$(CONFIG_USB_GADGET_VERBOSE) += -DVERBOSE_DEBUG -ccflags-y += -I$(PWD)/drivers/usb/gadget/udc +ccflags-y += -Idrivers/usb/gadget/udc obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o libcomposite-y := usbstring.o config.o epautoconf.o diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 6d91f21b52a6..83ae1065149d 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -2,8 +2,8 @@ # USB peripheral controller drivers # -ccflags-y := -I$(PWD)/drivers/usb/gadget/ -ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ +ccflags-y := -Idrivers/usb/gadget/ +ccflags-y += -Idrivers/usb/gadget/udc/ # USB Functions usb_f_acm-y := f_acm.o diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index d50adda913cf..6e6f87656e7b 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1127,10 +1127,7 @@ void gether_disconnect(struct gether *link) DBG(dev, "%s\n", __func__); - netif_tx_lock(dev->net); netif_stop_queue(dev->net); - netif_tx_unlock(dev->net); - netif_carrier_off(dev->net); /* disable endpoints, forcing (synchronous) completion diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..a5eb9a3fbb7a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -195,6 +195,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) printk(KERN_INFO "Failed to queue request (%d).\n", ret); usb_ep_set_halt(ep); spin_unlock_irqrestore(&video->queue.irqlock, flags); + uvc_queue_cancel(queue, 0); goto requeue; } spin_unlock_irqrestore(&video->queue.irqlock, flags); @@ -281,6 +282,7 @@ error: static int uvc_video_pump(struct uvc_video *video) { + struct uvc_video_queue *queue = &video->queue; struct usb_request *req; struct uvc_buffer *buf; unsigned long flags; @@ -322,6 +324,7 @@ uvc_video_pump(struct uvc_video *video) printk(KERN_INFO "Failed to queue request (%d)\n", ret); usb_ep_set_halt(video->ep); spin_unlock_irqrestore(&video->queue.irqlock, flags); + uvc_queue_cancel(queue, 0); break; } spin_unlock_irqrestore(&video->queue.irqlock, flags); diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile index a11aad5635df..edba2d1ee0f3 100644 --- a/drivers/usb/gadget/legacy/Makefile +++ b/drivers/usb/gadget/legacy/Makefile @@ -2,9 +2,9 @@ # USB gadget drivers # -ccflags-y := -I$(PWD)/drivers/usb/gadget/ -ccflags-y += -I$(PWD)/drivers/usb/gadget/udc/ -ccflags-y += -I$(PWD)/drivers/usb/gadget/function/ +ccflags-y := -Idrivers/usb/gadget/ +ccflags-y += -Idrivers/usb/gadget/udc/ +ccflags-y += -Idrivers/usb/gadget/function/ g_zero-y := zero.o g_audio-y := audio.o diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 986fc511a2ed..225e385a6160 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -222,10 +222,12 @@ static void dbgp_unbind(struct usb_gadget *gadget) { #ifdef CONFIG_USB_G_DBGP_SERIAL kfree(dbgp.serial); + dbgp.serial = NULL; #endif if (dbgp.req) { kfree(dbgp.req->buf); usb_ep_free_request(gadget->ep0, dbgp.req); + dbgp.req = NULL; } gadget->ep0->driver_data = NULL; diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 2e4ce7704908..e96077b8bf79 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -440,7 +440,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) value = -ENOMEM; kbuf = memdup_user(buf, len); - if (!kbuf) { + if (IS_ERR(kbuf)) { value = PTR_ERR(kbuf); goto free1; } diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 5151f947a4f5..34ebaa68504c 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -332,7 +332,7 @@ config USB_GOKU gadget drivers to also be dynamically linked. config USB_EG20T - tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" + tristate "Intel QUARK X1000/EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" depends on PCI help This is a USB device driver for EG20T PCH. @@ -353,6 +353,7 @@ config USB_EG20T ML7213/ML7831 is companion chip for Intel Atom E6xx series. ML7213/ML7831 is completely compatible for Intel EG20T PCH. + This driver can be used with Intel's Quark X1000 SOC platform # # LAST -- dummy/emulated controller # diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 906e65f0e4fa..c9fe67e29d35 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -1661,7 +1661,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) if (dma_status) { int i; - for (i = 1; i < USBA_NR_DMAS; i++) + for (i = 1; i <= USBA_NR_DMAS; i++) if (dma_status & (1 << i)) usba_dma_irq(udc, &udc->usba_ep[i]); } diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index d40255f784df..5c5d1adda7eb 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c @@ -1398,13 +1398,17 @@ static int fusb300_probe(struct platform_device *pdev) /* initialize udc */ fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); - if (fusb300 == NULL) + if (fusb300 == NULL) { + ret = -ENOMEM; goto clean_up; + } for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); - if (_ep[i] == NULL) + if (_ep[i] == NULL) { + ret = -ENOMEM; goto clean_up; + } fusb300->ep[i] = _ep[i]; } diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index eb8c3bedb57a..460d953c91b6 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -343,6 +343,7 @@ struct pch_vbus_gpio_data { * @setup_data: Received setup data * @phys_addr: of device memory * @base_addr: for mapped device memory + * @bar: Indicates which PCI BAR for USB regs * @irq: IRQ line for the device * @cfg_data: current cfg, intf, and alt in use * @vbus_gpio: GPIO informaton for detecting VBUS @@ -370,14 +371,17 @@ struct pch_udc_dev { struct usb_ctrlrequest setup_data; unsigned long phys_addr; void __iomem *base_addr; + unsigned bar; unsigned irq; struct pch_udc_cfg_data cfg_data; struct pch_vbus_gpio_data vbus_gpio; }; #define to_pch_udc(g) (container_of((g), struct pch_udc_dev, gadget)) +#define PCH_UDC_PCI_BAR_QUARK_X1000 0 #define PCH_UDC_PCI_BAR 1 #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 +#define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC 0x0939 #define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D #define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 @@ -3076,7 +3080,7 @@ static void pch_udc_remove(struct pci_dev *pdev) iounmap(dev->base_addr); if (dev->mem_region) release_mem_region(dev->phys_addr, - pci_resource_len(pdev, PCH_UDC_PCI_BAR)); + pci_resource_len(pdev, dev->bar)); if (dev->active) pci_disable_device(pdev); kfree(dev); @@ -3144,9 +3148,15 @@ static int pch_udc_probe(struct pci_dev *pdev, dev->active = 1; pci_set_drvdata(pdev, dev); + /* Determine BAR based on PCI ID */ + if (id->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC) + dev->bar = PCH_UDC_PCI_BAR_QUARK_X1000; + else + dev->bar = PCH_UDC_PCI_BAR; + /* PCI resource allocation */ - resource = pci_resource_start(pdev, 1); - len = pci_resource_len(pdev, 1); + resource = pci_resource_start(pdev, dev->bar); + len = pci_resource_len(pdev, dev->bar); if (!request_mem_region(resource, len, KBUILD_MODNAME)) { dev_err(&pdev->dev, "%s: pci device used already\n", __func__); @@ -3212,6 +3222,12 @@ finished: static const struct pci_device_id pch_udc_pcidev_id[] = { { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC), + .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, + .class_mask = 0xffffffff, + }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, .class_mask = 0xffffffff, diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 46008421c1ec..de2a8713b428 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1868,8 +1868,8 @@ static int r8a66597_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); - if (!reg) - return -ENODEV; + if (IS_ERR(reg)) + return PTR_ERR(reg); ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq = ires->start; diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index cc305c71ac3d..6130b7574908 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -1230,7 +1230,7 @@ int ehci_hub_control( if (selector == EHSET_TEST_SINGLE_STEP_SET_FEATURE) { spin_unlock_irqrestore(&ehci->lock, flags); retval = ehset_single_step_set_feature(hcd, - wIndex); + wIndex + 1); spin_lock_irqsave(&ehci->lock, flags); break; } diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 687d36608155..c22a3e15a16e 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -101,6 +101,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) /* AMD PLL quirk */ if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) xhci->quirks |= XHCI_AMD_PLL_FIX; + + if (pdev->vendor == PCI_VENDOR_ID_AMD) + xhci->quirks |= XHCI_TRUST_TX_LENGTH; + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_INTEL_HOST; @@ -151,6 +155,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_VIA) xhci->quirks |= XHCI_RESET_ON_RESUME; + /* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ + if (pdev->vendor == PCI_VENDOR_ID_VIA && + pdev->device == 0x3432) + xhci->quirks |= XHCI_BROKEN_STREAMS; + if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "QUIRK: Resetting on resume"); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 60fb52ae864b..abed30b82905 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -364,32 +364,6 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, } } -/* - * Find the segment that trb is in. Start searching in start_seg. - * If we must move past a segment that has a link TRB with a toggle cycle state - * bit set, then we will toggle the value pointed at by cycle_state. - */ -static struct xhci_segment *find_trb_seg( - struct xhci_segment *start_seg, - union xhci_trb *trb, int *cycle_state) -{ - struct xhci_segment *cur_seg = start_seg; - struct xhci_generic_trb *generic_trb; - - while (cur_seg->trbs > trb || - &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { - generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic; - if (generic_trb->field[3] & cpu_to_le32(LINK_TOGGLE)) - *cycle_state ^= 0x1; - cur_seg = cur_seg->next; - if (cur_seg == start_seg) - /* Looped over the entire list. Oops! */ - return NULL; - } - return cur_seg; -} - - static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, unsigned int stream_id) @@ -459,9 +433,12 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, struct xhci_virt_device *dev = xhci->devs[slot_id]; struct xhci_virt_ep *ep = &dev->eps[ep_index]; struct xhci_ring *ep_ring; - struct xhci_generic_trb *trb; + struct xhci_segment *new_seg; + union xhci_trb *new_deq; dma_addr_t addr; u64 hw_dequeue; + bool cycle_found = false; + bool td_last_trb_found = false; ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, ep_index, stream_id); @@ -486,45 +463,45 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, hw_dequeue = le64_to_cpu(ep_ctx->deq); } - /* Find virtual address and segment of hardware dequeue pointer */ - state->new_deq_seg = ep_ring->deq_seg; - state->new_deq_ptr = ep_ring->dequeue; - while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr) - != (dma_addr_t)(hw_dequeue & ~0xf)) { - next_trb(xhci, ep_ring, &state->new_deq_seg, - &state->new_deq_ptr); - if (state->new_deq_ptr == ep_ring->dequeue) { - WARN_ON(1); - return; - } - } + new_seg = ep_ring->deq_seg; + new_deq = ep_ring->dequeue; + state->new_cycle_state = hw_dequeue & 0x1; + /* - * Find cycle state for last_trb, starting at old cycle state of - * hw_dequeue. If there is only one segment ring, find_trb_seg() will - * return immediately and cannot toggle the cycle state if this search - * wraps around, so add one more toggle manually in that case. + * We want to find the pointer, segment and cycle state of the new trb + * (the one after current TD's last_trb). We know the cycle state at + * hw_dequeue, so walk the ring until both hw_dequeue and last_trb are + * found. */ - state->new_cycle_state = hw_dequeue & 0x1; - if (ep_ring->first_seg == ep_ring->first_seg->next && - cur_td->last_trb < state->new_deq_ptr) - state->new_cycle_state ^= 0x1; + do { + if (!cycle_found && xhci_trb_virt_to_dma(new_seg, new_deq) + == (dma_addr_t)(hw_dequeue & ~0xf)) { + cycle_found = true; + if (td_last_trb_found) + break; + } + if (new_deq == cur_td->last_trb) + td_last_trb_found = true; - state->new_deq_ptr = cur_td->last_trb; - xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Finding segment containing last TRB in TD."); - state->new_deq_seg = find_trb_seg(state->new_deq_seg, - state->new_deq_ptr, &state->new_cycle_state); - if (!state->new_deq_seg) { - WARN_ON(1); - return; - } + if (cycle_found && + TRB_TYPE_LINK_LE32(new_deq->generic.field[3]) && + new_deq->generic.field[3] & cpu_to_le32(LINK_TOGGLE)) + state->new_cycle_state ^= 0x1; + + next_trb(xhci, ep_ring, &new_seg, &new_deq); + + /* Search wrapped around, bail out */ + if (new_deq == ep->ring->dequeue) { + xhci_err(xhci, "Error: Failed finding new dequeue state\n"); + state->new_deq_seg = NULL; + state->new_deq_ptr = NULL; + return; + } + + } while (!cycle_found || !td_last_trb_found); - /* Increment to find next TRB after last_trb. Cycle if appropriate. */ - trb = &state->new_deq_ptr->generic; - if (TRB_TYPE_LINK_LE32(trb->field[3]) && - (trb->field[3] & cpu_to_le32(LINK_TOGGLE))) - state->new_cycle_state ^= 0x1; - next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); + state->new_deq_seg = new_seg; + state->new_deq_ptr = new_deq; /* Don't update the ring cycle state for the producer (us). */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, @@ -2487,7 +2464,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, * last TRB of the previous TD. The command completion handle * will take care the rest. */ - if (!event_seg && trb_comp_code == COMP_STOP_INVAL) { + if (!event_seg && (trb_comp_code == COMP_STOP || + trb_comp_code == COMP_STOP_INVAL)) { ret = 0; goto cleanup; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b6f21175b872..c020b094fe7d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2880,6 +2880,9 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, ep_index, ep->stopped_stream, ep->stopped_td, &deq_state); + if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg) + return; + /* HW with the reset endpoint quirk will use the saved dequeue state to * issue a configure endpoint command later. */ diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 06b5d77cd9ad..633caf643122 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3250,6 +3250,7 @@ static const struct usb_device_id sisusb_table[] = { { USB_DEVICE(0x0711, 0x0918) }, { USB_DEVICE(0x0711, 0x0920) }, { USB_DEVICE(0x0711, 0x0950) }, + { USB_DEVICE(0x0711, 0x5200) }, { USB_DEVICE(0x182d, 0x021c) }, { USB_DEVICE(0x182d, 0x0269) }, { } diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index 9aad00f11bd5..221faed9f074 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -96,7 +96,7 @@ static bool ux500_configure_channel(struct dma_channel *channel, struct musb *musb = ux500_channel->controller->private_data; dev_dbg(musb->controller, - "packet_sz=%d, mode=%d, dma_addr=0x%llu, len=%d is_tx=%d\n", + "packet_sz=%d, mode=%d, dma_addr=0x%llx, len=%d is_tx=%d\n", packet_sz, mode, (unsigned long long) dma_addr, len, ux500_channel->is_tx); diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c index ea9e705555df..f4b14bd97e14 100644 --- a/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -260,10 +260,8 @@ static int gpio_vbus_probe(struct platform_device *pdev) gpio_vbus->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); - if (!gpio_vbus->phy.otg) { - kfree(gpio_vbus); + if (!gpio_vbus->phy.otg) return -ENOMEM; - } platform_set_drvdata(pdev, gpio_vbus); gpio_vbus->dev = &pdev->dev; diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index e4108eec5ef4..afc09087ec36 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1601,8 +1601,8 @@ static int msm_otg_probe(struct platform_device *pdev) */ if (motg->phy_number) { phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); - if (IS_ERR(phy_select)) - return PTR_ERR(phy_select); + if (!phy_select) + return -ENOMEM; /* Enable second PHY with the OTG port */ writel(0x1, phy_select); } diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h index 68771bfd1825..80eedd45a20a 100644 --- a/drivers/usb/phy/phy-samsung-usb.h +++ b/drivers/usb/phy/phy-samsung-usb.h @@ -216,7 +216,7 @@ #define EXYNOS5_DRD_PHYPARAM1 (0x20) -#define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) +#define PHYPARAM1_PCS_TXDEEMPH_MASK (0x3f << 0) #define PHYPARAM1_PCS_TXDEEMPH (0x1c) #define EXYNOS5_DRD_PHYTERM (0x24) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 6d0f6080eceb..045cd309367a 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -232,6 +232,9 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) phy = __usb_find_phy_dev(dev, &phy_bind_list, index); if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { dev_dbg(dev, "unable to find transceiver\n"); + if (!IS_ERR(phy)) + phy = ERR_PTR(-ENODEV); + goto err0; } diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 216ce3078270..824ea5e7ec8b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -146,6 +146,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_BM_ATOM_NANO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, @@ -934,6 +935,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, + /* ekey Devices */ + { USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) }, /* Infineon Devices */ { USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) }, { } /* Terminating entry */ diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1e58d90a0b6c..70b0b1d88ae9 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -42,6 +42,8 @@ /* www.candapter.com Ewert Energy Systems CANdapter device */ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ +#define FTDI_BM_ATOM_NANO_PID 0xa559 /* Basic Micro ATOM Nano USB2Serial */ + /* * Texas Instruments XDS100v2 JTAG / BeagleBone A3 * http://processors.wiki.ti.com/index.php/XDS100 @@ -1378,3 +1380,8 @@ #define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ #define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ #define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ + +/* + * ekey biometric systems GmbH (http://ekey.net/) + */ +#define FTDI_EKEY_CONV_USB_PID 0xCB08 /* Converter USB */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a9688940543d..54a8120897a6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -275,8 +275,12 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_MC2718 0xffe8 #define ZTE_PRODUCT_AC2726 0xfff1 +#define ZTE_PRODUCT_CDMA_TECH 0xfffe +#define ZTE_PRODUCT_AC8710T 0xffff +#define ZTE_PRODUCT_MC2718 0xffe8 +#define ZTE_PRODUCT_AD3812 0xffeb +#define ZTE_PRODUCT_MC2716 0xffed #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -494,6 +498,10 @@ static void option_instat_callback(struct urb *urb); #define INOVIA_VENDOR_ID 0x20a6 #define INOVIA_SEW858 0x1105 +/* VIA Telecom */ +#define VIATELECOM_VENDOR_ID 0x15eb +#define VIATELECOM_PRODUCT_CDS7 0x0001 + /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -527,10 +535,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { .reserved = BIT(4), }; +static const struct option_blacklist_info zte_ad3812_z_blacklist = { + .sendsetup = BIT(0) | BIT(1) | BIT(2), +}; + static const struct option_blacklist_info zte_mc2718_z_blacklist = { .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), }; +static const struct option_blacklist_info zte_mc2716_z_blacklist = { + .sendsetup = BIT(1) | BIT(2) | BIT(3), +}; + static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; @@ -1070,6 +1086,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ @@ -1544,13 +1561,18 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) }, - /* NOTE: most ZTE CDMA devices should be driven by zte_ev, not option */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, @@ -1724,6 +1746,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, + { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -1916,6 +1939,8 @@ static void option_instat_callback(struct urb *urb) dev_dbg(dev, "%s: type %x req %x\n", __func__, req_pkt->bRequestType, req_pkt->bRequest); } + } else if (status == -ENOENT || status == -ESHUTDOWN) { + dev_dbg(dev, "%s: urb stopped: %d\n", __func__, status); } else dev_err(dev, "%s: error %d\n", __func__, status); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b3d5a35c0d4b..e9bad928039f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -45,6 +45,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 42bc082896ac..71fd9da1d6e7 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -22,6 +22,7 @@ #define PL2303_PRODUCT_ID_GPRS 0x0609 #define PL2303_PRODUCT_ID_HCR331 0x331a #define PL2303_PRODUCT_ID_MOTOROLA 0x0307 +#define PL2303_PRODUCT_ID_ZTEK 0xe1f1 #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 02de3110fe94..475723c006f9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -764,29 +764,39 @@ static int usb_serial_probe(struct usb_interface *interface, if (usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ dev_dbg(ddev, "found bulk in on endpoint %d\n", i); - bulk_in_endpoint[num_bulk_in] = endpoint; - ++num_bulk_in; + if (num_bulk_in < MAX_NUM_PORTS) { + bulk_in_endpoint[num_bulk_in] = endpoint; + ++num_bulk_in; + } } if (usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ dev_dbg(ddev, "found bulk out on endpoint %d\n", i); - bulk_out_endpoint[num_bulk_out] = endpoint; - ++num_bulk_out; + if (num_bulk_out < MAX_NUM_PORTS) { + bulk_out_endpoint[num_bulk_out] = endpoint; + ++num_bulk_out; + } } if (usb_endpoint_is_int_in(endpoint)) { /* we found a interrupt in endpoint */ dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; + if (num_interrupt_in < MAX_NUM_PORTS) { + interrupt_in_endpoint[num_interrupt_in] = + endpoint; + ++num_interrupt_in; + } } if (usb_endpoint_is_int_out(endpoint)) { /* we found an interrupt out endpoint */ dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); - interrupt_out_endpoint[num_interrupt_out] = endpoint; - ++num_interrupt_out; + if (num_interrupt_out < MAX_NUM_PORTS) { + interrupt_out_endpoint[num_interrupt_out] = + endpoint; + ++num_interrupt_out; + } } } @@ -809,8 +819,10 @@ static int usb_serial_probe(struct usb_interface *interface, if (usb_endpoint_is_int_in(endpoint)) { /* we found a interrupt in endpoint */ dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; + if (num_interrupt_in < MAX_NUM_PORTS) { + interrupt_in_endpoint[num_interrupt_in] = endpoint; + ++num_interrupt_in; + } } } } @@ -850,6 +862,11 @@ static int usb_serial_probe(struct usb_interface *interface, num_ports = type->num_ports; } + if (num_ports > MAX_NUM_PORTS) { + dev_warn(ddev, "too many ports requested: %d\n", num_ports); + num_ports = MAX_NUM_PORTS; + } + serial->num_ports = num_ports; serial->num_bulk_in = num_bulk_in; serial->num_bulk_out = num_bulk_out; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index e62f2dff8b7d..6c3734d2b45a 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -514,6 +514,10 @@ static void command_port_read_callback(struct urb *urb) dev_dbg(&urb->dev->dev, "%s - command_info is NULL, exiting.\n", __func__); return; } + if (!urb->actual_length) { + dev_dbg(&urb->dev->dev, "%s - empty response, exiting.\n", __func__); + return; + } if (status) { dev_dbg(&urb->dev->dev, "%s - nonzero urb status: %d\n", __func__, status); if (status != -ENOENT) @@ -534,7 +538,8 @@ static void command_port_read_callback(struct urb *urb) /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */ dev_dbg(&urb->dev->dev, "%s - event received\n", __func__); - } else if (data[0] == WHITEHEAT_GET_DTR_RTS) { + } else if ((data[0] == WHITEHEAT_GET_DTR_RTS) && + (urb->actual_length - 1 <= sizeof(command_info->result_buffer))) { memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1); command_info->command_finished = WHITEHEAT_CMD_COMPLETE; diff --git a/drivers/usb/serial/zte_ev.c b/drivers/usb/serial/zte_ev.c index e40ab739c4a6..1a132e9e947a 100644 --- a/drivers/usb/serial/zte_ev.c +++ b/drivers/usb/serial/zte_ev.c @@ -272,28 +272,8 @@ static void zte_ev_usb_serial_close(struct usb_serial_port *port) } static const struct usb_device_id id_table[] = { - /* AC8710, AC8710T */ - { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffff, 0xff, 0xff, 0xff) }, - /* AC8700 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xfffe, 0xff, 0xff, 0xff) }, /* MG880 */ { USB_DEVICE(0x19d2, 0xfffd) }, - { USB_DEVICE(0x19d2, 0xfffc) }, - { USB_DEVICE(0x19d2, 0xfffb) }, - /* AC8710_V3 */ - { USB_DEVICE(0x19d2, 0xfff6) }, - { USB_DEVICE(0x19d2, 0xfff7) }, - { USB_DEVICE(0x19d2, 0xfff8) }, - { USB_DEVICE(0x19d2, 0xfff9) }, - { USB_DEVICE(0x19d2, 0xffee) }, - /* AC2716, MC2716 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffed, 0xff, 0xff, 0xff) }, - /* AD3812 */ - { USB_DEVICE_AND_INTERFACE_INFO(0x19d2, 0xffeb, 0xff, 0xff, 0xff) }, - { USB_DEVICE(0x19d2, 0xffec) }, - { USB_DEVICE(0x05C6, 0x3197) }, - { USB_DEVICE(0x05C6, 0x6000) }, - { USB_DEVICE(0x05C6, 0x9008) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 80a5b366255f..7ef99b2f3aaf 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -922,6 +922,12 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +UNUSUAL_DEV( 0x06ca, 0x2003, 0x0100, 0x0100, + "Newer Technology", + "uSCSI", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + /* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, "RockChip", diff --git a/drivers/staging/usbip/Kconfig b/drivers/usb/usbip/Kconfig index bd99e9e47e50..bd99e9e47e50 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig diff --git a/drivers/staging/usbip/Makefile b/drivers/usb/usbip/Makefile index 9ecd61545be1..9ecd61545be1 100644 --- a/drivers/staging/usbip/Makefile +++ b/drivers/usb/usbip/Makefile diff --git a/drivers/staging/usbip/README b/drivers/usb/usbip/README index 41a2cf2e77a6..41a2cf2e77a6 100644 --- a/drivers/staging/usbip/README +++ b/drivers/usb/usbip/README diff --git a/drivers/staging/usbip/stub.h b/drivers/usb/usbip/stub.h index 266e2b0ce9a8..266e2b0ce9a8 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/usb/usbip/stub.h diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index 51d0c7188738..fac20e0434c0 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -26,33 +26,6 @@ #include "stub.h" /* - * Define device IDs here if you want to explicitly limit exportable devices. - * In most cases, wildcard matching will be okay because driver binding can be - * changed dynamically by a userland program. - */ -static struct usb_device_id stub_table[] = { -#if 0 - /* just an example */ - { USB_DEVICE(0x05ac, 0x0301) }, /* Mac 1 button mouse */ - { USB_DEVICE(0x0430, 0x0009) }, /* Plat Home Keyboard */ - { USB_DEVICE(0x059b, 0x0001) }, /* Iomega USB Zip 100 */ - { USB_DEVICE(0x04b3, 0x4427) }, /* IBM USB CD-ROM */ - { USB_DEVICE(0x05a9, 0xa511) }, /* LifeView USB cam */ - { USB_DEVICE(0x55aa, 0x0201) }, /* Imation card reader */ - { USB_DEVICE(0x046d, 0x0870) }, /* Qcam Express(QV-30) */ - { USB_DEVICE(0x04bb, 0x0101) }, /* IO-DATA HD 120GB */ - { USB_DEVICE(0x04bb, 0x0904) }, /* IO-DATA USB-ET/TX */ - { USB_DEVICE(0x04bb, 0x0201) }, /* IO-DATA USB-ET/TX */ - { USB_DEVICE(0x08bb, 0x2702) }, /* ONKYO USB Speaker */ - { USB_DEVICE(0x046d, 0x08b2) }, /* Logicool Qcam 4000 Pro */ -#endif - /* magic for wild card */ - { .driver_info = 1 }, - { 0, } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, stub_table); - -/* * usbip_status shows the status of usbip-host as long as this driver is bound * to the target device. */ diff --git a/drivers/staging/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 44ab43fc4fcc..44ab43fc4fcc 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 00e475c51a12..00e475c51a12 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index dbcabc9dbe0d..dbcabc9dbe0d 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index facaaf003f19..facaaf003f19 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index 4da3866a037d..86b08475c254 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -29,7 +29,7 @@ #include <linux/types.h> #include <linux/usb.h> #include <linux/wait.h> -#include "uapi/usbip.h" +#include <uapi/linux/usbip.h> #define USBIP_VERSION "1.0.0" diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c index 64933b993d7a..64933b993d7a 100644 --- a/drivers/staging/usbip/usbip_event.c +++ b/drivers/usb/usbip/usbip_event.c diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/usb/usbip/usbip_protocol.txt index 16b6fe27284c..16b6fe27284c 100644 --- a/drivers/staging/usbip/usbip_protocol.txt +++ b/drivers/usb/usbip/usbip_protocol.txt diff --git a/drivers/staging/usbip/vhci.h b/drivers/usb/usbip/vhci.h index a863a98a91ce..a863a98a91ce 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index c02374b6049c..c02374b6049c 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index 00e4a54308e4..00e4a54308e4 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 211f43f67ea2..211f43f67ea2 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index 409fd99f3257..409fd99f3257 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 3e2e4ed20157..e279015be466 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -2602,6 +2602,7 @@ static void wa_buf_in_cb(struct urb *urb) dev = &wa->usb_iface->dev; --(wa->active_buf_in_urbs); active_buf_in_urbs = wa->active_buf_in_urbs; + rpipe = xfer->ep->hcpriv; if (usb_pipeisoc(xfer->urb->pipe)) { struct usb_iso_packet_descriptor *iso_frame_desc = @@ -2659,7 +2660,6 @@ static void wa_buf_in_cb(struct urb *urb) resubmit_dti = (isoc_data_frame_count == urb_frame_count); } else if (active_buf_in_urbs == 0) { - rpipe = xfer->ep->hcpriv; dev_dbg(dev, "xfer %p 0x%08X#%u: data in done (%zu bytes)\n", xfer, wa_xfer_id(xfer), seg->index, @@ -2685,7 +2685,6 @@ static void wa_buf_in_cb(struct urb *urb) */ resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING; spin_lock_irqsave(&xfer->lock, flags); - rpipe = xfer->ep->hcpriv; if (printk_ratelimit()) dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n", xfer, wa_xfer_id(xfer), seg->index, diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index beadd3edaa17..a7b6217ac87b 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -24,6 +24,7 @@ #include <linux/list.h> #include <linux/amba/bus.h> #include <linux/amba/clcd.h> +#include <linux/bitops.h> #include <linux/clk.h> #include <linux/hardirq.h> #include <linux/dma-mapping.h> @@ -650,6 +651,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) { struct device_node *endpoint; int err; + unsigned int bpp; u32 max_bandwidth; u32 tft_r0b0g0[3]; @@ -667,11 +669,22 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", &max_bandwidth); - if (!err) - fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres * - fb->panel->mode.yres * fb->panel->mode.refresh); - else - fb->panel->bpp = 32; + if (!err) { + /* + * max_bandwidth is in bytes per second and pixclock in + * pico-seconds, so the maximum allowed bits per pixel is + * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000) + * Rearrange this calculation to avoid overflow and then ensure + * result is a valid format. + */ + bpp = max_bandwidth / (1000 / 8) + / PICOS2KHZ(fb->panel->mode.pixclock); + bpp = rounddown_pow_of_two(bpp); + if (bpp > 32) + bpp = 32; + } else + bpp = 32; + fb->panel->bpp = bpp; #ifdef CONFIG_CPU_BIG_ENDIAN fb->panel->cntl |= CNTL_BEBO; diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 92640d46770a..1d8bdb92939b 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -1102,12 +1102,14 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) timings = of_get_display_timings(display_np); if (!timings) { dev_err(dev, "failed to get display timings\n"); + ret = -EINVAL; goto put_display_node; } timings_np = of_find_node_by_name(display_np, "display-timings"); if (!timings_np) { dev_err(dev, "failed to find display-timings node\n"); + ret = -ENODEV; goto put_display_node; } diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 206a66b61072..59abdc6a97f6 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -273,7 +273,7 @@ static struct chips_init_reg chips_init_xr[] = { { 0xa8, 0x00 } }; -static void __init chips_hw_init(void) +static void chips_hw_init(void) { int i; diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index 788f6b37fce7..10c876c95772 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -419,7 +419,7 @@ static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, { u32 reg; - reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; + reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0x3ff; reg |= (((back_porch-1) & 0xff) << 24) | (((front_porch-1) & 0xff) << 16) | (((pulse_width-1) & 0x3f) << 10); diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 987edf110038..5c098d5b4043 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -236,6 +236,7 @@ timingfail: if (native_mode) of_node_put(native_mode); display_timings_release(disp); + disp = NULL; entryfail: kfree(disp); dispfail: @@ -793,6 +793,8 @@ void exit_aio(struct mm_struct *mm) for (i = 0; i < table->nr; ++i) { struct kioctx *ctx = table->table[i]; + struct completion requests_done = + COMPLETION_INITIALIZER_ONSTACK(requests_done); if (!ctx) continue; @@ -804,7 +806,10 @@ void exit_aio(struct mm_struct *mm) * that it needs to unmap the area, just set it to 0. */ ctx->mmap_size = 0; - kill_ioctx(mm, ctx, NULL); + kill_ioctx(mm, ctx, &requests_done); + + /* Wait until all IO for the context are done. */ + wait_for_completion(&requests_done); } RCU_INIT_POINTER(mm->ioctx_table, NULL); @@ -1111,6 +1116,12 @@ static long aio_read_events_ring(struct kioctx *ctx, tail = ring->tail; kunmap_atomic(ring); + /* + * Ensure that once we've read the current tail pointer, that + * we also see the events that were stored up to the tail. + */ + smp_rmb(); + pr_debug("h%u t%u m%u\n", head, tail, ctx->nr_events); if (head == tail) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 5b19760b1de5..b0c225cdb52c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1825,7 +1825,7 @@ ext4_group_first_block_no(struct super_block *sb, ext4_group_t group_no) /* * Special error return code only used by dx_probe() and its callers. */ -#define ERR_BAD_DX_DIR -75000 +#define ERR_BAD_DX_DIR (-(MAX_ERRNO - 1)) /* * Timeout and state flag for lazy initialization inode thread. @@ -2454,6 +2454,22 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize) up_write(&EXT4_I(inode)->i_data_sem); } +/* Update i_size, i_disksize. Requires i_mutex to avoid races with truncate */ +static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize) +{ + int changed = 0; + + if (newsize > inode->i_size) { + i_size_write(inode, newsize); + changed = 1; + } + if (newsize > EXT4_I(inode)->i_disksize) { + ext4_update_i_disksize(inode, newsize); + changed |= 2; + } + return changed; +} + struct ext4_group_info { unsigned long bb_state; struct rb_root bb_free_root; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 76c2df382b7d..74292a71b384 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4665,7 +4665,8 @@ retry: } static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, - ext4_lblk_t len, int flags, int mode) + ext4_lblk_t len, loff_t new_size, + int flags, int mode) { struct inode *inode = file_inode(file); handle_t *handle; @@ -4674,8 +4675,10 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, int retries = 0; struct ext4_map_blocks map; unsigned int credits; + loff_t epos; map.m_lblk = offset; + map.m_len = len; /* * Don't normalize the request if it can fit in one extent so * that it doesn't get unnecessarily split into multiple @@ -4690,9 +4693,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, credits = ext4_chunk_trans_blocks(inode, len); retry: - while (ret >= 0 && ret < len) { - map.m_lblk = map.m_lblk + ret; - map.m_len = len = len - ret; + while (ret >= 0 && len) { handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, credits); if (IS_ERR(handle)) { @@ -4709,6 +4710,21 @@ retry: ret2 = ext4_journal_stop(handle); break; } + map.m_lblk += ret; + map.m_len = len = len - ret; + epos = (loff_t)map.m_lblk << inode->i_blkbits; + inode->i_ctime = ext4_current_time(inode); + if (new_size) { + if (epos > new_size) + epos = new_size; + if (ext4_update_inode_size(inode, epos) & 0x1) + inode->i_mtime = inode->i_ctime; + } else { + if (epos > inode->i_size) + ext4_set_inode_flag(inode, + EXT4_INODE_EOFBLOCKS); + } + ext4_mark_inode_dirty(handle, inode); ret2 = ext4_journal_stop(handle); if (ret2) break; @@ -4731,7 +4747,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, loff_t new_size = 0; int ret = 0; int flags; - int partial; + int credits; + int partial_begin, partial_end; loff_t start, end; ext4_lblk_t lblk; struct address_space *mapping = inode->i_mapping; @@ -4771,7 +4788,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, if (start < offset || end > offset + len) return -EINVAL; - partial = (offset + len) & ((1 << blkbits) - 1); + partial_begin = offset & ((1 << blkbits) - 1); + partial_end = (offset + len) & ((1 << blkbits) - 1); lblk = start >> blkbits; max_blocks = (end >> blkbits); @@ -4805,7 +4823,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, * If we have a partial block after EOF we have to allocate * the entire block. */ - if (partial) + if (partial_end) max_blocks += 1; } @@ -4813,6 +4831,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, /* Now release the pages and zero block aligned part of pages*/ truncate_pagecache_range(inode, start, end - 1); + inode->i_mtime = inode->i_ctime = ext4_current_time(inode); /* Wait all existing dio workers, newcomers will block on i_mutex */ ext4_inode_block_unlocked_dio(inode); @@ -4825,13 +4844,22 @@ static long ext4_zero_range(struct file *file, loff_t offset, if (ret) goto out_dio; - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, flags, - mode); + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags, mode); if (ret) goto out_dio; } + if (!partial_begin && !partial_end) + goto out_dio; - handle = ext4_journal_start(inode, EXT4_HT_MISC, 4); + /* + * In worst case we have to writeout two nonadjacent unwritten + * blocks and update the inode + */ + credits = (2 * ext4_ext_index_trans_blocks(inode, 2)) + 1; + if (ext4_should_journal_data(inode)) + credits += 2; + handle = ext4_journal_start(inode, EXT4_HT_MISC, credits); if (IS_ERR(handle)) { ret = PTR_ERR(handle); ext4_std_error(inode->i_sb, ret); @@ -4839,12 +4867,8 @@ static long ext4_zero_range(struct file *file, loff_t offset, } inode->i_mtime = inode->i_ctime = ext4_current_time(inode); - if (new_size) { - if (new_size > i_size_read(inode)) - i_size_write(inode, new_size); - if (new_size > EXT4_I(inode)->i_disksize) - ext4_update_i_disksize(inode, new_size); + ext4_update_inode_size(inode, new_size); } else { /* * Mark that we allocate beyond EOF so the subsequent truncate @@ -4853,7 +4877,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, if ((offset + len) > i_size_read(inode)) ext4_set_inode_flag(inode, EXT4_INODE_EOFBLOCKS); } - ext4_mark_inode_dirty(handle, inode); /* Zero out partial block at the edges of the range */ @@ -4880,13 +4903,11 @@ out_mutex: long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); - handle_t *handle; loff_t new_size = 0; unsigned int max_blocks; int ret = 0; int flags; ext4_lblk_t lblk; - struct timespec tv; unsigned int blkbits = inode->i_blkbits; /* Return error if mode is not supported */ @@ -4937,36 +4958,15 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) goto out; } - ret = ext4_alloc_file_blocks(file, lblk, max_blocks, flags, mode); + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags, mode); if (ret) goto out; - handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); - if (IS_ERR(handle)) - goto out; - - tv = inode->i_ctime = ext4_current_time(inode); - - if (new_size) { - if (new_size > i_size_read(inode)) { - i_size_write(inode, new_size); - inode->i_mtime = tv; - } - if (new_size > EXT4_I(inode)->i_disksize) - ext4_update_i_disksize(inode, new_size); - } else { - /* - * Mark that we allocate beyond EOF so the subsequent truncate - * can proceed even if the new size is the same as i_size. - */ - if ((offset + len) > i_size_read(inode)) - ext4_set_inode_flag(inode, EXT4_INODE_EOFBLOCKS); + if (file->f_flags & O_SYNC && EXT4_SB(inode->i_sb)->s_journal) { + ret = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal, + EXT4_I(inode)->i_sync_tid); } - ext4_mark_inode_dirty(handle, inode); - if (file->f_flags & O_SYNC) - ext4_handle_sync(handle); - - ext4_journal_stop(handle); out: mutex_unlock(&inode->i_mutex); trace_ext4_fallocate_exit(inode, offset, max_blocks, ret); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 367a60c07cf0..3aa26e9117c4 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1055,27 +1055,11 @@ static int ext4_write_end(struct file *file, } else copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); - /* - * No need to use i_size_read() here, the i_size - * cannot change under us because we hole i_mutex. - * - * But it's important to update i_size while still holding page lock: + * it's important to update i_size while still holding page lock: * page writeout could otherwise come in and zero beyond i_size. */ - if (pos + copied > inode->i_size) { - i_size_write(inode, pos + copied); - i_size_changed = 1; - } - - if (pos + copied > EXT4_I(inode)->i_disksize) { - /* We need to mark inode dirty even if - * new_i_size is less that inode->i_size - * but greater than i_disksize. (hint delalloc) - */ - ext4_update_i_disksize(inode, (pos + copied)); - i_size_changed = 1; - } + i_size_changed = ext4_update_inode_size(inode, pos + copied); unlock_page(page); page_cache_release(page); @@ -1123,7 +1107,7 @@ static int ext4_journalled_write_end(struct file *file, int ret = 0, ret2; int partial = 0; unsigned from, to; - loff_t new_i_size; + int size_changed = 0; trace_ext4_journalled_write_end(inode, pos, len, copied); from = pos & (PAGE_CACHE_SIZE - 1); @@ -1146,20 +1130,18 @@ static int ext4_journalled_write_end(struct file *file, if (!partial) SetPageUptodate(page); } - new_i_size = pos + copied; - if (new_i_size > inode->i_size) - i_size_write(inode, pos+copied); + size_changed = ext4_update_inode_size(inode, pos + copied); ext4_set_inode_state(inode, EXT4_STATE_JDATA); EXT4_I(inode)->i_datasync_tid = handle->h_transaction->t_tid; - if (new_i_size > EXT4_I(inode)->i_disksize) { - ext4_update_i_disksize(inode, new_i_size); + unlock_page(page); + page_cache_release(page); + + if (size_changed) { ret2 = ext4_mark_inode_dirty(handle, inode); if (!ret) ret = ret2; } - unlock_page(page); - page_cache_release(page); if (pos + len > inode->i_size && ext4_can_truncate(inode)) /* if we have allocated more blocks and copied * less. We will have blocks allocated outside @@ -2095,6 +2077,7 @@ static int mpage_map_and_submit_extent(handle_t *handle, struct ext4_map_blocks *map = &mpd->map; int err; loff_t disksize; + int progress = 0; mpd->io_submit.io_end->offset = ((loff_t)map->m_lblk) << inode->i_blkbits; @@ -2111,8 +2094,11 @@ static int mpage_map_and_submit_extent(handle_t *handle, * is non-zero, a commit should free up blocks. */ if ((err == -ENOMEM) || - (err == -ENOSPC && ext4_count_free_clusters(sb))) + (err == -ENOSPC && ext4_count_free_clusters(sb))) { + if (progress) + goto update_disksize; return err; + } ext4_msg(sb, KERN_CRIT, "Delayed block allocation failed for " "inode %lu at logical offset %llu with" @@ -2129,15 +2115,17 @@ static int mpage_map_and_submit_extent(handle_t *handle, *give_up_on_write = true; return err; } + progress = 1; /* * Update buffer state, submit mapped pages, and get us new * extent to map */ err = mpage_map_and_submit_buffers(mpd); if (err < 0) - return err; + goto update_disksize; } while (map->m_len); +update_disksize: /* * Update on-disk size after IO is submitted. Races with * truncate are avoided by checking i_size under i_data_sem. diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 956027711faf..8b0f9ef517d6 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1412,6 +1412,8 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, int last = first + count - 1; struct super_block *sb = e4b->bd_sb; + if (WARN_ON(count == 0)) + return; BUG_ON(last >= (sb->s_blocksize << 3)); assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group)); /* Don't bother if the block group is corrupt. */ @@ -3221,6 +3223,8 @@ static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac) int err; if (pa == NULL) { + if (ac->ac_f_ex.fe_len == 0) + return; err = ext4_mb_load_buddy(ac->ac_sb, ac->ac_f_ex.fe_group, &e4b); if (err) { /* @@ -3235,6 +3239,7 @@ static void ext4_discard_allocated_blocks(struct ext4_allocation_context *ac) mb_free_blocks(ac->ac_inode, &e4b, ac->ac_f_ex.fe_start, ac->ac_f_ex.fe_len); ext4_unlock_group(ac->ac_sb, ac->ac_f_ex.fe_group); + ext4_mb_unload_buddy(&e4b); return; } if (pa->pa_type == MB_INODE_PA) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b147a67baa0d..90a3cdca3f88 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1227,7 +1227,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, buffer */ int num = 0; ext4_lblk_t nblocks; - int i, err; + int i, err = 0; int namelen; *res_dir = NULL; @@ -1264,7 +1264,11 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, * return. Otherwise, fall back to doing a search the * old fashioned way. */ - if (bh || (err != ERR_BAD_DX_DIR)) + if (err == -ENOENT) + return NULL; + if (err && err != ERR_BAD_DX_DIR) + return ERR_PTR(err); + if (bh) return bh; dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, " "falling back\n")); @@ -1295,6 +1299,11 @@ restart: } num++; bh = ext4_getblk(NULL, dir, b++, 0, &err); + if (unlikely(err)) { + if (ra_max == 0) + return ERR_PTR(err); + break; + } bh_use[ra_max] = bh; if (bh) ll_rw_block(READ | REQ_META | REQ_PRIO, @@ -1417,6 +1426,8 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi return ERR_PTR(-ENAMETOOLONG); bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); + if (IS_ERR(bh)) + return (struct dentry *) bh; inode = NULL; if (bh) { __u32 ino = le32_to_cpu(de->inode); @@ -1450,6 +1461,8 @@ struct dentry *ext4_get_parent(struct dentry *child) struct buffer_head *bh; bh = ext4_find_entry(child->d_inode, &dotdot, &de, NULL); + if (IS_ERR(bh)) + return (struct dentry *) bh; if (!bh) return ERR_PTR(-ENOENT); ino = le32_to_cpu(de->inode); @@ -2727,6 +2740,8 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) retval = -ENOENT; bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); + if (IS_ERR(bh)) + return PTR_ERR(bh); if (!bh) goto end_rmdir; @@ -2794,6 +2809,8 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) retval = -ENOENT; bh = ext4_find_entry(dir, &dentry->d_name, &de, NULL); + if (IS_ERR(bh)) + return PTR_ERR(bh); if (!bh) goto end_unlink; @@ -3121,6 +3138,8 @@ static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, struct ext4_dir_entry_2 *de; bh = ext4_find_entry(dir, d_name, &de, NULL); + if (IS_ERR(bh)) + return PTR_ERR(bh); if (bh) { retval = ext4_delete_entry(handle, dir, de, bh); brelse(bh); @@ -3128,7 +3147,8 @@ static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, return retval; } -static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent) +static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent, + int force_reread) { int retval; /* @@ -3140,7 +3160,8 @@ static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent) if (le32_to_cpu(ent->de->inode) != ent->inode->i_ino || ent->de->name_len != ent->dentry->d_name.len || strncmp(ent->de->name, ent->dentry->d_name.name, - ent->de->name_len)) { + ent->de->name_len) || + force_reread) { retval = ext4_find_delete_entry(handle, ent->dir, &ent->dentry->d_name); } else { @@ -3191,6 +3212,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, .dentry = new_dentry, .inode = new_dentry->d_inode, }; + int force_reread; int retval; dquot_initialize(old.dir); @@ -3202,6 +3224,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, dquot_initialize(new.inode); old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); + if (IS_ERR(old.bh)) + return PTR_ERR(old.bh); /* * Check for inode number is _not_ due to possible IO errors. * We might rmdir the source, keep it as pwd of some process @@ -3214,6 +3238,10 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, &new.de, &new.inlined); + if (IS_ERR(new.bh)) { + retval = PTR_ERR(new.bh); + goto end_rename; + } if (new.bh) { if (!new.inode) { brelse(new.bh); @@ -3246,6 +3274,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, if (retval) goto end_rename; } + /* + * If we're renaming a file within an inline_data dir and adding or + * setting the new dirent causes a conversion from inline_data to + * extents/blockmap, we need to force the dirent delete code to + * re-read the directory, or else we end up trying to delete a dirent + * from what is now the extent tree root (or a block map). + */ + force_reread = (new.dir->i_ino == old.dir->i_ino && + ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA)); if (!new.bh) { retval = ext4_add_entry(handle, new.dentry, old.inode); if (retval) @@ -3256,6 +3293,9 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, if (retval) goto end_rename; } + if (force_reread) + force_reread = !ext4_test_inode_flag(new.dir, + EXT4_INODE_INLINE_DATA); /* * Like most other Unix systems, set the ctime for inodes on a @@ -3267,7 +3307,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, /* * ok, that's it */ - ext4_rename_delete(handle, &old); + ext4_rename_delete(handle, &old, force_reread); if (new.inode) { ext4_dec_count(handle, new.inode); @@ -3330,6 +3370,8 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry, old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, &old.inlined); + if (IS_ERR(old.bh)) + return PTR_ERR(old.bh); /* * Check for inode number is _not_ due to possible IO errors. * We might rmdir the source, keep it as pwd of some process @@ -3342,6 +3384,10 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry, new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, &new.de, &new.inlined); + if (IS_ERR(new.bh)) { + retval = PTR_ERR(new.bh); + goto end_rename; + } /* RENAME_EXCHANGE case: old *and* new must both exist */ if (!new.bh || le32_to_cpu(new.de->inode) != new.inode->i_ino) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 32b43ad154b9..0b28b36e7915 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3181,9 +3181,9 @@ static int set_journal_csum_feature_set(struct super_block *sb) if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { - /* journal checksum v2 */ + /* journal checksum v3 */ compat = 0; - incompat = JBD2_FEATURE_INCOMPAT_CSUM_V2; + incompat = JBD2_FEATURE_INCOMPAT_CSUM_V3; } else { /* journal checksum v1 */ compat = JBD2_FEATURE_COMPAT_CHECKSUM; @@ -3205,6 +3205,7 @@ static int set_journal_csum_feature_set(struct super_block *sb) jbd2_journal_clear_features(sbi->s_journal, JBD2_FEATURE_COMPAT_CHECKSUM, 0, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT | + JBD2_FEATURE_INCOMPAT_CSUM_V3 | JBD2_FEATURE_INCOMPAT_CSUM_V2); } diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index 214fe1054fce..736a348509f7 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -23,7 +23,7 @@ config F2FS_STAT_FS mounted as f2fs. Each file shows the whole f2fs information. /sys/kernel/debug/f2fs/status includes: - - major file system information managed by f2fs currently + - major filesystem information managed by f2fs currently - average SIT information about whole segments - current memory footprint consumed by f2fs. @@ -68,6 +68,6 @@ config F2FS_CHECK_FS bool "F2FS consistency checking feature" depends on F2FS_FS help - Enables BUG_ONs which check the file system consistency in runtime. + Enables BUG_ONs which check the filesystem consistency in runtime. If you want to improve the performance, say N. diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 6aeed5bada52..ec3b7a5381fa 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -160,14 +160,11 @@ static int f2fs_write_meta_page(struct page *page, goto redirty_out; if (wbc->for_reclaim) goto redirty_out; - - /* Should not write any meta pages, if any IO error was occurred */ - if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG))) - goto no_write; + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; f2fs_wait_on_page_writeback(page, META); write_meta_page(sbi, page); -no_write: dec_page_count(sbi, F2FS_DIRTY_META); unlock_page(page); return 0; @@ -348,7 +345,7 @@ bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode) return e ? true : false; } -static void release_dirty_inode(struct f2fs_sb_info *sbi) +void release_dirty_inode(struct f2fs_sb_info *sbi) { struct ino_entry *e, *tmp; int i; @@ -446,8 +443,8 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) struct f2fs_orphan_block *orphan_blk = NULL; unsigned int nentries = 0; unsigned short index; - unsigned short orphan_blocks = (unsigned short)((sbi->n_orphans + - (F2FS_ORPHANS_PER_BLOCK - 1)) / F2FS_ORPHANS_PER_BLOCK); + unsigned short orphan_blocks = + (unsigned short)GET_ORPHAN_BLOCKS(sbi->n_orphans); struct page *page = NULL; struct ino_entry *orphan = NULL; @@ -737,7 +734,7 @@ retry: /* * Freeze all the FS-operations for checkpoint. */ -static void block_operations(struct f2fs_sb_info *sbi) +static int block_operations(struct f2fs_sb_info *sbi) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, @@ -745,6 +742,7 @@ static void block_operations(struct f2fs_sb_info *sbi) .for_reclaim = 0, }; struct blk_plug plug; + int err = 0; blk_start_plug(&plug); @@ -754,11 +752,15 @@ retry_flush_dents: if (get_pages(sbi, F2FS_DIRTY_DENTS)) { f2fs_unlock_all(sbi); sync_dirty_dir_inodes(sbi); + if (unlikely(f2fs_cp_error(sbi))) { + err = -EIO; + goto out; + } goto retry_flush_dents; } /* - * POR: we should ensure that there is no dirty node pages + * POR: we should ensure that there are no dirty node pages * until finishing nat/sit flush. */ retry_flush_nodes: @@ -767,9 +769,16 @@ retry_flush_nodes: if (get_pages(sbi, F2FS_DIRTY_NODES)) { up_write(&sbi->node_write); sync_node_pages(sbi, 0, &wbc); + if (unlikely(f2fs_cp_error(sbi))) { + f2fs_unlock_all(sbi); + err = -EIO; + goto out; + } goto retry_flush_nodes; } +out: blk_finish_plug(&plug); + return err; } static void unblock_operations(struct f2fs_sb_info *sbi) @@ -813,8 +822,11 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); /* Flush all the NAT/SIT pages */ - while (get_pages(sbi, F2FS_DIRTY_META)) + while (get_pages(sbi, F2FS_DIRTY_META)) { sync_meta_pages(sbi, META, LONG_MAX); + if (unlikely(f2fs_cp_error(sbi))) + return; + } next_free_nid(sbi, &last_nid); @@ -825,7 +837,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ckpt->elapsed_time = cpu_to_le64(get_mtime(sbi)); ckpt->valid_block_count = cpu_to_le64(valid_user_blocks(sbi)); ckpt->free_segment_count = cpu_to_le32(free_segments(sbi)); - for (i = 0; i < 3; i++) { + for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) { ckpt->cur_node_segno[i] = cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_NODE)); ckpt->cur_node_blkoff[i] = @@ -833,7 +845,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) ckpt->alloc_type[i + CURSEG_HOT_NODE] = curseg_alloc_type(sbi, i + CURSEG_HOT_NODE); } - for (i = 0; i < 3; i++) { + for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { ckpt->cur_data_segno[i] = cpu_to_le32(curseg_segno(sbi, i + CURSEG_HOT_DATA)); ckpt->cur_data_blkoff[i] = @@ -848,24 +860,23 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* 2 cp + n data seg summary + orphan inode blocks */ data_sum_blocks = npages_for_summary_flush(sbi); - if (data_sum_blocks < 3) + if (data_sum_blocks < NR_CURSEG_DATA_TYPE) set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); else clear_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); - orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1) - / F2FS_ORPHANS_PER_BLOCK; + orphan_blocks = GET_ORPHAN_BLOCKS(sbi->n_orphans); ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + orphan_blocks); if (is_umount) { set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); - ckpt->cp_pack_total_block_count = cpu_to_le32(2 + + ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ cp_payload_blks + data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE); } else { clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); - ckpt->cp_pack_total_block_count = cpu_to_le32(2 + + ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + cp_payload_blks + data_sum_blocks + orphan_blocks); } @@ -924,6 +935,9 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* wait for previous submitted node/meta pages writeback */ wait_on_all_pages_writeback(sbi); + if (unlikely(f2fs_cp_error(sbi))) + return; + filemap_fdatawait_range(NODE_MAPPING(sbi), 0, LONG_MAX); filemap_fdatawait_range(META_MAPPING(sbi), 0, LONG_MAX); @@ -934,15 +948,17 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) /* Here, we only have one bio having CP pack */ sync_meta_pages(sbi, META_FLUSH, LONG_MAX); - if (!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG)) { - clear_prefree_segments(sbi); - release_dirty_inode(sbi); - F2FS_RESET_SB_DIRT(sbi); - } + release_dirty_inode(sbi); + + if (unlikely(f2fs_cp_error(sbi))) + return; + + clear_prefree_segments(sbi); + F2FS_RESET_SB_DIRT(sbi); } /* - * We guarantee that this checkpoint procedure should not fail. + * We guarantee that this checkpoint procedure will not fail. */ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) { @@ -952,7 +968,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) trace_f2fs_write_checkpoint(sbi->sb, is_umount, "start block_ops"); mutex_lock(&sbi->cp_mutex); - block_operations(sbi); + + if (!sbi->s_dirty) + goto out; + if (unlikely(f2fs_cp_error(sbi))) + goto out; + if (block_operations(sbi)) + goto out; trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops"); @@ -976,9 +998,9 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) do_checkpoint(sbi, is_umount); unblock_operations(sbi); - mutex_unlock(&sbi->cp_mutex); - stat_inc_cp_count(sbi->stat_info); +out: + mutex_unlock(&sbi->cp_mutex); trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint"); } @@ -999,8 +1021,8 @@ void init_ino_entry_info(struct f2fs_sb_info *sbi) * for cp pack we can have max 1020*504 orphan entries */ sbi->n_orphans = 0; - sbi->max_orphans = (sbi->blocks_per_seg - 2 - NR_CURSEG_TYPE) - * F2FS_ORPHANS_PER_BLOCK; + sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_TYPE) * F2FS_ORPHANS_PER_BLOCK; } int __init create_checkpoint_caches(void) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 03313099c51c..76de83e25a89 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -53,7 +53,7 @@ static void f2fs_write_end_io(struct bio *bio, int err) struct page *page = bvec->bv_page; if (unlikely(err)) { - SetPageError(page); + set_page_dirty(page); set_bit(AS_EIO, &page->mapping->flags); f2fs_stop_checkpoint(sbi); } @@ -691,7 +691,7 @@ get_next: allocated = true; blkaddr = dn.data_blkaddr; } - /* Give more consecutive addresses for the read ahead */ + /* Give more consecutive addresses for the readahead */ if (blkaddr == (bh_result->b_blocknr + ofs)) { ofs++; dn.ofs_in_node++; @@ -739,7 +739,7 @@ static int f2fs_read_data_page(struct file *file, struct page *page) trace_f2fs_readpage(page, DATA); - /* If the file has inline data, try to read it directlly */ + /* If the file has inline data, try to read it directly */ if (f2fs_has_inline_data(inode)) ret = f2fs_read_inline_data(inode, page); else @@ -836,10 +836,19 @@ write: /* Dentry blocks are controlled by checkpoint */ if (S_ISDIR(inode->i_mode)) { + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; err = do_write_data_page(page, &fio); goto done; } + /* we should bypass data pages to proceed the kworkder jobs */ + if (unlikely(f2fs_cp_error(sbi))) { + SetPageError(page); + unlock_page(page); + return 0; + } + if (!wbc->for_reclaim) need_balance_fs = true; else if (has_not_enough_free_secs(sbi, 0)) @@ -927,7 +936,7 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) if (to > inode->i_size) { truncate_pagecache(inode, inode->i_size); - truncate_blocks(inode, inode->i_size); + truncate_blocks(inode, inode->i_size, true); } } @@ -946,7 +955,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, f2fs_balance_fs(sbi); repeat: - err = f2fs_convert_inline_data(inode, pos + len); + err = f2fs_convert_inline_data(inode, pos + len, NULL); if (err) goto fail; diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index a441ba33be11..fecebdbfd781 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -32,7 +32,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) struct f2fs_stat_info *si = F2FS_STAT(sbi); int i; - /* valid check of the segment numbers */ + /* validation check of the segment numbers */ si->hit_ext = sbi->read_hit_ext; si->total_ext = sbi->total_hit_ext; si->ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); @@ -152,7 +152,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->base_mem += NR_DIRTY_TYPE * f2fs_bitmap_size(TOTAL_SEGS(sbi)); si->base_mem += f2fs_bitmap_size(TOTAL_SECS(sbi)); - /* buld nm */ + /* build nm */ si->base_mem += sizeof(struct f2fs_nm_info); si->base_mem += __bitmap_size(sbi, NAT_BITMAP); diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index bcf893c3d903..155fb056b7f1 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -124,7 +124,7 @@ static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, /* * For the most part, it should be a bug when name_len is zero. - * We stop here for figuring out where the bugs are occurred. + * We stop here for figuring out where the bugs has occurred. */ f2fs_bug_on(!de->name_len); @@ -391,7 +391,7 @@ put_error: error: /* once the failed inode becomes a bad inode, i_mode is S_IFREG */ truncate_inode_pages(&inode->i_data, 0); - truncate_blocks(inode, 0); + truncate_blocks(inode, 0, false); remove_dirty_dir_inode(inode); remove_inode_page(inode); return ERR_PTR(err); @@ -563,7 +563,7 @@ fail: } /* - * It only removes the dentry from the dentry page,corresponding name + * It only removes the dentry from the dentry page, corresponding name * entry in name page does not need to be touched during deletion. */ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4dab5338a97a..e921242186f6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -24,7 +24,7 @@ #define f2fs_bug_on(condition) BUG_ON(condition) #define f2fs_down_write(x, y) down_write_nest_lock(x, y) #else -#define f2fs_bug_on(condition) +#define f2fs_bug_on(condition) WARN_ON(condition) #define f2fs_down_write(x, y) down_write(x) #endif @@ -395,7 +395,7 @@ enum count_type { }; /* - * The below are the page types of bios used in submti_bio(). + * The below are the page types of bios used in submit_bio(). * The available types are: * DATA User data pages. It operates as async mode. * NODE Node pages. It operates as async mode. @@ -470,7 +470,7 @@ struct f2fs_sb_info { struct list_head dir_inode_list; /* dir inode list */ spinlock_t dir_inode_lock; /* for dir inode list lock */ - /* basic file system units */ + /* basic filesystem units */ unsigned int log_sectors_per_block; /* log2 sectors per block */ unsigned int log_blocksize; /* log2 block size */ unsigned int blocksize; /* block size */ @@ -799,7 +799,7 @@ static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) /* * odd numbered checkpoint should at cp segment 0 - * and even segent must be at cp segment 1 + * and even segment must be at cp segment 1 */ if (!(ckpt_version & 1)) start_addr += sbi->blocks_per_seg; @@ -1096,6 +1096,11 @@ static inline int f2fs_readonly(struct super_block *sb) return sb->s_flags & MS_RDONLY; } +static inline bool f2fs_cp_error(struct f2fs_sb_info *sbi) +{ + return is_set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); +} + static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi) { set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); @@ -1117,7 +1122,7 @@ static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi) */ int f2fs_sync_file(struct file *, loff_t, loff_t, int); void truncate_data_blocks(struct dnode_of_data *); -int truncate_blocks(struct inode *, u64); +int truncate_blocks(struct inode *, u64, bool); void f2fs_truncate(struct inode *); int f2fs_getattr(struct vfsmount *, struct dentry *, struct kstat *); int f2fs_setattr(struct dentry *, struct iattr *); @@ -1202,10 +1207,8 @@ int sync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *); bool alloc_nid(struct f2fs_sb_info *, nid_t *); void alloc_nid_done(struct f2fs_sb_info *, nid_t); void alloc_nid_failed(struct f2fs_sb_info *, nid_t); -void recover_node_page(struct f2fs_sb_info *, struct page *, - struct f2fs_summary *, struct node_info *, block_t); void recover_inline_xattr(struct inode *, struct page *); -bool recover_xattr_data(struct inode *, struct page *, block_t); +void recover_xattr_data(struct inode *, struct page *, block_t); int recover_inode_page(struct f2fs_sb_info *, struct page *); int restore_node_summary(struct f2fs_sb_info *, unsigned int, struct f2fs_summary_block *); @@ -1238,8 +1241,6 @@ void write_data_page(struct page *, struct dnode_of_data *, block_t *, void rewrite_data_page(struct page *, block_t, struct f2fs_io_info *); void recover_data_page(struct f2fs_sb_info *, struct page *, struct f2fs_summary *, block_t, block_t); -void rewrite_node_page(struct f2fs_sb_info *, struct page *, - struct f2fs_summary *, block_t, block_t); void allocate_data_block(struct f2fs_sb_info *, struct page *, block_t, block_t *, struct f2fs_summary *, int); void f2fs_wait_on_page_writeback(struct page *, enum page_type); @@ -1262,6 +1263,7 @@ int ra_meta_pages(struct f2fs_sb_info *, int, int, int); long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type); void remove_dirty_inode(struct f2fs_sb_info *, nid_t, int type); +void release_dirty_inode(struct f2fs_sb_info *); bool exist_written_data(struct f2fs_sb_info *, nid_t, int); int acquire_orphan_inode(struct f2fs_sb_info *); void release_orphan_inode(struct f2fs_sb_info *); @@ -1439,8 +1441,8 @@ extern const struct inode_operations f2fs_special_inode_operations; */ bool f2fs_may_inline(struct inode *); int f2fs_read_inline_data(struct inode *, struct page *); -int f2fs_convert_inline_data(struct inode *, pgoff_t); +int f2fs_convert_inline_data(struct inode *, pgoff_t, struct page *); int f2fs_write_inline_data(struct inode *, struct page *, unsigned int); void truncate_inline_data(struct inode *, u64); -int recover_inline_data(struct inode *, struct page *); +bool recover_inline_data(struct inode *, struct page *); #endif diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 208f1a9bd569..060aee65aee8 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -41,6 +41,11 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma, sb_start_pagefault(inode->i_sb); + /* force to convert with normal data indices */ + err = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1, page); + if (err) + goto out; + /* block allocation */ f2fs_lock_op(sbi); set_new_dnode(&dn, inode, NULL, NULL, 0); @@ -110,6 +115,25 @@ static int get_parent_ino(struct inode *inode, nid_t *pino) return 1; } +static inline bool need_do_checkpoint(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); + bool need_cp = false; + + if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) + need_cp = true; + else if (file_wrong_pino(inode)) + need_cp = true; + else if (!space_for_roll_forward(sbi)) + need_cp = true; + else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) + need_cp = true; + else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi))) + need_cp = true; + + return need_cp; +} + int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file->f_mapping->host; @@ -154,23 +178,12 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) /* guarantee free sections for fsync */ f2fs_balance_fs(sbi); - down_read(&fi->i_sem); - /* * Both of fdatasync() and fsync() are able to be recovered from * sudden-power-off. */ - if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1) - need_cp = true; - else if (file_wrong_pino(inode)) - need_cp = true; - else if (!space_for_roll_forward(sbi)) - need_cp = true; - else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) - need_cp = true; - else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi))) - need_cp = true; - + down_read(&fi->i_sem); + need_cp = need_do_checkpoint(inode); up_read(&fi->i_sem); if (need_cp) { @@ -288,7 +301,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence) if (err && err != -ENOENT) { goto fail; } else if (err == -ENOENT) { - /* direct node is not exist */ + /* direct node does not exists */ if (whence == SEEK_DATA) { pgofs = PGOFS_OF_NEXT_DNODE(pgofs, F2FS_I(inode)); @@ -417,7 +430,7 @@ out: f2fs_put_page(page, 1); } -int truncate_blocks(struct inode *inode, u64 from) +int truncate_blocks(struct inode *inode, u64 from, bool lock) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); unsigned int blocksize = inode->i_sb->s_blocksize; @@ -433,14 +446,16 @@ int truncate_blocks(struct inode *inode, u64 from) free_from = (pgoff_t) ((from + blocksize - 1) >> (sbi->log_blocksize)); - f2fs_lock_op(sbi); + if (lock) + f2fs_lock_op(sbi); set_new_dnode(&dn, inode, NULL, NULL, 0); err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE); if (err) { if (err == -ENOENT) goto free_next; - f2fs_unlock_op(sbi); + if (lock) + f2fs_unlock_op(sbi); trace_f2fs_truncate_blocks_exit(inode, err); return err; } @@ -458,7 +473,8 @@ int truncate_blocks(struct inode *inode, u64 from) f2fs_put_dnode(&dn); free_next: err = truncate_inode_blocks(inode, free_from); - f2fs_unlock_op(sbi); + if (lock) + f2fs_unlock_op(sbi); done: /* lastly zero out the first data page */ truncate_partial_data_page(inode, from); @@ -475,7 +491,7 @@ void f2fs_truncate(struct inode *inode) trace_f2fs_truncate(inode); - if (!truncate_blocks(inode, i_size_read(inode))) { + if (!truncate_blocks(inode, i_size_read(inode), true)) { inode->i_mtime = inode->i_ctime = CURRENT_TIME; mark_inode_dirty(inode); } @@ -533,7 +549,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { - err = f2fs_convert_inline_data(inode, attr->ia_size); + err = f2fs_convert_inline_data(inode, attr->ia_size, NULL); if (err) return err; @@ -622,7 +638,7 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) loff_t off_start, off_end; int ret = 0; - ret = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1); + ret = f2fs_convert_inline_data(inode, MAX_INLINE_DATA + 1, NULL); if (ret) return ret; @@ -678,7 +694,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset, if (ret) return ret; - ret = f2fs_convert_inline_data(inode, offset + len); + ret = f2fs_convert_inline_data(inode, offset + len, NULL); if (ret) return ret; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index d7947d90ccc3..943a31db7cc3 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -58,7 +58,7 @@ static int gc_thread_func(void *data) * 3. IO subsystem is idle by checking the # of requests in * bdev's request list. * - * Note) We have to avoid triggering GCs too much frequently. + * Note) We have to avoid triggering GCs frequently. * Because it is possible that some segments can be * invalidated soon after by user update or deletion. * So, I'd like to wait some time to collect dirty segments. @@ -222,7 +222,7 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno) u = (vblocks * 100) >> sbi->log_blocks_per_seg; - /* Handle if the system time is changed by user */ + /* Handle if the system time has changed by the user */ if (mtime < sit_i->min_mtime) sit_i->min_mtime = mtime; if (mtime > sit_i->max_mtime) @@ -593,7 +593,7 @@ next_step: if (phase == 2) { inode = f2fs_iget(sb, dni.ino); - if (IS_ERR(inode)) + if (IS_ERR(inode) || is_bad_inode(inode)) continue; start_bidx = start_bidx_of_node(nofs, F2FS_I(inode)); @@ -693,7 +693,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi) gc_more: if (unlikely(!(sbi->sb->s_flags & MS_ACTIVE))) goto stop; - if (unlikely(is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ERROR_FLAG))) + if (unlikely(f2fs_cp_error(sbi))) goto stop; if (gc_type == BG_GC && has_not_enough_free_secs(sbi, nfree)) { diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h index 5d5eb6047bf4..16f0b2b22999 100644 --- a/fs/f2fs/gc.h +++ b/fs/f2fs/gc.h @@ -91,7 +91,7 @@ static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) block_t invalid_user_blocks = sbi->user_block_count - written_block_count(sbi); /* - * Background GC is triggered with the following condition. + * Background GC is triggered with the following conditions. * 1. There are a number of invalid blocks. * 2. There is not enough free space. */ diff --git a/fs/f2fs/hash.c b/fs/f2fs/hash.c index 948d17bf7281..a844fcfb9a8d 100644 --- a/fs/f2fs/hash.c +++ b/fs/f2fs/hash.c @@ -42,7 +42,8 @@ static void TEA_transform(unsigned int buf[4], unsigned int const in[]) buf[1] += b1; } -static void str2hashbuf(const char *msg, size_t len, unsigned int *buf, int num) +static void str2hashbuf(const unsigned char *msg, size_t len, + unsigned int *buf, int num) { unsigned pad, val; int i; @@ -73,9 +74,9 @@ f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info) { __u32 hash; f2fs_hash_t f2fs_hash; - const char *p; + const unsigned char *p; __u32 in[8], buf[4]; - const char *name = name_info->name; + const unsigned char *name = name_info->name; size_t len = name_info->len; if ((len <= 2) && (name[0] == '.') && diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 5beeccef9ae1..3e8ecdf3742b 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -68,7 +68,7 @@ out: static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) { - int err; + int err = 0; struct page *ipage; struct dnode_of_data dn; void *src_addr, *dst_addr; @@ -86,6 +86,10 @@ static int __f2fs_convert_inline_data(struct inode *inode, struct page *page) goto out; } + /* someone else converted inline_data already */ + if (!f2fs_has_inline_data(inode)) + goto out; + /* * i_addr[0] is not used for inline data, * so reserving new block will not destroy inline data @@ -124,9 +128,10 @@ out: return err; } -int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) +int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size, + struct page *page) { - struct page *page; + struct page *new_page = page; int err; if (!f2fs_has_inline_data(inode)) @@ -134,17 +139,20 @@ int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size) else if (to_size <= MAX_INLINE_DATA) return 0; - page = grab_cache_page(inode->i_mapping, 0); - if (!page) - return -ENOMEM; + if (!page || page->index != 0) { + new_page = grab_cache_page(inode->i_mapping, 0); + if (!new_page) + return -ENOMEM; + } - err = __f2fs_convert_inline_data(inode, page); - f2fs_put_page(page, 1); + err = __f2fs_convert_inline_data(inode, new_page); + if (!page || page->index != 0) + f2fs_put_page(new_page, 1); return err; } int f2fs_write_inline_data(struct inode *inode, - struct page *page, unsigned size) + struct page *page, unsigned size) { void *src_addr, *dst_addr; struct page *ipage; @@ -199,7 +207,7 @@ void truncate_inline_data(struct inode *inode, u64 from) f2fs_put_page(ipage, 1); } -int recover_inline_data(struct inode *inode, struct page *npage) +bool recover_inline_data(struct inode *inode, struct page *npage) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct f2fs_inode *ri = NULL; @@ -218,7 +226,7 @@ int recover_inline_data(struct inode *inode, struct page *npage) ri = F2FS_INODE(npage); if (f2fs_has_inline_data(inode) && - ri && ri->i_inline & F2FS_INLINE_DATA) { + ri && (ri->i_inline & F2FS_INLINE_DATA)) { process_inline: ipage = get_node_page(sbi, inode->i_ino); f2fs_bug_on(IS_ERR(ipage)); @@ -230,7 +238,7 @@ process_inline: memcpy(dst_addr, src_addr, MAX_INLINE_DATA); update_inode(inode, ipage); f2fs_put_page(ipage, 1); - return -1; + return true; } if (f2fs_has_inline_data(inode)) { @@ -242,10 +250,10 @@ process_inline: clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); update_inode(inode, ipage); f2fs_put_page(ipage, 1); - } else if (ri && ri->i_inline & F2FS_INLINE_DATA) { - truncate_blocks(inode, 0); + } else if (ri && (ri->i_inline & F2FS_INLINE_DATA)) { + truncate_blocks(inode, 0, false); set_inode_flag(F2FS_I(inode), FI_INLINE_DATA); goto process_inline; } - return 0; + return false; } diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 27b03776ffd2..ee103fd7283c 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -134,9 +134,7 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, return 0; out: clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); + iget_failed(inode); alloc_nid_failed(sbi, ino); return err; } @@ -229,7 +227,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) f2fs_delete_entry(de, page, inode); f2fs_unlock_op(sbi); - /* In order to evict this inode, we set it dirty */ + /* In order to evict this inode, we set it dirty */ mark_inode_dirty(inode); fail: trace_f2fs_unlink_exit(inode, err); @@ -267,9 +265,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, return err; out: clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); + iget_failed(inode); alloc_nid_failed(sbi, inode->i_ino); return err; } @@ -308,9 +304,7 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) out_fail: clear_inode_flag(F2FS_I(inode), FI_INC_LINK); clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); + iget_failed(inode); alloc_nid_failed(sbi, inode->i_ino); return err; } @@ -354,9 +348,7 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, return 0; out: clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); + iget_failed(inode); alloc_nid_failed(sbi, inode->i_ino); return err; } @@ -688,9 +680,7 @@ release_out: out: f2fs_unlock_op(sbi); clear_nlink(inode); - unlock_new_inode(inode); - make_bad_inode(inode); - iput(inode); + iget_failed(inode); alloc_nid_failed(sbi, inode->i_ino); return err; } @@ -704,7 +694,6 @@ const struct inode_operations f2fs_dir_inode_operations = { .mkdir = f2fs_mkdir, .rmdir = f2fs_rmdir, .mknod = f2fs_mknod, - .rename = f2fs_rename, .rename2 = f2fs_rename2, .tmpfile = f2fs_tmpfile, .getattr = f2fs_getattr, diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index d3d90d284631..45378196e19a 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -237,7 +237,7 @@ retry: nat_get_blkaddr(e) != NULL_ADDR && new_blkaddr == NEW_ADDR); - /* increament version no as node is removed */ + /* increment version no as node is removed */ if (nat_get_blkaddr(e) != NEW_ADDR && new_blkaddr == NULL_ADDR) { unsigned char version = nat_get_version(e); nat_set_version(e, inc_node_version(version)); @@ -274,7 +274,7 @@ int try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) } /* - * This function returns always success + * This function always returns success */ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni) { @@ -650,7 +650,7 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, /* get indirect nodes in the path */ for (i = 0; i < idx + 1; i++) { - /* refernece count'll be increased */ + /* reference count'll be increased */ pages[i] = get_node_page(sbi, nid[i]); if (IS_ERR(pages[i])) { err = PTR_ERR(pages[i]); @@ -823,22 +823,26 @@ int truncate_xattr_node(struct inode *inode, struct page *page) */ void remove_inode_page(struct inode *inode) { - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); - struct page *page; - nid_t ino = inode->i_ino; struct dnode_of_data dn; - page = get_node_page(sbi, ino); - if (IS_ERR(page)) + set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); + if (get_dnode_of_data(&dn, 0, LOOKUP_NODE)) return; - if (truncate_xattr_node(inode, page)) { - f2fs_put_page(page, 1); + if (truncate_xattr_node(inode, dn.inode_page)) { + f2fs_put_dnode(&dn); return; } - /* 0 is possible, after f2fs_new_inode() is failed */ + + /* remove potential inline_data blocks */ + if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || + S_ISLNK(inode->i_mode)) + truncate_data_blocks_range(&dn, 1); + + /* 0 is possible, after f2fs_new_inode() has failed */ f2fs_bug_on(inode->i_blocks != 0 && inode->i_blocks != 1); - set_new_dnode(&dn, inode, page, page, ino); + + /* will put inode & node pages */ truncate_node(&dn); } @@ -1129,8 +1133,11 @@ continue_unlock: set_fsync_mark(page, 0); set_dentry_mark(page, 0); } - NODE_MAPPING(sbi)->a_ops->writepage(page, wbc); - wrote++; + + if (NODE_MAPPING(sbi)->a_ops->writepage(page, wbc)) + unlock_page(page); + else + wrote++; if (--wbc->nr_to_write == 0) break; @@ -1212,6 +1219,8 @@ static int f2fs_write_node_page(struct page *page, if (unlikely(sbi->por_doing)) goto redirty_out; + if (unlikely(f2fs_cp_error(sbi))) + goto redirty_out; f2fs_wait_on_page_writeback(page, NODE); @@ -1540,15 +1549,6 @@ void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid) kmem_cache_free(free_nid_slab, i); } -void recover_node_page(struct f2fs_sb_info *sbi, struct page *page, - struct f2fs_summary *sum, struct node_info *ni, - block_t new_blkaddr) -{ - rewrite_node_page(sbi, page, sum, ni->blk_addr, new_blkaddr); - set_node_addr(sbi, ni, new_blkaddr, false); - clear_node_page_dirty(page); -} - void recover_inline_xattr(struct inode *inode, struct page *page) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); @@ -1557,40 +1557,33 @@ void recover_inline_xattr(struct inode *inode, struct page *page) struct page *ipage; struct f2fs_inode *ri; - if (!f2fs_has_inline_xattr(inode)) - return; - - if (!IS_INODE(page)) - return; - - ri = F2FS_INODE(page); - if (!(ri->i_inline & F2FS_INLINE_XATTR)) - return; - ipage = get_node_page(sbi, inode->i_ino); f2fs_bug_on(IS_ERR(ipage)); + ri = F2FS_INODE(page); + if (!(ri->i_inline & F2FS_INLINE_XATTR)) { + clear_inode_flag(F2FS_I(inode), FI_INLINE_XATTR); + goto update_inode; + } + dst_addr = inline_xattr_addr(ipage); src_addr = inline_xattr_addr(page); inline_size = inline_xattr_size(inode); f2fs_wait_on_page_writeback(ipage, NODE); memcpy(dst_addr, src_addr, inline_size); - +update_inode: update_inode(inode, ipage); f2fs_put_page(ipage, 1); } -bool recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) +void recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid; nid_t new_xnid = nid_of_node(page); struct node_info ni; - if (!f2fs_has_xattr_block(ofs_of_node(page))) - return false; - /* 1: invalidate the previous xattr nid */ if (!prev_xnid) goto recover_xnid; @@ -1618,7 +1611,6 @@ recover_xnid: set_node_addr(sbi, &ni, blkaddr, false); update_inode_page(inode); - return true; } int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) @@ -1637,7 +1629,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) if (!ipage) return -ENOMEM; - /* Should not use this inode from free nid list */ + /* Should not use this inode from free nid list */ remove_free_nid(NM_I(sbi), ino); SetPageUptodate(ipage); @@ -1651,6 +1643,7 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) dst->i_blocks = cpu_to_le64(1); dst->i_links = cpu_to_le32(1); dst->i_xattr_nid = 0; + dst->i_inline = src->i_inline & F2FS_INLINE_XATTR; new_ni = old_ni; new_ni.ino = ino; @@ -1659,13 +1652,14 @@ int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) WARN_ON(1); set_node_addr(sbi, &new_ni, NEW_ADDR, false); inc_valid_inode_count(sbi); + set_page_dirty(ipage); f2fs_put_page(ipage, 1); return 0; } /* * ra_sum_pages() merge contiguous pages into one bio and submit. - * these pre-readed pages are alloced in bd_inode's mapping tree. + * these pre-read pages are allocated in bd_inode's mapping tree. */ static int ra_sum_pages(struct f2fs_sb_info *sbi, struct page **pages, int start, int nrpages) @@ -1709,7 +1703,7 @@ int restore_node_summary(struct f2fs_sb_info *sbi, for (i = 0; !err && i < last_offset; i += nrpages, addr += nrpages) { nrpages = min(last_offset - i, bio_blocks); - /* read ahead node pages */ + /* readahead node pages */ nrpages = ra_sum_pages(sbi, pages, addr, nrpages); if (!nrpages) return -ENOMEM; @@ -1967,7 +1961,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks; /* not used nids: 0, node, meta, (and root counted as valid node) */ - nm_i->available_nids = nm_i->max_nid - 3; + nm_i->available_nids = nm_i->max_nid - F2FS_RESERVED_NODE_NUM; nm_i->fcnt = 0; nm_i->nat_cnt = 0; nm_i->ram_thresh = DEF_RAM_THRESHOLD; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index fe1c6d921ba2..756c41cd2582 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -62,8 +62,10 @@ static int recover_dentry(struct page *ipage, struct inode *inode) } retry: de = f2fs_find_entry(dir, &name, &page); - if (de && inode->i_ino == le32_to_cpu(de->ino)) + if (de && inode->i_ino == le32_to_cpu(de->ino)) { + clear_inode_flag(F2FS_I(inode), FI_INC_LINK); goto out_unmap_put; + } if (de) { einode = f2fs_iget(inode->i_sb, le32_to_cpu(de->ino)); if (IS_ERR(einode)) { @@ -300,14 +302,19 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, struct node_info ni; int err = 0, recovered = 0; - recover_inline_xattr(inode, page); - - if (recover_inline_data(inode, page)) + /* step 1: recover xattr */ + if (IS_INODE(page)) { + recover_inline_xattr(inode, page); + } else if (f2fs_has_xattr_block(ofs_of_node(page))) { + recover_xattr_data(inode, page, blkaddr); goto out; + } - if (recover_xattr_data(inode, page, blkaddr)) + /* step 2: recover inline data */ + if (recover_inline_data(inode, page)) goto out; + /* step 3: recover data indices */ start = start_bidx_of_node(ofs_of_node(page), fi); end = start + ADDRS_PER_PAGE(page, fi); @@ -364,8 +371,6 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode, fill_node_footer(dn.node_page, dn.nid, ni.ino, ofs_of_node(page), false); set_page_dirty(dn.node_page); - - recover_node_page(sbi, dn.node_page, &sum, &ni, blkaddr); err: f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); @@ -452,6 +457,9 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) /* step #1: find fsynced inode numbers */ sbi->por_doing = true; + /* prevent checkpoint */ + mutex_lock(&sbi->cp_mutex); + blkaddr = NEXT_FREE_BLKADDR(sbi, curseg); err = find_fsync_dnodes(sbi, &inode_list); @@ -465,7 +473,8 @@ int recover_fsync_data(struct f2fs_sb_info *sbi) /* step #2: recover data */ err = recover_data(sbi, &inode_list, CURSEG_WARM_NODE); - f2fs_bug_on(!list_empty(&inode_list)); + if (!err) + f2fs_bug_on(!list_empty(&inode_list)); out: destroy_fsync_dnodes(&inode_list); kmem_cache_destroy(fsync_entry_slab); @@ -482,8 +491,13 @@ out: /* Flush all the NAT/SIT pages */ while (get_pages(sbi, F2FS_DIRTY_META)) sync_meta_pages(sbi, META, LONG_MAX); + set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG); + mutex_unlock(&sbi->cp_mutex); } else if (need_writecp) { + mutex_unlock(&sbi->cp_mutex); write_checkpoint(sbi, false); + } else { + mutex_unlock(&sbi->cp_mutex); } return err; } diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 0dfeebae2a50..0aa337cd5bba 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -62,7 +62,7 @@ static inline unsigned long __reverse_ffs(unsigned long word) } /* - * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c becasue + * __find_rev_next(_zero)_bit is copied from lib/find_next_bit.c because * f2fs_set_bit makes MSB and LSB reversed in a byte. * Example: * LSB <--> MSB @@ -808,7 +808,7 @@ static void __refresh_next_blkoff(struct f2fs_sb_info *sbi, } /* - * This function always allocates a used segment (from dirty seglist) by SSR + * This function always allocates a used segment(from dirty seglist) by SSR * manner, so it should recover the existing segment information of valid blocks */ static void change_curseg(struct f2fs_sb_info *sbi, int type, bool reuse) @@ -1103,55 +1103,6 @@ void recover_data_page(struct f2fs_sb_info *sbi, mutex_unlock(&curseg->curseg_mutex); } -void rewrite_node_page(struct f2fs_sb_info *sbi, - struct page *page, struct f2fs_summary *sum, - block_t old_blkaddr, block_t new_blkaddr) -{ - struct sit_info *sit_i = SIT_I(sbi); - int type = CURSEG_WARM_NODE; - struct curseg_info *curseg; - unsigned int segno, old_cursegno; - block_t next_blkaddr = next_blkaddr_of_node(page); - unsigned int next_segno = GET_SEGNO(sbi, next_blkaddr); - struct f2fs_io_info fio = { - .type = NODE, - .rw = WRITE_SYNC, - }; - - curseg = CURSEG_I(sbi, type); - - mutex_lock(&curseg->curseg_mutex); - mutex_lock(&sit_i->sentry_lock); - - segno = GET_SEGNO(sbi, new_blkaddr); - old_cursegno = curseg->segno; - - /* change the current segment */ - if (segno != curseg->segno) { - curseg->next_segno = segno; - change_curseg(sbi, type, true); - } - curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); - __add_sum_entry(sbi, type, sum); - - /* change the current log to the next block addr in advance */ - if (next_segno != segno) { - curseg->next_segno = next_segno; - change_curseg(sbi, type, true); - } - curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, next_blkaddr); - - /* rewrite node page */ - set_page_writeback(page); - f2fs_submit_page_mbio(sbi, page, new_blkaddr, &fio); - f2fs_submit_merged_bio(sbi, NODE, WRITE); - refresh_sit_entry(sbi, old_blkaddr, new_blkaddr); - locate_dirty_segment(sbi, old_cursegno); - - mutex_unlock(&sit_i->sentry_lock); - mutex_unlock(&curseg->curseg_mutex); -} - static inline bool is_merged_page(struct f2fs_sb_info *sbi, struct page *page, enum page_type type) { diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 55973f7b0330..ff483257283b 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -549,7 +549,7 @@ static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr) } /* - * Summary block is always treated as invalid block + * Summary block is always treated as an invalid block */ static inline void check_block_count(struct f2fs_sb_info *sbi, int segno, struct f2fs_sit_entry *raw_sit) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 657582fc7601..41bdf511003d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -432,9 +432,15 @@ static void f2fs_put_super(struct super_block *sb) stop_gc_thread(sbi); /* We don't need to do checkpoint when it's clean */ - if (sbi->s_dirty && get_pages(sbi, F2FS_DIRTY_NODES)) + if (sbi->s_dirty) write_checkpoint(sbi, true); + /* + * normally superblock is clean, so we need to release this. + * In addition, EIO will skip do checkpoint, we need this as well. + */ + release_dirty_inode(sbi); + iput(sbi->node_inode); iput(sbi->meta_inode); @@ -457,9 +463,6 @@ int f2fs_sync_fs(struct super_block *sb, int sync) trace_f2fs_sync_fs(sb, sync); - if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) - return 0; - if (sync) { mutex_lock(&sbi->gc_mutex); write_checkpoint(sbi, false); @@ -505,8 +508,8 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; buf->f_bavail = user_block_count - valid_user_blocks(sbi); - buf->f_files = sbi->total_node_count; - buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi); + buf->f_files = sbi->total_node_count - F2FS_RESERVED_NODE_NUM; + buf->f_ffree = buf->f_files - valid_inode_count(sbi); buf->f_namelen = F2FS_NAME_LEN; buf->f_fsid.val[0] = (u32)id; @@ -663,7 +666,7 @@ restore_gc: if (need_restart_gc) { if (start_gc_thread(sbi)) f2fs_msg(sbi->sb, KERN_WARNING, - "background gc thread is stop"); + "background gc thread has stopped"); } else if (need_stop_gc) { stop_gc_thread(sbi); } @@ -812,7 +815,7 @@ static int sanity_check_ckpt(struct f2fs_sb_info *sbi) if (unlikely(fsmeta >= total)) return 1; - if (unlikely(is_set_ckpt_flags(ckpt, CP_ERROR_FLAG))) { + if (unlikely(f2fs_cp_error(sbi))) { f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); return 1; } @@ -899,8 +902,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) struct buffer_head *raw_super_buf; struct inode *root; long err = -EINVAL; + bool retry = true; int i; +try_onemore: /* allocate memory for f2fs-specific super block info */ sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); if (!sbi) @@ -1080,9 +1085,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* recover fsynced data */ if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { err = recover_fsync_data(sbi); - if (err) + if (err) { f2fs_msg(sb, KERN_ERR, "Cannot recover all fsync data errno=%ld", err); + goto free_kobj; + } } /* @@ -1123,6 +1130,13 @@ free_sb_buf: brelse(raw_super_buf); free_sbi: kfree(sbi); + + /* give only one another chance */ + if (retry) { + retry = 0; + shrink_dcache_sb(sb); + goto try_onemore; + } return err; } diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 8bea941ee309..728a5dc3dc16 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -528,7 +528,7 @@ static int __f2fs_setxattr(struct inode *inode, int index, int free; /* * If value is NULL, it is remove operation. - * In case of update operation, we caculate free. + * In case of update operation, we calculate free. */ free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr); if (found) diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 6fac74349856..b73e0215baa7 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -97,7 +97,7 @@ static void jbd2_commit_block_csum_set(journal_t *j, struct buffer_head *bh) struct commit_header *h; __u32 csum; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return; h = (struct commit_header *)(bh->b_data); @@ -313,11 +313,11 @@ static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) return checksum; } -static void write_tag_block(int tag_bytes, journal_block_tag_t *tag, +static void write_tag_block(journal_t *j, journal_block_tag_t *tag, unsigned long long block) { tag->t_blocknr = cpu_to_be32(block & (u32)~0); - if (tag_bytes > JBD2_TAG_SIZE32) + if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_64BIT)) tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); } @@ -327,7 +327,7 @@ static void jbd2_descr_block_csum_set(journal_t *j, struct jbd2_journal_block_tail *tail; __u32 csum; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return; tail = (struct jbd2_journal_block_tail *)(bh->b_data + j->j_blocksize - @@ -340,12 +340,13 @@ static void jbd2_descr_block_csum_set(journal_t *j, static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, struct buffer_head *bh, __u32 sequence) { + journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; struct page *page = bh->b_page; __u8 *addr; __u32 csum32; __be32 seq; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return; seq = cpu_to_be32(sequence); @@ -355,8 +356,10 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, bh->b_size); kunmap_atomic(addr); - /* We only have space to store the lower 16 bits of the crc32c. */ - tag->t_checksum = cpu_to_be16(csum32); + if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3)) + tag3->t_checksum = cpu_to_be32(csum32); + else + tag->t_checksum = cpu_to_be16(csum32); } /* * jbd2_journal_commit_transaction @@ -396,7 +399,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) LIST_HEAD(io_bufs); LIST_HEAD(log_bufs); - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) csum_size = sizeof(struct jbd2_journal_block_tail); /* @@ -690,7 +693,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) tag_flag |= JBD2_FLAG_SAME_UUID; tag = (journal_block_tag_t *) tagp; - write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr); + write_tag_block(journal, tag, jh2bh(jh)->b_blocknr); tag->t_flags = cpu_to_be16(tag_flag); jbd2_block_tag_csum_set(journal, tag, wbuf[bufs], commit_transaction->t_tid); diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 67b8e303946c..19d74d86d99c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -124,7 +124,7 @@ EXPORT_SYMBOL(__jbd2_debug); /* Checksumming functions */ static int jbd2_verify_csum_type(journal_t *j, journal_superblock_t *sb) { - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; return sb->s_checksum_type == JBD2_CRC32C_CHKSUM; @@ -145,7 +145,7 @@ static __be32 jbd2_superblock_csum(journal_t *j, journal_superblock_t *sb) static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) { - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; return sb->s_checksum == jbd2_superblock_csum(j, sb); @@ -153,7 +153,7 @@ static int jbd2_superblock_csum_verify(journal_t *j, journal_superblock_t *sb) static void jbd2_superblock_csum_set(journal_t *j, journal_superblock_t *sb) { - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return; sb->s_checksum = jbd2_superblock_csum(j, sb); @@ -1522,21 +1522,29 @@ static int journal_get_superblock(journal_t *journal) goto out; } - if (JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM) && - JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) { + if (jbd2_journal_has_csum_v2or3(journal) && + JBD2_HAS_COMPAT_FEATURE(journal, JBD2_FEATURE_COMPAT_CHECKSUM)) { /* Can't have checksum v1 and v2 on at the same time! */ printk(KERN_ERR "JBD2: Can't enable checksumming v1 and v2 " "at the same time!\n"); goto out; } + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) && + JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) { + /* Can't have checksum v2 and v3 at the same time! */ + printk(KERN_ERR "JBD2: Can't enable checksumming v2 and v3 " + "at the same time!\n"); + goto out; + } + if (!jbd2_verify_csum_type(journal, sb)) { printk(KERN_ERR "JBD2: Unknown checksum type\n"); goto out; } /* Load the checksum driver */ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) { + if (jbd2_journal_has_csum_v2or3(journal)) { journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); if (IS_ERR(journal->j_chksum_driver)) { printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); @@ -1553,7 +1561,7 @@ static int journal_get_superblock(journal_t *journal) } /* Precompute checksum seed for all metadata */ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, sizeof(sb->s_uuid)); @@ -1813,8 +1821,14 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, if (!jbd2_journal_check_available_features(journal, compat, ro, incompat)) return 0; - /* Asking for checksumming v2 and v1? Only give them v2. */ - if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V2 && + /* If enabling v2 checksums, turn on v3 instead */ + if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V2) { + incompat &= ~JBD2_FEATURE_INCOMPAT_CSUM_V2; + incompat |= JBD2_FEATURE_INCOMPAT_CSUM_V3; + } + + /* Asking for checksumming v3 and v1? Only give them v3. */ + if (incompat & JBD2_FEATURE_INCOMPAT_CSUM_V3 && compat & JBD2_FEATURE_COMPAT_CHECKSUM) compat &= ~JBD2_FEATURE_COMPAT_CHECKSUM; @@ -1823,8 +1837,8 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, sb = journal->j_superblock; - /* If enabling v2 checksums, update superblock */ - if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V2)) { + /* If enabling v3 checksums, update superblock */ + if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { sb->s_checksum_type = JBD2_CRC32C_CHKSUM; sb->s_feature_compat &= ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); @@ -1842,8 +1856,7 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, } /* Precompute checksum seed for all metadata */ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, - JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, sizeof(sb->s_uuid)); @@ -1852,7 +1865,8 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat, /* If enabling v1 checksums, downgrade superblock */ if (COMPAT_FEATURE_ON(JBD2_FEATURE_COMPAT_CHECKSUM)) sb->s_feature_incompat &= - ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2); + ~cpu_to_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2 | + JBD2_FEATURE_INCOMPAT_CSUM_V3); sb->s_feature_compat |= cpu_to_be32(compat); sb->s_feature_ro_compat |= cpu_to_be32(ro); @@ -2165,16 +2179,20 @@ int jbd2_journal_blocks_per_page(struct inode *inode) */ size_t journal_tag_bytes(journal_t *journal) { - journal_block_tag_t tag; - size_t x = 0; + size_t sz; + + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) + return sizeof(journal_block_tag3_t); + + sz = sizeof(journal_block_tag_t); if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) - x += sizeof(tag.t_checksum); + sz += sizeof(__u16); if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) - return x + JBD2_TAG_SIZE64; + return sz; else - return x + JBD2_TAG_SIZE32; + return sz - sizeof(__u32); } /* diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 3b6bb19d60b1..9b329b55ffe3 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -181,7 +181,7 @@ static int jbd2_descr_block_csum_verify(journal_t *j, __be32 provided; __u32 calculated; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; tail = (struct jbd2_journal_block_tail *)(buf + j->j_blocksize - @@ -205,7 +205,7 @@ static int count_tags(journal_t *journal, struct buffer_head *bh) int nr = 0, size = journal->j_blocksize; int tag_bytes = journal_tag_bytes(journal); - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) size -= sizeof(struct jbd2_journal_block_tail); tagp = &bh->b_data[sizeof(journal_header_t)]; @@ -338,10 +338,11 @@ int jbd2_journal_skip_recovery(journal_t *journal) return err; } -static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) +static inline unsigned long long read_tag_block(journal_t *journal, + journal_block_tag_t *tag) { unsigned long long block = be32_to_cpu(tag->t_blocknr); - if (tag_bytes > JBD2_TAG_SIZE32) + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; return block; } @@ -384,7 +385,7 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) __be32 provided; __u32 calculated; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; h = buf; @@ -399,17 +400,21 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag, void *buf, __u32 sequence) { + journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; __u32 csum32; __be32 seq; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; seq = cpu_to_be32(sequence); csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq)); csum32 = jbd2_chksum(j, csum32, buf, j->j_blocksize); - return tag->t_checksum == cpu_to_be16(csum32); + if (JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V3)) + return tag3->t_checksum == cpu_to_be32(csum32); + else + return tag->t_checksum == cpu_to_be16(csum32); } static int do_one_pass(journal_t *journal, @@ -426,6 +431,7 @@ static int do_one_pass(journal_t *journal, int tag_bytes = journal_tag_bytes(journal); __u32 crc32_sum = ~0; /* Transactional Checksums */ int descr_csum_size = 0; + int block_error = 0; /* * First thing is to establish what we expect to find in the log @@ -512,8 +518,7 @@ static int do_one_pass(journal_t *journal, switch(blocktype) { case JBD2_DESCRIPTOR_BLOCK: /* Verify checksum first */ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, - JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) descr_csum_size = sizeof(struct jbd2_journal_block_tail); if (descr_csum_size > 0 && @@ -574,7 +579,7 @@ static int do_one_pass(journal_t *journal, unsigned long long blocknr; J_ASSERT(obh != NULL); - blocknr = read_tag_block(tag_bytes, + blocknr = read_tag_block(journal, tag); /* If the block has been @@ -598,7 +603,8 @@ static int do_one_pass(journal_t *journal, "checksum recovering " "block %llu in log\n", blocknr); - continue; + block_error = 1; + goto skip_write; } /* Find a buffer for the new @@ -797,7 +803,8 @@ static int do_one_pass(journal_t *journal, success = -EIO; } } - + if (block_error && success == 0) + success = -EIO; return success; failed: @@ -811,7 +818,7 @@ static int jbd2_revoke_block_csum_verify(journal_t *j, __be32 provided; __u32 calculated; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return 1; tail = (struct jbd2_journal_revoke_tail *)(buf + j->j_blocksize - diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 198c9c10276d..d5e95a175c92 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c @@ -91,8 +91,8 @@ #include <linux/list.h> #include <linux/init.h> #include <linux/bio.h> -#endif #include <linux/log2.h> +#endif static struct kmem_cache *jbd2_revoke_record_cache; static struct kmem_cache *jbd2_revoke_table_cache; @@ -597,7 +597,7 @@ static void write_one_revoke_record(journal_t *journal, offset = *offsetp; /* Do we need to leave space at the end for a checksum? */ - if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (jbd2_journal_has_csum_v2or3(journal)) csum_size = sizeof(struct jbd2_journal_revoke_tail); /* Make sure we have a descriptor with space left for the record */ @@ -644,7 +644,7 @@ static void jbd2_revoke_csum_set(journal_t *j, struct buffer_head *bh) struct jbd2_journal_revoke_tail *tail; __u32 csum; - if (!JBD2_HAS_INCOMPAT_FEATURE(j, JBD2_FEATURE_INCOMPAT_CSUM_V2)) + if (!jbd2_journal_has_csum_v2or3(j)) return; tail = (struct jbd2_journal_revoke_tail *)(bh->b_data + j->j_blocksize - diff --git a/fs/locks.c b/fs/locks.c index cb66fb05ad4a..bb08857f90b5 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1619,7 +1619,7 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp smp_mb(); error = check_conflicting_open(dentry, arg); if (error) - locks_unlink_lock(flp); + locks_unlink_lock(before); out: if (is_deleg) mutex_unlock(&inode->i_mutex); diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index d0fec260132a..24c6898159cc 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -129,7 +129,10 @@ static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, .rpc_argp = &args, .rpc_resp = &fattr, }; - int status; + int status = 0; + + if (acl == NULL && (!S_ISDIR(inode->i_mode) || dfacl == NULL)) + goto out; status = -EOPNOTSUPP; if (!nfs_server_capable(inode, NFS_CAP_ACLS)) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 75ae8d22f067..7dd8aca31c29 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2560,6 +2560,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) struct nfs4_closedata *calldata = data; struct nfs4_state *state = calldata->state; struct nfs_server *server = NFS_SERVER(calldata->inode); + nfs4_stateid *res_stateid = NULL; dprintk("%s: begin!\n", __func__); if (!nfs4_sequence_done(task, &calldata->res.seq_res)) @@ -2570,12 +2571,12 @@ static void nfs4_close_done(struct rpc_task *task, void *data) */ switch (task->tk_status) { case 0: - if (calldata->roc) + res_stateid = &calldata->res.stateid; + if (calldata->arg.fmode == 0 && calldata->roc) pnfs_roc_set_barrier(state->inode, calldata->roc_barrier); - nfs_clear_open_stateid(state, &calldata->res.stateid, 0); renew_lease(server, calldata->timestamp); - goto out_release; + break; case -NFS4ERR_ADMIN_REVOKED: case -NFS4ERR_STALE_STATEID: case -NFS4ERR_OLD_STATEID: @@ -2589,7 +2590,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) goto out_release; } } - nfs_clear_open_stateid(state, NULL, calldata->arg.fmode); + nfs_clear_open_stateid(state, res_stateid, calldata->arg.fmode); out_release: nfs_release_seqid(calldata->arg.seqid); nfs_refresh_inode(calldata->inode, calldata->res.fattr); @@ -2601,6 +2602,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) struct nfs4_closedata *calldata = data; struct nfs4_state *state = calldata->state; struct inode *inode = calldata->inode; + bool is_rdonly, is_wronly, is_rdwr; int call_close = 0; dprintk("%s: begin!\n", __func__); @@ -2608,18 +2610,24 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) goto out_wait; task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; - calldata->arg.fmode = FMODE_READ|FMODE_WRITE; spin_lock(&state->owner->so_lock); + is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags); + is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags); + is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags); + /* Calculate the current open share mode */ + calldata->arg.fmode = 0; + if (is_rdonly || is_rdwr) + calldata->arg.fmode |= FMODE_READ; + if (is_wronly || is_rdwr) + calldata->arg.fmode |= FMODE_WRITE; /* Calculate the change in open mode */ if (state->n_rdwr == 0) { if (state->n_rdonly == 0) { - call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags); - call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); + call_close |= is_rdonly || is_rdwr; calldata->arg.fmode &= ~FMODE_READ; } if (state->n_wronly == 0) { - call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags); - call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); + call_close |= is_wronly || is_rdwr; calldata->arg.fmode &= ~FMODE_WRITE; } } diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index 1ec141e758d7..62e8ec619b4c 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c @@ -160,9 +160,18 @@ static void o2quo_make_decision(struct work_struct *work) } out: - spin_unlock(&qs->qs_lock); - if (fence) + if (fence) { + spin_unlock(&qs->qs_lock); o2quo_fence_self(); + } else { + mlog(ML_NOTICE, "not fencing this node, heartbeating: %d, " + "connected: %d, lowest: %d (%sreachable)\n", + qs->qs_heartbeating, qs->qs_connected, lowest_hb, + lowest_reachable ? "" : "un"); + spin_unlock(&qs->qs_lock); + + } + } static void o2quo_set_hold(struct o2quo_state *qs, u8 node) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 681691bc233a..ea34952f9496 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -1480,6 +1480,14 @@ static int o2net_set_nodelay(struct socket *sock) return ret; } +static int o2net_set_usertimeout(struct socket *sock) +{ + int user_timeout = O2NET_TCP_USER_TIMEOUT; + + return kernel_setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, + (char *)&user_timeout, sizeof(user_timeout)); +} + static void o2net_initialize_handshake(void) { o2net_hand->o2hb_heartbeat_timeout_ms = cpu_to_be32( @@ -1536,16 +1544,20 @@ static void o2net_idle_timer(unsigned long data) #endif printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " - "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc), - msecs / 1000, msecs % 1000); + "idle for %lu.%lu secs.\n", + SC_NODEF_ARGS(sc), msecs / 1000, msecs % 1000); - /* - * Initialize the nn_timeout so that the next connection attempt - * will continue in o2net_start_connect. + /* idle timerout happen, don't shutdown the connection, but + * make fence decision. Maybe the connection can recover before + * the decision is made. */ atomic_set(&nn->nn_timeout, 1); + o2quo_conn_err(o2net_num_from_nn(nn)); + queue_delayed_work(o2net_wq, &nn->nn_still_up, + msecs_to_jiffies(O2NET_QUORUM_DELAY_MS)); + + o2net_sc_reset_idle_timer(sc); - o2net_sc_queue_work(sc, &sc->sc_shutdown_work); } static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) @@ -1560,6 +1572,15 @@ static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) { + struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); + + /* clear fence decision since the connection recover from timeout*/ + if (atomic_read(&nn->nn_timeout)) { + o2quo_conn_up(o2net_num_from_nn(nn)); + cancel_delayed_work(&nn->nn_still_up); + atomic_set(&nn->nn_timeout, 0); + } + /* Only push out an existing timer */ if (timer_pending(&sc->sc_idle_timeout)) o2net_sc_reset_idle_timer(sc); @@ -1650,6 +1671,12 @@ static void o2net_start_connect(struct work_struct *work) goto out; } + ret = o2net_set_usertimeout(sock); + if (ret) { + mlog(ML_ERROR, "set TCP_USER_TIMEOUT failed with %d\n", ret); + goto out; + } + o2net_register_callbacks(sc->sc_sock->sk, sc); spin_lock(&nn->nn_lock); @@ -1831,6 +1858,12 @@ static int o2net_accept_one(struct socket *sock, int *more) goto out; } + ret = o2net_set_usertimeout(new_sock); + if (ret) { + mlog(ML_ERROR, "set TCP_USER_TIMEOUT failed with %d\n", ret); + goto out; + } + slen = sizeof(sin); ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, &slen, 1); diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h index 5bada2a69b50..c571e849fda4 100644 --- a/fs/ocfs2/cluster/tcp.h +++ b/fs/ocfs2/cluster/tcp.h @@ -63,6 +63,7 @@ typedef void (o2net_post_msg_handler_func)(int status, void *data, #define O2NET_KEEPALIVE_DELAY_MS_DEFAULT 2000 #define O2NET_IDLE_TIMEOUT_MS_DEFAULT 30000 +#define O2NET_TCP_USER_TIMEOUT 0x7fffffff /* TODO: figure this out.... */ static inline int o2net_link_down(int err, struct socket *sock) diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 6f66b3751ace..53e6c40ed4c6 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -35,9 +35,8 @@ copy_to_user((typeof(a) __user *)b, &(a), sizeof(a)) /* - * This call is void because we are already reporting an error that may - * be -EFAULT. The error will be returned from the ioctl(2) call. It's - * just a best-effort to tell userspace that this request caused the error. + * This is just a best-effort to tell userspace that this request + * caused the error. */ static inline void o2info_set_request_error(struct ocfs2_info_request *kreq, struct ocfs2_info_request __user *req) @@ -146,136 +145,105 @@ bail: static int ocfs2_info_handle_blocksize(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_blocksize oib; if (o2info_from_user(oib, req)) - goto bail; + return -EFAULT; oib.ib_blocksize = inode->i_sb->s_blocksize; o2info_set_request_filled(&oib.ib_req); if (o2info_to_user(oib, req)) - goto bail; - - status = 0; -bail: - if (status) - o2info_set_request_error(&oib.ib_req, req); + return -EFAULT; - return status; + return 0; } static int ocfs2_info_handle_clustersize(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_clustersize oic; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oic, req)) - goto bail; + return -EFAULT; oic.ic_clustersize = osb->s_clustersize; o2info_set_request_filled(&oic.ic_req); if (o2info_to_user(oic, req)) - goto bail; - - status = 0; -bail: - if (status) - o2info_set_request_error(&oic.ic_req, req); + return -EFAULT; - return status; + return 0; } static int ocfs2_info_handle_maxslots(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_maxslots oim; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oim, req)) - goto bail; + return -EFAULT; oim.im_max_slots = osb->max_slots; o2info_set_request_filled(&oim.im_req); if (o2info_to_user(oim, req)) - goto bail; + return -EFAULT; - status = 0; -bail: - if (status) - o2info_set_request_error(&oim.im_req, req); - - return status; + return 0; } static int ocfs2_info_handle_label(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_label oil; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oil, req)) - goto bail; + return -EFAULT; memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN); o2info_set_request_filled(&oil.il_req); if (o2info_to_user(oil, req)) - goto bail; + return -EFAULT; - status = 0; -bail: - if (status) - o2info_set_request_error(&oil.il_req, req); - - return status; + return 0; } static int ocfs2_info_handle_uuid(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_uuid oiu; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oiu, req)) - goto bail; + return -EFAULT; memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1); o2info_set_request_filled(&oiu.iu_req); if (o2info_to_user(oiu, req)) - goto bail; - - status = 0; -bail: - if (status) - o2info_set_request_error(&oiu.iu_req, req); + return -EFAULT; - return status; + return 0; } static int ocfs2_info_handle_fs_features(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_fs_features oif; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oif, req)) - goto bail; + return -EFAULT; oif.if_compat_features = osb->s_feature_compat; oif.if_incompat_features = osb->s_feature_incompat; @@ -284,39 +252,28 @@ static int ocfs2_info_handle_fs_features(struct inode *inode, o2info_set_request_filled(&oif.if_req); if (o2info_to_user(oif, req)) - goto bail; + return -EFAULT; - status = 0; -bail: - if (status) - o2info_set_request_error(&oif.if_req, req); - - return status; + return 0; } static int ocfs2_info_handle_journal_size(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_journal_size oij; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); if (o2info_from_user(oij, req)) - goto bail; + return -EFAULT; oij.ij_journal_size = i_size_read(osb->journal->j_inode); o2info_set_request_filled(&oij.ij_req); if (o2info_to_user(oij, req)) - goto bail; + return -EFAULT; - status = 0; -bail: - if (status) - o2info_set_request_error(&oij.ij_req, req); - - return status; + return 0; } static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb, @@ -373,7 +330,7 @@ static int ocfs2_info_handle_freeinode(struct inode *inode, u32 i; u64 blkno = -1; char namebuf[40]; - int status = -EFAULT, type = INODE_ALLOC_SYSTEM_INODE; + int status, type = INODE_ALLOC_SYSTEM_INODE; struct ocfs2_info_freeinode *oifi = NULL; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct inode *inode_alloc = NULL; @@ -385,8 +342,10 @@ static int ocfs2_info_handle_freeinode(struct inode *inode, goto out_err; } - if (o2info_from_user(*oifi, req)) - goto bail; + if (o2info_from_user(*oifi, req)) { + status = -EFAULT; + goto out_free; + } oifi->ifi_slotnum = osb->max_slots; @@ -424,14 +383,16 @@ static int ocfs2_info_handle_freeinode(struct inode *inode, o2info_set_request_filled(&oifi->ifi_req); - if (o2info_to_user(*oifi, req)) - goto bail; + if (o2info_to_user(*oifi, req)) { + status = -EFAULT; + goto out_free; + } status = 0; bail: if (status) o2info_set_request_error(&oifi->ifi_req, req); - +out_free: kfree(oifi); out_err: return status; @@ -658,7 +619,7 @@ static int ocfs2_info_handle_freefrag(struct inode *inode, { u64 blkno = -1; char namebuf[40]; - int status = -EFAULT, type = GLOBAL_BITMAP_SYSTEM_INODE; + int status, type = GLOBAL_BITMAP_SYSTEM_INODE; struct ocfs2_info_freefrag *oiff; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); @@ -671,8 +632,10 @@ static int ocfs2_info_handle_freefrag(struct inode *inode, goto out_err; } - if (o2info_from_user(*oiff, req)) - goto bail; + if (o2info_from_user(*oiff, req)) { + status = -EFAULT; + goto out_free; + } /* * chunksize from userspace should be power of 2. */ @@ -711,14 +674,14 @@ static int ocfs2_info_handle_freefrag(struct inode *inode, if (o2info_to_user(*oiff, req)) { status = -EFAULT; - goto bail; + goto out_free; } status = 0; bail: if (status) o2info_set_request_error(&oiff->iff_req, req); - +out_free: kfree(oiff); out_err: return status; @@ -727,23 +690,17 @@ out_err: static int ocfs2_info_handle_unknown(struct inode *inode, struct ocfs2_info_request __user *req) { - int status = -EFAULT; struct ocfs2_info_request oir; if (o2info_from_user(oir, req)) - goto bail; + return -EFAULT; o2info_clear_request_filled(&oir); if (o2info_to_user(oir, req)) - goto bail; + return -EFAULT; - status = 0; -bail: - if (status) - o2info_set_request_error(&oir, req); - - return status; + return 0; } /* diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index eb726b9c5762..a1e31f274fcd 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -127,10 +127,9 @@ enum { BLK_MQ_RQ_QUEUE_ERROR = 2, /* end IO with error */ BLK_MQ_F_SHOULD_MERGE = 1 << 0, - BLK_MQ_F_SHOULD_SORT = 1 << 1, - BLK_MQ_F_TAG_SHARED = 1 << 2, - BLK_MQ_F_SG_MERGE = 1 << 3, - BLK_MQ_F_SYSFS_UP = 1 << 4, + BLK_MQ_F_TAG_SHARED = 1 << 1, + BLK_MQ_F_SG_MERGE = 1 << 2, + BLK_MQ_F_SYSFS_UP = 1 << 3, BLK_MQ_S_STOPPED = 0, BLK_MQ_S_TAG_ACTIVE = 1, diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 6ff0b0b42d47..08ed2b0a96e6 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -24,6 +24,9 @@ #define NULL_ADDR ((block_t)0) /* used as block_t addresses */ #define NEW_ADDR ((block_t)-1) /* used as block_t addresses */ +/* 0, 1(node nid), 2(meta nid) are reserved node id */ +#define F2FS_RESERVED_NODE_NUM 3 + #define F2FS_ROOT_INO(sbi) (sbi->root_ino_num) #define F2FS_NODE_INO(sbi) (sbi->node_ino_num) #define F2FS_META_INO(sbi) (sbi->meta_ino_num) @@ -87,6 +90,8 @@ struct f2fs_super_block { #define CP_ORPHAN_PRESENT_FLAG 0x00000002 #define CP_UMOUNT_FLAG 0x00000001 +#define F2FS_CP_PACKS 2 /* # of checkpoint packs */ + struct f2fs_checkpoint { __le64 checkpoint_ver; /* checkpoint block version number */ __le64 user_block_count; /* # of user blocks */ @@ -123,6 +128,9 @@ struct f2fs_checkpoint { */ #define F2FS_ORPHANS_PER_BLOCK 1020 +#define GET_ORPHAN_BLOCKS(n) ((n + F2FS_ORPHANS_PER_BLOCK - 1) / \ + F2FS_ORPHANS_PER_BLOCK) + struct f2fs_orphan_block { __le32 ino[F2FS_ORPHANS_PER_BLOCK]; /* inode numbers */ __le32 reserved; /* reserved */ @@ -144,6 +152,7 @@ struct f2fs_extent { #define F2FS_NAME_LEN 255 #define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs */ #define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode */ +#define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */ #define ADDRS_PER_INODE(fi) addrs_per_inode(fi) #define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block */ #define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block */ @@ -163,8 +172,9 @@ struct f2fs_extent { #define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \ F2FS_INLINE_XATTR_ADDRS - 1)) -#define INLINE_DATA_OFFSET (PAGE_CACHE_SIZE - sizeof(struct node_footer) \ - - sizeof(__le32) * (DEF_ADDRS_PER_INODE + 5 - 1)) +#define INLINE_DATA_OFFSET (PAGE_CACHE_SIZE - sizeof(struct node_footer) -\ + sizeof(__le32) * (DEF_ADDRS_PER_INODE + \ + DEF_NIDS_PER_INODE - 1)) struct f2fs_inode { __le16 i_mode; /* file mode */ @@ -194,7 +204,7 @@ struct f2fs_inode { __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */ - __le32 i_nid[5]; /* direct(2), indirect(2), + __le32 i_nid[DEF_NIDS_PER_INODE]; /* direct(2), indirect(2), double_indirect(1) node id */ } __packed; diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index d5b50a19463c..0dae71e9971c 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -159,7 +159,11 @@ typedef struct journal_header_s * journal_block_tag (in the descriptor). The other h_chksum* fields are * not used. * - * Checksum v1 and v2 are mutually exclusive features. + * If FEATURE_INCOMPAT_CSUM_V3 is set, the descriptor block uses + * journal_block_tag3_t to store a full 32-bit checksum. Everything else + * is the same as v2. + * + * Checksum v1, v2, and v3 are mutually exclusive features. */ struct commit_header { __be32 h_magic; @@ -179,6 +183,14 @@ struct commit_header { * raw struct shouldn't be used for pointer math or sizeof() - use * journal_tag_bytes(journal) instead to compute this. */ +typedef struct journal_block_tag3_s +{ + __be32 t_blocknr; /* The on-disk block number */ + __be32 t_flags; /* See below */ + __be32 t_blocknr_high; /* most-significant high 32bits. */ + __be32 t_checksum; /* crc32c(uuid+seq+block) */ +} journal_block_tag3_t; + typedef struct journal_block_tag_s { __be32 t_blocknr; /* The on-disk block number */ @@ -187,9 +199,6 @@ typedef struct journal_block_tag_s __be32 t_blocknr_high; /* most-significant high 32bits. */ } journal_block_tag_t; -#define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) -#define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t)) - /* Tail of descriptor block, for checksumming */ struct jbd2_journal_block_tail { __be32 t_checksum; /* crc32c(uuid+descr_block) */ @@ -284,6 +293,7 @@ typedef struct journal_superblock_s #define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 #define JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004 #define JBD2_FEATURE_INCOMPAT_CSUM_V2 0x00000008 +#define JBD2_FEATURE_INCOMPAT_CSUM_V3 0x00000010 /* Features known to this kernel version: */ #define JBD2_KNOWN_COMPAT_FEATURES JBD2_FEATURE_COMPAT_CHECKSUM @@ -291,7 +301,8 @@ typedef struct journal_superblock_s #define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | \ JBD2_FEATURE_INCOMPAT_64BIT | \ JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT | \ - JBD2_FEATURE_INCOMPAT_CSUM_V2) + JBD2_FEATURE_INCOMPAT_CSUM_V2 | \ + JBD2_FEATURE_INCOMPAT_CSUM_V3) #ifdef __KERNEL__ @@ -1296,6 +1307,15 @@ static inline int tid_geq(tid_t x, tid_t y) extern int jbd2_journal_blocks_per_page(struct inode *inode); extern size_t journal_tag_bytes(journal_t *journal); +static inline int jbd2_journal_has_csum_v2or3(journal_t *journal) +{ + if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V2) || + JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_CSUM_V3)) + return 1; + + return 0; +} + /* * We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for * transaction control blocks. diff --git a/include/linux/leds.h b/include/linux/leds.h index 6a599dce7f9d..e43686472197 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -15,6 +15,7 @@ #include <linux/list.h> #include <linux/spinlock.h> #include <linux/rwsem.h> +#include <linux/timer.h> #include <linux/workqueue.h> struct device; @@ -68,7 +69,7 @@ struct led_classdev { const char *default_trigger; /* Trigger to use */ unsigned long blink_delay_on, blink_delay_off; - struct delayed_work blink_work; + struct timer_list blink_timer; int blink_brightness; struct work_struct set_brightness_work; diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h index 660c029d694f..16ec262dfcc8 100644 --- a/include/linux/platform_data/mtd-nand-omap2.h +++ b/include/linux/platform_data/mtd-nand-omap2.h @@ -21,8 +21,17 @@ enum nand_io { }; enum omap_ecc { - /* 1-bit ECC calculation by GPMC, Error detection by Software */ - OMAP_ECC_HAM1_CODE_HW = 0, + /* + * 1-bit ECC: calculation and correction by SW + * ECC stored at end of spare area + */ + OMAP_ECC_HAM1_CODE_SW = 0, + + /* + * 1-bit ECC: calculation by GPMC, Error detection by Software + * ECC layout compatible with ROM code layout + */ + OMAP_ECC_HAM1_CODE_HW, /* 4-bit ECC calculation by GPMC, Error detection by Software */ OMAP_ECC_BCH4_CODE_HW_DETECTION_SW, /* 4-bit ECC calculation by GPMC, Error detection by ELM */ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index e713543336f1..46d188a9947c 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -253,6 +253,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * the device whose settings are being modified. * @transfer: adds a message to the controller's transfer queue. * @cleanup: frees controller-specific state + * @can_dma: determine whether this master supports DMA * @queued: whether this master is providing an internal message queue * @kworker: thread struct for message pump * @kworker_task: pointer to task for message pump kworker thread @@ -262,6 +263,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @cur_msg: the currently in-flight message * @cur_msg_prepared: spi_prepare_message was called for the currently * in-flight message + * @cur_msg_mapped: message has been mapped for DMA * @xfer_completion: used by core transfer_one_message() * @busy: message pump is busy * @running: message pump is running @@ -299,6 +301,10 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). + * @dma_tx: DMA transmit channel + * @dma_rx: DMA receive channel + * @dummy_rx: dummy receive buffer for full-duplex devices + * @dummy_tx: dummy transmit buffer for full-duplex devices * * Each SPI master controller can communicate with one or more @spi_device * children. These make a small bus, sharing MOSI, MISO and SCK signals @@ -632,6 +638,7 @@ struct spi_transfer { * addresses for each transfer buffer * @complete: called to report transaction completions * @context: the argument to complete() when it's called + * @frame_length: the total number of bytes in the message * @actual_length: the total number of bytes that were transferred in all * successful segments * @status: zero for success, else negative errno diff --git a/include/sound/soc.h b/include/sound/soc.h index be6ecae247b0..c83a334dd00f 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -277,7 +277,7 @@ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | \ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ .tlv.c = (snd_soc_bytes_tlv_callback), \ - .info = snd_soc_info_bytes_ext, \ + .info = snd_soc_bytes_info_ext, \ .private_value = (unsigned long)&(struct soc_bytes_ext) \ {.max = xcount, .get = xhandler_get, .put = xhandler_put, } } #define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \ diff --git a/drivers/staging/usbip/uapi/usbip.h b/include/uapi/linux/usbip.h index fa5db30ede36..fa5db30ede36 100644 --- a/drivers/staging/usbip/uapi/usbip.h +++ b/include/uapi/linux/usbip.h diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index c38355c1f3c9..1590c49cae57 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -13,7 +13,7 @@ #ifndef _UAPI_LINUX_XATTR_H #define _UAPI_LINUX_XATTR_H -#ifdef __UAPI_DEF_XATTR +#if __UAPI_DEF_XATTR #define __USE_KERNEL_XATTR_DEFS #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index a2b28a2fd7b1..6223fab9a9d2 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -517,6 +517,7 @@ out: chip->irq_eoi(&desc->irq_data); raw_spin_unlock(&desc->lock); } +EXPORT_SYMBOL_GPL(handle_fasteoi_irq); /** * handle_edge_irq - edge type IRQ handler diff --git a/kernel/kexec.c b/kernel/kexec.c index 0b49a0a58102..2bee072268d9 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -64,7 +64,9 @@ bool kexec_in_progress = false; char __weak kexec_purgatory[0]; size_t __weak kexec_purgatory_size = 0; +#ifdef CONFIG_KEXEC_FILE static int kexec_calculate_store_digests(struct kimage *image); +#endif /* Location of the reserved area for the crash kernel */ struct resource crashk_res = { @@ -341,6 +343,7 @@ out_free_image: return ret; } +#ifdef CONFIG_KEXEC_FILE static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len) { struct fd f = fdget(fd); @@ -612,6 +615,9 @@ out_free_image: kfree(image); return ret; } +#else /* CONFIG_KEXEC_FILE */ +static inline void kimage_file_post_load_cleanup(struct kimage *image) { } +#endif /* CONFIG_KEXEC_FILE */ static int kimage_is_destination_range(struct kimage *image, unsigned long start, @@ -1375,6 +1381,7 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry, } #endif +#ifdef CONFIG_KEXEC_FILE SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags) @@ -1451,6 +1458,8 @@ out: return ret; } +#endif /* CONFIG_KEXEC_FILE */ + void crash_kexec(struct pt_regs *regs) { /* Take the kexec_mutex here to prevent sys_kexec_load @@ -2006,6 +2015,7 @@ static int __init crash_save_vmcoreinfo_init(void) subsys_initcall(crash_save_vmcoreinfo_init); +#ifdef CONFIG_KEXEC_FILE static int __kexec_add_segment(struct kimage *image, char *buf, unsigned long bufsz, unsigned long mem, unsigned long memsz) @@ -2682,6 +2692,7 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, return 0; } +#endif /* CONFIG_KEXEC_FILE */ /* * Move into place and start executing a preloaded standalone diff --git a/kernel/resource.c b/kernel/resource.c index da14b8d09296..60c5a3856ab7 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -351,15 +351,12 @@ static int find_next_iomem_res(struct resource *res, char *name, end = res->end; BUG_ON(start >= end); - read_lock(&resource_lock); - - if (first_level_children_only) { - p = iomem_resource.child; + if (first_level_children_only) sibling_only = true; - } else - p = &iomem_resource; - while ((p = next_resource(p, sibling_only))) { + read_lock(&resource_lock); + + for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) { if (p->flags != res->flags) continue; if (name && strcmp(p->name, name)) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1b233fc67466..a28590083622 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1036,8 +1036,13 @@ config TRACE_IRQFLAGS either tracing or lock debugging. config STACKTRACE - bool + bool "Stack backtrace support" depends on STACKTRACE_SUPPORT + help + This option causes the kernel to create a /proc/pid/stack for + every process, showing its current stack trace. + It is also used by various kernel debugging features that require + stack trace generation. config DEBUG_KOBJECT bool "kobject debugging" diff --git a/lib/assoc_array.c b/lib/assoc_array.c index c0b1007011e1..ae146f0734eb 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c @@ -1735,7 +1735,7 @@ ascend_old_tree: gc_complete: edit->set[0].to = new_root; assoc_array_apply_edit(edit); - edit->array->nr_leaves_on_tree = nr_leaves_on_tree; + array->nr_leaves_on_tree = nr_leaves_on_tree; return 0; enomem: diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c index 9eebfadeeee1..a67c26e0f360 100644 --- a/mm/hugetlb_cgroup.c +++ b/mm/hugetlb_cgroup.c @@ -217,7 +217,7 @@ void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, if (hugetlb_cgroup_disabled()) return; - VM_BUG_ON(!spin_is_locked(&hugetlb_lock)); + lockdep_assert_held(&hugetlb_lock); h_cg = hugetlb_cgroup_from_page(page); if (unlikely(!h_cg)) return; diff --git a/mm/memblock.c b/mm/memblock.c index 6d2f219a48b0..70fad0c0dafb 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -192,8 +192,7 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end, int nid) { - int ret; - phys_addr_t kernel_end; + phys_addr_t kernel_end, ret; /* pump up @end */ if (end == MEMBLOCK_ALLOC_ACCESSIBLE) diff --git a/mm/memory.c b/mm/memory.c index ab3537bcfed2..adeac306610f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -751,7 +751,7 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn = pte_pfn(pte); if (HAVE_PTE_SPECIAL) { - if (likely(!pte_special(pte) || pte_numa(pte))) + if (likely(!pte_special(pte))) goto check_pfn; if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) return NULL; @@ -777,15 +777,14 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, } } + if (is_zero_pfn(pfn)) + return NULL; check_pfn: if (unlikely(pfn > highest_memmap_pfn)) { print_bad_pte(vma, addr, pte, NULL); return NULL; } - if (is_zero_pfn(pfn)) - return NULL; - /* * NOTE! We still have PageReserved() pages in the page tables. * eg. VDSO mappings can cause them to exist. diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c index a8b919925934..dfb79e028ecb 100644 --- a/mm/pgtable-generic.c +++ b/mm/pgtable-generic.c @@ -195,7 +195,7 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, pmd_t entry = *pmdp; if (pmd_numa(entry)) entry = pmd_mknonnuma(entry); - set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp)); + set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(entry)); flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ diff --git a/mm/zbud.c b/mm/zbud.c index a05790b1915e..f26e7fcc7fa2 100644 --- a/mm/zbud.c +++ b/mm/zbud.c @@ -195,6 +195,7 @@ static struct zpool_driver zbud_zpool_driver = { .total_size = zbud_zpool_total_size, }; +MODULE_ALIAS("zpool-zbud"); #endif /* CONFIG_ZPOOL */ /***************** diff --git a/mm/zpool.c b/mm/zpool.c index e40612a1df00..739cdf0d183a 100644 --- a/mm/zpool.c +++ b/mm/zpool.c @@ -150,7 +150,7 @@ struct zpool *zpool_create_pool(char *type, gfp_t gfp, struct zpool_ops *ops) driver = zpool_get_driver(type); if (!driver) { - request_module(type); + request_module("zpool-%s", type); driver = zpool_get_driver(type); } diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 4e2fc83cb394..94f38fac5e81 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -315,6 +315,7 @@ static struct zpool_driver zs_zpool_driver = { .total_size = zs_zpool_total_size, }; +MODULE_ALIAS("zpool-zsmalloc"); #endif /* CONFIG_ZPOOL */ /* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 31a731e06f50..b385bcbbf2f5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2133,7 +2133,7 @@ sub process { # Check for improperly formed commit descriptions if ($in_commit_log && $line =~ /\bcommit\s+[0-9a-f]{5,}/i && - $line !~ /\b[Cc]ommit [0-9a-f]{12,16} \("/) { + $line !~ /\b[Cc]ommit [0-9a-f]{12,40} \("/) { $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i; my $init_char = $1; my $orig_commit = lc($2); @@ -2141,7 +2141,7 @@ sub process { my $desc = 'commit description'; ($id, $desc) = git_commit_info($orig_commit, $id, $desc); ERROR("GIT_COMMIT_ID", - "Please use 12 to 16 chars for the git commit ID like: '${init_char}ommit $id (\"$desc\")'\n" . $herecurr); + "Please use 12 or more chars for the git commit ID like: '${init_char}ommit $id (\"$desc\")'\n" . $herecurr); } # Check for added, moved or deleted files diff --git a/security/keys/key.c b/security/keys/key.c index b90a68c4e2c4..6d0cad16f002 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -27,8 +27,8 @@ DEFINE_SPINLOCK(key_serial_lock); struct rb_root key_user_tree; /* tree of quota records indexed by UID */ DEFINE_SPINLOCK(key_user_lock); -unsigned int key_quota_root_maxkeys = 200; /* root's key count quota */ -unsigned int key_quota_root_maxbytes = 20000; /* root's key space quota */ +unsigned int key_quota_root_maxkeys = 1000000; /* root's key count quota */ +unsigned int key_quota_root_maxbytes = 25000000; /* root's key space quota */ unsigned int key_quota_maxkeys = 200; /* general key count quota */ unsigned int key_quota_maxbytes = 20000; /* general key space quota */ diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index f96bf4c7c232..95fc2eaf11dc 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -507,7 +507,16 @@ static void amdtp_pull_midi(struct amdtp_stream *s, static void update_pcm_pointers(struct amdtp_stream *s, struct snd_pcm_substream *pcm, unsigned int frames) -{ unsigned int ptr; +{ + unsigned int ptr; + + /* + * In IEC 61883-6, one data block represents one event. In ALSA, one + * event equals to one PCM frame. But Dice has a quirk to transfer + * two PCM frames in one data block. + */ + if (s->double_pcm_frames) + frames *= 2; ptr = s->pcm_buffer_pointer + frames; if (ptr >= pcm->runtime->buffer_size) diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index d8ee7b0e9386..4823c08196ac 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -125,6 +125,7 @@ struct amdtp_stream { unsigned int pcm_buffer_pointer; unsigned int pcm_period_pointer; bool pointer_flush; + bool double_pcm_frames; struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c index a9a30c0161f1..e3a04d69c853 100644 --- a/sound/firewire/dice.c +++ b/sound/firewire/dice.c @@ -567,10 +567,14 @@ static int dice_hw_params(struct snd_pcm_substream *substream, return err; /* - * At rates above 96 kHz, pretend that the stream runs at half the - * actual sample rate with twice the number of channels; two samples - * of a channel are stored consecutively in the packet. Requires - * blocking mode and PCM buffer size should be aligned to SYT_INTERVAL. + * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in + * one data block of AMDTP packet. Thus sampling transfer frequency is + * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are + * transferred on AMDTP packets at 96 kHz. Two successive samples of a + * channel are stored consecutively in the packet. This quirk is called + * as 'Dual Wire'. + * For this quirk, blocking mode is required and PCM buffer size should + * be aligned to SYT_INTERVAL. */ channels = params_channels(hw_params); if (rate_index > 4) { @@ -579,18 +583,25 @@ static int dice_hw_params(struct snd_pcm_substream *substream, return err; } - for (i = 0; i < channels; i++) { - dice->stream.pcm_positions[i * 2] = i; - dice->stream.pcm_positions[i * 2 + 1] = i + channels; - } - rate /= 2; channels *= 2; + dice->stream.double_pcm_frames = true; + } else { + dice->stream.double_pcm_frames = false; } mode = rate_index_to_mode(rate_index); amdtp_stream_set_parameters(&dice->stream, rate, channels, dice->rx_midi_ports[mode]); + if (rate_index > 4) { + channels /= 2; + + for (i = 0; i < channels; i++) { + dice->stream.pcm_positions[i] = i * 2; + dice->stream.pcm_positions[i + channels] = i * 2 + 1; + } + } + amdtp_stream_set_pcm_format(&dice->stream, params_format(hw_params)); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 6f2fa838b635..6e5d0cb4e3d7 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -217,6 +217,7 @@ enum { CXT_FIXUP_HEADPHONE_MIC_PIN, CXT_FIXUP_HEADPHONE_MIC, CXT_FIXUP_GPIO1, + CXT_FIXUP_ASPIRE_DMIC, CXT_FIXUP_THINKPAD_ACPI, CXT_FIXUP_OLPC_XO, CXT_FIXUP_CAP_MIX_AMP, @@ -664,6 +665,12 @@ static const struct hda_fixup cxt_fixups[] = { { } }, }, + [CXT_FIXUP_ASPIRE_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_stereo_dmic, + .chained = true, + .chain_id = CXT_FIXUP_GPIO1, + }, [CXT_FIXUP_THINKPAD_ACPI] = { .type = HDA_FIXUP_FUNC, .v.func = hda_fixup_thinkpad_acpi, @@ -744,7 +751,7 @@ static const struct hda_model_fixup cxt5051_fixup_models[] = { static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1), + SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d446ac3137b3..1ba22fb527c2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -328,6 +328,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0885: case 0x10ec0887: /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ + case 0x10ec0900: alc889_coef_init(codec); break; case 0x10ec0888: @@ -2350,6 +2351,7 @@ static int patch_alc882(struct hda_codec *codec) switch (codec->vendor_id) { case 0x10ec0882: case 0x10ec0885: + case 0x10ec0900: break; default: /* ALC883 and variants */ diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index a20b30ca52c0..98523209f739 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -282,10 +282,10 @@ static const struct cs4265_clk_para clk_map_table[] = { /*64k*/ {8192000, 64000, 1, 0}, - {1228800, 64000, 1, 1}, - {1693440, 64000, 1, 2}, - {2457600, 64000, 1, 3}, - {3276800, 64000, 1, 4}, + {12288000, 64000, 1, 1}, + {16934400, 64000, 1, 2}, + {24576000, 64000, 1, 3}, + {32768000, 64000, 1, 4}, /* 88.2k */ {11289600, 88200, 1, 0}, @@ -435,10 +435,10 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream, index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params)); if (index >= 0) { snd_soc_update_bits(codec, CS4265_ADC_CTL, - CS4265_ADC_FM, clk_map_table[index].fm_mode); + CS4265_ADC_FM, clk_map_table[index].fm_mode << 6); snd_soc_update_bits(codec, CS4265_MCLK_FREQ, CS4265_MCLK_FREQ_MASK, - clk_map_table[index].mclkdiv); + clk_map_table[index].mclkdiv << 4); } else { dev_err(codec->dev, "can't get correct mclk\n"); diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h index 1dceafeec415..f586cbd30b77 100644 --- a/sound/soc/codecs/da732x.h +++ b/sound/soc/codecs/da732x.h @@ -11,7 +11,7 @@ */ #ifndef __DA732X_H_ -#define __DA732X_H +#define __DA732X_H_ #include <sound/soc.h> diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 6bc6efdec550..f1ec6e6bd08a 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2059,6 +2059,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { static const struct regmap_config rt5640_regmap = { .reg_bits = 8, .val_bits = 16, + .use_single_rw = true, .max_register = RT5640_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5640_ranges) * RT5640_PR_SPACING), diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 67f14556462f..5337c448b5e3 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -2135,10 +2135,10 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "BST2", NULL, "IN2P" }, { "BST2", NULL, "IN2N" }, - { "IN1P", NULL, "micbias1" }, - { "IN1N", NULL, "micbias1" }, - { "IN2P", NULL, "micbias1" }, - { "IN2N", NULL, "micbias1" }, + { "IN1P", NULL, "MICBIAS1" }, + { "IN1N", NULL, "MICBIAS1" }, + { "IN2P", NULL, "MICBIAS1" }, + { "IN2N", NULL, "MICBIAS1" }, { "ADC 1", NULL, "BST1" }, { "ADC 1", NULL, "ADC 1 power" }, diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 159e517fa09a..cef7776b712c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -481,12 +481,19 @@ static int asoc_simple_card_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&priv->snd_card, priv); ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); + if (ret >= 0) + return ret; err: asoc_simple_card_unref(pdev); return ret; } +static int asoc_simple_card_remove(struct platform_device *pdev) +{ + return asoc_simple_card_unref(pdev); +} + static const struct of_device_id asoc_simple_of_match[] = { { .compatible = "simple-audio-card", }, {}, @@ -500,6 +507,7 @@ static struct platform_driver asoc_simple_card = { .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, + .remove = asoc_simple_card_remove, }; module_platform_driver(asoc_simple_card); diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index f8a6adc2d81c..4336d1831485 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -260,7 +260,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { .stream_name = "TWL4030 Voice", .cpu_dai_name = "omap-mcbsp.3", .codec_dai_name = "twl4030-voice", - .platform_name = "omap-mcbsp.2", + .platform_name = "omap-mcbsp.3", .codec_name = "twl4030-codec", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM, diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 3fdf3be7b99a..f95e7ab135e8 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -247,7 +247,7 @@ rsnd_gen2_dma_addr(struct rsnd_priv *priv, }; /* it shouldn't happen */ - if (use_dvc & !use_src) + if (use_dvc && !use_src) dev_err(dev, "DVC is selected without SRC\n"); /* use SSIU or SSI ? */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d4bfd4a9076f..889f4e3d35dc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1325,7 +1325,7 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, device_initialize(rtd->dev); rtd->dev->parent = rtd->card->dev; rtd->dev->release = rtd_release; - rtd->dev->init_name = name; + dev_set_name(rtd->dev, "%s", name); dev_set_drvdata(rtd->dev, rtd); mutex_init(&rtd->pcm_mutex); INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients); diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 9577121ce971..ca8037634100 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -21,7 +21,7 @@ */ #ifndef __TEGRA_ASOC_UTILS_H__ -#define __TEGRA_ASOC_UTILS_H_ +#define __TEGRA_ASOC_UTILS_H__ struct clk; struct device; diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile index 5386fd7c43ae..74bbefdeaf4c 100644 --- a/tools/testing/selftests/ipc/Makefile +++ b/tools/testing/selftests/ipc/Makefile @@ -1,18 +1,18 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) ifeq ($(ARCH),i386) - ARCH := X86 + ARCH := x86 CFLAGS := -DCONFIG_X86_32 -D__i386__ endif ifeq ($(ARCH),x86_64) - ARCH := X86 + ARCH := x86 CFLAGS := -DCONFIG_X86_64 -D__x86_64__ endif CFLAGS += -I../../../../usr/include/ all: -ifeq ($(ARCH),X86) +ifeq ($(ARCH),x86) gcc $(CFLAGS) msgque.c -o msgque_test else echo "Not an x86 target, can't build msgque selftest" diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile index d7d6bbeeff2f..8aabd82db9e4 100644 --- a/tools/testing/selftests/kcmp/Makefile +++ b/tools/testing/selftests/kcmp/Makefile @@ -1,11 +1,11 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) ifeq ($(ARCH),i386) - ARCH := X86 + ARCH := x86 CFLAGS := -DCONFIG_X86_32 -D__i386__ endif ifeq ($(ARCH),x86_64) - ARCH := X86 + ARCH := x86 CFLAGS := -DCONFIG_X86_64 -D__x86_64__ endif @@ -15,7 +15,7 @@ CFLAGS += -I../../../../usr/include/ CFLAGS += -I../../../../arch/x86/include/ all: -ifeq ($(ARCH),X86) +ifeq ($(ARCH),x86) gcc $(CFLAGS) kcmp_test.c -o kcmp_test else echo "Not an x86 target, can't build kcmp selftest" diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile index 6816c491c5ff..ad4ab01cd28f 100644 --- a/tools/testing/selftests/memfd/Makefile +++ b/tools/testing/selftests/memfd/Makefile @@ -1,10 +1,10 @@ uname_M := $(shell uname -m 2>/dev/null || echo not) ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/) ifeq ($(ARCH),i386) - ARCH := X86 + ARCH := x86 endif ifeq ($(ARCH),x86_64) - ARCH := X86 + ARCH := x86 endif CFLAGS += -D_FILE_OFFSET_BITS=64 @@ -14,20 +14,20 @@ CFLAGS += -I../../../../include/uapi/ CFLAGS += -I../../../../include/ all: -ifeq ($(ARCH),X86) +ifeq ($(ARCH),x86) gcc $(CFLAGS) memfd_test.c -o memfd_test else echo "Not an x86 target, can't build memfd selftest" endif run_tests: all -ifeq ($(ARCH),X86) +ifeq ($(ARCH),x86) gcc $(CFLAGS) memfd_test.c -o memfd_test endif @./memfd_test || echo "memfd_test: [FAIL]" build_fuse: -ifeq ($(ARCH),X86) +ifeq ($(ARCH),x86) gcc $(CFLAGS) fuse_mnt.c `pkg-config fuse --cflags --libs` -o fuse_mnt gcc $(CFLAGS) fuse_test.c -o fuse_test else diff --git a/drivers/staging/usbip/userspace/.gitignore b/tools/usb/usbip/.gitignore index 9aad9e30a8ba..9aad9e30a8ba 100644 --- a/drivers/staging/usbip/userspace/.gitignore +++ b/tools/usb/usbip/.gitignore diff --git a/drivers/staging/usbip/userspace/AUTHORS b/tools/usb/usbip/AUTHORS index a27ea8d03aec..a27ea8d03aec 100644 --- a/drivers/staging/usbip/userspace/AUTHORS +++ b/tools/usb/usbip/AUTHORS diff --git a/drivers/staging/usbip/userspace/COPYING b/tools/usb/usbip/COPYING index c5611e48a8e1..c5611e48a8e1 100644 --- a/drivers/staging/usbip/userspace/COPYING +++ b/tools/usb/usbip/COPYING diff --git a/drivers/staging/usbip/userspace/INSTALL b/tools/usb/usbip/INSTALL index d3c5b40a9409..d3c5b40a9409 100644 --- a/drivers/staging/usbip/userspace/INSTALL +++ b/tools/usb/usbip/INSTALL diff --git a/drivers/staging/usbip/userspace/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf038c9f..66f8bf038c9f 100644 --- a/drivers/staging/usbip/userspace/Makefile.am +++ b/tools/usb/usbip/Makefile.am diff --git a/drivers/staging/usbip/userspace/README b/tools/usb/usbip/README index 831f49fea3ce..831f49fea3ce 100644 --- a/drivers/staging/usbip/userspace/README +++ b/tools/usb/usbip/README diff --git a/drivers/staging/usbip/userspace/autogen.sh b/tools/usb/usbip/autogen.sh index e1112d3fcbf6..e1112d3fcbf6 100755 --- a/drivers/staging/usbip/userspace/autogen.sh +++ b/tools/usb/usbip/autogen.sh diff --git a/drivers/staging/usbip/userspace/cleanup.sh b/tools/usb/usbip/cleanup.sh index 955c3ccb729a..955c3ccb729a 100755 --- a/drivers/staging/usbip/userspace/cleanup.sh +++ b/tools/usb/usbip/cleanup.sh diff --git a/drivers/staging/usbip/userspace/configure.ac b/tools/usb/usbip/configure.ac index 607d05c5ccfd..607d05c5ccfd 100644 --- a/drivers/staging/usbip/userspace/configure.ac +++ b/tools/usb/usbip/configure.ac diff --git a/drivers/staging/usbip/userspace/doc/usbip.8 b/tools/usb/usbip/doc/usbip.8 index a6097be25d28..a6097be25d28 100644 --- a/drivers/staging/usbip/userspace/doc/usbip.8 +++ b/tools/usb/usbip/doc/usbip.8 diff --git a/drivers/staging/usbip/userspace/doc/usbipd.8 b/tools/usb/usbip/doc/usbipd.8 index ac4635db3f03..ac4635db3f03 100644 --- a/drivers/staging/usbip/userspace/doc/usbipd.8 +++ b/tools/usb/usbip/doc/usbipd.8 diff --git a/drivers/staging/usbip/userspace/libsrc/Makefile.am b/tools/usb/usbip/libsrc/Makefile.am index 7c8f8a4d54e4..7c8f8a4d54e4 100644 --- a/drivers/staging/usbip/userspace/libsrc/Makefile.am +++ b/tools/usb/usbip/libsrc/Makefile.am diff --git a/drivers/staging/usbip/userspace/libsrc/list.h b/tools/usb/usbip/libsrc/list.h index 8d0c936e184f..8d0c936e184f 100644 --- a/drivers/staging/usbip/userspace/libsrc/list.h +++ b/tools/usb/usbip/libsrc/list.h diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/tools/usb/usbip/libsrc/names.c index 81ff8522405c..81ff8522405c 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/tools/usb/usbip/libsrc/names.c diff --git a/drivers/staging/usbip/userspace/libsrc/names.h b/tools/usb/usbip/libsrc/names.h index 680926512de2..680926512de2 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.h +++ b/tools/usb/usbip/libsrc/names.h diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c b/tools/usb/usbip/libsrc/sysfs_utils.c index 36ac88ece0b8..36ac88ece0b8 100644 --- a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c +++ b/tools/usb/usbip/libsrc/sysfs_utils.c diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h b/tools/usb/usbip/libsrc/sysfs_utils.h index 32ac1d105d18..32ac1d105d18 100644 --- a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h +++ b/tools/usb/usbip/libsrc/sysfs_utils.h diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/tools/usb/usbip/libsrc/usbip_common.c index ac73710473de..ac73710473de 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ b/tools/usb/usbip/libsrc/usbip_common.c diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h index 5a0e95edf4df..5a0e95edf4df 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h +++ b/tools/usb/usbip/libsrc/usbip_common.h diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/tools/usb/usbip/libsrc/usbip_host_driver.c index bef08d5c44e8..bef08d5c44e8 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c +++ b/tools/usb/usbip/libsrc/usbip_host_driver.c diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h b/tools/usb/usbip/libsrc/usbip_host_driver.h index 2a31f855c616..2a31f855c616 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h +++ b/tools/usb/usbip/libsrc/usbip_host_driver.h diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad9204773533..ad9204773533 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316cf2cac..fa2316cf2cac 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4ebadeff..e81a4ebadeff 100644 --- a/drivers/staging/usbip/userspace/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am diff --git a/drivers/staging/usbip/userspace/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d943529..d7599d943529 100644 --- a/drivers/staging/usbip/userspace/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c diff --git a/drivers/staging/usbip/userspace/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a9d8ad..84fe66a9d8ad 100644 --- a/drivers/staging/usbip/userspace/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index d58a14dfc094..d58a14dfc094 100644 --- a/drivers/staging/usbip/userspace/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c diff --git a/drivers/staging/usbip/userspace/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141ae68b..fa46141ae68b 100644 --- a/drivers/staging/usbip/userspace/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/tools/usb/usbip/src/usbip_detach.c index 05c6d15856eb..05c6d15856eb 100644 --- a/drivers/staging/usbip/userspace/src/usbip_detach.c +++ b/tools/usb/usbip/src/usbip_detach.c diff --git a/drivers/staging/usbip/userspace/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index d5ce34a410e7..d5ce34a410e7 100644 --- a/drivers/staging/usbip/userspace/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c diff --git a/drivers/staging/usbip/userspace/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c index b4c37e76a6e0..b4c37e76a6e0 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.c +++ b/tools/usb/usbip/src/usbip_network.c diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h index c1e875cf1078..c1e875cf1078 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.h +++ b/tools/usb/usbip/src/usbip_network.h diff --git a/drivers/staging/usbip/userspace/src/usbip_port.c b/tools/usb/usbip/src/usbip_port.c index a2e884fd9226..a2e884fd9226 100644 --- a/drivers/staging/usbip/userspace/src/usbip_port.c +++ b/tools/usb/usbip/src/usbip_port.c diff --git a/drivers/staging/usbip/userspace/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c9cbaf..a4a496c9cbaf 100644 --- a/drivers/staging/usbip/userspace/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 2f87f2d348ba..2f87f2d348ba 100644 --- a/drivers/staging/usbip/userspace/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c diff --git a/drivers/staging/usbip/userspace/src/utils.c b/tools/usb/usbip/src/utils.c index 2b3d6d235015..2b3d6d235015 100644 --- a/drivers/staging/usbip/userspace/src/utils.c +++ b/tools/usb/usbip/src/utils.c diff --git a/drivers/staging/usbip/userspace/src/utils.h b/tools/usb/usbip/src/utils.h index 5916fd3e02a6..5916fd3e02a6 100644 --- a/drivers/staging/usbip/userspace/src/utils.h +++ b/tools/usb/usbip/src/utils.h |