diff --git a/Documentation/devicetree/bindings/spi/efm32-spi.txt b/Documentation/devicetree/bindings/spi/efm32-spi.txt index a590ca51be75..f762e11bfe11 100644 --- a/Documentation/devicetree/bindings/spi/efm32-spi.txt +++ b/Documentation/devicetree/bindings/spi/efm32-spi.txt @@ -3,7 +3,7 @@ Required properties: - #address-cells: see spi-bus.txt - #size-cells: see spi-bus.txt -- compatible: should be "efm32,spi" +- compatible: should be "energymicro,efm32-spi" - reg: Offset and length of the register set for the controller - interrupts: pair specifying rx and tx irq - clocks: phandle to the spi clock @@ -15,7 +15,7 @@ Example: spi1: spi@0x4000c400 { /* USART1 */ #address-cells = <1>; #size-cells = <0>; - compatible = "efm32,spi"; + compatible = "energymicro,efm32-spi"; reg = <0x4000c400 0x400>; interrupts = <15 16>; clocks = <&cmu 20>; diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index e55124e7c40c..855d9b37bf76 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -317,6 +317,7 @@ for more than this value report a warning. This file shows up if CONFIG_DETECT_HUNG_TASK is enabled. 0: means infinite timeout - no checking done. +Possible values to set are in range {0..LONG_MAX/HZ}. ============================================================== diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 1e6b6531bbcc..d2ba80bb7af5 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -55,6 +55,7 @@ zc3xx 0458:700f Genius VideoCam Web V2 sonixj 0458:7025 Genius Eye 311Q sn9c20x 0458:7029 Genius Look 320s sonixj 0458:702e Genius Slim 310 NB +sn9c20x 0458:7045 Genius Look 1320 V2 sn9c20x 0458:704a Genius Slim 1320 sn9c20x 0458:704c Genius i-Look 1321 sn9c20x 045e:00f4 LifeCam VX-6000 (SN9C20x + OV9650) diff --git a/Makefile b/Makefile index b2f7de81e9a2..eed07f3f9308 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 14 -SUBLEVEL = 2 +SUBLEVEL = 3 EXTRAVERSION = NAME = Shuffling Zombie Juror diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15949459611f..44298add8a48 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -898,7 +898,7 @@ config ARCH_MULTI_V5 bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)" depends on !ARCH_MULTI_V6_V7 select ARCH_MULTI_V4_V5 - select CPU_ARM926T if (!CPU_ARM946E || CPU_ARM1020 || \ + select CPU_ARM926T if !(CPU_ARM946E || CPU_ARM1020 || \ CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \ CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index e3f27ec31718..2e7d932887b5 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -183,7 +183,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -204,7 +204,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 7e6c64ed966d..801055a42998 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -325,7 +325,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -346,7 +346,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 486880b74831..dd142bc677ca 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -334,7 +334,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index 7063311a58d9..5942e7dab94f 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -202,7 +202,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -223,7 +223,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 6d95d3df33c7..79087ccf64bc 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -448,7 +448,7 @@ ti,hwmods = "usb_otg_hs"; status = "disabled"; - usb_ctrl_mod: control@44e10000 { + usb_ctrl_mod: control@44e10620 { compatible = "ti,am335x-usb-ctrl-module"; reg = <0x44e10620 0x10 0x44e10648 0x4>; @@ -551,7 +551,7 @@ "tx14", "tx15"; }; - cppi41dma: dma-controller@07402000 { + cppi41dma: dma-controller@47402000 { compatible = "ti,am3359-cppi41"; reg = <0x47400000 0x1000 0x47402000 0x1000 diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 74b5964430ac..e5d4902c630f 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -226,6 +226,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x72004 0x4>; + clocks = <&gateclk 4>; }; eth1: ethernet@74000 { diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index b42e658876e5..457112d659ea 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -287,6 +287,7 @@ regulator-name = "vdd_g3d"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; + regulator-always-on; regulator-boot-on; op_mode = <1>; }; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index d3f8a6e8ca20..69409f7e05dc 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -275,6 +275,8 @@ gpmc,num-waitpins = <4>; ti,hwmods = "gpmc"; ti,no-idle-on-init; + clocks = <&l3_div_ck>; + clock-names = "fck"; }; uart1: serial@4806a000 { diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index a72813a9663e..7a16647c76f4 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -302,6 +302,8 @@ gpmc,num-cs = <8>; gpmc,num-waitpins = <4>; ti,hwmods = "gpmc"; + clocks = <&l3_iclk_div>; + clock-names = "fck"; }; i2c1: i2c@48070000 { diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index ec0698a8354a..9c2ba74a8b60 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -164,19 +164,6 @@ status = "disabled"; }; - serial@70006400 { - compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; - reg = <0x70006400 0x40>; - reg-shift = <2>; - interrupts = ; - clocks = <&tegra_car TEGRA124_CLK_UARTE>; - resets = <&tegra_car 66>; - reset-names = "serial"; - dmas = <&apbdma 20>, <&apbdma 20>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - pwm@7000a000 { compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm"; reg = <0x7000a000 0x100>; diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index 191ada6e4d2d..662c7bd06108 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -156,7 +156,7 @@ /* Select the best insn combination to perform the */ \ /* actual __m * __n / (__p << 64) operation. */ \ if (!__c) { \ - asm ( "umull %Q0, %R0, %1, %Q2\n\t" \ + asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \ "mov %Q0, #0" \ : "=&r" (__res) \ : "r" (__m), "r" (__n) \ diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index e42cf597f6e6..2aff798fbef4 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -3,11 +3,6 @@ #ifdef __KERNEL__ -#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP) -/* ARM doesn't provide unprivileged exclusive memory accessors */ -#include -#else - #include #include #include @@ -164,6 +159,5 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) return ret; } -#endif /* !(CPU_USE_DOMAINS && SMP) */ #endif /* __KERNEL__ */ #endif /* _ASM_ARM_FUTEX_H */ diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index dfff709fda3c..219ac88a9542 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h @@ -140,6 +140,7 @@ #define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */ #define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */ #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ +#define L_PTE_MT_VECTORS (_AT(pteval_t, 0x0f) << 2) /* 1111 */ #define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) #ifndef __ASSEMBLY__ diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index acabef1a75df..43876245fc57 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -48,6 +48,5 @@ */ #define __IGNORE_fadvise64_64 #define __IGNORE_migrate_pages -#define __IGNORE_kcmp #endif /* __ASM_ARM_UNISTD_H */ diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index f0d180d8b29f..8cf0996aa1a8 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -184,3 +184,10 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_entry_phys); } + +void arch_crash_save_vmcoreinfo(void) +{ +#ifdef CONFIG_ARM_LPAE + VMCOREINFO_CONFIG(ARM_LPAE); +#endif +} diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index e022a869bff2..6037a9a01ed5 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -222,6 +222,7 @@ void __init ti81xx_init_irq(void) static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs *regs) { u32 irqnr; + int handled_irq = 0; do { irqnr = readl_relaxed(base_addr + 0x98); @@ -249,8 +250,15 @@ out: if (irqnr) { irqnr = irq_find_mapping(domain, irqnr); handle_IRQ(irqnr, regs); + handled_irq = 1; } } while (irqnr); + + /* If an irq is masked or deasserted while active, we will + * keep ending up here with no irq handled. So remove it from + * the INTC with an ack.*/ + if (!handled_irq) + omap_ack_irq(NULL); } asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs *regs) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 1f33f5db10d5..66c60fe1104c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2546,11 +2546,12 @@ static int __init _init(struct omap_hwmod *oh, void *data) return -EINVAL; } - if (np) + if (np) { if (of_find_property(np, "ti,no-reset-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_RESET; if (of_find_property(np, "ti,no-idle-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_IDLE; + } oh->_state = _HWMOD_STATE_INITIALIZED; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4c3b1e6df508..ea4643abbe61 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1968,7 +1968,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { .name = "usb_host_hs", .class = &omap3xxx_usb_host_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "usbhost_clkdm", .mpu_irqs = omap3xxx_usb_host_hs_irqs, .main_clk = "usbhost_48m_fck", .prcm = { @@ -2053,7 +2053,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { .name = "usb_tll_hs", .class = &omap3xxx_usb_tll_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "core_l4_clkdm", .mpu_irqs = omap3xxx_usb_tll_hs_irqs, .main_clk = "usbtll_fck", .prcm = { diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 7bdd22afce69..d4d0fce325c7 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -103,7 +103,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { } #define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0) -#if defined(CONFIG_ARCH_OMAP4) +#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4) extern u16 pm44xx_errata; #define IS_PM44XX_ERRATUM(id) (pm44xx_errata & (id)) #else diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h index 8bc02913517c..0e1bb46264f9 100644 --- a/arch/arm/mach-pxa/include/mach/hx4700.h +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -14,6 +14,7 @@ #include #include +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ #define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO #define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 1f8fed94c2a4..ca8ecdee47d8 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -446,7 +446,6 @@ config CPU_32v5 config CPU_32v6 bool - select CPU_USE_DOMAINS if CPU_V6 && MMU select TLS_REG_EMUL if !CPU_32v6K && !MMU config CPU_32v6K @@ -671,7 +670,7 @@ config ARM_VIRT_EXT config SWP_EMULATE bool "Emulate SWP/SWPB instructions" - depends on !CPU_USE_DOMAINS && CPU_V7 + depends on CPU_V7 default y if SMP select HAVE_PROC_CPU if PROC_FS help diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index a623cb3ad012..b68c6b22e1c8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -516,6 +516,16 @@ static void __init build_mem_type_table(void) s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2; /* + * We don't use domains on ARMv6 (since this causes problems with + * v6/v7 kernels), so we must use a separate memory type for user + * r/o, kernel r/w to map the vectors page. + */ +#ifndef CONFIG_ARM_LPAE + if (cpu_arch == CPU_ARCH_ARMv6) + vecs_pgprot |= L_PTE_MT_VECTORS; +#endif + + /* * ARMv6 and above have extended page tables. */ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index e3c48a3fe063..ee1d80593958 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -112,13 +112,9 @@ * 100x 1 0 1 r/o no acc * 10x0 1 0 1 r/o no acc * 1011 0 0 1 r/w no acc - * 110x 0 1 0 r/w r/o - * 11x0 0 1 0 r/w r/o - * 1111 0 1 1 r/w r/w - * - * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed: * 110x 1 1 1 r/o r/o * 11x0 1 1 1 r/o r/o + * 1111 0 1 1 r/w r/w */ .macro armv6_mt_table pfx \pfx\()_mt_table: @@ -137,7 +133,7 @@ .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED .long 0x00 @ unused .long 0x00 @ unused - .long 0x00 @ unused + .long PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX @ L_PTE_MT_VECTORS .endm .macro armv6_set_pte_ext pfx @@ -158,24 +154,21 @@ tst r1, #L_PTE_USER orrne r3, r3, #PTE_EXT_AP1 -#ifdef CONFIG_CPU_USE_DOMAINS - @ allow kernel read/write access to read-only user pages tstne r3, #PTE_EXT_APX - bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 -#endif + + @ user read-only -> kernel read-only + bicne r3, r3, #PTE_EXT_AP0 tst r1, #L_PTE_XN orrne r3, r3, #PTE_EXT_XN - orr r3, r3, r2 + eor r3, r3, r2 tst r1, #L_PTE_YOUNG tstne r1, #L_PTE_PRESENT moveq r3, #0 -#ifndef CONFIG_CPU_USE_DOMAINS tstne r1, #L_PTE_NONE movne r3, #0 -#endif str r3, [r0] mcr p15, 0, r0, c7, c10, 1 @ flush_pte diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S index bdd3be4be77a..1f52915f2b28 100644 --- a/arch/arm/mm/proc-v7-2level.S +++ b/arch/arm/mm/proc-v7-2level.S @@ -90,21 +90,14 @@ ENTRY(cpu_v7_set_pte_ext) tst r1, #L_PTE_USER orrne r3, r3, #PTE_EXT_AP1 -#ifdef CONFIG_CPU_USE_DOMAINS - @ allow kernel read/write access to read-only user pages - tstne r3, #PTE_EXT_APX - bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 -#endif tst r1, #L_PTE_XN orrne r3, r3, #PTE_EXT_XN tst r1, #L_PTE_YOUNG tstne r1, #L_PTE_VALID -#ifndef CONFIG_CPU_USE_DOMAINS eorne r1, r1, #L_PTE_NONE tstne r1, #L_PTE_NONE -#endif moveq r3, #0 ARM( str r3, [r0, #2048]! ) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index aa3917c8b623..acb17e0d5e24 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -199,7 +199,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { if (pte_valid_user(pte)) { - if (pte_exec(pte)) + if (!pte_special(pte) && pte_exec(pte)) __sync_icache_dcache(pte, addr); if (pte_dirty(pte) && pte_write(pte)) pte_val(pte) &= ~PTE_RDONLY; @@ -286,11 +286,11 @@ static inline int has_transparent_hugepage(void) * Mark the prot value as uncacheable and unbufferable. */ #define pgprot_noncached(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) #define pgprot_writecombine(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) #define pgprot_dmacoherent(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC)) + __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) #define __HAVE_PHYS_MEM_ACCESS_PROT struct file; extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index bb8eb8a78e67..faa0e1ce59df 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -404,7 +404,7 @@ __SYSCALL(379, sys_finit_module) __SYSCALL(380, sys_sched_setattr) __SYSCALL(381, sys_sched_getattr) -#define __NR_compat_syscalls 379 +#define __NR_compat_syscalls 382 /* * Compat syscall numbers used by the AArch64 kernel. diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index fa9aaf7144b7..1d4706114a45 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -15,23 +15,29 @@ #include #include +#include #include #define ATOMIC_INIT(i) { (i) } +#define __ATOMIC_NO_BARRIER "\n" + #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES #define __ATOMIC_OR "lao" #define __ATOMIC_AND "lan" #define __ATOMIC_ADD "laa" +#define __ATOMIC_BARRIER "bcr 14,0\n" -#define __ATOMIC_LOOP(ptr, op_val, op_string) \ +#define __ATOMIC_LOOP(ptr, op_val, op_string, __barrier) \ ({ \ int old_val; \ \ typecheck(atomic_t *, ptr); \ asm volatile( \ + __barrier \ op_string " %0,%2,%1\n" \ + __barrier \ : "=d" (old_val), "+Q" ((ptr)->counter) \ : "d" (op_val) \ : "cc", "memory"); \ @@ -43,8 +49,9 @@ #define __ATOMIC_OR "or" #define __ATOMIC_AND "nr" #define __ATOMIC_ADD "ar" +#define __ATOMIC_BARRIER "\n" -#define __ATOMIC_LOOP(ptr, op_val, op_string) \ +#define __ATOMIC_LOOP(ptr, op_val, op_string, __barrier) \ ({ \ int old_val, new_val; \ \ @@ -82,7 +89,7 @@ static inline void atomic_set(atomic_t *v, int i) static inline int atomic_add_return(int i, atomic_t *v) { - return __ATOMIC_LOOP(v, i, __ATOMIC_ADD) + i; + return __ATOMIC_LOOP(v, i, __ATOMIC_ADD, __ATOMIC_BARRIER) + i; } static inline void atomic_add(int i, atomic_t *v) @@ -94,12 +101,10 @@ static inline void atomic_add(int i, atomic_t *v) : "+Q" (v->counter) : "i" (i) : "cc", "memory"); - } else { - atomic_add_return(i, v); + return; } -#else - atomic_add_return(i, v); #endif + __ATOMIC_LOOP(v, i, __ATOMIC_ADD, __ATOMIC_NO_BARRIER); } #define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0) @@ -115,12 +120,12 @@ static inline void atomic_add(int i, atomic_t *v) static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { - __ATOMIC_LOOP(v, ~mask, __ATOMIC_AND); + __ATOMIC_LOOP(v, ~mask, __ATOMIC_AND, __ATOMIC_NO_BARRIER); } static inline void atomic_set_mask(unsigned int mask, atomic_t *v) { - __ATOMIC_LOOP(v, mask, __ATOMIC_OR); + __ATOMIC_LOOP(v, mask, __ATOMIC_OR, __ATOMIC_NO_BARRIER); } #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) @@ -157,19 +162,24 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #ifdef CONFIG_64BIT +#define __ATOMIC64_NO_BARRIER "\n" + #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES #define __ATOMIC64_OR "laog" #define __ATOMIC64_AND "lang" #define __ATOMIC64_ADD "laag" +#define __ATOMIC64_BARRIER "bcr 14,0\n" -#define __ATOMIC64_LOOP(ptr, op_val, op_string) \ +#define __ATOMIC64_LOOP(ptr, op_val, op_string, __barrier) \ ({ \ long long old_val; \ \ typecheck(atomic64_t *, ptr); \ asm volatile( \ + __barrier \ op_string " %0,%2,%1\n" \ + __barrier \ : "=d" (old_val), "+Q" ((ptr)->counter) \ : "d" (op_val) \ : "cc", "memory"); \ @@ -181,8 +191,9 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #define __ATOMIC64_OR "ogr" #define __ATOMIC64_AND "ngr" #define __ATOMIC64_ADD "agr" +#define __ATOMIC64_BARRIER "\n" -#define __ATOMIC64_LOOP(ptr, op_val, op_string) \ +#define __ATOMIC64_LOOP(ptr, op_val, op_string, __barrier) \ ({ \ long long old_val, new_val; \ \ @@ -220,17 +231,32 @@ static inline void atomic64_set(atomic64_t *v, long long i) static inline long long atomic64_add_return(long long i, atomic64_t *v) { - return __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD) + i; + return __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD, __ATOMIC64_BARRIER) + i; +} + +static inline void atomic64_add(long long i, atomic64_t *v) +{ +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES + if (__builtin_constant_p(i) && (i > -129) && (i < 128)) { + asm volatile( + "agsi %0,%1\n" + : "+Q" (v->counter) + : "i" (i) + : "cc", "memory"); + return; + } +#endif + __ATOMIC64_LOOP(v, i, __ATOMIC64_ADD, __ATOMIC64_NO_BARRIER); } static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) { - __ATOMIC64_LOOP(v, ~mask, __ATOMIC64_AND); + __ATOMIC64_LOOP(v, ~mask, __ATOMIC64_AND, __ATOMIC64_NO_BARRIER); } static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) { - __ATOMIC64_LOOP(v, mask, __ATOMIC64_OR); + __ATOMIC64_LOOP(v, mask, __ATOMIC64_OR, __ATOMIC64_NO_BARRIER); } #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) @@ -334,25 +360,13 @@ static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) } while (atomic64_cmpxchg(v, old, new) != old); } -#endif /* CONFIG_64BIT */ - static inline void atomic64_add(long long i, atomic64_t *v) { -#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES - if (__builtin_constant_p(i) && (i > -129) && (i < 128)) { - asm volatile( - "agsi %0,%1\n" - : "+Q" (v->counter) - : "i" (i) - : "cc", "memory"); - } else { - atomic64_add_return(i, v); - } -#else atomic64_add_return(i, v); -#endif } +#endif /* CONFIG_64BIT */ + static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u) { long long c, old; diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 6e6ad0680829..4e206123b439 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -47,14 +47,18 @@ #include #include +#include + +#define __BITOPS_NO_BARRIER "\n" #ifndef CONFIG_64BIT #define __BITOPS_OR "or" #define __BITOPS_AND "nr" #define __BITOPS_XOR "xr" +#define __BITOPS_BARRIER "\n" -#define __BITOPS_LOOP(__addr, __val, __op_string) \ +#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \ ({ \ unsigned long __old, __new; \ \ @@ -67,7 +71,7 @@ " jl 0b" \ : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\ : "d" (__val) \ - : "cc"); \ + : "cc", "memory"); \ __old; \ }) @@ -78,17 +82,20 @@ #define __BITOPS_OR "laog" #define __BITOPS_AND "lang" #define __BITOPS_XOR "laxg" +#define __BITOPS_BARRIER "bcr 14,0\n" -#define __BITOPS_LOOP(__addr, __val, __op_string) \ +#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \ ({ \ unsigned long __old; \ \ typecheck(unsigned long *, (__addr)); \ asm volatile( \ + __barrier \ __op_string " %0,%2,%1\n" \ + __barrier \ : "=d" (__old), "+Q" (*(__addr)) \ : "d" (__val) \ - : "cc"); \ + : "cc", "memory"); \ __old; \ }) @@ -97,8 +104,9 @@ #define __BITOPS_OR "ogr" #define __BITOPS_AND "ngr" #define __BITOPS_XOR "xgr" +#define __BITOPS_BARRIER "\n" -#define __BITOPS_LOOP(__addr, __val, __op_string) \ +#define __BITOPS_LOOP(__addr, __val, __op_string, __barrier) \ ({ \ unsigned long __old, __new; \ \ @@ -111,7 +119,7 @@ " jl 0b" \ : "=&d" (__old), "=&d" (__new), "+Q" (*(__addr))\ : "d" (__val) \ - : "cc"); \ + : "cc", "memory"); \ __old; \ }) @@ -149,12 +157,12 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *ptr) "oi %0,%b1\n" : "+Q" (*caddr) : "i" (1 << (nr & 7)) - : "cc"); + : "cc", "memory"); return; } #endif mask = 1UL << (nr & (BITS_PER_LONG - 1)); - __BITOPS_LOOP(addr, mask, __BITOPS_OR); + __BITOPS_LOOP(addr, mask, __BITOPS_OR, __BITOPS_NO_BARRIER); } static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr) @@ -170,12 +178,12 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *ptr) "ni %0,%b1\n" : "+Q" (*caddr) : "i" (~(1 << (nr & 7))) - : "cc"); + : "cc", "memory"); return; } #endif mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); - __BITOPS_LOOP(addr, mask, __BITOPS_AND); + __BITOPS_LOOP(addr, mask, __BITOPS_AND, __BITOPS_NO_BARRIER); } static inline void change_bit(unsigned long nr, volatile unsigned long *ptr) @@ -191,12 +199,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *ptr) "xi %0,%b1\n" : "+Q" (*caddr) : "i" (1 << (nr & 7)) - : "cc"); + : "cc", "memory"); return; } #endif mask = 1UL << (nr & (BITS_PER_LONG - 1)); - __BITOPS_LOOP(addr, mask, __BITOPS_XOR); + __BITOPS_LOOP(addr, mask, __BITOPS_XOR, __BITOPS_NO_BARRIER); } static inline int @@ -206,8 +214,7 @@ test_and_set_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long old, mask; mask = 1UL << (nr & (BITS_PER_LONG - 1)); - old = __BITOPS_LOOP(addr, mask, __BITOPS_OR); - barrier(); + old = __BITOPS_LOOP(addr, mask, __BITOPS_OR, __BITOPS_BARRIER); return (old & mask) != 0; } @@ -218,8 +225,7 @@ test_and_clear_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long old, mask; mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); - old = __BITOPS_LOOP(addr, mask, __BITOPS_AND); - barrier(); + old = __BITOPS_LOOP(addr, mask, __BITOPS_AND, __BITOPS_BARRIER); return (old & ~mask) != 0; } @@ -230,8 +236,7 @@ test_and_change_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long old, mask; mask = 1UL << (nr & (BITS_PER_LONG - 1)); - old = __BITOPS_LOOP(addr, mask, __BITOPS_XOR); - barrier(); + old = __BITOPS_LOOP(addr, mask, __BITOPS_XOR, __BITOPS_BARRIER); return (old & mask) != 0; } diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index f201af8be580..31b5ca8f8c3d 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -219,7 +219,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define to_ccwdev(n) container_of(n, struct ccw_device, dev) #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) -extern struct ccw_device *ccw_device_probe_console(void); +extern struct ccw_device *ccw_device_probe_console(struct ccw_driver *); extern void ccw_device_wait_idle(struct ccw_device *); extern int ccw_device_force_console(struct ccw_device *); diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f6be6087a0e9..a48bc79a111f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -64,7 +64,7 @@ void update_cr_regs(struct task_struct *task) if (task->thread.per_flags & PER_FLAG_NO_TE) cr_new &= ~(1UL << 55); if (cr_new != cr) - __ctl_load(cr, 0, 0); + __ctl_load(cr_new, 0, 0); /* Set or clear transaction execution TDC bits 62 and 63. */ __ctl_store(cr, 2, 2); cr_new = cr & ~3UL; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index e0676f390d57..95f4a976c160 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -753,7 +753,8 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) if (rc == 0) { if (kvm_is_ucontrol(vcpu->kvm)) - rc = -EOPNOTSUPP; + /* Don't exit for host interrupts. */ + rc = vcpu->arch.sie_block->icptcode ? -EOPNOTSUPP : 0; else rc = kvm_handle_sie_intercept(vcpu); } diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index b959f5592604..8dfe645bcc4b 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c @@ -115,7 +115,7 @@ static int print_trace_stack(void *data, char *name) */ static void print_trace_address(void *data, unsigned long addr, int reliable) { - printk(data); + printk("%s", (char *)data); printk_address(addr, reliable); } diff --git a/arch/x86/Makefile b/arch/x86/Makefile index eeda43abed6e..f8842c444560 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -152,6 +152,7 @@ cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTI # does binutils support specific instructions? asinstr := $(call as-instr,fxsaveq (%rax),-DCONFIG_AS_FXSAVEQ=1) +asinstr += $(call as-instr,crc32l %eax$(comma)%eax,-DCONFIG_AS_CRC32=1) avx_instr := $(call as-instr,vxorps %ymm0$(comma)%ymm1$(comma)%ymm2,-DCONFIG_AS_AVX=1) avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index a7677babf946..78cbb2db5a85 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -425,6 +425,9 @@ void setup_graphics(struct boot_params *boot_params) * Because the x86 boot code expects to be passed a boot_params we * need to create one ourselves (usually the bootloader would create * one for us). + * + * The caller is responsible for filling out ->code32_start in the + * returned boot_params. */ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) { @@ -483,8 +486,6 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) hdr->vid_mode = 0xffff; hdr->boot_flag = 0xAA55; - hdr->code32_start = (__u64)(unsigned long)image->image_base; - hdr->type_of_loader = 0x21; /* Convert unicode cmdline to ascii */ diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 9116aac232c7..f45ab7a36fb6 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -50,6 +50,13 @@ ENTRY(efi_pe_entry) pushl %eax pushl %esi pushl %ecx + + call reloc +reloc: + popl %ecx + subl reloc, %ecx + movl %ecx, BP_code32_start(%eax) + sub $0x4, %esp ENTRY(efi_stub_entry) @@ -63,12 +70,7 @@ ENTRY(efi_stub_entry) hlt jmp 1b 2: - call 3f -3: - popl %eax - subl $3b, %eax - subl BP_pref_address(%esi), %eax - add BP_code32_start(%esi), %eax + movl BP_code32_start(%esi), %eax leal preferred_addr(%eax), %eax jmp *%eax diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index c5c1ae0997e7..b10fa66a2540 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -217,6 +217,8 @@ ENTRY(efi_pe_entry) cmpq $0,%rax je 1f mov %rax, %rdx + leaq startup_32(%rip), %rax + movl %eax, BP_code32_start(%rdx) popq %rsi popq %rdi @@ -230,12 +232,7 @@ ENTRY(efi_stub_entry) hlt jmp 1b 2: - call 3f -3: - popq %rax - subq $3b, %rax - subq BP_pref_address(%rsi), %rax - add BP_code32_start(%esi), %eax + movl BP_code32_start(%esi), %eax leaq preferred_addr(%rax), %rax jmp *%rax diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index e099f9502ace..5f1296872aed 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -217,9 +217,13 @@ #define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */ #define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */ #define X86_FEATURE_MPX (9*32+14) /* Memory Protection Extension */ +#define X86_FEATURE_AVX512F (9*32+16) /* AVX-512 Foundation */ #define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */ #define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */ #define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */ +#define X86_FEATURE_AVX512PF (9*32+26) /* AVX-512 Prefetch */ +#define X86_FEATURE_AVX512ER (9*32+27) /* AVX-512 Exponential and Reciprocal */ +#define X86_FEATURE_AVX512CD (9*32+28) /* AVX-512 Conflict Detection */ /* * BUG word(s) diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index 554738963b28..6c1d7411eb00 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h @@ -6,11 +6,14 @@ #define XSTATE_CPUID 0x0000000d -#define XSTATE_FP 0x1 -#define XSTATE_SSE 0x2 -#define XSTATE_YMM 0x4 -#define XSTATE_BNDREGS 0x8 -#define XSTATE_BNDCSR 0x10 +#define XSTATE_FP 0x1 +#define XSTATE_SSE 0x2 +#define XSTATE_YMM 0x4 +#define XSTATE_BNDREGS 0x8 +#define XSTATE_BNDCSR 0x10 +#define XSTATE_OPMASK 0x20 +#define XSTATE_ZMM_Hi256 0x40 +#define XSTATE_Hi16_ZMM 0x80 #define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE) @@ -23,7 +26,8 @@ #define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) /* Supported features which support lazy state saving */ -#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) +#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \ + | XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM) /* Supported features which require eager state saving */ #define XSTATE_EAGER (XSTATE_BNDREGS | XSTATE_BNDCSR) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index e6253195a301..1ffc32dbe450 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -659,8 +659,8 @@ ftrace_modify_code(unsigned long ip, unsigned const char *old_code, ret = -EPERM; goto out; } - run_sync(); out: + run_sync(); return ret; fail_update: diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index ebc987398923..af1d14a9ebda 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -229,6 +229,17 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) } } + /* + * On x86-64 we do not support 16-bit segments due to + * IRET leaking the high bits of the kernel stack address. + */ +#ifdef CONFIG_X86_64 + if (!ldt_info.seg_32bit) { + error = -EINVAL; + goto out_unlock; + } +#endif + fill_ldt(&ldt, &ldt_info); if (oldmode) ldt.avl = 0; diff --git a/arch/x86/lib/hash.c b/arch/x86/lib/hash.c index 3056702e81fb..060cc4415bd9 100644 --- a/arch/x86/lib/hash.c +++ b/arch/x86/lib/hash.c @@ -39,7 +39,11 @@ static inline u32 crc32_u32(u32 crc, u32 val) { +#ifdef CONFIG_AS_CRC32 asm ("crc32l %1,%0\n" : "+r" (crc) : "rm" (val)); +#else + asm (".byte 0xf2, 0x0f, 0x38, 0xf1, 0xc1" : "+a" (crc) : "c" (val)); +#endif return crc; } diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index a05afff50eb9..b6f6863c07f9 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -207,13 +207,30 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info, * this predefined name. Either one return value is expected, or none, * for both methods and other objects. * - * Exit now if there is no return object. Warning if one was expected. + * Try to fix if there was no return object. Warning if failed to fix. */ if (!return_object) { if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, - ACPI_WARN_ALWAYS, - "Missing expected return value")); + if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { + ACPI_WARN_PREDEFINED((AE_INFO, + info->full_pathname, + ACPI_WARN_ALWAYS, + "Found unexpected NULL package element")); + + status = + acpi_ns_repair_null_element(info, + expected_btypes, + package_index, + return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (AE_OK); /* Repair was successful */ + } + } else { + ACPI_WARN_PREDEFINED((AE_INFO, + info->full_pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); + } return (AE_AML_NO_RETURN_VALUE); } diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index d777bb7cea93..a8939b98f9c3 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -252,38 +252,45 @@ static void mtip_async_complete(struct mtip_port *port, void *data, int status) { - struct mtip_cmd *command; + struct mtip_cmd *cmd; struct driver_data *dd = data; - int cb_status = status ? -EIO : 0; + int unaligned, cb_status = status ? -EIO : 0; + void (*func)(void *, int); if (unlikely(!dd) || unlikely(!port)) return; - command = &port->commands[tag]; + cmd = &port->commands[tag]; if (unlikely(status == PORT_IRQ_TF_ERR)) { dev_warn(&port->dd->pdev->dev, "Command tag %d failed due to TFE\n", tag); } + /* Clear the active flag */ + atomic_set(&port->commands[tag].active, 0); + /* Upper layer callback */ - if (likely(command->async_callback)) - command->async_callback(command->async_data, cb_status); + func = cmd->async_callback; + if (likely(func && cmpxchg(&cmd->async_callback, func, 0) == func)) { - command->async_callback = NULL; - command->comp_func = NULL; + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&dd->pdev->dev, + cmd->sg, + cmd->scatter_ents, + cmd->direction); - /* Unmap the DMA scatter list entries */ - dma_unmap_sg(&dd->pdev->dev, - command->sg, - command->scatter_ents, - command->direction); + func(cmd->async_data, cb_status); + unaligned = cmd->unaligned; - /* Clear the allocated and active bits for the command */ - atomic_set(&port->commands[tag].active, 0); - release_slot(port, tag); + /* Clear the allocated bit for the command */ + release_slot(port, tag); - up(&port->cmd_slot); + if (unlikely(unaligned)) + up(&port->cmd_slot_unal); + else + up(&port->cmd_slot); + } } /* @@ -660,11 +667,12 @@ static void mtip_timeout_function(unsigned long int data) { struct mtip_port *port = (struct mtip_port *) data; struct host_to_dev_fis *fis; - struct mtip_cmd *command; - int tag, cmdto_cnt = 0; + struct mtip_cmd *cmd; + int unaligned, tag, cmdto_cnt = 0; unsigned int bit, group; unsigned int num_command_slots; unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; + void (*func)(void *, int); if (unlikely(!port)) return; @@ -694,8 +702,8 @@ static void mtip_timeout_function(unsigned long int data) group = tag >> 5; bit = tag & 0x1F; - command = &port->commands[tag]; - fis = (struct host_to_dev_fis *) command->command; + cmd = &port->commands[tag]; + fis = (struct host_to_dev_fis *) cmd->command; set_bit(tag, tagaccum); cmdto_cnt++; @@ -709,27 +717,30 @@ static void mtip_timeout_function(unsigned long int data) */ writel(1 << bit, port->completed[group]); - /* Call the async completion callback. */ - if (likely(command->async_callback)) - command->async_callback(command->async_data, - -EIO); - command->async_callback = NULL; - command->comp_func = NULL; + /* Clear the active flag for the command */ + atomic_set(&port->commands[tag].active, 0); - /* Unmap the DMA scatter list entries */ - dma_unmap_sg(&port->dd->pdev->dev, - command->sg, - command->scatter_ents, - command->direction); + func = cmd->async_callback; + if (func && + cmpxchg(&cmd->async_callback, func, 0) == func) { - /* - * Clear the allocated bit and active tag for the - * command. - */ - atomic_set(&port->commands[tag].active, 0); - release_slot(port, tag); + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&port->dd->pdev->dev, + cmd->sg, + cmd->scatter_ents, + cmd->direction); - up(&port->cmd_slot); + func(cmd->async_data, -EIO); + unaligned = cmd->unaligned; + + /* Clear the allocated bit for the command. */ + release_slot(port, tag); + + if (unaligned) + up(&port->cmd_slot_unal); + else + up(&port->cmd_slot); + } } } @@ -4213,6 +4224,7 @@ skip_create_disk: blk_queue_max_hw_sectors(dd->queue, 0xffff); blk_queue_max_segment_size(dd->queue, 0x400000); blk_queue_io_min(dd->queue, 4096); + blk_queue_bounce_limit(dd->queue, dd->pdev->dma_mask); /* * write back cache is not supported in the device. FUA depends on diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 54174cb32feb..ffb955e7ccb9 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -92,7 +92,7 @@ /* Driver name and version strings */ #define MTIP_DRV_NAME "mtip32xx" -#define MTIP_DRV_VERSION "1.3.0" +#define MTIP_DRV_VERSION "1.3.1" /* Maximum number of minor device numbers per device. */ #define MTIP_MAX_MINORS 16 diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 00a3abe103a5..27c83e45eaed 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -130,7 +130,7 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev) int i; if (!iodev->dev->of_node) - return NULL; + return ERR_PTR(-EINVAL); clk_np = of_find_node_by_name(iodev->dev->of_node, "clocks"); if (!clk_np) { diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 166e02f16c8a..cc37c342c4cb 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -764,7 +764,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, - [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, @@ -809,7 +808,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true }, [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true }, [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true }, - [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true }, [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true }, [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true }, [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true }, @@ -952,7 +950,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true }, [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true }, - [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true }, }; static struct tegra_devclk devclks[] __initdata = { diff --git a/drivers/clk/ti/clk-44xx.c b/drivers/clk/ti/clk-44xx.c index ae00218b5da3..02517a8206bd 100644 --- a/drivers/clk/ti/clk-44xx.c +++ b/drivers/clk/ti/clk-44xx.c @@ -222,7 +222,6 @@ static struct ti_dt_clk omap44xx_clks[] = { DT_CLK(NULL, "auxclk5_src_ck", "auxclk5_src_ck"), DT_CLK(NULL, "auxclk5_ck", "auxclk5_ck"), DT_CLK(NULL, "auxclkreq5_ck", "auxclkreq5_ck"), - DT_CLK("50000000.gpmc", "fck", "dummy_ck"), DT_CLK("omap_i2c.1", "ick", "dummy_ck"), DT_CLK("omap_i2c.2", "ick", "dummy_ck"), DT_CLK("omap_i2c.3", "ick", "dummy_ck"), diff --git a/drivers/clk/ti/clk-54xx.c b/drivers/clk/ti/clk-54xx.c index 0ef9f581286b..08f3d1b915b3 100644 --- a/drivers/clk/ti/clk-54xx.c +++ b/drivers/clk/ti/clk-54xx.c @@ -182,7 +182,6 @@ static struct ti_dt_clk omap54xx_clks[] = { DT_CLK(NULL, "auxclk3_src_ck", "auxclk3_src_ck"), DT_CLK(NULL, "auxclk3_ck", "auxclk3_ck"), DT_CLK(NULL, "auxclkreq3_ck", "auxclkreq3_ck"), - DT_CLK(NULL, "gpmc_ck", "dummy_ck"), DT_CLK("omap_i2c.1", "ick", "dummy_ck"), DT_CLK("omap_i2c.2", "ick", "dummy_ck"), DT_CLK("omap_i2c.3", "ick", "dummy_ck"), diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 9977653f2d63..f7e40734c819 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -262,7 +262,6 @@ static struct ti_dt_clk dra7xx_clks[] = { DT_CLK(NULL, "vip1_gclk_mux", "vip1_gclk_mux"), DT_CLK(NULL, "vip2_gclk_mux", "vip2_gclk_mux"), DT_CLK(NULL, "vip3_gclk_mux", "vip3_gclk_mux"), - DT_CLK(NULL, "gpmc_ck", "dummy_ck"), DT_CLK("omap_i2c.1", "ick", "dummy_ck"), DT_CLK("omap_i2c.2", "ick", "dummy_ck"), DT_CLK("omap_i2c.3", "ick", "dummy_ck"), diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c index b6bffbfd3be7..3a74def216a5 100644 --- a/drivers/firmware/efi/efi-stub-helper.c +++ b/drivers/firmware/efi/efi-stub-helper.c @@ -468,7 +468,7 @@ grow: chunksize = EFI_READ_CHUNK_SIZE; else chunksize = size; - status = efi_call_phys3(fh->read, + status = efi_call_phys3(files[j].handle->read, files[j].handle, &chunksize, (void *)addr); @@ -480,7 +480,7 @@ grow: size -= chunksize; } - efi_call_phys1(fh->close, files[j].handle); + efi_call_phys1(files[j].handle->close, files[j].handle); } } @@ -497,7 +497,7 @@ free_file_total: close_handles: for (k = j; k < i; k++) - efi_call_phys1(fh->close, files[k].handle); + efi_call_phys1(files[k].handle->close, files[k].handle); free_files: efi_call_phys1(sys_table_arg->boottime->free_pool, files); fail: diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index d8e398275ca8..66a492aa4f1e 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -678,6 +678,7 @@ static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix, base + LCD_SPU_SRAM_WRDAT); writel_relaxed(addr | SRAM_WRITE, base + LCD_SPU_SRAM_CTRL); + readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN); addr += 1; if ((addr & 0x00ff) == 0) addr += 0xf00; diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index f2d7bf90c9fe..2e7801af466e 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u32 current_version) case (VERSION_WIN8): return VERSION_WIN7; + case (VERSION_WIN8_1): + return VERSION_WIN8; + case (VERSION_WS2008): default: return VERSION_INVAL; @@ -77,7 +80,7 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); - if (version == VERSION_WIN8) + if (version == VERSION_WIN8_1) msg->target_vcpu = hv_context.vp_index[smp_processor_id()]; /* diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 5b1aa027c034..bbba014c9939 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -765,14 +765,17 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, if (!pdata) return -EINVAL; + st->caps = (struct at91_adc_caps *) + platform_get_device_id(pdev)->driver_data; + st->use_external = pdata->use_external_triggers; st->vref_mv = pdata->vref; st->channels_mask = pdata->channels_used; - st->num_channels = pdata->num_channels; + st->num_channels = st->caps->num_channels; st->startup_time = pdata->startup_time; st->trigger_number = pdata->trigger_number; st->trigger_list = pdata->trigger_list; - st->registers = pdata->registers; + st->registers = &st->caps->registers; return 0; } @@ -1101,7 +1104,6 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static struct at91_adc_caps at91sam9260_caps = { .calc_startup_ticks = calc_startup_ticks_9260, .num_channels = 4, @@ -1154,11 +1156,27 @@ static const struct of_device_id at91_adc_dt_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); -#endif + +static const struct platform_device_id at91_adc_ids[] = { + { + .name = "at91sam9260-adc", + .driver_data = (unsigned long)&at91sam9260_caps, + }, { + .name = "at91sam9g45-adc", + .driver_data = (unsigned long)&at91sam9g45_caps, + }, { + .name = "at91sam9x5-adc", + .driver_data = (unsigned long)&at91sam9x5_caps, + }, { + /* terminator */ + } +}; +MODULE_DEVICE_TABLE(platform, at91_adc_ids); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, .remove = at91_adc_remove, + .id_table = at91_adc_ids, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(at91_adc_dt_ids), diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c67d83bdc8f0..fe25042f056a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -165,7 +165,8 @@ static ssize_t iio_scan_el_show(struct device *dev, int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); - ret = test_bit(to_iio_dev_attr(attr)->address, + /* Ensure ret is 0 or 1. */ + ret = !!test_bit(to_iio_dev_attr(attr)->address, indio_dev->buffer->scan_mask); return sprintf(buf, "%d\n", ret); @@ -866,7 +867,8 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, if (!buffer->scan_mask) return 0; - return test_bit(bit, buffer->scan_mask); + /* Ensure return value is 0 or 1. */ + return !!test_bit(bit, buffer->scan_mask); }; EXPORT_SYMBOL_GPL(iio_scan_mask_query); diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 47a6dbac2d0c..d976e6ce60db 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -221,6 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, *val = cm32181->calibscale; return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: + *val = 0; ret = cm32181_read_als_it(cm32181, val2); return ret; } diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index a45e07492db3..39fc67e82138 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -652,7 +652,19 @@ static int cm36651_probe(struct i2c_client *client, cm36651->client = client; cm36651->ps_client = i2c_new_dummy(client->adapter, CM36651_I2C_ADDR_PS); + if (!cm36651->ps_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_disable_reg; + } + cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA); + if (!cm36651->ara_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_i2c_unregister_ps; + } + mutex_init(&cm36651->lock); indio_dev->dev.parent = &client->dev; indio_dev->channels = cm36651_channels; @@ -664,7 +676,7 @@ static int cm36651_probe(struct i2c_client *client, ret = cm36651_setup_reg(cm36651); if (ret) { dev_err(&client->dev, "%s: register setup failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler, @@ -672,7 +684,7 @@ static int cm36651_probe(struct i2c_client *client, "cm36651", indio_dev); if (ret) { dev_err(&client->dev, "%s: request irq failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = iio_device_register(indio_dev); @@ -685,6 +697,10 @@ static int cm36651_probe(struct i2c_client *client, error_free_irq: free_irq(client->irq, indio_dev); +error_i2c_unregister_ara: + i2c_unregister_device(cm36651->ara_client); +error_i2c_unregister_ps: + i2c_unregister_device(cm36651->ps_client); error_disable_reg: regulator_disable(cm36651->vled_reg); return ret; @@ -698,6 +714,8 @@ static int cm36651_remove(struct i2c_client *client) iio_device_unregister(indio_dev); regulator_disable(cm36651->vled_reg); free_irq(client->irq, indio_dev); + i2c_unregister_device(cm36651->ps_client); + i2c_unregister_device(cm36651->ara_client); return 0; } diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 0601b9daf840..c3239170d8b7 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -349,23 +349,6 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, grh, &av->ah_attr); } -int ib_update_cm_av(struct ib_cm_id *id, const u8 *smac, const u8 *alt_smac) -{ - struct cm_id_private *cm_id_priv; - - cm_id_priv = container_of(id, struct cm_id_private, id); - - if (smac != NULL) - memcpy(cm_id_priv->av.smac, smac, sizeof(cm_id_priv->av.smac)); - - if (alt_smac != NULL) - memcpy(cm_id_priv->alt_av.smac, alt_smac, - sizeof(cm_id_priv->alt_av.smac)); - - return 0; -} -EXPORT_SYMBOL(ib_update_cm_av); - static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) { struct cm_device *cm_dev; diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 199958d9ddc8..42c3058e6e9c 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1284,15 +1284,6 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) struct rdma_id_private *listen_id, *conn_id; struct rdma_cm_event event; int offset, ret; - u8 smac[ETH_ALEN]; - u8 alt_smac[ETH_ALEN]; - u8 *psmac = smac; - u8 *palt_smac = alt_smac; - int is_iboe = ((rdma_node_get_transport(cm_id->device->node_type) == - RDMA_TRANSPORT_IB) && - (rdma_port_get_link_layer(cm_id->device, - ib_event->param.req_rcvd.port) == - IB_LINK_LAYER_ETHERNET)); listen_id = cm_id->context; if (!cma_check_req_qp_type(&listen_id->id, ib_event)) @@ -1336,28 +1327,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) ret = conn_id->id.event_handler(&conn_id->id, &event); if (ret) goto err3; - - if (is_iboe) { - if (ib_event->param.req_rcvd.primary_path != NULL) - rdma_addr_find_smac_by_sgid( - &ib_event->param.req_rcvd.primary_path->sgid, - psmac, NULL); - else - psmac = NULL; - if (ib_event->param.req_rcvd.alternate_path != NULL) - rdma_addr_find_smac_by_sgid( - &ib_event->param.req_rcvd.alternate_path->sgid, - palt_smac, NULL); - else - palt_smac = NULL; - } /* * Acquire mutex to prevent user executing rdma_destroy_id() * while we're accessing the cm_id. */ mutex_lock(&lock); - if (is_iboe) - ib_update_cm_av(cm_id, psmac, palt_smac); if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD)) ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 212150c25ea0..8cc837537768 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -283,6 +283,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, (my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1)); if (ib_copy_to_udata(udata, &resp, sizeof(resp))) { ehca_err(device, "Copy to udata failed."); + cq = ERR_PTR(-EFAULT); goto create_cq_exit4; } } diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index 714293b78518..e2f9a51f4a38 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c @@ -326,7 +326,7 @@ static ssize_t ipath_diagpkt_write(struct file *fp, size_t count, loff_t *off) { u32 __iomem *piobuf; - u32 plen, clen, pbufn; + u32 plen, pbufn, maxlen_reserve; struct ipath_diag_pkt odp; struct ipath_diag_xpkt dp; u32 *tmpbuf = NULL; @@ -335,51 +335,29 @@ static ssize_t ipath_diagpkt_write(struct file *fp, u64 val; u32 l_state, lt_state; /* LinkState, LinkTrainingState */ - if (count < sizeof(odp)) { - ret = -EINVAL; - goto bail; - } if (count == sizeof(dp)) { if (copy_from_user(&dp, data, sizeof(dp))) { ret = -EFAULT; goto bail; } - } else if (copy_from_user(&odp, data, sizeof(odp))) { - ret = -EFAULT; + } else if (count == sizeof(odp)) { + if (copy_from_user(&odp, data, sizeof(odp))) { + ret = -EFAULT; + goto bail; + } + } else { + ret = -EINVAL; goto bail; } - /* - * Due to padding/alignment issues (lessened with new struct) - * the old and new structs are the same length. We need to - * disambiguate them, which we can do because odp.len has never - * been less than the total of LRH+BTH+DETH so far, while - * dp.unit (same offset) unit is unlikely to get that high. - * Similarly, dp.data, the pointer to user at the same offset - * as odp.unit, is almost certainly at least one (512byte)page - * "above" NULL. The if-block below can be omitted if compatibility - * between a new driver and older diagnostic code is unimportant. - * compatibility the other direction (new diags, old driver) is - * handled in the diagnostic code, with a warning. - */ - if (dp.unit >= 20 && dp.data < 512) { - /* very probable version mismatch. Fix it up */ - memcpy(&odp, &dp, sizeof(odp)); - /* We got a legacy dp, copy elements to dp */ - dp.unit = odp.unit; - dp.data = odp.data; - dp.len = odp.len; - dp.pbc_wd = 0; /* Indicate we need to compute PBC wd */ - } - /* send count must be an exact number of dwords */ if (dp.len & 3) { ret = -EINVAL; goto bail; } - clen = dp.len >> 2; + plen = dp.len >> 2; dd = ipath_lookup(dp.unit); if (!dd || !(dd->ipath_flags & IPATH_PRESENT) || @@ -422,16 +400,22 @@ static ssize_t ipath_diagpkt_write(struct file *fp, goto bail; } - /* need total length before first word written */ - /* +1 word is for the qword padding */ - plen = sizeof(u32) + dp.len; - - if ((plen + 4) > dd->ipath_ibmaxlen) { + /* + * need total length before first word written, plus 2 Dwords. One Dword + * is for padding so we get the full user data when not aligned on + * a word boundary. The other Dword is to make sure we have room for the + * ICRC which gets tacked on later. + */ + maxlen_reserve = 2 * sizeof(u32); + if (dp.len > dd->ipath_ibmaxlen - maxlen_reserve) { ipath_dbg("Pkt len 0x%x > ibmaxlen %x\n", - plen - 4, dd->ipath_ibmaxlen); + dp.len, dd->ipath_ibmaxlen); ret = -EINVAL; - goto bail; /* before writing pbc */ + goto bail; } + + plen = sizeof(u32) + dp.len; + tmpbuf = vmalloc(plen); if (!tmpbuf) { dev_info(&dd->pcidev->dev, "Unable to allocate tmp buffer, " @@ -473,11 +457,11 @@ static ssize_t ipath_diagpkt_write(struct file *fp, */ if (dd->ipath_flags & IPATH_PIO_FLUSH_WC) { ipath_flush_wc(); - __iowrite32_copy(piobuf + 2, tmpbuf, clen - 1); + __iowrite32_copy(piobuf + 2, tmpbuf, plen - 1); ipath_flush_wc(); - __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1); + __raw_writel(tmpbuf[plen - 1], piobuf + plen + 1); } else - __iowrite32_copy(piobuf + 2, tmpbuf, clen); + __iowrite32_copy(piobuf + 2, tmpbuf, plen); ipath_flush_wc(); diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 5b71d43bd89c..42dde06fdb91 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -695,6 +695,7 @@ static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries, if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) { mthca_free_cq(to_mdev(ibdev), cq); + err = -EFAULT; goto err_free; } diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 8308e3634767..eb624611f94b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1186,7 +1186,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); kfree(nesqp->allocated_buffer); nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n"); - return NULL; + return ERR_PTR(-EFAULT); } if (req.user_wqe_buffers) { virt_wqs = 1; diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 275f247f9fca..2023cd61b897 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -1578,7 +1578,7 @@ static int do_qib_user_sdma_queue_create(struct file *fp) struct qib_ctxtdata *rcd = fd->rcd; struct qib_devdata *dd = rcd->dd; - if (dd->flags & QIB_HAS_SEND_DMA) + if (dd->flags & QIB_HAS_SEND_DMA) { fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev, dd->unit, @@ -1586,6 +1586,7 @@ static int do_qib_user_sdma_queue_create(struct file *fp) fd->subctxt); if (!fd->pq) return -ENOMEM; + } return 0; } diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 24e802f4ea2f..76c3e177164d 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1097,14 +1097,10 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) int ret; dd = (struct qib_devdata *) ib_alloc_device(sizeof(*dd) + extra); - if (!dd) { - dd = ERR_PTR(-ENOMEM); - goto bail; - } + if (!dd) + return ERR_PTR(-ENOMEM); -#ifdef CONFIG_DEBUG_FS - qib_dbg_ibdev_init(&dd->verbs_dev); -#endif + INIT_LIST_HEAD(&dd->list); idr_preload(GFP_KERNEL); spin_lock_irqsave(&qib_devs_lock, flags); @@ -1121,11 +1117,6 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) if (ret < 0) { qib_early_err(&pdev->dev, "Could not allocate unit ID: error %d\n", -ret); -#ifdef CONFIG_DEBUG_FS - qib_dbg_ibdev_exit(&dd->verbs_dev); -#endif - ib_dealloc_device(&dd->verbs_dev.ibdev); - dd = ERR_PTR(ret); goto bail; } @@ -1139,9 +1130,15 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) qib_early_err(&pdev->dev, "Could not alloc cpulist info, cpu affinity might be wrong\n"); } - -bail: +#ifdef CONFIG_DEBUG_FS + qib_dbg_ibdev_init(&dd->verbs_dev); +#endif return dd; +bail: + if (!list_empty(&dd->list)) + list_del_init(&dd->list); + ib_dealloc_device(&dd->verbs_dev.ibdev); + return ERR_PTR(ret);; } /* diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 8ee228e9ab5a..f596b413a35b 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -436,11 +436,18 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn) { struct fast_reg_descriptor *fr_desc; struct isert_device *device = isert_conn->conn_device; - int i, ret; + struct se_session *se_sess = isert_conn->conn->sess->se_sess; + struct se_node_acl *se_nacl = se_sess->se_node_acl; + int i, ret, tag_num; + /* + * Setup the number of FRMRs based upon the number of tags + * available to session in iscsi_target_locate_portal(). + */ + tag_num = max_t(u32, ISCSIT_MIN_TAGS, se_nacl->queue_depth); + tag_num = (tag_num * 2) + ISCSIT_EXTRA_TAGS; - INIT_LIST_HEAD(&isert_conn->conn_fr_pool); isert_conn->conn_fr_pool_size = 0; - for (i = 0; i < ISCSI_DEF_XMIT_CMDS_MAX; i++) { + for (i = 0; i < tag_num; i++) { fr_desc = kzalloc(sizeof(*fr_desc), GFP_KERNEL); if (!fr_desc) { pr_err("Failed to allocate fast_reg descriptor\n"); @@ -498,6 +505,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) kref_get(&isert_conn->conn_kref); mutex_init(&isert_conn->conn_mutex); spin_lock_init(&isert_conn->conn_lock); + INIT_LIST_HEAD(&isert_conn->conn_fr_pool); cma_id->context = isert_conn; isert_conn->conn_cm_id = cma_id; @@ -569,15 +577,6 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) goto out_mr; } - if (device->use_fastreg) { - ret = isert_conn_create_fastreg_pool(isert_conn); - if (ret) { - pr_err("Conn: %p failed to create fastreg pool\n", - isert_conn); - goto out_fastreg; - } - } - ret = isert_conn_setup_qp(isert_conn, cma_id); if (ret) goto out_conn_dev; @@ -591,9 +590,6 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) return 0; out_conn_dev: - if (device->use_fastreg) - isert_conn_free_fastreg_pool(isert_conn); -out_fastreg: ib_dereg_mr(isert_conn->conn_mr); out_mr: ib_dealloc_pd(isert_conn->conn_pd); @@ -967,6 +963,15 @@ isert_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, } if (!login->login_failed) { if (login->login_complete) { + if (isert_conn->conn_device->use_fastreg) { + ret = isert_conn_create_fastreg_pool(isert_conn); + if (ret) { + pr_err("Conn: %p failed to create" + " fastreg pool\n", isert_conn); + return ret; + } + } + ret = isert_alloc_rx_descriptors(isert_conn); if (ret) return ret; @@ -1451,7 +1456,7 @@ isert_unreg_rdma(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn) } static void -isert_put_cmd(struct isert_cmd *isert_cmd) +isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err) { struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; struct isert_conn *isert_conn = isert_cmd->conn; @@ -1467,8 +1472,21 @@ isert_put_cmd(struct isert_cmd *isert_cmd) list_del_init(&cmd->i_conn_node); spin_unlock_bh(&conn->cmd_lock); - if (cmd->data_direction == DMA_TO_DEVICE) + if (cmd->data_direction == DMA_TO_DEVICE) { iscsit_stop_dataout_timer(cmd); + /* + * Check for special case during comp_err where + * WRITE_PENDING has been handed off from core, + * but requires an extra target_put_sess_cmd() + * before transport_generic_free_cmd() below. + */ + if (comp_err && + cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) { + struct se_cmd *se_cmd = &cmd->se_cmd; + + target_put_sess_cmd(se_cmd->se_sess, se_cmd); + } + } device->unreg_rdma_mem(isert_cmd, isert_conn); transport_generic_free_cmd(&cmd->se_cmd, 0); @@ -1523,7 +1541,7 @@ isert_unmap_tx_desc(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev) static void isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, - struct ib_device *ib_dev) + struct ib_device *ib_dev, bool comp_err) { if (isert_cmd->pdu_buf_dma != 0) { pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n"); @@ -1533,7 +1551,7 @@ isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, } isert_unmap_tx_desc(tx_desc, ib_dev); - isert_put_cmd(isert_cmd); + isert_put_cmd(isert_cmd, comp_err); } static void @@ -1577,14 +1595,14 @@ isert_do_control_comp(struct work_struct *work) iscsit_tmr_post_handler(cmd, cmd->conn); cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); + isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); break; case ISTATE_SEND_REJECT: pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n"); atomic_dec(&isert_conn->post_send_buf_count); cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); + isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); break; case ISTATE_SEND_LOGOUTRSP: pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); @@ -1598,7 +1616,7 @@ isert_do_control_comp(struct work_struct *work) case ISTATE_SEND_TEXTRSP: atomic_dec(&isert_conn->post_send_buf_count); cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); + isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false); break; default: pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state); @@ -1629,7 +1647,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc, atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); cmd->i_state = ISTATE_SENT_STATUS; - isert_completion_put(tx_desc, isert_cmd, ib_dev); + isert_completion_put(tx_desc, isert_cmd, ib_dev, false); } static void @@ -1710,7 +1728,7 @@ isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_de wr = &t->isert_cmd->rdma_wr; atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); - isert_completion_put(t, t->isert_cmd, ib_dev); + isert_completion_put(t, t->isert_cmd, ib_dev, true); } } @@ -1729,14 +1747,14 @@ isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn wr = &t->isert_cmd->rdma_wr; atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); - isert_completion_put(t, t->isert_cmd, ib_dev); + isert_completion_put(t, t->isert_cmd, ib_dev, true); } tx_desc->comp_llnode_batch = NULL; if (!isert_cmd) isert_unmap_tx_desc(tx_desc, ib_dev); else - isert_completion_put(tx_desc, isert_cmd, ib_dev); + isert_completion_put(tx_desc, isert_cmd, ib_dev, true); } static void diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 0e537d8d0e47..d1078ce73095 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1078,6 +1078,7 @@ static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch, static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx) { + struct ib_device *dev = ch->sport->sdev->device; struct se_cmd *cmd; struct scatterlist *sg, *sg_orig; int sg_cnt; @@ -1124,7 +1125,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, db = ioctx->rbufs; tsize = cmd->data_length; - dma_len = sg_dma_len(&sg[0]); + dma_len = ib_sg_dma_len(dev, &sg[0]); riu = ioctx->rdma_ius; /* @@ -1155,7 +1156,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, ++j; if (j < count) { sg = sg_next(sg); - dma_len = sg_dma_len(sg); + dma_len = ib_sg_dma_len( + dev, sg); } } } else { @@ -1192,8 +1194,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, tsize = cmd->data_length; riu = ioctx->rdma_ius; sg = sg_orig; - dma_len = sg_dma_len(&sg[0]); - dma_addr = sg_dma_address(&sg[0]); + dma_len = ib_sg_dma_len(dev, &sg[0]); + dma_addr = ib_sg_dma_address(dev, &sg[0]); /* this second loop is really mapped sg_addres to rdma_iu->ib_sge */ for (i = 0, j = 0; @@ -1216,8 +1218,10 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, ++j; if (j < count) { sg = sg_next(sg); - dma_len = sg_dma_len(sg); - dma_addr = sg_dma_address(sg); + dma_len = ib_sg_dma_len( + dev, sg); + dma_addr = ib_sg_dma_address( + dev, sg); } } } else { diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index b2351466b0da..32cffca14d0b 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -715,6 +715,22 @@ static int m88rs2000_get_frontend(struct dvb_frontend *fe) return 0; } +static int m88rs2000_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + if (c->symbol_rate > 3000000) + tune->min_delay_ms = 2000; + else + tune->min_delay_ms = 3000; + + tune->step_size = c->symbol_rate / 16000; + tune->max_drift = c->symbol_rate / 2000; + + return 0; +} + static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct m88rs2000_state *state = fe->demodulator_priv; @@ -746,7 +762,7 @@ static struct dvb_frontend_ops m88rs2000_ops = { .symbol_rate_tolerance = 500, /* ppm */ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | + FE_CAN_QPSK | FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO }, @@ -766,6 +782,7 @@ static struct dvb_frontend_ops m88rs2000_ops = { .set_frontend = m88rs2000_set_frontend, .get_frontend = m88rs2000_get_frontend, + .get_tune_settings = m88rs2000_get_tune_settings, }; struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config, diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index c9b2350e92c8..6e4bdb90aa92 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -8045,8 +8045,8 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; } /* switch() */ - /* initialize tuner */ - if (TUNER_ABSENT != dev->tuner_type) { + /* initialize tuner (don't do this when resuming) */ + if (!dev->insuspend && TUNER_ABSENT != dev->tuner_type) { int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); /* Note: radio tuner address is always filled in, diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 1c776c1186f1..1dbff1472809 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -1079,6 +1079,7 @@ static void preview_config_input_format(struct isp_prev_device *prev, */ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) { + const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK]; struct isp_device *isp = to_isp_device(prev); unsigned int sph = prev->crop.left; unsigned int eph = prev->crop.left + prev->crop.width - 1; @@ -1086,6 +1087,14 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) unsigned int elv = prev->crop.top + prev->crop.height - 1; u32 features; + if (format->code != V4L2_MBUS_FMT_Y8_1X8 && + format->code != V4L2_MBUS_FMT_Y10_1X10) { + sph -= 2; + eph += 2; + slv -= 2; + elv += 2; + } + features = (prev->params.params[0].features & active) | (prev->params.params[1].features & ~active); diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 05e9bd11a3ff..dfdfa772eb1e 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -252,7 +252,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) { struct em28xx *dev = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - int ret = 0; + int nonblock, ret = 0; if (!dev) { em28xx_err("BUG: em28xx can't find device struct." @@ -265,15 +265,15 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); + nonblock = !!(substream->f_flags & O_NONBLOCK); + if (nonblock) { + if (!mutex_trylock(&dev->lock)) + return -EAGAIN; + } else + mutex_lock(&dev->lock); + runtime->hw = snd_em28xx_hw_capture; if ((dev->alt == 0 || dev->is_audio_only) && dev->adev.users == 0) { - int nonblock = !!(substream->f_flags & O_NONBLOCK); - - if (nonblock) { - if (!mutex_trylock(&dev->lock)) - return -EAGAIN; - } else - mutex_lock(&dev->lock); if (dev->is_audio_only) /* vendor audio is on a separate interface */ dev->alt = 1; @@ -299,11 +299,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) ret = em28xx_audio_analog_set(dev); if (ret < 0) goto err; - - dev->adev.users++; - mutex_unlock(&dev->lock); } + dev->adev.users++; + mutex_unlock(&dev->lock); + /* Dynamically adjust the period size */ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a0a669e81362..1373cfa4e974 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -693,7 +693,8 @@ static void pctv_520e_init(struct em28xx *dev) static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) { struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct em28xx *dev = fe->dvb->priv; + struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv; + struct em28xx *dev = i2c_bus->dev; #ifdef CONFIG_GPIOLIB struct em28xx_dvb *dvb = dev->dvb; int ret; diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c index 2a38621cf718..41a9a892f79c 100644 --- a/drivers/media/usb/gspca/sn9c20x.c +++ b/drivers/media/usb/gspca/sn9c20x.c @@ -2359,6 +2359,7 @@ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, + {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)}, {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)}, {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)}, {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 898c208889cd..e32d6a59eaca 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1847,7 +1847,25 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) if (!enable) { uvc_uninit_video(stream, 1); - usb_set_interface(stream->dev->udev, stream->intfnum, 0); + if (stream->intf->num_altsetting > 1) { + usb_set_interface(stream->dev->udev, + stream->intfnum, 0); + } else { + /* UVC doesn't specify how to inform a bulk-based device + * when the video stream is stopped. Windows sends a + * CLEAR_FEATURE(HALT) request to the video streaming + * bulk endpoint, mimic the same behaviour. + */ + unsigned int epnum = stream->header.bEndpointAddress + & USB_ENDPOINT_NUMBER_MASK; + unsigned int dir = stream->header.bEndpointAddress + & USB_ENDPOINT_DIR_MASK; + unsigned int pipe; + + pipe = usb_sndbulkpipe(stream->dev->udev, epnum) | dir; + usb_clear_halt(stream->dev->udev, pipe); + } + uvc_queue_enable(&stream->queue, 0); uvc_video_clock_cleanup(stream); return 0; diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 8f7a6a454a4c..b63a5e584aa0 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -787,8 +787,8 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32) #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32) #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) -#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 63, struct v4l2_subdev_edid32) -#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 64, struct v4l2_subdev_edid32) +#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 40, struct v4l2_subdev_edid32) +#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 41, struct v4l2_subdev_edid32) #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index f7902fe8a526..a2e257970fec 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -26,6 +26,10 @@ #include #include +MODULE_AUTHOR("Hans Verkuil"); +MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); +MODULE_LICENSE("GPL"); + const struct v4l2_dv_timings v4l2_dv_timings_presets[] = { V4L2_DV_BT_CEA_640X480P59_94, V4L2_DV_BT_CEA_720X480I59_94, diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index 7dca1e640970..841717a2842c 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client, ret = pm800_pages_init(chip); if (ret) { dev_err(&client->dev, "pm800_pages_init failed!\n"); - goto err_page_init; + goto err_device_init; } ret = device_800_init(chip, pdata); @@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client, err_device_init: pm800_pages_exit(chip); -err_page_init: err_subchip_alloc: pm80x_deinit(); out_init: diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index c9b1f6422941..bcfc9e85b4a0 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client, chip->companion_addr = pdata->companion_addr; chip->companion = i2c_new_dummy(chip->client->adapter, chip->companion_addr); + if (!chip->companion) { + dev_err(&client->dev, + "Failed to allocate I2C companion device\n"); + return -ENODEV; + } chip->regmap_companion = regmap_init_i2c(chip->companion, &pm860x_regmap_config); if (IS_ERR(chip->regmap_companion)) { ret = PTR_ERR(chip->regmap_companion); dev_err(&chip->companion->dev, "Failed to allocate register map: %d\n", ret); + i2c_unregister_device(chip->companion); return ret; } i2c_set_clientdata(chip->companion, chip); diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index d3e23278d299..38917a822335 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld) return -ENODEV; } - /* Release hardware mutex if aquired */ - if (!(index_reg & KEMPLD_MUTEX_KEY)) + /* Release hardware mutex if acquired */ + if (!(index_reg & KEMPLD_MUTEX_KEY)) { iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); + /* PXT and COMe-cPC2 boards may require a second release */ + iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); + } mutex_unlock(&pld->lock); diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f53d5823a3f7..e5fce765accb 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -121,6 +121,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c, dev_info(max77686->dev, "device found\n"); max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); + if (!max77686->rtc) { + dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n"); + return -ENODEV; + } i2c_set_clientdata(max77686->rtc, max77686); max77686_irq_init(max77686); diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index e0859987ab6b..c5535f018466 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -148,9 +148,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c, dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); + if (!max77693->muic) { + dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n"); + return -ENODEV; + } i2c_set_clientdata(max77693->muic, max77693); max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); + if (!max77693->haptic) { + dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n"); + ret = -ENODEV; + goto err_i2c_haptic; + } i2c_set_clientdata(max77693->haptic, max77693); /* @@ -184,8 +193,9 @@ err_mfd: max77693_irq_exit(max77693); err_irq: err_regmap_muic: - i2c_unregister_device(max77693->muic); i2c_unregister_device(max77693->haptic); +err_i2c_haptic: + i2c_unregister_device(max77693->muic); return ret; } diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 176aa26fc787..a83eed5c15ca 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client, mutex_init(&chip->io_lock); chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); + if (!chip->rtc) { + dev_err(chip->dev, "Failed to allocate I2C device for RTC\n"); + return -ENODEV; + } i2c_set_clientdata(chip->rtc, chip); chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); + if (!chip->adc) { + dev_err(chip->dev, "Failed to allocate I2C device for ADC\n"); + i2c_unregister_device(chip->rtc); + return -ENODEV; + } i2c_set_clientdata(chip->adc, chip); device_init_wakeup(&client->dev, 1); diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 5adede0fb04c..8cf7a015cfe5 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -208,10 +208,26 @@ static int max8997_i2c_probe(struct i2c_client *i2c, mutex_init(&max8997->iolock); max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); + if (!max8997->rtc) { + dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n"); + return -ENODEV; + } i2c_set_clientdata(max8997->rtc, max8997); + max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); + if (!max8997->haptic) { + dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n"); + ret = -ENODEV; + goto err_i2c_haptic; + } i2c_set_clientdata(max8997->haptic, max8997); + max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); + if (!max8997->muic) { + dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n"); + ret = -ENODEV; + goto err_i2c_muic; + } i2c_set_clientdata(max8997->muic, max8997); pm_runtime_set_active(max8997->dev); @@ -239,7 +255,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c, err_mfd: mfd_remove_devices(max8997->dev); i2c_unregister_device(max8997->muic); +err_i2c_muic: i2c_unregister_device(max8997->haptic); +err_i2c_haptic: i2c_unregister_device(max8997->rtc); return ret; } diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 5d5e186b5d8b..592db06098e6 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -215,6 +215,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c, mutex_init(&max8998->iolock); max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); + if (!max8998->rtc) { + dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n"); + return -ENODEV; + } i2c_set_clientdata(max8998->rtc, max8998); max8998_irq_init(max8998); diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 714e2135210e..a76cd85a2868 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -252,6 +252,10 @@ static int sec_pmic_probe(struct i2c_client *i2c, } sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); + if (!sec_pmic->rtc) { + dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n"); + return -ENODEV; + } i2c_set_clientdata(sec_pmic->rtc, sec_pmic); sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1f142d76cbbc..d6573318977f 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -255,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq, ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq, IRQF_ONESHOT, pdata->irq_base, tps6591x_irqs_chip, &tps65910->irq_data); - if (ret < 0) + if (ret < 0) { dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret); + tps65910->chip_irq = 0; + } return ret; } diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index ed718328eff1..e87140bef667 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -282,11 +282,11 @@ static struct reg_default twl4030_49_defaults[] = { static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg) { switch (reg) { - case 0: - case 3: - case 40: - case 41: - case 42: + case 0x00: + case 0x03: + case 0x40: + case 0x41: + case 0x42: return false; default: return true; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 89a557972d1b..5a9bfa71df86 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -74,23 +74,69 @@ int mei_me_cl_by_id(struct mei_device *dev, u8 client_id) /** - * mei_io_list_flush - removes list entry belonging to cl. + * mei_cl_cmp_id - tells if the clients are the same * - * @list: An instance of our list structure - * @cl: host client + * @cl1: host client 1 + * @cl2: host client 2 + * + * returns true - if the clients has same host and me ids + * false - otherwise + */ +static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, + const struct mei_cl *cl2) +{ + return cl1 && cl2 && + (cl1->host_client_id == cl2->host_client_id) && + (cl1->me_client_id == cl2->me_client_id); +} + +/** + * mei_io_list_flush - removes cbs belonging to cl. + * + * @list: an instance of our list structure + * @cl: host client, can be NULL for flushing the whole list + * @free: whether to free the cbs */ -void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) +static void __mei_io_list_flush(struct mei_cl_cb *list, + struct mei_cl *cl, bool free) { struct mei_cl_cb *cb; struct mei_cl_cb *next; + /* enable removing everything if no cl is specified */ list_for_each_entry_safe(cb, next, &list->list, list) { - if (cb->cl && mei_cl_cmp_id(cl, cb->cl)) + if (!cl || (cb->cl && mei_cl_cmp_id(cl, cb->cl))) { list_del(&cb->list); + if (free) + mei_io_cb_free(cb); + } } } /** + * mei_io_list_flush - removes list entry belonging to cl. + * + * @list: An instance of our list structure + * @cl: host client + */ +static inline void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) +{ + __mei_io_list_flush(list, cl, false); +} + + +/** + * mei_io_list_free - removes cb belonging to cl and free them + * + * @list: An instance of our list structure + * @cl: host client + */ +static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl) +{ + __mei_io_list_flush(list, cl, true); +} + +/** * mei_io_cb_free - free mei_cb_private related memory * * @cb: mei callback struct @@ -196,8 +242,8 @@ int mei_cl_flush_queues(struct mei_cl *cl) cl_dbg(dev, cl, "remove list entry belonging to cl\n"); mei_io_list_flush(&cl->dev->read_list, cl); - mei_io_list_flush(&cl->dev->write_list, cl); - mei_io_list_flush(&cl->dev->write_waiting_list, cl); + mei_io_list_free(&cl->dev->write_list, cl); + mei_io_list_free(&cl->dev->write_waiting_list, cl); mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); mei_io_list_flush(&cl->dev->amthif_cmd_list, cl); @@ -942,20 +988,8 @@ void mei_cl_all_wakeup(struct mei_device *dev) */ void mei_cl_all_write_clear(struct mei_device *dev) { - struct mei_cl_cb *cb, *next; - struct list_head *list; - - list = &dev->write_list.list; - list_for_each_entry_safe(cb, next, list, list) { - list_del(&cb->list); - mei_io_cb_free(cb); - } - - list = &dev->write_waiting_list.list; - list_for_each_entry_safe(cb, next, list, list) { - list_del(&cb->list); - mei_io_cb_free(cb); - } + mei_io_list_free(&dev->write_list, NULL); + mei_io_list_free(&dev->write_waiting_list, NULL); } diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index c8396e582f1c..0820e121d137 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -45,8 +45,6 @@ static inline void mei_io_list_init(struct mei_cl_cb *list) { INIT_LIST_HEAD(&list->list); } -void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl); - /* * MEI Host Client Functions */ @@ -61,22 +59,6 @@ int mei_cl_unlink(struct mei_cl *cl); int mei_cl_flush_queues(struct mei_cl *cl); struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl); -/** - * mei_cl_cmp_id - tells if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns true - if ids are the same and not NULL - */ -static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, - const struct mei_cl *cl2) -{ - return cl1 && cl2 && - (cl1->host_client_id == cl2->host_client_id) && - (cl1->me_client_id == cl2->me_client_id); -} - int mei_cl_flow_ctrl_creds(struct mei_cl *cl); diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 66f411a6e8ea..cabc04383685 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -115,6 +115,11 @@ #define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */ #define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */ + +/* Host Firmware Status Registers in PCI Config Space */ +#define PCI_CFG_HFS_1 0x40 +#define PCI_CFG_HFS_2 0x48 + /* * MEI HW Section */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index f0fbb5179f80..d36286874946 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -428,8 +428,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) cl->status = 0; list_del(&cb->list); - if (MEI_WRITING == cl->writing_state && - cb->fop_type == MEI_FOP_WRITE && + if (cb->fop_type == MEI_FOP_WRITE && cl != &dev->iamthif_cl) { cl_dbg(dev, cl, "MEI WRITE COMPLETE\n"); cl->writing_state = MEI_WRITE_COMPLETE; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 5424f8ff3f7f..cfe1789923a3 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -653,8 +653,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) goto out; } - if (MEI_WRITE_COMPLETE == cl->writing_state) - mask |= (POLLIN | POLLRDNORM); + mask |= (POLLIN | POLLRDNORM); out: mutex_unlock(&dev->device_lock); diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index ddadd08956f4..bf4bb74c39ff 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -100,15 +100,31 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { u32 reg; - if (ent->device == MEI_DEV_ID_PBG_1) { - pci_read_config_dword(pdev, 0x48, ®); - /* make sure that bit 9 is up and bit 10 is down */ - if ((reg & 0x600) == 0x200) { - dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); - return false; - } + /* Cougar Point || Patsburg */ + if (ent->device == MEI_DEV_ID_CPT_1 || + ent->device == MEI_DEV_ID_PBG_1) { + pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®); + /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */ + if ((reg & 0x600) == 0x200) + goto no_mei; } + + /* Lynx Point */ + if (ent->device == MEI_DEV_ID_LPT_H || + ent->device == MEI_DEV_ID_LPT_W || + ent->device == MEI_DEV_ID_LPT_HR) { + /* Read ME FW Status check for SPS Firmware */ + pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); + /* if bits [19:16] = 15, running SPS Firmware */ + if ((reg & 0xf0000) == 0xf0000) + goto no_mei; + } + return true; + +no_mei: + dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); + return false; } /** * mei_probe - Device Initialization Routine diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index e8663a8c3406..ee082509b0ba 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -424,20 +424,40 @@ static void imx6_pcie_reset_phy(struct pcie_port *pp) static int imx6_pcie_link_up(struct pcie_port *pp) { - u32 rc, ltssm, rx_valid; + u32 rc, debug_r0, rx_valid; + int count = 5; /* - * Test if the PHY reports that the link is up and also that - * the link training finished. It might happen that the PHY - * reports the link is already up, but the link training bit - * is still set, so make sure to check the training is done - * as well here. + * Test if the PHY reports that the link is up and also that the LTSSM + * training finished. There are three possible states of the link when + * this code is called: + * 1) The link is DOWN (unlikely) + * The link didn't come up yet for some reason. This usually means + * we have a real problem somewhere. Reset the PHY and exit. This + * state calls for inspection of the DEBUG registers. + * 2) The link is UP, but still in LTSSM training + * Wait for the training to finish, which should take a very short + * time. If the training does not finish, we have a problem and we + * need to inspect the DEBUG registers. If the training does finish, + * the link is up and operating correctly. + * 3) The link is UP and no longer in LTSSM training + * The link is up and operating correctly. */ - rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); - if ((rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP) && - !(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) - return 1; - + while (1) { + rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1); + if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_UP)) + break; + if (!(rc & PCIE_PHY_DEBUG_R1_XMLH_LINK_IN_TRAINING)) + return 1; + if (!count--) + break; + dev_dbg(pp->dev, "Link is up, but still in training\n"); + /* + * Wait a little bit, then re-check if the link finished + * the training. + */ + usleep_range(1000, 2000); + } /* * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). @@ -446,15 +466,16 @@ static int imx6_pcie_link_up(struct pcie_port *pp) * to gen2 is stuck */ pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); - ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; + debug_r0 = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0); if (rx_valid & 0x01) return 0; - if (ltssm != 0x0d) + if ((debug_r0 & 0x3f) != 0x0d) return 0; dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); + dev_dbg(pp->dev, "debug_r0=%08x debug_r1=%08x\n", debug_r0, rc); imx6_pcie_reset_phy(pp); diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 0e79665afd44..05e352889868 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -797,7 +797,7 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn, for (i = 0; i < nranges; i++) { u32 flags = of_read_number(range, 1); - u32 slot = of_read_number(range, 2); + u32 slot = of_read_number(range + 1, 1); u64 cpuaddr = of_read_number(range + na, pna); unsigned long rtype; diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4f6c2055f6b2..f0ea4fdfde87 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -153,11 +153,9 @@ static const struct regulator_desc arizona_ldo1 = { .vsel_reg = ARIZONA_LDO1_CONTROL_1, .vsel_mask = ARIZONA_LDO1_VSEL_MASK, - .bypass_reg = ARIZONA_LDO1_CONTROL_1, - .bypass_mask = ARIZONA_LDO1_BYPASS, .min_uV = 900000, - .uV_step = 50000, - .n_voltages = 7, + .uV_step = 25000, + .n_voltages = 13, .enable_time = 500, .owner = THIS_MODULE, @@ -203,6 +201,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) */ switch (arizona->type) { case WM5102: + case WM8997: desc = &arizona_ldo1_hc; ldo1->init_data = arizona_ldo1_dvfs; break; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index eb5d22795c47..bb86494e2b7b 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -922,7 +922,7 @@ static int __init con3215_init(void) raw3215_freelist = req; } - cdev = ccw_device_probe_console(); + cdev = ccw_device_probe_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 699fd3e363df..bb6b0df50b33 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -576,7 +576,6 @@ static struct console con3270 = { static int __init con3270_init(void) { - struct ccw_device *cdev; struct raw3270 *rp; void *cbuf; int i; @@ -591,10 +590,7 @@ con3270_init(void) cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } - cdev = ccw_device_probe_console(); - if (IS_ERR(cdev)) - return -ENODEV; - rp = raw3270_setup_console(cdev); + rp = raw3270_setup_console(); if (IS_ERR(rp)) return PTR_ERR(rp); diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 2cdec21e8924..de2c0483949f 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -776,16 +776,24 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) } #ifdef CONFIG_TN3270_CONSOLE +/* Tentative definition - see below for actual definition. */ +static struct ccw_driver raw3270_ccw_driver; + /* * Setup 3270 device configured as console. */ -struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) +struct raw3270 __init *raw3270_setup_console(void) { + struct ccw_device *cdev; unsigned long flags; struct raw3270 *rp; char *ascebc; int rc; + cdev = ccw_device_probe_console(&raw3270_ccw_driver); + if (IS_ERR(cdev)) + return ERR_CAST(cdev); + rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); ascebc = kzalloc(256, GFP_KERNEL); rc = raw3270_setup_device(cdev, rp, ascebc); diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h index 7b73ff8c1bd7..359276a88396 100644 --- a/drivers/s390/char/raw3270.h +++ b/drivers/s390/char/raw3270.h @@ -190,7 +190,7 @@ raw3270_put_view(struct raw3270_view *view) wake_up(&raw3270_wait_queue); } -struct raw3270 *raw3270_setup_console(struct ccw_device *cdev); +struct raw3270 *raw3270_setup_console(void); void raw3270_wait_cons_dev(struct raw3270 *); /* Notifier for device addition/removal */ diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e9d783563cbb..4283dd3cdd49 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1609,7 +1609,7 @@ out_unlock: return rc; } -struct ccw_device *ccw_device_probe_console(void) +struct ccw_device *ccw_device_probe_console(struct ccw_driver *drv) { struct io_subchannel_private *io_priv; struct ccw_device *cdev; @@ -1631,6 +1631,7 @@ struct ccw_device *ccw_device_probe_console(void) kfree(io_priv); return cdev; } + cdev->drv = drv; set_io_private(sch, io_priv); ret = ccw_device_console_enable(cdev, sch); if (ret) { diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 4f6a30b8e5f9..652b41b4ddbd 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2500,16 +2500,15 @@ static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) { uint32_t cdb_phyaddr, cdb_phyaddr_hi32; - dma_addr_t dma_coherent_handle; + /* ******************************************************************** ** here we need to tell iop 331 our freeccb.HighPart ** if freeccb.HighPart is not zero ******************************************************************** */ - dma_coherent_handle = acb->dma_coherent_handle; - cdb_phyaddr = (uint32_t)(dma_coherent_handle); - cdb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); + cdb_phyaddr = lower_32_bits(acb->dma_coherent_handle); + cdb_phyaddr_hi32 = upper_32_bits(acb->dma_coherent_handle); acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32; /* *********************************************************************** diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 89a53002b585..83cb61266979 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2536,7 +2536,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->flags.enable_64bit_addressing ? "enable" : "disable"); ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp); - if (!ret) { + if (ret) { ql_log_pci(ql_log_fatal, pdev, 0x0031, "Failed to allocate memory for adapter, aborting.\n"); @@ -3478,10 +3478,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, else { qla2x00_set_reserved_loop_ids(ha); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, - "loop_id_map=%p. \n", ha->loop_id_map); + "loop_id_map=%p.\n", ha->loop_id_map); } - return 1; + return 0; fail_async_pd: dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index bf98d63d92b3..e63d27013142 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -671,12 +671,6 @@ static int dw_spi_setup(struct spi_device *spi) return 0; } -static void dw_spi_cleanup(struct spi_device *spi) -{ - struct chip_data *chip = spi_get_ctldata(spi); - kfree(chip); -} - static int init_queue(struct dw_spi *dws) { INIT_LIST_HEAD(&dws->queue); @@ -806,7 +800,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); master->bus_num = dws->bus_num; master->num_chipselect = dws->num_cs; - master->cleanup = dw_spi_cleanup; master->setup = dw_spi_setup; master->transfer = dw_spi_transfer; diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c index d4d3cc534792..8933eb7ab79b 100644 --- a/drivers/spi/spi-efm32.c +++ b/drivers/spi/spi-efm32.c @@ -487,6 +487,9 @@ static int efm32_spi_remove(struct platform_device *pdev) static const struct of_device_id efm32_spi_dt_ids[] = { { + .compatible = "energymicro,efm32-spi", + }, { + /* doesn't follow the "vendor,device" scheme, don't use */ .compatible = "efm32,spi", }, { /* sentinel */ diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 71db683098d6..b59af0303581 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -493,7 +493,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) /* pointer to the DA */ *datap++ = val & 0xff; *datap++ = (val >> 8) & 0xff; - *datap++ = chan; + *datap++ = chan << 6; devpriv->ao_readback[chan] = val; s->async->events |= COMEDI_CB_BLOCK; @@ -1040,11 +1040,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; - for (i = 0; i < cmd->chanlist_len; ++i) { - unsigned int chan = CR_CHAN(cmd->chanlist[i]); - - devpriv->ao_chanlist[i] = chan << 6; - } + for (i = 0; i < cmd->chanlist_len; ++i) + devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]); /* we count in steps of 1ms (125us) */ /* 125us mode not used yet */ diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index c9c180649c12..cec3f1628cd8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -542,7 +542,7 @@ _func_exit_; /* set the security information in the recv_frame */ static union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame) { - u8 *psta_addr = NULL, *ptr; + u8 *psta_addr, *ptr; uint auth_alg; struct recv_frame_hdr *pfhdr; struct sta_info *psta; @@ -556,7 +556,6 @@ static union recv_frame *portctrl(struct adapter *adapter, union recv_frame *pre _func_enter_; pstapriv = &adapter->stapriv; - psta = rtw_get_stainfo(pstapriv, psta_addr); auth_alg = adapter->securitypriv.dot11AuthAlgrthm; @@ -564,6 +563,7 @@ _func_enter_; pfhdr = &precv_frame->u.hdr; pattrib = &pfhdr->attrib; psta_addr = pattrib->ta; + psta = rtw_get_stainfo(pstapriv, psta_addr); prtnframe = NULL; diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 23ec684b60e1..274c359279ef 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -254,7 +254,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, struct sta_info *psta; struct sta_priv *pstapriv; union recv_frame *prtnframe; - u16 ether_type = 0; + u16 ether_type; pstapriv = &adapter->stapriv; ptr = get_recvframe_data(precv_frame); @@ -263,15 +263,14 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, psta = r8712_get_stainfo(pstapriv, psta_addr); auth_alg = adapter->securitypriv.AuthAlgrthm; if (auth_alg == 2) { + /* get ether_type */ + ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; + memcpy(ðer_type, ptr, 2); + ether_type = ntohs((unsigned short)ether_type); + if ((psta != NULL) && (psta->ieee8021x_blocked)) { /* blocked * only accept EAPOL frame */ - prtnframe = precv_frame; - /*get ether_type */ - ptr = ptr + pfhdr->attrib.hdrlen + - pfhdr->attrib.iv_len + LLC_HEADER_SIZE; - memcpy(ðer_type, ptr, 2); - ether_type = ntohs((unsigned short)ether_type); if (ether_type == 0x888e) prtnframe = precv_frame; else { diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index f0fcbf7c7d7f..868226953d5c 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -724,7 +724,7 @@ static int qt_startup(struct usb_serial *serial) goto startup_error; } - switch (serial->dev->descriptor.idProduct) { + switch (le16_to_cpu(serial->dev->descriptor.idProduct)) { case QUATECH_DSU100: case QUATECH_QSU100: case QUATECH_ESU100A: diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index b83ec378d04f..7e5469a80fe3 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -2468,6 +2468,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) { struct iscsi_cmd *cmd; struct iscsi_conn *conn_p; + bool found = false; /* * Only send a Asynchronous Message on connections whos network @@ -2476,11 +2477,12 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { iscsit_inc_conn_usage_count(conn_p); + found = true; break; } } - if (!conn_p) + if (!found) return; cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING); diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 554d4f75a75a..9e0232cca92e 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -203,10 +203,9 @@ static void iblock_free_device(struct se_device *dev) if (ib_dev->ibd_bd != NULL) blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); - if (ib_dev->ibd_bio_set != NULL) { - bioset_integrity_free(ib_dev->ibd_bio_set); + if (ib_dev->ibd_bio_set != NULL) bioset_free(ib_dev->ibd_bio_set); - } + kfree(ib_dev); } diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 66a5aba5a0d9..b920db3388cd 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -242,7 +242,7 @@ static void rd_release_prot_space(struct rd_dev *rd_dev) rd_dev->sg_prot_count = 0; } -static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length) +static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length, int block_size) { struct rd_dev_sg_table *sg_table; u32 total_sg_needed, sg_tables; @@ -252,8 +252,13 @@ static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length) if (rd_dev->rd_flags & RDF_NULLIO) return 0; - - total_sg_needed = rd_dev->rd_page_count / prot_length; + /* + * prot_length=8byte dif data + * tot sg needed = rd_page_count * (PGSZ/block_size) * + * (prot_length/block_size) + pad + * PGSZ canceled each other. + */ + total_sg_needed = (rd_dev->rd_page_count * prot_length / block_size) + 1; sg_tables = (total_sg_needed / max_sg_per_table) + 1; @@ -606,7 +611,8 @@ static int rd_init_prot(struct se_device *dev) if (!dev->dev_attrib.pi_prot_type) return 0; - return rd_build_prot_space(rd_dev, dev->prot_length); + return rd_build_prot_space(rd_dev, dev->prot_length, + dev->dev_attrib.block_size); } static void rd_free_prot(struct se_device *dev) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 77e6531fb0a1..aa064a7bb446 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -425,13 +425,14 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) goto out; } - write_sg = kzalloc(sizeof(struct scatterlist) * cmd->t_data_nents, + write_sg = kmalloc(sizeof(struct scatterlist) * cmd->t_data_nents, GFP_KERNEL); if (!write_sg) { pr_err("Unable to allocate compare_and_write sg\n"); ret = TCM_OUT_OF_RESOURCES; goto out; } + sg_init_table(write_sg, cmd->t_data_nents); /* * Setup verify and write data payloads from total NumberLBAs. */ diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index ae52c08dad09..e9fe60fa7df1 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -68,6 +68,7 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport) if (tport) { tport->tpg = tpg; + tpg->tport = tport; return tport; } diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 50b46881b6ca..94f9e3a38412 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,9 @@ static struct task_struct *hvc_task; /* Picks up late kicks after list walk but before schedule() */ static int hvc_kicked; +/* hvc_init is triggered from hvc_alloc, i.e. only when actually used */ +static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1); + static int hvc_init(void); #ifdef CONFIG_MAGIC_SYSRQ @@ -851,7 +855,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, int i; /* We wait until a driver actually comes along */ - if (!hvc_driver) { + if (atomic_inc_not_zero(&hvc_needs_init)) { int err = hvc_init(); if (err) return ERR_PTR(err); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ab90a0156828..4ebf1b2034e8 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -990,8 +990,7 @@ EXPORT_SYMBOL_GPL(usb_deregister); * it doesn't support pre_reset/post_reset/reset_resume or * because it doesn't support suspend/resume. * - * The caller must hold @intf's device's lock, but not its pm_mutex - * and not @intf->dev.sem. + * The caller must hold @intf's device's lock, but not @intf's lock. */ void usb_forced_unbind_intf(struct usb_interface *intf) { @@ -1004,16 +1003,37 @@ void usb_forced_unbind_intf(struct usb_interface *intf) intf->needs_binding = 1; } +/* + * Unbind drivers for @udev's marked interfaces. These interfaces have + * the needs_binding flag set, for example by usb_resume_interface(). + * + * The caller must hold @udev's device lock. + */ +static void unbind_marked_interfaces(struct usb_device *udev) +{ + struct usb_host_config *config; + int i; + struct usb_interface *intf; + + config = udev->actconfig; + if (config) { + for (i = 0; i < config->desc.bNumInterfaces; ++i) { + intf = config->interface[i]; + if (intf->dev.driver && intf->needs_binding) + usb_forced_unbind_intf(intf); + } + } +} + /* Delayed forced unbinding of a USB interface driver and scan * for rebinding. * - * The caller must hold @intf's device's lock, but not its pm_mutex - * and not @intf->dev.sem. + * The caller must hold @intf's device's lock, but not @intf's lock. * * Note: Rebinds will be skipped if a system sleep transition is in * progress and the PM "complete" callback hasn't occurred yet. */ -void usb_rebind_intf(struct usb_interface *intf) +static void usb_rebind_intf(struct usb_interface *intf) { int rc; @@ -1030,68 +1050,66 @@ void usb_rebind_intf(struct usb_interface *intf) } } -#ifdef CONFIG_PM - -/* Unbind drivers for @udev's interfaces that don't support suspend/resume - * There is no check for reset_resume here because it can be determined - * only during resume whether reset_resume is needed. +/* + * Rebind drivers to @udev's marked interfaces. These interfaces have + * the needs_binding flag set. * * The caller must hold @udev's device lock. */ -static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) +static void rebind_marked_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; - struct usb_driver *drv; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; - - if (intf->dev.driver) { - drv = to_usb_driver(intf->dev.driver); - if (!drv->suspend || !drv->resume) - usb_forced_unbind_intf(intf); - } + if (intf->needs_binding) + usb_rebind_intf(intf); } } } -/* Unbind drivers for @udev's interfaces that failed to support reset-resume. - * These interfaces have the needs_binding flag set by usb_resume_interface(). +/* + * Unbind all of @udev's marked interfaces and then rebind all of them. + * This ordering is necessary because some drivers claim several interfaces + * when they are first probed. * * The caller must hold @udev's device lock. */ -static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) +void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev) { - struct usb_host_config *config; - int i; - struct usb_interface *intf; - - config = udev->actconfig; - if (config) { - for (i = 0; i < config->desc.bNumInterfaces; ++i) { - intf = config->interface[i]; - if (intf->dev.driver && intf->needs_binding) - usb_forced_unbind_intf(intf); - } - } + unbind_marked_interfaces(udev); + rebind_marked_interfaces(udev); } -static void do_rebind_interfaces(struct usb_device *udev) +#ifdef CONFIG_PM + +/* Unbind drivers for @udev's interfaces that don't support suspend/resume + * There is no check for reset_resume here because it can be determined + * only during resume whether reset_resume is needed. + * + * The caller must hold @udev's device lock. + */ +static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; struct usb_interface *intf; + struct usb_driver *drv; config = udev->actconfig; if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; - if (intf->needs_binding) - usb_rebind_intf(intf); + + if (intf->dev.driver) { + drv = to_usb_driver(intf->dev.driver); + if (!drv->suspend || !drv->resume) + usb_forced_unbind_intf(intf); + } } } } @@ -1420,7 +1438,7 @@ int usb_resume_complete(struct device *dev) * whose needs_binding flag is set */ if (udev->state != USB_STATE_NOTATTACHED) - do_rebind_interfaces(udev); + rebind_marked_interfaces(udev); return 0; } @@ -1442,7 +1460,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - unbind_no_reset_resume_drivers_interfaces(udev); + unbind_marked_interfaces(udev); } /* Avoid PM error messages for devices disconnected while suspended diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index d59d99347d54..1f02e65fe305 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -75,7 +75,7 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd, PCI_SLOT(companion->devfn) != slot) continue; companion_hcd = pci_get_drvdata(companion); - if (!companion_hcd) + if (!companion_hcd || !companion_hcd->self.root_hub) continue; fn(pdev, hcd, companion, companion_hcd); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 64ea21971be2..d498d03afdbd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -5340,10 +5340,11 @@ int usb_reset_device(struct usb_device *udev) else if (cintf->condition == USB_INTERFACE_BOUND) rebind = 1; + if (rebind) + cintf->needs_binding = 1; } - if (ret == 0 && rebind) - usb_rebind_intf(cintf); } + usb_unbind_and_rebind_marked_interfaces(udev); } usb_autosuspend_device(udev); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 823857767a16..0923add72b59 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -55,7 +55,7 @@ extern int usb_match_one_id_intf(struct usb_device *dev, extern int usb_match_device(struct usb_device *dev, const struct usb_device_id *id); extern void usb_forced_unbind_intf(struct usb_interface *intf); -extern void usb_rebind_intf(struct usb_interface *intf); +extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev); extern int usb_hub_claim_port(struct usb_device *hdev, unsigned port, struct dev_state *owner); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index f8af8d44af85..546e67a2e4cd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -815,15 +815,15 @@ struct dwc3_event_depevt { * 12 - VndrDevTstRcved * @reserved15_12: Reserved, not used * @event_info: Information about this event - * @reserved31_24: Reserved, not used + * @reserved31_25: Reserved, not used */ struct dwc3_event_devt { u32 one_bit:1; u32 device_event:7; u32 type:4; u32 reserved15_12:4; - u32 event_info:8; - u32 reserved31_24:8; + u32 event_info:9; + u32 reserved31_25:7; } __packed; /** @@ -856,6 +856,19 @@ union dwc3_event { struct dwc3_event_gevt gevt; }; +/** + * struct dwc3_gadget_ep_cmd_params - representation of endpoint command + * parameters + * @param2: third parameter + * @param1: second parameter + * @param0: first parameter + */ +struct dwc3_gadget_ep_cmd_params { + u32 param2; + u32 param1; + u32 param0; +}; + /* * DWC3 Features to be used as Driver Data */ @@ -881,11 +894,31 @@ static inline void dwc3_host_exit(struct dwc3 *dwc) #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) int dwc3_gadget_init(struct dwc3 *dwc); void dwc3_gadget_exit(struct dwc3 *dwc); +int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); +int dwc3_gadget_get_link_state(struct dwc3 *dwc); +int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); +int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, + unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); +int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param); #else static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; } static inline void dwc3_gadget_exit(struct dwc3 *dwc) { } +static inline int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) +{ return 0; } +static inline int dwc3_gadget_get_link_state(struct dwc3 *dwc) +{ return 0; } +static inline int dwc3_gadget_set_link_state(struct dwc3 *dwc, + enum dwc3_link_state state) +{ return 0; } + +static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, + unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) +{ return 0; } +static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc, + int cmd, u32 param) +{ return 0; } #endif /* power management interface */ diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index febe1aa7b714..a0ee75b68a80 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -56,12 +56,6 @@ struct dwc3; /* DEPXFERCFG parameter 0 */ #define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff) -struct dwc3_gadget_ep_cmd_params { - u32 param2; - u32 param1; - u32 param0; -}; - /* -------------------------------------------------------------------------- */ #define to_dwc3_request(r) (container_of(r, struct dwc3_request, request)) @@ -85,9 +79,6 @@ static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req) void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status); -int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode); -int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state); - void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); void dwc3_ep0_out_start(struct dwc3 *dwc); @@ -95,9 +86,6 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags); int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); -int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, - unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); -int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param); /** * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 52771d4c44bc..167843de2d8a 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1827,12 +1827,12 @@ static int atmel_usba_stop(struct usb_gadget *gadget, toggle_bias(0); usba_writel(udc, CTRL, USBA_DISABLE_MASK); - udc->driver = NULL; - clk_disable_unprepare(udc->hclk); clk_disable_unprepare(udc->pclk); - DBG(DBG_GADGET, "unregistered driver `%s'\n", driver->driver.name); + DBG(DBG_GADGET, "unregistered driver `%s'\n", udc->driver->driver.name); + + udc->driver = NULL; return 0; } diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 0f8aad78b54f..460c266b8e24 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1613,7 +1613,7 @@ static struct se_wwn *usbg_make_tport( return ERR_PTR(-ENOMEM); } tport->tport_wwpn = wwpn; - snprintf(tport->tport_name, sizeof(tport->tport_name), wnn_name); + snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name); return &tport->tport_wwn; } diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 9f170c53e3d9..134f354ede62 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -300,7 +300,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) ss_opts->isoc_interval = gzero_options.isoc_interval; ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; ss_opts->isoc_mult = gzero_options.isoc_mult; - ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket; + ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; ss_opts->bulk_buflen = gzero_options.bulk_buflen; func_ss = usb_get_function(func_inst_ss); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index af28b748e87a..633dbea28f30 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -513,8 +513,31 @@ static struct platform_driver tegra_ehci_driver = { } }; +static int tegra_ehci_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + int txfifothresh; + + retval = ehci_setup(hcd); + if (retval) + return retval; + + /* + * We should really pull this value out of tegra_ehci_soc_config, but + * to avoid needing access to it, make use of the fact that Tegra20 is + * the only one so far that needs a value of 10, and Tegra20 is the + * only one which doesn't set has_hostpc. + */ + txfifothresh = ehci->has_hostpc ? 0x10 : 10; + ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning); + + return 0; +} + static const struct ehci_driver_overrides tegra_overrides __initconst = { .extra_priv_size = sizeof(struct tegra_ehci_hcd), + .reset = tegra_ehci_reset, }; static int __init ehci_tegra_init(void) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 04f986d9234f..08a5f92d6c54 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -134,6 +134,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) */ if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP) xhci->quirks |= XHCI_SPURIOUS_WAKEUP; + + xhci->quirks |= XHCI_SPURIOUS_REBOOT; } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_ASROCK_P67) { @@ -143,9 +145,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_TRUST_TX_LENGTH; } if (pdev->vendor == PCI_VENDOR_ID_RENESAS && - pdev->device == 0x0015 && - pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && - pdev->subsystem_device == 0xc0cd) + pdev->device == 0x0015) xhci->quirks |= XHCI_RESET_ON_RESUME; if (pdev->vendor == PCI_VENDOR_ID_VIA) xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -190,6 +190,10 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) struct usb_hcd *hcd; driver = (struct hc_driver *)id->driver_data; + + /* Prevent runtime suspending between USB-2 and USB-3 initialization */ + pm_runtime_get_noresume(&dev->dev); + /* Register the USB 2.0 roothub. * FIXME: USB core must know to register the USB 2.0 roothub first. * This is sort of silly, because we could just set the HCD driver flags @@ -199,7 +203,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) retval = usb_hcd_pci_probe(dev, id); if (retval) - return retval; + goto put_runtime_pm; /* USB 2.0 roothub is stored in the PCI device now. */ hcd = dev_get_drvdata(&dev->dev); @@ -228,12 +232,17 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (xhci->quirks & XHCI_LPM_SUPPORT) hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1; + /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ + pm_runtime_put_noidle(&dev->dev); + return 0; put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); dealloc_usb2_hcd: usb_hcd_pci_remove(dev); +put_runtime_pm: + pm_runtime_put_noidle(&dev->dev); return retval; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0ed64eb68e48..dff9b5ead3b3 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -550,6 +550,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, struct xhci_generic_trb *trb; struct xhci_ep_ctx *ep_ctx; dma_addr_t addr; + u64 hw_dequeue; ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, ep_index, stream_id); @@ -559,56 +560,57 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, stream_id); return; } - state->new_cycle_state = 0; - xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Finding segment containing stopped TRB."); - state->new_deq_seg = find_trb_seg(cur_td->start_seg, - dev->eps[ep_index].stopped_trb, - &state->new_cycle_state); - if (!state->new_deq_seg) { - WARN_ON(1); - return; - } /* Dig out the cycle state saved by the xHC during the stop ep cmd */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Finding endpoint context"); ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); - state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); + 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; + } + } + /* + * 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. + */ + 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; 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); + state->new_deq_ptr, &state->new_cycle_state); if (!state->new_deq_seg) { WARN_ON(1); return; } + /* 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); - /* - * If there is only one segment in a ring, find_trb_seg()'s while loop - * will not run, and it will return before it has a chance to see if it - * needs to toggle the cycle bit. It can't tell if the stalled transfer - * ended just before the link TRB on a one-segment ring, or if the TD - * wrapped around the top of the ring, because it doesn't have the TD in - * question. Look for the one-segment case where stalled TRB's address - * is greater than the new dequeue pointer address. - */ - if (ep_ring->first_seg == ep_ring->first_seg->next && - state->new_deq_ptr < dev->eps[ep_index].stopped_trb) - state->new_cycle_state ^= 0x1; + /* Don't update the ring cycle state for the producer (us). */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Cycle state = 0x%x", state->new_cycle_state); - /* Don't update the ring cycle state for the producer (us). */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "New dequeue segment = %p (virtual)", state->new_deq_seg); @@ -791,7 +793,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, if (list_empty(&ep->cancelled_td_list)) { xhci_stop_watchdog_timer_in_irq(xhci, ep); ep->stopped_td = NULL; - ep->stopped_trb = NULL; ring_doorbell_for_active_rings(xhci, slot_id, ep_index); return; } @@ -859,11 +860,9 @@ remove_finished_td: ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - /* Clear stopped_td and stopped_trb if endpoint is not halted */ - if (!(ep->ep_state & EP_HALTED)) { + /* Clear stopped_td if endpoint is not halted */ + if (!(ep->ep_state & EP_HALTED)) ep->stopped_td = NULL; - ep->stopped_trb = NULL; - } /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -1908,14 +1907,12 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; ep->ep_state |= EP_HALTED; ep->stopped_td = td; - ep->stopped_trb = event_trb; ep->stopped_stream = stream_id; xhci_queue_reset_ep(xhci, slot_id, ep_index); xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index); ep->stopped_td = NULL; - ep->stopped_trb = NULL; ep->stopped_stream = 0; xhci_ring_cmd_db(xhci); @@ -1997,7 +1994,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, * the ring dequeue pointer or take this TD off any lists yet. */ ep->stopped_td = td; - ep->stopped_trb = event_trb; return 0; } else { if (trb_comp_code == COMP_STALL) { @@ -2009,7 +2005,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, * USB class driver clear the stall later. */ ep->stopped_td = td; - ep->stopped_trb = event_trb; ep->stopped_stream = ep_ring->stream_id; } else if (xhci_requires_manual_halt_cleanup(xhci, ep_ctx, trb_comp_code)) { @@ -2626,7 +2621,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, * successful event after a short transfer. * Ignore it. */ - if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && + if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && ep_ring->last_td_was_short) { ep_ring->last_td_was_short = false; ret = 0; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 924a6ccdb622..cca289667cf6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -404,16 +404,16 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) #else -static int xhci_try_enable_msi(struct usb_hcd *hcd) +static inline int xhci_try_enable_msi(struct usb_hcd *hcd) { return 0; } -static void xhci_cleanup_msix(struct xhci_hcd *xhci) +static inline void xhci_cleanup_msix(struct xhci_hcd *xhci) { } -static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) +static inline void xhci_msix_sync_irqs(struct xhci_hcd *xhci) { } @@ -2933,7 +2933,6 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, xhci_ring_cmd_db(xhci); } virt_ep->stopped_td = NULL; - virt_ep->stopped_trb = NULL; virt_ep->stopped_stream = 0; spin_unlock_irqrestore(&xhci->lock, flags); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 58ed9d088e63..8faef64371c6 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -864,8 +864,6 @@ struct xhci_virt_ep { #define EP_GETTING_NO_STREAMS (1 << 5) /* ---- Related to URB cancellation ---- */ struct list_head cancelled_td_list; - /* The TRB that was last reported in a stopped endpoint ring */ - union xhci_trb *stopped_trb; struct xhci_td *stopped_td; unsigned int stopped_stream; /* Watchdog timer for stop endpoint command to cancel URBs */ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 239ad0b1ceb6..07576907e2c6 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -438,7 +438,6 @@ void musb_hnp_stop(struct musb *musb) static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl) { - struct usb_otg *otg = musb->xceiv->otg; irqreturn_t handled = IRQ_NONE; dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, @@ -656,7 +655,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_B_PERIPHERAL: musb_g_suspend(musb); - musb->is_active = otg->gadget->b_hnp_enable; + musb->is_active = musb->g.b_hnp_enable; if (musb->is_active) { musb->xceiv->state = OTG_STATE_B_WAIT_ACON; dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); @@ -672,7 +671,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, break; case OTG_STATE_A_HOST: musb->xceiv->state = OTG_STATE_A_SUSPEND; - musb->is_active = otg->host->b_hnp_enable; + musb->is_active = musb->hcd->self.b_hnp_enable; break; case OTG_STATE_B_HOST: /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 8aa59a2c5eb2..8e90d327e52b 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -416,6 +416,7 @@ static int omap2430_musb_init(struct musb *musb) omap_musb_set_mailbox(glue); phy_init(musb->phy); + phy_power_on(musb->phy); pm_runtime_put_noidle(musb->controller); return 0; @@ -478,6 +479,7 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); + phy_power_off(musb->phy); phy_exit(musb->phy); return 0; diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index d75196ad5f2f..35b6083b7999 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "am35x-phy-control.h" struct am335x_control_usb { @@ -86,6 +87,14 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) } writel(val, usb_ctrl->phy_reg + reg); + + /* + * Give the PHY ~1ms to complete the power up operation. + * Tests have shown unstable behaviour if other USB PHY related + * registers are written too shortly after such a transition. + */ + if (on) + mdelay(1); } static const struct phy_control ctrl_am335x = { diff --git a/drivers/usb/phy/phy-ulpi.c b/drivers/usb/phy/phy-ulpi.c index 217339dd7a90..17ea3f271bd8 100644 --- a/drivers/usb/phy/phy-ulpi.c +++ b/drivers/usb/phy/phy-ulpi.c @@ -47,6 +47,8 @@ struct ulpi_info { static struct ulpi_info ulpi_ids[] = { ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), + ULPI_INFO(ULPI_ID(0x0424, 0x0007), "SMSC USB3320"), + ULPI_INFO(ULPI_ID(0x0451, 0x1507), "TI TUSB1210"), }; static int ulpi_set_otg_flags(struct usb_phy *phy) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 2e22fc22c382..b3d5a35c0d4b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -83,6 +83,9 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index c38b8c00c06f..42bc082896ac 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -121,8 +121,11 @@ #define SUPERIAL_VENDOR_ID 0x5372 #define SUPERIAL_PRODUCT_ID 0x2303 -/* Hewlett-Packard LD220-HP POS Pole Display */ +/* Hewlett-Packard POS Pole Displays */ #define HP_VENDOR_ID 0x03f0 +#define HP_LD960_PRODUCT_ID 0x0b39 +#define HP_LCM220_PRODUCT_ID 0x3139 +#define HP_LCM960_PRODUCT_ID 0x3239 #define HP_LD220_PRODUCT_ID 0x3524 /* Cressi Edy (diving computer) PC interface */ diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index cd961622f9c1..b74e5f5ddac8 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -1298,6 +1298,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) goto unregister_irqs; } + ret = atmel_lcdfb_set_par(info); + if (ret < 0) { + dev_err(dev, "set par failed: %d\n", ret); + goto unregister_irqs; + } + dev_set_drvdata(dev, info); /* diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index 40788c925d1c..73705aff53cb 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c @@ -54,28 +54,29 @@ static void w1_send_slave(struct w1_master *dev, u64 rn) struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1); struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1); int avail; + u64 *data; /* update kernel slave list */ w1_slave_found(dev, rn); avail = dev->priv_size - cmd->len; - if (avail > 8) { - u64 *data = (void *)(cmd + 1) + cmd->len; + if (avail < 8) { + msg->ack++; + cn_netlink_send(msg, 0, GFP_KERNEL); - *data = rn; - cmd->len += 8; - hdr->len += 8; - msg->len += 8; - return; + msg->len = sizeof(struct w1_netlink_msg) + + sizeof(struct w1_netlink_cmd); + hdr->len = sizeof(struct w1_netlink_cmd); + cmd->len = 0; } - msg->ack++; - cn_netlink_send(msg, 0, GFP_KERNEL); + data = (void *)(cmd + 1) + cmd->len; - msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd); - hdr->len = sizeof(struct w1_netlink_cmd); - cmd->len = 0; + *data = rn; + cmd->len += 8; + hdr->len += 8; + msg->len += 8; } static int w1_process_search_command(struct w1_master *dev, struct cn_msg *msg, diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d3a534fdc5ff..3a603a8d9f96 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2462,23 +2462,6 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize) up_write(&EXT4_I(inode)->i_data_sem); } -/* - * Update i_disksize after writeback has been started. Races with truncate - * are avoided by checking i_size under i_data_sem. - */ -static inline void ext4_wb_update_i_disksize(struct inode *inode, loff_t newsize) -{ - loff_t i_size; - - down_write(&EXT4_I(inode)->i_data_sem); - i_size = i_size_read(inode); - if (newsize > i_size) - newsize = i_size; - if (newsize > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = newsize; - up_write(&EXT4_I(inode)->i_data_sem); -} - struct ext4_group_info { unsigned long bb_state; struct rb_root bb_free_root; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 1a5073959f32..2a8b2e15dcc4 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -82,7 +82,7 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, size_t count = iov_length(iov, nr_segs); loff_t final_size = pos + count; - if (pos >= inode->i_size) + if (pos >= i_size_read(inode)) return 0; if ((pos & blockmask) || (final_size & blockmask)) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 24bfd7ff3049..4e8903d0432e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -515,6 +515,10 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, "logical block %lu\n", inode->i_ino, flags, map->m_len, (unsigned long) map->m_lblk); + /* We can handle the block number less than EXT_MAX_BLOCKS */ + if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS)) + return -EIO; + /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { ext4_es_lru_add(inode); @@ -2232,13 +2236,23 @@ static int mpage_map_and_submit_extent(handle_t *handle, return err; } while (map->m_len); - /* Update on-disk size after IO is submitted */ + /* + * Update on-disk size after IO is submitted. Races with + * truncate are avoided by checking i_size under i_data_sem. + */ disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT; if (disksize > EXT4_I(inode)->i_disksize) { int err2; - - ext4_wb_update_i_disksize(inode, disksize); + loff_t i_size; + + down_write(&EXT4_I(inode)->i_data_sem); + i_size = i_size_read(inode); + if (disksize > i_size) + disksize = i_size; + if (disksize > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = disksize; err2 = ext4_mark_inode_dirty(handle, inode); + up_write(&EXT4_I(inode)->i_data_sem); if (err2) ext4_error(inode->i_sb, "Failed to mark inode %lu dirty", diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index ab95508e3d40..c18d95b50540 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -308,13 +308,14 @@ static void ext4_end_bio(struct bio *bio, int error) if (error) { struct inode *inode = io_end->inode; - ext4_warning(inode->i_sb, "I/O error writing to inode %lu " + ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu " "(offset %llu size %ld starting block %llu)", - inode->i_ino, + error, inode->i_ino, (unsigned long long) io_end->offset, (long) io_end->size, (unsigned long long) bi_sector >> (inode->i_blkbits - 9)); + mapping_set_error(inode->i_mapping, error); } if (io_end->flag & EXT4_IO_END_UNWRITTEN) { diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index e175e94116ac..55e611c1513c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -517,8 +517,8 @@ static void ext4_xattr_update_super_block(handle_t *handle, } /* - * Release the xattr block BH: If the reference count is > 1, decrement - * it; otherwise free the block. + * Release the xattr block BH: If the reference count is > 1, decrement it; + * otherwise free the block. */ static void ext4_xattr_release_block(handle_t *handle, struct inode *inode, @@ -538,16 +538,31 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, if (ce) mb_cache_entry_free(ce); get_bh(bh); + unlock_buffer(bh); ext4_free_blocks(handle, inode, bh, 0, 1, EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); - unlock_buffer(bh); } else { le32_add_cpu(&BHDR(bh)->h_refcount, -1); if (ce) mb_cache_entry_release(ce); + /* + * Beware of this ugliness: Releasing of xattr block references + * from different inodes can race and so we have to protect + * from a race where someone else frees the block (and releases + * its journal_head) before we are done dirtying the buffer. In + * nojournal mode this race is harmless and we actually cannot + * call ext4_handle_dirty_xattr_block() with locked buffer as + * that function can call sync_dirty_buffer() so for that case + * we handle the dirtying after unlocking the buffer. + */ + if (ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); unlock_buffer(bh); - error = ext4_handle_dirty_xattr_block(handle, inode, bh); + if (!ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); if (IS_SYNC(inode)) ext4_handle_sync(handle); dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1)); diff --git a/fs/namespace.c b/fs/namespace.c index 2ffc5a2905d4..65233a5f390a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -885,7 +885,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, goto out_free; } - mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; + mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); /* Don't allow unprivileged users to change mount flags */ if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; @@ -1661,9 +1661,9 @@ static int attach_recursive_mnt(struct mount *source_mnt, if (err) goto out; err = propagate_mnt(dest_mnt, dest_mp, source_mnt, &tree_list); + lock_mount_hash(); if (err) goto out_cleanup_ids; - lock_mount_hash(); for (p = source_mnt; p; p = next_mnt(p, source_mnt)) set_mnt_shared(p); } else { @@ -1690,6 +1690,11 @@ static int attach_recursive_mnt(struct mount *source_mnt, return 0; out_cleanup_ids: + while (!hlist_empty(&tree_list)) { + child = hlist_entry(tree_list.first, struct mount, mnt_hash); + umount_tree(child, 0); + } + unlock_mount_hash(); cleanup_group_ids(source_mnt, NULL); out: return err; @@ -2044,7 +2049,7 @@ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags) struct mount *parent; int err; - mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | MNT_DOOMED | MNT_SYNC_UMOUNT); + mnt_flags &= ~MNT_INTERNAL_FLAGS; mp = lock_mount(path); if (IS_ERR(mp)) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 450bfedbe2f4..d5d06e868841 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1068,6 +1068,7 @@ static void nfs4_opendata_free(struct kref *kref) dput(p->dentry); nfs_sb_deactive(sb); nfs_fattr_free_names(&p->f_attr); + kfree(p->f_attr.mdsthreshold); kfree(p); } @@ -2244,10 +2245,12 @@ static int _nfs4_do_open(struct inode *dir, } } - if (ctx_th && server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { - opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); - if (!opendata->f_attr.mdsthreshold) - goto err_free_label; + if (server->attr_bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD) { + if (!opendata->f_attr.mdsthreshold) { + opendata->f_attr.mdsthreshold = pnfs_mdsthreshold_alloc(); + if (!opendata->f_attr.mdsthreshold) + goto err_free_label; + } opendata->o_arg.open_bitmap = &nfs4_pnfs_open_bitmap[0]; } if (dentry->d_inode != NULL) @@ -2275,11 +2278,10 @@ static int _nfs4_do_open(struct inode *dir, if (opendata->file_created) *opened |= FILE_CREATED; - if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) + if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) { *ctx_th = opendata->f_attr.mdsthreshold; - else - kfree(opendata->f_attr.mdsthreshold); - opendata->f_attr.mdsthreshold = NULL; + opendata->f_attr.mdsthreshold = NULL; + } nfs4_label_free(olabel); @@ -2289,7 +2291,6 @@ static int _nfs4_do_open(struct inode *dir, err_free_label: nfs4_label_free(olabel); err_opendata_put: - kfree(opendata->f_attr.mdsthreshold); nfs4_opendata_put(opendata); err_put_state_owner: nfs4_put_state_owner(sp); diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 7f05cd140de3..3eaa6e30a2dc 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -637,9 +637,11 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) { + int maxtime = max_cb_time(clp->net); struct rpc_timeout timeparms = { - .to_initval = max_cb_time(clp->net), + .to_initval = maxtime, .to_retries = 0, + .to_maxval = maxtime, }; struct rpc_create_args args = { .net = clp->net, diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 82189b208af3..9a914e892bb1 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1359,6 +1359,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, /* If op is non-idempotent */ if (opdesc->op_flags & OP_MODIFIES_SOMETHING) { plen = opdesc->op_rsize_bop(rqstp, op); + /* + * If there's still another operation, make sure + * we'll have space to at least encode an error: + */ + if (resp->opcnt < args->opcnt) + plen += COMPOUND_ERR_SLACK_SPACE; op->status = nfsd4_check_resp_size(resp, plen); } @@ -1523,7 +1529,8 @@ static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *o static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) { - return (op_encode_hdr_size + 2 + 1024) * sizeof(__be32); + return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) * + sizeof(__be32); } static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index d5d070fbeb35..7415eac36501 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5062,7 +5062,6 @@ nfs4_state_destroy_net(struct net *net) int i; struct nfs4_client *clp = NULL; struct nfsd_net *nn = net_generic(net, nfsd_net_id); - struct rb_node *node, *tmp; for (i = 0; i < CLIENT_HASH_SIZE; i++) { while (!list_empty(&nn->conf_id_hashtbl[i])) { @@ -5071,13 +5070,11 @@ nfs4_state_destroy_net(struct net *net) } } - node = rb_first(&nn->unconf_name_tree); - while (node != NULL) { - tmp = node; - node = rb_next(tmp); - clp = rb_entry(tmp, struct nfs4_client, cl_namenode); - rb_erase(tmp, &nn->unconf_name_tree); - destroy_client(clp); + for (i = 0; i < CLIENT_HASH_SIZE; i++) { + while (!list_empty(&nn->unconf_id_hashtbl[i])) { + clp = list_entry(nn->unconf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); + destroy_client(clp); + } } kfree(nn->sessionid_hashtbl); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 63f2395c57ed..16e8fa71eb84 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2483,6 +2483,8 @@ out_acl: goto out; } if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) { + if ((buflen -= 16) < 0) + goto out_resource; WRITE32(3); WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0); WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1); @@ -2499,8 +2501,10 @@ out: security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); - if (tempfh) + if (tempfh) { fh_put(tempfh); + kfree(tempfh); + } return status; out_nfserr: status = nfserrno(err); @@ -3471,6 +3475,9 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_test_stateid_id *stateid, *next; __be32 *p; + if (nfserr) + return nfserr; + RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids)); *p++ = htonl(test_stateid->ts_num_ids); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 7f555179bf81..f34d9de802ab 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -699,6 +699,11 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net) if (err != 0 || fd < 0) return -EINVAL; + if (svc_alien_sock(net, fd)) { + printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__); + return -EINVAL; + } + err = nfsd_create_serv(net); if (err != 0) return err; diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 30f34ab02137..479eb681c27c 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -282,7 +282,7 @@ void nfsd_lockd_shutdown(void); * reason. */ #define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ -#define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ +#define COMPOUND_ERR_SLACK_SPACE 16 /* OP_SETATTR */ #define NFSD_LAUNDROMAT_MINTIMEOUT 1 /* seconds */ diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index b17d93214d01..9c769a47ac5a 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -152,7 +152,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, type = (stat->mode & S_IFMT); *p++ = htonl(nfs_ftypes[type >> 12]); - *p++ = htonl((u32) (stat->mode & S_IALLUGO)); + *p++ = htonl((u32) stat->mode); *p++ = htonl((u32) stat->nlink); *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6d7be3f80356..eea5ad188984 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -404,6 +404,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, umode_t ftype = 0; __be32 err; int host_err; + bool get_write_count; int size_change = 0; if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) @@ -411,10 +412,18 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, if (iap->ia_valid & ATTR_SIZE) ftype = S_IFREG; + /* Callers that do fh_verify should do the fh_want_write: */ + get_write_count = !fhp->fh_dentry; + /* Get inode */ err = fh_verify(rqstp, fhp, ftype, accmode); if (err) goto out; + if (get_write_count) { + host_err = fh_want_write(fhp); + if (host_err) + return nfserrno(host_err); + } dentry = fhp->fh_dentry; inode = dentry->d_inode; diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index 5b704c63a103..1edcb141f639 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c @@ -90,7 +90,6 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, * information for this bh as it's not marked locally * uptodate. */ ret = -EIO; - put_bh(bh); mlog_errno(ret); } @@ -420,7 +419,6 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb, if (!buffer_uptodate(bh)) { ret = -EIO; - put_bh(bh); mlog_errno(ret); } diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 7035af09cc03..fe29f7978f81 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -537,7 +537,10 @@ master_here: /* success! see if any other nodes need recovery */ mlog(0, "DONE mastering recovery of %s:%u here(this=%u)!\n", dlm->name, dlm->reco.dead_node, dlm->node_num); - dlm_reset_recovery(dlm); + spin_lock(&dlm->spinlock); + __dlm_reset_recovery(dlm); + dlm->reco.state &= ~DLM_RECO_STATE_FINALIZE; + spin_unlock(&dlm->spinlock); } dlm_end_recovery(dlm); @@ -695,6 +698,14 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) if (all_nodes_done) { int ret; + /* Set this flag on recovery master to avoid + * a new recovery for another dead node start + * before the recovery is not done. That may + * cause recovery hung.*/ + spin_lock(&dlm->spinlock); + dlm->reco.state |= DLM_RECO_STATE_FINALIZE; + spin_unlock(&dlm->spinlock); + /* all nodes are now in DLM_RECO_NODE_DATA_DONE state * just send a finalize message to everyone and * clean up */ @@ -1750,13 +1761,13 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, struct dlm_migratable_lockres *mres) { struct dlm_migratable_lock *ml; - struct list_head *queue; + struct list_head *queue, *iter; struct list_head *tmpq = NULL; struct dlm_lock *newlock = NULL; struct dlm_lockstatus *lksb = NULL; int ret = 0; int i, j, bad; - struct dlm_lock *lock = NULL; + struct dlm_lock *lock; u8 from = O2NM_MAX_NODES; unsigned int added = 0; __be64 c; @@ -1791,14 +1802,16 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, /* MIGRATION ONLY! */ BUG_ON(!(mres->flags & DLM_MRES_MIGRATION)); + lock = NULL; spin_lock(&res->spinlock); for (j = DLM_GRANTED_LIST; j <= DLM_BLOCKED_LIST; j++) { tmpq = dlm_list_idx_to_ptr(res, j); - list_for_each_entry(lock, tmpq, list) { - if (lock->ml.cookie != ml->cookie) - lock = NULL; - else + list_for_each(iter, tmpq) { + lock = list_entry(iter, + struct dlm_lock, list); + if (lock->ml.cookie == ml->cookie) break; + lock = NULL; } if (lock) break; @@ -2882,8 +2895,8 @@ int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data, BUG(); } dlm->reco.state &= ~DLM_RECO_STATE_FINALIZE; + __dlm_reset_recovery(dlm); spin_unlock(&dlm->spinlock); - dlm_reset_recovery(dlm); dlm_kick_recovery_thread(dlm); break; default: diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 3683643f3f0e..feed025fe064 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -450,7 +450,6 @@ leave: brelse(new_fe_bh); brelse(parent_fe_bh); - kfree(si.name); kfree(si.value); ocfs2_free_dir_lookup_result(&lookup); @@ -1855,7 +1854,6 @@ bail: brelse(new_fe_bh); brelse(parent_fe_bh); - kfree(si.name); kfree(si.value); ocfs2_free_dir_lookup_result(&lookup); if (inode_ac) diff --git a/fs/pnode.c b/fs/pnode.c index 88396df725b4..a364a704333b 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -164,46 +164,94 @@ static struct mount *propagation_next(struct mount *m, } } -/* - * return the source mount to be used for cloning - * - * @dest the current destination mount - * @last_dest the last seen destination mount - * @last_src the last seen source mount - * @type return CL_SLAVE if the new mount has to be - * cloned as a slave. - */ -static struct mount *get_source(struct mount *dest, - struct mount *last_dest, - struct mount *last_src, - int *type) +static struct mount *next_group(struct mount *m, struct mount *origin) { - struct mount *p_last_src = NULL; - struct mount *p_last_dest = NULL; - - while (last_dest != dest->mnt_master) { - p_last_dest = last_dest; - p_last_src = last_src; - last_dest = last_dest->mnt_master; - last_src = last_src->mnt_master; + while (1) { + while (1) { + struct mount *next; + if (!IS_MNT_NEW(m) && !list_empty(&m->mnt_slave_list)) + return first_slave(m); + next = next_peer(m); + if (m->mnt_group_id == origin->mnt_group_id) { + if (next == origin) + return NULL; + } else if (m->mnt_slave.next != &next->mnt_slave) + break; + m = next; + } + /* m is the last peer */ + while (1) { + struct mount *master = m->mnt_master; + if (m->mnt_slave.next != &master->mnt_slave_list) + return next_slave(m); + m = next_peer(master); + if (master->mnt_group_id == origin->mnt_group_id) + break; + if (master->mnt_slave.next == &m->mnt_slave) + break; + m = master; + } + if (m == origin) + return NULL; } +} - if (p_last_dest) { - do { - p_last_dest = next_peer(p_last_dest); - } while (IS_MNT_NEW(p_last_dest)); - /* is that a peer of the earlier? */ - if (dest == p_last_dest) { - *type = CL_MAKE_SHARED; - return p_last_src; +/* all accesses are serialized by namespace_sem */ +static struct user_namespace *user_ns; +static struct mount *last_dest, *last_source, *dest_master; +static struct mountpoint *mp; +static struct hlist_head *list; + +static int propagate_one(struct mount *m) +{ + struct mount *child; + int type; + /* skip ones added by this propagate_mnt() */ + if (IS_MNT_NEW(m)) + return 0; + /* skip if mountpoint isn't covered by it */ + if (!is_subdir(mp->m_dentry, m->mnt.mnt_root)) + return 0; + if (m->mnt_group_id == last_dest->mnt_group_id) { + type = CL_MAKE_SHARED; + } else { + struct mount *n, *p; + for (n = m; ; n = p) { + p = n->mnt_master; + if (p == dest_master || IS_MNT_MARKED(p)) { + while (last_dest->mnt_master != p) { + last_source = last_source->mnt_master; + last_dest = last_source->mnt_parent; + } + if (n->mnt_group_id != last_dest->mnt_group_id) { + last_source = last_source->mnt_master; + last_dest = last_source->mnt_parent; + } + break; + } } + type = CL_SLAVE; + /* beginning of peer group among the slaves? */ + if (IS_MNT_SHARED(m)) + type |= CL_MAKE_SHARED; } - /* slave of the earlier, then */ - *type = CL_SLAVE; - /* beginning of peer group among the slaves? */ - if (IS_MNT_SHARED(dest)) - *type |= CL_MAKE_SHARED; - return last_src; + + /* Notice when we are propagating across user namespaces */ + if (m->mnt_ns->user_ns != user_ns) + type |= CL_UNPRIVILEGED; + child = copy_tree(last_source, last_source->mnt.mnt_root, type); + if (IS_ERR(child)) + return PTR_ERR(child); + mnt_set_mountpoint(m, mp, child); + last_dest = m; + last_source = child; + if (m->mnt_master != dest_master) { + read_seqlock_excl(&mount_lock); + SET_MNT_MARK(m->mnt_master); + read_sequnlock_excl(&mount_lock); + } + hlist_add_head(&child->mnt_hash, list); + return 0; } /* @@ -222,56 +270,48 @@ static struct mount *get_source(struct mount *dest, int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp, struct mount *source_mnt, struct hlist_head *tree_list) { - struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; - struct mount *m, *child; + struct mount *m, *n; int ret = 0; - struct mount *prev_dest_mnt = dest_mnt; - struct mount *prev_src_mnt = source_mnt; - HLIST_HEAD(tmp_list); - - for (m = propagation_next(dest_mnt, dest_mnt); m; - m = propagation_next(m, dest_mnt)) { - int type; - struct mount *source; - - if (IS_MNT_NEW(m)) - continue; - - source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); - - /* Notice when we are propagating across user namespaces */ - if (m->mnt_ns->user_ns != user_ns) - type |= CL_UNPRIVILEGED; - - child = copy_tree(source, source->mnt.mnt_root, type); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - tmp_list = *tree_list; - tmp_list.first->pprev = &tmp_list.first; - INIT_HLIST_HEAD(tree_list); + + /* + * we don't want to bother passing tons of arguments to + * propagate_one(); everything is serialized by namespace_sem, + * so globals will do just fine. + */ + user_ns = current->nsproxy->mnt_ns->user_ns; + last_dest = dest_mnt; + last_source = source_mnt; + mp = dest_mp; + list = tree_list; + dest_master = dest_mnt->mnt_master; + + /* all peers of dest_mnt, except dest_mnt itself */ + for (n = next_peer(dest_mnt); n != dest_mnt; n = next_peer(n)) { + ret = propagate_one(n); + if (ret) goto out; - } + } - if (is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) { - mnt_set_mountpoint(m, dest_mp, child); - hlist_add_head(&child->mnt_hash, tree_list); - } else { - /* - * This can happen if the parent mount was bind mounted - * on some subdirectory of a shared/slave mount. - */ - hlist_add_head(&child->mnt_hash, &tmp_list); - } - prev_dest_mnt = m; - prev_src_mnt = child; + /* all slave groups */ + for (m = next_group(dest_mnt, dest_mnt); m; + m = next_group(m, dest_mnt)) { + /* everything in that slave group */ + n = m; + do { + ret = propagate_one(n); + if (ret) + goto out; + n = next_peer(n); + } while (n != m); } out: - lock_mount_hash(); - while (!hlist_empty(&tmp_list)) { - child = hlist_entry(tmp_list.first, struct mount, mnt_hash); - umount_tree(child, 0); + read_seqlock_excl(&mount_lock); + hlist_for_each_entry(n, tree_list, mnt_hash) { + m = n->mnt_parent; + if (m->mnt_master != dest_mnt->mnt_master) + CLEAR_MNT_MARK(m->mnt_master); } - unlock_mount_hash(); + read_sequnlock_excl(&mount_lock); return ret; } diff --git a/fs/pnode.h b/fs/pnode.h index fc28a27fa892..4a246358b031 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -16,6 +16,9 @@ #define IS_MNT_NEW(m) (!(m)->mnt_ns) #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) +#define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED) +#define SET_MNT_MARK(m) ((m)->mnt.mnt_flags |= MNT_MARKED) +#define CLEAR_MNT_MARK(m) ((m)->mnt.mnt_flags &= ~MNT_MARKED) #define CL_EXPIRE 0x01 #define CL_SLAVE 0x02 diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 1fd2051109a3..af677353a3f5 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -125,6 +125,7 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) int d_reclen; char *d_name; ino_t d_ino; + loff_t cur_pos = deh_offset(deh); if (!de_visible(deh)) /* it is hidden entry */ @@ -196,8 +197,9 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) if (local_buf != small_buf) { kfree(local_buf); } - // next entry should be looked for with such offset - next_pos = deh_offset(deh) + 1; + + /* deh_offset(deh) may be invalid now. */ + next_pos = cur_pos + 1; if (item_moved(&tmp_ih, &path_to_entry)) { set_cpu_key_k_offset(&pos_key, diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h index d3909effd725..d96deb443f18 100644 --- a/include/asm-generic/word-at-a-time.h +++ b/include/asm-generic/word-at-a-time.h @@ -50,11 +50,7 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct } #ifndef zero_bytemask -#ifdef CONFIG_64BIT -#define zero_bytemask(mask) (~0ul << fls64(mask)) -#else -#define zero_bytemask(mask) (~0ul << fls(mask)) -#endif /* CONFIG_64BIT */ -#endif /* zero_bytemask */ +#define zero_bytemask(mask) (~0ul << __fls(mask) << 1) +#endif #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/include/dt-bindings/clock/tegra124-car.h b/include/dt-bindings/clock/tegra124-car.h index 8c1603b10665..433528ab5161 100644 --- a/include/dt-bindings/clock/tegra124-car.h +++ b/include/dt-bindings/clock/tegra124-car.h @@ -29,7 +29,7 @@ /* 10 (register bit affects spdif_in and spdif_out) */ #define TEGRA124_CLK_I2S1 11 #define TEGRA124_CLK_I2C1 12 -#define TEGRA124_CLK_NDFLASH 13 +/* 13 */ #define TEGRA124_CLK_SDMMC1 14 #define TEGRA124_CLK_SDMMC4 15 /* 16 */ @@ -83,7 +83,7 @@ /* 64 */ #define TEGRA124_CLK_UARTD 65 -#define TEGRA124_CLK_UARTE 66 +/* 66 */ #define TEGRA124_CLK_I2C3 67 #define TEGRA124_CLK_SBC4 68 #define TEGRA124_CLK_SDMMC3 69 @@ -97,7 +97,7 @@ #define TEGRA124_CLK_TRACE 77 #define TEGRA124_CLK_SOC_THERM 78 #define TEGRA124_CLK_DTV 79 -#define TEGRA124_CLK_NDSPEED 80 +/* 80 */ #define TEGRA124_CLK_I2CSLOW 81 #define TEGRA124_CLK_DSIB 82 #define TEGRA124_CLK_TSEC 83 diff --git a/include/linux/bio.h b/include/linux/bio.h index 5a4d39b4686b..5aa372a7380c 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -216,9 +216,9 @@ static inline void bvec_iter_advance(struct bio_vec *bv, struct bvec_iter *iter, } #define for_each_bvec(bvl, bio_vec, iter, start) \ - for ((iter) = start; \ - (bvl) = bvec_iter_bvec((bio_vec), (iter)), \ - (iter).bi_size; \ + for (iter = (start); \ + (iter).bi_size && \ + ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \ bvec_iter_advance((bio_vec), &(iter), (bvl).bv_len)) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 344883dce584..6088058a3e00 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -464,15 +464,17 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, * 0 . 13 (Windows Server 2008) * 1 . 1 (Windows 7) * 2 . 4 (Windows 8) + * 3 . 0 (Windows 8 R2) */ #define VERSION_WS2008 ((0 << 16) | (13)) #define VERSION_WIN7 ((1 << 16) | (1)) #define VERSION_WIN8 ((2 << 16) | (4)) +#define VERSION_WIN8_1 ((3 << 16) | (0)) #define VERSION_INVAL -1 -#define VERSION_CURRENT VERSION_WIN8 +#define VERSION_CURRENT VERSION_WIN8_1 /* Make maximum size of pipe payload of 16K */ #define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) diff --git a/include/linux/mount.h b/include/linux/mount.h index 371d346fa270..839bac270904 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -44,6 +44,8 @@ struct mnt_namespace; #define MNT_SHARED_MASK (MNT_UNBINDABLE) #define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) +#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \ + MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED) #define MNT_INTERNAL 0x4000 @@ -51,6 +53,7 @@ struct mnt_namespace; #define MNT_LOCKED 0x800000 #define MNT_DOOMED 0x1000000 #define MNT_SYNC_UMOUNT 0x2000000 +#define MNT_MARKED 0x4000000 struct vfsmount { struct dentry *mnt_root; /* root of the mounted tree */ diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 62fd1b756e99..947009ed5996 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -56,6 +56,7 @@ int svc_recv(struct svc_rqst *, long); int svc_send(struct svc_rqst *); void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); +bool svc_alien_sock(struct net *net, int fd); int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, const size_t len); void svc_init_xprt_sock(void); diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h index f29e3a27c2cc..0e3ff30647d5 100644 --- a/include/rdma/ib_cm.h +++ b/include/rdma/ib_cm.h @@ -601,5 +601,4 @@ struct ib_cm_sidr_rep_param { int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, struct ib_cm_sidr_rep_param *param); -int ib_update_cm_av(struct ib_cm_id *id, const u8 *smac, const u8 *alt_smac); #endif /* IB_CM_H */ diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h index 335e8a7cad39..c140620dad92 100644 --- a/include/uapi/linux/libc-compat.h +++ b/include/uapi/linux/libc-compat.h @@ -85,6 +85,12 @@ #endif /* _NETINET_IN_H */ +/* Definitions for xattr.h */ +#if defined(_SYS_XATTR_H) +#define __UAPI_DEF_XATTR 0 +#else +#define __UAPI_DEF_XATTR 1 +#endif /* If we did not see any headers from any supported C libraries, * or we are being included in the kernel, then define everything @@ -98,6 +104,9 @@ #define __UAPI_DEF_IPV6_MREQ 1 #define __UAPI_DEF_IPPROTO_V6 1 +/* Definitions for xattr.h */ +#define __UAPI_DEF_XATTR 1 + #endif /* __GLIBC__ */ #endif /* _UAPI_LIBC_COMPAT_H */ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 6ae7bbe988cc..fe94bb90582e 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1059,14 +1059,14 @@ struct v4l2_bt_timings { /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ - (bt->hfrontporch + bt->hsync + bt->hbackporch) + ((bt)->hfrontporch + (bt)->hsync + (bt)->hbackporch) #define V4L2_DV_BT_FRAME_WIDTH(bt) \ - (bt->width + V4L2_DV_BT_BLANKING_WIDTH(bt)) + ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt)) #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \ - (bt->vfrontporch + bt->vsync + bt->vbackporch + \ - bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch) + ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \ + (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) #define V4L2_DV_BT_FRAME_HEIGHT(bt) \ - (bt->height + V4L2_DV_BT_BLANKING_HEIGHT(bt)) + ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt)) /** struct v4l2_dv_timings - DV timings * @type: the type of the timings diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 40bbc04b6f81..c38355c1f3c9 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -7,11 +7,18 @@ Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. Copyright (c) 2004 Red Hat, Inc., James Morris */ + +#include + #ifndef _UAPI_LINUX_XATTR_H #define _UAPI_LINUX_XATTR_H +#ifdef __UAPI_DEF_XATTR +#define __USE_KERNEL_XATTR_DEFS + #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#endif /* Namespaces */ #define XATTR_OS2_PREFIX "os2." diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 49e13e1f8fe6..aae21e842918 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -144,6 +144,11 @@ static int min_percpu_pagelist_fract = 8; static int ngroups_max = NGROUPS_MAX; static const int cap_last_cap = CAP_LAST_CAP; +/*this is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs */ +#ifdef CONFIG_DETECT_HUNG_TASK +static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); +#endif + #ifdef CONFIG_INOTIFY_USER #include #endif @@ -995,6 +1000,7 @@ static struct ctl_table kern_table[] = { .maxlen = sizeof(unsigned long), .mode = 0644, .proc_handler = proc_dohung_task_timeout_secs, + .extra2 = &hung_task_timeout_max, }, { .procname = "hung_task_warnings", diff --git a/mm/hugetlb.c b/mm/hugetlb.c index c01cb9fedb18..2de3c845f03a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1509,6 +1509,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, while (min_count < persistent_huge_pages(h)) { if (!free_pool_huge_page(h, nodes_allowed, 0)) break; + cond_resched_lock(&hugetlb_lock); } while (count < persistent_huge_pages(h)) { if (!adjust_pool_surplus(h, nodes_allowed, 1)) diff --git a/mm/internal.h b/mm/internal.h index 29e1e761f9eb..3e910000fda4 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -370,5 +370,6 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone, #define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ #define ALLOC_CPUSET 0x40 /* check for correct cpuset */ #define ALLOC_CMA 0x80 /* allow allocations from CMA areas */ +#define ALLOC_FAIR 0x100 /* fair zone allocation */ #endif /* __MM_INTERNAL_H */ diff --git a/mm/mlock.c b/mm/mlock.c index 4e1a68162285..b1eb53634005 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -79,6 +79,7 @@ void clear_page_mlock(struct page *page) */ void mlock_vma_page(struct page *page) { + /* Serialize with page migration */ BUG_ON(!PageLocked(page)); if (!TestSetPageMlocked(page)) { @@ -174,6 +175,7 @@ unsigned int munlock_vma_page(struct page *page) unsigned int nr_pages; struct zone *zone = page_zone(page); + /* For try_to_munlock() and to serialize with page migration */ BUG_ON(!PageLocked(page)); /* diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3bac76ae4b30..7387a671234e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1238,15 +1238,6 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) } local_irq_restore(flags); } -static bool gfp_thisnode_allocation(gfp_t gfp_mask) -{ - return (gfp_mask & GFP_THISNODE) == GFP_THISNODE; -} -#else -static bool gfp_thisnode_allocation(gfp_t gfp_mask) -{ - return false; -} #endif /* @@ -1583,12 +1574,7 @@ again: get_pageblock_migratetype(page)); } - /* - * NOTE: GFP_THISNODE allocations do not partake in the kswapd - * aging protocol, so they can't be fair. - */ - if (!gfp_thisnode_allocation(gfp_flags)) - __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); + __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); __count_zone_vm_events(PGALLOC, zone, 1 << order); zone_statistics(preferred_zone, zone, gfp_flags); @@ -1954,23 +1940,12 @@ zonelist_scan: * zone size to ensure fair page aging. The zone a * page was allocated in should have no effect on the * time the page has in memory before being reclaimed. - * - * Try to stay in local zones in the fastpath. If - * that fails, the slowpath is entered, which will do - * another pass starting with the local zones, but - * ultimately fall back to remote zones that do not - * partake in the fairness round-robin cycle of this - * zonelist. - * - * NOTE: GFP_THISNODE allocations do not partake in - * the kswapd aging protocol, so they can't be fair. */ - if ((alloc_flags & ALLOC_WMARK_LOW) && - !gfp_thisnode_allocation(gfp_mask)) { - if (zone_page_state(zone, NR_ALLOC_BATCH) <= 0) - continue; + if (alloc_flags & ALLOC_FAIR) { if (!zone_local(preferred_zone, zone)) continue; + if (zone_page_state(zone, NR_ALLOC_BATCH) <= 0) + continue; } /* * When allocating a page cache page for writing, we @@ -2408,32 +2383,40 @@ __alloc_pages_high_priority(gfp_t gfp_mask, unsigned int order, return page; } -static void prepare_slowpath(gfp_t gfp_mask, unsigned int order, - struct zonelist *zonelist, - enum zone_type high_zoneidx, - struct zone *preferred_zone) +static void reset_alloc_batches(struct zonelist *zonelist, + enum zone_type high_zoneidx, + struct zone *preferred_zone) { struct zoneref *z; struct zone *zone; for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { - if (!(gfp_mask & __GFP_NO_KSWAPD)) - wakeup_kswapd(zone, order, zone_idx(preferred_zone)); /* * Only reset the batches of zones that were actually - * considered in the fast path, we don't want to - * thrash fairness information for zones that are not + * considered in the fairness pass, we don't want to + * trash fairness information for zones that are not * actually part of this zonelist's round-robin cycle. */ if (!zone_local(preferred_zone, zone)) continue; mod_zone_page_state(zone, NR_ALLOC_BATCH, - high_wmark_pages(zone) - - low_wmark_pages(zone) - - zone_page_state(zone, NR_ALLOC_BATCH)); + high_wmark_pages(zone) - low_wmark_pages(zone) - + atomic_long_read(&zone->vm_stat[NR_ALLOC_BATCH])); } } +static void wake_all_kswapds(unsigned int order, + struct zonelist *zonelist, + enum zone_type high_zoneidx, + struct zone *preferred_zone) +{ + struct zoneref *z; + struct zone *zone; + + for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) + wakeup_kswapd(zone, order, zone_idx(preferred_zone)); +} + static inline int gfp_to_alloc_flags(gfp_t gfp_mask) { @@ -2522,12 +2505,13 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, * allowed per node queues are empty and that nodes are * over allocated. */ - if (gfp_thisnode_allocation(gfp_mask)) + if (IS_ENABLED(CONFIG_NUMA) && + (gfp_mask & GFP_THISNODE) == GFP_THISNODE) goto nopage; restart: - prepare_slowpath(gfp_mask, order, zonelist, - high_zoneidx, preferred_zone); + if (!(gfp_mask & __GFP_NO_KSWAPD)) + wake_all_kswapds(order, zonelist, high_zoneidx, preferred_zone); /* * OK, we're below the kswapd watermark and have kicked background @@ -2711,7 +2695,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, struct page *page = NULL; int migratetype = allocflags_to_migratetype(gfp_mask); unsigned int cpuset_mems_cookie; - int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET; + int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET|ALLOC_FAIR; struct mem_cgroup *memcg = NULL; gfp_mask &= gfp_allowed_mask; @@ -2752,12 +2736,29 @@ retry_cpuset: if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) alloc_flags |= ALLOC_CMA; #endif +retry: /* First allocation attempt */ page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order, zonelist, high_zoneidx, alloc_flags, preferred_zone, migratetype); if (unlikely(!page)) { /* + * The first pass makes sure allocations are spread + * fairly within the local node. However, the local + * node might have free pages left after the fairness + * batches are exhausted, and remote zones haven't + * even been considered yet. Try once more without + * fairness, and include remote zones now, before + * entering the slowpath and waking kswapd: prefer + * spilling to a remote zone over swapping locally. + */ + if (alloc_flags & ALLOC_FAIR) { + reset_alloc_batches(zonelist, high_zoneidx, + preferred_zone); + alloc_flags &= ~ALLOC_FAIR; + goto retry; + } + /* * Runtime PM, block IO and its error handling path * can deadlock because I/O on the device might not * complete. diff --git a/mm/rmap.c b/mm/rmap.c index 8fc049f9a5a6..d3cbac508c2f 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1322,9 +1322,19 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount, BUG_ON(!page || PageAnon(page)); if (locked_vma) { - mlock_vma_page(page); /* no-op if already mlocked */ - if (page == check_page) + if (page == check_page) { + /* we know we have check_page locked */ + mlock_vma_page(page); ret = SWAP_MLOCK; + } else if (trylock_page(page)) { + /* + * If we can lock the page, perform mlock. + * Otherwise leave the page alone, it will be + * eventually encountered again later. + */ + mlock_vma_page(page); + unlock_page(page); + } continue; /* don't unmap */ } diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index b6e59f0a9475..d06cb8752dcd 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1397,6 +1397,22 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, return svsk; } +bool svc_alien_sock(struct net *net, int fd) +{ + int err; + struct socket *sock = sockfd_lookup(fd, &err); + bool ret = false; + + if (!sock) + goto out; + if (sock_net(sock->sk) != net) + ret = true; + sockfd_put(sock); +out: + return ret; +} +EXPORT_SYMBOL_GPL(svc_alien_sock); + /** * svc_addsock - add a listener socket to an RPC service * @serv: pointer to RPC service to which to add a new listener diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8d0a84436674..41106813a9aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -993,6 +993,7 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), + SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), @@ -2786,6 +2787,89 @@ static void alc269_shutup(struct hda_codec *codec) snd_hda_shutup_pins(codec); } +static void alc283_restore_default_value(struct hda_codec *codec) +{ + int val; + + /* Power Down Control */ + alc_write_coef_idx(codec, 0x03, 0x0002); + /* FIFO and filter clock */ + alc_write_coef_idx(codec, 0x05, 0x0700); + /* DMIC control */ + alc_write_coef_idx(codec, 0x07, 0x0200); + /* Analog clock */ + val = alc_read_coef_idx(codec, 0x06); + alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); + /* JD */ + val = alc_read_coef_idx(codec, 0x08); + alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); + /* JD offset1 */ + alc_write_coef_idx(codec, 0x0a, 0xcccc); + /* JD offset2 */ + alc_write_coef_idx(codec, 0x0b, 0xcccc); + /* LDO1/2/3, DAC/ADC */ + alc_write_coef_idx(codec, 0x0e, 0x6fc0); + /* JD */ + val = alc_read_coef_idx(codec, 0x0f); + alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); + /* Capless */ + val = alc_read_coef_idx(codec, 0x10); + alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); + /* Class D test 4 */ + alc_write_coef_idx(codec, 0x3a, 0x0); + /* IO power down directly */ + val = alc_read_coef_idx(codec, 0x0c); + alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); + /* ANC */ + alc_write_coef_idx(codec, 0x22, 0xa0c0); + /* AGC MUX */ + val = alc_read_coefex_idx(codec, 0x53, 0x01); + alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); + /* DAC simple content protection */ + val = alc_read_coef_idx(codec, 0x1d); + alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); + /* ADC simple content protection */ + val = alc_read_coef_idx(codec, 0x1f); + alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); + /* DAC ADC Zero Detection */ + alc_write_coef_idx(codec, 0x21, 0x8804); + /* PLL */ + alc_write_coef_idx(codec, 0x2e, 0x2902); + /* capless control 2 */ + alc_write_coef_idx(codec, 0x33, 0xa080); + /* capless control 3 */ + alc_write_coef_idx(codec, 0x34, 0x3400); + /* capless control 4 */ + alc_write_coef_idx(codec, 0x35, 0x2f3e); + /* capless control 5 */ + alc_write_coef_idx(codec, 0x36, 0x0); + /* class D test 2 */ + val = alc_read_coef_idx(codec, 0x38); + alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); + /* class D test 3 */ + alc_write_coef_idx(codec, 0x39, 0x110a); + /* class D test 5 */ + val = alc_read_coef_idx(codec, 0x3b); + alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); + /* class D test 6 */ + alc_write_coef_idx(codec, 0x3c, 0x0014); + /* classD OCP */ + alc_write_coef_idx(codec, 0x3d, 0xc2ba); + /* classD pure DC test */ + val = alc_read_coef_idx(codec, 0x42); + alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); + /* test mode */ + alc_write_coef_idx(codec, 0x49, 0x0); + /* Class D DC enable */ + val = alc_read_coef_idx(codec, 0x40); + alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); + /* DC offset */ + val = alc_read_coef_idx(codec, 0x42); + alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); + /* Class D amp control */ + alc_write_coef_idx(codec, 0x37, 0xfc06); +} + static void alc283_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -2793,6 +2877,8 @@ static void alc283_init(struct hda_codec *codec) bool hp_pin_sense; int val; + alc283_restore_default_value(codec); + if (!hp_pin) return; hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); @@ -3126,8 +3212,9 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) if (spec->mute_led_polarity) enabled = !enabled; - pinval = AC_PINCTL_IN_EN | - (enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80); + pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); + pinval &= ~AC_PINCTL_VREFEN; + pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; if (spec->mute_led_nid) snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); } @@ -4319,6 +4406,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -4618,6 +4708,7 @@ static int patch_alc269(struct hda_codec *codec) spec->codec_variant = ALC269_TYPE_ALC285; break; case 0x10ec0286: + case 0x10ec0288: spec->codec_variant = ALC269_TYPE_ALC286; break; case 0x10ec0255: @@ -5184,6 +5275,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), + SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP), @@ -5424,6 +5517,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, + { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 28ec872e54c0..b6e278fe8f67 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -685,9 +685,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream * if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) return 0; ptr = runtime->buffer_size - inw(ice->ddma_port + 4); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) @@ -704,9 +705,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substrea addr = ICE1712_DSC_ADDR0; ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - ice->playback_con_virt_addr[substream->number]; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) @@ -717,9 +719,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) return 0; ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback = { @@ -1113,9 +1116,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substre if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) return 0; ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) @@ -1126,9 +1130,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) return 0; ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); + ptr = bytes_to_frames(substream->runtime, ptr); if (ptr == substream->runtime->buffer_size) ptr = 0; - return bytes_to_frames(substream->runtime, ptr); + return ptr; } static const struct snd_pcm_hardware snd_ice1712_playback_pro = { diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6e9ea8379a91..7a272fa90b39 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -124,9 +124,8 @@ static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0); static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); -/* This is a lie. after -102 db, it stays at -102 */ -/* maybe a range would be better */ -static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0); + +static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0); static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0); static const char *chan_mix[] = { @@ -141,7 +140,7 @@ static const struct soc_enum cs42l51_chan_mix = static const struct snd_kcontrol_new cs42l51_snd_controls[] = { SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, - 6, 0x19, 0x7F, adc_pcm_tlv), + 0, 0x19, 0x7F, adc_pcm_tlv), SOC_DOUBLE_R("PCM Playback Switch", CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", @@ -149,7 +148,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 0, 0x34, 0xE4, aout_tlv), SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, - 6, 0x19, 0x7F, adc_pcm_tlv), + 0, 0x19, 0x7F, adc_pcm_tlv), SOC_DOUBLE_R("ADC Mixer Switch", CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0bac6d5a4ac8..1102ced9b20e 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -347,7 +347,7 @@ static const char * const right_swap_text[] = { static const unsigned int swap_values[] = { 0, 1, 3 }; static const struct soc_enum adca_swap_enum = - SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 1, + SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 3, ARRAY_SIZE(left_swap_text), left_swap_text, swap_values); @@ -356,7 +356,7 @@ static const struct snd_kcontrol_new adca_mixer = SOC_DAPM_ENUM("Route", adca_swap_enum); static const struct soc_enum pcma_swap_enum = - SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 1, + SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 3, ARRAY_SIZE(left_swap_text), left_swap_text, swap_values); @@ -365,7 +365,7 @@ static const struct snd_kcontrol_new pcma_mixer = SOC_DAPM_ENUM("Route", pcma_swap_enum); static const struct soc_enum adcb_swap_enum = - SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 1, + SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 3, ARRAY_SIZE(right_swap_text), right_swap_text, swap_values); @@ -374,7 +374,7 @@ static const struct snd_kcontrol_new adcb_mixer = SOC_DAPM_ENUM("Route", adcb_swap_enum); static const struct soc_enum pcmb_swap_enum = - SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 1, + SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 3, ARRAY_SIZE(right_swap_text), right_swap_text, swap_values); diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 549d5d6a3fef..7b95f7cbc515 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -319,7 +319,7 @@ static const char * const cs42l73_mono_mix_texts[] = { static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 }; static const struct soc_enum spk_asp_enum = - SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1, + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 3, ARRAY_SIZE(cs42l73_mono_mix_texts), cs42l73_mono_mix_texts, cs42l73_mono_mix_values); @@ -337,7 +337,7 @@ static const struct snd_kcontrol_new spk_xsp_mixer = SOC_DAPM_ENUM("Route", spk_xsp_enum); static const struct soc_enum esl_asp_enum = - SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5, + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 3, ARRAY_SIZE(cs42l73_mono_mix_texts), cs42l73_mono_mix_texts, cs42l73_mono_mix_values); @@ -346,7 +346,7 @@ static const struct snd_kcontrol_new esl_asp_mixer = SOC_DAPM_ENUM("Route", esl_asp_enum); static const struct soc_enum esl_xsp_enum = - SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7, + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 3, ARRAY_SIZE(cs42l73_mono_mix_texts), cs42l73_mono_mix_texts, cs42l73_mono_mix_values); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 28522bd03b8e..47e1ce771e65 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1989,7 +1989,6 @@ int soc_dpcm_runtime_update(struct snd_soc_card *card) paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list); if (paths < 0) { - dpcm_path_put(&list); dev_warn(fe->dev, "ASoC: %s no valid %s path\n", fe->dai_link->name, "playback"); mutex_unlock(&card->mutex); @@ -2019,7 +2018,6 @@ capture: paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list); if (paths < 0) { - dpcm_path_put(&list); dev_warn(fe->dev, "ASoC: %s no valid %s path\n", fe->dai_link->name, "capture"); mutex_unlock(&card->mutex); @@ -2084,7 +2082,6 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream) fe->dpcm[stream].runtime = fe_substream->runtime; if (dpcm_path_get(fe, stream, &list) <= 0) { - dpcm_path_put(&list); dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", fe->dai_link->name, stream ? "capture" : "playback"); }