diff --git a/[refs] b/[refs] index 80f643772b16..17d5c8082ee3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 946edc47b6106e7fbacac667fdf26d858231c7c4 +refs/heads/master: 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 diff --git a/trunk/Documentation/arm64/memory.txt b/trunk/Documentation/arm64/memory.txt index 4110cca96bd6..dbbdcbba75a3 100644 --- a/trunk/Documentation/arm64/memory.txt +++ b/trunk/Documentation/arm64/memory.txt @@ -27,17 +27,17 @@ Start End Size Use ----------------------------------------------------------------------- 0000000000000000 0000007fffffffff 512GB user -ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc +ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc -ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] +ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] -ffffffbc00000000 ffffffbdffffffff 8GB vmemmap +ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space -ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] +ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] -ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap -ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] +ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] ffffffbffc000000 ffffffbfffffffff 64MB modules diff --git a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt deleted file mode 100644 index df70318a617f..000000000000 --- a/trunk/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt +++ /dev/null @@ -1,19 +0,0 @@ -* EETI eGalax Multiple Touch Controller - -Required properties: -- compatible: must be "eeti,egalax_ts" -- reg: i2c slave address -- interrupt-parent: the phandle for the interrupt controller -- interrupts: touch controller interrupt -- wakeup-gpios: the gpio pin to be used for waking up the controller - as well as uased as irq pin - -Example: - - egalax_ts@04 { - compatible = "eeti,egalax_ts"; - reg = <0x04>; - interrupt-parent = <&gpio1>; - interrupts = <9 2>; - wakeup-gpios = <&gpio1 9 0>; - }; diff --git a/trunk/Documentation/hwmon/fam15h_power b/trunk/Documentation/hwmon/fam15h_power index 80654813d04a..a92918e0bd69 100644 --- a/trunk/Documentation/hwmon/fam15h_power +++ b/trunk/Documentation/hwmon/fam15h_power @@ -10,7 +10,7 @@ Supported chips: BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors (not yet published) -Author: Andreas Herrmann +Author: Andreas Herrmann Description ----------- diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 59203e77ce9e..cb7d1a42f2cd 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -503,7 +503,7 @@ F: include/linux/altera_uart.h F: include/linux/altera_jtaguart.h AMD FAM15H PROCESSOR POWER MONITORING DRIVER -M: Andreas Herrmann +M: Andreas Herrmann L: lm-sensors@lm-sensors.org S: Maintained F: Documentation/hwmon/fam15h_power @@ -2507,7 +2507,6 @@ M: Joonyoung Shim M: Seung-Woo Kim M: Kyungmin Park L: dri-devel@lists.freedesktop.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git S: Supported F: drivers/gpu/drm/exynos F: include/drm/exynos* diff --git a/trunk/Makefile b/trunk/Makefile index 6edac73ee1ba..42d0e56818ea 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc3 NAME = Terrified Chipmunk # *DOCUMENTATION* diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index 42f042ee4ada..35c1ed89b936 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Q" (*(volatile u16 __force *)addr) + : "+Qo" (*(volatile u16 __force *)addr) : "r" (val)); } @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile("ldrh %1, %0" - : "+Q" (*(volatile u16 __force *)addr), + : "+Qo" (*(volatile u16 __force *)addr), "=r" (val)); return val; } diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h index e3f757263438..05b8e82ec9f5 100644 --- a/trunk/arch/arm/include/asm/sched_clock.h +++ b/trunk/arch/arm/include/asm/sched_clock.h @@ -10,5 +10,7 @@ extern void sched_clock_postinit(void); extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); +extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate); #endif diff --git a/trunk/arch/arm/include/asm/vfpmacros.h b/trunk/arch/arm/include/asm/vfpmacros.h index 301c1db3e99b..6a6f1e485f41 100644 --- a/trunk/arch/arm/include/asm/vfpmacros.h +++ b/trunk/arch/arm/include/asm/vfpmacros.h @@ -27,9 +27,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field @@ -51,9 +51,9 @@ #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] - tst \tmp, #HWCAP_VFPD32 - stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} - addeq \base, \base, #32*4 @ step over unused register space + tst \tmp, #HWCAP_VFPv3D16 + stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field diff --git a/trunk/arch/arm/include/uapi/asm/hwcap.h b/trunk/arch/arm/include/uapi/asm/hwcap.h index 3688fd15a32d..f254f6503cce 100644 --- a/trunk/arch/arm/include/uapi/asm/hwcap.h +++ b/trunk/arch/arm/include/uapi/asm/hwcap.h @@ -18,12 +18,11 @@ #define HWCAP_THUMBEE (1 << 11) #define HWCAP_NEON (1 << 12) #define HWCAP_VFPv3 (1 << 13) -#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ +#define HWCAP_VFPv3D16 (1 << 14) #define HWCAP_TLS (1 << 15) #define HWCAP_VFPv4 (1 << 16) #define HWCAP_IDIVA (1 << 17) #define HWCAP_IDIVT (1 << 18) -#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index fc6692e2b603..e21bac20d90d 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -107,6 +107,13 @@ static void sched_clock_poll(unsigned long wrap_ticks) update_sched_clock(); } +void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, + unsigned long rate) +{ + setup_sched_clock(read, bits, rate); + cd.needs_suspend = true; +} + void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) { unsigned long r, w; @@ -182,15 +189,18 @@ void __init sched_clock_postinit(void) static int sched_clock_suspend(void) { sched_clock_poll(sched_clock_timer.data); - cd.suspended = true; + if (cd.needs_suspend) + cd.suspended = true; return 0; } static void sched_clock_resume(void) { - cd.epoch_cyc = read_sched_clock(); - cd.epoch_cyc_copy = cd.epoch_cyc; - cd.suspended = false; + if (cd.needs_suspend) { + cd.epoch_cyc = read_sched_clock(); + cd.epoch_cyc_copy = cd.epoch_cyc; + cd.suspended = false; + } } static struct syscore_ops sched_clock_ops = { diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index b820edaf3184..023f443784ec 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - union offset_union uninitialized_var(offset); + union offset_union offset; unsigned long instr = 0, instrptr; int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); unsigned int type; diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index 3b44e0dd0a93..c834b32af275 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -701,14 +701,11 @@ static int __init vfp_init(void) elf_hwcap |= HWCAP_VFPv3; /* - * Check for VFPv3 D16 and VFPv4 D16. CPUs in - * this configuration only have 16 x 64bit - * registers. + * Check for VFPv3 D16. CPUs in this configuration + * only have 16 x 64bit registers. */ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) - elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ - else - elf_hwcap |= HWCAP_VFPD32; + elf_hwcap |= HWCAP_VFPv3D16; } #endif /* diff --git a/trunk/arch/arm/xen/enlighten.c b/trunk/arch/arm/xen/enlighten.c index f57609275449..59bcb96ac369 100644 --- a/trunk/arch/arm/xen/enlighten.c +++ b/trunk/arch/arm/xen/enlighten.c @@ -166,14 +166,3 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) *pages = NULL; } EXPORT_SYMBOL_GPL(free_xenballooned_pages); - -/* In the hypervisor.S file. */ -EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); -EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); -EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); -EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); -EXPORT_SYMBOL_GPL(privcmd_call); diff --git a/trunk/arch/arm/xen/hypercall.S b/trunk/arch/arm/xen/hypercall.S index 71f723984cbd..074f5ed101b9 100644 --- a/trunk/arch/arm/xen/hypercall.S +++ b/trunk/arch/arm/xen/hypercall.S @@ -48,16 +48,20 @@ #include #include -#include #include -#define XEN_IMM 0xEA1 +/* HVC 0xEA1 */ +#ifdef CONFIG_THUMB2_KERNEL +#define xen_hvc .word 0xf7e08ea1 +#else +#define xen_hvc .word 0xe140ea71 +#endif #define HYPERCALL_SIMPLE(hypercall) \ ENTRY(HYPERVISOR_##hypercall) \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc; \ mov pc, lr; \ ENDPROC(HYPERVISOR_##hypercall) @@ -72,7 +76,7 @@ ENTRY(HYPERVISOR_##hypercall) \ stmdb sp!, {r4} \ ldr r4, [sp, #4] \ mov r12, #__HYPERVISOR_##hypercall; \ - __HVC(XEN_IMM); \ + xen_hvc \ ldm sp!, {r4} \ mov pc, lr \ ENDPROC(HYPERVISOR_##hypercall) @@ -96,7 +100,7 @@ ENTRY(privcmd_call) mov r2, r3 ldr r3, [sp, #8] ldr r4, [sp, #4] - __HVC(XEN_IMM) + xen_hvc ldm sp!, {r4} mov pc, lr ENDPROC(privcmd_call); diff --git a/trunk/arch/arm64/Kconfig b/trunk/arch/arm64/Kconfig index 15ac18a56c93..ef54a59a9e89 100644 --- a/trunk/arch/arm64/Kconfig +++ b/trunk/arch/arm64/Kconfig @@ -1,7 +1,6 @@ config ARM64 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE - select ARCH_WANT_COMPAT_IPC_PARSE_VERSION select GENERIC_CLOCKEVENTS select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IOMAP diff --git a/trunk/arch/arm64/include/asm/elf.h b/trunk/arch/arm64/include/asm/elf.h index 07fea290d7c1..cf284649dfcb 100644 --- a/trunk/arch/arm64/include/asm/elf.h +++ b/trunk/arch/arm64/include/asm/elf.h @@ -25,10 +25,12 @@ #include typedef unsigned long elf_greg_t; +typedef unsigned long elf_freg_t[3]; #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -typedef struct user_fpsimd_state elf_fpregset_t; + +typedef struct user_fp elf_fpregset_t; #define EM_AARCH64 183 @@ -85,6 +87,7 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define R_AARCH64_MOVW_PREL_G2_NC 292 #define R_AARCH64_MOVW_PREL_G3 293 + /* * These are used to set parameters in the core dumps. */ diff --git a/trunk/arch/arm64/include/asm/fpsimd.h b/trunk/arch/arm64/include/asm/fpsimd.h index c43b4ac13008..b42fab9f62a9 100644 --- a/trunk/arch/arm64/include/asm/fpsimd.h +++ b/trunk/arch/arm64/include/asm/fpsimd.h @@ -25,8 +25,9 @@ * - FPSR and FPCR * - 32 128-bit data registers * - * Note that user_fpsimd forms a prefix of this structure, which is - * relied upon in the ptrace FP/SIMD accessors. + * Note that user_fp forms a prefix of this structure, which is relied + * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must + * form a prefix of struct fpsimd_state. */ struct fpsimd_state { union { diff --git a/trunk/arch/arm64/include/asm/io.h b/trunk/arch/arm64/include/asm/io.h index 54f6116697f7..74a2a7d304a9 100644 --- a/trunk/arch/arm64/include/asm/io.h +++ b/trunk/arch/arm64/include/asm/io.h @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) * I/O port access primitives. */ #define IO_SPACE_LIMIT 0xffff -#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) +#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) static inline u8 inb(unsigned long addr) { @@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr); #define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) -#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) +#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) +#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) #define iounmap __iounmap #define ARCH_HAS_IOREMAP_WC diff --git a/trunk/arch/arm64/include/asm/processor.h b/trunk/arch/arm64/include/asm/processor.h index 77f696c14339..5d810044feda 100644 --- a/trunk/arch/arm64/include/asm/processor.h +++ b/trunk/arch/arm64/include/asm/processor.h @@ -43,8 +43,6 @@ #else #define STACK_TOP STACK_TOP_MAX #endif /* CONFIG_COMPAT */ - -#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK #endif /* __KERNEL__ */ struct debug_info { diff --git a/trunk/arch/arm64/include/asm/unistd.h b/trunk/arch/arm64/include/asm/unistd.h index 68aff2816e86..63f853f8b718 100644 --- a/trunk/arch/arm64/include/asm/unistd.h +++ b/trunk/arch/arm64/include/asm/unistd.h @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #ifdef CONFIG_COMPAT +#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME #define __ARCH_WANT_SYS_PAUSE diff --git a/trunk/arch/arm64/kernel/perf_event.c b/trunk/arch/arm64/kernel/perf_event.c index c76c7241125b..ecbf2d81ec5c 100644 --- a/trunk/arch/arm64/kernel/perf_event.c +++ b/trunk/arch/arm64/kernel/perf_event.c @@ -613,11 +613,17 @@ enum armv8_pmuv3_perf_types { ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, + + /* + * This isn't an architected event. + * We detect this event number and use the cycle counter instead. + */ + ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, }; /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, @@ -1100,7 +1106,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; /* Always place a cycle counter into the cycle counter. */ - if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { + if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) return -EAGAIN; diff --git a/trunk/arch/arm64/kernel/process.c b/trunk/arch/arm64/kernel/process.c index e04cebdbb47f..f22965ea1cfc 100644 --- a/trunk/arch/arm64/kernel/process.c +++ b/trunk/arch/arm64/kernel/process.c @@ -309,6 +309,24 @@ struct task_struct *__switch_to(struct task_struct *prev, return last; } +/* + * Fill in the task's elfregs structure for a core dump. + */ +int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) +{ + elf_core_copy_regs(elfregs, task_pt_regs(t)); + return 1; +} + +/* + * fill in the fpe structure for a core dump... + */ +int dump_fpu (struct pt_regs *regs, struct user_fp *fp) +{ + return 0; +} +EXPORT_SYMBOL(dump_fpu); + /* * Shuffle the argument into the correct register before calling the * thread function. x1 is the thread argument, x2 is the pointer to diff --git a/trunk/arch/arm64/kernel/smp.c b/trunk/arch/arm64/kernel/smp.c index 538300f2273d..226b6bf6e9c2 100644 --- a/trunk/arch/arm64/kernel/smp.c +++ b/trunk/arch/arm64/kernel/smp.c @@ -211,7 +211,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); - complete(&cpu_running); + while (!cpu_active(cpu)) + cpu_relax(); /* * OK, it's off to the idle thread for us diff --git a/trunk/arch/arm64/mm/init.c b/trunk/arch/arm64/mm/init.c index 4cd28931dba9..efbf7df05d3f 100644 --- a/trunk/arch/arm64/mm/init.c +++ b/trunk/arch/arm64/mm/init.c @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) #ifdef CONFIG_ZONE_DMA32 /* 4GB maximum for 32-bit only capable devices */ max_dma32 = min(max, MAX_DMA32_PFN); - zone_size[ZONE_DMA32] = max(min, max_dma32) - min; + zone_size[ZONE_DMA32] = max_dma32 - min; #endif zone_size[ZONE_NORMAL] = max - max_dma32; diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index df2eb4bd9fa2..b7412504f08a 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -13,7 +13,6 @@ config FRV select GENERIC_CPU_DEVICES select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE config ZONE_DMA bool diff --git a/trunk/arch/frv/boot/Makefile b/trunk/arch/frv/boot/Makefile index 636d5bbcd53f..6ae3254da019 100644 --- a/trunk/arch/frv/boot/Makefile +++ b/trunk/arch/frv/boot/Makefile @@ -17,8 +17,6 @@ PARAMS_PHYS = 0x0207c000 INITRD_PHYS = 0x02180000 INITRD_VIRT = 0x02180000 -OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment - # # If you don't define ZRELADDR above, # then it defaults to ZTEXTADDR @@ -34,18 +32,18 @@ Image: $(obj)/Image targets: $(obj)/Image $(obj)/Image: vmlinux FORCE - $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@ + $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@ #$(obj)/Image: $(CONFIGURE) $(SYSTEM) -# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@ +# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/$(LINUX) - $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@ + $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@ bootpImage: bootp/bootp - $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@ + $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ compressed/$(LINUX): $(LINUX) dep @$(MAKE) -C compressed $(LINUX) diff --git a/trunk/arch/frv/include/asm/unistd.h b/trunk/arch/frv/include/asm/unistd.h index 2358634cacca..266a5b25a0c1 100644 --- a/trunk/arch/frv/include/asm/unistd.h +++ b/trunk/arch/frv/include/asm/unistd.h @@ -30,6 +30,7 @@ #define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_KERNEL_EXECVE /* * "Conditional" syscalls diff --git a/trunk/arch/frv/kernel/entry.S b/trunk/arch/frv/kernel/entry.S index dfcd263c0517..ee0beb354e4d 100644 --- a/trunk/arch/frv/kernel/entry.S +++ b/trunk/arch/frv/kernel/entry.S @@ -869,6 +869,11 @@ ret_from_kernel_thread: call schedule_tail calll.p @(gr21,gr0) or gr20,gr20,gr8 + bra sys_exit + + .globl ret_from_kernel_execve +ret_from_kernel_execve: + ori gr28,0,sp bra __syscall_exit ################################################################################################### @@ -1075,10 +1080,27 @@ __entry_return_from_kernel_interrupt: subicc gr5,#0,gr0,icc0 beq icc0,#0,__entry_return_direct - subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ - call preempt_schedule_irq -#endif +__entry_preempt_need_resched: + ldi @(gr15,#TI_FLAGS),gr4 + andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 + beq icc0,#1,__entry_return_direct + + setlos #PREEMPT_ACTIVE,gr5 + sti gr5,@(gr15,#TI_FLAGS) + + andi gr23,#~PSR_PIL,gr23 + movgs gr23,psr + + call schedule + sti gr0,@(gr15,#TI_PRE_COUNT) + + movsg psr,gr23 + ori gr23,#PSR_PIL_14,gr23 + movgs gr23,psr + bra __entry_preempt_need_resched +#else bra __entry_return_direct +#endif ############################################################################### diff --git a/trunk/arch/frv/kernel/process.c b/trunk/arch/frv/kernel/process.c index 7e33215f1d8f..e1e3aa196aa4 100644 --- a/trunk/arch/frv/kernel/process.c +++ b/trunk/arch/frv/kernel/process.c @@ -181,9 +181,6 @@ int copy_thread(unsigned long clone_flags, childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); - /* set up the userspace frame (the only place that the USP is stored) */ - *childregs = *__kernel_frame0_ptr; - p->set_child_tid = p->clear_child_tid = NULL; p->thread.frame = childregs; @@ -194,8 +191,10 @@ int copy_thread(unsigned long clone_flags, p->thread.frame0 = childregs; if (unlikely(!regs)) { + memset(childregs, 0, sizeof(struct pt_regs)); childregs->gr9 = usp; /* function */ childregs->gr8 = arg; + childregs->psr = PSR_S; p->thread.pc = (unsigned long) ret_from_kernel_thread; save_user_regs(p->thread.user); return 0; diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index b99c2a7cc7a4..e47857f889b6 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/h8300/include/asm/cache.h b/trunk/arch/h8300/include/asm/cache.h index 05887a1d80e5..c6350283649d 100644 --- a/trunk/arch/h8300/include/asm/cache.h +++ b/trunk/arch/h8300/include/asm/cache.h @@ -2,8 +2,7 @@ #define __ARCH_H8300_CACHE_H /* bytes per L1 cache line */ -#define L1_CACHE_SHIFT 2 -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define L1_CACHE_BYTES 4 /* m68k-elf-gcc 2.95.2 doesn't like these */ diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index ad2b924167d7..55bde6035216 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -9,8 +9,6 @@ #define LPM_ANYPATH 0xff #define __MAX_CSSID 0 -#define __MAX_SUBCHANNEL 65535 -#define __MAX_SSID 3 #include diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 2d3b7cb26005..dd647c919a66 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -506,15 +506,12 @@ static inline int pud_bad(pud_t pud) static inline int pmd_present(pmd_t pmd) { - unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; - return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || - !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); + return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; } static inline int pmd_none(pmd_t pmd) { - return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && - !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; } static inline int pmd_large(pmd_t pmd) @@ -1226,11 +1223,6 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) } #ifdef CONFIG_TRANSPARENT_HUGEPAGE - -#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) -#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) -#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) - #define __HAVE_ARCH_PGTABLE_DEPOSIT extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); @@ -1250,15 +1242,16 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) { - /* - * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) - * Convert to segment table entry format. - */ - if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) - return pgprot_val(SEGMENT_NONE); - if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) - return pgprot_val(SEGMENT_RO); - return pgprot_val(SEGMENT_RW); + unsigned long pgprot_pmd = 0; + + if (pgprot_val(pgprot) & _PAGE_INVALID) { + if (pgprot_val(pgprot) & _PAGE_SWT) + pgprot_pmd |= _HPAGE_TYPE_NONE; + pgprot_pmd |= _SEGMENT_ENTRY_INV; + } + if (pgprot_val(pgprot) & _PAGE_RO) + pgprot_pmd |= _SEGMENT_ENTRY_RO; + return pgprot_pmd; } static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) @@ -1276,9 +1269,7 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) static inline pmd_t pmd_mkwrite(pmd_t pmd) { - /* Do not clobber _HPAGE_TYPE_NONE pages! */ - if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) - pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; return pmd; } diff --git a/trunk/arch/s390/kernel/sclp.S b/trunk/arch/s390/kernel/sclp.S index b6506ee32a36..bf053898630d 100644 --- a/trunk/arch/s390/kernel/sclp.S +++ b/trunk/arch/s390/kernel/sclp.S @@ -44,12 +44,6 @@ _sclp_wait_int: #endif mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) mvc 0(16,%r8),0(%r9) -#ifdef CONFIG_64BIT - epsw %r6,%r7 # set current addressing mode - nill %r6,0x1 # in new psw (31 or 64 bit mode) - nilh %r7,0x8000 - stm %r6,%r7,0(%r8) -#endif lhi %r6,0x0200 # cr mask for ext int (cr0.54) ltr %r2,%r2 jz .LsetctS1 @@ -93,7 +87,7 @@ _sclp_wait_int: .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int #ifdef CONFIG_64BIT .LextpswS1_64: - .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit + .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit #endif .LwaitpswS1: .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 9017a63dda3d..2d37bb861faf 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) return -0x10UL; - if (pmd_large(*pmd)) { + if (pmd_huge(*pmd)) { if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) return -0x04UL; return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); diff --git a/trunk/arch/s390/mm/gup.c b/trunk/arch/s390/mm/gup.c index 8b8285310b5a..60acb93a4680 100644 --- a/trunk/arch/s390/mm/gup.c +++ b/trunk/arch/s390/mm/gup.c @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, */ if (pmd_none(pmd) || pmd_trans_splitting(pmd)) return 0; - if (unlikely(pmd_large(pmd))) { + if (unlikely(pmd_huge(pmd))) { if (!gup_huge_pmd(pmdp, pmd, addr, next, write, pages, nr)) return 0; diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 9f2edb5c5551..b6b442b0d793 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -20,7 +20,6 @@ config SPARC select HAVE_ARCH_TRACEHOOK select SYSCTL_EXCEPTION_TRACE select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK diff --git a/trunk/arch/sparc/crypto/Makefile b/trunk/arch/sparc/crypto/Makefile index 5d469d81761f..6ae1ad5e502b 100644 --- a/trunk/arch/sparc/crypto/Makefile +++ b/trunk/arch/sparc/crypto/Makefile @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o -sha1-sparc64-y := sha1_asm.o sha1_glue.o -sha256-sparc64-y := sha256_asm.o sha256_glue.o -sha512-sparc64-y := sha512_asm.o sha512_glue.o -md5-sparc64-y := md5_asm.o md5_glue.o +sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o +sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o +sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o +md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o -aes-sparc64-y := aes_asm.o aes_glue.o -des-sparc64-y := des_asm.o des_glue.o -camellia-sparc64-y := camellia_asm.o camellia_glue.o +aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o +des-sparc64-y := des_asm.o des_glue.o crop_devid.o +camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o -crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o diff --git a/trunk/arch/sparc/crypto/aes_glue.c b/trunk/arch/sparc/crypto/aes_glue.c index 3965d1d36dfa..8f1c9980f637 100644 --- a/trunk/arch/sparc/crypto/aes_glue.c +++ b/trunk/arch/sparc/crypto/aes_glue.c @@ -475,5 +475,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/camellia_glue.c b/trunk/arch/sparc/crypto/camellia_glue.c index 62c89af3fd3f..42905c084299 100644 --- a/trunk/arch/sparc/crypto/camellia_glue.c +++ b/trunk/arch/sparc/crypto/camellia_glue.c @@ -320,5 +320,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); MODULE_ALIAS("aes"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/crc32c_glue.c b/trunk/arch/sparc/crypto/crc32c_glue.c index 5162fad912ce..0bd89cea8d8e 100644 --- a/trunk/arch/sparc/crypto/crc32c_glue.c +++ b/trunk/arch/sparc/crypto/crc32c_glue.c @@ -177,5 +177,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); MODULE_ALIAS("crc32c"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/des_glue.c b/trunk/arch/sparc/crypto/des_glue.c index 41524cebcc49..c4940c2d3073 100644 --- a/trunk/arch/sparc/crypto/des_glue.c +++ b/trunk/arch/sparc/crypto/des_glue.c @@ -527,5 +527,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); MODULE_ALIAS("des"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/md5_glue.c b/trunk/arch/sparc/crypto/md5_glue.c index 09a9ea1dfb69..603d723038ce 100644 --- a/trunk/arch/sparc/crypto/md5_glue.c +++ b/trunk/arch/sparc/crypto/md5_glue.c @@ -186,5 +186,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); MODULE_ALIAS("md5"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha1_glue.c b/trunk/arch/sparc/crypto/sha1_glue.c index 6cd5f29e1e0d..2bbb20bee9f1 100644 --- a/trunk/arch/sparc/crypto/sha1_glue.c +++ b/trunk/arch/sparc/crypto/sha1_glue.c @@ -181,5 +181,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); MODULE_ALIAS("sha1"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha256_glue.c b/trunk/arch/sparc/crypto/sha256_glue.c index 04f555ab2680..591e656bd891 100644 --- a/trunk/arch/sparc/crypto/sha256_glue.c +++ b/trunk/arch/sparc/crypto/sha256_glue.c @@ -239,5 +239,3 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op MODULE_ALIAS("sha224"); MODULE_ALIAS("sha256"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/crypto/sha512_glue.c b/trunk/arch/sparc/crypto/sha512_glue.c index f04d1994d19a..486f0a2b7001 100644 --- a/trunk/arch/sparc/crypto/sha512_glue.c +++ b/trunk/arch/sparc/crypto/sha512_glue.c @@ -224,5 +224,3 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op MODULE_ALIAS("sha384"); MODULE_ALIAS("sha512"); - -#include "crop_devid.c" diff --git a/trunk/arch/sparc/include/asm/atomic_64.h b/trunk/arch/sparc/include/asm/atomic_64.h index be56a244c9cf..ce35a1cf1a20 100644 --- a/trunk/arch/sparc/include/asm/atomic_64.h +++ b/trunk/arch/sparc/include/asm/atomic_64.h @@ -1,7 +1,7 @@ /* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * - * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) */ #ifndef __ARCH_SPARC64_ATOMIC__ @@ -106,8 +106,6 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -extern long atomic64_dec_if_positive(atomic64_t *v); - /* Atomic operations are already serializing */ #define smp_mb__before_atomic_dec() barrier() #define smp_mb__after_atomic_dec() barrier() diff --git a/trunk/arch/sparc/include/asm/backoff.h b/trunk/arch/sparc/include/asm/backoff.h index 4e02086b839c..db3af0d30fb1 100644 --- a/trunk/arch/sparc/include/asm/backoff.h +++ b/trunk/arch/sparc/include/asm/backoff.h @@ -1,46 +1,6 @@ #ifndef _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H -/* The macros in this file implement an exponential backoff facility - * for atomic operations. - * - * When multiple threads compete on an atomic operation, it is - * possible for one thread to be continually denied a successful - * completion of the compare-and-swap instruction. Heavily - * threaded cpu implementations like Niagara can compound this - * problem even further. - * - * When an atomic operation fails and needs to be retried, we spin a - * certain number of times. At each subsequent failure of the same - * operation we double the spin count, realizing an exponential - * backoff. - * - * When we spin, we try to use an operation that will cause the - * current cpu strand to block, and therefore make the core fully - * available to any other other runnable strands. There are two - * options, based upon cpu capabilities. - * - * On all cpus prior to SPARC-T4 we do three dummy reads of the - * condition code register. Each read blocks the strand for something - * between 40 and 50 cpu cycles. - * - * For SPARC-T4 and later we have a special "pause" instruction - * available. This is implemented using writes to register %asr27. - * The cpu will block the number of cycles written into the register, - * unless a disrupting trap happens first. SPARC-T4 specifically - * implements pause with a granularity of 8 cycles. Each strand has - * an internal pause counter which decrements every 8 cycles. So the - * chip shifts the %asr27 value down by 3 bits, and writes the result - * into the pause counter. If a value smaller than 8 is written, the - * chip blocks for 1 cycle. - * - * To achieve the same amount of backoff as the three %ccr reads give - * on earlier chips, we shift the backoff value up by 7 bits. (Three - * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the - * whole amount we want to block into the pause register, rather than - * loop writing 128 each time. - */ - #define BACKOFF_LIMIT (4 * 1024) #ifdef CONFIG_SMP @@ -51,25 +11,16 @@ #define BACKOFF_LABEL(spin_label, continue_label) \ spin_label -#define BACKOFF_SPIN(reg, tmp, label) \ - mov reg, tmp; \ -88: rd %ccr, %g0; \ - rd %ccr, %g0; \ - rd %ccr, %g0; \ - .section .pause_3insn_patch,"ax";\ - .word 88b; \ - sllx tmp, 7, tmp; \ - wr tmp, 0, %asr27; \ - clr tmp; \ - .previous; \ - brnz,pt tmp, 88b; \ - sub tmp, 1, tmp; \ - set BACKOFF_LIMIT, tmp; \ - cmp reg, tmp; \ - bg,pn %xcc, label; \ - nop; \ - ba,pt %xcc, label; \ - sllx reg, 1, reg; +#define BACKOFF_SPIN(reg, tmp, label) \ + mov reg, tmp; \ +88: brnz,pt tmp, 88b; \ + sub tmp, 1, tmp; \ + set BACKOFF_LIMIT, tmp; \ + cmp reg, tmp; \ + bg,pn %xcc, label; \ + nop; \ + ba,pt %xcc, label; \ + sllx reg, 1, reg; #else diff --git a/trunk/arch/sparc/include/asm/compat.h b/trunk/arch/sparc/include/asm/compat.h index 830502fe62b4..cef99fbc0a21 100644 --- a/trunk/arch/sparc/include/asm/compat.h +++ b/trunk/arch/sparc/include/asm/compat.h @@ -232,10 +232,9 @@ static inline void __user *arch_compat_alloc_user_space(long len) struct pt_regs *regs = current_thread_info()->kregs; unsigned long usp = regs->u_regs[UREG_I6]; - if (test_thread_64bit_stack(usp)) + if (!(test_thread_flag(TIF_32BIT))) usp += STACK_BIAS; - - if (test_thread_flag(TIF_32BIT)) + else usp &= 0xffffffffUL; usp -= len; diff --git a/trunk/arch/sparc/include/asm/processor_64.h b/trunk/arch/sparc/include/asm/processor_64.h index 721e25f0e2ea..4e5a483122a0 100644 --- a/trunk/arch/sparc/include/asm/processor_64.h +++ b/trunk/arch/sparc/include/asm/processor_64.h @@ -196,22 +196,7 @@ extern unsigned long get_wchan(struct task_struct *task); #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) -/* Please see the commentary in asm/backoff.h for a description of - * what these instructions are doing and how they have been choosen. - * To make a long story short, we are trying to yield the current cpu - * strand during busy loops. - */ -#define cpu_relax() asm volatile("\n99:\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - "rd %%ccr, %%g0\n\t" \ - ".section .pause_3insn_patch,\"ax\"\n\t"\ - ".word 99b\n\t" \ - "wr %%g0, 128, %%asr27\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".previous" \ - ::: "memory") +#define cpu_relax() barrier() /* Prefetch support. This is tuned for UltraSPARC-III and later. * UltraSPARC-I will treat these as nops, and UltraSPARC-II has diff --git a/trunk/arch/sparc/include/asm/prom.h b/trunk/arch/sparc/include/asm/prom.h index f93003123bce..c28765110706 100644 --- a/trunk/arch/sparc/include/asm/prom.h +++ b/trunk/arch/sparc/include/asm/prom.h @@ -63,10 +63,5 @@ extern char *of_console_options; extern void irq_trans_init(struct device_node *dp); extern char *build_path_component(struct device_node *dp); -/* SPARC has a local implementation */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); -#define of_address_to_resource of_address_to_resource - #endif /* __KERNEL__ */ #endif /* _SPARC_PROM_H */ diff --git a/trunk/arch/sparc/include/asm/thread_info_64.h b/trunk/arch/sparc/include/asm/thread_info_64.h index a3fe4dcc0aa6..4e2276631081 100644 --- a/trunk/arch/sparc/include/asm/thread_info_64.h +++ b/trunk/arch/sparc/include/asm/thread_info_64.h @@ -259,11 +259,6 @@ static inline bool test_and_clear_restore_sigmask(void) #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) -#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) -#define test_thread_64bit_stack(__SP) \ - ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ - false : true) - #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/sparc/include/asm/ttable.h b/trunk/arch/sparc/include/asm/ttable.h index 71b5a67522ab..48f2807d3265 100644 --- a/trunk/arch/sparc/include/asm/ttable.h +++ b/trunk/arch/sparc/include/asm/ttable.h @@ -372,9 +372,7 @@ etrap_spill_fixup_64bit: \ /* Normal 32bit spill */ #define SPILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + %g0] ASI; \ mov 0x04, %g3; \ stwa %l1, [%sp + %g3] ASI; \ @@ -400,16 +398,14 @@ etrap_spill_fixup_64bit: \ stwa %i6, [%g1 + %g0] ASI; \ stwa %i7, [%g1 + %g3] ASI; \ saved; \ - retry; \ + retry; nop; nop; \ b,a,pt %xcc, spill_fixup_dax; \ b,a,pt %xcc, spill_fixup_mna; \ b,a,pt %xcc, spill_fixup; #define SPILL_2_GENERIC_ETRAP \ etrap_user_spill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, etrap_user_spill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ stwa %l0, [%sp + 0x00] %asi; \ stwa %l1, [%sp + 0x04] %asi; \ stwa %l2, [%sp + 0x08] %asi; \ @@ -431,7 +427,7 @@ etrap_user_spill_32bit: \ ba,pt %xcc, etrap_save; \ wrpr %g1, %cwp; \ nop; nop; nop; nop; \ - nop; nop; \ + nop; nop; nop; nop; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; \ ba,a,pt %xcc, etrap_spill_fixup_32bit; @@ -596,9 +592,7 @@ user_rtt_fill_64bit: \ /* Normal 32bit fill */ #define FILL_2_GENERIC(ASI) \ - and %sp, 1, %g3; \ - brnz,pn %g3, (. - (128 + 4)); \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + %g0] ASI, %l0; \ mov 0x04, %g2; \ mov 0x08, %g3; \ @@ -622,16 +616,14 @@ user_rtt_fill_64bit: \ lduwa [%g1 + %g3] ASI, %i6; \ lduwa [%g1 + %g5] ASI, %i7; \ restored; \ - retry; nop; nop; \ + retry; nop; nop; nop; nop; \ b,a,pt %xcc, fill_fixup_dax; \ b,a,pt %xcc, fill_fixup_mna; \ b,a,pt %xcc, fill_fixup; #define FILL_2_GENERIC_RTRAP \ user_rtt_fill_32bit: \ - and %sp, 1, %g3; \ - brnz,pn %g3, user_rtt_fill_64bit; \ - srl %sp, 0, %sp; \ + srl %sp, 0, %sp; \ lduwa [%sp + 0x00] %asi, %l0; \ lduwa [%sp + 0x04] %asi, %l1; \ lduwa [%sp + 0x08] %asi, %l2; \ @@ -651,7 +643,7 @@ user_rtt_fill_32bit: \ ba,pt %xcc, user_rtt_pre_restore; \ restored; \ nop; nop; nop; nop; nop; \ - nop; nop; nop; \ + nop; nop; nop; nop; nop; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; \ ba,a,pt %xcc, user_rtt_fill_fixup; diff --git a/trunk/arch/sparc/include/uapi/asm/unistd.h b/trunk/arch/sparc/include/uapi/asm/unistd.h index cac719d1bc5c..8974ef7ae920 100644 --- a/trunk/arch/sparc/include/uapi/asm/unistd.h +++ b/trunk/arch/sparc/include/uapi/asm/unistd.h @@ -405,13 +405,8 @@ #define __NR_setns 337 #define __NR_process_vm_readv 338 #define __NR_process_vm_writev 339 -#define __NR_kern_features 340 -#define __NR_kcmp 341 -#define NR_syscalls 342 - -/* Bitmask values returned from kern_features system call. */ -#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 +#define NR_syscalls 340 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/trunk/arch/sparc/kernel/entry.h b/trunk/arch/sparc/kernel/entry.h index cc3c5cb47cda..0c218e4c0881 100644 --- a/trunk/arch/sparc/kernel/entry.h +++ b/trunk/arch/sparc/kernel/entry.h @@ -59,13 +59,6 @@ struct popc_6insn_patch_entry { extern struct popc_6insn_patch_entry __popc_6insn_patch, __popc_6insn_patch_end; -struct pause_patch_entry { - unsigned int addr; - unsigned int insns[3]; -}; -extern struct pause_patch_entry __pause_3insn_patch, - __pause_3insn_patch_end; - extern void __init per_cpu_patch(void); extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, struct sun4v_1insn_patch_entry *); diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index 87f60ee65433..f8b6eee40bde 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -56,13 +56,11 @@ static inline unsigned int leon_eirq_get(int cpu) static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) { unsigned int eirq; - struct irq_bucket *p; int cpu = sparc_leon3_cpuid(); eirq = leon_eirq_get(cpu); - p = irq_map[eirq]; - if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ - generic_handle_irq(p->irq); + if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ + generic_handle_irq(irq_map[eirq]->irq); } /* The extended IRQ controller has been found, this function registers it */ diff --git a/trunk/arch/sparc/kernel/perf_event.c b/trunk/arch/sparc/kernel/perf_event.c index b5c38faa4ead..885a8af74064 100644 --- a/trunk/arch/sparc/kernel/perf_event.c +++ b/trunk/arch/sparc/kernel/perf_event.c @@ -1762,25 +1762,15 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { + struct sparc_stackf32 *usf, sf; unsigned long pc; - if (thread32_stack_is_64bit(ufp)) { - struct sparc_stackf *usf, sf; + usf = (struct sparc_stackf32 *) ufp; + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) + break; - ufp += STACK_BIAS; - usf = (struct sparc_stackf *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc & 0xffffffff; - ufp = ((unsigned long) sf.fp) & 0xffffffff; - } else { - struct sparc_stackf32 *usf, sf; - usf = (struct sparc_stackf32 *) ufp; - if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) - break; - pc = sf.callers_pc; - ufp = (unsigned long)sf.fp; - } + pc = sf.callers_pc; + ufp = (unsigned long)sf.fp; perf_callchain_store(entry, pc); } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/trunk/arch/sparc/kernel/process_64.c b/trunk/arch/sparc/kernel/process_64.c index c6e0c2910043..d778248ef3f8 100644 --- a/trunk/arch/sparc/kernel/process_64.c +++ b/trunk/arch/sparc/kernel/process_64.c @@ -452,16 +452,13 @@ void flush_thread(void) /* It's a bit more tricky when 64-bit tasks are involved... */ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) { - bool stack_64bit = test_thread_64bit_stack(psp); unsigned long fp, distance, rval; - if (stack_64bit) { + if (!(test_thread_flag(TIF_32BIT))) { csp += STACK_BIAS; psp += STACK_BIAS; __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); fp += STACK_BIAS; - if (test_thread_flag(TIF_32BIT)) - fp &= 0xffffffff; } else __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); @@ -475,7 +472,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) rval = (csp - distance); if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) rval = 0; - else if (!stack_64bit) { + else if (test_thread_flag(TIF_32BIT)) { if (put_user(((u32)csp), &(((struct reg_window32 __user *)rval)->ins[6]))) rval = 0; @@ -510,18 +507,18 @@ void synchronize_user_stack(void) flush_user_windows(); if ((window = get_thread_wsaved()) != 0) { + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; + window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (!copy_to_user((char __user *)sp, rwin, winsize)) { shift_window_buffer(window, get_thread_wsaved() - 1, t); @@ -547,6 +544,13 @@ void fault_in_user_windows(void) { struct thread_info *t = current_thread_info(); unsigned long window; + int winsize = sizeof(struct reg_window); + int bias = 0; + + if (test_thread_flag(TIF_32BIT)) + winsize = sizeof(struct reg_window32); + else + bias = STACK_BIAS; flush_user_windows(); window = get_thread_wsaved(); @@ -554,16 +558,8 @@ void fault_in_user_windows(void) if (likely(window != 0)) { window -= 1; do { + unsigned long sp = (t->rwbuf_stkptrs[window] + bias); struct reg_window *rwin = &t->reg_window[window]; - int winsize = sizeof(struct reg_window); - unsigned long sp; - - sp = t->rwbuf_stkptrs[window]; - - if (test_thread_64bit_stack(sp)) - sp += STACK_BIAS; - else - winsize = sizeof(struct reg_window32); if (unlikely(sp & 0x7UL)) stack_unaligned(sp); diff --git a/trunk/arch/sparc/kernel/ptrace_64.c b/trunk/arch/sparc/kernel/ptrace_64.c index 7ff45e4ba681..484dabac7045 100644 --- a/trunk/arch/sparc/kernel/ptrace_64.c +++ b/trunk/arch/sparc/kernel/ptrace_64.c @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, { unsigned long rw_addr = regs->u_regs[UREG_I6]; - if (!test_thread_64bit_stack(rw_addr)) { + if (test_tsk_thread_flag(current, TIF_32BIT)) { struct reg_window32 win32; int i; diff --git a/trunk/arch/sparc/kernel/setup_64.c b/trunk/arch/sparc/kernel/setup_64.c index 0eaf0059aaef..0800e71d8a88 100644 --- a/trunk/arch/sparc/kernel/setup_64.c +++ b/trunk/arch/sparc/kernel/setup_64.c @@ -316,25 +316,6 @@ static void __init popc_patch(void) } } -static void __init pause_patch(void) -{ - struct pause_patch_entry *p; - - p = &__pause_3insn_patch; - while (p < &__pause_3insn_patch_end) { - unsigned long i, addr = p->addr; - - for (i = 0; i < 3; i++) { - *(unsigned int *) (addr + (i * 4)) = p->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p++; - } -} - #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -547,8 +528,6 @@ static void __init init_sparc64_elf_hwcap(void) if (sparc64_elf_hwcap & AV_SPARC_POPC) popc_patch(); - if (sparc64_elf_hwcap & AV_SPARC_PAUSE) - pause_patch(); } void __init setup_arch(char **cmdline_p) diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 878ef3d5fec5..11c6c9603e71 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -751,8 +751,3 @@ int kernel_execve(const char *filename, : "cc"); return __res; } - -asmlinkage long sys_kern_features(void) -{ - return KERN_FEATURE_MIXED_MODE_STACK; -} diff --git a/trunk/arch/sparc/kernel/systbls_32.S b/trunk/arch/sparc/kernel/systbls_32.S index 5147f574f125..63402f9e9f51 100644 --- a/trunk/arch/sparc/kernel/systbls_32.S +++ b/trunk/arch/sparc/kernel/systbls_32.S @@ -85,4 +85,3 @@ sys_call_table: /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .long sys_ni_syscall, sys_kcmp diff --git a/trunk/arch/sparc/kernel/systbls_64.S b/trunk/arch/sparc/kernel/systbls_64.S index 1c9af9fa38e9..3a58e0d66f51 100644 --- a/trunk/arch/sparc/kernel/systbls_64.S +++ b/trunk/arch/sparc/kernel/systbls_64.S @@ -86,7 +86,6 @@ sys_call_table32: .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp #endif /* CONFIG_COMPAT */ @@ -164,4 +163,3 @@ sys_call_table: .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -/*340*/ .word sys_kern_features, sys_kcmp diff --git a/trunk/arch/sparc/kernel/unaligned_64.c b/trunk/arch/sparc/kernel/unaligned_64.c index 8201c25e7669..f81d038f7340 100644 --- a/trunk/arch/sparc/kernel/unaligned_64.c +++ b/trunk/arch/sparc/kernel/unaligned_64.c @@ -113,24 +113,21 @@ static inline long sign_extend_imm13(long imm) static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -138,24 +135,19 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) { - unsigned long fp; - if (reg < 16) return ®s->u_regs[reg]; - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 *win32; - win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long *)&win32->locals[reg - 16]; } else { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -400,15 +392,13 @@ int handle_popc(u32 insn, struct pt_regs *regs) if (rd) regs->u_regs[rd] = ret; } else { - unsigned long fp = regs->u_regs[UREG_FP]; - - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); put_user(ret, &win32->locals[rd - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); put_user(ret, &win->locals[rd - 16]); } } @@ -564,7 +554,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) reg[0] = 0; if ((insn & 0x780000) == 0x180000) reg[1] = 0; - } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + } else if (test_thread_flag(TIF_32BIT)) { put_user(0, (int __user *) reg); if ((insn & 0x780000) == 0x180000) put_user(0, ((int __user *) reg) + 1); diff --git a/trunk/arch/sparc/kernel/visemul.c b/trunk/arch/sparc/kernel/visemul.c index c096c624ac4d..08e074b7eb6a 100644 --- a/trunk/arch/sparc/kernel/visemul.c +++ b/trunk/arch/sparc/kernel/visemul.c @@ -149,24 +149,21 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) { - unsigned long value, fp; + unsigned long value; if (reg < 16) return (!reg ? 0 : regs->u_regs[reg]); - - fp = regs->u_regs[UREG_FP]; - if (regs->tstate & TSTATE_PRIV) { struct reg_window *win; - win = (struct reg_window *)(fp + STACK_BIAS); + win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); value = win->locals[reg - 16]; - } else if (!test_thread_64bit_stack(fp)) { + } else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); get_user(value, &win32->locals[reg - 16]); } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); get_user(value, &win->locals[reg - 16]); } return value; @@ -175,18 +172,16 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, struct pt_regs *regs) { - unsigned long fp = regs->u_regs[UREG_FP]; - BUG_ON(reg < 16); BUG_ON(regs->tstate & TSTATE_PRIV); - if (!test_thread_64bit_stack(fp)) { + if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; - win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); + win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); return (unsigned long __user *)&win32->locals[reg - 16]; } else { struct reg_window __user *win; - win = (struct reg_window __user *)(fp + STACK_BIAS); + win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); return &win->locals[reg - 16]; } } @@ -209,7 +204,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) } else { unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); - if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) + if (test_thread_flag(TIF_32BIT)) __put_user((u32)val, (u32 __user *)rd_user); else __put_user(val, rd_user); diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 0bacceb19150..89c2c29f154b 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -132,11 +132,6 @@ SECTIONS *(.popc_6insn_patch) __popc_6insn_patch_end = .; } - .pause_3insn_patch : { - __pause_3insn_patch = .; - *(.pause_3insn_patch) - __pause_3insn_patch_end = .; - } PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/sparc/kernel/winfixup.S b/trunk/arch/sparc/kernel/winfixup.S index 1e67ce958369..a6b0863c27df 100644 --- a/trunk/arch/sparc/kernel/winfixup.S +++ b/trunk/arch/sparc/kernel/winfixup.S @@ -43,8 +43,6 @@ spill_fixup_mna: spill_fixup_dax: TRAP_LOAD_THREAD_REG(%g6, %g1) ldx [%g6 + TI_FLAGS], %g1 - andcc %sp, 0x1, %g0 - movne %icc, 0, %g1 andcc %g1, _TIF_32BIT, %g0 ldub [%g6 + TI_WSAVED], %g1 sll %g1, 3, %g3 diff --git a/trunk/arch/sparc/lib/atomic_64.S b/trunk/arch/sparc/lib/atomic_64.S index 85c233d0a340..4d502da3de78 100644 --- a/trunk/arch/sparc/lib/atomic_64.S +++ b/trunk/arch/sparc/lib/atomic_64.S @@ -1,6 +1,6 @@ /* atomic.S: These things are too big to do inline. * - * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) */ #include @@ -117,17 +117,3 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ sub %g1, %o0, %o0 2: BACKOFF_SPIN(%o2, %o3, 1b) ENDPROC(atomic64_sub_ret) - -ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o0], %g1 - brlez,pn %g1, 3f - sub %g1, 1, %g7 - casx [%o0], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop -3: retl - sub %g1, 1, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_dec_if_positive) diff --git a/trunk/arch/sparc/lib/ksyms.c b/trunk/arch/sparc/lib/ksyms.c index 0c4e35e522fa..ee31b884c61b 100644 --- a/trunk/arch/sparc/lib/ksyms.c +++ b/trunk/arch/sparc/lib/ksyms.c @@ -116,7 +116,6 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); -EXPORT_SYMBOL(atomic64_dec_if_positive); /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); diff --git a/trunk/arch/sparc/math-emu/math_64.c b/trunk/arch/sparc/math-emu/math_64.c index 034aadbff036..1704068da928 100644 --- a/trunk/arch/sparc/math-emu/math_64.c +++ b/trunk/arch/sparc/math-emu/math_64.c @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) XR = 0; else if (freg < 16) XR = regs->u_regs[freg]; - else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { + else if (test_thread_flag(TIF_32BIT)) { struct reg_window32 __user *win32; flushw_user (); win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); diff --git a/trunk/arch/x86/include/asm/xen/hypercall.h b/trunk/arch/x86/include/asm/xen/hypercall.h index c20d1ce62dc6..59c226d120cd 100644 --- a/trunk/arch/x86/include/asm/xen/hypercall.h +++ b/trunk/arch/x86/include/asm/xen/hypercall.h @@ -359,14 +359,18 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, return _hypercall4(int, update_va_mapping, va, new_val.pte, new_val.pte >> 32, flags); } -extern int __must_check xen_event_channel_op_compat(int, void *); static inline int HYPERVISOR_event_channel_op(int cmd, void *arg) { int rc = _hypercall2(int, event_channel_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = xen_event_channel_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct evtchn_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, event_channel_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } @@ -382,14 +386,17 @@ HYPERVISOR_console_io(int cmd, int count, char *str) return _hypercall3(int, console_io, cmd, count, str); } -extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); - static inline int HYPERVISOR_physdev_op(int cmd, void *arg) { int rc = _hypercall2(int, physdev_op, cmd, arg); - if (unlikely(rc == -ENOSYS)) - rc = HYPERVISOR_physdev_op_compat(cmd, arg); + if (unlikely(rc == -ENOSYS)) { + struct physdev_op op; + op.cmd = cmd; + memcpy(&op.u, arg, sizeof(op.u)); + rc = _hypercall1(int, physdev_op_compat, &op); + memcpy(arg, &op.u, sizeof(op.u)); + } return rc; } diff --git a/trunk/arch/x86/include/asm/xen/hypervisor.h b/trunk/arch/x86/include/asm/xen/hypervisor.h index 125f344f06a9..66d0fff1ee84 100644 --- a/trunk/arch/x86/include/asm/xen/hypervisor.h +++ b/trunk/arch/x86/include/asm/xen/hypervisor.h @@ -33,6 +33,7 @@ #ifndef _ASM_X86_XEN_HYPERVISOR_H #define _ASM_X86_XEN_HYPERVISOR_H +/* arch/i386/kernel/setup.c */ extern struct shared_info *HYPERVISOR_shared_info; extern struct start_info *xen_start_info; diff --git a/trunk/arch/x86/kvm/cpuid.h b/trunk/arch/x86/kvm/cpuid.h index a10e46016851..58fc51488828 100644 --- a/trunk/arch/x86/kvm/cpuid.h +++ b/trunk/arch/x86/kvm/cpuid.h @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + if (!static_cpu_has(X86_FEATURE_XSAVE)) + return 0; + best = kvm_find_cpuid_entry(vcpu, 1, 0); return best && (best->ecx & bit(X86_FEATURE_XSAVE)); } diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 224a7e78cb6c..4f7641756be2 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int pending_vec, max_bits, idx; struct desc_ptr dt; + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) + return -EINVAL; + dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index dcf5f2dd91ec..6226c99729b9 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1288,25 +1288,6 @@ unsigned long xen_read_cr2_direct(void) return this_cpu_read(xen_vcpu_info.arch.cr2); } -void xen_flush_tlb_all(void) -{ - struct mmuext_op *op; - struct multicall_space mcs; - - trace_xen_mmu_flush_tlb_all(0); - - preempt_disable(); - - mcs = xen_mc_entry(sizeof(*op)); - - op = mcs.args; - op->cmd = MMUEXT_TLB_FLUSH_ALL; - MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); - - xen_mc_issue(PARAVIRT_LAZY_MMU); - - preempt_enable(); -} static void xen_flush_tlb(void) { struct mmuext_op *op; @@ -2537,7 +2518,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, err = 0; out: - xen_flush_tlb_all(); + flush_tlb_all(); return err; } diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 0d1f36a22c98..cdcb48adee4c 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -13,8 +13,6 @@ config XTENSA select GENERIC_CPU_DEVICES select MODULES_USE_ELF_RELA select GENERIC_PCI_IOMAP - select GENERIC_KERNEL_THREAD - select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB help Xtensa processors are 32-bit RISC machines designed by Tensilica diff --git a/trunk/arch/xtensa/include/asm/io.h b/trunk/arch/xtensa/include/asm/io.h index 700c2e6f2d25..e6be5b9091c2 100644 --- a/trunk/arch/xtensa/include/asm/io.h +++ b/trunk/arch/xtensa/include/asm/io.h @@ -62,10 +62,6 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { } - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - #endif /* CONFIG_MMU */ /* diff --git a/trunk/arch/xtensa/include/asm/processor.h b/trunk/arch/xtensa/include/asm/processor.h index 2d630e7399ca..5c371d8d4528 100644 --- a/trunk/arch/xtensa/include/asm/processor.h +++ b/trunk/arch/xtensa/include/asm/processor.h @@ -152,7 +152,6 @@ struct thread_struct { /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ - memset(regs, 0, sizeof(*regs)); \ regs->pc = new_pc; \ regs->ps = USER_PS_VALUE; \ regs->areg[1] = new_sp; \ @@ -169,6 +168,9 @@ struct mm_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) +/* Create a kernel thread without removing it from tasklists */ +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); + /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) diff --git a/trunk/arch/xtensa/include/asm/syscall.h b/trunk/arch/xtensa/include/asm/syscall.h index 124aeee0d381..c1dacca312f3 100644 --- a/trunk/arch/xtensa/include/asm/syscall.h +++ b/trunk/arch/xtensa/include/asm/syscall.h @@ -10,7 +10,7 @@ struct pt_regs; struct sigaction; -asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); +asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); asmlinkage long xtensa_ptrace(long, long, long, long); asmlinkage long xtensa_sigreturn(struct pt_regs*); diff --git a/trunk/arch/xtensa/include/asm/unistd.h b/trunk/arch/xtensa/include/asm/unistd.h index f4e6eaa40d1c..9ef1c31d2c83 100644 --- a/trunk/arch/xtensa/include/asm/unistd.h +++ b/trunk/arch/xtensa/include/asm/unistd.h @@ -1,9 +1,16 @@ -#ifndef _XTENSA_UNISTD_H -#define _XTENSA_UNISTD_H +/* + * include/asm-xtensa/unistd.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + */ -#define __ARCH_WANT_SYS_EXECVE #include + /* * "Conditional" syscalls * @@ -30,5 +37,3 @@ #define __IGNORE_mmap /* use mmap2 */ #define __IGNORE_vfork /* use clone */ #define __IGNORE_fadvise64 /* use fadvise64_64 */ - -#endif /* _XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/include/uapi/asm/unistd.h b/trunk/arch/xtensa/include/uapi/asm/unistd.h index 9f36d0e3e0ac..479abaea5aae 100644 --- a/trunk/arch/xtensa/include/uapi/asm/unistd.h +++ b/trunk/arch/xtensa/include/uapi/asm/unistd.h @@ -1,4 +1,14 @@ -#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) +/* + * include/asm-xtensa/unistd.h + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2012 Tensilica Inc. + */ + +#ifndef _UAPI_XTENSA_UNISTD_H #define _UAPI_XTENSA_UNISTD_H #ifndef __SYSCALL @@ -262,7 +272,7 @@ __SYSCALL(115, sys_sendmmsg, 4) #define __NR_clone 116 __SYSCALL(116, xtensa_clone, 5) #define __NR_execve 117 -__SYSCALL(117, sys_execve, 3) +__SYSCALL(117, xtensa_execve, 3) #define __NR_exit 118 __SYSCALL(118, sys_exit, 1) #define __NR_exit_group 119 @@ -749,6 +759,4 @@ __SYSCALL(331, sys_kcmp, 5) #define SYS_XTENSA_COUNT 5 /* count */ -#undef __SYSCALL - #endif /* _UAPI_XTENSA_UNISTD_H */ diff --git a/trunk/arch/xtensa/kernel/entry.S b/trunk/arch/xtensa/kernel/entry.S index 90bfc1dbc13d..18453067c258 100644 --- a/trunk/arch/xtensa/kernel/entry.S +++ b/trunk/arch/xtensa/kernel/entry.S @@ -1832,6 +1832,50 @@ ENTRY(system_call) retw +/* + * Create a kernel thread + * + * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_thread) + entry a1, 16 + + mov a5, a2 # preserve fn over syscall + mov a7, a3 # preserve args over syscall + + movi a3, _CLONE_VM | _CLONE_UNTRACED + movi a2, __NR_clone + or a6, a4, a3 # arg0: flags + mov a3, a1 # arg1: sp + syscall + + beq a3, a1, 1f # branch if parent + mov a6, a7 # args + callx4 a5 # fn(args) + + movi a2, __NR_exit + syscall # return value of fn(args) still in a6 + +1: retw + +/* + * Do a system call from kernel instead of calling sys_execve, so we end up + * with proper pt_regs. + * + * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_execve) + entry a1, 16 + mov a6, a2 # arg0 is in a6 + movi a2, __NR_execve + syscall + + retw + /* * Task switch. * @@ -1914,16 +1958,3 @@ ENTRY(ret_from_fork) j common_exception_return -/* - * Kernel thread creation helper - * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg - * left from _switch_to: a6 = prev - */ -ENTRY(ret_from_kernel_thread) - - call4 schedule_tail - mov a6, a3 - callx4 a2 - j common_exception_return - -ENDPROC(ret_from_kernel_thread) diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 09ae7bfab9a7..1908f6642d31 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -45,7 +45,6 @@ #include extern void ret_from_fork(void); -extern void ret_from_kernel_thread(void); struct task_struct *current_set[NR_CPUS] = {&init_task, }; @@ -159,30 +158,18 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy thread. * - * There are two modes in which this function is called: - * 1) Userspace thread creation, - * regs != NULL, usp_thread_fn is userspace stack pointer. - * It is expected to copy parent regs (in case CLONE_VM is not set - * in the clone_flags) and set up passed usp in the childregs. - * 2) Kernel thread creation, - * regs == NULL, usp_thread_fn is the function to run in the new thread - * and thread_fn_arg is its parameter. - * childregs are not used for the kernel threads. - * * The stack layout for the new thread looks like this: * - * +------------------------+ + * +------------------------+ <- sp in childregs (= tos) * | childregs | * +------------------------+ <- thread.sp = sp in dummy-frame * | dummy-frame | (saved in dummy-frame spill-area) * +------------------------+ * - * We create a dummy frame to return to either ret_from_fork or - * ret_from_kernel_thread: - * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) + * We create a dummy frame to return to ret_from_fork: + * a0 points to ret_from_fork (simulating a call4) * sp points to itself (thread.sp) - * a2, a3 are unused for userspace threads, - * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. + * a2, a3 are unused. * * Note: This is a pristine frame, so we don't need any spill region on top of * childregs. @@ -198,63 +185,43 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) * involved. Much simpler to just not copy those live frames across. */ -int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, - unsigned long thread_fn_arg, - struct task_struct *p, struct pt_regs *unused) +int copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long unused, + struct task_struct * p, struct pt_regs * regs) { - struct pt_regs *childregs = task_pt_regs(p); + struct pt_regs *childregs; + unsigned long tos; + int user_mode = user_mode(regs); #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) struct thread_info *ti; #endif + /* Set up new TSS. */ + tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; + if (user_mode) + childregs = (struct pt_regs*)(tos - PT_USER_SIZE); + else + childregs = (struct pt_regs*)tos - 1; + + /* This does not copy all the regs. In a bout of brilliance or madness, + ARs beyond a0-a15 exist past the end of the struct. */ + *childregs = *regs; + /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ *((int*)childregs - 3) = (unsigned long)childregs; *((int*)childregs - 4) = 0; + childregs->areg[2] = 0; + p->set_child_tid = p->clear_child_tid = NULL; + p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); p->thread.sp = (unsigned long)childregs; - if (!(p->flags & PF_KTHREAD)) { - struct pt_regs *regs = current_pt_regs(); - unsigned long usp = usp_thread_fn ? - usp_thread_fn : regs->areg[1]; + if (user_mode(regs)) { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_fork, 0x1); - - /* This does not copy all the regs. - * In a bout of brilliance or madness, - * ARs beyond a0-a15 exist past the end of the struct. - */ - *childregs = *regs; childregs->areg[1] = usp; - childregs->areg[2] = 0; - - /* When sharing memory with the parent thread, the child - usually starts on a pristine stack, so we have to reset - windowbase, windowstart and wmask. - (Note that such a new thread is required to always create - an initial call4 frame) - The exception is vfork, where the new thread continues to - run on the parent's stack until it calls execve. This could - be a call8 or call12, which requires a legal stack frame - of the previous caller for the overflow handlers to work. - (Note that it's always legal to overflow live registers). - In this case, ensure to spill at least the stack pointer - of that frame. */ - if (clone_flags & CLONE_VM) { - /* check that caller window is live and same stack */ - int len = childregs->wmask & ~0xf; - if (regs->areg[1] == usp && len != 0) { - int callinc = (regs->areg[0] >> 30) & 3; - int caller_ars = XCHAL_NUM_AREGS - callinc * 4; - put_user(regs->areg[caller_ars+1], - (unsigned __user*)(usp - 12)); - } - childregs->wmask = 1; - childregs->windowstart = 1; - childregs->windowbase = 0; + childregs->wmask = 1; /* can't share live windows */ } else { int len = childregs->wmask & ~0xf; memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], @@ -263,19 +230,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, // FIXME: we need to set THREADPTR in thread_info... if (clone_flags & CLONE_SETTLS) childregs->areg[2] = childregs->areg[6]; + } else { - p->thread.ra = MAKE_RA_FOR_CALL( - (unsigned long)ret_from_kernel_thread, 1); - - /* pass parameters to ret_from_kernel_thread: - * a2 = thread_fn, a3 = thread_fn arg - */ - *((int *)childregs - 1) = thread_fn_arg; - *((int *)childregs - 2) = usp_thread_fn; - - /* Childregs are only used when we're going to userspace - * in which case start_thread will set them up. - */ + /* In kernel space, we start a new thread with a new stack. */ + childregs->wmask = 1; + childregs->areg[1] = tos; } #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) @@ -371,5 +330,32 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, void __user *child_tid, long a5, struct pt_regs *regs) { + if (!newsp) + newsp = regs->areg[1]; return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } + +/* + * xtensa_execve() executes a new program. + */ + +asmlinkage +long xtensa_execve(const char __user *name, + const char __user *const __user *argv, + const char __user *const __user *envp, + long a3, long a4, long a5, + struct pt_regs *regs) +{ + long error; + struct filename *filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + error = do_execve(filename->name, argv, envp, regs); + putname(filename); +out: + return error; +} + diff --git a/trunk/arch/xtensa/kernel/syscall.c b/trunk/arch/xtensa/kernel/syscall.c index 5702065f472a..a5c01e74d5d5 100644 --- a/trunk/arch/xtensa/kernel/syscall.c +++ b/trunk/arch/xtensa/kernel/syscall.c @@ -32,8 +32,10 @@ typedef void (*syscall_t)(void); syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, +#undef __SYSCALL #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, -#include +#undef __KERNEL_SYSCALLS__ +#include }; asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) @@ -47,8 +49,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) return (long)ret; } -asmlinkage long xtensa_fadvise64_64(int fd, int advice, - unsigned long long offset, unsigned long long len) +asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) { return sys_fadvise64_64(fd, offset, len, advice); } diff --git a/trunk/arch/xtensa/kernel/xtensa_ksyms.c b/trunk/arch/xtensa/kernel/xtensa_ksyms.c index afe058b24e6e..a8b9f1fd1e17 100644 --- a/trunk/arch/xtensa/kernel/xtensa_ksyms.c +++ b/trunk/arch/xtensa/kernel/xtensa_ksyms.c @@ -43,6 +43,7 @@ EXPORT_SYMBOL(__strncpy_user); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/trunk/crypto/cryptd.c b/trunk/crypto/cryptd.c index 7bdd61b867c8..671d4d6d14df 100644 --- a/trunk/crypto/cryptd.c +++ b/trunk/crypto/cryptd.c @@ -137,18 +137,13 @@ static void cryptd_queue_worker(struct work_struct *work) struct crypto_async_request *req, *backlog; cpu_queue = container_of(work, struct cryptd_cpu_queue, work); - /* - * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. - */ - local_bh_disable(); + /* Only handle one request at a time to avoid hogging crypto + * workqueue. preempt_disable/enable is used to prevent + * being preempted by cryptd_enqueue_request() */ preempt_disable(); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); preempt_enable(); - local_bh_enable(); if (!req) return; diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 0230cb6cbb3a..f94d4c818fc7 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -1345,15 +1345,12 @@ static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { - int status = 0; + int status; struct acpi_device *dev; - /* - * There are systems where video module known to work fine regardless - * of broken _DOD and ignoring returned value here doesn't cause - * any issues later. - */ - acpi_video_device_enumerate(video); + status = acpi_video_device_enumerate(video); + if (status) + return status; list_for_each_entry(dev, &device->children, node) { diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 72c776f2a1f5..8727e9c5eea4 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -83,16 +83,9 @@ EXPORT_SYMBOL_GPL(platform_get_resource); */ int platform_get_irq(struct platform_device *dev, unsigned int num) { -#ifdef CONFIG_SPARC - /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ - if (!dev || num >= dev->archdata.num_irqs) - return -ENXIO; - return dev->archdata.irqs[num]; -#else struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); return r ? r->start : -ENXIO; -#endif } EXPORT_SYMBOL_GPL(platform_get_irq); diff --git a/trunk/drivers/clk/ux500/u8500_clk.c b/trunk/drivers/clk/ux500/u8500_clk.c index e2c17d187d98..ca4a25ed844c 100644 --- a/trunk/drivers/clk/ux500/u8500_clk.c +++ b/trunk/drivers/clk/ux500/u8500_clk.c @@ -40,7 +40,7 @@ void u8500_clk_init(void) CLK_IS_ROOT|CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); + clk_register_clkdev(clk, NULL, "rtc-pl031"); /* PRCMU clocks */ fw_version = prcmu_get_fw_version(); @@ -228,17 +228,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); - clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "msp0"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); - clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, BIT(4), 0); - clk_register_clkdev(clk, "apb_pclk", "msp1"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, BIT(5), 0); @@ -246,7 +239,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -254,7 +246,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, BIT(8), 0); - clk_register_clkdev(clk, "apb_pclk", "slimbus0"); clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, BIT(9), 0); @@ -264,16 +255,11 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); - clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); - clk_register_clkdev(clk, "apb_pclk", "msp3"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -293,13 +279,12 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, BIT(5), 0); - clk_register_clkdev(clk, "apb_pclk", "msp2"); - clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); + clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -331,15 +316,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp0"); - clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); - clk_register_clkdev(clk, "apb_pclk", "ssp1"); - clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); - clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -421,17 +401,10 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.1"); - clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp0"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); - clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp1"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); @@ -439,25 +412,17 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.2"); - clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "slimbus0"); - + U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); + /* FIXME: Redefinition of BIT(3). */ clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.4"); - clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp3"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -465,8 +430,6 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "msp2"); - clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); @@ -487,15 +450,10 @@ void u8500_clk_init(void) /* Periph3 */ clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp0"); - clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "ssp1"); - clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); - clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); diff --git a/trunk/drivers/cpufreq/powernow-k8.c b/trunk/drivers/cpufreq/powernow-k8.c index e3ebb4fa2c3e..c16a3a593ba4 100644 --- a/trunk/drivers/cpufreq/powernow-k8.c +++ b/trunk/drivers/cpufreq/powernow-k8.c @@ -5,7 +5,7 @@ * http://www.gnu.org/licenses/gpl.html * * Maintainer: - * Andreas Herrmann + * Andreas Herrmann * * Based on the powernow-k7.c module written by Dave Jones. * (C) 2003 Dave Jones on behalf of SuSE Labs diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index f11d8e3b4041..d055cee36942 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -47,7 +47,7 @@ if GPIOLIB config OF_GPIO def_bool y - depends on OF + depends on OF && !SPARC config DEBUG_GPIO bool "Debug GPIO calls" diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 133b4132983e..7ef1b673e1be 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -121,8 +121,6 @@ int drm_open(struct inode *inode, struct file *filp) int minor_id = iminor(inode); struct drm_minor *minor; int retcode = 0; - int need_setup = 0; - struct address_space *old_mapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -134,37 +132,23 @@ int drm_open(struct inode *inode, struct file *filp) if (drm_device_is_unplugged(dev)) return -ENODEV; - if (!dev->open_count++) - need_setup = 1; - mutex_lock(&dev->struct_mutex); - old_mapping = dev->dev_mapping; - if (old_mapping == NULL) - dev->dev_mapping = &inode->i_data; - /* ihold ensures nobody can remove inode with our i_data */ - ihold(container_of(dev->dev_mapping, struct inode, i_data)); - inode->i_mapping = dev->dev_mapping; - filp->f_mapping = dev->dev_mapping; - mutex_unlock(&dev->struct_mutex); - retcode = drm_open_helper(inode, filp, dev); - if (retcode) - goto err_undo; - atomic_inc(&dev->counts[_DRM_STAT_OPENS]); - if (need_setup) { - retcode = drm_setup(dev); - if (retcode) - goto err_undo; + if (!retcode) { + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); + if (!dev->open_count++) + retcode = drm_setup(dev); + } + if (!retcode) { + mutex_lock(&dev->struct_mutex); + if (dev->dev_mapping == NULL) + dev->dev_mapping = &inode->i_data; + /* ihold ensures nobody can remove inode with our i_data */ + ihold(container_of(dev->dev_mapping, struct inode, i_data)); + inode->i_mapping = dev->dev_mapping; + filp->f_mapping = dev->dev_mapping; + mutex_unlock(&dev->struct_mutex); } - return 0; -err_undo: - mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_mapping; - inode->i_mapping = old_mapping; - iput(container_of(dev->dev_mapping, struct inode, i_data)); - dev->dev_mapping = old_mapping; - mutex_unlock(&dev->struct_mutex); - dev->open_count--; return retcode; } EXPORT_SYMBOL(drm_open); diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index fc345d4ebb03..59a26e577b57 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -1,6 +1,6 @@ config DRM_EXYNOS tristate "DRM Support for Samsung SoC EXYNOS Series" - depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) + depends on DRM && PLAT_SAMSUNG select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c index 0f68a2872673..18c271862ca8 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -374,7 +374,6 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, exynos_connector->encoder_id = encoder->base.id; exynos_connector->manager = manager; exynos_connector->dpms = DRM_MODE_DPMS_OFF; - connector->dpms = DRM_MODE_DPMS_OFF; connector->encoder = encoder; err = drm_mode_connector_attach_encoder(connector, encoder); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 241ad1eeec64..e51503fbaf2b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -43,14 +43,12 @@ * @manager: specific encoder has its own manager to control a hardware * appropriately and we can access a hardware drawing on this manager. * @dpms: store the encoder dpms value. - * @updated: indicate whether overlay data updating is needed or not. */ struct exynos_drm_encoder { struct drm_crtc *old_crtc; struct drm_encoder drm_encoder; struct exynos_drm_manager *manager; - int dpms; - bool updated; + int dpms; }; static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) @@ -87,9 +85,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: if (manager_ops && manager_ops->apply) - if (!exynos_encoder->updated) - manager_ops->apply(manager->dev); - + manager_ops->apply(manager->dev); exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; break; @@ -98,7 +94,6 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_OFF: exynos_drm_connector_power(encoder, mode); exynos_encoder->dpms = mode; - exynos_encoder->updated = false; break; default: DRM_ERROR("unspecified mode %d\n", mode); @@ -210,22 +205,13 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) static void exynos_drm_encoder_commit(struct drm_encoder *encoder) { - struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); - struct exynos_drm_manager *manager = exynos_encoder->manager; + struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); struct exynos_drm_manager_ops *manager_ops = manager->ops; DRM_DEBUG_KMS("%s\n", __FILE__); if (manager_ops && manager_ops->commit) manager_ops->commit(manager->dev); - - /* - * this will avoid one issue that overlay data is updated to - * real hardware two times. - * And this variable will be used to check if the data was - * already updated or not by exynos_drm_encoder_dpms function. - */ - exynos_encoder->updated = true; } static void exynos_drm_encoder_disable(struct drm_encoder *encoder) @@ -414,6 +400,19 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) if (manager_ops && manager_ops->dpms) manager_ops->dpms(manager->dev, mode); + /* + * set current mode to new one so that data aren't updated into + * registers by drm_helper_connector_dpms two times. + * + * in case that drm_crtc_helper_set_mode() is called, + * overlay_ops->commit() and manager_ops->commit() callbacks + * can be called two times, first at drm_crtc_helper_set_mode() + * and second at drm_helper_connector_dpms(). + * so with this setting, when drm_helper_connector_dpms() is called + * encoder->funcs->dpms() will be ignored. + */ + exynos_encoder->dpms = mode; + /* * if this condition is ok then it means that the crtc is already * detached from encoder and last function for detaching is properly diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e7fbb823fd8e..614b2e9ac462 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) const struct of_device_id *match; match = of_match_node(of_match_ptr(mixer_match_types), pdev->dev.of_node); - drv = (struct mixer_drv_data *)match->data; + drv = match->data; } else { drv = (struct mixer_drv_data *) platform_get_device_id(pdev)->driver_data; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 61ae104dca8c..c9bfd83dde64 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1505,8 +1505,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_gmch; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kick_out_firmware_fb(dev_priv); + i915_kick_out_firmware_fb(dev_priv); pci_set_master(dev->pdev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index b726b478a4f5..f78061af7045 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) crt->base.type = INTEL_OUTPUT_ANALOG; crt->base.cloneable = true; - if (IS_HASWELL(dev) || IS_I830(dev)) + if (IS_HASWELL(dev)) crt->base.crtc_mask = (1 << 0); else crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); diff --git a/trunk/drivers/gpu/drm/i915/intel_overlay.c b/trunk/drivers/gpu/drm/i915/intel_overlay.c index d7bc817f51a0..495625914e4a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_overlay.c +++ b/trunk/drivers/gpu/drm/i915/intel_overlay.c @@ -341,17 +341,9 @@ static int intel_overlay_off(struct intel_overlay *overlay) intel_ring_emit(ring, flip_addr); intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); /* turn overlay off */ - if (IS_I830(dev)) { - /* Workaround: Don't disable the overlay fully, since otherwise - * it dies on the next OVERLAY_ON cmd. */ - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_NOOP); - } else { - intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); - intel_ring_emit(ring, flip_addr); - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); - } + intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); + intel_ring_emit(ring, flip_addr); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); intel_ring_advance(ring); return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index e2aacd329545..e019b2369861 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) props.type = BACKLIGHT_RAW; props.max_brightness = _intel_panel_get_max_backlight(dev); if (props.max_brightness == 0) { - DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); + DRM_ERROR("Failed to get maximum backlight value\n"); return -ENODEV; } dev_priv->backlight = diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 79d308da29ff..c01d97db0061 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -894,45 +894,6 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) } #endif -static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, - unsigned if_index, uint8_t tx_rate, - uint8_t *data, unsigned length) -{ - uint8_t set_buf_index[2] = { if_index, 0 }; - uint8_t hbuf_size, tmp[8]; - int i; - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2)) - return false; - - if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, - &hbuf_size, 1)) - return false; - - /* Buffer size is 0 based, hooray! */ - hbuf_size++; - - DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", - if_index, length, hbuf_size); - - for (i = 0; i < hbuf_size; i += 8) { - memset(tmp, 0, 8); - if (i < length) - memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); - - if (!intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_DATA, - tmp, 8)) - return false; - } - - return intel_sdvo_set_value(intel_sdvo, - SDVO_CMD_SET_HBUF_TXRATE, - &tx_rate, 1); -} - static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) { struct dip_infoframe avi_if = { @@ -940,7 +901,11 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) .ver = DIP_VERSION_AVI, .len = DIP_LEN_AVI, }; + uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; + uint8_t set_buf_index[2] = { 1, 0 }; uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; + uint64_t *data = (uint64_t *)sdvo_data; + unsigned i; intel_dip_infoframe_csum(&avi_if); @@ -950,9 +915,22 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) sdvo_data[3] = avi_if.checksum; memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); - return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, - SDVO_HBUF_TX_VSYNC, - sdvo_data, sizeof(sdvo_data)); + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2)) + return false; + + for (i = 0; i < sizeof(sdvo_data); i += 8) { + if (!intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_DATA, + data, 8)) + return false; + data++; + } + + return intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_HBUF_TXRATE, + &tx_rate, 1); } static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h index 770bdd6ecd9f..9d030142ee43 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo_regs.h @@ -708,8 +708,6 @@ struct intel_sdvo_enhancements_arg { #define SDVO_CMD_SET_AUDIO_STAT 0x91 #define SDVO_CMD_GET_AUDIO_STAT 0x92 #define SDVO_CMD_SET_HBUF_INDEX 0x93 - #define SDVO_HBUF_INDEX_ELD 0 - #define SDVO_HBUF_INDEX_AVI_IF 1 #define SDVO_CMD_GET_HBUF_INDEX 0x94 #define SDVO_CMD_GET_HBUF_INFO 0x95 #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 05a909a17cee..16a9afb1060b 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -22,8 +22,6 @@ * Authors: Ben Skeggs */ -#include - #include #include @@ -39,7 +37,6 @@ nv50_disp_sclass[] = { static void nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) { - struct nouveau_bar *bar = nouveau_bar(priv); struct nouveau_disp *disp = &priv->base; struct nouveau_software_chan *chan, *temp; unsigned long flags; @@ -49,19 +46,18 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) if (chan->vblank.crtc != crtc) continue; + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); nv_wr32(priv, 0x001570, chan->vblank.offset); nv_wr32(priv, 0x001574, chan->vblank.value); } else { - nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); - bar->flush(bar); - nv_wr32(priv, 0x06000c, - upper_32_bits(chan->vblank.offset)); - nv_wr32(priv, 0x060010, - lower_32_bits(chan->vblank.offset)); + if (nv_device(priv)->chipset >= 0xc0) { + nv_wr32(priv, 0x06000c, + upper_32_bits(chan->vblank.offset)); + } + nv_wr32(priv, 0x060010, chan->vblank.offset); nv_wr32(priv, 0x060014, chan->vblank.value); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 425001204a89..8d0021049ec0 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, static int nv40_graph_context_fini(struct nouveau_object *object, bool suspend) { - struct nv40_graph_priv *priv = (void *)object->engine; - struct nv40_graph_chan *chan = (void *)object; + struct nv04_graph_priv *priv = (void *)object->engine; + struct nv04_graph_chan *chan = (void *)object; u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; int ret = 0; diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index f7c581ad1991..12418574efea 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { }; struct nv40_mpeg_chan { - struct nouveau_mpeg_chan base; + struct nouveau_mpeg base; }; /******************************************************************************* diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 9474cfca6e4c..49050d991e75 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) static void nv41_vm_flush(struct nouveau_vm *vm) { - struct nv04_vmmgr_priv *priv = (void *)vm->vmm; + struct nv04_vm_priv *priv = (void *)vm->vmm; mutex_lock(&nv_subdev(priv)->mutex); nv_wr32(priv, 0x100810, 0x00000022); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index d3595b23434a..9a6e2cb282dc 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) * valid - it's not (rh#613284) */ if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { - if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { + if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { status = connector_status_connected; goto out; } diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 3bce0299f64a..2e566e123e9e 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1696,43 +1696,35 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) return ATOM_PPLL2; DRM_ERROR("unable to allocate a PPLL\n"); return ATOM_PPLL_INVALID; - } else if (ASIC_IS_AVIVO(rdev)) { - /* in DP mode, the DP ref clock can come from either PPLL - * depending on the asic: - * DCE3: PPLL1 or PPLL2 - */ - if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { - /* use the same PPLL for all DP monitors */ - pll = radeon_get_shared_dp_ppll(crtc); - if (pll != ATOM_PPLL_INVALID) - return pll; - } else { - /* use the same PPLL for all monitors with the same clock */ - pll = radeon_get_shared_nondp_ppll(crtc); - if (pll != ATOM_PPLL_INVALID) - return pll; - } - /* all other cases */ - pll_in_use = radeon_get_pll_use_mask(crtc); - /* the order shouldn't matter here, but we probably - * need this until we have atomic modeset - */ - if (rdev->flags & RADEON_IS_IGP) { + } else { + if (ASIC_IS_AVIVO(rdev)) { + /* in DP mode, the DP ref clock can come from either PPLL + * depending on the asic: + * DCE3: PPLL1 or PPLL2 + */ + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { + /* use the same PPLL for all DP monitors */ + pll = radeon_get_shared_dp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } else { + /* use the same PPLL for all monitors with the same clock */ + pll = radeon_get_shared_nondp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) + return pll; + } + /* all other cases */ + pll_in_use = radeon_get_pll_use_mask(crtc); if (!(pll_in_use & (1 << ATOM_PPLL1))) return ATOM_PPLL1; if (!(pll_in_use & (1 << ATOM_PPLL2))) return ATOM_PPLL2; + DRM_ERROR("unable to allocate a PPLL\n"); + return ATOM_PPLL_INVALID; } else { - if (!(pll_in_use & (1 << ATOM_PPLL2))) - return ATOM_PPLL2; - if (!(pll_in_use & (1 << ATOM_PPLL1))) - return ATOM_PPLL1; + /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ + return radeon_crtc->crtc_id; } - DRM_ERROR("unable to allocate a PPLL\n"); - return ATOM_PPLL_INVALID; - } else { - /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ - return radeon_crtc->crtc_id; } } diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index af31f829f4a8..14313ad43b76 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1372,7 +1372,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); for (i = 0; i < rdev->num_crtc; i++) { - if (save->crtc_enabled[i]) { + if (save->crtc_enabled) { if (ASIC_IS_DCE6(rdev)) { tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index c042e497e450..30271b641913 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, /* macro tile width & height */ palign = (8 * surf->bankw * track->npipes) * surf->mtilea; halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; - mtileb = (palign / 8) * (halign / 8) * tileb; + mtileb = (palign / 8) * (halign / 8) * tileb;; mtile_pr = surf->nbx / palign; mtile_ps = (mtile_pr * surf->nby) / halign; surf->layer_size = mtile_ps * mtileb * slice_pt; @@ -2725,9 +2725,6 @@ static bool evergreen_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: - case CP_COHER_CNTL: - case CP_COHER_SIZE: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_GS_VERTEX_REUSE: diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 2bc0f6a1b428..df542f1a5dfb 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -91,10 +91,6 @@ #define FB_READ_EN (1 << 0) #define FB_WRITE_EN (1 << 1) -#define CP_STRMOUT_CNTL 0x84FC - -#define CP_COHER_CNTL 0x85F0 -#define CP_COHER_SIZE 0x85F4 #define CP_COHER_BASE 0x85F8 #define CP_STALLED_STAT1 0x8674 #define CP_STALLED_STAT2 0x8678 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 15f5ded65e0c..37f6a907aea4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) } /** - * radeon_atpx_power_state - power down/up the requested GPU + * radeon_atpx_switchto - switch to the requested GPU * - * @id: GPU to power down/up + * @id: GPU to switch to * @state: requested power state (0 = off, 1 = on) * * Execute the necessary ATPX function to power down/up the discrete GPU diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index b884c362a8c2..67cfc1795ecd 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) struct drm_mode_object *obj; int i; enum drm_connector_status ret = connector_status_disconnected; - bool dret = false, broken_edid = false; + bool dret = false; if (!force && radeon_check_hpd_status_unchanged(connector)) return connector->status; @@ -965,9 +965,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); radeon_connector->ddc_bus = NULL; - } else { - ret = connector_status_connected; - broken_edid = true; /* defer use_digital to later */ } } else { radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); @@ -1050,24 +1047,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder_funcs = encoder->helper_private; if (encoder_funcs->detect) { - if (!broken_edid) { - if (ret != connector_status_connected) { - /* deal with analog monitors without DDC */ - ret = encoder_funcs->detect(encoder, connector); - if (ret == connector_status_connected) { - radeon_connector->use_digital = false; - } - if (ret != connector_status_disconnected) - radeon_connector->detected_by_load = true; - } - } else { - enum drm_connector_status lret; - /* assume digital unless load detected otherwise */ - radeon_connector->use_digital = true; - lret = encoder_funcs->detect(encoder, connector); - DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); - if (lret == connector_status_connected) + if (ret != connector_status_connected) { + ret = encoder_funcs->detect(encoder, connector); + if (ret == connector_status_connected) { radeon_connector->use_digital = false; + } + if (ret != connector_status_disconnected) + radeon_connector->detected_by_load = true; } break; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 6857cb4efb76..5677a424b585 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -295,7 +295,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc_ext_cntl = 0; uint32_t mask; if (radeon_crtc->crtc_id) @@ -308,16 +307,6 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS); - /* - * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. - * Therefore it is set in the DAC DMPS function. - * This is different for GPU's with a single CRTC but a primary and a - * TV DAC: here it controls the single CRTC no matter where it is - * routed. Therefore we set it here. - */ - if (rdev->flags & RADEON_SINGLE_CRTC) - crtc_ext_cntl = RADEON_CRTC_CRT_ON; - switch (mode) { case DRM_MODE_DPMS_ON: radeon_crtc->enabled = true; @@ -328,7 +317,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); } drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); radeon_crtc_load_lut(crtc); @@ -342,7 +331,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) else { WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | RADEON_CRTC_DISP_REQ_EN_B)); - WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); } radeon_crtc->enabled = false; /* adjust pm to dpms changes AFTER disabling crtcs */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index f5ba2241dacc..0063df9d166d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -537,9 +537,7 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode break; } - /* handled in radeon_crtc_dpms() */ - if (!(rdev->flags & RADEON_SINGLE_CRTC)) - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); WREG32(RADEON_DAC_CNTL, dac_cntl); WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); @@ -664,8 +662,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc if (ASIC_IS_R300(rdev)) tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); - else if (ASIC_IS_RV100(rdev)) - tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); else tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); @@ -675,7 +671,6 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; WREG32(RADEON_DAC_CNTL, tmp); - tmp = dac_macro_cntl; tmp &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); @@ -1097,8 +1092,7 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) } else { if (is_tv) WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); - /* handled in radeon_crtc_dpms() */ - else if (!(rdev->flags & RADEON_SINGLE_CRTC)) + else WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); } @@ -1422,104 +1416,13 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, return found; } -static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; - uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; - uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; - uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; - uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; - bool found = false; - int i; - - /* save the regs we need */ - gpio_monid = RREG32(RADEON_GPIO_MONID); - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); - disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); - disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); - disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); - disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); - disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); - crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); - crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); - crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); - crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); - - tmp = RREG32(RADEON_GPIO_MONID); - tmp &= ~RADEON_GPIO_A_0; - WREG32(RADEON_GPIO_MONID, tmp); - - WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | - RADEON_FP2_PANEL_FORMAT | - R200_FP2_SOURCE_SEL_TRANS_UNIT | - RADEON_FP2_DVO_EN | - R200_FP2_DVO_RATE_SEL_SDR)); - - WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | - RADEON_DISP_TRANS_MATRIX_GRAPHICS)); - - WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | - RADEON_CRTC2_DISP_REQ_EN_B)); - - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); - - WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); - - for (i = 0; i < 200; i++) { - tmp = RREG32(RADEON_GPIO_MONID); - if (tmp & RADEON_GPIO_Y_0) - found = true; - - if (found) - break; - - if (!drm_can_sleep()) - mdelay(1); - else - msleep(1); - } - - /* restore the regs we used */ - WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); - WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); - WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); - WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); - WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); - WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - WREG32(RADEON_GPIO_MONID, gpio_monid); - - return found; -} - static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; - uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t gpiopad_a = 0, pixclks_cntl, tmp; - uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; + uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; + uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; enum drm_connector_status found = connector_status_disconnected; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; @@ -1556,27 +1459,12 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder return connector_status_disconnected; } - /* R200 uses an external DAC for secondary DAC */ - if (rdev->family == CHIP_R200) { - if (radeon_legacy_ext_dac_detect(encoder, connector)) - found = connector_status_connected; - return found; - } - /* save the regs we need */ pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); - - if (rdev->flags & RADEON_SINGLE_CRTC) { - crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); - } else { - if (ASIC_IS_R300(rdev)) { - gpiopad_a = RREG32(RADEON_GPIOPAD_A); - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); - } else { - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - } - crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - } + gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; + disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; + disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); dac_cntl2 = RREG32(RADEON_DAC_CNTL2); @@ -1585,24 +1473,22 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder | RADEON_PIX2CLK_DAC_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - if (rdev->flags & RADEON_SINGLE_CRTC) { - tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; - WREG32(RADEON_CRTC_EXT_CNTL, tmp); - } else { - tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; - tmp |= RADEON_CRTC2_CRT2_ON | - (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); - WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + if (ASIC_IS_R300(rdev)) + WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - if (ASIC_IS_R300(rdev)) { - WREG32_P(RADEON_GPIOPAD_A, 1, ~1); - tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; - tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; - WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); - } else { - tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; - WREG32(RADEON_DISP_HW_DEBUG, tmp); - } + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; + tmp |= RADEON_CRTC2_CRT2_ON | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); + + WREG32(RADEON_CRTC2_GEN_CNTL, tmp); + + if (ASIC_IS_R300(rdev)) { + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; + WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); + } else { + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; + WREG32(RADEON_DISP_HW_DEBUG, tmp); } tmp = RADEON_TV_DAC_NBLANK | @@ -1644,19 +1530,14 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder WREG32(RADEON_DAC_CNTL2, dac_cntl2); WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (rdev->flags & RADEON_SINGLE_CRTC) { - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + if (ASIC_IS_R300(rdev)) { + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); + WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); } else { - WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - if (ASIC_IS_R300(rdev)) { - WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); - } else { - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - } + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); } - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); return found; diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 4422d630b33b..b0db712060fb 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2474,7 +2474,6 @@ static bool si_vm_reg_valid(u32 reg) /* check config regs */ switch (reg) { case GRBM_GFX_INDEX: - case CP_STRMOUT_CNTL: case VGT_VTX_VECT_EJECT_REG: case VGT_CACHE_INVALIDATION: case VGT_ESGS_RING_SIZE: diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index a8871afc5b4e..7d2a20e56577 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -424,7 +424,6 @@ # define RDERR_INT_ENABLE (1 << 0) # define GUI_IDLE_INT_ENABLE (1 << 19) -#define CP_STRMOUT_CNTL 0x84FC #define SCRATCH_REG0 0x8500 #define SCRATCH_REG1 0x8504 #define SCRATCH_REG2 0x8508 diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.h b/trunk/drivers/gpu/drm/udl/udl_drv.h index 87aa5f5d3c88..fccd361f7b50 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.h +++ b/trunk/drivers/gpu/drm/udl/udl_drv.h @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr); int udl_dumb_create(struct drm_file *file_priv, diff --git a/trunk/drivers/gpu/drm/udl/udl_fb.c b/trunk/drivers/gpu/drm/udl/udl_fb.c index d4ab3beaada0..69a2b16f42a6 100644 --- a/trunk/drivers/gpu/drm/udl/udl_fb.c +++ b/trunk/drivers/gpu/drm/udl/udl_fb.c @@ -114,10 +114,9 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, list_for_each_entry(cur, &fbdefio->pagelist, lru) { if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), - &urb, (char *) info->fix.smem_start, - &cmd, cur->index << PAGE_SHIFT, - cur->index << PAGE_SHIFT, - PAGE_SIZE, &bytes_identical, &bytes_sent)) + &urb, (char *) info->fix.smem_start, + &cmd, cur->index << PAGE_SHIFT, + PAGE_SIZE, &bytes_identical, &bytes_sent)) goto error; bytes_rendered += PAGE_SIZE; } @@ -188,11 +187,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, for (i = y; i < y + height ; i++) { const int line_offset = fb->base.pitches[0] * i; const int byte_offset = line_offset + (x * bpp); - const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); + if (udl_render_hline(dev, bpp, &urb, (char *) fb->obj->vmapping, - &cmd, byte_offset, dev_byte_offset, - width * bpp, + &cmd, byte_offset, width * bpp, &bytes_identical, &bytes_sent)) goto error; } diff --git a/trunk/drivers/gpu/drm/udl/udl_transfer.c b/trunk/drivers/gpu/drm/udl/udl_transfer.c index 142fee5f983f..dc095526ffb7 100644 --- a/trunk/drivers/gpu/drm/udl/udl_transfer.c +++ b/trunk/drivers/gpu/drm/udl/udl_transfer.c @@ -213,12 +213,11 @@ static void udl_compress_hline16( */ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, - u32 byte_width, + u32 byte_offset, u32 byte_width, int *ident_ptr, int *sent_ptr) { const u8 *line_start, *line_end, *next_pixel; - u32 base16 = 0 + (device_byte_offset / bpp) * 2; + u32 base16 = 0 + (byte_offset / bpp) * 2; struct urb *urb = *urb_ptr; u8 *cmd = *urb_buf_ptr; u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c index d1498bfd7873..3ce68a2e312d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) BUG_ON(!atomic_read(&bo->reserved)); BUG_ON(old_mem_type != TTM_PL_VRAM && - old_mem_type != VMW_PL_GMR); + old_mem_type != VMW_PL_FLAG_GMR); pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; if (pin) diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 2dd185e42f21..ed3c1e7ddde9 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1098,11 +1098,6 @@ static void vmw_pm_complete(struct device *kdev) struct drm_device *dev = pci_get_drvdata(pdev); struct vmw_private *dev_priv = vmw_priv(dev); - mutex_lock(&dev_priv->hw_mutex); - vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); - (void) vmw_read(dev_priv, SVGA_REG_ID); - mutex_unlock(&dev_priv->hw_mutex); - /** * Reclaim 3d reference held by fbdev and potentially * start fifo. diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 7c47fc3f7b2b..17d15bb610d1 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -42,6 +42,7 @@ static struct cdev hidraw_cdev; static struct class *hidraw_class; static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; static DEFINE_MUTEX(minors_lock); +static void drop_ref(struct hidraw *hid, int exists_bit); static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { @@ -113,7 +114,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, __u8 *buf; int ret = 0; - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { ret = -ENODEV; goto out; } @@ -261,7 +262,7 @@ static int hidraw_open(struct inode *inode, struct file *file) } mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { + if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { err = -ENODEV; goto out_unlock; } @@ -298,36 +299,12 @@ static int hidraw_open(struct inode *inode, struct file *file) static int hidraw_release(struct inode * inode, struct file * file) { unsigned int minor = iminor(inode); - struct hidraw *dev; struct hidraw_list *list = file->private_data; - int ret; - int i; - - mutex_lock(&minors_lock); - if (!hidraw_table[minor]) { - ret = -ENODEV; - goto unlock; - } + drop_ref(hidraw_table[minor], 0); list_del(&list->node); - dev = hidraw_table[minor]; - if (!--dev->open) { - if (list->hidraw->exist) { - hid_hw_power(dev->hid, PM_HINT_NORMAL); - hid_hw_close(dev->hid); - } else { - kfree(list->hidraw); - } - } - - for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) - kfree(list->buffer[i].value); kfree(list); - ret = 0; -unlock: - mutex_unlock(&minors_lock); - - return ret; + return 0; } static long hidraw_ioctl(struct file *file, unsigned int cmd, @@ -529,21 +506,7 @@ EXPORT_SYMBOL_GPL(hidraw_connect); void hidraw_disconnect(struct hid_device *hid) { struct hidraw *hidraw = hid->hidraw; - - mutex_lock(&minors_lock); - hidraw->exist = 0; - - device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); - - hidraw_table[hidraw->minor] = NULL; - - if (hidraw->open) { - hid_hw_close(hid); - wake_up_interruptible(&hidraw->wait); - } else { - kfree(hidraw); - } - mutex_unlock(&minors_lock); + drop_ref(hidraw, 1); } EXPORT_SYMBOL_GPL(hidraw_disconnect); @@ -592,3 +555,23 @@ void hidraw_exit(void) unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); } + +static void drop_ref(struct hidraw *hidraw, int exists_bit) +{ + mutex_lock(&minors_lock); + if (exists_bit) { + hid_hw_close(hidraw->hid); + hidraw->exist = 0; + if (hidraw->open) + wake_up_interruptible(&hidraw->wait); + } else { + --hidraw->open; + } + + if (!hidraw->open && !hidraw->exist) { + device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); + hidraw_table[hidraw->minor] = NULL; + kfree(hidraw); + } + mutex_unlock(&minors_lock); +} diff --git a/trunk/drivers/hwmon/asb100.c b/trunk/drivers/hwmon/asb100.c index 520e5bf4f76d..a227be47149f 100644 --- a/trunk/drivers/hwmon/asb100.c +++ b/trunk/drivers/hwmon/asb100.c @@ -32,7 +32,7 @@ * ASB100-A supports pwm1, while plain ASB100 does not. There is no known * way for the driver to tell which one is there. * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * asb100 7 3 1 4 0x31 0x0694 yes no */ diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index 4f4110407387..68ad7d255512 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -2,7 +2,7 @@ * fam15h_power.c - AMD Family 15h processor power monitoring * * Copyright (c) 2011 Advanced Micro Devices, Inc. - * Author: Andreas Herrmann + * Author: Andreas Herrmann * * * This driver is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); -MODULE_AUTHOR("Andreas Herrmann "); +MODULE_AUTHOR("Andreas Herrmann "); MODULE_LICENSE("GPL"); /* D18F3 */ diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index 1381a2e3bbd4..36509ae32083 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -630,9 +630,7 @@ static struct platform_driver gpio_fan_driver = { .driver = { .name = "gpio-fan", .pm = GPIO_FAN_PM, -#ifdef CONFIG_OF_GPIO .of_match_table = of_match_ptr(of_gpio_fan_match), -#endif }, }; diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index de3c7e04c3b5..1821b7423d5b 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -2083,7 +2083,6 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) mutex_init(&data->lock); mutex_init(&data->update_lock); data->name = w83627ehf_device_names[sio_data->kind]; - data->bank = 0xff; /* Force initial bank selection */ platform_set_drvdata(pdev, data); /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index af1589908709..5b1a6a666441 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -25,7 +25,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index 20f11d31da40..5a5046d94c3e 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -24,7 +24,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * as99127f 7 3 0 3 0x31 0x12c3 yes no * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index ed397c645198..39ab7bcc616e 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -22,7 +22,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83791d 10 5 5 3 0x71 0x5ca3 yes no * * The w83791d chip appears to be part way between the 83781d and the diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index 301942d08453..053645279f38 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -31,7 +31,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83792d 9 7 7 3 0x7a 0x5ca3 yes no */ diff --git a/trunk/drivers/hwmon/w83l786ng.c b/trunk/drivers/hwmon/w83l786ng.c index 79710bcac2f7..f0e8286c3c70 100644 --- a/trunk/drivers/hwmon/w83l786ng.c +++ b/trunk/drivers/hwmon/w83l786ng.c @@ -20,7 +20,7 @@ /* * Supports following chips: * - * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no */ diff --git a/trunk/drivers/i2c/busses/i2c-mxs.c b/trunk/drivers/i2c/busses/i2c-mxs.c index 286ca1917820..1f58197062cf 100644 --- a/trunk/drivers/i2c/busses/i2c-mxs.c +++ b/trunk/drivers/i2c/busses/i2c-mxs.c @@ -1,7 +1,7 @@ /* * Freescale MXS I2C bus driver * - * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. + * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. * * based on a (non-working) driver which was: * @@ -35,6 +35,10 @@ #define DRIVER_NAME "mxs-i2c" +static bool use_pioqueue; +module_param(use_pioqueue, bool, 0); +MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); + #define MXS_I2C_CTRL0 (0x00) #define MXS_I2C_CTRL0_SET (0x04) @@ -71,6 +75,23 @@ MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ MXS_I2C_CTRL1_SLAVE_IRQ) +#define MXS_I2C_QUEUECTRL (0x60) +#define MXS_I2C_QUEUECTRL_SET (0x64) +#define MXS_I2C_QUEUECTRL_CLR (0x68) + +#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 +#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 + +#define MXS_I2C_QUEUESTAT (0x70) +#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 +#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F + +#define MXS_I2C_QUEUECMD (0x80) + +#define MXS_I2C_QUEUEDATA (0x90) + +#define MXS_I2C_DATA (0xa0) + #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ MXS_I2C_CTRL0_PRE_SEND_START | \ @@ -132,6 +153,7 @@ struct mxs_i2c_dev { const struct mxs_i2c_speed_config *speed; /* DMA support components */ + bool dma_mode; int dma_channel; struct dma_chan *dmach; struct mxs_dma_data dma_data; @@ -150,6 +172,99 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); + if (i2c->dma_mode) + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); + else + writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, + i2c->regs + MXS_I2C_QUEUECTRL_SET); +} + +static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, + int flags) +{ + u32 data; + + writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); + + data = (addr << 1) | I2C_SMBUS_READ; + writel(data, i2c->regs + MXS_I2C_DATA); + + data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); +} + +static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, + u8 addr, u8 *buf, int len, int flags) +{ + u32 data; + int i, shifts_left; + + data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; + writel(data, i2c->regs + MXS_I2C_QUEUECMD); + + /* + * We have to copy the slave address (u8) and buffer (arbitrary number + * of u8) into the data register (u32). To achieve that, the u8 are put + * into the MSBs of 'data' which is then shifted for the next u8. When + * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 + * looks like this: + * + * 3 2 1 0 + * 10987654|32109876|54321098|76543210 + * --------+--------+--------+-------- + * buffer+2|buffer+1|buffer+0|slave_addr + */ + + data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; + + for (i = 0; i < len; i++) { + data >>= 8; + data |= buf[i] << 24; + if ((i & 3) == 2) + writel(data, i2c->regs + MXS_I2C_DATA); + } + + /* Write out the remaining bytes if any */ + shifts_left = 24 - (i & 3) * 8; + if (shifts_left) + writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); +} + +/* + * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the + * rd_threshold to 1). Couldn't get this to work, though. + */ +static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + while (readl(i2c->regs + MXS_I2C_QUEUESTAT) + & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + cond_resched(); + } + + return 0; +} + +static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) +{ + u32 uninitialized_var(data); + int i; + + for (i = 0; i < len; i++) { + if ((i & 3) == 0) { + if (mxs_i2c_wait_for_data(i2c)) + return -ETIMEDOUT; + data = readl(i2c->regs + MXS_I2C_QUEUEDATA); + } + buf[i] = data & 0xff; + data >>= 8; + } + + return 0; } static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) @@ -317,17 +432,39 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, init_completion(&i2c->cmd_complete); i2c->cmd_err = 0; - ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); - if (ret) - return ret; + if (i2c->dma_mode) { + ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); + if (ret) + return ret; + } else { + if (msg->flags & I2C_M_RD) { + mxs_i2c_pioq_setup_read(i2c, msg->addr, + msg->len, flags); + } else { + mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, + msg->len, flags); + } + + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_SET); + } ret = wait_for_completion_timeout(&i2c->cmd_complete, msecs_to_jiffies(1000)); if (ret == 0) goto timeout; + if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { + ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); + if (ret) + goto timeout; + } + if (i2c->cmd_err == -ENXIO) mxs_i2c_reset(i2c); + else + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -335,7 +472,8 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, timeout: dev_dbg(i2c->dev, "Timeout!\n"); - mxs_i2c_dma_finish(i2c); + if (i2c->dma_mode) + mxs_i2c_dma_finish(i2c); mxs_i2c_reset(i2c); return -ETIMEDOUT; } @@ -364,6 +502,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) { struct mxs_i2c_dev *i2c = dev_id; u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; + bool is_last_cmd; if (!stat) return IRQ_NONE; @@ -376,6 +515,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ i2c->cmd_err = -EIO; + if (!i2c->dma_mode) { + is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & + MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; + + if (is_last_cmd || i2c->cmd_err) + complete(&i2c->cmd_complete); + } + writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); return IRQ_HANDLED; @@ -408,6 +555,15 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) struct device_node *node = dev->of_node; int ret; + /* + * The MXS I2C DMA mode is prefered and enabled by default. + * The PIO mode is still supported, but should be used only + * for debuging purposes etc. + */ + i2c->dma_mode = !use_pioqueue; + if (!i2c->dma_mode) + dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); + /* * TODO: This is a temporary solution and should be changed * to use generic DMA binding later when the helpers get in. @@ -415,8 +571,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) ret = of_property_read_u32(node, "fsl,i2c-dma-channel", &i2c->dma_channel); if (ret) { - dev_err(dev, "Failed to get DMA channel!\n"); - return -ENODEV; + dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); + i2c->dma_mode = 0; } ret = of_property_read_u32(node, "clock-frequency", &speed); @@ -478,13 +634,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) } /* Setup the DMA */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - i2c->dma_data.chan_irq = dmairq; - i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); - if (!i2c->dmach) { - dev_err(dev, "Failed to request dma\n"); - return -ENODEV; + if (i2c->dma_mode) { + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + i2c->dma_data.chan_irq = dmairq; + i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); + if (!i2c->dmach) { + dev_err(dev, "Failed to request dma\n"); + return -ENODEV; + } } platform_set_drvdata(pdev, i2c); diff --git a/trunk/drivers/i2c/busses/i2c-nomadik.c b/trunk/drivers/i2c/busses/i2c-nomadik.c index 02c3115a2dfa..698d7acb0f08 100644 --- a/trunk/drivers/i2c/busses/i2c-nomadik.c +++ b/trunk/drivers/i2c/busses/i2c-nomadik.c @@ -644,11 +644,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, pm_runtime_get_sync(&dev->adev->dev); - status = clk_prepare_enable(dev->clk); - if (status) { - dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); - goto out_clk; - } + clk_enable(dev->clk); status = init_hw(dev); if (status) @@ -675,8 +671,7 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, } out: - clk_disable_unprepare(dev->clk); -out_clk: + clk_disable(dev->clk); pm_runtime_put_sync(&dev->adev->dev); dev->busy = false; diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index dcea77bf6f50..f981ac4e6783 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) } ret = devm_request_irq(&pdev->dev, i2c_dev->irq, - tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); + tegra_i2c_isr, 0, pdev->name, i2c_dev); if (ret) { dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); return ret; diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index de0874054e9f..b4b65af8612a 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -335,7 +335,6 @@ config KEYBOARD_LOCOMO config KEYBOARD_LPC32XX tristate "LPC32XX matrix key scanner support" depends on ARCH_LPC32XX && OF - select INPUT_MATRIXKMAP help Say Y here if you want to use NXP LPC32XX SoC key scanner interface, connected to a key matrix. diff --git a/trunk/drivers/input/keyboard/pxa27x_keypad.c b/trunk/drivers/input/keyboard/pxa27x_keypad.c index cad9d5dd5973..803ff6fe021e 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keypad.c +++ b/trunk/drivers/input/keyboard/pxa27x_keypad.c @@ -368,9 +368,6 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) unsigned int mask = 0, direct_key_num = 0; unsigned long kpc = 0; - /* clear pending interrupt bit */ - keypad_readl(KPC); - /* enable matrix keys with automatic scan */ if (pdata->matrix_key_rows && pdata->matrix_key_cols) { kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; diff --git a/trunk/drivers/input/misc/xen-kbdfront.c b/trunk/drivers/input/misc/xen-kbdfront.c index 6f7d99013031..02ca8680ea5b 100644 --- a/trunk/drivers/input/misc/xen-kbdfront.c +++ b/trunk/drivers/input/misc/xen-kbdfront.c @@ -311,6 +311,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -349,10 +350,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index 858ad446de91..2c1e12bf2ab4 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf, features->pktlen = WACOM_PKGLEN_TPC2FG; } - if (features->type == MTSCREEN || features->type == WACOM_24HDT) + if (features->type == MTSCREEN || WACOM_24HDT) features->pktlen = WACOM_PKGLEN_MTOUCH; if (features->type == BAMBOO_PT) { diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 0a67031ffc13..aa6010131179 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -1518,9 +1518,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - wacom_setup_cintiq(wacom_wac); break; diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index f7668b24c378..1ba232cbc09d 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI config TOUCHSCREEN_EGALAX tristate "EETI eGalax multi-touch panel support" - depends on I2C && OF + depends on I2C help Say Y here to enable support for I2C connected EETI eGalax multi-touch panels. diff --git a/trunk/drivers/input/touchscreen/egalax_ts.c b/trunk/drivers/input/touchscreen/egalax_ts.c index 13fa62fdfb0b..c1e3460f1195 100644 --- a/trunk/drivers/input/touchscreen/egalax_ts.c +++ b/trunk/drivers/input/touchscreen/egalax_ts.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * Mouse Mode: some panel may configure the controller to mouse mode, @@ -123,17 +122,9 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) /* wake up controller by an falling edge of interrupt gpio. */ static int egalax_wake_up_device(struct i2c_client *client) { - struct device_node *np = client->dev.of_node; - int gpio; + int gpio = irq_to_gpio(client->irq); int ret; - if (!np) - return -ENODEV; - - gpio = of_get_named_gpio(np, "wakeup-gpios", 0); - if (!gpio_is_valid(gpio)) - return -ENODEV; - ret = gpio_request(gpio, "egalax_irq"); if (ret < 0) { dev_err(&client->dev, @@ -190,11 +181,7 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, ts->input_dev = input_dev; /* controller may be in sleep, wake it up. */ - error = egalax_wake_up_device(client); - if (error) { - dev_err(&client->dev, "Failed to wake up the controller\n"); - goto err_free_dev; - } + egalax_wake_up_device(client); ret = egalax_firmware_version(client); if (ret < 0) { @@ -287,17 +274,11 @@ static int egalax_ts_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); -static struct of_device_id egalax_ts_dt_ids[] = { - { .compatible = "eeti,egalax_ts" }, - { /* sentinel */ } -}; - static struct i2c_driver egalax_ts_driver = { .driver = { .name = "egalax_ts", .owner = THIS_MODULE, .pm = &egalax_ts_pm_ops, - .of_match_table = of_match_ptr(egalax_ts_dt_ids), }, .id_table = egalax_ts_id, .probe = egalax_ts_probe, diff --git a/trunk/drivers/input/touchscreen/tsc40.c b/trunk/drivers/input/touchscreen/tsc40.c index eb96f168fb9d..63209aaa55f0 100644 --- a/trunk/drivers/input/touchscreen/tsc40.c +++ b/trunk/drivers/input/touchscreen/tsc40.c @@ -107,6 +107,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) __set_bit(BTN_TOUCH, input_dev->keybit); input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); + input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); serio_set_drvdata(serio, ptsc); diff --git a/trunk/drivers/isdn/Kconfig b/trunk/drivers/isdn/Kconfig index 86cd75a0e84d..a233ed53913a 100644 --- a/trunk/drivers/isdn/Kconfig +++ b/trunk/drivers/isdn/Kconfig @@ -4,7 +4,7 @@ menuconfig ISDN bool "ISDN support" - depends on NET && NETDEVICES + depends on NET depends on !S390 && !UML ---help--- ISDN ("Integrated Services Digital Network", called RNIS in France) diff --git a/trunk/drivers/isdn/i4l/Kconfig b/trunk/drivers/isdn/i4l/Kconfig index 9c6650ea848e..2302fbe70ac6 100644 --- a/trunk/drivers/isdn/i4l/Kconfig +++ b/trunk/drivers/isdn/i4l/Kconfig @@ -6,7 +6,7 @@ if ISDN_I4L config ISDN_PPP bool "Support synchronous PPP" - depends on INET + depends on INET && NETDEVICES select SLHC help Over digital connections such as ISDN, there is no need to diff --git a/trunk/drivers/isdn/i4l/isdn_common.c b/trunk/drivers/isdn/i4l/isdn_common.c index e2a945ee9f05..8c610fa6782b 100644 --- a/trunk/drivers/isdn/i4l/isdn_common.c +++ b/trunk/drivers/isdn/i4l/isdn_common.c @@ -1312,6 +1312,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) } else return -EINVAL; break; +#ifdef CONFIG_NETDEVICES case IIOCNETGPN: /* Get peer phone number of a connected * isdn network interface */ @@ -1321,6 +1322,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return isdn_net_getpeer(&phone, argp); } else return -EINVAL; +#endif default: return -EINVAL; } @@ -1350,6 +1352,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) case IIOCNETLCR: printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); return -ENODEV; +#ifdef CONFIG_NETDEVICES case IIOCNETAIF: /* Add a network-interface */ if (arg) { @@ -1488,6 +1491,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) return -EFAULT; return isdn_net_force_hangup(name); break; +#endif /* CONFIG_NETDEVICES */ case IIOCSETVER: dev->net_verbose = arg; printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); diff --git a/trunk/drivers/leds/ledtrig-cpu.c b/trunk/drivers/leds/ledtrig-cpu.c index 4239b3955ff0..b312056da14d 100644 --- a/trunk/drivers/leds/ledtrig-cpu.c +++ b/trunk/drivers/leds/ledtrig-cpu.c @@ -33,6 +33,8 @@ struct led_trigger_cpu { char name[MAX_NAME_LEN]; struct led_trigger *_trig; + struct mutex lock; + int lock_is_inited; }; static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); @@ -48,6 +50,12 @@ void ledtrig_cpu(enum cpu_led_event ledevt) { struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); + /* mutex lock should be initialized before calling mutex_call() */ + if (!trig->lock_is_inited) + return; + + mutex_lock(&trig->lock); + /* Locate the correct CPU LED */ switch (ledevt) { case CPU_LED_IDLE_END: @@ -67,6 +75,8 @@ void ledtrig_cpu(enum cpu_led_event ledevt) /* Will leave the LED as it is */ break; } + + mutex_unlock(&trig->lock); } EXPORT_SYMBOL(ledtrig_cpu); @@ -107,9 +117,14 @@ static int __init ledtrig_cpu_init(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_init(&trig->lock); + snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + mutex_lock(&trig->lock); led_trigger_register_simple(trig->name, &trig->_trig); + trig->lock_is_inited = 1; + mutex_unlock(&trig->lock); } register_syscore_ops(&ledtrig_cpu_syscore_ops); @@ -127,9 +142,15 @@ static void __exit ledtrig_cpu_exit(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_lock(&trig->lock); + led_trigger_unregister_simple(trig->_trig); trig->_trig = NULL; memset(trig->name, 0, MAX_NAME_LEN); + trig->lock_is_inited = 0; + + mutex_unlock(&trig->lock); + mutex_destroy(&trig->lock); } unregister_syscore_ops(&ledtrig_cpu_syscore_ops); diff --git a/trunk/drivers/mmc/host/dw_mmc-exynos.c b/trunk/drivers/mmc/host/dw_mmc-exynos.c index 4d50da618166..660bbc528862 100644 --- a/trunk/drivers/mmc/host/dw_mmc-exynos.c +++ b/trunk/drivers/mmc/host/dw_mmc-exynos.c @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { MMC_CAP_CMD23, }; -static const struct dw_mci_drv_data exynos5250_drv_data = { +static struct dw_mci_drv_data exynos5250_drv_data = { .caps = exynos5250_dwmmc_caps, .init = dw_mci_exynos_priv_init, .setup_clock = dw_mci_exynos_setup_clock, @@ -220,14 +220,14 @@ static const struct dw_mci_drv_data exynos5250_drv_data = { static const struct of_device_id dw_mci_exynos_match[] = { { .compatible = "samsung,exynos5250-dw-mshc", - .data = &exynos5250_drv_data, }, + .data = (void *)&exynos5250_drv_data, }, {}, }; -MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); +MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); int dw_mci_exynos_probe(struct platform_device *pdev) { - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; const struct of_device_id *match; match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.c b/trunk/drivers/mmc/host/dw_mmc-pltfm.c index 917936bee5d5..c960ca7ffbe6 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.c +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.c @@ -24,7 +24,7 @@ #include "dw_mmc.h" int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data) + struct dw_mci_drv_data *drv_data) { struct dw_mci *host; struct resource *regs; @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, if (!host->regs) return -ENOMEM; - if (drv_data && drv_data->init) { - ret = drv_data->init(host); + if (host->drv_data->init) { + ret = host->drv_data->init(host); if (ret) return ret; } diff --git a/trunk/drivers/mmc/host/dw_mmc-pltfm.h b/trunk/drivers/mmc/host/dw_mmc-pltfm.h index 2ac37b81de4d..301f24541fc2 100644 --- a/trunk/drivers/mmc/host/dw_mmc-pltfm.h +++ b/trunk/drivers/mmc/host/dw_mmc-pltfm.h @@ -13,7 +13,7 @@ #define _DW_MMC_PLTFM_H_ extern int dw_mci_pltfm_register(struct platform_device *pdev, - const struct dw_mci_drv_data *drv_data); + struct dw_mci_drv_data *drv_data); extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); extern const struct dev_pm_ops dw_mci_pltfm_pmops; diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index c0667c8af2bd..c2828f35c3b8 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -232,7 +232,6 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) { struct mmc_data *data; struct dw_mci_slot *slot = mmc_priv(mmc); - struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 cmdr; cmd->error = -EINPROGRESS; @@ -262,8 +261,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) cmdr |= SDMMC_CMD_DAT_WR; } - if (drv_data && drv_data->prepare_command) - drv_data->prepare_command(slot->host, &cmdr); + if (slot->host->drv_data->prepare_command) + slot->host->drv_data->prepare_command(slot->host, &cmdr); return cmdr; } @@ -435,7 +434,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) return 0; } -static const struct dw_mci_dma_ops dw_mci_idmac_ops = { +static struct dw_mci_dma_ops dw_mci_idmac_ops = { .init = dw_mci_idmac_init, .start = dw_mci_idmac_start_dma, .stop = dw_mci_idmac_stop_dma, @@ -773,7 +772,6 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct dw_mci_slot *slot = mmc_priv(mmc); - struct dw_mci_drv_data *drv_data = slot->host->drv_data; u32 regs; /* set default 1 bit mode */ @@ -809,8 +807,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) slot->clock = ios->clock; } - if (drv_data && drv_data->set_ios) - drv_data->set_ios(slot->host, ios); + if (slot->host->drv_data->set_ios) + slot->host->drv_data->set_ios(slot->host, ios); switch (ios->power_mode) { case MMC_POWER_UP: @@ -1817,7 +1815,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) { struct mmc_host *mmc; struct dw_mci_slot *slot; - struct dw_mci_drv_data *drv_data = host->drv_data; int ctrl_id, ret; u8 bus_width; @@ -1857,8 +1854,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) } else { ctrl_id = to_platform_device(host->dev)->id; } - if (drv_data && drv_data->caps) - mmc->caps |= drv_data->caps[ctrl_id]; + if (host->drv_data && host->drv_data->caps) + mmc->caps |= host->drv_data->caps[ctrl_id]; if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; @@ -1870,10 +1867,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) else bus_width = 1; - if (drv_data && drv_data->setup_bus) { + if (host->drv_data->setup_bus) { struct device_node *slot_np; slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); - ret = drv_data->setup_bus(host, slot_np, bus_width); + ret = host->drv_data->setup_bus(host, slot_np, bus_width); if (ret) goto err_setup_bus; } @@ -1971,7 +1968,7 @@ static void dw_mci_init_dma(struct dw_mci *host) /* Determine which DMA interface to use */ #ifdef CONFIG_MMC_DW_IDMAC host->dma_ops = &dw_mci_idmac_ops; - dev_info(host->dev, "Using internal DMA controller.\n"); + dev_info(&host->dev, "Using internal DMA controller.\n"); #endif if (!host->dma_ops) @@ -2038,7 +2035,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) struct dw_mci_board *pdata; struct device *dev = host->dev; struct device_node *np = dev->of_node; - struct dw_mci_drv_data *drv_data = host->drv_data; int idx, ret; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); @@ -2066,8 +2062,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); - if (drv_data && drv_data->parse_dt) { - ret = drv_data->parse_dt(host); + if (host->drv_data->parse_dt) { + ret = host->drv_data->parse_dt(host); if (ret) return ERR_PTR(ret); } @@ -2084,7 +2080,6 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) int dw_mci_probe(struct dw_mci *host) { - struct dw_mci_drv_data *drv_data = host->drv_data; int width, i, ret = 0; u32 fifo_size; int init_slots = 0; @@ -2132,8 +2127,8 @@ int dw_mci_probe(struct dw_mci *host) else host->bus_hz = clk_get_rate(host->ciu_clk); - if (drv_data && drv_data->setup_clock) { - ret = drv_data->setup_clock(host); + if (host->drv_data->setup_clock) { + ret = host->drv_data->setup_clock(host); if (ret) { dev_err(host->dev, "implementation specific clock setup failed\n"); @@ -2233,21 +2228,6 @@ int dw_mci_probe(struct dw_mci *host) else host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; - /* - * Enable interrupts for command done, data over, data empty, card det, - * receive ready and error such as transmit, receive timeout, crc error - */ - mci_writel(host, RINTSTS, 0xFFFFFFFF); - mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | - SDMMC_INT_TXDR | SDMMC_INT_RXDR | - DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); - mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ - - dev_info(host->dev, "DW MMC controller at irq %d, " - "%d bit host data width, " - "%u deep fifo\n", - host->irq, width, fifo_size); - /* We need at least one slot to succeed */ for (i = 0; i < host->num_slots; i++) { ret = dw_mci_init_slot(host, i); @@ -2277,6 +2257,20 @@ int dw_mci_probe(struct dw_mci *host) else host->data_offset = DATA_240A_OFFSET; + /* + * Enable interrupts for command done, data over, data empty, card det, + * receive ready and error such as transmit, receive timeout, crc error + */ + mci_writel(host, RINTSTS, 0xFFFFFFFF); + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | + SDMMC_INT_TXDR | SDMMC_INT_RXDR | + DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); + mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ + + dev_info(host->dev, "DW MMC controller at irq %d, " + "%d bit host data width, " + "%u deep fifo\n", + host->irq, width, fifo_size); if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); diff --git a/trunk/drivers/mmc/host/mxcmmc.c b/trunk/drivers/mmc/host/mxcmmc.c index 6290b7f1ccfe..565c2e4fac75 100644 --- a/trunk/drivers/mmc/host/mxcmmc.c +++ b/trunk/drivers/mmc/host/mxcmmc.c @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); MODULE_AUTHOR("Sascha Hauer, Pengutronix"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mxc-mmc"); +MODULE_ALIAS("platform:imx-mmc"); diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index fedd258cc4ea..54bfd0cc106b 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -178,8 +178,7 @@ struct omap_hsmmc_host { static int omap_hsmmc_card_detect(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -187,8 +186,7 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) static int omap_hsmmc_get_wp(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); @@ -196,8 +194,7 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) static int omap_hsmmc_get_cover_state(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); @@ -207,8 +204,7 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; disable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -216,8 +212,7 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) { - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_mmc_platform_data *mmc = host->pdata; + struct omap_mmc_platform_data *mmc = dev->platform_data; enable_irq(mmc->slots[0].card_detect_irq); return 0; @@ -2014,9 +2009,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) clk_put(host->dbclk); } - omap_hsmmc_gpio_free(host->pdata); - iounmap(host->base); mmc_free_host(host->mmc); + iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) diff --git a/trunk/drivers/mmc/host/sdhci-dove.c b/trunk/drivers/mmc/host/sdhci-dove.c index 8fd50a211037..90140eb03e36 100644 --- a/trunk/drivers/mmc/host/sdhci-dove.c +++ b/trunk/drivers/mmc/host/sdhci-dove.c @@ -19,7 +19,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -85,32 +84,30 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) struct sdhci_dove_priv *priv; int ret; + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); + if (ret) + goto sdhci_dove_register_fail; + priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "unable to allocate private data"); - return -ENOMEM; + ret = -ENOMEM; + goto sdhci_dove_allocate_fail; } - priv->clk = clk_get(&pdev->dev, NULL); - if (!IS_ERR(priv->clk)) - clk_prepare_enable(priv->clk); - - ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); - if (ret) - goto sdhci_dove_register_fail; - host = platform_get_drvdata(pdev); pltfm_host = sdhci_priv(host); pltfm_host->priv = priv; + priv->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(priv->clk)) + clk_prepare_enable(priv->clk); return 0; +sdhci_dove_allocate_fail: + sdhci_pltfm_unregister(pdev); sdhci_dove_register_fail: - if (!IS_ERR(priv->clk)) { - clk_disable_unprepare(priv->clk); - clk_put(priv->clk); - } return ret; } @@ -120,13 +117,14 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_dove_priv *priv = pltfm_host->priv; - sdhci_pltfm_unregister(pdev); - - if (!IS_ERR(priv->clk)) { - clk_disable_unprepare(priv->clk); - clk_put(priv->clk); + if (priv->clk) { + if (!IS_ERR(priv->clk)) { + clk_disable_unprepare(priv->clk); + clk_put(priv->clk); + } + devm_kfree(&pdev->dev, priv->clk); } - return 0; + return sdhci_pltfm_unregister(pdev); } static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { diff --git a/trunk/drivers/mmc/host/sdhci-of-esdhc.c b/trunk/drivers/mmc/host/sdhci-of-esdhc.c index 63d219f57cae..ae5fcbfa1eef 100644 --- a/trunk/drivers/mmc/host/sdhci-of-esdhc.c +++ b/trunk/drivers/mmc/host/sdhci-of-esdhc.c @@ -169,16 +169,6 @@ static void esdhc_of_resume(struct sdhci_host *host) } #endif -static void esdhc_of_platform_init(struct sdhci_host *host) -{ - u32 vvn; - - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); - vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; - if (vvn == VENDOR_V_22) - host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; -} - static struct sdhci_ops sdhci_esdhc_ops = { .read_l = esdhc_readl, .read_w = esdhc_readw, @@ -190,7 +180,6 @@ static struct sdhci_ops sdhci_esdhc_ops = { .enable_dma = esdhc_of_enable_dma, .get_max_clock = esdhc_of_get_max_clock, .get_min_clock = esdhc_of_get_min_clock, - .platform_init = esdhc_of_platform_init, #ifdef CONFIG_PM .platform_suspend = esdhc_of_suspend, .platform_resume = esdhc_of_resume, diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 04936f353ced..4bb74b042a06 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( return ERR_PTR(-ENODEV); } - if (pci_resource_len(pdev, bar) < 0x100) { + if (pci_resource_len(pdev, bar) != 0x100) { dev_err(&pdev->dev, "Invalid iomem size. You may " "experience problems.\n"); } diff --git a/trunk/drivers/mmc/host/sdhci-pltfm.c b/trunk/drivers/mmc/host/sdhci-pltfm.c index 27164457f861..65551a9709cc 100644 --- a/trunk/drivers/mmc/host/sdhci-pltfm.c +++ b/trunk/drivers/mmc/host/sdhci-pltfm.c @@ -150,13 +150,6 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, goto err_remap; } - /* - * Some platforms need to probe the controller to be able to - * determine which caps should be used. - */ - if (host->ops && host->ops->platform_init) - host->ops->platform_init(host); - platform_set_drvdata(pdev, host); return host; diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index a54dd5d7a5f9..2903949594c6 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) if (ourhost->cur_clk != best_src) { struct clk *clk = ourhost->clk_bus[best_src]; - clk_prepare_enable(clk); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(clk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); /* turn clock off to card before changing clock source */ writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); @@ -607,7 +607,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } /* enable the local io clock and keep it running for the moment. */ - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { struct clk *clk; @@ -638,7 +638,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } #ifndef CONFIG_PM_RUNTIME - clk_prepare_enable(sc->clk_bus[sc->cur_clk]); + clk_enable(sc->clk_bus[sc->cur_clk]); #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -747,14 +747,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) sdhci_s3c_setup_card_detect_gpio(sc); #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); #endif return 0; err_req_regs: #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { @@ -763,7 +762,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) } err_no_busclks: - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); err_io_clk: @@ -795,8 +794,7 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) gpio_free(sc->ext_cd_gpio); #ifdef CONFIG_PM_RUNTIME - if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) - clk_prepare_enable(sc->clk_io); + clk_enable(sc->clk_io); #endif sdhci_remove_host(host, 1); @@ -804,14 +802,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); #ifndef CONFIG_PM_RUNTIME - clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); + clk_disable(sc->clk_bus[sc->cur_clk]); #endif for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { clk_put(sc->clk_bus[ptr]); } } - clk_disable_unprepare(sc->clk_io); + clk_disable(sc->clk_io); clk_put(sc->clk_io); if (pdev->dev.of_node) { @@ -851,8 +849,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) ret = sdhci_runtime_suspend_host(host); - clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); - clk_disable_unprepare(busclk); + clk_disable(ourhost->clk_bus[ourhost->cur_clk]); + clk_disable(busclk); return ret; } @@ -863,8 +861,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) struct clk *busclk = ourhost->clk_io; int ret; - clk_prepare_enable(busclk); - clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); + clk_enable(busclk); + clk_enable(ourhost->clk_bus[ourhost->cur_clk]); ret = sdhci_runtime_resume_host(host); return ret; } diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index c7851c0aabce..7922adb42386 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -1315,19 +1315,16 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) */ if ((host->flags & SDHCI_NEEDS_RETUNING) && !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { - if (mmc->card) { - /* eMMC uses cmd21 but sd and sdio use cmd19 */ - tuning_opcode = - mmc->card->type == MMC_TYPE_MMC ? - MMC_SEND_TUNING_BLOCK_HS200 : - MMC_SEND_TUNING_BLOCK; - spin_unlock_irqrestore(&host->lock, flags); - sdhci_execute_tuning(mmc, tuning_opcode); - spin_lock_irqsave(&host->lock, flags); - - /* Restore original mmc_request structure */ - host->mrq = mrq; - } + /* eMMC uses cmd21 while sd and sdio use cmd19 */ + tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? + MMC_SEND_TUNING_BLOCK_HS200 : + MMC_SEND_TUNING_BLOCK; + spin_unlock_irqrestore(&host->lock, flags); + sdhci_execute_tuning(mmc, tuning_opcode); + spin_lock_irqsave(&host->lock, flags); + + /* Restore original mmc_request structure */ + host->mrq = mrq; } if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) @@ -2840,9 +2837,6 @@ int sdhci_add_host(struct sdhci_host *host) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) mmc->caps |= MMC_CAP_4_BIT_DATA; - if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) - mmc->caps &= ~MMC_CAP_CMD23; - if (caps[0] & SDHCI_CAN_DO_HISPD) mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; @@ -2852,12 +2846,9 @@ int sdhci_add_host(struct sdhci_host *host) /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); - if (IS_ERR_OR_NULL(host->vqmmc)) { - if (PTR_ERR(host->vqmmc) < 0) { - pr_info("%s: no vqmmc regulator found\n", - mmc_hostname(mmc)); - host->vqmmc = NULL; - } + if (IS_ERR(host->vqmmc)) { + pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); + host->vqmmc = NULL; } else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) regulator_enable(host->vqmmc); @@ -2913,12 +2904,9 @@ int sdhci_add_host(struct sdhci_host *host) ocr_avail = 0; host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); - if (IS_ERR_OR_NULL(host->vmmc)) { - if (PTR_ERR(host->vmmc) < 0) { - pr_info("%s: no vmmc regulator found\n", - mmc_hostname(mmc)); - host->vmmc = NULL; - } + if (IS_ERR(host->vmmc)) { + pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); + host->vmmc = NULL; } else regulator_enable(host->vmmc); diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index 71a4a7ed46c5..97653ea8942b 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -278,7 +278,6 @@ struct sdhci_ops { void (*hw_reset)(struct sdhci_host *host); void (*platform_suspend)(struct sdhci_host *host); void (*platform_resume)(struct sdhci_host *host); - void (*platform_init)(struct sdhci_host *host); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS diff --git a/trunk/drivers/mmc/host/sh_mmcif.c b/trunk/drivers/mmc/host/sh_mmcif.c index d25bc97dc5c6..11d2bc3b51d5 100644 --- a/trunk/drivers/mmc/host/sh_mmcif.c +++ b/trunk/drivers/mmc/host/sh_mmcif.c @@ -1466,9 +1466,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - clk_disable(host->hclk); mmc_free_host(host->mmc); pm_runtime_put_sync(&pdev->dev); + clk_disable(host->hclk); pm_runtime_disable(&pdev->dev); return 0; diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index ef8d2a080d17..dc15d248443f 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -1060,7 +1060,7 @@ static ssize_t bonding_store_primary(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing primary */ if (!strlen(ifname) || buf[0] == '\n') { @@ -1237,7 +1237,7 @@ static ssize_t bonding_store_active_slave(struct device *d, goto out; } - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ + sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ /* check to see if we are clearing active */ if (!strlen(ifname) || buf[0] == '\n') { diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 6e5bdd1a31d9..c65295dded39 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) SHMEM_EEE_ADV_STATUS_SHIFT); if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { DP(BNX2X_MSG_ETHTOOL, - "Direct manipulation of EEE advertisement is not supported\n"); + "Direct manipulation of EEE advertisment is not supported\n"); return -EINVAL; } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f6cfdc6cf20f..e2e45ee5df33 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -137,16 +137,7 @@ #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD -#define LINK_UPDATE_MASK \ - (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \ - LINK_STATUS_LINK_UP | \ - LINK_STATUS_PHYSICAL_LINK_FLAG | \ - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \ - LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \ - LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \ - LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \ - LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) + #define SFP_EEPROM_CON_TYPE_ADDR 0x2 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 @@ -3304,21 +3295,6 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) DEFAULT_PHY_DEV_ADDR); } -static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy, - struct link_params *params, - u32 action) -{ - struct bnx2x *bp = params->bp; - switch (action) { - case PHY_INIT: - /* Set correct devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, - phy->def_md_devad); - break; - } -} - static void bnx2x_xgxs_deassert(struct link_params *params) { struct bnx2x *bp = params->bp; @@ -3333,8 +3309,10 @@ static void bnx2x_xgxs_deassert(struct link_params *params) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - bnx2x_xgxs_specific_func(¶ms->phy[INT_PHY], params, - PHY_INIT); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); } static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, @@ -3567,11 +3545,14 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 lane, i, cl72_ctrl, an_adv = 0; - u16 ucode_ver; + u16 val16 = 0, lane, i; struct bnx2x *bp = params->bp; static struct bnx2x_reg_set reg_set[] = { {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, @@ -3584,19 +3565,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); - cl72_ctrl &= 0xf8ff; - cl72_ctrl |= 0x3800; - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); - /* Check adding advertisement for 1G KX */ if (((vars->line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || (vars->line_speed == SPEED_1000)) { u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; - an_adv |= (1<<5); + val16 |= (1<<5); /* Enable CL37 1G Parallel Detect */ bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); @@ -3606,14 +3580,11 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || (vars->line_speed == SPEED_10000)) { /* Check adding advertisement for 10G KR */ - an_adv |= (1<<7); + val16 |= (1<<7); /* Enable 10G Parallel Detect */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 1); - bnx2x_set_aer_mmd(params, phy); + DP(NETIF_MSG_LINK, "Advertize 10G\n"); } @@ -3633,7 +3604,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Advertised speeds */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv); + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); /* Advertised and set FEC (Forward Error Correction) */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, @@ -3657,10 +3628,9 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 */ bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); - if (ucode_ver < 0xd108) { - DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", - ucode_ver); + MDIO_WC_REG_UC_INFO_B1_VERSION, &val16); + if (val16 < 0xd108) { + DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; } bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, @@ -3681,16 +3651,21 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val16, i, lane; + u16 i; static struct bnx2x_reg_set reg_set[] = { /* Disable Autoneg */ {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, + {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00}, {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, + /* Disable CL36 PCS Tx */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, + /* Double Wide Single Data Rate @ pll rate */ + {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, /* Leave cl72 training enable, needed for KR */ {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, @@ -3701,24 +3676,11 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, reg_set[i].val); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Global registers */ - CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 &= ~(0x0011 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); + /* Leave CL72 enabled */ + bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, + 0x3800); - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 |= (0x0303 << (lane << 1)); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); /* Set speed via PMA/PMD register */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); @@ -4341,7 +4303,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u16 val16, lane; + u16 val16; bnx2x_sfp_e3_set_transmitter(params, phy, 0); bnx2x_set_mdio_clk(bp, params->chip_id, params->port); bnx2x_set_aer_mmd(params, phy); @@ -4378,30 +4340,6 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, MDIO_WC_REG_XGXSBLK1_LANECTRL2, val16 & 0xff00); - lane = bnx2x_get_warpcore_lane(phy, params); - /* Disable CL36 PCS Tx */ - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); - val16 |= (0x11 << lane); - if (phy->flags & FLAGS_WC_DUAL_MODE) - val16 |= (0x22 << lane); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); - - bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); - val16 &= ~(0x0303 << (lane << 1)); - val16 |= (0x0101 << (lane << 1)); - if (phy->flags & FLAGS_WC_DUAL_MODE) { - val16 &= ~(0x0c0c << (lane << 1)); - val16 |= (0x0404 << (lane << 1)); - } - - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); - /* Restore AER */ - bnx2x_set_aer_mmd(params, phy); - } static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, @@ -6358,7 +6296,15 @@ static int bnx2x_update_link_down(struct link_params *params, vars->mac_type = MAC_TYPE_NONE; /* Update shared memory */ - vars->link_status &= ~LINK_UPDATE_MASK; + vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | + LINK_STATUS_LINK_UP | + LINK_STATUS_PHYSICAL_LINK_FLAG | + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | + LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | + LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | + LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | + LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE); vars->line_speed = 0; bnx2x_update_mng(params, vars->link_status); @@ -6506,7 +6452,6 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; u8 active_external_phy = INT_PHY; vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; - vars->link_status &= ~LINK_UPDATE_MASK; for (phy_index = INT_PHY; phy_index < params->num_phys; phy_index++) { phy_vars[phy_index].flow_ctrl = 0; @@ -7634,7 +7579,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params, static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, - u8 *o_buf, u8 is_init) + u8 *o_buf) { int rc = 0; u8 i, j = 0, cnt = 0; @@ -7651,10 +7596,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { - if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) { + if (cnt == I2C_WA_PWR_ITER) { bnx2x_warpcore_power_module(params, phy, 0); /* Note that 100us are not enough here */ - usleep_range(1000, 2000); + usleep_range(1000,1000); bnx2x_warpcore_power_module(params, phy, 1); } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, @@ -7774,7 +7719,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf, 0); + byte_cnt, o_buf); break; } return rc; @@ -7978,7 +7923,6 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, { u8 val; - int rc; struct bnx2x *bp = params->bp; u16 timeout; /* Initialization time after hot-plug may take up to 300ms for @@ -7986,14 +7930,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, */ for (timeout = 0; timeout < 60; timeout++) { - if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, - params, 1, - 1, &val, 1); - else - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, - &val); - if (rc == 0) { + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) + == 0) { DP(NETIF_MSG_LINK, "SFP+ module initialization took %d ms\n", timeout * 5); @@ -8001,8 +7939,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, } usleep_range(5000, 10000); } - rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val); - return rc; + return -EINVAL; } static void bnx2x_8727_power_module(struct bnx2x *bp, @@ -9941,7 +9878,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, else rc = bnx2x_8483x_disable_eee(phy, params, vars); if (rc) { - DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); + DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); return rc; } } else { @@ -11056,7 +10993,7 @@ static struct bnx2x_phy phy_xgxs = { .format_fw_ver = (format_fw_ver_t)NULL, .hw_reset = (hw_reset_t)NULL, .set_link_led = (set_link_led_t)NULL, - .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func + .phy_specific_func = (phy_specific_func_t)NULL }; static struct bnx2x_phy phy_warpcore = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, @@ -11528,11 +11465,6 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_BASE_T; break; case PORT_HW_CFG_NET_SERDES_IF_XFI: - phy->supported &= (SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); phy->media_type = ETH_PHY_XFP_FIBER; break; case PORT_HW_CFG_NET_SERDES_IF_SFI: @@ -12987,7 +12919,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); break; default: - DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); + DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); } DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, old_status, status); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index bd1fd3d87c24..d5648fc666bd 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -6794,9 +6794,8 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) bnx2x_init_block(bp, BLOCK_DORQ, init_phase); - bnx2x_init_block(bp, BLOCK_BRB1, init_phase); - if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); if (IS_MF(bp)) low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); @@ -11903,15 +11902,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* disable FCOE L2 queue for E1x */ if (CHIP_IS_E1x(bp)) bp->flags |= NO_FCOE_FLAG; - /* disable FCOE for 57840 device, until FW supports it */ - switch (ent->driver_data) { - case BCM57840_O: - case BCM57840_4_10: - case BCM57840_2_20: - case BCM57840_MFO: - case BCM57840_MF: - bp->flags |= NO_FCOE_FLAG; - } + #endif diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 0df1284df497..c1cde11b0c6d 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3415,6 +3415,16 @@ static int adap_init0_config(struct adapter *adapter, int reset) "mismatch: [fini] csum=%#x, computed csum=%#x\n", finicsum, cfcsum); + /* + * If we're a pure NIC driver then disable all offloading facilities. + * This will allow the firmware to optimize aspects of the hardware + * configuration which will result in improved performance. + */ + caps_cmd.ofldcaps = 0; + caps_cmd.iscsicaps = 0; + caps_cmd.rdmacaps = 0; + caps_cmd.fcoecaps = 0; + /* * And now tell the firmware to use the configuration we just loaded. */ diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 730ae2cfa49e..32eec15fe4c2 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2519,7 +2519,6 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) { struct fw_bye_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, BYE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2536,7 +2535,6 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) { struct fw_initialize_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, INITIALIZE, WRITE); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -2553,7 +2551,6 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) { struct fw_reset_cmd c; - memset(&c, 0, sizeof(c)); INIT_CMD(c, RESET, WRITE); c.val = htonl(reset); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); @@ -2831,7 +2828,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, HOSTPAGESIZEPF7(sge_hps)); t4_set_reg_field(adap, SGE_CONTROL, - INGPADBOUNDARY_MASK | + INGPADBOUNDARY(INGPADBOUNDARY_MASK) | EGRSTATUSPAGESIZE_MASK, INGPADBOUNDARY(fl_align_log - 5) | EGRSTATUSPAGESIZE(stat_len != 64)); @@ -3281,7 +3278,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, { struct fw_vi_enable_cmd c; - memset(&c, 0, sizeof(c)); c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index 19ac096cb07b..1d03dcdd5e56 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -1353,11 +1353,8 @@ static int gfar_restore(struct device *dev) struct gfar_private *priv = dev_get_drvdata(dev); struct net_device *ndev = priv->ndev; - if (!netif_running(ndev)) { - netif_device_attach(ndev); - + if (!netif_running(ndev)) return 0; - } gfar_init_bds(ndev); init_registers(ndev); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 116f0e901bee..56b20d17d0e4 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2673,9 +2673,6 @@ static int ixgbe_get_ts_info(struct net_device *dev, case ixgbe_mac_X540: case ixgbe_mac_82599EB: info->so_timestamping = - SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; diff --git a/trunk/drivers/net/ethernet/jme.c b/trunk/drivers/net/ethernet/jme.c index 92317e9c0f73..f8064df10cc4 100644 --- a/trunk/drivers/net/ethernet/jme.c +++ b/trunk/drivers/net/ethernet/jme.c @@ -1948,10 +1948,10 @@ jme_close(struct net_device *netdev) JME_NAPI_DISABLE(jme); - tasklet_kill(&jme->linkch_task); - tasklet_kill(&jme->txclean_task); - tasklet_kill(&jme->rxclean_task); - tasklet_kill(&jme->rxempty_task); + tasklet_disable(&jme->linkch_task); + tasklet_disable(&jme->txclean_task); + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); diff --git a/trunk/drivers/net/ethernet/marvell/skge.c b/trunk/drivers/net/ethernet/marvell/skge.c index d19a143aa5a8..9b9c2ac5c4c2 100644 --- a/trunk/drivers/net/ethernet/marvell/skge.c +++ b/trunk/drivers/net/ethernet/marvell/skge.c @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) dev0 = hw->dev[0]; unregister_netdev(dev0); - tasklet_kill(&hw->phy_task); + tasklet_disable(&hw->phy_task); spin_lock_irq(&hw->hw_lock); hw->intr_mask = 0; diff --git a/trunk/drivers/net/ethernet/micrel/ksz884x.c b/trunk/drivers/net/ethernet/micrel/ksz884x.c index e558edd1cb6c..318fee91c79d 100644 --- a/trunk/drivers/net/ethernet/micrel/ksz884x.c +++ b/trunk/drivers/net/ethernet/micrel/ksz884x.c @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) /* Delay for receive task to stop scheduling itself. */ msleep(2000 / HZ); - tasklet_kill(&hw_priv->rx_tasklet); - tasklet_kill(&hw_priv->tx_tasklet); + tasklet_disable(&hw_priv->rx_tasklet); + tasklet_disable(&hw_priv->tx_tasklet); free_irq(dev->irq, hw_priv->dev); transmit_cleanup(hw_priv, 0); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index af8b4142088c..53743f7a2ca9 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -1524,7 +1524,6 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) pldat->dma_buff_base_p); free_irq(ndev->irq, ndev); iounmap(pldat->net_base); - mdiobus_unregister(pldat->mii_bus); mdiobus_free(pldat->mii_bus); clk_disable(pldat->clk); clk_put(pldat->clk); diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 927aa33d4349..e7ff886e8047 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3827,8 +3827,6 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_25: - case RTL_GIGA_MAC_VER_26: case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_32: @@ -4521,9 +4519,6 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = swab32(data); } - if (tp->mac_version == RTL_GIGA_MAC_VER_35) - mc_filter[1] = mc_filter[0] = 0xffffffff; - RTL_W32(MAR0 + 4, mc_filter[1]); RTL_W32(MAR0 + 0, mc_filter[0]); diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1d04754a6637..0793299bd39e 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -990,7 +990,7 @@ static int axienet_stop(struct net_device *ndev) axienet_setoptions(ndev, lp->options & ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); - tasklet_kill(&lp->dma_err_tasklet); + tasklet_disable(&lp->dma_err_tasklet); free_irq(lp->tx_irq, ndev); free_irq(lp->rx_irq, ndev); diff --git a/trunk/drivers/net/phy/mdio-bitbang.c b/trunk/drivers/net/phy/mdio-bitbang.c index 6428fcbbdd4b..daec9b05d168 100644 --- a/trunk/drivers/net/phy/mdio-bitbang.c +++ b/trunk/drivers/net/phy/mdio-bitbang.c @@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus) struct mdiobb_ctrl *ctrl = bus->priv; module_put(ctrl->ops->owner); - mdiobus_unregister(bus); mdiobus_free(bus); } EXPORT_SYMBOL(free_mdio_bitbang); diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index 08d55b6bf272..c81e278629ff 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -31,7 +31,6 @@ #include #include #include -#include /* @@ -93,7 +92,7 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) /* no jumbogram (16K) support for now */ - dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; + dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 3286166415b4..7479a5761d0d 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1344,7 +1344,6 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, } else { u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); skb_push(skb, 4); - cpu_to_le32s(&csum_preamble); memcpy(skb->data, &csum_preamble, 4); } } diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index edb81ed06950..cb04f900cc46 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -359,12 +359,10 @@ static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb, void usbnet_defer_kevent (struct usbnet *dev, int work) { set_bit (work, &dev->flags); - if (!schedule_work (&dev->kevent)) { - if (net_ratelimit()) - netdev_err(dev->net, "kevent %d may have been dropped\n", work); - } else { + if (!schedule_work (&dev->kevent)) + netdev_err(dev->net, "kevent %d may have been dropped\n", work); + else netdev_dbg(dev->net, "kevent %d scheduled\n", work); - } } EXPORT_SYMBOL_GPL(usbnet_defer_kevent); diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index 0ae1bcc6da73..ce9d4f2c9776 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -744,43 +744,28 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - u32 buf_size; - - buf_offset = 0; - len = skb_frag_size(frag); - while (len) { - tbi = tq->buf_info + tq->tx_ring.next2fill; - if (len < VMXNET3_MAX_TX_BUF_SIZE) { - buf_size = len; - dw2 |= len; - } else { - buf_size = VMXNET3_MAX_TX_BUF_SIZE; - /* spec says that for TxDesc.len, 0 == 2^14 */ - } - tbi->map_type = VMXNET3_MAP_PAGE; - tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, - buf_offset, buf_size, - DMA_TO_DEVICE); - tbi->len = buf_size; + tbi = tq->buf_info + tq->tx_ring.next2fill; + tbi->map_type = VMXNET3_MAP_PAGE; + tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag, + 0, skb_frag_size(frag), + DMA_TO_DEVICE); - gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; - BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); + tbi->len = skb_frag_size(frag); - gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); - gdesc->dword[2] = cpu_to_le32(dw2); - gdesc->dword[3] = 0; + gdesc = tq->tx_ring.base + tq->tx_ring.next2fill; + BUG_ON(gdesc->txd.gen == tq->tx_ring.gen); - dev_dbg(&adapter->netdev->dev, - "txd[%u]: 0x%llu %u %u\n", - tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), - le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); - vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); - dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; + gdesc->txd.addr = cpu_to_le64(tbi->dma_addr); + gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag)); + gdesc->dword[3] = 0; - len -= buf_size; - buf_offset += buf_size; - } + dev_dbg(&adapter->netdev->dev, + "txd[%u]: 0x%llu %u %u\n", + tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr), + le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]); + vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring); + dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT; } ctx->eop_txd = gdesc; @@ -901,18 +886,6 @@ vmxnet3_prepare_tso(struct sk_buff *skb, } } -static int txd_estimate(const struct sk_buff *skb) -{ - int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1; - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - - count += VMXNET3_TXD_NEEDED(skb_frag_size(frag)); - } - return count; -} /* * Transmits a pkt thru a given tq @@ -941,7 +914,9 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, union Vmxnet3_GenericDesc tempTxDesc; #endif - count = txd_estimate(skb); + /* conservatively estimate # of descriptors to use */ + count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + + skb_shinfo(skb)->nr_frags + 1; ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP)); diff --git a/trunk/drivers/net/vxlan.c b/trunk/drivers/net/vxlan.c index 7b4adde93c01..607976c00162 100644 --- a/trunk/drivers/net/vxlan.c +++ b/trunk/drivers/net/vxlan.c @@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long arg) = container_of(p, struct vxlan_fdb, hlist); unsigned long timeout; - if (f->state & NUD_PERMANENT) + if (f->state == NUD_PERMANENT) continue; timeout = f->used + vxlan->age_interval * HZ; diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 741918a2027b..378bd70256b2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); - bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -394,7 +393,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; - bool rc_update = true, isba; + bool rc_update = true; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; @@ -438,17 +437,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; - isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted - * - * Only BlockAcks have a TID and therefore normal Acks cannot be - * checked */ - if (isba && tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1779,7 +1774,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; - bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); diff --git a/trunk/drivers/net/wireless/b43legacy/pio.c b/trunk/drivers/net/wireless/b43legacy/pio.c index 282eedec675e..192251adf986 100644 --- a/trunk/drivers/net/wireless/b43legacy/pio.c +++ b/trunk/drivers/net/wireless/b43legacy/pio.c @@ -382,7 +382,7 @@ static void cancel_transfers(struct b43legacy_pioqueue *queue) { struct b43legacy_pio_txpacket *packet, *tmp_packet; - tasklet_kill(&queue->txtask); + tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) free_txpacket(packet, 0); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 59474ae0aec0..01dc8891070c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index a543746fb354..6241fd05bd41 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -320,7 +320,10 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *), } else next = dev->bus_list.next; + /* Run device routines with the device locked */ + device_lock(&dev->dev); retval = cb(dev, userdata); + device_unlock(&dev->dev); if (retval) break; } diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 6c94fc9489e7..94c6e2aa03d6 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -398,8 +398,6 @@ static void pci_device_shutdown(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; - pm_runtime_resume(dev); - if (drv && drv->shutdown) drv->shutdown(pci_dev); pci_msi_shutdown(pci_dev); @@ -410,6 +408,16 @@ static void pci_device_shutdown(struct device *dev) * continue to do DMA */ pci_disable_device(pci_dev); + + /* + * Devices may be enabled to wake up by runtime PM, but they need not + * be supposed to wake up the system from its "power off" state (e.g. + * ACPI S5). Therefore disable wakeup for all devices that aren't + * supposed to wake up the system at this point. The state argument + * will be ignored by pci_enable_wake(). + */ + if (!device_may_wakeup(dev)) + pci_enable_wake(pci_dev, PCI_UNKNOWN, false); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index f39378d9da15..02d107b15281 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) } struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static void +pci_config_pm_runtime_get(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + if (parent) + pm_runtime_get_sync(parent); + pm_runtime_get_noresume(dev); + /* + * pdev->current_state is set to PCI_D3cold during suspending, + * so wait until suspending completes + */ + pm_runtime_barrier(dev); + /* + * Only need to resume devices in D3cold, because config + * registers are still accessible for devices suspended but + * not in D3cold. + */ + if (pdev->current_state == PCI_D3cold) + pm_runtime_resume(dev); +} + +static void +pci_config_pm_runtime_put(struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + + pm_runtime_put(dev); + if (parent) + pm_runtime_put_sync(parent); +} + static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index aabf64798bda..54858838f098 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -1858,38 +1858,6 @@ bool pci_dev_run_wake(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_dev_run_wake); -void pci_config_pm_runtime_get(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - if (parent) - pm_runtime_get_sync(parent); - pm_runtime_get_noresume(dev); - /* - * pdev->current_state is set to PCI_D3cold during suspending, - * so wait until suspending completes - */ - pm_runtime_barrier(dev); - /* - * Only need to resume devices in D3cold, because config - * registers are still accessible for devices suspended but - * not in D3cold. - */ - if (pdev->current_state == PCI_D3cold) - pm_runtime_resume(dev); -} - -void pci_config_pm_runtime_put(struct pci_dev *pdev) -{ - struct device *dev = &pdev->dev; - struct device *parent = dev->parent; - - pm_runtime_put(dev); - if (parent) - pm_runtime_put_sync(parent); -} - /** * pci_pm_init - Initialize PM functions of given PCI device * @dev: PCI device to handle. diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index fd92aab9904b..bacbcba69cf3 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -72,8 +72,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev); extern int pci_finish_runtime_suspend(struct pci_dev *dev); extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); extern void pci_wakeup_bus(struct pci_bus *bus); -extern void pci_config_pm_runtime_get(struct pci_dev *dev); -extern void pci_config_pm_runtime_put(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index af4e31cd3a3b..06bad96af415 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -213,7 +213,6 @@ static int report_error_detected(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); dev->error_state = result_data->state; if (!dev->driver || @@ -232,14 +231,12 @@ static int report_error_detected(struct pci_dev *dev, void *data) dev->driver ? "no AER-aware driver" : "no driver"); } - goto out; + return 0; } err_handler = dev->driver->err_handler; vote = err_handler->error_detected(dev, result_data->state); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -250,17 +247,14 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->mmio_enabled) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->mmio_enabled(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -271,17 +265,14 @@ static int report_slot_reset(struct pci_dev *dev, void *data) struct aer_broadcast_data *result_data; result_data = (struct aer_broadcast_data *) data; - device_lock(&dev->dev); if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->slot_reset) - goto out; + return 0; err_handler = dev->driver->err_handler; vote = err_handler->slot_reset(dev); result_data->result = merge_result(result_data->result, vote); -out: - device_unlock(&dev->dev); return 0; } @@ -289,18 +280,15 @@ static int report_resume(struct pci_dev *dev, void *data) { const struct pci_error_handlers *err_handler; - device_lock(&dev->dev); dev->error_state = pci_channel_io_normal; if (!dev->driver || !dev->driver->err_handler || !dev->driver->err_handler->resume) - goto out; + return 0; err_handler = dev->driver->err_handler; err_handler->resume(dev); -out: - device_unlock(&dev->dev); return 0; } diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index ed129b414624..d03a7a39b2d8 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -272,8 +272,7 @@ static int get_port_device_capability(struct pci_dev *dev) } /* Hot-Plug Capable */ - if ((cap_mask & PCIE_PORT_SERVICE_HP) && - dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { + if (cap_mask & PCIE_PORT_SERVICE_HP) { pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) { services |= PCIE_PORT_SERVICE_HP; diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 9b8505ccc56d..eb907a8faf2a 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/drivers/pci/proc.c @@ -76,8 +76,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp if (!access_ok(VERIFY_WRITE, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); @@ -123,8 +121,6 @@ proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *pp cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; return nbytes; } @@ -150,8 +146,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof if (!access_ok(VERIFY_READ, buf, cnt)) return -EINVAL; - pci_config_pm_runtime_get(dev); - if ((pos & 1) && cnt) { unsigned char val; __get_user(val, buf); @@ -197,8 +191,6 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof cnt--; } - pci_config_pm_runtime_put(dev); - *ppos = pos; i_size_write(ino, dp->size); return nbytes; diff --git a/trunk/drivers/pinctrl/Kconfig b/trunk/drivers/pinctrl/Kconfig index d96caefd914a..7bf914df6e91 100644 --- a/trunk/drivers/pinctrl/Kconfig +++ b/trunk/drivers/pinctrl/Kconfig @@ -179,13 +179,11 @@ config PINCTRL_COH901 config PINCTRL_SAMSUNG bool "Samsung pinctrl driver" - depends on OF && GPIOLIB select PINMUX select PINCONF config PINCTRL_EXYNOS4 bool "Pinctrl driver data for Exynos4 SoC" - depends on OF && GPIOLIB select PINCTRL_SAMSUNG config PINCTRL_MVEBU diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear.c b/trunk/drivers/pinctrl/spear/pinctrl-spear.c index b1fd6ee33c6c..5d4f44f462f0 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear.c @@ -244,7 +244,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, else temp = ~muxreg->val; - val |= muxreg->mask & temp; + val |= temp; pmx_writel(pmx, val, muxreg->reg); } } diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c index 0436fc7895d6..d6cca8c81b92 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -25,8 +25,8 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { }; /* registers */ -#define PERIP_CFG 0x3B0 - #define MCIF_SEL_SHIFT 5 +#define PERIP_CFG 0x32C + #define MCIF_SEL_SHIFT 3 #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT) #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT) #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT) @@ -164,10 +164,6 @@ static const struct pinctrl_pin_desc spear1310_pins[] = { #define PMX_SSP0_CS0_MASK (1 << 29) #define PMX_SSP0_CS1_2_MASK (1 << 30) -#define PAD_DIRECTION_SEL_0 0x65C -#define PAD_DIRECTION_SEL_1 0x660 -#define PAD_DIRECTION_SEL_2 0x664 - /* combined macros */ #define PMX_GMII_MASK (PMX_GMIICLK_MASK | \ PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \ @@ -241,10 +237,6 @@ static struct spear_muxreg i2c0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = PMX_I2C0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -277,10 +269,6 @@ static struct spear_muxreg ssp0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SSP0_MASK, .val = PMX_SSP0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SSP0_MASK, - .val = PMX_SSP0_MASK, }, }; @@ -306,10 +294,6 @@ static struct spear_muxreg ssp0_cs0_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS0_MASK, .val = PMX_SSP0_CS0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS0_MASK, - .val = PMX_SSP0_CS0_MASK, }, }; @@ -335,10 +319,6 @@ static struct spear_muxreg ssp0_cs1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_SSP0_CS1_2_MASK, .val = PMX_SSP0_CS1_2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_SSP0_CS1_2_MASK, - .val = PMX_SSP0_CS1_2_MASK, }, }; @@ -372,10 +352,6 @@ static struct spear_muxreg i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = PMX_I2S0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -408,10 +384,6 @@ static struct spear_muxreg i2s1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK, .val = PMX_I2S1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK, - .val = PMX_I2S1_MASK, }, }; @@ -446,10 +418,6 @@ static struct spear_muxreg clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = PMX_CLCD1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -475,10 +443,6 @@ static struct spear_muxreg clcd_high_res_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_CLCD2_MASK, .val = PMX_CLCD2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_CLCD2_MASK, - .val = PMX_CLCD2_MASK, }, }; @@ -497,7 +461,7 @@ static struct spear_pingroup clcd_high_res_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux), }; -static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res_grp" }; +static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -515,14 +479,6 @@ static struct spear_muxreg arm_gpio_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_EGPIO_1_GRP_MASK, .val = PMX_EGPIO_1_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_EGPIO_0_GRP_MASK, - .val = PMX_EGPIO_0_GRP_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_EGPIO_1_GRP_MASK, - .val = PMX_EGPIO_1_GRP_MASK, }, }; @@ -555,10 +511,6 @@ static struct spear_muxreg smi_2_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -587,14 +539,6 @@ static struct spear_muxreg smi_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, - .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK, }, }; @@ -629,10 +573,6 @@ static struct spear_muxreg gmii_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_GMII_MASK, .val = PMX_GMII_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_GMII_MASK, - .val = PMX_GMII_MASK, }, }; @@ -675,18 +615,6 @@ static struct spear_muxreg rgmii_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_RGMII_REG2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_RGMII_REG0_MASK, - .val = PMX_RGMII_REG0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_RGMII_REG1_MASK, - .val = PMX_RGMII_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_RGMII_REG2_MASK, - .val = PMX_RGMII_REG2_MASK, }, }; @@ -721,10 +649,6 @@ static struct spear_muxreg smii_0_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_SMII_0_1_2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_SMII_0_1_2_MASK, - .val = PMX_SMII_0_1_2_MASK, }, }; @@ -757,10 +681,6 @@ static struct spear_muxreg ras_mii_txclk_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFCE2_MASK, - .val = PMX_NFCE2_MASK, }, }; @@ -801,14 +721,6 @@ static struct spear_muxreg nand_8bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND8BIT_1_MASK, .val = PMX_NAND8BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NAND8BIT_0_MASK, - .val = PMX_NAND8BIT_0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND8BIT_1_MASK, - .val = PMX_NAND8BIT_1_MASK, }, }; @@ -835,10 +747,6 @@ static struct spear_muxreg nand_16bit_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND16BIT_1_MASK, .val = PMX_NAND16BIT_1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND16BIT_1_MASK, - .val = PMX_NAND16BIT_1_MASK, }, }; @@ -864,10 +772,6 @@ static struct spear_muxreg nand_4_chips_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NAND_4CHIPS_MASK, .val = PMX_NAND_4CHIPS_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NAND_4CHIPS_MASK, - .val = PMX_NAND_4CHIPS_MASK, }, }; @@ -929,10 +833,6 @@ static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL68_MASK, .val = PMX_KBD_ROWCOL68_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL68_MASK, - .val = PMX_KBD_ROWCOL68_MASK, }, }; @@ -966,10 +866,6 @@ static struct spear_muxreg uart0_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_UART0_MASK, .val = PMX_UART0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_UART0_MASK, - .val = PMX_UART0_MASK, }, }; @@ -995,10 +891,6 @@ static struct spear_muxreg uart0_modem_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_UART0_MODEM_MASK, .val = PMX_UART0_MODEM_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_UART0_MODEM_MASK, - .val = PMX_UART0_MODEM_MASK, }, }; @@ -1031,10 +923,6 @@ static struct spear_muxreg gpt0_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR0_MASK, .val = PMX_GPT0_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR0_MASK, - .val = PMX_GPT0_TMR0_MASK, }, }; @@ -1060,10 +948,6 @@ static struct spear_muxreg gpt0_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT0_TMR1_MASK, .val = PMX_GPT0_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT0_TMR1_MASK, - .val = PMX_GPT0_TMR1_MASK, }, }; @@ -1096,10 +980,6 @@ static struct spear_muxreg gpt1_tmr0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR0_MASK, .val = PMX_GPT1_TMR0_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR0_MASK, - .val = PMX_GPT1_TMR0_MASK, }, }; @@ -1125,10 +1005,6 @@ static struct spear_muxreg gpt1_tmr1_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_GPT1_TMR1_MASK, .val = PMX_GPT1_TMR1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_GPT1_TMR1_MASK, - .val = PMX_GPT1_TMR1_MASK, }, }; @@ -1173,20 +1049,6 @@ static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214, .reg = PAD_FUNCTION_EN_2, \ .mask = PMX_MCIFALL_2_MASK, \ .val = PMX_MCIFALL_2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_0, \ - .mask = PMX_MCI_DATA8_15_MASK, \ - .val = PMX_MCI_DATA8_15_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_1, \ - .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - .val = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \ - PMX_NFWPRT2_MASK, \ - }, { \ - .reg = PAD_DIRECTION_SEL_2, \ - .mask = PMX_MCIFALL_2_MASK, \ - .val = PMX_MCIFALL_2_MASK, \ } /* sdhci device */ @@ -1292,10 +1154,6 @@ static struct spear_muxreg touch_xy_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_TOUCH_XY_MASK, .val = PMX_TOUCH_XY_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_TOUCH_XY_MASK, - .val = PMX_TOUCH_XY_MASK, }, }; @@ -1329,10 +1187,6 @@ static struct spear_muxreg uart1_dis_i2c_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2C0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2C0_MASK, - .val = PMX_I2C0_MASK, }, }; @@ -1359,12 +1213,6 @@ static struct spear_muxreg uart1_dis_sd_muxreg[] = { .mask = PMX_MCIDATA1_MASK | PMX_MCIDATA2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, - .val = PMX_MCIDATA1_MASK | - PMX_MCIDATA2_MASK, }, }; @@ -1398,10 +1246,6 @@ static struct spear_muxreg uart2_3_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK, - .val = PMX_I2S0_MASK, }, }; @@ -1434,10 +1278,6 @@ static struct spear_muxreg uart4_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK, - .val = PMX_I2S0_MASK | PMX_CLCD1_MASK, }, }; @@ -1470,10 +1310,6 @@ static struct spear_muxreg uart5_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1508,10 +1344,6 @@ static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1544,10 +1376,6 @@ static struct spear_muxreg i2c_1_2_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK, - .val = PMX_CLCD1_MASK, }, }; @@ -1581,10 +1409,6 @@ static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_CLCD1_MASK | PMX_SMI_MASK, - .val = PMX_CLCD1_MASK | PMX_SMI_MASK, }, }; @@ -1611,10 +1435,6 @@ static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, - .val = PMX_I2S1_MASK | PMX_MCIDATA3_MASK, }, }; @@ -1649,10 +1469,6 @@ static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = { .reg = PAD_FUNCTION_EN_0, .mask = PMX_SMI_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_SMI_MASK, - .val = PMX_SMI_MASK, }, }; @@ -1683,14 +1499,6 @@ static struct spear_muxreg i2c4_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCIDATA5_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_MCIDATA4_MASK, - .val = PMX_MCIDATA4_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA5_MASK, - .val = PMX_MCIDATA5_MASK, }, }; @@ -1718,12 +1526,6 @@ static struct spear_muxreg i2c5_dis_sd_muxreg[] = { .mask = PMX_MCIDATA6_MASK | PMX_MCIDATA7_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, - .val = PMX_MCIDATA6_MASK | - PMX_MCIDATA7_MASK, }, }; @@ -1758,10 +1560,6 @@ static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1789,12 +1587,6 @@ static struct spear_muxreg i2c6_dis_sd_muxreg[] = { .mask = PMX_MCIIORDRE_MASK | PMX_MCIIOWRWE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, - .val = PMX_MCIIORDRE_MASK | - PMX_MCIIOWRWE_MASK, }, }; @@ -1821,12 +1613,6 @@ static struct spear_muxreg i2c7_dis_sd_muxreg[] = { .mask = PMX_MCIRESETCF_MASK | PMX_MCICS0CE_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, - .val = PMX_MCIRESETCF_MASK | - PMX_MCICS0CE_MASK, }, }; @@ -1865,14 +1651,6 @@ static struct spear_muxreg can0_dis_nor_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_NFRSTPWDWN3_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_NFRSTPWDWN2_MASK, - .val = PMX_NFRSTPWDWN2_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_NFRSTPWDWN3_MASK, - .val = PMX_NFRSTPWDWN3_MASK, }, }; @@ -1899,10 +1677,6 @@ static struct spear_muxreg can0_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, - .val = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK, }, }; @@ -1937,10 +1711,6 @@ static struct spear_muxreg can1_dis_sd_muxreg[] = { .reg = PAD_FUNCTION_EN_2, .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, - .val = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK, }, }; @@ -1967,10 +1737,6 @@ static struct spear_muxreg can1_dis_kbd_muxreg[] = { .reg = PAD_FUNCTION_EN_1, .mask = PMX_KBD_ROWCOL25_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK, - .val = PMX_KBD_ROWCOL25_MASK, }, }; @@ -1997,64 +1763,29 @@ static struct spear_function can1_function = { .ngroups = ARRAY_SIZE(can1_grps), }; -/* Pad multiplexing for (ras-ip) pci device */ -static const unsigned pci_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, +/* Pad multiplexing for pci device */ +static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }; +#define PCI_SATA_MUXREG \ + { \ + .reg = PAD_FUNCTION_EN_0, \ + .mask = PMX_MCI_DATA8_15_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_1, \ + .mask = PMX_PCI_REG1_MASK, \ + .val = 0, \ + }, { \ + .reg = PAD_FUNCTION_EN_2, \ + .mask = PMX_PCI_REG2_MASK, \ + .val = 0, \ + } -static struct spear_muxreg pci_muxreg[] = { - { - .reg = PAD_FUNCTION_EN_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_1, - .mask = PMX_PCI_REG1_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_2, - .mask = PMX_PCI_REG2_MASK, - .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_0, - .mask = PMX_MCI_DATA8_15_MASK, - .val = PMX_MCI_DATA8_15_MASK, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_PCI_REG1_MASK, - .val = PMX_PCI_REG1_MASK, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_PCI_REG2_MASK, - .val = PMX_PCI_REG2_MASK, - }, -}; - -static struct spear_modemux pci_modemux[] = { - { - .muxregs = pci_muxreg, - .nmuxregs = ARRAY_SIZE(pci_muxreg), - }, -}; - -static struct spear_pingroup pci_pingroup = { - .name = "pci_grp", - .pins = pci_pins, - .npins = ARRAY_SIZE(pci_pins), - .modemuxs = pci_modemux, - .nmodemuxs = ARRAY_SIZE(pci_modemux), -}; - -static const char *const pci_grps[] = { "pci_grp" }; -static struct spear_function pci_function = { - .name = "pci", - .groups = pci_grps, - .ngroups = ARRAY_SIZE(pci_grps), -}; - -/* pad multiplexing for (fix-part) pcie0 device */ +/* pad multiplexing for pcie0 device */ static struct spear_muxreg pcie0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(0), @@ -2071,12 +1802,15 @@ static struct spear_modemux pcie0_modemux[] = { static struct spear_pingroup pcie0_pingroup = { .name = "pcie0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie0_modemux, .nmodemuxs = ARRAY_SIZE(pcie0_modemux), }; -/* pad multiplexing for (fix-part) pcie1 device */ +/* pad multiplexing for pcie1 device */ static struct spear_muxreg pcie1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(1), @@ -2093,12 +1827,15 @@ static struct spear_modemux pcie1_modemux[] = { static struct spear_pingroup pcie1_pingroup = { .name = "pcie1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie1_modemux, .nmodemuxs = ARRAY_SIZE(pcie1_modemux), }; -/* pad multiplexing for (fix-part) pcie2 device */ +/* pad multiplexing for pcie2 device */ static struct spear_muxreg pcie2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = PCIE_CFG_VAL(2), @@ -2115,20 +1852,22 @@ static struct spear_modemux pcie2_modemux[] = { static struct spear_pingroup pcie2_pingroup = { .name = "pcie2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = pcie2_modemux, .nmodemuxs = ARRAY_SIZE(pcie2_modemux), }; -static const char *const pcie_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" -}; -static struct spear_function pcie_function = { - .name = "pci_express", - .groups = pcie_grps, - .ngroups = ARRAY_SIZE(pcie_grps), +static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" }; +static struct spear_function pci_function = { + .name = "pci", + .groups = pci_grps, + .ngroups = ARRAY_SIZE(pci_grps), }; /* pad multiplexing for sata0 device */ static struct spear_muxreg sata0_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(0), @@ -2145,12 +1884,15 @@ static struct spear_modemux sata0_modemux[] = { static struct spear_pingroup sata0_pingroup = { .name = "sata0_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata0_modemux, .nmodemuxs = ARRAY_SIZE(sata0_modemux), }; /* pad multiplexing for sata1 device */ static struct spear_muxreg sata1_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(1), @@ -2167,12 +1909,15 @@ static struct spear_modemux sata1_modemux[] = { static struct spear_pingroup sata1_pingroup = { .name = "sata1_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata1_modemux, .nmodemuxs = ARRAY_SIZE(sata1_modemux), }; /* pad multiplexing for sata2 device */ static struct spear_muxreg sata2_muxreg[] = { + PCI_SATA_MUXREG, { .reg = PCIE_SATA_CFG, .mask = SATA_CFG_VAL(2), @@ -2189,6 +1934,8 @@ static struct spear_modemux sata2_modemux[] = { static struct spear_pingroup sata2_pingroup = { .name = "sata2_grp", + .pins = pci_sata_pins, + .npins = ARRAY_SIZE(pci_sata_pins), .modemuxs = sata2_modemux, .nmodemuxs = ARRAY_SIZE(sata2_modemux), }; @@ -2210,14 +1957,6 @@ static struct spear_muxreg ssp1_dis_kbd_muxreg[] = { PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | PMX_NFCE2_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_1, - .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, - .val = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK | - PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK | - PMX_NFCE2_MASK, }, }; @@ -2244,12 +1983,6 @@ static struct spear_muxreg ssp1_dis_sd_muxreg[] = { .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | PMX_MCICECF_MASK | PMX_MCICEXD_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, - .val = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK | - PMX_MCICECF_MASK | PMX_MCICEXD_MASK, }, }; @@ -2284,12 +2017,6 @@ static struct spear_muxreg gpt64_muxreg[] = { .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK | PMX_MCILEDS_MASK, .val = 0, - }, { - .reg = PAD_DIRECTION_SEL_2, - .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, - .val = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK - | PMX_MCILEDS_MASK, }, }; @@ -2366,7 +2093,6 @@ static struct spear_pingroup *spear1310_pingroups[] = { &can0_dis_sd_pingroup, &can1_dis_sd_pingroup, &can1_dis_kbd_pingroup, - &pci_pingroup, &pcie0_pingroup, &pcie1_pingroup, &pcie2_pingroup, @@ -2412,7 +2138,6 @@ static struct spear_function *spear1310_functions[] = { &can0_function, &can1_function, &pci_function, - &pcie_function, &sata_function, &ssp1_function, &gpt64_function, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c index 0606b8cf3f2c..a0eb057e55bd 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -213,7 +213,7 @@ static const struct pinctrl_pin_desc spear1340_pins[] = { * Pad multiplexing for making all pads as gpio's. This is done to override the * values passed from bootloader and start from scratch. */ -static const unsigned pads_as_gpio_pins[] = { 12, 88, 89, 251 }; +static const unsigned pads_as_gpio_pins[] = { 251 }; static struct spear_muxreg pads_as_gpio_muxreg[] = { { .reg = PAD_FUNCTION_EN_1, @@ -1692,43 +1692,7 @@ static struct spear_pingroup clcd_pingroup = { .nmodemuxs = ARRAY_SIZE(clcd_modemux), }; -/* Disable cld runtime to save panel damage */ -static struct spear_muxreg clcd_sleep_muxreg[] = { - { - .reg = PAD_SHARED_IP_EN_1, - .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK, - .val = 0, - }, { - .reg = PAD_FUNCTION_EN_5, - .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_6, - .mask = CLCD_AND_ARM_TRACE_REG5_MASK, - .val = 0x0, - }, { - .reg = PAD_FUNCTION_EN_7, - .mask = CLCD_AND_ARM_TRACE_REG6_MASK, - .val = 0x0, - }, -}; - -static struct spear_modemux clcd_sleep_modemux[] = { - { - .muxregs = clcd_sleep_muxreg, - .nmuxregs = ARRAY_SIZE(clcd_sleep_muxreg), - }, -}; - -static struct spear_pingroup clcd_sleep_pingroup = { - .name = "clcd_sleep_grp", - .pins = clcd_pins, - .npins = ARRAY_SIZE(clcd_pins), - .modemuxs = clcd_sleep_modemux, - .nmodemuxs = ARRAY_SIZE(clcd_sleep_modemux), -}; - -static const char *const clcd_grps[] = { "clcd_grp", "clcd_sleep_grp" }; +static const char *const clcd_grps[] = { "clcd_grp" }; static struct spear_function clcd_function = { .name = "clcd", .groups = clcd_grps, @@ -1929,7 +1893,6 @@ static struct spear_pingroup *spear1340_pingroups[] = { &sdhci_pingroup, &cf_pingroup, &xd_pingroup, - &clcd_sleep_pingroup, &clcd_pingroup, &arm_trace_pingroup, &miphy_dbg_pingroup, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c index ca47b0e50780..020b1e0bdb3e 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2239,10 +2239,6 @@ static struct spear_muxreg pwm2_pin_34_muxreg[] = { .reg = PMX_CONFIG_REG, .mask = PMX_SSP_CS_MASK, .val = 0, - }, { - .reg = MODE_CONFIG_REG, - .mask = PMX_PWM_MASK, - .val = PMX_PWM_MASK, }, { .reg = IP_SEL_PAD_30_39_REG, .mask = PMX_PL_34_MASK, @@ -2960,9 +2956,9 @@ static struct spear_function mii2_function = { }; /* Pad multiplexing for cadence mii 1_2 as smii or rmii device */ -static const unsigned rmii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, +static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 }; -static const unsigned smii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; +static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 }; static struct spear_muxreg mii0_1_muxreg[] = { { .reg = PMX_CONFIG_REG, diff --git a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h index 7860b36053c4..31f44347f17c 100644 --- a/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/trunk/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -15,7 +15,6 @@ #include "pinctrl-spear.h" /* pad mux declarations */ -#define PMX_PWM_MASK (1 << 16) #define PMX_FIRDA_MASK (1 << 14) #define PMX_I2C_MASK (1 << 13) #define PMX_SSP_CS_MASK (1 << 12) diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index 4af3dfe70ef5..33bb4d891e16 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -112,6 +112,9 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); +#define __MAX_SUBCHANNEL 65535 +#define __MAX_SSID 3 + struct channel_subsystem { u8 cssid; int valid; diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index fd3143c291c6..fc916f5d7314 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) } if (device_is_disconnected(cdev)) return IO_SCH_REPROBE; - if (cdev->online && !cdev->private->flags.resuming) + if (cdev->online) return IO_SCH_VERIFY; if (cdev->private->state == DEV_STATE_NOT_OPER) return IO_SCH_UNREG_ATTACH; @@ -1469,6 +1469,12 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) rc = 0; goto out_unlock; case IO_SCH_VERIFY: + if (cdev->private->flags.resuming == 1) { + if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { + ccw_device_set_notoper(cdev); + break; + } + } /* Trigger path verification. */ io_subchannel_verify(sch); rc = 0; diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index 65d13e38803f..199bc6791177 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -125,7 +125,8 @@ int idset_is_empty(struct idset *set) void idset_add_set(struct idset *to, struct idset *from) { - int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); + int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), + __BITOPS_WORDS(from->num_ssid * from->num_id)); bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); } diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 71fddbc60f18..b191dd549207 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1294,19 +1294,26 @@ static struct scsi_host_template qpti_template = { static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; + struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; const char *fcode; + match = of_match_device(qpti_match, &op->dev); + if (!match) + return -EINVAL; + tpnt = match->data; + /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ if (op->archdata.irqs[0] == 0) return -ENODEV; - host = scsi_host_alloc(&qpti_template, sizeof(struct qlogicpti)); + host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); if (!host) return -ENOMEM; @@ -1438,15 +1445,19 @@ static int __devexit qpti_sbus_remove(struct platform_device *op) static const struct of_device_id qpti_match[] = { { .name = "ptisp", + .data = &qpti_template, }, { .name = "PTI,ptisp", + .data = &qpti_template, }, { .name = "QLGC,isp", + .data = &qpti_template, }, { .name = "SUNW,isp", + .data = &qpti_template, }, {}, }; diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 035c2c762537..d6ce2182e672 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -3719,9 +3719,7 @@ int iscsi_target_tx_thread(void *arg) */ iscsit_thread_check_cpumask(conn, current, 1); - wait_event_interruptible(conn->queues_wq, - !iscsit_conn_all_queues_empty(conn) || - ts->status == ISCSI_THREAD_SET_RESET); + schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); if ((ts->status == ISCSI_THREAD_SET_RESET) || signal_pending(current)) diff --git a/trunk/drivers/target/iscsi/iscsi_target_core.h b/trunk/drivers/target/iscsi/iscsi_target_core.h index 21048dbf7d13..2ba9f9b9435c 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_core.h +++ b/trunk/drivers/target/iscsi/iscsi_target_core.h @@ -486,7 +486,6 @@ struct iscsi_tmr_req { }; struct iscsi_conn { - wait_queue_head_t queues_wq; /* Authentication Successful for this connection */ u8 auth_complete; /* State connection is currently in */ diff --git a/trunk/drivers/target/iscsi/iscsi_target_login.c b/trunk/drivers/target/iscsi/iscsi_target_login.c index f8dbec05d5e5..cdc8a10939c3 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_login.c +++ b/trunk/drivers/target/iscsi/iscsi_target_login.c @@ -41,7 +41,6 @@ static int iscsi_login_init_conn(struct iscsi_conn *conn) { - init_waitqueue_head(&conn->queues_wq); INIT_LIST_HEAD(&conn->conn_list); INIT_LIST_HEAD(&conn->conn_cmd_list); INIT_LIST_HEAD(&conn->immed_queue_list); diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.c b/trunk/drivers/target/iscsi/iscsi_target_util.c index 1a91195ab619..afd98ccd40ae 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.c +++ b/trunk/drivers/target/iscsi/iscsi_target_util.c @@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue( atomic_set(&conn->check_immediate_queue, 1); spin_unlock_bh(&conn->immed_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) @@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue( atomic_inc(&cmd->response_queue_count); spin_unlock_bh(&conn->response_queue_lock); - wake_up(&conn->queues_wq); + wake_up_process(conn->thread_set->tx_thread); } struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) @@ -616,24 +616,6 @@ static void iscsit_remove_cmd_from_response_queue( } } -bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) -{ - bool empty; - - spin_lock_bh(&conn->immed_queue_lock); - empty = list_empty(&conn->immed_queue_list); - spin_unlock_bh(&conn->immed_queue_lock); - - if (!empty) - return empty; - - spin_lock_bh(&conn->response_queue_lock); - empty = list_empty(&conn->response_queue_list); - spin_unlock_bh(&conn->response_queue_lock); - - return empty; -} - void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) { struct iscsi_queue_req *qr, *qr_tmp; diff --git a/trunk/drivers/target/iscsi/iscsi_target_util.h b/trunk/drivers/target/iscsi/iscsi_target_util.h index 894d0f837924..44054bd35437 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_util.h +++ b/trunk/drivers/target/iscsi/iscsi_target_util.h @@ -25,7 +25,6 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_ extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8); extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *); extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); -extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); extern void iscsit_release_cmd(struct iscsi_cmd *); extern void iscsit_free_cmd(struct iscsi_cmd *); diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index c123327499a3..015f5be27bf6 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -3206,8 +3206,7 @@ static int __init target_core_init_configfs(void) if (ret < 0) goto out; - ret = core_dev_setup_virtual_lun0(); - if (ret < 0) + if (core_dev_setup_virtual_lun0() < 0) goto out; return 0; diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 9abef9f8eb76..8d774da16320 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev) static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size) { - u32 aligned_max_sectors; - u32 alignment; + u32 tmp, aligned_max_sectors; /* * Limit max_sectors to a PAGE_SIZE aligned value for modern * transport_allocate_data_tasks() operation. */ - alignment = max(1ul, PAGE_SIZE / block_size); - aligned_max_sectors = rounddown(max_sectors, alignment); - - if (max_sectors != aligned_max_sectors) - pr_info("Rounding down aligned max_sectors from %u to %u\n", - max_sectors, aligned_max_sectors); + tmp = rounddown((max_sectors * block_size), PAGE_SIZE); + aligned_max_sectors = (tmp / block_size); + if (max_sectors != aligned_max_sectors) { + printk(KERN_INFO "Rounding down aligned max_sectors from %u" + " to %u\n", max_sectors, aligned_max_sectors); + return aligned_max_sectors; + } - return aligned_max_sectors; + return max_sectors; } void se_dev_set_default_attribs( diff --git a/trunk/drivers/target/target_core_spc.c b/trunk/drivers/target/target_core_spc.c index 6fd434d3d7e4..9229bd9ad61b 100644 --- a/trunk/drivers/target/target_core_spc.c +++ b/trunk/drivers/target/target_core_spc.c @@ -605,8 +605,6 @@ static int spc_emulate_inquiry(struct se_cmd *cmd) unsigned char buf[SE_INQUIRY_BUF]; int p, ret; - memset(buf, 0, SE_INQUIRY_BUF); - if (dev == tpg->tpg_virt_lun0.lun_se_dev) buf[0] = 0x3f; /* Not connected */ else diff --git a/trunk/drivers/target/target_core_tmr.c b/trunk/drivers/target/target_core_tmr.c index be75c4331a92..1c59a3c23b2c 100644 --- a/trunk/drivers/target/target_core_tmr.c +++ b/trunk/drivers/target/target_core_tmr.c @@ -140,15 +140,15 @@ void core_tmr_abort_task( printk("ABORT_TASK: Found referenced %s task_tag: %u\n", se_cmd->se_tfo->get_fabric_name(), ref_tag); - spin_lock(&se_cmd->t_state_lock); + spin_lock_irq(&se_cmd->t_state_lock); if (se_cmd->transport_state & CMD_T_COMPLETE) { printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); goto out; } se_cmd->transport_state |= CMD_T_ABORTED; - spin_unlock(&se_cmd->t_state_lock); + spin_unlock_irq(&se_cmd->t_state_lock); list_del_init(&se_cmd->se_cmd_list); kref_get(&se_cmd->cmd_kref); diff --git a/trunk/drivers/thermal/exynos_thermal.c b/trunk/drivers/thermal/exynos_thermal.c index 6dd29e4ce36b..fd03e8581afc 100644 --- a/trunk/drivers/thermal/exynos_thermal.c +++ b/trunk/drivers/thermal/exynos_thermal.c @@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = { }, { }, }; -MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids); +MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids); static inline struct exynos_tmu_platform_data *exynos_get_driver_data( struct platform_device *pdev) diff --git a/trunk/drivers/thermal/rcar_thermal.c b/trunk/drivers/thermal/rcar_thermal.c index f7a1b574a304..d4452716aaab 100644 --- a/trunk/drivers/thermal/rcar_thermal.c +++ b/trunk/drivers/thermal/rcar_thermal.c @@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) goto error_free_priv; } - zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv, + zone = thermal_zone_device_register("rcar_thermal", 0, priv, &rcar_thermal_zone_ops, 0, 0); if (IS_ERR(zone)) { dev_err(&pdev->dev, "thermal zone device is NULL\n"); diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index 4ec3c0d7a18b..6458764994ef 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "u_ether.h" @@ -296,7 +295,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); diff --git a/trunk/drivers/video/xen-fbfront.c b/trunk/drivers/video/xen-fbfront.c index 917bb5681684..b7f5173ff9e9 100644 --- a/trunk/drivers/video/xen-fbfront.c +++ b/trunk/drivers/video/xen-fbfront.c @@ -641,6 +641,7 @@ static void xenfb_backend_changed(struct xenbus_device *dev, case XenbusStateReconfiguring: case XenbusStateReconfigured: case XenbusStateUnknown: + case XenbusStateClosed: break; case XenbusStateInitWait: @@ -669,10 +670,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, info->feature_resize = val; break; - case XenbusStateClosed: - if (dev->state == XenbusStateClosed) - break; - /* Missed the backend's CLOSING state -- fallthrough */ case XenbusStateClosing: xenbus_frontend_closed(dev); break; diff --git a/trunk/drivers/virtio/virtio.c b/trunk/drivers/virtio/virtio.c index 809b0de59c09..1e8659ca27ef 100644 --- a/trunk/drivers/virtio/virtio.c +++ b/trunk/drivers/virtio/virtio.c @@ -225,10 +225,8 @@ EXPORT_SYMBOL_GPL(register_virtio_device); void unregister_virtio_device(struct virtio_device *dev) { - int index = dev->index; /* save for after device release */ - device_unregister(&dev->dev); - ida_simple_remove(&virtio_index_ida, index); + ida_simple_remove(&virtio_index_ida, dev->index); } EXPORT_SYMBOL_GPL(unregister_virtio_device); diff --git a/trunk/drivers/xen/Makefile b/trunk/drivers/xen/Makefile index 74354708c6c4..0e8637035457 100644 --- a/trunk/drivers/xen/Makefile +++ b/trunk/drivers/xen/Makefile @@ -2,7 +2,6 @@ ifneq ($(CONFIG_ARM),y) obj-y += manage.o balloon.o obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o endif -obj-$(CONFIG_X86) += fallback.o obj-y += grant-table.o features.o events.o obj-y += xenbus/ diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 0be4df39e953..912ac81b6dbf 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -1395,10 +1395,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - irq_enter(); #ifdef CONFIG_X86 exit_idle(); #endif + irq_enter(); __xen_evtchn_do_upcall(); diff --git a/trunk/drivers/xen/fallback.c b/trunk/drivers/xen/fallback.c deleted file mode 100644 index 0ef7c4d40f86..000000000000 --- a/trunk/drivers/xen/fallback.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int xen_event_channel_op_compat(int cmd, void *arg) -{ - struct evtchn_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, event_channel_op_compat, &op); - - switch (cmd) { - case EVTCHNOP_close: - case EVTCHNOP_send: - case EVTCHNOP_bind_vcpu: - case EVTCHNOP_unmask: - /* no output */ - break; - -#define COPY_BACK(eop) \ - case EVTCHNOP_##eop: \ - memcpy(arg, &op.u.eop, sizeof(op.u.eop)); \ - break - - COPY_BACK(bind_interdomain); - COPY_BACK(bind_virq); - COPY_BACK(bind_pirq); - COPY_BACK(status); - COPY_BACK(alloc_unbound); - COPY_BACK(bind_ipi); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} -EXPORT_SYMBOL_GPL(xen_event_channel_op_compat); - -int HYPERVISOR_physdev_op_compat(int cmd, void *arg) -{ - struct physdev_op op; - int rc; - - op.cmd = cmd; - memcpy(&op.u, arg, sizeof(op.u)); - rc = _hypercall1(int, physdev_op_compat, &op); - - switch (cmd) { - case PHYSDEVOP_IRQ_UNMASK_NOTIFY: - case PHYSDEVOP_set_iopl: - case PHYSDEVOP_set_iobitmap: - case PHYSDEVOP_apic_write: - /* no output */ - break; - -#define COPY_BACK(pop, fld) \ - case PHYSDEVOP_##pop: \ - memcpy(arg, &op.u.fld, sizeof(op.u.fld)); \ - break - - COPY_BACK(irq_status_query, irq_status_query); - COPY_BACK(apic_read, apic_op); - COPY_BACK(ASSIGN_VECTOR, irq_op); -#undef COPY_BACK - - default: - WARN_ON(rc != -ENOSYS); - break; - } - - return rc; -} diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 2e22df2f7a3f..610bfc6be177 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -105,21 +105,6 @@ static void gntdev_print_maps(struct gntdev_priv *priv, #endif } -static void gntdev_free_map(struct grant_map *map) -{ - if (map == NULL) - return; - - if (map->pages) - free_xenballooned_pages(map->count, map->pages); - kfree(map->pages); - kfree(map->grants); - kfree(map->map_ops); - kfree(map->unmap_ops); - kfree(map->kmap_ops); - kfree(map); -} - static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) { struct grant_map *add; @@ -157,7 +142,12 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) return add; err: - gntdev_free_map(add); + kfree(add->pages); + kfree(add->grants); + kfree(add->map_ops); + kfree(add->unmap_ops); + kfree(add->kmap_ops); + kfree(add); return NULL; } @@ -208,9 +198,17 @@ static void gntdev_put_map(struct grant_map *map) evtchn_put(map->notify.event); } - if (map->pages && !use_ptemod) - unmap_grant_pages(map, 0, map->count); - gntdev_free_map(map); + if (map->pages) { + if (!use_ptemod) + unmap_grant_pages(map, 0, map->count); + + free_xenballooned_pages(map->count, map->pages); + } + kfree(map->pages); + kfree(map->grants); + kfree(map->map_ops); + kfree(map->unmap_ops); + kfree(map); } /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c index ac727028e658..89f76252a16f 100644 --- a/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp, goto out; /* Can't write a xenbus message larger we can buffer */ - if (len > sizeof(u->u.buffer) - u->len) { + if ((len + u->len) > sizeof(u->u.buffer)) { /* On error, dump existing buffer */ u->len = 0; rc = -EINVAL; diff --git a/trunk/fs/cifs/cifsacl.c b/trunk/fs/cifs/cifsacl.c index 0fb15bbbe43c..fc783e264420 100644 --- a/trunk/fs/cifs/cifsacl.c +++ b/trunk/fs/cifs/cifsacl.c @@ -224,13 +224,6 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr) } } -static void -cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) -{ - memcpy(dst, src, sizeof(*dst)); - dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS); -} - static void id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, struct cifs_sid_id **psidid, char *typestr) @@ -255,7 +248,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, } } - cifs_copy_sid(&(*psidid)->sid, sidptr); + memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); (*psidid)->refcount = 0; @@ -361,7 +354,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) * any fields of the node after a reference is put . */ if (test_bit(SID_ID_MAPPED, &psidid->state)) { - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); psidid->time = jiffies; /* update ts for accessing */ goto id_sid_out; } @@ -377,14 +370,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) if (IS_ERR(sidkey)) { rc = -EINVAL; cFYI(1, "%s: Can't map and id to a SID", __func__); - } else if (sidkey->datalen < sizeof(struct cifs_sid)) { - rc = -EIO; - cFYI(1, "%s: Downcall contained malformed key " - "(datalen=%hu)", __func__, sidkey->datalen); } else { lsid = (struct cifs_sid *)sidkey->payload.data; - cifs_copy_sid(&psidid->sid, lsid); - cifs_copy_sid(ssid, &psidid->sid); + memcpy(&psidid->sid, lsid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); + memcpy(ssid, &psidid->sid, + sidkey->datalen < sizeof(struct cifs_sid) ? + sidkey->datalen : sizeof(struct cifs_sid)); set_bit(SID_ID_MAPPED, &psidid->state); key_put(sidkey); kfree(psidid->sidstr); @@ -403,7 +396,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid) return rc; } if (test_bit(SID_ID_MAPPED, &psidid->state)) - cifs_copy_sid(ssid, &psidid->sid); + memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid)); else rc = -EINVAL; } @@ -682,6 +675,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) static void copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, __u32 sidsoffset) { + int i; + struct cifs_sid *owner_sid_ptr, *group_sid_ptr; struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; @@ -697,14 +692,26 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd, owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->osidoffset)); nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); - cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + nowner_sid_ptr->revision = owner_sid_ptr->revision; + nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i]; /* copy group sid */ group_sid_ptr = (struct cifs_sid *)((char *)pntsd + le32_to_cpu(pntsd->gsidoffset)); ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + sizeof(struct cifs_sid)); - cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + + ngroup_sid_ptr->revision = group_sid_ptr->revision; + ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth; + for (i = 0; i < 6; i++) + ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i]; + for (i = 0; i < 5; i++) + ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i]; return; } @@ -1113,7 +1120,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(nowner_sid_ptr); return rc; } - cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr); + memcpy(owner_sid_ptr, nowner_sid_ptr, + sizeof(struct cifs_sid)); kfree(nowner_sid_ptr); *aclflag = CIFS_ACL_OWNER; } @@ -1131,7 +1139,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, kfree(ngroup_sid_ptr); return rc; } - cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr); + memcpy(group_sid_ptr, ngroup_sid_ptr, + sizeof(struct cifs_sid)); kfree(ngroup_sid_ptr); *aclflag = CIFS_ACL_GROUP; } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index d3671f2acb29..7c0a81283645 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -398,16 +398,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, * in network traffic in the other paths. */ if (!(oflags & O_CREAT)) { - struct dentry *res; - - /* - * Check for hashed negative dentry. We have already revalidated - * the dentry and it is fine. No need to perform another lookup. - */ - if (!d_unhashed(direntry)) - return -ENOENT; - - res = cifs_lookup(inode, direntry, 0); + struct dentry *res = cifs_lookup(inode, direntry, 0); if (IS_ERR(res)) return PTR_ERR(res); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index cd96649bfe62..da72250ddc1c 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p) /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ static inline int ep_op_has_event(int op) { - return op != EPOLL_CTL_DEL; + return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD; } /* Initialize the poll safe wake up structure */ @@ -676,6 +676,34 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) return 0; } +/* + * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item + * had no event flags set, indicating that another thread may be currently + * handling that item's events (in the case that EPOLLONESHOT was being + * used). Otherwise a zero result indicates that the item has been disabled + * from receiving events. A disabled item may be re-enabled via + * EPOLL_CTL_MOD. Must be called with "mtx" held. + */ +static int ep_disable(struct eventpoll *ep, struct epitem *epi) +{ + int result = 0; + unsigned long flags; + + spin_lock_irqsave(&ep->lock, flags); + if (epi->event.events & ~EP_PRIVATE_BITS) { + if (ep_is_linked(&epi->rdllink)) + list_del_init(&epi->rdllink); + /* Ensure ep_poll_callback will not add epi back onto ready + list: */ + epi->event.events &= EP_PRIVATE_BITS; + } + else + result = -EBUSY; + spin_unlock_irqrestore(&ep->lock, flags); + + return result; +} + static void ep_free(struct eventpoll *ep) { struct rb_node *rbp; @@ -1020,8 +1048,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) rb_insert_color(&epi->rbn, &ep->rbr); } - - #define PATH_ARR_SIZE 5 /* * These are the number paths of length 1 to 5, that we are allowing to emanate @@ -1787,6 +1813,12 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, } else error = -ENOENT; break; + case EPOLL_CTL_DISABLE: + if (epi) + error = ep_disable(ep, epi); + else + error = -ENOENT; + break; } mutex_unlock(&ep->mtx); diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index e056b4ce4877..0def0504afc1 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -516,13 +516,15 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) struct gfs2_holder i_gh; int error; - error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, - &i_gh); + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + error = gfs2_glock_nq(&i_gh); + if (error == 0) { + file_accessed(file); + gfs2_glock_dq(&i_gh); + } + gfs2_holder_uninit(&i_gh); if (error) return error; - /* grab lock to update inode */ - gfs2_glock_dq_uninit(&i_gh); - file_accessed(file); } vma->vm_ops = &gfs2_vm_ops; @@ -675,8 +677,10 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, size_t writesize = iov_length(iov, nr_segs); struct dentry *dentry = file->f_dentry; struct gfs2_inode *ip = GFS2_I(dentry->d_inode); + struct gfs2_sbd *sdp; int ret; + sdp = GFS2_SB(file->f_mapping->host); ret = gfs2_rs_alloc(ip); if (ret) return ret; diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index 9ceccb1595a3..8ff95a2d54ee 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -393,10 +393,12 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct gfs2_meta_header *mh; struct gfs2_trans *tr; + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); tr = current->journal_info; tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; @@ -412,6 +414,9 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) sdp->sd_log_num_buf++; list_add(&bd->bd_list, &sdp->sd_log_le_buf); tr->tr_num_buf_new++; +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } static void gfs2_check_magic(struct buffer_head *bh) @@ -616,6 +621,7 @@ static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) static void revoke_lo_before_commit(struct gfs2_sbd *sdp) { + struct gfs2_log_descriptor *ld; struct gfs2_meta_header *mh; unsigned int offset; struct list_head *head = &sdp->sd_log_le_revoke; @@ -628,6 +634,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) length = gfs2_struct2blk(sdp, sdp->sd_log_num_revoke, sizeof(u64)); page = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE, length, sdp->sd_log_num_revoke); + ld = page_address(page); offset = sizeof(struct gfs2_log_descriptor); list_for_each_entry(bd, head, bd_list) { @@ -770,10 +777,12 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) struct address_space *mapping = bd->bd_bh->b_page->mapping; struct gfs2_inode *ip = GFS2_I(mapping->host); + lock_buffer(bd->bd_bh); + gfs2_log_lock(sdp); if (tr) tr->tr_touched = 1; if (!list_empty(&bd->bd_list)) - return; + goto out; set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); if (gfs2_is_jdata(ip)) { @@ -784,6 +793,9 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) } else { list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); } +out: + gfs2_log_unlock(sdp); + unlock_buffer(bd->bd_bh); } /** diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index c5af8e18f27a..40c4b0d42fa8 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -497,11 +497,8 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) struct gfs2_quota_data **qd; int error; - if (ip->i_res == NULL) { - error = gfs2_rs_alloc(ip); - if (error) - return error; - } + if (ip->i_res == NULL) + gfs2_rs_alloc(ip); qd = ip->i_res->rs_qa_qd; diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 38fe18f2f055..3cc402ce6fea 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -553,6 +553,7 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) */ int gfs2_rs_alloc(struct gfs2_inode *ip) { + int error = 0; struct gfs2_blkreserv *res; if (ip->i_res) @@ -560,7 +561,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); if (!res) - return -ENOMEM; + error = -ENOMEM; RB_CLEAR_NODE(&res->rs_node); @@ -570,7 +571,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) else ip->i_res = res; up_write(&ip->i_rw_mutex); - return 0; + return error; } static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) @@ -1262,9 +1263,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) int ret = 0; u64 amt; u64 trimmed = 0; - u64 start, end, minlen; unsigned int x; - unsigned bs_shift = sdp->sd_sb.sb_bsize_shift; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1272,25 +1271,19 @@ int gfs2_fitrim(struct file *filp, void __user *argp) if (!blk_queue_discard(q)) return -EOPNOTSUPP; - if (copy_from_user(&r, argp, sizeof(r))) + if (argp == NULL) { + r.start = 0; + r.len = ULLONG_MAX; + r.minlen = 0; + } else if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; ret = gfs2_rindex_update(sdp); if (ret) return ret; - start = r.start >> bs_shift; - end = start + (r.len >> bs_shift); - minlen = max_t(u64, r.minlen, - q->limits.discard_granularity) >> bs_shift; - - rgd = gfs2_blk2rgrpd(sdp, start, 0); - rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); - - if (end <= start || - minlen > sdp->sd_max_rg_data || - start > rgd_end->rd_data0 + rgd_end->rd_data) - return -EINVAL; + rgd = gfs2_blk2rgrpd(sdp, r.start, 0); + rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); while (1) { @@ -1302,9 +1295,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) /* Trim each bitmap in the rgrp */ for (x = 0; x < rgd->rd_length; x++) { struct gfs2_bitmap *bi = rgd->rd_bits + x; - ret = gfs2_rgrp_send_discards(sdp, - rgd->rd_data0, NULL, bi, minlen, - &amt); + ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); if (ret) { gfs2_glock_dq_uninit(&gh); goto out; @@ -1333,7 +1324,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) out: r.len = trimmed << 9; - if (copy_to_user(argp, &r, sizeof(r))) + if (argp && copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return ret; diff --git a/trunk/fs/gfs2/super.c b/trunk/fs/gfs2/super.c index d6488674d916..bc737261f234 100644 --- a/trunk/fs/gfs2/super.c +++ b/trunk/fs/gfs2/super.c @@ -810,8 +810,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) return; } need_unlock = 1; - } else if (WARN_ON_ONCE(ip->i_gl->gl_state != LM_ST_EXCLUSIVE)) - return; + } if (current->journal_info == NULL) { ret = gfs2_trans_begin(sdp, RES_DINODE, 0); diff --git a/trunk/fs/gfs2/trans.c b/trunk/fs/gfs2/trans.c index 413627072f36..adbd27875ef9 100644 --- a/trunk/fs/gfs2/trans.c +++ b/trunk/fs/gfs2/trans.c @@ -155,22 +155,14 @@ void gfs2_trans_add_bh(struct gfs2_glock *gl, struct buffer_head *bh, int meta) struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_bufdata *bd; - lock_buffer(bh); - gfs2_log_lock(sdp); bd = bh->b_private; if (bd) gfs2_assert(sdp, bd->bd_gl == gl); else { - gfs2_log_unlock(sdp); - unlock_buffer(bh); gfs2_attach_bufdata(gl, bh, meta); bd = bh->b_private; - lock_buffer(bh); - gfs2_log_lock(sdp); } lops_add(sdp, bd); - gfs2_log_unlock(sdp); - unlock_buffer(bh); } void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) diff --git a/trunk/fs/nfs/dns_resolve.c b/trunk/fs/nfs/dns_resolve.c index ca4b11ec87a2..31c26c4dcc23 100644 --- a/trunk/fs/nfs/dns_resolve.c +++ b/trunk/fs/nfs/dns_resolve.c @@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) { char buf1[NFS_DNS_HOSTNAME_MAXLEN+1]; struct nfs_dns_ent key, *item; - unsigned int ttl; + unsigned long ttl; ssize_t len; int ret = -EINVAL; @@ -240,8 +240,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen) key.namelen = len; memset(&key.h, 0, sizeof(key.h)); - if (get_uint(&buf, &ttl) < 0) - goto out; + ttl = get_expiry(&buf); if (ttl == 0) goto out; key.h.expiry_time = ttl + seconds_since_boot(); diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 6fa01aea2488..5c7325c5c5e6 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -685,10 +685,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) if (ctx->cred != NULL) put_rpccred(ctx->cred); dput(ctx->dentry); - if (is_sync) - nfs_sb_deactive(sb); - else - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(ctx->mdsthreshold); kfree(ctx); } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 05521cadac2e..59b133c5d652 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -351,12 +351,10 @@ extern int __init register_nfs_fs(void); extern void __exit unregister_nfs_fs(void); extern void nfs_sb_active(struct super_block *sb); extern void nfs_sb_deactive(struct super_block *sb); -extern void nfs_sb_deactive_async(struct super_block *sb); /* namespace.c */ -#define NFS_PATH_CANONICAL 1 extern char *nfs_path(char **p, struct dentry *dentry, - char *buffer, ssize_t buflen, unsigned flags); + char *buffer, ssize_t buflen); extern struct vfsmount *nfs_d_automount(struct path *path); struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *, struct nfs_fh *, struct nfs_fattr *); @@ -500,7 +498,7 @@ static inline char *nfs_devname(struct dentry *dentry, char *buffer, ssize_t buflen) { char *dummy; - return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL); + return nfs_path(&dummy, dentry, buffer, buflen); } /* diff --git a/trunk/fs/nfs/mount_clnt.c b/trunk/fs/nfs/mount_clnt.c index 015f71f8f62c..8e65c7f1f87c 100644 --- a/trunk/fs/nfs/mount_clnt.c +++ b/trunk/fs/nfs/mount_clnt.c @@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info) else msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT]; - status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT); + status = rpc_call_sync(mnt_clnt, &msg, 0); rpc_shutdown_client(mnt_clnt); if (status < 0) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index dd057bc6b65b..655925373b91 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -33,7 +33,6 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * @dentry - pointer to dentry * @buffer - result buffer * @buflen - length of buffer - * @flags - options (see below) * * Helper function for constructing the server pathname * by arbitrary hashed dentry. @@ -41,14 +40,8 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ; * This is mainly for use in figuring out the path on the * server side when automounting on top of an existing partition * and in generating /proc/mounts and friends. - * - * Supported flags: - * NFS_PATH_CANONICAL: ensure there is exactly one slash after - * the original device (export) name - * (if unset, the original name is returned verbatim) */ -char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, - unsigned flags) +char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen) { char *end; int namelen; @@ -81,7 +74,7 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, rcu_read_unlock(); goto rename_retry; } - if ((flags & NFS_PATH_CANONICAL) && *end != '/') { + if (*end != '/') { if (--buflen < 0) { spin_unlock(&dentry->d_lock); rcu_read_unlock(); @@ -98,11 +91,9 @@ char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen, return end; } namelen = strlen(base); - if (flags & NFS_PATH_CANONICAL) { - /* Strip off excess slashes in base string */ - while (namelen > 0 && base[namelen - 1] == '/') - namelen--; - } + /* Strip off excess slashes in base string */ + while (namelen > 0 && base[namelen - 1] == '/') + namelen--; buflen -= namelen; if (buflen < 0) { spin_unlock(&dentry->d_lock); diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index 1e09eb78543b..79fbb61ce202 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -81,8 +81,7 @@ static char *nfs_path_component(const char *nfspath, const char *end) static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) { char *limit; - char *path = nfs_path(&limit, dentry, buffer, buflen, - NFS_PATH_CANONICAL); + char *path = nfs_path(&limit, dentry, buffer, buflen); if (!IS_ERR(path)) { char *path_component = nfs_path_component(path, limit); if (path_component) diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 5eec4429970c..68b21d81b7ac 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -339,7 +339,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc dprintk("%s ERROR: %d Reset session\n", __func__, errorcode); nfs4_schedule_session_recovery(clp->cl_session, errorcode); - goto wait_on_recovery; + exception->retry = 1; + break; #endif /* defined(CONFIG_NFS_V4_1) */ case -NFS4ERR_FILE_OPEN: if (exception->timeout > HZ) { @@ -1571,11 +1572,9 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, - &data->o_res.seq_res, - task) != 0) - nfs_release_seqid(data->o_arg.seqid); - else - rpc_call_start(task); + &data->o_res.seq_res, task)) + return; + rpc_call_start(task); return; unlock_no_action: rcu_read_unlock(); @@ -1749,7 +1748,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred, /* even though OPEN succeeded, access is denied. Close the file */ nfs4_close_state(state, fmode); - return -EACCES; + return -NFS4ERR_ACCESS; } /* @@ -2197,7 +2196,7 @@ static void nfs4_free_closedata(void *data) nfs4_put_open_state(calldata->state); nfs_free_seqid(calldata->arg.seqid); nfs4_put_state_owner(sp); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); kfree(calldata); } @@ -2297,10 +2296,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) if (nfs4_setup_sequence(NFS_SERVER(inode), &calldata->arg.seq_args, &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + task)) + goto out; + rpc_call_start(task); out: dprintk("%s: done!\n", __func__); } @@ -4531,7 +4529,6 @@ static void nfs4_locku_done(struct rpc_task *task, void *data) if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN) rpc_restart_call_prepare(task); } - nfs_release_seqid(calldata->arg.seqid); } static void nfs4_locku_prepare(struct rpc_task *task, void *data) @@ -4548,11 +4545,9 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data) calldata->timestamp = jiffies; if (nfs4_setup_sequence(calldata->server, &calldata->arg.seq_args, - &calldata->res.seq_res, - task) != 0) - nfs_release_seqid(calldata->arg.seqid); - else - rpc_call_start(task); + &calldata->res.seq_res, task)) + return; + rpc_call_start(task); } static const struct rpc_call_ops nfs4_locku_ops = { @@ -4697,7 +4692,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) /* Do we need to do an open_to_lock_owner? */ if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0) - goto out_release_lock_seqid; + return; data->arg.open_stateid = &state->stateid; data->arg.new_lock_owner = 1; data->res.open_seqid = data->arg.open_seqid; @@ -4706,15 +4701,10 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) data->timestamp = jiffies; if (nfs4_setup_sequence(data->server, &data->arg.seq_args, - &data->res.seq_res, - task) == 0) { - rpc_call_start(task); + &data->res.seq_res, task)) return; - } - nfs_release_seqid(data->arg.open_seqid); -out_release_lock_seqid: - nfs_release_seqid(data->arg.lock_seqid); - dprintk("%s: done!, ret = %d\n", __func__, task->tk_status); + rpc_call_start(task); + dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status); } static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata) @@ -5677,7 +5667,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl, tbl->slots = new; tbl->max_slots = max_slots; } - tbl->highest_used_slotid = NFS4_NO_SLOT; + tbl->highest_used_slotid = -1; /* no slot is currently used */ for (i = 0; i < tbl->max_slots; i++) tbl->slots[i].seq_nr = ivalue; spin_unlock(&tbl->slot_tbl_lock); diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 2878f97bd78d..fe624c91bd00 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -925,8 +925,8 @@ pnfs_find_alloc_layout(struct inode *ino, if (likely(nfsi->layout == NULL)) { /* Won the race? */ nfsi->layout = new; return new; - } else if (new != NULL) - pnfs_free_layout_hdr(new); + } + pnfs_free_layout_hdr(new); out_existing: pnfs_get_layout_hdr(nfsi->layout); return nfsi->layout; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 652d3f7176a9..e831bce49766 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -54,7 +54,6 @@ #include #include #include -#include #include @@ -416,54 +415,6 @@ void nfs_sb_deactive(struct super_block *sb) } EXPORT_SYMBOL_GPL(nfs_sb_deactive); -static int nfs_deactivate_super_async_work(void *ptr) -{ - struct super_block *sb = ptr; - - deactivate_super(sb); - module_put_and_exit(0); - return 0; -} - -/* - * same effect as deactivate_super, but will do final unmount in kthread - * context - */ -static void nfs_deactivate_super_async(struct super_block *sb) -{ - struct task_struct *task; - char buf[INET6_ADDRSTRLEN + 1]; - struct nfs_server *server = NFS_SB(sb); - struct nfs_client *clp = server->nfs_client; - - if (!atomic_add_unless(&sb->s_active, -1, 1)) { - rcu_read_lock(); - snprintf(buf, sizeof(buf), - rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); - rcu_read_unlock(); - - __module_get(THIS_MODULE); - task = kthread_run(nfs_deactivate_super_async_work, sb, - "%s-deactivate-super", buf); - if (IS_ERR(task)) { - pr_err("%s: kthread_run: %ld\n", - __func__, PTR_ERR(task)); - /* make synchronous call and hope for the best */ - deactivate_super(sb); - module_put(THIS_MODULE); - } - } -} - -void nfs_sb_deactive_async(struct super_block *sb) -{ - struct nfs_server *server = NFS_SB(sb); - - if (atomic_dec_and_test(&server->active)) - nfs_deactivate_super_async(sb); -} -EXPORT_SYMBOL_GPL(nfs_sb_deactive_async); - /* * Deliver file system statistics to userspace */ @@ -820,7 +771,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root) int err = 0; if (!page) return -ENOMEM; - devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0); + devname = nfs_path(&dummy, root, page, PAGE_SIZE); if (IS_ERR(devname)) err = PTR_ERR(devname); else diff --git a/trunk/fs/nfs/unlink.c b/trunk/fs/nfs/unlink.c index 3f79c77153b8..13cea637eff8 100644 --- a/trunk/fs/nfs/unlink.c +++ b/trunk/fs/nfs/unlink.c @@ -95,7 +95,7 @@ static void nfs_async_unlink_release(void *calldata) nfs_dec_sillycount(data->dir); nfs_free_unlinkdata(data); - nfs_sb_deactive_async(sb); + nfs_sb_deactive(sb); } static void nfs_unlink_prepare(struct rpc_task *task, void *calldata) diff --git a/trunk/fs/notify/fanotify/fanotify.c b/trunk/fs/notify/fanotify/fanotify.c index a50636025364..f35794b97e8e 100644 --- a/trunk/fs/notify/fanotify/fanotify.c +++ b/trunk/fs/notify/fanotify/fanotify.c @@ -21,7 +21,6 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new) if ((old->path.mnt == new->path.mnt) && (old->path.dentry == new->path.dentry)) return true; - break; case (FSNOTIFY_EVENT_NONE): return true; default: diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index 335206a9c698..4f33c32affe3 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -1866,7 +1866,6 @@ xfs_alloc_fix_freelist( /* * Initialize the args structure. */ - memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; targs.agbp = agbp; @@ -2208,7 +2207,7 @@ xfs_alloc_read_agf( * group or loop over the allocation groups to find the result. */ int /* error */ -xfs_alloc_vextent( +__xfs_alloc_vextent( xfs_alloc_arg_t *args) /* allocation argument structure */ { xfs_agblock_t agsize; /* allocation group size */ @@ -2418,6 +2417,46 @@ xfs_alloc_vextent( return error; } +static void +xfs_alloc_vextent_worker( + struct work_struct *work) +{ + struct xfs_alloc_arg *args = container_of(work, + struct xfs_alloc_arg, work); + unsigned long pflags; + + /* we are in a transaction context here */ + current_set_flags_nested(&pflags, PF_FSTRANS); + + args->result = __xfs_alloc_vextent(args); + complete(args->done); + + current_restore_flags_nested(&pflags, PF_FSTRANS); +} + +/* + * Data allocation requests often come in with little stack to work on. Push + * them off to a worker thread so there is lots of stack to use. Metadata + * requests, OTOH, are generally from low stack usage paths, so avoid the + * context switch overhead here. + */ +int +xfs_alloc_vextent( + struct xfs_alloc_arg *args) +{ + DECLARE_COMPLETION_ONSTACK(done); + + if (!args->userdata) + return __xfs_alloc_vextent(args); + + + args->done = &done; + INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); + queue_work(xfs_alloc_wq, &args->work); + wait_for_completion(&done); + return args->result; +} + /* * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent diff --git a/trunk/fs/xfs/xfs_alloc.h b/trunk/fs/xfs/xfs_alloc.h index feacb061bab7..93be4a667ca1 100644 --- a/trunk/fs/xfs/xfs_alloc.h +++ b/trunk/fs/xfs/xfs_alloc.h @@ -120,6 +120,9 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ + struct completion *done; + struct work_struct work; + int result; } xfs_alloc_arg_t; /* diff --git a/trunk/fs/xfs/xfs_alloc_btree.c b/trunk/fs/xfs/xfs_alloc_btree.c index f7876c6d6165..f1647caace8f 100644 --- a/trunk/fs/xfs/xfs_alloc_btree.c +++ b/trunk/fs/xfs/xfs_alloc_btree.c @@ -121,8 +121,6 @@ xfs_allocbt_free_block( xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, XFS_EXTENT_BUSY_SKIP_DISCARD); xfs_trans_agbtree_delta(cur->bc_tp, -1); - - xfs_trans_binval(cur->bc_tp, bp); return 0; } diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 83d0cf3df930..848ffa77707b 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -2437,7 +2437,6 @@ xfs_bmap_btalloc( * Normal allocation, done through xfs_alloc_vextent. */ tryagain = isaligned = 0; - memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; args.fsbno = ap->blkno; @@ -3083,7 +3082,6 @@ xfs_bmap_extents_to_btree( * Convert to a btree with two levels, one record in root. */ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; args.firstblock = *firstblock; @@ -3239,7 +3237,6 @@ xfs_bmap_local_to_extents( xfs_buf_t *bp; /* buffer for extent block */ xfs_bmbt_rec_host_t *ep;/* extent record pointer */ - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; args.firstblock = *firstblock; @@ -4619,11 +4616,12 @@ xfs_bmapi_delay( STATIC int -__xfs_bmapi_allocate( - struct xfs_bmalloca *bma) +xfs_bmapi_allocate( + struct xfs_bmalloca *bma, + int flags) { struct xfs_mount *mp = bma->ip->i_mount; - int whichfork = (bma->flags & XFS_BMAPI_ATTRFORK) ? + int whichfork = (flags & XFS_BMAPI_ATTRFORK) ? XFS_ATTR_FORK : XFS_DATA_FORK; struct xfs_ifork *ifp = XFS_IFORK_PTR(bma->ip, whichfork); int tmp_logflags = 0; @@ -4656,27 +4654,24 @@ __xfs_bmapi_allocate( * Indicate if this is the first user data in the file, or just any * user data. */ - if (!(bma->flags & XFS_BMAPI_METADATA)) { + if (!(flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; } - bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; + bma->minlen = (flags & XFS_BMAPI_CONTIG) ? bma->length : 1; /* * Only want to do the alignment at the eof if it is userdata and * allocation length is larger than a stripe unit. */ if (mp->m_dalign && bma->length >= mp->m_dalign && - !(bma->flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { + !(flags & XFS_BMAPI_METADATA) && whichfork == XFS_DATA_FORK) { error = xfs_bmap_isaeof(bma, whichfork); if (error) return error; } - if (bma->flags & XFS_BMAPI_STACK_SWITCH) - bma->stack_switch = 1; - error = xfs_bmap_alloc(bma); if (error) return error; @@ -4711,7 +4706,7 @@ __xfs_bmapi_allocate( * A wasdelay extent has been initialized, so shouldn't be flagged * as unwritten. */ - if (!bma->wasdel && (bma->flags & XFS_BMAPI_PREALLOC) && + if (!bma->wasdel && (flags & XFS_BMAPI_PREALLOC) && xfs_sb_version_hasextflgbit(&mp->m_sb)) bma->got.br_state = XFS_EXT_UNWRITTEN; @@ -4739,45 +4734,6 @@ __xfs_bmapi_allocate( return 0; } -static void -xfs_bmapi_allocate_worker( - struct work_struct *work) -{ - struct xfs_bmalloca *args = container_of(work, - struct xfs_bmalloca, work); - unsigned long pflags; - - /* we are in a transaction context here */ - current_set_flags_nested(&pflags, PF_FSTRANS); - - args->result = __xfs_bmapi_allocate(args); - complete(args->done); - - current_restore_flags_nested(&pflags, PF_FSTRANS); -} - -/* - * Some allocation requests often come in with little stack to work on. Push - * them off to a worker thread so there is lots of stack to use. Otherwise just - * call directly to avoid the context switch overhead here. - */ -int -xfs_bmapi_allocate( - struct xfs_bmalloca *args) -{ - DECLARE_COMPLETION_ONSTACK(done); - - if (!args->stack_switch) - return __xfs_bmapi_allocate(args); - - - args->done = &done; - INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); - queue_work(xfs_alloc_wq, &args->work); - wait_for_completion(&done); - return args->result; -} - STATIC int xfs_bmapi_convert_unwritten( struct xfs_bmalloca *bma, @@ -4963,7 +4919,6 @@ xfs_bmapi_write( bma.conv = !!(flags & XFS_BMAPI_CONVERT); bma.wasdel = wasdelay; bma.offset = bno; - bma.flags = flags; /* * There's a 32/64 bit type mismatch between the @@ -4979,7 +4934,7 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(bma.length > 0); - error = xfs_bmapi_allocate(&bma); + error = xfs_bmapi_allocate(&bma, flags); if (error) goto error0; if (bma.blkno == NULLFSBLOCK) diff --git a/trunk/fs/xfs/xfs_bmap.h b/trunk/fs/xfs/xfs_bmap.h index 5f469c3516eb..803b56d7ce16 100644 --- a/trunk/fs/xfs/xfs_bmap.h +++ b/trunk/fs/xfs/xfs_bmap.h @@ -77,7 +77,6 @@ typedef struct xfs_bmap_free * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x040 -#define XFS_BMAPI_STACK_SWITCH 0x080 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ @@ -86,8 +85,7 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" }, \ - { XFS_BMAPI_STACK_SWITCH, "STACK_SWITCH" } + { XFS_BMAPI_CONVERT, "CONVERT" } static inline int xfs_bmapi_aflag(int w) @@ -135,11 +133,6 @@ typedef struct xfs_bmalloca { char userdata;/* set if is user data */ char aeof; /* allocated space at eof */ char conv; /* overwriting unwritten extents */ - char stack_switch; - int flags; - struct completion *done; - struct work_struct work; - int result; } xfs_bmalloca_t; /* diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index becf4a97efc6..a8d0ed911196 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -526,25 +526,7 @@ xfs_buf_item_unpin( } xfs_buf_relse(bp); } else if (freed && remove) { - /* - * There are currently two references to the buffer - the active - * LRU reference and the buf log item. What we are about to do - * here - simulate a failed IO completion - requires 3 - * references. - * - * The LRU reference is removed by the xfs_buf_stale() call. The - * buf item reference is removed by the xfs_buf_iodone() - * callback that is run by xfs_buf_do_callbacks() during ioend - * processing (via the bp->b_iodone callback), and then finally - * the ioend processing will drop the IO reference if the buffer - * is marked XBF_ASYNC. - * - * Hence we need to take an additional reference here so that IO - * completion processing doesn't free the buffer prematurely. - */ xfs_buf_lock(bp); - xfs_buf_hold(bp); - bp->b_flags |= XBF_ASYNC; xfs_buf_ioerror(bp, EIO); XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index 4beaede43277..c25b094efbf7 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -399,26 +399,9 @@ xfs_growfs_data_private( /* update secondary superblocks. */ for (agno = 1; agno < nagcount; agno++) { - error = 0; - /* - * new secondary superblocks need to be zeroed, not read from - * disk as the contents of the new area we are growing into is - * completely unknown. - */ - if (agno < oagcount) { - error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, + error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), XFS_FSS_TO_BB(mp, 1), 0, &bp); - } else { - bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, - XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), - XFS_FSS_TO_BB(mp, 1), 0); - if (bp) - xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); - else - error = ENOMEM; - } - if (error) { xfs_warn(mp, "error %d reading secondary superblock for ag %d", @@ -440,7 +423,7 @@ xfs_growfs_data_private( break; /* no point in continuing */ } } - return error; + return 0; error0: xfs_trans_cancel(tp, XFS_TRANS_ABORT); diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index c5c4ef4f2bdb..445bf1aef31c 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -250,7 +250,6 @@ xfs_ialloc_ag_alloc( /* boundary */ struct xfs_perag *pag; - memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = tp->t_mountp; diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 1938b41ee9f5..2778258fcfa2 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -1509,8 +1509,7 @@ xfs_ifree_cluster( * to mark all the active inodes on the buffer stale. */ bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, - mp->m_bsize * blks_per_cluster, - XBF_UNMAPPED); + mp->m_bsize * blks_per_cluster, 0); if (!bp) return ENOMEM; diff --git a/trunk/fs/xfs/xfs_ioctl.c b/trunk/fs/xfs/xfs_ioctl.c index c1df3c623de2..8305f2ac6773 100644 --- a/trunk/fs/xfs/xfs_ioctl.c +++ b/trunk/fs/xfs/xfs_ioctl.c @@ -70,7 +70,7 @@ xfs_find_handle( int hsize; xfs_handle_t handle; struct inode *inode; - struct fd f = {0}; + struct fd f; struct path path; int error; struct xfs_inode *ip; diff --git a/trunk/fs/xfs/xfs_iomap.c b/trunk/fs/xfs/xfs_iomap.c index 7f537663365b..973dff6ad935 100644 --- a/trunk/fs/xfs/xfs_iomap.c +++ b/trunk/fs/xfs/xfs_iomap.c @@ -584,9 +584,7 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, - XFS_BMAPI_STACK_SWITCH, - &first_block, 1, + count_fsb, 0, &first_block, 1, imap, &nimaps, &free_list); if (error) goto trans_cancel; diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 4dad756962d0..7f4f9370d0e7 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -2387,27 +2387,14 @@ xlog_state_do_callback( /* - * Completion of a iclog IO does not imply that - * a transaction has completed, as transactions - * can be large enough to span many iclogs. We - * cannot change the tail of the log half way - * through a transaction as this may be the only - * transaction in the log and moving th etail to - * point to the middle of it will prevent - * recovery from finding the start of the - * transaction. Hence we should only update the - * last_sync_lsn if this iclog contains - * transaction completion callbacks on it. - * - * We have to do this before we drop the + * update the last_sync_lsn before we drop the * icloglock to ensure we are the only one that * can update it. */ ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); - if (iclog->ic_callback) - atomic64_set(&log->l_last_sync_lsn, - be64_to_cpu(iclog->ic_header.h_lsn)); + atomic64_set(&log->l_last_sync_lsn, + be64_to_cpu(iclog->ic_header.h_lsn)); } else ioerrors++; diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index d308749fabf1..5da3ace352bf 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -3541,7 +3541,7 @@ xlog_do_recovery_pass( * - order is important. */ error = xlog_bread_offset(log, 0, - bblks - split_bblks, dbp, + bblks - split_bblks, hbp, offset + BBTOB(split_bblks)); if (error) goto bread_err2; diff --git a/trunk/include/linux/hashtable.h b/trunk/include/linux/hashtable.h deleted file mode 100644 index 227c62424f3c..000000000000 --- a/trunk/include/linux/hashtable.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Statically sized hash table implementation - * (C) 2012 Sasha Levin - */ - -#ifndef _LINUX_HASHTABLE_H -#define _LINUX_HASHTABLE_H - -#include -#include -#include -#include -#include - -#define DEFINE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] = \ - { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT } - -#define DECLARE_HASHTABLE(name, bits) \ - struct hlist_head name[1 << (bits)] - -#define HASH_SIZE(name) (ARRAY_SIZE(name)) -#define HASH_BITS(name) ilog2(HASH_SIZE(name)) - -/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ -#define hash_min(val, bits) \ - (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) - -static inline void __hash_init(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - INIT_HLIST_HEAD(&ht[i]); -} - -/** - * hash_init - initialize a hash table - * @hashtable: hashtable to be initialized - * - * Calculates the size of the hashtable from the given parameter, otherwise - * same as hash_init_size. - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_add - add an object to a hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add(hashtable, node, key) \ - hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_add_rcu - add an object to a rcu enabled hashtable - * @hashtable: hashtable to add to - * @node: the &struct hlist_node of the object to be added - * @key: the key of the object to be added - */ -#define hash_add_rcu(hashtable, node, key) \ - hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))]) - -/** - * hash_hashed - check whether an object is in any hashtable - * @node: the &struct hlist_node of the object to be checked - */ -static inline bool hash_hashed(struct hlist_node *node) -{ - return !hlist_unhashed(node); -} - -static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz) -{ - unsigned int i; - - for (i = 0; i < sz; i++) - if (!hlist_empty(&ht[i])) - return false; - - return true; -} - -/** - * hash_empty - check whether a hashtable is empty - * @hashtable: hashtable to check - * - * This has to be a macro since HASH_BITS() will not work on pointers since - * it calculates the size during preprocessing. - */ -#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable)) - -/** - * hash_del - remove an object from a hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del(struct hlist_node *node) -{ - hlist_del_init(node); -} - -/** - * hash_del_rcu - remove an object from a rcu enabled hashtable - * @node: &struct hlist_node of the object to remove - */ -static inline void hash_del_rcu(struct hlist_node *node) -{ - hlist_del_init_rcu(node); -} - -/** - * hash_for_each - iterate over a hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry(obj, node, &name[bkt], member) - -/** - * hash_for_each_rcu - iterate over a rcu enabled hashtable - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_rcu(name, bkt, node, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_rcu(obj, node, &name[bkt], member) - -/** - * hash_for_each_safe - iterate over a hashtable safe against removal of - * hash entry - * @name: hashtable to iterate - * @bkt: integer to use as bucket loop cursor - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @obj: the type * to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - */ -#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \ - for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\ - hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member) - -/** - * hash_for_each_possible - iterate over all possible objects hashing to the - * same bucket - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible(name, obj, node, member, key) \ - hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_rcu - iterate over all possible objects hashing to the - * same bucket in an rcu enabled hashtable - * in a rcu enabled hashtable - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_rcu(name, obj, node, member, key) \ - hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member) - -/** - * hash_for_each_possible_safe - iterate over all possible objects hashing to the - * same bucket safe against removals - * @name: hashtable to iterate - * @obj: the type * to use as a loop cursor for each entry - * @node: the &struct list_head to use as a loop cursor for each entry - * @tmp: a &struct used for temporary storage - * @member: the name of the hlist_node within the struct - * @key: the key of the objects to iterate over - */ -#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \ - hlist_for_each_entry_safe(obj, node, tmp, \ - &name[hash_min(key, HASH_BITS(name))], member) - - -#endif diff --git a/trunk/include/linux/mmc/dw_mmc.h b/trunk/include/linux/mmc/dw_mmc.h index 96531664a061..7c6a1139d8fa 100644 --- a/trunk/include/linux/mmc/dw_mmc.h +++ b/trunk/include/linux/mmc/dw_mmc.h @@ -137,7 +137,7 @@ struct dw_mci { dma_addr_t sg_dma; void *sg_cpu; - const struct dw_mci_dma_ops *dma_ops; + struct dw_mci_dma_ops *dma_ops; #ifdef CONFIG_MMC_DW_IDMAC unsigned int ring_size; #else @@ -162,7 +162,7 @@ struct dw_mci { u16 data_offset; struct device *dev; struct dw_mci_board *pdata; - const struct dw_mci_drv_data *drv_data; + struct dw_mci_drv_data *drv_data; void *priv; struct clk *biu_clk; struct clk *ciu_clk; @@ -186,7 +186,7 @@ struct dw_mci { struct regulator *vmmc; /* Power regulator */ unsigned long irq_flags; /* IRQ flags */ - int irq; + unsigned int irq; }; /* DMA ops for Internal/External DMAC interface */ diff --git a/trunk/include/linux/mmc/sdhci.h b/trunk/include/linux/mmc/sdhci.h index 1edcb4dad8c4..fa8529a859b8 100644 --- a/trunk/include/linux/mmc/sdhci.h +++ b/trunk/include/linux/mmc/sdhci.h @@ -91,7 +91,6 @@ struct sdhci_host { unsigned int quirks2; /* More deviations from spec. */ #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0) -#define SDHCI_QUIRK2_HOST_NO_CMD23 (1<<1) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ diff --git a/trunk/include/linux/of_address.h b/trunk/include/linux/of_address.h index e20e3af68fb6..a1984dd037da 100644 --- a/trunk/include/linux/of_address.h +++ b/trunk/include/linux/of_address.h @@ -28,13 +28,11 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #else /* CONFIG_OF_ADDRESS */ -#ifndef of_address_to_resource static inline int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { return -EINVAL; } -#endif static inline struct device_node *of_find_matching_node_by_address( struct device_node *from, const struct of_device_id *matches, diff --git a/trunk/include/linux/ptp_clock_kernel.h b/trunk/include/linux/ptp_clock_kernel.h index 38a993508327..f2dc6d8fc680 100644 --- a/trunk/include/linux/ptp_clock_kernel.h +++ b/trunk/include/linux/ptp_clock_kernel.h @@ -54,8 +54,7 @@ struct ptp_clock_request { * clock operations * * @adjfreq: Adjusts the frequency of the hardware clock. - * parameter delta: Desired frequency offset from nominal frequency - * in parts per billion + * parameter delta: Desired period change in parts per billion. * * @adjtime: Shifts the time of the hardware clock. * parameter delta: Desired change in nanoseconds. diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 7d5b6000378b..f8cd4cf3fad8 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -2651,15 +2651,6 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); -/** - * ieee80211_get_mesh_hdrlen - get mesh extension header length - * @meshhdr: the mesh extension header, only the flags field - * (first byte) will be accessed - * Returns the length of the extension header, which is always at - * least 6 bytes and at most 18 if address 5 and 6 are present. - */ -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); - /** * DOC: Data path helpers * diff --git a/trunk/include/trace/events/xen.h b/trunk/include/trace/events/xen.h index d06b6da5c1e3..15ba03bdd7c6 100644 --- a/trunk/include/trace/events/xen.h +++ b/trunk/include/trace/events/xen.h @@ -377,14 +377,6 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd, DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin); DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin); -TRACE_EVENT(xen_mmu_flush_tlb_all, - TP_PROTO(int x), - TP_ARGS(x), - TP_STRUCT__entry(__array(char, x, 0)), - TP_fast_assign((void)x), - TP_printk("%s", "") - ); - TRACE_EVENT(xen_mmu_flush_tlb, TP_PROTO(int x), TP_ARGS(x), diff --git a/trunk/include/uapi/linux/eventpoll.h b/trunk/include/uapi/linux/eventpoll.h index 2c267bcbb85c..8c99ce7202c5 100644 --- a/trunk/include/uapi/linux/eventpoll.h +++ b/trunk/include/uapi/linux/eventpoll.h @@ -25,6 +25,7 @@ #define EPOLL_CTL_ADD 1 #define EPOLL_CTL_DEL 2 #define EPOLL_CTL_MOD 3 +#define EPOLL_CTL_DISABLE 4 /* * Request the handling of system wakeup events so as to prevent system suspends diff --git a/trunk/include/xen/hvm.h b/trunk/include/xen/hvm.h index 13e43e41637d..b193fa2f9fdd 100644 --- a/trunk/include/xen/hvm.h +++ b/trunk/include/xen/hvm.h @@ -5,36 +5,6 @@ #include #include -static const char *param_name(int op) -{ -#define PARAM(x) [HVM_PARAM_##x] = #x - static const char *const names[] = { - PARAM(CALLBACK_IRQ), - PARAM(STORE_PFN), - PARAM(STORE_EVTCHN), - PARAM(PAE_ENABLED), - PARAM(IOREQ_PFN), - PARAM(BUFIOREQ_PFN), - PARAM(TIMER_MODE), - PARAM(HPET_ENABLED), - PARAM(IDENT_PT), - PARAM(DM_DOMAIN), - PARAM(ACPI_S_STATE), - PARAM(VM86_TSS), - PARAM(VPT_ALIGN), - PARAM(CONSOLE_PFN), - PARAM(CONSOLE_EVTCHN), - }; -#undef PARAM - - if (op >= ARRAY_SIZE(names)) - return "unknown"; - - if (!names[op]) - return "reserved"; - - return names[op]; -} static inline int hvm_get_parameter(int idx, uint64_t *value) { struct xen_hvm_param xhv; @@ -44,8 +14,8 @@ static inline int hvm_get_parameter(int idx, uint64_t *value) xhv.index = idx; r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); if (r < 0) { - printk(KERN_ERR "Cannot get hvm parameter %s (%d): %d!\n", - param_name(idx), idx, r); + printk(KERN_ERR "Cannot get hvm parameter %d: %d!\n", + idx, r); return r; } *value = xhv.value; diff --git a/trunk/init/main.c b/trunk/init/main.c index e33e09df3cbc..9cf77ab138a6 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -442,11 +442,9 @@ void __init __weak smp_setup_processor_id(void) { } -# if THREAD_SIZE >= PAGE_SIZE void __init __weak thread_info_cache_init(void) { } -#endif /* * Set up kernel memory allocators diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 20ef219bbe9b..3717e7b306e0 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, struct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, force_take = 0; + int lock_taken, ret, ownerdied = 0; u32 uval, newval, curval, vpid = task_pid_vnr(task); retry: @@ -755,15 +755,17 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, newval = curval | FUTEX_WAITERS; /* - * Should we force take the futex? See below. + * There are two cases, where a futex might have no owner (the + * owner TID is 0): OWNER_DIED. We take over the futex in this + * case. We also do an unconditional take over, when the owner + * of the futex died. + * + * This is safe as we are protected by the hash bucket lock ! */ - if (unlikely(force_take)) { - /* - * Keep the OWNER_DIED and the WAITERS bit and set the - * new TID value. - */ + if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { + /* Keep the OWNER_DIED bit */ newval = (curval & ~FUTEX_TID_MASK) | vpid; - force_take = 0; + ownerdied = 0; lock_taken = 1; } @@ -773,7 +775,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, goto retry; /* - * We took the lock due to forced take over. + * We took the lock due to owner died take over. */ if (unlikely(lock_taken)) return 1; @@ -788,25 +790,20 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, switch (ret) { case -ESRCH: /* - * We failed to find an owner for this - * futex. So we have no pi_state to block - * on. This can happen in two cases: - * - * 1) The owner died - * 2) A stale FUTEX_WAITERS bit - * - * Re-read the futex value. + * No owner found for this futex. Check if the + * OWNER_DIED bit is set to figure out whether + * this is a robust futex or not. */ if (get_futex_value_locked(&curval, uaddr)) return -EFAULT; /* - * If the owner died or we have a stale - * WAITERS bit the owner TID in the user space - * futex is 0. + * We simply start over in case of a robust + * futex. The code above will take the futex + * and return happy. */ - if (!(curval & FUTEX_TID_MASK)) { - force_take = 1; + if (curval & FUTEX_OWNER_DIED) { + ownerdied = 1; goto retry; } default: diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 6e48c3a43599..6085f5ef88ea 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2293,17 +2293,12 @@ static void layout_symtab(struct module *mod, struct load_info *info) src = (void *)info->hdr + symsect->sh_offset; nsrc = symsect->sh_size / sizeof(*src); - /* strtab always starts with a nul, so offset 0 is the empty string. */ - strtab_size = 1; - /* Compute total space required for the core symbols' strtab. */ - for (ndst = i = 0; i < nsrc; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - strtab_size += strlen(&info->strtab[src[i].st_name])+1; + for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src) + if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { + strtab_size += strlen(&info->strtab[src->st_name]) + 1; ndst++; } - } /* Append room for core symbols at end of core part. */ info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); @@ -2337,15 +2332,15 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) mod->core_symtab = dst = mod->module_core + info->symoffs; mod->core_strtab = s = mod->module_core + info->stroffs; src = mod->symtab; + *dst = *src; *s++ = 0; - for (ndst = i = 0; i < mod->num_symtab; i++) { - if (i == 0 || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { - dst[ndst] = src[i]; - dst[ndst++].st_name = s - mod->core_strtab; - s += strlcpy(s, &mod->strtab[src[i].st_name], - KSYM_NAME_LEN) + 1; - } + for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) { + if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) + continue; + + dst[ndst] = *src; + dst[ndst++].st_name = s - mod->core_strtab; + s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1; } mod->core_num_syms = ndst; } diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 8b055e9379bc..2624edcfb420 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -3017,8 +3017,6 @@ static int kswapd(void *p) &balanced_classzone_idx); } } - - current->reclaim_state = NULL; return 0; } diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index bda6d004f9f0..09cb3f6dc40c 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) { - if (!ptype->af_packet_priv || !skb->sk) + if (ptype->af_packet_priv == NULL) return false; if (ptype->id_match) diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index fad649ae4dec..76d4c2c3c89b 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -2192,8 +2192,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, goto skip; err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, - portid, seq, - RTM_NEWNEIGH, NTF_SELF); + portid, seq, 0, NTF_SELF); if (err < 0) return err; skip: diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 0c34bfabc11f..535584c00f91 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -892,16 +892,13 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, struct inet_diag_req_v2 *r, struct nlattr *bc) { const struct inet_diag_handler *handler; - int err = 0; handler = inet_diag_lock_handler(r->sdiag_protocol); if (!IS_ERR(handler)) handler->dump(skb, cb, r, bc); - else - err = PTR_ERR(handler); inet_diag_unlock_handler(handler); - return err ? : skb->len; + return skb->len; } static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) diff --git a/trunk/net/ipv4/netfilter/iptable_nat.c b/trunk/net/ipv4/netfilter/iptable_nat.c index a82047282dbb..9e0ffaf1d942 100644 --- a/trunk/net/ipv4/netfilter/iptable_nat.c +++ b/trunk/net/ipv4/netfilter/iptable_nat.c @@ -184,8 +184,7 @@ nf_nat_ipv4_out(unsigned int hooknum, if ((ct->tuplehash[dir].tuple.src.u3.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET) < 0) ret = NF_DROP; @@ -222,7 +221,6 @@ nf_nat_ipv4_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET) < 0) diff --git a/trunk/net/ipv4/tcp_illinois.c b/trunk/net/ipv4/tcp_illinois.c index 834857f3c871..813b43a76fec 100644 --- a/trunk/net/ipv4/tcp_illinois.c +++ b/trunk/net/ipv4/tcp_illinois.c @@ -313,13 +313,11 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, .tcpv_rttcnt = ca->cnt_rtt, .tcpv_minrtt = ca->base_rtt, }; + u64 t = ca->sum_rtt; - if (info.tcpv_rttcnt > 0) { - u64 t = ca->sum_rtt; + do_div(t, ca->cnt_rtt); + info.tcpv_rtt = t; - do_div(t, info.tcpv_rttcnt); - info.tcpv_rtt = t; - } nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); } } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 2c2b13a999ea..1db663983587 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -4529,9 +4529,6 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) struct tcphdr *th; bool fragstolen; - if (size == 0) - return 0; - skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); if (!skb) goto err; diff --git a/trunk/net/ipv4/tcp_metrics.c b/trunk/net/ipv4/tcp_metrics.c index 53bc5847bfa8..4c752a6e0bcd 100644 --- a/trunk/net/ipv4/tcp_metrics.c +++ b/trunk/net/ipv4/tcp_metrics.c @@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr, } a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; if (a) { - if (nla_len(a) != sizeof(struct in6_addr)) + if (nla_len(a) != sizeof(sizeof(struct in6_addr))) return -EINVAL; addr->family = AF_INET6; memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); diff --git a/trunk/net/ipv6/ip6_gre.c b/trunk/net/ipv6/ip6_gre.c index d5cb3c4e66f8..0185679c5f53 100644 --- a/trunk/net/ipv6/ip6_gre.c +++ b/trunk/net/ipv6/ip6_gre.c @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) /* IFLA_GRE_OKEY */ nla_total_size(4) + /* IFLA_GRE_LOCAL */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_REMOTE */ - nla_total_size(sizeof(struct in6_addr)) + + nla_total_size(4) + /* IFLA_GRE_TTL */ nla_total_size(1) + /* IFLA_GRE_TOS */ @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || - nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || - nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || + nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 2edce30ef733..ff36194a71aa 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; - struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; + struct in6_addr mcaddr; idev = in6_dev_get(dev); if (!idev) @@ -543,6 +543,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { + addrconf_addr_solict_mult(&ifa->addr, &mcaddr); ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, /*router=*/ !!idev->cnf.forwarding, /*solicited=*/ false, /*override=*/ true, diff --git a/trunk/net/ipv6/netfilter/ip6table_nat.c b/trunk/net/ipv6/netfilter/ip6table_nat.c index d57dab17a182..e418bd6350a4 100644 --- a/trunk/net/ipv6/netfilter/ip6table_nat.c +++ b/trunk/net/ipv6/netfilter/ip6table_nat.c @@ -186,8 +186,7 @@ nf_nat_ipv6_out(unsigned int hooknum, if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3) || - (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && - ct->tuplehash[dir].tuple.src.u.all != + (ct->tuplehash[dir].tuple.src.u.all != ct->tuplehash[!dir].tuple.dst.u.all)) if (nf_xfrm_me_harder(skb, AF_INET6) < 0) ret = NF_DROP; @@ -223,7 +222,6 @@ nf_nat_ipv6_local_fn(unsigned int hooknum, } #ifdef CONFIG_XFRM else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && - ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && ct->tuplehash[dir].tuple.dst.u.all != ct->tuplehash[!dir].tuple.src.u.all) if (nf_xfrm_me_harder(skb, AF_INET6)) diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 22c8ea951185..18bd9bbbd1c6 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { { } }; -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { struct ctl_table *table; struct ctl_table_header *hdr; @@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) } #else -static int nf_ct_frag6_sysctl_register(struct net *net) +static int __net_init nf_ct_frag6_sysctl_register(struct net *net) { return 0; } diff --git a/trunk/net/l2tp/l2tp_eth.c b/trunk/net/l2tp/l2tp_eth.c index 76125c57ee6d..37b8b8ba31f7 100644 --- a/trunk/net/l2tp/l2tp_eth.c +++ b/trunk/net/l2tp/l2tp_eth.c @@ -291,7 +291,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p out_del_dev: free_netdev(dev); - spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index bf87c70ac6c5..5f3620f0bc0a 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; - memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); + memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 00ade7feb2e3..61c621e9273f 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -531,11 +531,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; - - /* make sure category field is present */ - if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) - return RX_DROP_MONITOR; - mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && @@ -888,16 +883,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { - unsigned int hdrlen; - __be16 ethertype; - - hdrlen = ieee80211_hdrlen(hdr->frame_control); - - if (rx->skb->len < hdrlen + 8) - return RX_DROP_MONITOR; - - skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); - if (ethertype == rx->sdata->control_port_protocol) + u16 ethertype; + u8 *payload; + + payload = rx->skb->data + + ieee80211_hdrlen(hdr->frame_control); + ethertype = (payload[6] << 8) | payload[7]; + if (cpu_to_be16(ethertype) == + rx->sdata->control_port_protocol) return RX_CONTINUE; } @@ -1469,14 +1462,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; - - if (ieee80211_is_ctl(fc)) - return RX_CONTINUE; - sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || + (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; @@ -1899,20 +1889,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); - - /* make sure fixed part of mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, hdrlen + 6)) - return RX_DROP_MONITOR; - - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - - /* make sure full mesh header is there, also checks skb len */ - if (!pskb_may_pull(rx->skb, - hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) - return RX_DROP_MONITOR; - - /* reload pointers */ - hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ @@ -1921,8 +1897,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; - if (!ieee80211_is_data(hdr->frame_control) || - !(status->rx_flags & IEEE80211_RX_RA_MATCH)) + if (!ieee80211_is_data(hdr->frame_control)) return RX_CONTINUE; if (!mesh_hdr->ttl) @@ -1936,12 +1911,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; - } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { - /* has_a4 already checked in ieee80211_rx_mesh_check */ + } else { mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; - } else { - return RX_DROP_MONITOR; } rcu_read_lock(); @@ -1969,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) + goto out; + if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); - goto out; + return RX_DROP_MONITOR; } if (!ifmsh->mshcfg.dot11MeshForwarding) @@ -2378,10 +2353,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.self_prot.action_code))) - break; - switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: @@ -2400,10 +2371,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: - if (len < (IEEE80211_MIN_ACTION_SIZE + - sizeof(mgmt->u.action.u.mesh_action.action_code))) - break; - if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && @@ -2946,15 +2913,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; - if (ieee80211_is_mgmt(fc)) { - /* drop frame if too short for header */ - if (skb->len < ieee80211_hdrlen(fc)) - err = -ENOBUFS; - else - err = skb_linearize(skb); - } else { + if (ieee80211_is_mgmt(fc)) + err = skb_linearize(skb); + else err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); - } if (err) { dev_kfree_skb(skb); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 239391807ca9..94e586873979 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -643,41 +643,13 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, break; } - switch (id) { - case WLAN_EID_SSID: - case WLAN_EID_SUPP_RATES: - case WLAN_EID_FH_PARAMS: - case WLAN_EID_DS_PARAMS: - case WLAN_EID_CF_PARAMS: - case WLAN_EID_TIM: - case WLAN_EID_IBSS_PARAMS: - case WLAN_EID_CHALLENGE: - case WLAN_EID_RSN: - case WLAN_EID_ERP_INFO: - case WLAN_EID_EXT_SUPP_RATES: - case WLAN_EID_HT_CAPABILITY: - case WLAN_EID_HT_OPERATION: - case WLAN_EID_VHT_CAPABILITY: - case WLAN_EID_VHT_OPERATION: - case WLAN_EID_MESH_ID: - case WLAN_EID_MESH_CONFIG: - case WLAN_EID_PEER_MGMT: - case WLAN_EID_PREQ: - case WLAN_EID_PREP: - case WLAN_EID_PERR: - case WLAN_EID_RANN: - case WLAN_EID_CHANNEL_SWITCH: - case WLAN_EID_EXT_CHANSWITCH_ANN: - case WLAN_EID_COUNTRY: - case WLAN_EID_PWR_CONSTRAINT: - case WLAN_EID_TIMEOUT_INTERVAL: - if (test_bit(id, seen_elems)) { - elems->parse_error = true; - left -= elen; - pos += elen; - continue; - } - break; + if (id != WLAN_EID_VENDOR_SPECIFIC && + id != WLAN_EID_QUIET && + test_bit(id, seen_elems)) { + elems->parse_error = true; + left -= elen; + pos += elen; + continue; } if (calc_crc && id < 64 && (filter & (1ULL << id))) diff --git a/trunk/net/netfilter/nf_conntrack_h323_main.c b/trunk/net/netfilter/nf_conntrack_h323_main.c index 962795e839ab..1b30b0dee708 100644 --- a/trunk/net/netfilter/nf_conntrack_h323_main.c +++ b/trunk/net/netfilter/nf_conntrack_h323_main.c @@ -753,8 +753,7 @@ static int callforward_do_filter(const union nf_inet_addr *src, flowi4_to_flowi(&fl1), false)) { if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, flowi4_to_flowi(&fl2), false)) { - if (rt_nexthop(rt1, fl1.daddr) == - rt_nexthop(rt2, fl2.daddr) && + if (rt1->rt_gateway == rt2->rt_gateway && rt1->dst.dev == rt2->dst.dev) ret = 1; dst_release(&rt2->dst); diff --git a/trunk/net/sched/sch_qfq.c b/trunk/net/sched/sch_qfq.c index 9687fa1c2275..f0dd83cff906 100644 --- a/trunk/net/sched/sch_qfq.c +++ b/trunk/net/sched/sch_qfq.c @@ -84,19 +84,18 @@ * grp->index is the index of the group; and grp->slot_shift * is the shift for the corresponding (scaled) sigma_i. */ -#define QFQ_MAX_INDEX 24 -#define QFQ_MAX_WSHIFT 12 +#define QFQ_MAX_INDEX 19 +#define QFQ_MAX_WSHIFT 16 #define QFQ_MAX_WEIGHT (1<wsum += delta_w; } -static void qfq_update_reactivate_class(struct qfq_sched *q, - struct qfq_class *cl, - u32 inv_w, u32 lmax, int delta_w) -{ - bool need_reactivation = false; - int i = qfq_calc_index(inv_w, lmax); - - if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { - /* - * shift cl->F back, to not charge the - * class for the not-yet-served head - * packet - */ - cl->F = cl->S; - /* remove class from its slot in the old group */ - qfq_deactivate_class(q, cl); - need_reactivation = true; - } - - qfq_update_class_params(q, cl, lmax, inv_w, delta_w); - - if (need_reactivation) /* activate in new group */ - qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); -} - - static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca, unsigned long *arg) { @@ -265,7 +238,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct qfq_class *cl = (struct qfq_class *)*arg; struct nlattr *tb[TCA_QFQ_MAX + 1]; u32 weight, lmax, inv_w; - int err; + int i, err; int delta_w; if (tca[TCA_OPTIONS] == NULL) { @@ -297,14 +270,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tb[TCA_QFQ_LMAX]) { lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); - if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { + if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { pr_notice("qfq: invalid max length %u\n", lmax); return -EINVAL; } } else - lmax = psched_mtu(qdisc_dev(sch)); + lmax = 1UL << QFQ_MTU_SHIFT; if (cl != NULL) { + bool need_reactivation = false; + if (tca[TCA_RATE]) { err = gen_replace_estimator(&cl->bstats, &cl->rate_est, qdisc_root_sleeping_lock(sch), @@ -316,8 +291,24 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (lmax == cl->lmax && inv_w == cl->inv_w) return 0; /* nothing to update */ + i = qfq_calc_index(inv_w, lmax); sch_tree_lock(sch); - qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); + if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { + /* + * shift cl->F back, to not charge the + * class for the not-yet-served head + * packet + */ + cl->F = cl->S; + /* remove class from its slot in the old group */ + qfq_deactivate_class(q, cl); + need_reactivation = true; + } + + qfq_update_class_params(q, cl, lmax, inv_w, delta_w); + + if (need_reactivation) /* activate in new group */ + qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); sch_tree_unlock(sch); return 0; @@ -672,48 +663,15 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) /* - * If the weight and lmax (max_pkt_size) of the classes do not change, - * then QFQ guarantees that the slot index is never higher than - * 2 + ((1<S rounded on grp->slot_shift bits. */ static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, u64 roundedS) { u64 slot = (roundedS - grp->S) >> grp->slot_shift; - unsigned int i; /* slot index in the bucket list */ - - if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { - u64 deltaS = roundedS - grp->S - - ((u64)(QFQ_MAX_SLOTS - 2)<slot_shift); - cl->S -= deltaS; - cl->F -= deltaS; - slot = QFQ_MAX_SLOTS - 2; - } - - i = (grp->front + slot) % QFQ_MAX_SLOTS; + unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; hlist_add_head(&cl->next, &grp->slots[i]); __set_bit(slot, &grp->full_slots); @@ -934,13 +892,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) } pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); - if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { - pr_debug("qfq: increasing maxpkt from %u to %u for class %u", - cl->lmax, qdisc_pkt_len(skb), cl->common.classid); - qfq_update_reactivate_class(q, cl, cl->inv_w, - qdisc_pkt_len(skb), 0); - } - err = qdisc_enqueue(skb, cl->qdisc); if (unlikely(err != NET_XMIT_SUCCESS)) { pr_debug("qfq_enqueue: enqueue failed %d\n", err); diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index a60d1f8b41c5..59d16ea927f0 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -974,7 +974,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, void *addr_buf; struct sctp_af *af; - SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p" + SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); if (unlikely(addrs_size <= 0)) diff --git a/trunk/net/sunrpc/backchannel_rqst.c b/trunk/net/sunrpc/backchannel_rqst.c index a9c0bbccad6b..5a3d675d2f2f 100644 --- a/trunk/net/sunrpc/backchannel_rqst.c +++ b/trunk/net/sunrpc/backchannel_rqst.c @@ -172,7 +172,7 @@ int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) xprt_free_allocation(req); dprintk("RPC: setup backchannel transport failed\n"); - return -ENOMEM; + return -1; } EXPORT_SYMBOL_GPL(xprt_setup_backchannel); diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c index b36f0fcd9bdf..111ff8300ae5 100644 --- a/trunk/net/tipc/handler.c +++ b/trunk/net/tipc/handler.c @@ -116,6 +116,7 @@ void tipc_handler_stop(void) return; handler_enabled = 0; + tasklet_disable(&tipc_tasklet); tasklet_kill(&tipc_tasklet); spin_lock_bh(&qitem_lock); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 3f7253052088..443d4d7deea2 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -526,7 +526,8 @@ int wiphy_register(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { sband->channels[i].orig_flags = sband->channels[i].flags; - sband->channels[i].orig_mag = INT_MAX; + sband->channels[i].orig_mag = + sband->channels[i].max_antenna_gain; sband->channels[i].orig_mpwr = sband->channels[i].max_power; sband->channels[i].band = band; diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index bcc7d7ee5a51..3b8cbbc214db 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -908,7 +908,7 @@ static void handle_channel(struct wiphy *wiphy, map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = chan->orig_mag = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = chan->orig_mpwr = + chan->max_power = chan->orig_mpwr = (int) MBM_TO_DBM(power_rule->max_eirp); return; } @@ -1331,8 +1331,7 @@ static void handle_channel_custom(struct wiphy *wiphy, chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags; chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain); - chan->max_reg_power = chan->max_power = - (int) MBM_TO_DBM(power_rule->max_eirp); + chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); } static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band, diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 2762e8329986..ef35f4ef2aa6 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -309,21 +309,23 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) +static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) { int ae = meshhdr->flags & MESH_FLAGS_AE; - /* 802.11-2012, 8.2.4.7.3 */ + /* 7.1.3.5a.2 */ switch (ae) { - default: case 0: return 6; case MESH_FLAGS_AE_A4: return 12; case MESH_FLAGS_AE_A5_A6: return 18; + case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6): + return 24; + default: + return 6; } } -EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, enum nl80211_iftype iftype) @@ -371,8 +373,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A4) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), @@ -397,8 +397,6 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, /* make sure meshdr->flags is on the linear part */ if (!pskb_may_pull(skb, hdrlen + 1)) return -1; - if (meshdr->flags & MESH_FLAGS_AE_A5_A6) - return -1; if (meshdr->flags & MESH_FLAGS_AE_A4) skb_copy_bits(skb, hdrlen + offsetof(struct ieee80211s_hdr, eaddr1), diff --git a/trunk/scripts/Makefile.modinst b/trunk/scripts/Makefile.modinst index ecbb44797e28..dda4b2b61927 100644 --- a/trunk/scripts/Makefile.modinst +++ b/trunk/scripts/Makefile.modinst @@ -16,9 +16,8 @@ PHONY += $(modules) __modinst: $(modules) @: -# Don't stop modules_install if we can't sign external modules. quiet_cmd_modules_install = INSTALL $@ - cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) + cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default INSTALL_MOD_DIR ?= extra diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index f18750e3bd6c..21a9f5de0a21 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1890,10 +1890,8 @@ sub process { } if ($realfile =~ m@^(drivers/net/|net/)@ && - $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ - $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ - $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ - $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ + $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ && + $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { WARN("NETWORKING_BLOCK_COMMENT_STYLE", "networking block comments put the trailing */ on a separate line\n" . $herecurr); } diff --git a/trunk/scripts/kconfig/expr.h b/trunk/scripts/kconfig/expr.h index cdd48600e02a..bd2e09895553 100644 --- a/trunk/scripts/kconfig/expr.h +++ b/trunk/scripts/kconfig/expr.h @@ -12,7 +12,7 @@ extern "C" { #include #include -#include "list.h" +#include #ifndef __cplusplus #include #endif @@ -175,11 +175,12 @@ struct menu { #define MENU_ROOT 0x0002 struct jump_key { - struct list_head entries; + CIRCLEQ_ENTRY(jump_key) entries; size_t offset; struct menu *target; int index; }; +CIRCLEQ_HEAD(jk_head, jump_key); #define JUMP_NB 9 diff --git a/trunk/scripts/kconfig/list.h b/trunk/scripts/kconfig/list.h deleted file mode 100644 index 0ae730be5f49..000000000000 --- a/trunk/scripts/kconfig/list.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef LIST_H -#define LIST_H - -/* - * Copied from include/linux/... - */ - -#undef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - - -struct list_head { - struct list_head *next, *prev; -}; - - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *_new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = _new; - _new->next = next; - _new->prev = prev; - prev->next = _new; -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *_new, struct list_head *head) -{ - __list_add(_new, head->prev, head); -} - -#endif diff --git a/trunk/scripts/kconfig/lkc_proto.h b/trunk/scripts/kconfig/lkc_proto.h index ef1a7381f956..1d1c08537f1e 100644 --- a/trunk/scripts/kconfig/lkc_proto.h +++ b/trunk/scripts/kconfig/lkc_proto.h @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head *head)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); diff --git a/trunk/scripts/kconfig/mconf.c b/trunk/scripts/kconfig/mconf.c index 53975cf87608..48f67448af7b 100644 --- a/trunk/scripts/kconfig/mconf.c +++ b/trunk/scripts/kconfig/mconf.c @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) struct search_data { - struct list_head *head; + struct jk_head *head; struct menu **targets; int *keys; }; @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) struct jump_key *pos; int k = 0; - list_for_each_entry(pos, data->head, entries) { + CIRCLEQ_FOREACH(pos, data->head, entries) { if (pos->offset >= start && pos->offset < end) { char header[4]; @@ -375,7 +375,7 @@ static void search_conf(void) sym_arr = sym_re_search(dialog_input); do { - LIST_HEAD(head); + struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); struct menu *targets[JUMP_NB]; int keys[JUMP_NB + 1], i; struct search_data data = { diff --git a/trunk/scripts/kconfig/menu.c b/trunk/scripts/kconfig/menu.c index e98a05c8e508..a3cade659f89 100644 --- a/trunk/scripts/kconfig/menu.c +++ b/trunk/scripts/kconfig/menu.c @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) } static void get_prompt_str(struct gstr *r, struct property *prop, - struct list_head *head) + struct jk_head *head) { int i, j; struct menu *submenu[8], *menu, *location = NULL; @@ -544,13 +544,12 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } else jump->target = location; - if (list_empty(head)) + if (CIRCLEQ_EMPTY(head)) jump->index = 0; else - jump->index = list_entry(head->prev, struct jump_key, - entries)->index + 1; + jump->index = CIRCLEQ_LAST(head)->index + 1; - list_add_tail(&jump->entries, head); + CIRCLEQ_INSERT_TAIL(head, jump, entries); } if (i > 0) { @@ -574,8 +573,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop, /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, - struct list_head *head) +void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) { bool hit; struct property *prop; @@ -614,7 +612,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, str_append(r, "\n\n"); } -struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) +struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) { struct symbol *sym; struct gstr res = str_new(); diff --git a/trunk/sound/core/oss/mixer_oss.c b/trunk/sound/core/oss/mixer_oss.c index e8a1d18774b2..a9a2e63c0222 100644 --- a/trunk/sound/core/oss/mixer_oss.c +++ b/trunk/sound/core/oss/mixer_oss.c @@ -76,7 +76,6 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) snd_card_unref(card); return -EFAULT; } - snd_card_unref(card); return 0; } diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 4c1cc51772e6..f337b66a020b 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -2454,7 +2454,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) mutex_unlock(&pcm->open_mutex); if (err < 0) goto __error; - snd_card_unref(pcm->card); return err; __error: diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index f9ddecf2f4cd..6e8872de5ba0 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -2122,8 +2122,7 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_PLAYBACK); err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); - if (pcm) - snd_card_unref(pcm->card); + snd_card_unref(pcm->card); return err; } @@ -2136,8 +2135,7 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_CAPTURE); err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); - if (pcm) - snd_card_unref(pcm->card); + snd_card_unref(pcm->card); return err; } diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 70ccdab74153..89780c323f19 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -114,7 +114,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type) mreg = snd_minors[minor]; if (mreg && mreg->type == type) { private_data = mreg->private_data; - if (private_data && mreg->card_ptr) + if (mreg->card_ptr) atomic_inc(&mreg->card_ptr->refcount); } else private_data = NULL; diff --git a/trunk/sound/core/sound_oss.c b/trunk/sound/core/sound_oss.c index 726a49ac9725..e1d79ee35906 100644 --- a/trunk/sound/core/sound_oss.c +++ b/trunk/sound/core/sound_oss.c @@ -54,7 +54,7 @@ void *snd_lookup_oss_minor_data(unsigned int minor, int type) mreg = snd_oss_minors[minor]; if (mreg && mreg->type == type) { private_data = mreg->private_data; - if (private_data && mreg->card_ptr) + if (mreg->card_ptr) atomic_inc(&mreg->card_ptr->refcount); } else private_data = NULL; diff --git a/trunk/sound/i2c/other/ak4113.c b/trunk/sound/i2c/other/ak4113.c index e04e750a77ed..ef68d710d08c 100644 --- a/trunk/sound/i2c/other/ak4113.c +++ b/trunk/sound/i2c/other/ak4113.c @@ -426,7 +426,7 @@ static struct snd_kcontrol_new snd_ak4113_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4113_spdif_pinfo, diff --git a/trunk/sound/i2c/other/ak4114.c b/trunk/sound/i2c/other/ak4114.c index 5bf4fca19e48..816e7d225fb0 100644 --- a/trunk/sound/i2c/other/ak4114.c +++ b/trunk/sound/i2c/other/ak4114.c @@ -401,7 +401,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_spdif_pinfo, .get = snd_ak4114_spdif_pget, diff --git a/trunk/sound/i2c/other/ak4117.c b/trunk/sound/i2c/other/ak4117.c index 40e33c9f2b09..b4b2a51fc117 100644 --- a/trunk/sound/i2c/other/ak4117.c +++ b/trunk/sound/i2c/other/ak4117.c @@ -380,7 +380,7 @@ static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = { }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 Preamble Capture Default", + .name = "IEC958 Preample Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4117_spdif_pinfo, .get = snd_ak4117_spdif_pget, diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index 50169bcfd903..5d0e568fdea1 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -2655,8 +2655,6 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { { TYPE_MAESTRO2E, 0x1179 }, { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ { TYPE_MAESTRO2E, 0x1558 }, - { TYPE_MAESTRO2E, 0x125d }, /* a PCI card, e.g. Terratec DMX */ - { TYPE_MAESTRO2, 0x125d }, /* a PCI card, e.g. SF64-PCE2 */ }; static struct ess_device_list mpu_blacklist[] __devinitdata = { diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index cd2dbaf1be78..72b085ae7d46 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -3563,8 +3563,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, - { PCI_DEVICE(0x6549, 0x2200), - .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, /* Creative X-Fi (CA0110-IBG) */ /* CTHDA chips */ { PCI_DEVICE(0x1102, 0x0010), diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 1eeba7386666..cdd43eadbc67 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -545,7 +545,6 @@ static int ad198x_build_pcms(struct hda_codec *codec) if (spec->multiout.dig_out_nid) { info++; codec->num_pcms++; - codec->spdif_status_reset = 1; info->name = "AD198x Digital"; info->pcm_type = HDA_PCM_TYPE_SPDIF; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index d5f3a26d608d..61a71131711c 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -101,8 +101,8 @@ enum { #define CS420X_VENDOR_NID 0x11 #define CS_DIG_OUT1_PIN_NID 0x10 #define CS_DIG_OUT2_PIN_NID 0x15 -#define CS_DMIC1_PIN_NID 0x0e -#define CS_DMIC2_PIN_NID 0x12 +#define CS_DMIC1_PIN_NID 0x12 +#define CS_DMIC2_PIN_NID 0x0e /* coef indices */ #define IDX_SPDIF_STAT 0x0000 @@ -1079,18 +1079,14 @@ static void init_input(struct hda_codec *codec) cs_automic(codec, NULL); coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ - cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); - - coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG); if (is_active_pin(codec, CS_DMIC2_PIN_NID)) - coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */ + coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */ if (is_active_pin(codec, CS_DMIC1_PIN_NID)) - coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off + coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off * No effect if SPDIF_OUT2 is * selected in IDX_SPDIF_CTL. */ - - cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); + cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); } else { if (spec->mic_detect) cs_automic(codec, NULL); @@ -1111,7 +1107,7 @@ static const struct hda_verb cs_coef_init_verbs[] = { | 0x0400 /* Disable Coefficient Auto increment */ )}, /* Beep */ - {0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG}, + {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ {} /* terminator */ @@ -1732,7 +1728,8 @@ static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol, } -static const struct snd_kcontrol_new cs421x_capture_source = { +static struct snd_kcontrol_new cs421x_capture_source = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -1949,7 +1946,7 @@ static int cs421x_suspend(struct hda_codec *codec) } #endif -static const struct hda_codec_ops cs421x_patch_ops = { +static struct hda_codec_ops cs421x_patch_ops = { .build_controls = cs421x_build_controls, .build_pcms = cs_build_pcms, .init = cs421x_init, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index c0ce3b1f04b4..f7397ad02a0d 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5840,7 +5840,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) return alc_parse_auto_config(codec, alc269_ignore, ssids); } -static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) +static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); if (power_up) @@ -5857,10 +5857,10 @@ static void alc269_shutup(struct hda_codec *codec) if (spec->codec_variant != ALC269_TYPE_ALC269VB) return; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && - (alc_get_coef0(codec) & 0x00ff) == 0x018) { + if ((alc_get_coef0(codec) & 0x00ff) == 0x017) + alc269_toggle_power_output(codec, 0); + if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } } @@ -5870,22 +5870,24 @@ static int alc269_resume(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 0); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x018) { + alc269_toggle_power_output(codec, 0); msleep(150); } codec->patch_ops.init(codec); - if (spec->codec_variant == ALC269_TYPE_ALC269VB) - alc269vb_toggle_power_output(codec, 1); - if (spec->codec_variant == ALC269_TYPE_ALC269VB && + if (spec->codec_variant == ALC269_TYPE_ALC269VB || (alc_get_coef0(codec) & 0x00ff) == 0x017) { + alc269_toggle_power_output(codec, 1); msleep(200); } + if (spec->codec_variant == ALC269_TYPE_ALC269VB || + (alc_get_coef0(codec) & 0x00ff) == 0x018) + alc269_toggle_power_output(codec, 1); + snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); hda_call_check_power_status(codec, 0x01); @@ -7077,7 +7079,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc662 }, { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, - { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, @@ -7095,7 +7096,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, - { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 019e1a00414a..72a2f60b087c 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -1809,11 +1809,11 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; - int i; + int i, dac_num; hda_nid_t nid; - spec->multiout.num_dacs = 0; spec->multiout.dac_nids = spec->private_dac_nids; + dac_num = 0; for (i = 0; i < cfg->line_outs; i++) { hda_nid_t dac = 0; nid = cfg->line_out_pins[i]; @@ -1824,13 +1824,16 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) if (!i && parse_output_path(codec, nid, dac, 1, &spec->out_mix_path)) dac = spec->out_mix_path.path[0]; - if (dac) - spec->private_dac_nids[spec->multiout.num_dacs++] = dac; + if (dac) { + spec->private_dac_nids[i] = dac; + dac_num++; + } } if (!spec->out_path[0].depth && spec->out_mix_path.depth) { spec->out_path[0] = spec->out_mix_path; spec->out_mix_path.depth = 0; } + spec->multiout.num_dacs = dac_num; return 0; } @@ -3625,7 +3628,6 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) */ enum { VIA_FIXUP_INTMIC_BOOST, - VIA_FIXUP_ASUS_G75, }; static void via_fixup_intmic_boost(struct hda_codec *codec, @@ -3640,35 +3642,13 @@ static const struct hda_fixup via_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = via_fixup_intmic_boost, }, - [VIA_FIXUP_ASUS_G75] = { - .type = HDA_FIXUP_PINS, - .v.pins = (const struct hda_pintbl[]) { - /* set 0x24 and 0x33 as speakers */ - { 0x24, 0x991301f0 }, - { 0x33, 0x991301f1 }, /* subwoofer */ - { } - } - }, }; static const struct snd_pci_quirk vt2002p_fixups[] = { - SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), {} }; -/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e - * Replace this with mixer NID 0x1c - */ -static void fix_vt1802_connections(struct hda_codec *codec) -{ - static hda_nid_t conn_24[] = { 0x14, 0x1c }; - static hda_nid_t conn_33[] = { 0x1c }; - - snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24); - snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33); -} - /* patch for vt2002P */ static int patch_vt2002P(struct hda_codec *codec) { @@ -3683,8 +3663,6 @@ static int patch_vt2002P(struct hda_codec *codec) spec->aa_mix_nid = 0x21; override_mic_boost(codec, 0x2b, 0, 3, 40); override_mic_boost(codec, 0x29, 0, 3, 40); - if (spec->codec_type == VT1802) - fix_vt1802_connections(codec); add_secret_dac_path(codec); snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 748e36c66603..f1cd1e387801 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -3979,8 +3979,7 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, case 8: /* SYNC IN */ val = hdspm_sync_in_sync_check(hdspm); break; default: - val = hdspm_s1_sync_check(hdspm, - kcontrol->private_value-1); + val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); } break; @@ -4900,7 +4899,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, insel = "Coaxial"; break; default: - insel = "Unknown"; + insel = "Unkown"; } snd_iprintf(buffer, diff --git a/trunk/sound/soc/codecs/cs42l52.c b/trunk/sound/soc/codecs/cs42l52.c index 4d8db3685e96..61599298fb26 100644 --- a/trunk/sound/soc/codecs/cs42l52.c +++ b/trunk/sound/soc/codecs/cs42l52.c @@ -763,7 +763,7 @@ static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai, if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) { cs42l52->sysclk = freq; } else { - dev_err(codec->dev, "Invalid freq parameter\n"); + dev_err(codec->dev, "Invalid freq paramter\n"); return -EINVAL; } return 0; diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index b2b2b37131bd..3fddc7ad1127 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -3722,7 +3722,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) } while (count--); if (count == 0) - dev_warn(codec->dev, "No impedance range reported for jack\n"); + dev_warn(codec->dev, "No impedence range reported for jack\n"); #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); diff --git a/trunk/sound/usb/endpoint.c b/trunk/sound/usb/endpoint.c index 34de6f2faf61..7f78c6d782b0 100644 --- a/trunk/sound/usb/endpoint.c +++ b/trunk/sound/usb/endpoint.c @@ -35,7 +35,6 @@ #define EP_FLAG_ACTIVATED 0 #define EP_FLAG_RUNNING 1 -#define EP_FLAG_STOPPING 2 /* * snd_usb_endpoint is a model that abstracts everything related to an @@ -503,20 +502,10 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) if (alive) snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", alive, ep->ep_num); - clear_bit(EP_FLAG_STOPPING, &ep->flags); return 0; } -/* sync the pending stop operation; - * this function itself doesn't trigger the stop operation - */ -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) -{ - if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) - wait_clear_urbs(ep); -} - /* * unlink active urbs. */ @@ -929,8 +918,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, if (wait) wait_clear_urbs(ep); - else - set_bit(EP_FLAG_STOPPING, &ep->flags); } } diff --git a/trunk/sound/usb/endpoint.h b/trunk/sound/usb/endpoint.h index 3d4c9705041f..6376ccf10fd4 100644 --- a/trunk/sound/usb/endpoint.h +++ b/trunk/sound/usb/endpoint.h @@ -19,7 +19,6 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep); void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, int force, int can_sleep, int wait); -void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); void snd_usb_endpoint_free(struct list_head *head); diff --git a/trunk/sound/usb/pcm.c b/trunk/sound/usb/pcm.c index 5c12a3fe8c3e..37428f74dbb6 100644 --- a/trunk/sound/usb/pcm.c +++ b/trunk/sound/usb/pcm.c @@ -568,9 +568,6 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) goto unlock; } - snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); - snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); - ret = set_format(subs, subs->cur_audiofmt); if (ret < 0) goto unlock; diff --git a/trunk/tools/testing/selftests/Makefile b/trunk/tools/testing/selftests/Makefile index 85baf11e2acd..43480149119e 100644 --- a/trunk/tools/testing/selftests/Makefile +++ b/trunk/tools/testing/selftests/Makefile @@ -1,4 +1,4 @@ -TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug +TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll all: for TARGET in $(TARGETS); do \ diff --git a/trunk/tools/testing/selftests/epoll/Makefile b/trunk/tools/testing/selftests/epoll/Makefile new file mode 100644 index 000000000000..19806ed62f50 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/Makefile @@ -0,0 +1,11 @@ +# Makefile for epoll selftests + +all: test_epoll +%: %.c + gcc -pthread -g -o $@ $^ + +run_tests: all + ./test_epoll + +clean: + $(RM) test_epoll diff --git a/trunk/tools/testing/selftests/epoll/test_epoll.c b/trunk/tools/testing/selftests/epoll/test_epoll.c new file mode 100644 index 000000000000..f7525392ce84 --- /dev/null +++ b/trunk/tools/testing/selftests/epoll/test_epoll.c @@ -0,0 +1,344 @@ +/* + * tools/testing/selftests/epoll/test_epoll.c + * + * Copyright 2012 Adobe Systems Incorporated + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Paton J. Lewis + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * A pointer to an epoll_item_private structure will be stored in the epoll + * item's event structure so that we can get access to the epoll_item_private + * data after calling epoll_wait: + */ +struct epoll_item_private { + int index; /* Position of this struct within the epoll_items array. */ + int fd; + uint32_t events; + pthread_mutex_t mutex; /* Guards the following variables... */ + int stop; + int status; /* Stores any error encountered while handling item. */ + /* The following variable allows us to test whether we have encountered + a problem while attempting to cancel and delete the associated + event. When the test program exits, 'deleted' should be exactly + one. If it is greater than one, then the failed test reflects a real + world situation where we would have tried to access the epoll item's + private data after deleting it: */ + int deleted; +}; + +struct epoll_item_private *epoll_items; + +/* + * Delete the specified item from the epoll set. In a real-world secneario this + * is where we would free the associated data structure, but in this testing + * environment we retain the structure so that we can test for double-deletion: + */ +void delete_item(int index) +{ + __sync_fetch_and_add(&epoll_items[index].deleted, 1); +} + +/* + * A pointer to a read_thread_data structure will be passed as the argument to + * each read thread: + */ +struct read_thread_data { + int stop; + int status; /* Indicates any error encountered by the read thread. */ + int epoll_set; +}; + +/* + * The function executed by the read threads: + */ +void *read_thread_function(void *function_data) +{ + struct read_thread_data *thread_data = + (struct read_thread_data *)function_data; + struct epoll_event event_data; + struct epoll_item_private *item_data; + char socket_data; + + /* Handle events until we encounter an error or this thread's 'stop' + condition is set: */ + while (1) { + int result = epoll_wait(thread_data->epoll_set, + &event_data, + 1, /* Number of desired events */ + 1000); /* Timeout in ms */ + if (result < 0) { + /* Breakpoints signal all threads. Ignore that while + debugging: */ + if (errno == EINTR) + continue; + thread_data->status = errno; + return 0; + } else if (thread_data->stop) + return 0; + else if (result == 0) /* Timeout */ + continue; + + /* We need the mutex here because checking for the stop + condition and re-enabling the epoll item need to be done + together as one atomic operation when EPOLL_CTL_DISABLE is + available: */ + item_data = (struct epoll_item_private *)event_data.data.ptr; + pthread_mutex_lock(&item_data->mutex); + + /* Remove the item from the epoll set if we want to stop + handling that event: */ + if (item_data->stop) + delete_item(item_data->index); + else { + /* Clear the data that was written to the other end of + our non-blocking socket: */ + do { + if (read(item_data->fd, &socket_data, 1) < 1) { + if ((errno == EAGAIN) || + (errno == EWOULDBLOCK)) + break; + else + goto error_unlock; + } + } while (item_data->events & EPOLLET); + + /* The item was one-shot, so re-enable it: */ + event_data.events = item_data->events; + if (epoll_ctl(thread_data->epoll_set, + EPOLL_CTL_MOD, + item_data->fd, + &event_data) < 0) + goto error_unlock; + } + + pthread_mutex_unlock(&item_data->mutex); + } + +error_unlock: + thread_data->status = item_data->status = errno; + pthread_mutex_unlock(&item_data->mutex); + return 0; +} + +/* + * A pointer to a write_thread_data structure will be passed as the argument to + * the write thread: + */ +struct write_thread_data { + int stop; + int status; /* Indicates any error encountered by the write thread. */ + int n_fds; + int *fds; +}; + +/* + * The function executed by the write thread. It writes a single byte to each + * socket in turn until the stop condition for this thread is set. If writing to + * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for + * the moment and just move on to the next socket in the list. We don't care + * about the order in which we deliver events to the epoll set. In fact we don't + * care about the data we're writing to the pipes at all; we just want to + * trigger epoll events: + */ +void *write_thread_function(void *function_data) +{ + const char data = 'X'; + int index; + struct write_thread_data *thread_data = + (struct write_thread_data *)function_data; + while (!thread_data->stop) + for (index = 0; + !thread_data->stop && (index < thread_data->n_fds); + ++index) + if ((write(thread_data->fds[index], &data, 1) < 1) && + (errno != EAGAIN) && + (errno != EWOULDBLOCK)) { + thread_data->status = errno; + return; + } +} + +/* + * Arguments are currently ignored: + */ +int main(int argc, char **argv) +{ + const int n_read_threads = 100; + const int n_epoll_items = 500; + int index; + int epoll_set = epoll_create1(0); + struct write_thread_data write_thread_data = { + 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int)) + }; + struct read_thread_data *read_thread_data = + malloc(n_read_threads * sizeof(struct read_thread_data)); + pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t)); + pthread_t write_thread; + + printf("-----------------\n"); + printf("Runing test_epoll\n"); + printf("-----------------\n"); + + epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private)); + + if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 || + read_thread_data == 0 || read_threads == 0) + goto error; + + if (sysconf(_SC_NPROCESSORS_ONLN) < 2) { + printf("Error: please run this test on a multi-core system.\n"); + goto error; + } + + /* Create the socket pairs and epoll items: */ + for (index = 0; index < n_epoll_items; ++index) { + int socket_pair[2]; + struct epoll_event event_data; + if (socketpair(AF_UNIX, + SOCK_STREAM | SOCK_NONBLOCK, + 0, + socket_pair) < 0) + goto error; + write_thread_data.fds[index] = socket_pair[0]; + epoll_items[index].index = index; + epoll_items[index].fd = socket_pair[1]; + if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0) + goto error; + /* We always use EPOLLONESHOT because this test is currently + structured to demonstrate the need for EPOLL_CTL_DISABLE, + which only produces useful information in the EPOLLONESHOT + case (without EPOLLONESHOT, calling epoll_ctl with + EPOLL_CTL_DISABLE will never return EBUSY). If support for + testing events without EPOLLONESHOT is desired, it should + probably be implemented in a separate unit test. */ + epoll_items[index].events = EPOLLIN | EPOLLONESHOT; + if (index < n_epoll_items / 2) + epoll_items[index].events |= EPOLLET; + epoll_items[index].stop = 0; + epoll_items[index].status = 0; + epoll_items[index].deleted = 0; + event_data.events = epoll_items[index].events; + event_data.data.ptr = &epoll_items[index]; + if (epoll_ctl(epoll_set, + EPOLL_CTL_ADD, + epoll_items[index].fd, + &event_data) < 0) + goto error; + } + + /* Create and start the read threads: */ + for (index = 0; index < n_read_threads; ++index) { + read_thread_data[index].stop = 0; + read_thread_data[index].status = 0; + read_thread_data[index].epoll_set = epoll_set; + if (pthread_create(&read_threads[index], + NULL, + read_thread_function, + &read_thread_data[index]) != 0) + goto error; + } + + if (pthread_create(&write_thread, + NULL, + write_thread_function, + &write_thread_data) != 0) + goto error; + + /* Cancel all event pollers: */ +#ifdef EPOLL_CTL_DISABLE + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + if (epoll_ctl(epoll_set, + EPOLL_CTL_DISABLE, + epoll_items[index].fd, + NULL) == 0) + delete_item(index); + else if (errno != EBUSY) { + pthread_mutex_unlock(&epoll_items[index].mutex); + goto error; + } + /* EBUSY means events were being handled; allow the other thread + to delete the item. */ + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#else + for (index = 0; index < n_epoll_items; ++index) { + pthread_mutex_lock(&epoll_items[index].mutex); + ++epoll_items[index].stop; + pthread_mutex_unlock(&epoll_items[index].mutex); + /* Wait in case a thread running read_thread_function is + currently executing code between epoll_wait and + pthread_mutex_lock with this item. Note that a longer delay + would make double-deletion less likely (at the expense of + performance), but there is no guarantee that any delay would + ever be sufficient. Note also that we delete all event + pollers at once for testing purposes, but in a real-world + environment we are likely to want to be able to cancel event + pollers at arbitrary times. Therefore we can't improve this + situation by just splitting this loop into two loops + (i.e. signal 'stop' for all items, sleep, and then delete all + items). We also can't fix the problem via EPOLL_CTL_DEL + because that command can't prevent the case where some other + thread is executing read_thread_function within the region + mentioned above: */ + usleep(1); + pthread_mutex_lock(&epoll_items[index].mutex); + if (!epoll_items[index].deleted) + delete_item(index); + pthread_mutex_unlock(&epoll_items[index].mutex); + } +#endif + + /* Shut down the read threads: */ + for (index = 0; index < n_read_threads; ++index) + __sync_fetch_and_add(&read_thread_data[index].stop, 1); + for (index = 0; index < n_read_threads; ++index) { + if (pthread_join(read_threads[index], NULL) != 0) + goto error; + if (read_thread_data[index].status) + goto error; + } + + /* Shut down the write thread: */ + __sync_fetch_and_add(&write_thread_data.stop, 1); + if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status) + goto error; + + /* Check for final error conditions: */ + for (index = 0; index < n_epoll_items; ++index) { + if (epoll_items[index].status != 0) + goto error; + if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0) + goto error; + } + for (index = 0; index < n_epoll_items; ++index) + if (epoll_items[index].deleted != 1) { + printf("Error: item data deleted %1d times.\n", + epoll_items[index].deleted); + goto error; + } + + printf("[PASS]\n"); + return 0; + + error: + printf("[FAIL]\n"); + return errno; +}