diff options
414 files changed, 3451 insertions, 1951 deletions
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 615142da4ef..157416e78cc 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -21,6 +21,7 @@ Supported adapters:    * Intel DH89xxCC (PCH)    * Intel Panther Point (PCH)    * Intel Lynx Point (PCH) +  * Intel Lynx Point-LP (PCH)     Datasheets: Publicly available at the Intel website  On Intel Patsburg and later chipsets, both the normal host SMBus controller diff --git a/MAINTAINERS b/MAINTAINERS index fdc0119963e..53cc13c82cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3388,7 +3388,7 @@ M:	"Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>  L:	linux-i2c@vger.kernel.org  W:	http://i2c.wiki.kernel.org/  T:	quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ -T:	git git://git.fluff.org/bjdooks/linux.git +T:	git git://git.pengutronix.de/git/wsa/linux.git  S:	Maintained  F:	Documentation/i2c/  F:	drivers/i2c/ @@ -1,7 +1,7 @@  VERSION = 3  PATCHLEVEL = 6  SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6  NAME = Saber-toothed Squirrel  # *DOCUMENTATION* diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index f15f82bf3a5..e968a52e488 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -356,15 +356,15 @@ choice  		  is nothing connected to read from the DCC.  	config DEBUG_SEMIHOSTING -		bool "Kernel low-level debug output via semihosting I" +		bool "Kernel low-level debug output via semihosting I/O"  		help  		  Semihosting enables code running on an ARM target to use  		  the I/O facilities on a host debugger/emulator through a -		  simple SVC calls. The host debugger or emulator must have +		  simple SVC call. The host debugger or emulator must have  		  semihosting enabled for the special svc call to be trapped  		  otherwise the kernel will crash. -		  This is known to work with OpenOCD, as wellas +		  This is known to work with OpenOCD, as well as  		  ARM's Fast Models, or any other controlling environment  		  that implements semihosting. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 30eae87ead6..a051dfbdd7d 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -284,10 +284,10 @@ zImage Image xipImage bootpImage uImage: vmlinux  zinstall uinstall install: vmlinux  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ -%.dtb: +%.dtb: scripts  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ -dtbs: +dtbs: scripts  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@  # We use MRPROPER_FILES and CLEAN_FILES now diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b8c64b80baf..81769c1341f 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -659,10 +659,14 @@ __armv7_mmu_cache_on:  #ifdef CONFIG_CPU_ENDIAN_BE8  		orr	r0, r0, #1 << 25	@ big-endian page tables  #endif +		mrcne   p15, 0, r6, c2, c0, 2   @ read ttb control reg  		orrne	r0, r0, #1		@ MMU enabled  		movne	r1, #0xfffffffd		@ domain 0 = client +		bic     r6, r6, #1 << 31        @ 32-bit translation system +		bic     r6, r6, #3 << 0         @ use only ttbr0  		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer  		mcrne	p15, 0, r1, c3, c0, 0	@ load domain access control +		mcrne   p15, 0, r6, c2, c0, 2   @ load ttb control  #endif  		mcr	p15, 0, r0, c7, c5, 4	@ ISB  		mcr	p15, 0, r0, c1, c0, 0	@ load control register diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 03fb93621d0..5c8b3bf4d82 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -320,4 +320,12 @@  	.size \name , . - \name  	.endm +	.macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req +#ifndef CONFIG_CPU_USE_DOMAINS +	adds	\tmp, \addr, #\size - 1 +	sbcccs	\tmp, \tmp, \limit +	bcs	\bad +#endif +	.endm +  #endif /* __ASM_ASSEMBLER_H__ */ diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index e965f1b560f..5f6ddcc5645 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -187,6 +187,7 @@ static inline unsigned long __phys_to_virt(unsigned long x)  #define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)  #endif  #endif +#endif /* __ASSEMBLY__ */  #ifndef PHYS_OFFSET  #ifdef PLAT_PHYS_OFFSET @@ -196,6 +197,8 @@ static inline unsigned long __phys_to_virt(unsigned long x)  #endif  #endif +#ifndef __ASSEMBLY__ +  /*   * PFNs are used to describe any physical page; this means   * PFN 0 == physical address 0. diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 314d4664eae..99a19512ee2 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -199,6 +199,9 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,  {  	pgtable_page_dtor(pte); +#ifdef CONFIG_ARM_LPAE +	tlb_add_flush(tlb, addr); +#else  	/*  	 * With the classic ARM MMU, a pte page has two corresponding pmd  	 * entries, each covering 1MB. @@ -206,6 +209,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,  	addr &= PMD_MASK;  	tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);  	tlb_add_flush(tlb, addr + SZ_1M); +#endif  	tlb_remove_page(tlb, pte);  } diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 479a6352e0b..77bd79f2ffd 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -101,28 +101,39 @@ extern int __get_user_1(void *);  extern int __get_user_2(void *);  extern int __get_user_4(void *); -#define __get_user_x(__r2,__p,__e,__s,__i...)				\ +#define __GUP_CLOBBER_1	"lr", "cc" +#ifdef CONFIG_CPU_USE_DOMAINS +#define __GUP_CLOBBER_2	"ip", "lr", "cc" +#else +#define __GUP_CLOBBER_2 "lr", "cc" +#endif +#define __GUP_CLOBBER_4	"lr", "cc" + +#define __get_user_x(__r2,__p,__e,__l,__s)				\  	   __asm__ __volatile__ (					\  		__asmeq("%0", "r0") __asmeq("%1", "r2")			\ +		__asmeq("%3", "r1")					\  		"bl	__get_user_" #__s				\  		: "=&r" (__e), "=r" (__r2)				\ -		: "0" (__p)						\ -		: __i, "cc") +		: "0" (__p), "r" (__l)					\ +		: __GUP_CLOBBER_##__s) -#define get_user(x,p)							\ +#define __get_user_check(x,p)							\  	({								\ +		unsigned long __limit = current_thread_info()->addr_limit - 1; \  		register const typeof(*(p)) __user *__p asm("r0") = (p);\  		register unsigned long __r2 asm("r2");			\ +		register unsigned long __l asm("r1") = __limit;		\  		register int __e asm("r0");				\  		switch (sizeof(*(__p))) {				\  		case 1:							\ -			__get_user_x(__r2, __p, __e, 1, "lr");		\ -	       		break;						\ +			__get_user_x(__r2, __p, __e, __l, 1);		\ +			break;						\  		case 2:							\ -			__get_user_x(__r2, __p, __e, 2, "r3", "lr");	\ +			__get_user_x(__r2, __p, __e, __l, 2);		\  			break;						\  		case 4:							\ -	       		__get_user_x(__r2, __p, __e, 4, "lr");		\ +			__get_user_x(__r2, __p, __e, __l, 4);		\  			break;						\  		default: __e = __get_user_bad(); break;			\  		}							\ @@ -130,42 +141,57 @@ extern int __get_user_4(void *);  		__e;							\  	}) +#define get_user(x,p)							\ +	({								\ +		might_fault();						\ +		__get_user_check(x,p);					\ +	 }) +  extern int __put_user_1(void *, unsigned int);  extern int __put_user_2(void *, unsigned int);  extern int __put_user_4(void *, unsigned int);  extern int __put_user_8(void *, unsigned long long); -#define __put_user_x(__r2,__p,__e,__s)					\ +#define __put_user_x(__r2,__p,__e,__l,__s)				\  	   __asm__ __volatile__ (					\  		__asmeq("%0", "r0") __asmeq("%2", "r2")			\ +		__asmeq("%3", "r1")					\  		"bl	__put_user_" #__s				\  		: "=&r" (__e)						\ -		: "0" (__p), "r" (__r2)					\ +		: "0" (__p), "r" (__r2), "r" (__l)			\  		: "ip", "lr", "cc") -#define put_user(x,p)							\ +#define __put_user_check(x,p)							\  	({								\ +		unsigned long __limit = current_thread_info()->addr_limit - 1; \  		register const typeof(*(p)) __r2 asm("r2") = (x);	\  		register const typeof(*(p)) __user *__p asm("r0") = (p);\ +		register unsigned long __l asm("r1") = __limit;		\  		register int __e asm("r0");				\  		switch (sizeof(*(__p))) {				\  		case 1:							\ -			__put_user_x(__r2, __p, __e, 1);		\ +			__put_user_x(__r2, __p, __e, __l, 1);		\  			break;						\  		case 2:							\ -			__put_user_x(__r2, __p, __e, 2);		\ +			__put_user_x(__r2, __p, __e, __l, 2);		\  			break;						\  		case 4:							\ -			__put_user_x(__r2, __p, __e, 4);		\ +			__put_user_x(__r2, __p, __e, __l, 4);		\  			break;						\  		case 8:							\ -			__put_user_x(__r2, __p, __e, 8);		\ +			__put_user_x(__r2, __p, __e, __l, 8);		\  			break;						\  		default: __e = __put_user_bad(); break;			\  		}							\  		__e;							\  	}) +#define put_user(x,p)							\ +	({								\ +		might_fault();						\ +		__put_user_check(x,p);					\ +	 }) +  #else /* CONFIG_MMU */  /* @@ -219,6 +245,7 @@ do {									\  	unsigned long __gu_addr = (unsigned long)(ptr);			\  	unsigned long __gu_val;						\  	__chk_user_ptr(ptr);						\ +	might_fault();							\  	switch (sizeof(*(ptr))) {					\  	case 1:	__get_user_asm_byte(__gu_val,__gu_addr,err);	break;	\  	case 2:	__get_user_asm_half(__gu_val,__gu_addr,err);	break;	\ @@ -300,6 +327,7 @@ do {									\  	unsigned long __pu_addr = (unsigned long)(ptr);			\  	__typeof__(*(ptr)) __pu_val = (x);				\  	__chk_user_ptr(ptr);						\ +	might_fault();							\  	switch (sizeof(*(ptr))) {					\  	case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);	break;	\  	case 2: __put_user_asm_half(__pu_val,__pu_addr,err);	break;	\ diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd9410..281bf330124 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -159,6 +159,12 @@ static int debug_arch_supported(void)  		arch >= ARM_DEBUG_ARCH_V7_1;  } +/* Can we determine the watchpoint access type from the fsr? */ +static int debug_exception_updates_fsr(void) +{ +	return 0; +} +  /* Determine number of WRP registers available. */  static int get_num_wrp_resources(void)  { @@ -604,13 +610,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)  		/* Aligned */  		break;  	case 1: -		/* Allow single byte watchpoint. */ -		if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) -			break;  	case 2:  		/* Allow halfword watchpoints and breakpoints. */  		if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)  			break; +	case 3: +		/* Allow single byte watchpoint. */ +		if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) +			break;  	default:  		ret = -EINVAL;  		goto out; @@ -619,18 +626,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)  	info->address &= ~alignment_mask;  	info->ctrl.len <<= offset; -	/* -	 * Currently we rely on an overflow handler to take -	 * care of single-stepping the breakpoint when it fires. -	 * In the case of userspace breakpoints on a core with V7 debug, -	 * we can use the mismatch feature as a poor-man's hardware -	 * single-step, but this only works for per-task breakpoints. -	 */ -	if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || -	    !core_has_mismatch_brps() || !bp->hw.bp_target)) { -		pr_warning("overflow handler required but none found\n"); -		ret = -EINVAL; +	if (!bp->overflow_handler) { +		/* +		 * Mismatch breakpoints are required for single-stepping +		 * breakpoints. +		 */ +		if (!core_has_mismatch_brps()) +			return -EINVAL; + +		/* We don't allow mismatch breakpoints in kernel space. */ +		if (arch_check_bp_in_kernelspace(bp)) +			return -EPERM; + +		/* +		 * Per-cpu breakpoints are not supported by our stepping +		 * mechanism. +		 */ +		if (!bp->hw.bp_target) +			return -EINVAL; + +		/* +		 * We only support specific access types if the fsr +		 * reports them. +		 */ +		if (!debug_exception_updates_fsr() && +		    (info->ctrl.type == ARM_BREAKPOINT_LOAD || +		     info->ctrl.type == ARM_BREAKPOINT_STORE)) +			return -EINVAL;  	} +  out:  	return ret;  } @@ -706,10 +730,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,  				goto unlock;  			/* Check that the access type matches. */ -			access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : -				 HW_BREAKPOINT_R; -			if (!(access & hw_breakpoint_type(wp))) -				goto unlock; +			if (debug_exception_updates_fsr()) { +				access = (fsr & ARM_FSR_ACCESS_MASK) ? +					  HW_BREAKPOINT_W : HW_BREAKPOINT_R; +				if (!(access & hw_breakpoint_type(wp))) +					goto unlock; +			}  			/* We have a winner. */  			info->trigger = addr; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f7945218b8c..b0179b89a04 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -420,20 +420,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)  #endif  			instr = *(u32 *) pc;  	} else if (thumb_mode(regs)) { -		get_user(instr, (u16 __user *)pc); +		if (get_user(instr, (u16 __user *)pc)) +			goto die_sig;  		if (is_wide_instruction(instr)) {  			unsigned int instr2; -			get_user(instr2, (u16 __user *)pc+1); +			if (get_user(instr2, (u16 __user *)pc+1)) +				goto die_sig;  			instr <<= 16;  			instr |= instr2;  		} -	} else { -		get_user(instr, (u32 __user *)pc); +	} else if (get_user(instr, (u32 __user *)pc)) { +		goto die_sig;  	}  	if (call_undef_hook(regs, instr) == 0)  		return; +die_sig:  #ifdef CONFIG_DEBUG_USER  	if (user_debug & UDBG_UNDEFINED) {  		printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index d6dacc69254..395d5fbb8fa 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c @@ -59,6 +59,7 @@ void __init init_current_timer_delay(unsigned long freq)  {  	pr_info("Switching to timer-based delay loop\n");  	lpj_fine			= freq / HZ; +	loops_per_jiffy			= lpj_fine;  	arm_delay_ops.delay		= __timer_delay;  	arm_delay_ops.const_udelay	= __timer_const_udelay;  	arm_delay_ops.udelay		= __timer_udelay; diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index 11093a7c3e3..9b06bb41fca 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -16,8 +16,9 @@   * __get_user_X   *   * Inputs:	r0 contains the address + *		r1 contains the address limit, which must be preserved   * Outputs:	r0 is the error code - *		r2, r3 contains the zero-extended value + *		r2 contains the zero-extended value   *		lr corrupted   *   * No other registers must be altered.  (see <asm/uaccess.h> @@ -27,33 +28,39 @@   * Note also that it is intended that __get_user_bad is not global.   */  #include <linux/linkage.h> +#include <asm/assembler.h>  #include <asm/errno.h>  #include <asm/domain.h>  ENTRY(__get_user_1) +	check_uaccess r0, 1, r1, r2, __get_user_bad  1: TUSER(ldrb)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__get_user_1)  ENTRY(__get_user_2) -#ifdef CONFIG_THUMB2_KERNEL -2: TUSER(ldrb)	r2, [r0] -3: TUSER(ldrb)	r3, [r0, #1] +	check_uaccess r0, 2, r1, r2, __get_user_bad +#ifdef CONFIG_CPU_USE_DOMAINS +rb	.req	ip +2:	ldrbt	r2, [r0], #1 +3:	ldrbt	rb, [r0], #0  #else -2: TUSER(ldrb)	r2, [r0], #1 -3: TUSER(ldrb)	r3, [r0] +rb	.req	r0 +2:	ldrb	r2, [r0] +3:	ldrb	rb, [r0, #1]  #endif  #ifndef __ARMEB__ -	orr	r2, r2, r3, lsl #8 +	orr	r2, r2, rb, lsl #8  #else -	orr	r2, r3, r2, lsl #8 +	orr	r2, rb, r2, lsl #8  #endif  	mov	r0, #0  	mov	pc, lr  ENDPROC(__get_user_2)  ENTRY(__get_user_4) +	check_uaccess r0, 4, r1, r2, __get_user_bad  4: TUSER(ldr)	r2, [r0]  	mov	r0, #0  	mov	pc, lr diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 7db25990c58..3d73dcb959b 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S @@ -16,6 +16,7 @@   * __put_user_X   *   * Inputs:	r0 contains the address + *		r1 contains the address limit, which must be preserved   *		r2, r3 contains the value   * Outputs:	r0 is the error code   *		lr corrupted @@ -27,16 +28,19 @@   * Note also that it is intended that __put_user_bad is not global.   */  #include <linux/linkage.h> +#include <asm/assembler.h>  #include <asm/errno.h>  #include <asm/domain.h>  ENTRY(__put_user_1) +	check_uaccess r0, 1, r1, ip, __put_user_bad  1: TUSER(strb)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__put_user_1)  ENTRY(__put_user_2) +	check_uaccess r0, 2, r1, ip, __put_user_bad  	mov	ip, r2, lsr #8  #ifdef CONFIG_THUMB2_KERNEL  #ifndef __ARMEB__ @@ -60,12 +64,14 @@ ENTRY(__put_user_2)  ENDPROC(__put_user_2)  ENTRY(__put_user_4) +	check_uaccess r0, 4, r1, ip, __put_user_bad  4: TUSER(str)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__put_user_4)  ENTRY(__put_user_8) +	check_uaccess r0, 8, r1, ip, __put_user_bad  #ifdef CONFIG_THUMB2_KERNEL  5: TUSER(str)	r2, [r0]  6: TUSER(str)	r3, [r0, #4] diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index fdd8cc87c9f..4431a62fff5 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -222,10 +222,8 @@ int __init mx25_clocks_init(void)  	clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");  	clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");  	clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); -	clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1"); -	clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1"); +	clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0"); +	clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1");  	clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");  	clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");  	clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index c6422fb10ba..65fb8bcd86c 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -230,10 +230,8 @@ int __init mx35_clocks_init()  	clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");  	clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");  	clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); -	clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0"); -	clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1"); -	clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1"); +	clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); +	clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");  	/* i.mx35 has the i.mx21 type uart */  	clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");  	clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index a5ac352d68d..1dcb751b8fe 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -475,8 +475,7 @@ static void __init htcherald_lcd_init(void)  				break;  		}  		if (!tries) -			printk(KERN_WARNING "Timeout waiting for end of frame " -			       "-- LCD may not be available\n"); +			pr_err("Timeout waiting for end of frame -- LCD may not be available\n");  		/* turn off DMA */  		reg = omap_readw(OMAP_DMA_LCD_CCR); diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index a9ee06b6cb4..638f4070fc7 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -587,8 +587,8 @@ void omap1_clk_disable_unused(struct clk *clk)  	/* Clocks in the DSP domain need api_ck. Just assume bootloader  	 * has not enabled any DSP clocks */  	if (clk->enable_reg == DSP_IDLECT2) { -		printk(KERN_INFO "Skipping reset check for DSP domain " -		       "clock \"%s\"\n", clk->name); +		pr_info("Skipping reset check for DSP domain clock \"%s\"\n", +			clk->name);  		return;  	} diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 6a32b9b0dc3..9b45f4b0ee2 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -775,11 +775,10 @@ static struct clk_functions omap1_clk_functions = {  static void __init omap1_show_rates(void)  { -	pr_notice("Clocking rate (xtal/DPLL1/MPU): " -			"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", -		ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, -		ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, -		arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); +	pr_notice("Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", +		  ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, +		  ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, +		  arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);  }  u32 cpu_mask; @@ -840,8 +839,8 @@ int __init omap1_clk_init(void)  	if (cpu_is_omap16xx() && crystal_type == 2)  		ck_ref.rate = 19200000; -	pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: " -		"0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), +	pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", +		omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),  		omap_readw(ARM_CKCTL));  	/* We want to be in syncronous scalable mode */ diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index b0b0f0f2745..29007fef84c 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -331,8 +331,9 @@ static int __init omap1_system_dma_init(void)  	d->chan = kzalloc(sizeof(struct omap_dma_lch) *  					(d->lch_count), GFP_KERNEL);  	if (!d->chan) { -		dev_err(&pdev->dev, "%s: Memory allocation failed" -					"for d->chan!!!\n", __func__); +		dev_err(&pdev->dev, +			"%s: Memory allocation failed for d->chan!\n", +			__func__);  		goto exit_release_d;  	} diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c index 5769c71815b..ed42628611b 100644 --- a/arch/arm/mach-omap1/lcd_dma.c +++ b/arch/arm/mach-omap1/lcd_dma.c @@ -113,8 +113,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);  void omap_set_lcd_dma_b1_vxres(unsigned long vxres)  {  	if (cpu_is_omap15xx()) { -		printk(KERN_ERR "DMA virtual resolution is not supported " -				"in 1510 mode\n"); +		pr_err("DMA virtual resolution is not supported in 1510 mode\n");  		BUG();  	}  	lcd_dma.vxres = vxres; @@ -437,8 +436,7 @@ static int __init omap_init_lcd_dma(void)  	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,  			"LCD DMA", NULL);  	if (r != 0) -		printk(KERN_ERR "unable to request IRQ for LCD DMA " -			       "(error %d)\n", r); +		pr_err("unable to request IRQ for LCD DMA (error %d)\n", r);  	return r;  } diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c index 7f4bba9fa02..6f958aec945 100644 --- a/arch/arm/mach-omap1/leds-h2p2-debug.c +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c @@ -69,11 +69,13 @@ void h2p2_dbg_leds_event(led_event_t evt)  			gpio_set_value(GPIO_IDLE, 0);  		} -		__raw_writew(~0, &fpga->leds);  		led_state &= ~LED_STATE_ENABLED; -		if (evt == led_halted) { -			iounmap(fpga); -			fpga = NULL; +		if (fpga) { +			__raw_writew(~0, &fpga->leds); +			if (evt == led_halted) { +				iounmap(fpga); +				fpga = NULL; +			}  		}  		goto done; @@ -159,7 +161,7 @@ void h2p2_dbg_leds_event(led_event_t evt)  	/*  	 *  Actually burn the LEDs  	 */ -	if (led_state & LED_STATE_ENABLED) +	if (led_state & LED_STATE_ENABLED && fpga)  		__raw_writew(~hw_led_state, &fpga->leds);  done: diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index fcd4e85c4dd..346fd26f3aa 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -232,10 +232,11 @@ config MACH_OMAP3_PANDORA  	select OMAP_PACKAGE_CBB  	select REGULATOR_FIXED_VOLTAGE if REGULATOR -config MACH_OMAP3_TOUCHBOOK +config MACH_TOUCHBOOK  	bool "OMAP3 Touch Book"  	depends on ARCH_OMAP3  	default y +	select OMAP_PACKAGE_CBB  config MACH_OMAP_3430SDP  	bool "OMAP 3430 SDP board" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f6a24b3f9c4..34c2c7f59f0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -255,7 +255,7 @@ obj-$(CONFIG_MACH_OMAP_3630SDP)		+= board-zoom-display.o  obj-$(CONFIG_MACH_CM_T35)		+= board-cm-t35.o  obj-$(CONFIG_MACH_CM_T3517)		+= board-cm-t3517.o  obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o -obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)	+= board-omap3touchbook.o +obj-$(CONFIG_MACH_TOUCHBOOK)		+= board-omap3touchbook.o  obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o  obj-$(CONFIG_MACH_OMAP4_PANDA)		+= board-omap4panda.o diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index d8deaea37dc..4b43fe31157 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -550,8 +550,8 @@ static int n8x0_auto_sleep_regulators(void)  	ret = menelaus_set_regulator_sleep(1, val);  	if (ret < 0) { -		printk(KERN_ERR "Could not set regulators to sleep on " -			"menelaus: %u\n", ret); +		pr_err("Could not set regulators to sleep on menelaus: %u\n", +		       ret);  		return ret;  	}  	return 0; @@ -563,8 +563,7 @@ static int n8x0_auto_voltage_scale(void)  	ret = menelaus_set_vcore_hw(1400, 1050);  	if (ret < 0) { -		printk(KERN_ERR "Could not set VCORE voltage on " -			"menelaus: %u\n", ret); +		pr_err("Could not set VCORE voltage on menelaus: %u\n", ret);  		return ret;  	}  	return 0; diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 7a62d1322b7..13c101c2c64 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -516,8 +516,7 @@ static void __init overo_init(void)  		udelay(10);  		gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);  	} else { -		printk(KERN_ERR "could not obtain gpio for " -					"OVERO_GPIO_W2W_NRESET\n"); +		pr_err("could not obtain gpio for OVERO_GPIO_W2W_NRESET\n");  	}  	ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios)); @@ -536,8 +535,7 @@ static void __init overo_init(void)  	if (ret == 0)  		gpio_export(OVERO_GPIO_USBH_CPEN, 0);  	else -		printk(KERN_ERR "could not obtain gpio for " -					"OVERO_GPIO_USBH_CPEN\n"); +		pr_err("could not obtain gpio for OVERO_GPIO_USBH_CPEN\n");  }  MACHINE_START(OVERO, "Gumstix Overo") diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index 5ec069e529e..0d8d91917d1 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -84,8 +84,7 @@ static inline void __init zoom_init_quaduart(void)  	quart_cs = ZOOM_QUADUART_CS;  	if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) { -		printk(KERN_ERR "Failed to request GPMC mem" -				"for Quad UART(TL16CP754C)\n"); +		pr_err("Failed to request GPMC mem for Quad UART(TL16CP754C)\n");  		return;  	} @@ -107,8 +106,8 @@ static inline int omap_zoom_debugboard_detect(void)  	if (gpio_request_one(debug_board_detect, GPIOF_IN,  			     "Zoom debug board detect") < 0) { -		printk(KERN_ERR "Failed to request GPIO%d for Zoom debug" -		"board detect\n", debug_board_detect); +		pr_err("Failed to request GPIO%d for Zoom debug board detect\n", +		       debug_board_detect);  		return 0;  	} diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c index d6e34dd9e7e..298887b5bf6 100644 --- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c +++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c @@ -92,15 +92,13 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)  	pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,  		 validrate); -	pr_debug("clock: SDRC CS0 timing params used:" -		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", +	pr_debug("clock: SDRC CS0 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",  		 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,  		 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);  	if (sdrc_cs1) -		pr_debug("clock: SDRC CS1 timing params used: " -		 " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", -		 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, -		 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); +		pr_debug("clock: SDRC CS1 timing params used: RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", +			 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, +			 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);  	if (sdrc_cs1)  		omap3_configure_core_dpll( diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index 04d551b1f7f..19a980956d4 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c @@ -71,8 +71,8 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk,  	if (!clks->parent) {  		/* This indicates a data problem */ -		WARN(1, "clock: Could not find parent clock %s in clksel array " -		     "of clock %s\n", src_clk->name, clk->name); +		WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", +		     clk->name, src_clk->name);  		return NULL;  	} @@ -126,8 +126,8 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,  	if (max_div == 0) {  		/* This indicates an error in the clksel data */ -		WARN(1, "clock: Could not find divisor for clock %s parent %s" -		     "\n", clk->name, src_clk->parent->name); +		WARN(1, "clock: %s: could not find divisor for parent %s\n", +		     clk->name, src_clk->parent->name);  		return 0;  	} @@ -191,8 +191,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)  	if (!clkr->div) {  		/* This indicates a data error */ -		WARN(1, "clock: Could not find fieldval %d for clock %s parent " -		     "%s\n", field_val, clk->name, clk->parent->name); +		WARN(1, "clock: %s: could not find fieldval %d parent %s\n", +		     clk->name, field_val, clk->parent->name);  		return 0;  	} @@ -230,8 +230,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)  	}  	if (!clkr->div) { -		pr_err("clock: Could not find divisor %d for clock %s parent " -		       "%s\n", div, clk->name, clk->parent->name); +		pr_err("clock: %s: could not find divisor %d parent %s\n", +		       clk->name, div, clk->parent->name);  		return ~0;  	} @@ -300,8 +300,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,  		/* Sanity check */  		if (clkr->div <= last_div) -			pr_err("clock: clksel_rate table not sorted " -			       "for clock %s", clk->name); +			pr_err("clock: %s: clksel_rate table not sorted", +			       clk->name);  		last_div = clkr->div; @@ -312,9 +312,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,  	}  	if (!clkr->div) { -		pr_err("clock: Could not find divisor for target " -		       "rate %ld for clock %s parent %s\n", target_rate, -		       clk->name, clk->parent->name); +		pr_err("clock: %s: could not find divisor for target rate %ld parent %s\n", +		       clk->name, target_rate, clk->parent->name);  		return ~0;  	} @@ -359,8 +358,7 @@ void omap2_init_clksel_parent(struct clk *clk)  			if (clkr->val == r) {  				if (clk->parent != clks->parent) { -					pr_debug("clock: inited %s parent " -						 "to %s (was %s)\n", +					pr_debug("clock: %s: inited parent to %s (was %s)\n",  						 clk->name, clks->parent->name,  						 ((clk->parent) ?  						  clk->parent->name : "NULL")); diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index ae624c3b832..a3b60c7b9aa 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -105,13 +105,13 @@ static int _dpll_test_fint(struct clk *clk, u8 n)  	}  	if (fint < fint_min) { -		pr_debug("rejecting n=%d due to Fint failure, " -			 "lowering max_divider\n", n); +		pr_debug("rejecting n=%d due to Fint failure, lowering max_divider\n", +			 n);  		dd->max_divider = n;  		ret = DPLL_FINT_UNDERFLOW;  	} else if (fint > fint_max) { -		pr_debug("rejecting n=%d due to Fint failure, " -			 "boosting min_divider\n", n); +		pr_debug("rejecting n=%d due to Fint failure, boosting min_divider\n", +			 n);  		dd->min_divider = n;  		ret = DPLL_FINT_INVALID;  	} else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX && diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 1a1f97f3ca6..e97f98ffe8b 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -104,8 +104,8 @@ void omap2_init_clk_clkdm(struct clk *clk)  			 clk->name, clk->clkdm_name);  		clk->clkdm = clkdm;  	} else { -		pr_debug("clock: could not associate clk %s to " -			 "clkdm %s\n", clk->name, clk->clkdm_name); +		pr_debug("clock: could not associate clk %s to clkdm %s\n", +			 clk->name, clk->clkdm_name);  	}  } @@ -228,8 +228,7 @@ void omap2_dflt_clk_disable(struct clk *clk)  		 * 'Independent' here refers to a clock which is not  		 * controlled by its parent.  		 */ -		printk(KERN_ERR "clock: clk_disable called on independent " -		       "clock %s which has no enable_reg\n", clk->name); +		pr_err("clock: clk_disable called on independent clock %s which has no enable_reg\n", clk->name);  		return;  	} @@ -272,8 +271,7 @@ const struct clkops clkops_omap2_dflt = {  void omap2_clk_disable(struct clk *clk)  {  	if (clk->usecount == 0) { -		WARN(1, "clock: %s: omap2_clk_disable() called, but usecount " -		     "already 0?", clk->name); +		WARN(1, "clock: %s: omap2_clk_disable() called, but usecount already 0?", clk->name);  		return;  	} @@ -334,8 +332,8 @@ int omap2_clk_enable(struct clk *clk)  	if (clkdm_control && clk->clkdm) {  		ret = clkdm_clk_enable(clk->clkdm, clk);  		if (ret) { -			WARN(1, "clock: %s: could not enable clockdomain %s: " -			     "%d\n", clk->name, clk->clkdm->name, ret); +			WARN(1, "clock: %s: could not enable clockdomain %s: %d\n", +			     clk->name, clk->clkdm->name, ret);  			goto oce_err2;  		}  	} @@ -503,10 +501,8 @@ void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,  	hfclkin_rate = clk_get_rate(hfclkin_ck); -	pr_info("Switched to new clocking rate (Crystal/Core/MPU): " -		"%ld.%01ld/%ld/%ld MHz\n", -		(hfclkin_rate / 1000000), -		((hfclkin_rate / 100000) % 10), +	pr_info("Switched to new clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", +		(hfclkin_rate / 1000000), ((hfclkin_rate / 100000) % 10),  		(clk_get_rate(core_ck) / 1000000),  		(clk_get_rate(mpu_ck) / 1000000));  } diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c index 7aa5ecaee5a..8e06de665b1 100644 --- a/arch/arm/mach-omap2/clock33xx_data.c +++ b/arch/arm/mach-omap2/clock33xx_data.c @@ -1036,13 +1036,13 @@ static struct omap_clk am33xx_clks[] = {  	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX),  	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX),  	CLK(NULL,	"smartreflex1_fck",	&smartreflex1_fck,	CK_AM33XX), -	CLK(NULL,	"gpt1_fck",		&timer1_fck,	CK_AM33XX), -	CLK(NULL,	"gpt2_fck",		&timer2_fck,	CK_AM33XX), -	CLK(NULL,	"gpt3_fck",		&timer3_fck,	CK_AM33XX), -	CLK(NULL,	"gpt4_fck",		&timer4_fck,	CK_AM33XX), -	CLK(NULL,	"gpt5_fck",		&timer5_fck,	CK_AM33XX), -	CLK(NULL,	"gpt6_fck",		&timer6_fck,	CK_AM33XX), -	CLK(NULL,	"gpt7_fck",		&timer7_fck,	CK_AM33XX), +	CLK(NULL,	"timer1_fck",		&timer1_fck,	CK_AM33XX), +	CLK(NULL,	"timer2_fck",		&timer2_fck,	CK_AM33XX), +	CLK(NULL,	"timer3_fck",		&timer3_fck,	CK_AM33XX), +	CLK(NULL,	"timer4_fck",		&timer4_fck,	CK_AM33XX), +	CLK(NULL,	"timer5_fck",		&timer5_fck,	CK_AM33XX), +	CLK(NULL,	"timer6_fck",		&timer6_fck,	CK_AM33XX), +	CLK(NULL,	"timer7_fck",		&timer7_fck,	CK_AM33XX),  	CLK(NULL,	"usbotg_fck",		&usbotg_fck,	CK_AM33XX),  	CLK(NULL,	"ieee5000_fck",		&ieee5000_fck,	CK_AM33XX),  	CLK(NULL,	"wdt1_fck",		&wdt1_fck,	CK_AM33XX), diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c index fc2765bcdd4..15cdc647173 100644 --- a/arch/arm/mach-omap2/clock3xxx.c +++ b/arch/arm/mach-omap2/clock3xxx.c @@ -49,8 +49,7 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)  	 * on DPLL4.  	 */  	if (omap_rev() == OMAP3430_REV_ES1_0) { -		pr_err("clock: DPLL4 cannot change rate due to " -		       "silicon 'Limitation 2.5' on 3430ES1.\n"); +		pr_err("clock: DPLL4 cannot change rate due to silicon 'Limitation 2.5' on 3430ES1.\n");  		return -EINVAL;  	} diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 8664f5a8bfb..a1555627ad9 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -174,9 +174,8 @@ void _clkdm_add_autodeps(struct clockdomain *clkdm)  		if (IS_ERR(autodep->clkdm.ptr))  			continue; -		pr_debug("clockdomain: adding %s sleepdep/wkdep for " -			 "clkdm %s\n", autodep->clkdm.ptr->name, -			 clkdm->name); +		pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", +			 clkdm->name, autodep->clkdm.ptr->name);  		clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);  		clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); @@ -205,9 +204,8 @@ void _clkdm_del_autodeps(struct clockdomain *clkdm)  		if (IS_ERR(autodep->clkdm.ptr))  			continue; -		pr_debug("clockdomain: removing %s sleepdep/wkdep for " -			 "clkdm %s\n", autodep->clkdm.ptr->name, -			 clkdm->name); +		pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", +			 clkdm->name, autodep->clkdm.ptr->name);  		clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);  		clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); @@ -469,14 +467,14 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear wake up of " -			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	}  	if (atomic_inc_return(&cd->wkdep_usecount) == 1) { -		pr_debug("clockdomain: hardware will wake up %s when %s wakes " -			 "up\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name);  		ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);  	} @@ -510,14 +508,14 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear wake up of " -			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	}  	if (atomic_dec_return(&cd->wkdep_usecount) == 0) { -		pr_debug("clockdomain: hardware will no longer wake up %s " -			 "after %s wakes up\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", +			 clkdm1->name, clkdm2->name);  		ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);  	} @@ -555,8 +553,8 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear wake up of " -			 "%s when %s wakes up\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	} @@ -613,15 +611,14 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear sleep " -			 "dependency affecting %s from %s\n", clkdm1->name, -			 clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	}  	if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { -		pr_debug("clockdomain: will prevent %s from sleeping if %s " -			 "is active\n", clkdm1->name, clkdm2->name); +		pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", +			 clkdm1->name, clkdm2->name);  		ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);  	} @@ -657,16 +654,14 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear sleep " -			 "dependency affecting %s from %s\n", clkdm1->name, -			 clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	}  	if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { -		pr_debug("clockdomain: will no longer prevent %s from " -			 "sleeping if %s is active\n", clkdm1->name, -			 clkdm2->name); +		pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", +			 clkdm1->name, clkdm2->name);  		ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);  	} @@ -706,9 +701,8 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		ret = -EINVAL;  	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear sleep " -			 "dependency affecting %s from %s\n", clkdm1->name, -			 clkdm2->name); +		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", +			 clkdm1->name, clkdm2->name);  		return ret;  	} @@ -755,8 +749,8 @@ int clkdm_sleep(struct clockdomain *clkdm)  		return -EINVAL;  	if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { -		pr_debug("clockdomain: %s does not support forcing " -			 "sleep via software\n", clkdm->name); +		pr_debug("clockdomain: %s does not support forcing sleep via software\n", +			 clkdm->name);  		return -EINVAL;  	} @@ -790,8 +784,8 @@ int clkdm_wakeup(struct clockdomain *clkdm)  		return -EINVAL;  	if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { -		pr_debug("clockdomain: %s does not support forcing " -			 "wakeup via software\n", clkdm->name); +		pr_debug("clockdomain: %s does not support forcing wakeup via software\n", +			 clkdm->name);  		return -EINVAL;  	} @@ -826,8 +820,8 @@ void clkdm_allow_idle(struct clockdomain *clkdm)  		return;  	if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) { -		pr_debug("clock: automatic idle transitions cannot be enabled " -			 "on clockdomain %s\n", clkdm->name); +		pr_debug("clock: %s: automatic idle transitions cannot be enabled\n", +			 clkdm->name);  		return;  	} @@ -861,8 +855,8 @@ void clkdm_deny_idle(struct clockdomain *clkdm)  		return;  	if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) { -		pr_debug("clockdomain: automatic idle transitions cannot be " -			 "disabled on %s\n", clkdm->name); +		pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n", +			 clkdm->name);  		return;  	} @@ -927,7 +921,7 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)  	pwrdm_state_switch(clkdm->pwrdm.ptr);  	spin_unlock_irqrestore(&clkdm->lock, flags); -	pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name); +	pr_debug("clockdomain: %s: enabled\n", clkdm->name);  	return 0;  } @@ -952,7 +946,7 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)  	pwrdm_state_switch(clkdm->pwrdm.ptr);  	spin_unlock_irqrestore(&clkdm->lock, flags); -	pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name); +	pr_debug("clockdomain: %s: disabled\n", clkdm->name);  	return 0;  } diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c index a0d68dbecfa..f99e65cfb86 100644 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c @@ -241,6 +241,52 @@ static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)  		_clkdm_del_autodeps(clkdm);  } +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		_disable_hwsup(clkdm); +		_clkdm_add_autodeps(clkdm); +		_enable_hwsup(clkdm); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +			omap3_clkdm_wakeup(clkdm); +	} + +	return 0; +} + +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		_disable_hwsup(clkdm); +		_clkdm_del_autodeps(clkdm); +		_enable_hwsup(clkdm); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) +			omap3_clkdm_sleep(clkdm); +	} + +	return 0; +} +  struct clkdm_ops omap2_clkdm_operations = {  	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,  	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, @@ -267,6 +313,6 @@ struct clkdm_ops omap3_clkdm_operations = {  	.clkdm_wakeup		= omap3_clkdm_wakeup,  	.clkdm_allow_idle	= omap3_clkdm_allow_idle,  	.clkdm_deny_idle	= omap3_clkdm_deny_idle, -	.clkdm_clk_enable	= omap2_clkdm_clk_enable, -	.clkdm_clk_disable	= omap2_clkdm_clk_disable, +	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable, +	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,  }; diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 766338fe4d3..975f6bda0e0 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -67,6 +67,7 @@  #define OMAP3430_EN_IVA2_DPLL_MASK			(0x7 << 0)  /* CM_IDLEST_IVA2 */ +#define OMAP3430_ST_IVA2_SHIFT				0  #define OMAP3430_ST_IVA2_MASK				(1 << 0)  /* CM_IDLEST_PLL_IVA2 */ diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 013fedc9e13..f81dd0a18aa 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -120,8 +120,7 @@ void __init omap_nand_flash_init(int options, struct mtd_partition *parts,  	}  	if (nandcs > GPMC_CS_NUM) { -		printk(KERN_INFO "NAND: Unable to find configuration " -				 "in GPMC\n "); +		pr_info("NAND: Unable to find configuration in GPMC\n");  		return;  	} diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index d8318dc5ee9..ef666455c13 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -623,8 +623,11 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)  	while (pclk && !pclk->dpll_data)  		pclk = pclk->parent; -	/* clk does not have a DPLL as a parent? */ -	WARN_ON(!pclk); +	/* clk does not have a DPLL as a parent?  error in the clock data */ +	if (!pclk) { +		WARN_ON(1); +		return 0; +	}  	dd = pclk->dpll_data; diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 7b52bdfc59c..e7b246da02d 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -61,6 +61,7 @@ static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)  	pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);  	if (!pdata->regs) {  		pr_err("gpio%d: Memory allocation failed\n", id); +		kfree(pdata);  		return -ENOMEM;  	} diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 055ae8bd943..72428bd45ef 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -297,7 +297,7 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)  	div = gpmc_cs_calc_divider(cs, t->sync_clk);  	if (div < 0) -		return -1; +		return div;  	GPMC_SET_ONE(GPMC_CS_CONFIG2,  0,  3, cs_on);  	GPMC_SET_ONE(GPMC_CS_CONFIG2,  8, 12, cs_rd_off); diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 7219df0e831..6b98a178fbe 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -161,9 +161,8 @@ void __init omap2xxx_check_revision(void)  	}  	if (j == ARRAY_SIZE(omap_ids)) { -		printk(KERN_ERR "Unknown OMAP device type. " -				"Handling it as OMAP%04x\n", -				omap_ids[i].type >> 16); +		pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n", +		       omap_ids[i].type >> 16);  		j = i;  	} diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index efed4f540ad..3926f370448 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -108,9 +108,8 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)  	unsigned long tmp;  	tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff; -	printk(KERN_INFO "IRQ: Found an INTC at 0x%p " -			 "(revision %ld.%ld) with %d interrupts\n", -			 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs); +	pr_info("IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n", +		bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);  	tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG);  	tmp |= 1 << 1;	/* soft reset */ diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index b54427dec2a..ecaad7d371e 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -47,7 +47,7 @@  static void __iomem *wakeupgen_base;  static void __iomem *sar_base;  static DEFINE_SPINLOCK(wakeupgen_lock); -static unsigned int irq_target_cpu[NR_IRQS]; +static unsigned int irq_target_cpu[MAX_IRQS];  static unsigned int irq_banks = MAX_NR_REG_BANKS;  static unsigned int max_irqs = MAX_IRQS;  static unsigned int omap_secure_apis; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 9db1684df69..3615e0d9ee3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1438,8 +1438,8 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)   * Return the bit position of the reset line that match the   * input name. Return -ENOENT if not found.   */ -static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name, -			    struct omap_hwmod_rst_info *ohri) +static int _lookup_hardreset(struct omap_hwmod *oh, const char *name, +			     struct omap_hwmod_rst_info *ohri)  {  	int i; @@ -1475,7 +1475,7 @@ static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,  static int _assert_hardreset(struct omap_hwmod *oh, const char *name)  {  	struct omap_hwmod_rst_info ohri; -	u8 ret = -EINVAL; +	int ret = -EINVAL;  	if (!oh)  		return -EINVAL; @@ -1484,7 +1484,7 @@ static int _assert_hardreset(struct omap_hwmod *oh, const char *name)  		return -ENOSYS;  	ret = _lookup_hardreset(oh, name, &ohri); -	if (IS_ERR_VALUE(ret)) +	if (ret < 0)  		return ret;  	ret = soc_ops.assert_hardreset(oh, &ohri); @@ -1542,7 +1542,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)  static int _read_hardreset(struct omap_hwmod *oh, const char *name)  {  	struct omap_hwmod_rst_info ohri; -	u8 ret = -EINVAL; +	int ret = -EINVAL;  	if (!oh)  		return -EINVAL; @@ -1551,7 +1551,7 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)  		return -ENOSYS;  	ret = _lookup_hardreset(oh, name, &ohri); -	if (IS_ERR_VALUE(ret)) +	if (ret < 0)  		return ret;  	return soc_ops.is_hardreset_asserted(oh, &ohri); @@ -1641,8 +1641,8 @@ static int _ocp_softreset(struct omap_hwmod *oh)  	/* clocks must be on for this operation */  	if (oh->_state != _HWMOD_STATE_ENABLED) { -		pr_warning("omap_hwmod: %s: reset can only be entered from " -			   "enabled state\n", oh->name); +		pr_warn("omap_hwmod: %s: reset can only be entered from enabled state\n", +			oh->name);  		return -EINVAL;  	} @@ -1889,6 +1889,7 @@ static int _enable(struct omap_hwmod *oh)  			_enable_sysc(oh);  		}  	} else { +		_omap4_disable_module(oh);  		_disable_clocks(oh);  		pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",  			 oh->name, r); diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 75fbbac1392..8fec2cee3e1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -100,9 +100,9 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {  /* IVA2 (IVA2) */  static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { -	{ .name = "logic", .rst_shift = 0 }, -	{ .name = "seq0", .rst_shift = 1 }, -	{ .name = "seq1", .rst_shift = 2 }, +	{ .name = "logic", .rst_shift = 0, .st_shift = 8 }, +	{ .name = "seq0", .rst_shift = 1, .st_shift = 9 }, +	{ .name = "seq1", .rst_shift = 2, .st_shift = 10 },  };  static struct omap_hwmod omap3xxx_iva_hwmod = { @@ -112,6 +112,15 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {  	.rst_lines	= omap3xxx_iva_resets,  	.rst_lines_cnt	= ARRAY_SIZE(omap3xxx_iva_resets),  	.main_clk	= "iva2_ck", +	.prcm = { +		.omap2 = { +			.module_offs = OMAP3430_IVA2_MOD, +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT, +		} +	},  };  /* timer class */ diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index b95244b76a1..110be87cd99 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -4209,7 +4209,7 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {  };  /* dsp -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = {  	.master		= &omap44xx_dsp_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "dpll_iva_m5x2_ck", @@ -4827,7 +4827,7 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = {  };  /* iva -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = {  	.master		= &omap44xx_iva_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "dpll_iva_m5x2_ck", @@ -5361,7 +5361,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = {  };  /* l3_main_2 -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = {  	.master		= &omap44xx_l3_main_2_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "l3_div_ck", @@ -6031,7 +6031,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_abe__dmic,  	&omap44xx_l4_abe__dmic_dma,  	&omap44xx_dsp__iva, -	&omap44xx_dsp__sl2if, +	/* &omap44xx_dsp__sl2if, */  	&omap44xx_l4_cfg__dsp,  	&omap44xx_l3_main_2__dss,  	&omap44xx_l4_per__dss, @@ -6067,7 +6067,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_per__i2c4,  	&omap44xx_l3_main_2__ipu,  	&omap44xx_l3_main_2__iss, -	&omap44xx_iva__sl2if, +	/* &omap44xx_iva__sl2if, */  	&omap44xx_l3_main_2__iva,  	&omap44xx_l4_wkup__kbd,  	&omap44xx_l4_cfg__mailbox, @@ -6098,7 +6098,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_cfg__cm_core,  	&omap44xx_l4_wkup__prm,  	&omap44xx_l4_wkup__scrm, -	&omap44xx_l3_main_2__sl2if, +	/* &omap44xx_l3_main_2__sl2if, */  	&omap44xx_l4_abe__slimbus1,  	&omap44xx_l4_abe__slimbus1_dma,  	&omap44xx_l4_per__slimbus2, diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c index d8f6dbf45d1..45ad7f74f35 100644 --- a/arch/arm/mach-omap2/opp.c +++ b/arch/arm/mach-omap2/opp.c @@ -64,25 +64,22 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,  		}  		oh = omap_hwmod_lookup(opp_def->hwmod_name);  		if (!oh || !oh->od) { -			pr_debug("%s: no hwmod or odev for %s, [%d] " -				"cannot add OPPs.\n", __func__, -				opp_def->hwmod_name, i); +			pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", +				 __func__, opp_def->hwmod_name, i);  			continue;  		}  		dev = &oh->od->pdev->dev;  		r = opp_add(dev, opp_def->freq, opp_def->u_volt);  		if (r) { -			dev_err(dev, "%s: add OPP %ld failed for %s [%d] " -				"result=%d\n", -			       __func__, opp_def->freq, -			       opp_def->hwmod_name, i, r); +			dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", +				__func__, opp_def->freq, +				opp_def->hwmod_name, i, r);  		} else {  			if (!opp_def->default_available)  				r = opp_disable(dev, opp_def->freq);  			if (r) -				dev_err(dev, "%s: disable %ld failed for %s " -					"[%d] result=%d\n", +				dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n",  					__func__, opp_def->freq,  					opp_def->hwmod_name, i, r);  		} diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 9cb5cede0f5..939bd6f70b5 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -203,8 +203,8 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,  	bootup_volt = opp_get_voltage(opp);  	rcu_read_unlock();  	if (!bootup_volt) { -		pr_err("%s: unable to find voltage corresponding " -			"to the bootup OPP for vdd_%s\n", __func__, vdd_name); +		pr_err("%s: unable to find voltage corresponding to the bootup OPP for vdd_%s\n", +		       __func__, vdd_name);  		goto exit;  	} diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 90480f75997..ba670db1fd3 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -391,9 +391,8 @@ restore:  	list_for_each_entry(pwrst, &pwrst_list, node) {  		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);  		if (state > pwrst->next_state) { -			pr_info("Powerdomain (%s) didn't enter " -				"target state %d\n", -			       pwrst->pwrdm->name, pwrst->next_state); +			pr_info("Powerdomain (%s) didn't enter target state %d\n", +				pwrst->pwrdm->name, pwrst->next_state);  			ret = -1;  		}  		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); @@ -733,8 +732,7 @@ int __init omap3_pm_init(void)  		omap3_secure_ram_storage =  			kmalloc(0x803F, GFP_KERNEL);  		if (!omap3_secure_ram_storage) -			pr_err("Memory allocation failed when " -			       "allocating for secure sram context\n"); +			pr_err("Memory allocation failed when allocating for secure sram context\n");  		local_irq_disable();  		local_fiq_disable(); diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index ea24174f570..04922d14906 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -69,9 +69,8 @@ static int omap4_pm_suspend(void)  	list_for_each_entry(pwrst, &pwrst_list, node) {  		state = pwrdm_read_prev_pwrst(pwrst->pwrdm);  		if (state > pwrst->next_state) { -			pr_info("Powerdomain (%s) didn't enter " -			       "target state %d\n", -			       pwrst->pwrdm->name, pwrst->next_state); +			pr_info("Powerdomain (%s) didn't enter target state %d\n", +				pwrst->pwrdm->name, pwrst->next_state);  			ret = -1;  		}  		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); @@ -189,8 +188,7 @@ int __init omap4_pm_init(void)  	ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);  	ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);  	if (ret) { -		pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 " -				"wakeup dependency\n"); +		pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n");  		goto err2;  	} diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index ca5be83d501..1678a328423 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -341,8 +341,8 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)  	if (!pwrdm || !clkdm)  		return -EINVAL; -	pr_debug("powerdomain: associating clockdomain %s with powerdomain " -		 "%s\n", clkdm->name, pwrdm->name); +	pr_debug("powerdomain: %s: associating clockdomain %s\n", +		 pwrdm->name, clkdm->name);  	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {  		if (!pwrdm->pwrdm_clkdms[i]) @@ -356,8 +356,8 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)  	}  	if (i == PWRDM_MAX_CLKDMS) { -		pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for " -			 "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name); +		pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n", +			 pwrdm->name, clkdm->name);  		WARN_ON(1);  		ret = -ENOMEM;  		goto pac_exit; @@ -389,16 +389,16 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)  	if (!pwrdm || !clkdm)  		return -EINVAL; -	pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " -		 "%s\n", clkdm->name, pwrdm->name); +	pr_debug("powerdomain: %s: dissociating clockdomain %s\n", +		 pwrdm->name, clkdm->name);  	for (i = 0; i < PWRDM_MAX_CLKDMS; i++)  		if (pwrdm->pwrdm_clkdms[i] == clkdm)  			break;  	if (i == PWRDM_MAX_CLKDMS) { -		pr_debug("powerdomain: clkdm %s not associated with pwrdm " -			 "%s ?!\n", clkdm->name, pwrdm->name); +		pr_debug("powerdomain: %s: clkdm %s not associated?!\n", +			 pwrdm->name, clkdm->name);  		ret = -ENOENT;  		goto pdc_exit;  	} @@ -487,7 +487,7 @@ int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)  	if (!(pwrdm->pwrsts & (1 << pwrst)))  		return -EINVAL; -	pr_debug("powerdomain: setting next powerstate for %s to %0x\n", +	pr_debug("powerdomain: %s: setting next powerstate to %0x\n",  		 pwrdm->name, pwrst);  	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) { @@ -589,7 +589,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)  	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))  		return -EINVAL; -	pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n", +	pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n",  		 pwrdm->name, pwrst);  	if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst) @@ -626,8 +626,8 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)  	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))  		return -EINVAL; -	pr_debug("powerdomain: setting next memory powerstate for domain %s " -		 "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst); +	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n", +		 pwrdm->name, bank, pwrst);  	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)  		ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst); @@ -664,8 +664,8 @@ int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)  	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))  		return -EINVAL; -	pr_debug("powerdomain: setting next memory powerstate for domain %s " -		 "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst); +	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n", +		 pwrdm->name, bank, pwrst);  	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)  		ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst); @@ -843,7 +843,7 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)  	 * warn & fail if it is not ON.  	 */ -	pr_debug("powerdomain: clearing previous power state reg for %s\n", +	pr_debug("powerdomain: %s: clearing previous power state reg\n",  		 pwrdm->name);  	if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst) @@ -873,8 +873,7 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)  	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))  		return ret; -	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", -		 pwrdm->name); +	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);  	if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)  		ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm); @@ -903,8 +902,7 @@ int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)  	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))  		return ret; -	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", -		 pwrdm->name); +	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);  	if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)  		ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm); diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c index 0f0a9f1592f..3950ccfe5f4 100644 --- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c @@ -122,8 +122,8 @@ static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)  			udelay(1);  	if (c > PWRDM_TRANSITION_BAILOUT) { -		printk(KERN_ERR "powerdomain: waited too long for " -			"powerdomain %s to complete transition\n", pwrdm->name); +		pr_err("powerdomain: %s: waited too long to complete transition\n", +		       pwrdm->name);  		return -EAGAIN;  	} diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c index 601325b852a..aeac6f35ca1 100644 --- a/arch/arm/mach-omap2/powerdomain44xx.c +++ b/arch/arm/mach-omap2/powerdomain44xx.c @@ -198,8 +198,8 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)  		udelay(1);  	if (c > PWRDM_TRANSITION_BAILOUT) { -		printk(KERN_ERR "powerdomain: waited too long for " -		       "powerdomain %s to complete transition\n", pwrdm->name); +		pr_err("powerdomain: %s: waited too long to complete transition\n", +		       pwrdm->name);  		return -EAGAIN;  	} diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 9c9d23c1020..0f51e034e0a 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -139,11 +139,11 @@ int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,  			  MAX_MODULE_ENABLE_WAIT, i);  	if (i < MAX_MODULE_ENABLE_WAIT) -		pr_debug("cm: Module associated with clock %s ready after %d " -			 "loops\n", name, i); +		pr_debug("cm: Module associated with clock %s ready after %d loops\n", +			 name, i);  	else -		pr_err("cm: Module associated with clock %s didn't enable in " -		       "%d tries\n", name, MAX_MODULE_ENABLE_WAIT); +		pr_err("cm: Module associated with clock %s didn't enable in %d tries\n", +		       name, MAX_MODULE_ENABLE_WAIT);  	return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;  }; diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 7ca266e987f..0405c819080 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -232,9 +232,8 @@ static int __init omap_serial_early_init(void)  			if (console_loglevel >= 10) {  				uart_debug = true; -				pr_info("%s used as console in debug mode" -						" uart%d clocks will not be" -						" gated", uart_name, uart->num); +				pr_info("%s used as console in debug mode: uart%d clocks will not be gated", +					uart_name, uart->num);  			}  			if (cmdline_find_option("no_console_suspend")) @@ -319,8 +318,11 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,  	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,  				 NULL, 0, false); -	WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", -	     name, oh->name); +	if (IS_ERR(pdev)) { +		WARN(1, "Could not build omap_device for %s: %s.\n", name, +		     oh->name); +		return; +	}  	if ((console_uart_id == bdata->id) && no_console_suspend)  		omap_device_disable_idle_on_suspend(pdev); diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index d033a65f4e4..cbeae56b56a 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -104,16 +104,15 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)  	sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);  	if (!sr_data) { -		pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n", -			__func__, oh->name); +		pr_err("%s: Unable to allocate memory for %s sr_data\n", +		       __func__, oh->name);  		return -ENOMEM;  	}  	sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;  	if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { -		pr_err("%s: No voltage domain specified for %s." -				"Cannot initialize\n", __func__, -					oh->name); +		pr_err("%s: No voltage domain specified for %s. Cannot initialize\n", +		       __func__, oh->name);  		goto exit;  	} @@ -131,8 +130,8 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)  	omap_voltage_get_volttable(sr_data->voltdm, &volt_data);  	if (!volt_data) { -		pr_warning("%s: No Voltage table registered fo VDD%d." -			"Something really wrong\n\n", __func__, i + 1); +		pr_err("%s: No Voltage table registered for VDD%d\n", +		       __func__, i + 1);  		goto exit;  	} diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 25cbe73b0cd..5214d5bfba2 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -213,7 +213,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,  	res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source);  	BUG_ON(res); -	omap2_gp_timer_irq.dev_id = (void *)&clkev; +	omap2_gp_timer_irq.dev_id = &clkev;  	setup_irq(clkev.irq, &omap2_gp_timer_irq);  	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); @@ -262,6 +262,7 @@ static u32 notrace dmtimer_read_sched_clock(void)  	return 0;  } +#ifdef CONFIG_OMAP_32K_TIMER  /* Setup free-running counter for clocksource */  static int __init omap2_sync32k_clocksource_init(void)  { @@ -301,6 +302,12 @@ static int __init omap2_sync32k_clocksource_init(void)  	return ret;  } +#else +static inline int omap2_sync32k_clocksource_init(void) +{ +	return -ENODEV; +} +#endif  static void __init omap2_gptimer_clocksource_init(int gptimer_id,  						const char *fck_source) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index b451f3c1329..880249b1701 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -115,9 +115,8 @@ int omap_vc_pre_scale(struct voltagedomain *voltdm,  	}  	if (!voltdm->pmic->uv_to_vsel) { -		pr_err("%s: PMIC function to convert voltage in uV to" -			"vsel not registered. Hence unable to scale voltage" -			"for vdd_%s\n", __func__, voltdm->name); +		pr_err("%s: PMIC function to convert voltage in uV to vsel not registered. Hence unable to scale voltage for vdd_%s\n", +		       __func__, voltdm->name);  		return -ENODATA;  	} diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 4dc60e83e00..3ac8fe1d821 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -195,8 +195,8 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,  			return &voltdm->volt_data[i];  	} -	pr_notice("%s: Unable to match the current voltage with the voltage" -		"table for vdd_%s\n", __func__, voltdm->name); +	pr_notice("%s: Unable to match the current voltage with the voltage table for vdd_%s\n", +		  __func__, voltdm->name);  	return ERR_PTR(-ENODATA);  } @@ -249,8 +249,8 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,  		voltdm->scale = omap_vc_bypass_scale;  		return;  	default: -		pr_warning("%s: Trying to change the method of voltage scaling" -			"to an unsupported one!\n", __func__); +		pr_warn("%s: Trying to change the method of voltage scaling to an unsupported one!\n", +			__func__);  	}  } @@ -331,8 +331,8 @@ int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)  	if (!voltdm || !pwrdm)  		return -EINVAL; -	pr_debug("voltagedomain: associating powerdomain %s with voltagedomain " -		 "%s\n", pwrdm->name, voltdm->name); +	pr_debug("voltagedomain: %s: associating powerdomain %s\n", +		 voltdm->name, pwrdm->name);  	list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list); diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index f95c1bad9dc..85241b828c0 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -138,8 +138,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,  		udelay(1);  	}  	if (timeout >= VP_TRANXDONE_TIMEOUT) { -		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded." -			"Voltage change aborted", __func__, voltdm->name); +		pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted", +			__func__, voltdm->name);  		return -ETIMEDOUT;  	} @@ -157,9 +157,8 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,  	omap_test_timeout(vp->common->ops->check_txdone(vp->id),  			  VP_TRANXDONE_TIMEOUT, timeout);  	if (timeout >= VP_TRANXDONE_TIMEOUT) -		pr_err("%s: vdd_%s TRANXDONE timeout exceeded." -			"TRANXDONE never got set after the voltage update\n", -			__func__, voltdm->name); +		pr_err("%s: vdd_%s TRANXDONE timeout exceeded. TRANXDONE never got set after the voltage update\n", +		       __func__, voltdm->name);  	omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel); @@ -176,8 +175,7 @@ int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,  	}  	if (timeout >= VP_TRANXDONE_TIMEOUT) -		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying" -			"to clear the TRANXDONE status\n", +		pr_warn("%s: vdd_%s TRANXDONE timeout exceeded while trying to clear the TRANXDONE status\n",  			__func__, voltdm->name);  	/* Clear force bit */ @@ -257,8 +255,8 @@ void omap_vp_disable(struct voltagedomain *voltdm)  	/* If VP is already disabled, do nothing. Return */  	if (!vp->enabled) { -		pr_warning("%s: Trying to disable VP for vdd_%s when" -			"it is already disabled\n", __func__, voltdm->name); +		pr_warn("%s: Trying to disable VP for vdd_%s when it is already disabled\n", +			__func__, voltdm->name);  		return;  	} diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 119bc52ab93..4e07eec1270 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -63,10 +63,11 @@ static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd,  	pid = task_pid_nr(thread->task) << ASID_BITS;  	asm volatile(  	"	mrc	p15, 0, %0, c13, c0, 1\n" -	"	bfi	%1, %0, #0, %2\n" -	"	mcr	p15, 0, %1, c13, c0, 1\n" +	"	and	%0, %0, %2\n" +	"	orr	%0, %0, %1\n" +	"	mcr	p15, 0, %0, c13, c0, 1\n"  	: "=r" (contextidr), "+r" (pid) -	: "I" (ASID_BITS)); +	: "I" (~ASID_MASK));  	isb();  	return NOTIFY_OK; diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 051204fc461..e59c4ab71bc 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -489,7 +489,7 @@ static bool __in_atomic_pool(void *start, size_t size)  	void *pool_start = pool->vaddr;  	void *pool_end = pool->vaddr + pool->size; -	if (start < pool_start || start > pool_end) +	if (start < pool_start || start >= pool_end)  		return false;  	if (end <= pool_end) diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 6776160618e..a8ee92da354 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -55,6 +55,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page  /* permanent static mappings from iotable_init() */  #define VM_ARM_STATIC_MAPPING	0x40000000 +/* empty mapping */ +#define VM_ARM_EMPTY_MAPPING	0x20000000 +  /* mapping type (attributes) for permanent static mappings */  #define VM_ARM_MTYPE(mt)		((mt) << 20)  #define VM_ARM_MTYPE_MASK	(0x1f << 20) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4c2d0451e84..c2fa21d0103 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -807,7 +807,7 @@ static void __init pmd_empty_section_gap(unsigned long addr)  	vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));  	vm->addr = (void *)addr;  	vm->size = SECTION_SIZE; -	vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; +	vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;  	vm->caller = pmd_empty_section_gap;  	vm_area_add_early(vm);  } @@ -820,7 +820,7 @@ static void __init fill_pmd_gaps(void)  	/* we're still single threaded hence no lock needed here */  	for (vm = vmlist; vm; vm = vm->next) { -		if (!(vm->flags & VM_ARM_STATIC_MAPPING)) +		if (!(vm->flags & (VM_ARM_STATIC_MAPPING | VM_ARM_EMPTY_MAPPING)))  			continue;  		addr = (unsigned long)vm->addr;  		if (addr < next) @@ -961,8 +961,8 @@ void __init sanity_check_meminfo(void)  		 * Check whether this memory bank would partially overlap  		 * the vmalloc area.  		 */ -		if (__va(bank->start + bank->size) > vmalloc_min || -		    __va(bank->start + bank->size) < __va(bank->start)) { +		if (__va(bank->start + bank->size - 1) >= vmalloc_min || +		    __va(bank->start + bank->size - 1) <= __va(bank->start)) {  			unsigned long newsize = vmalloc_min - __va(bank->start);  			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "  			       "to -%.8llx (vmalloc region overlap).\n", diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 6dcad5873d5..c76ed8bff83 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -968,8 +968,7 @@ void omap_stop_dma(int lch)  			l = p->dma_read(CCR, lch);  		}  		if (i >= 100) -			printk(KERN_ERR "DMA drain did not complete on " -					"lch %d\n", lch); +			pr_err("DMA drain did not complete on lch %d\n", lch);  		/* Restore OCP_SYSCONFIG */  		p->dma_write(sys_cf, OCP_SYSCONFIG, lch);  	} else { @@ -1153,8 +1152,7 @@ void omap_dma_link_lch(int lch_head, int lch_queue)  	if ((dma_chan[lch_head].dev_id == -1) ||  	    (dma_chan[lch_queue].dev_id == -1)) { -		printk(KERN_ERR "omap_dma: trying to link " -		       "non requested channels\n"); +		pr_err("omap_dma: trying to link non requested channels\n");  		dump_stack();  	} @@ -1180,15 +1178,13 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)  	if (dma_chan[lch_head].next_lch != lch_queue ||  	    dma_chan[lch_head].next_lch == -1) { -		printk(KERN_ERR "omap_dma: trying to unlink " -		       "non linked channels\n"); +		pr_err("omap_dma: trying to unlink non linked channels\n");  		dump_stack();  	}  	if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||  	    (dma_chan[lch_queue].flags & OMAP_DMA_ACTIVE)) { -		printk(KERN_ERR "omap_dma: You need to stop the DMA channels " -		       "before unlinking\n"); +		pr_err("omap_dma: You need to stop the DMA channels before unlinking\n");  		dump_stack();  	} @@ -1830,16 +1826,15 @@ static int omap1_dma_handle_ch(int ch)  	if ((csr & 0x3f) == 0)  		return 0;  	if (unlikely(dma_chan[ch].dev_id == -1)) { -		printk(KERN_WARNING "Spurious interrupt from DMA channel " -		       "%d (CSR %04x)\n", ch, csr); +		pr_warn("Spurious interrupt from DMA channel %d (CSR %04x)\n", +			ch, csr);  		return 0;  	}  	if (unlikely(csr & OMAP1_DMA_TOUT_IRQ)) -		printk(KERN_WARNING "DMA timeout with device %d\n", -		       dma_chan[ch].dev_id); +		pr_warn("DMA timeout with device %d\n", dma_chan[ch].dev_id);  	if (unlikely(csr & OMAP_DMA_DROP_IRQ)) -		printk(KERN_WARNING "DMA synchronization event drop occurred " -		       "with device %d\n", dma_chan[ch].dev_id); +		pr_warn("DMA synchronization event drop occurred with device %d\n", +			dma_chan[ch].dev_id);  	if (likely(csr & OMAP_DMA_BLOCK_IRQ))  		dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;  	if (likely(dma_chan[ch].callback != NULL)) @@ -1879,21 +1874,19 @@ static int omap2_dma_handle_ch(int ch)  	if (!status) {  		if (printk_ratelimit()) -			printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", -				ch); +			pr_warn("Spurious DMA IRQ for lch %d\n", ch);  		p->dma_write(1 << ch, IRQSTATUS_L0, ch);  		return 0;  	}  	if (unlikely(dma_chan[ch].dev_id == -1)) {  		if (printk_ratelimit()) -			printk(KERN_WARNING "IRQ %04x for non-allocated DMA" -					"channel %d\n", status, ch); +			pr_warn("IRQ %04x for non-allocated DMA channel %d\n", +				status, ch);  		return 0;  	}  	if (unlikely(status & OMAP_DMA_DROP_IRQ)) -		printk(KERN_INFO -		       "DMA synchronization event drop occurred with device " -		       "%d\n", dma_chan[ch].dev_id); +		pr_info("DMA synchronization event drop occurred with device %d\n", +			dma_chan[ch].dev_id);  	if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {  		printk(KERN_INFO "DMA transaction error with device %d\n",  		       dma_chan[ch].dev_id); @@ -2013,8 +2006,9 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)  	p = pdev->dev.platform_data;  	if (!p) { -		dev_err(&pdev->dev, "%s: System DMA initialized without" -			"platform data\n", __func__); +		dev_err(&pdev->dev, +			"%s: System DMA initialized without platform data\n", +			__func__);  		return -EINVAL;  	} @@ -2089,8 +2083,8 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)  		}  		ret = setup_irq(dma_irq, &omap24xx_dma_irq);  		if (ret) { -			dev_err(&pdev->dev, "set_up failed for IRQ %d" -				"for DMA (error %d)\n", dma_irq, ret); +			dev_err(&pdev->dev, "set_up failed for IRQ %d for DMA (error %d)\n", +				dma_irq, ret);  			goto exit_dma_lch_fail;  		}  	} @@ -2098,8 +2092,7 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)  	/* reserve dma channels 0 and 1 in high security devices */  	if (cpu_is_omap34xx() &&  		(omap_type() != OMAP2_DEVICE_TYPE_GP)) { -		printk(KERN_INFO "Reserving DMA channels 0 and 1 for " -				"HS ROM code\n"); +		pr_info("Reserving DMA channels 0 and 1 for HS ROM code\n");  		dma_chan[0].dev_id = 0;  		dma_chan[1].dev_id = 1;  	} @@ -2107,8 +2100,8 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)  	return 0;  exit_dma_irq_fail: -	dev_err(&pdev->dev, "unable to request IRQ %d" -			"for DMA (error %d)\n", dma_irq, ret); +	dev_err(&pdev->dev, "unable to request IRQ %d for DMA (error %d)\n", +		dma_irq, ret);  	for (irq_rel = 0; irq_rel < ch;	irq_rel++) {  		dma_irq = platform_get_irq(pdev, irq_rel);  		free_irq(dma_irq, (void *)(irq_rel + 1)); diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index cff8712122b..fd0d3aad00e 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -76,7 +76,7 @@ int __init_or_module omap_cfg_reg(const unsigned long index)  		return -ENODEV;  	} -	reg = (struct pin_config *)&mux_cfg->pins[index]; +	reg = &mux_cfg->pins[index];  	if (!mux_cfg->cfg_reg)  		return -ENODEV; diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index 5a97b4d98d4..9f6413324df 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -41,11 +41,11 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)  	};  	if (t == -1) -		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: " -			 "dev %s\n", dev_name(dev)); +		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n", +			 dev_name(dev));  	else -		pr_debug("OMAP PM: add max MPU wakeup latency constraint: " -			 "dev %s, t = %ld usec\n", dev_name(dev), t); +		pr_debug("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n", +			 dev_name(dev), t);  	/*  	 * For current Linux, this needs to map the MPU to a @@ -70,11 +70,10 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)  	};  	if (r == 0) -		pr_debug("OMAP PM: remove min bus tput constraint: " -			 "dev %s for agent_id %d\n", dev_name(dev), agent_id); +		pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n", +			 dev_name(dev), agent_id);  	else -		pr_debug("OMAP PM: add min bus tput constraint: " -			 "dev %s for agent_id %d: rate %ld KiB\n", +		pr_debug("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n",  			 dev_name(dev), agent_id, r);  	/* @@ -97,11 +96,11 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,  	};  	if (t == -1) -		pr_debug("OMAP PM: remove max device latency constraint: " -			 "dev %s\n", dev_name(dev)); +		pr_debug("OMAP PM: remove max device latency constraint: dev %s\n", +			 dev_name(dev));  	else -		pr_debug("OMAP PM: add max device latency constraint: " -			 "dev %s, t = %ld usec\n", dev_name(dev), t); +		pr_debug("OMAP PM: add max device latency constraint: dev %s, t = %ld usec\n", +			 dev_name(dev), t);  	/*  	 * For current Linux, this needs to map the device to a @@ -127,11 +126,11 @@ int omap_pm_set_max_sdma_lat(struct device *dev, long t)  	};  	if (t == -1) -		pr_debug("OMAP PM: remove max DMA latency constraint: " -			 "dev %s\n", dev_name(dev)); +		pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n", +			 dev_name(dev));  	else -		pr_debug("OMAP PM: add max DMA latency constraint: " -			 "dev %s, t = %ld usec\n", dev_name(dev), t); +		pr_debug("OMAP PM: add max DMA latency constraint: dev %s, t = %ld usec\n", +			 dev_name(dev), t);  	/*  	 * For current Linux PM QOS params, this code should scan the @@ -156,11 +155,11 @@ int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)  	}  	if (r == 0) -		pr_debug("OMAP PM: remove min clk rate constraint: " -			 "dev %s\n", dev_name(dev)); +		pr_debug("OMAP PM: remove min clk rate constraint: dev %s\n", +			 dev_name(dev));  	else -		pr_debug("OMAP PM: add min clk rate constraint: " -			 "dev %s, rate = %ld Hz\n", dev_name(dev), r); +		pr_debug("OMAP PM: add min clk rate constraint: dev %s, rate = %ld Hz\n", +			 dev_name(dev), r);  	/*  	 * Code in a real implementation should keep track of these diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index c490240bb82..b59edb065c7 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -1,4 +1,3 @@ -  /*   * omap_device implementation   * @@ -153,21 +152,19 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)  		act_lat = timespec_to_ns(&c);  		dev_dbg(&od->pdev->dev, -			"omap_device: pm_lat %d: activate: elapsed time " -			"%llu nsec\n", od->pm_lat_level, act_lat); +			"omap_device: pm_lat %d: activate: elapsed time %llu nsec\n", +			od->pm_lat_level, act_lat);  		if (act_lat > odpl->activate_lat) {  			odpl->activate_lat_worst = act_lat;  			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {  				odpl->activate_lat = act_lat;  				dev_dbg(&od->pdev->dev, -					"new worst case activate latency " -					"%d: %llu\n", +					"new worst case activate latency %d: %llu\n",  					od->pm_lat_level, act_lat);  			} else  				dev_warn(&od->pdev->dev, -					 "activate latency %d " -					 "higher than exptected. (%llu > %d)\n", +					 "activate latency %d higher than expected. (%llu > %d)\n",  					 od->pm_lat_level, act_lat,  					 odpl->activate_lat);  		} @@ -220,21 +217,19 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)  		deact_lat = timespec_to_ns(&c);  		dev_dbg(&od->pdev->dev, -			"omap_device: pm_lat %d: deactivate: elapsed time " -			"%llu nsec\n", od->pm_lat_level, deact_lat); +			"omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n", +			od->pm_lat_level, deact_lat);  		if (deact_lat > odpl->deactivate_lat) {  			odpl->deactivate_lat_worst = deact_lat;  			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {  				odpl->deactivate_lat = deact_lat;  				dev_dbg(&od->pdev->dev, -					"new worst case deactivate latency " -					"%d: %llu\n", +					"new worst case deactivate latency %d: %llu\n",  					od->pm_lat_level, deact_lat);  			} else  				dev_warn(&od->pdev->dev, -					 "deactivate latency %d " -					 "higher than exptected. (%llu > %d)\n", +					 "deactivate latency %d higher than expected. (%llu > %d)\n",  					 od->pm_lat_level, deact_lat,  					 odpl->deactivate_lat);  		} @@ -449,8 +444,8 @@ static int omap_device_count_resources(struct omap_device *od)  	for (i = 0; i < od->hwmods_cnt; i++)  		c += omap_hwmod_count_resources(od->hwmods[i]); -	pr_debug("omap_device: %s: counted %d total resources across %d " -		 "hwmods\n", od->pdev->name, c, od->hwmods_cnt); +	pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", +		 od->pdev->name, c, od->hwmods_cnt);  	return c;  } diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index d861aa73299..28acb383e7d 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -67,6 +67,7 @@  static unsigned long omap_sram_start;  static void __iomem *omap_sram_base; +static unsigned long omap_sram_skip;  static unsigned long omap_sram_size;  static void __iomem *omap_sram_ceil; @@ -105,6 +106,7 @@ static int is_sram_locked(void)   */  static void __init omap_detect_sram(void)  { +	omap_sram_skip = SRAM_BOOTLOADER_SZ;  	if (cpu_class_is_omap2()) {  		if (is_sram_locked()) {  			if (cpu_is_omap34xx()) { @@ -112,6 +114,7 @@ static void __init omap_detect_sram(void)  				if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||  				    (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {  					omap_sram_size = 0x7000; /* 28K */ +					omap_sram_skip += SZ_16K;  				} else {  					omap_sram_size = 0x8000; /* 32K */  				} @@ -174,8 +177,10 @@ static void __init omap_map_sram(void)  		return;  #ifdef CONFIG_OMAP4_ERRATA_I688 +	if (cpu_is_omap44xx()) {  		omap_sram_start += PAGE_SIZE;  		omap_sram_size -= SZ_16K; +	}  #endif  	if (cpu_is_omap34xx()) {  		/* @@ -202,8 +207,8 @@ static void __init omap_map_sram(void)  	 * Looks like we need to preserve some bootloader code at the  	 * beginning of SRAM for jumping to flash for reboot to work...  	 */ -	memset_io(omap_sram_base + SRAM_BOOTLOADER_SZ, 0, -		  omap_sram_size - SRAM_BOOTLOADER_SZ); +	memset_io(omap_sram_base + omap_sram_skip, 0, +		  omap_sram_size - omap_sram_skip);  }  /* @@ -217,7 +222,7 @@ void *omap_sram_push_address(unsigned long size)  {  	unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; -	available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ); +	available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);  	if (size > available) {  		pr_err("Not enough space in SRAM\n"); diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f3486192063..c7092e6057c 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -38,6 +38,7 @@ config BLACKFIN  	select GENERIC_ATOMIC64  	select GENERIC_IRQ_PROBE  	select IRQ_PER_CPU if SMP +	select USE_GENERIC_SMP_HELPERS if SMP  	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG  	select GENERIC_SMP_IDLE_THREAD  	select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index d3d7e64ca96..66cf00095b8 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -20,7 +20,6 @@ endif  KBUILD_AFLAGS           += $(call cc-option,-mno-fdpic)  KBUILD_CFLAGS_MODULE    += -mlong-calls  LDFLAGS                 += -m elf32bfin -KALLSYMS         += --symbol-prefix=_  KBUILD_DEFCONFIG := BF537-STAMP_defconfig diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index dc3d144b4bb..9631598dcc5 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h @@ -18,6 +18,8 @@  #define raw_smp_processor_id()  blackfin_core_id()  extern void bfin_relocate_coreb_l1_mem(void); +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);  #if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1)  asmlinkage void blackfin_icache_flush_range_l1(unsigned long *ptr); diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 00bbe672b3b..a40151306b7 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -48,10 +48,13 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS];  struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; -#define BFIN_IPI_TIMER	      0 -#define BFIN_IPI_RESCHEDULE   1 -#define BFIN_IPI_CALL_FUNC    2 -#define BFIN_IPI_CPU_STOP     3 +enum ipi_message_type { +	BFIN_IPI_TIMER, +	BFIN_IPI_RESCHEDULE, +	BFIN_IPI_CALL_FUNC, +	BFIN_IPI_CALL_FUNC_SINGLE, +	BFIN_IPI_CPU_STOP, +};  struct blackfin_flush_data {  	unsigned long start; @@ -60,35 +63,20 @@ struct blackfin_flush_data {  void *secondary_stack; - -struct smp_call_struct { -	void (*func)(void *info); -	void *info; -	int wait; -	cpumask_t *waitmask; -}; -  static struct blackfin_flush_data smp_flush_data;  static DEFINE_SPINLOCK(stop_lock); -struct ipi_message { -	unsigned long type; -	struct smp_call_struct call_struct; -}; -  /* A magic number - stress test shows this is safe for common cases */  #define BFIN_IPI_MSGQ_LEN 5  /* Simple FIFO buffer, overflow leads to panic */ -struct ipi_message_queue { -	spinlock_t lock; +struct ipi_data {  	unsigned long count; -	unsigned long head; /* head of the queue */ -	struct ipi_message ipi_message[BFIN_IPI_MSGQ_LEN]; +	unsigned long bits;  }; -static DEFINE_PER_CPU(struct ipi_message_queue, ipi_msg_queue); +static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);  static void ipi_cpu_stop(unsigned int cpu)  { @@ -129,28 +117,6 @@ static void ipi_flush_icache(void *info)  	blackfin_icache_flush_range(fdata->start, fdata->end);  } -static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) -{ -	int wait; -	void (*func)(void *info); -	void *info; -	func = msg->call_struct.func; -	info = msg->call_struct.info; -	wait = msg->call_struct.wait; -	func(info); -	if (wait) { -#ifdef __ARCH_SYNC_CORE_DCACHE -		/* -		 * 'wait' usually means synchronization between CPUs. -		 * Invalidate D cache in case shared data was changed -		 * by func() to ensure cache coherence. -		 */ -		resync_core_dcache(); -#endif -		cpumask_clear_cpu(cpu, msg->call_struct.waitmask); -	} -} -  /* Use IRQ_SUPPLE_0 to request reschedule.   * When returning from interrupt to user space,   * there is chance to reschedule */ @@ -172,152 +138,95 @@ void ipi_timer(void)  static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)  { -	struct ipi_message *msg; -	struct ipi_message_queue *msg_queue; +	struct ipi_data *bfin_ipi_data;  	unsigned int cpu = smp_processor_id(); -	unsigned long flags; +	unsigned long pending; +	unsigned long msg;  	platform_clear_ipi(cpu, IRQ_SUPPLE_1); -	msg_queue = &__get_cpu_var(ipi_msg_queue); +	bfin_ipi_data = &__get_cpu_var(bfin_ipi); + +	while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) { +		msg = 0; +		do { +			msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1); +			switch (msg) { +			case BFIN_IPI_TIMER: +				ipi_timer(); +				break; +			case BFIN_IPI_RESCHEDULE: +				scheduler_ipi(); +				break; +			case BFIN_IPI_CALL_FUNC: +				generic_smp_call_function_interrupt(); +				break; + +			case BFIN_IPI_CALL_FUNC_SINGLE: +				generic_smp_call_function_single_interrupt(); +				break; -	spin_lock_irqsave(&msg_queue->lock, flags); +			case BFIN_IPI_CPU_STOP: +				ipi_cpu_stop(cpu); +				break; +			} +		} while (msg < BITS_PER_LONG); -	while (msg_queue->count) { -		msg = &msg_queue->ipi_message[msg_queue->head]; -		switch (msg->type) { -		case BFIN_IPI_TIMER: -			ipi_timer(); -			break; -		case BFIN_IPI_RESCHEDULE: -			scheduler_ipi(); -			break; -		case BFIN_IPI_CALL_FUNC: -			ipi_call_function(cpu, msg); -			break; -		case BFIN_IPI_CPU_STOP: -			ipi_cpu_stop(cpu); -			break; -		default: -			printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n", -			       cpu, msg->type); -			break; -		} -		msg_queue->head++; -		msg_queue->head %= BFIN_IPI_MSGQ_LEN; -		msg_queue->count--; +		smp_mb();  	} -	spin_unlock_irqrestore(&msg_queue->lock, flags);  	return IRQ_HANDLED;  } -static void ipi_queue_init(void) +static void bfin_ipi_init(void)  {  	unsigned int cpu; -	struct ipi_message_queue *msg_queue; +	struct ipi_data *bfin_ipi_data;  	for_each_possible_cpu(cpu) { -		msg_queue = &per_cpu(ipi_msg_queue, cpu); -		spin_lock_init(&msg_queue->lock); -		msg_queue->count = 0; -		msg_queue->head = 0; +		bfin_ipi_data = &per_cpu(bfin_ipi, cpu); +		bfin_ipi_data->bits = 0; +		bfin_ipi_data->count = 0;  	}  } -static inline void smp_send_message(cpumask_t callmap, unsigned long type, -					void (*func) (void *info), void *info, int wait) +void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)  {  	unsigned int cpu; -	struct ipi_message_queue *msg_queue; -	struct ipi_message *msg; -	unsigned long flags, next_msg; -	cpumask_t waitmask; /* waitmask is shared by all cpus */ +	struct ipi_data *bfin_ipi_data; +	unsigned long flags; -	cpumask_copy(&waitmask, &callmap); -	for_each_cpu(cpu, &callmap) { -		msg_queue = &per_cpu(ipi_msg_queue, cpu); -		spin_lock_irqsave(&msg_queue->lock, flags); -		if (msg_queue->count < BFIN_IPI_MSGQ_LEN) { -			next_msg = (msg_queue->head + msg_queue->count) -					% BFIN_IPI_MSGQ_LEN; -			msg = &msg_queue->ipi_message[next_msg]; -			msg->type = type; -			if (type == BFIN_IPI_CALL_FUNC) { -				msg->call_struct.func = func; -				msg->call_struct.info = info; -				msg->call_struct.wait = wait; -				msg->call_struct.waitmask = &waitmask; -			} -			msg_queue->count++; -		} else -			panic("IPI message queue overflow\n"); -		spin_unlock_irqrestore(&msg_queue->lock, flags); +	local_irq_save(flags); + +	for_each_cpu(cpu, cpumask) { +		bfin_ipi_data = &per_cpu(bfin_ipi, cpu); +		smp_mb(); +		set_bit(msg, &bfin_ipi_data->bits); +		bfin_ipi_data->count++;  		platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);  	} -	if (wait) { -		while (!cpumask_empty(&waitmask)) -			blackfin_dcache_invalidate_range( -				(unsigned long)(&waitmask), -				(unsigned long)(&waitmask)); -#ifdef __ARCH_SYNC_CORE_DCACHE -		/* -		 * Invalidate D cache in case shared data was changed by -		 * other processors to ensure cache coherence. -		 */ -		resync_core_dcache(); -#endif -	} +	local_irq_restore(flags);  } -int smp_call_function(void (*func)(void *info), void *info, int wait) +void arch_send_call_function_single_ipi(int cpu)  { -	cpumask_t callmap; - -	preempt_disable(); -	cpumask_copy(&callmap, cpu_online_mask); -	cpumask_clear_cpu(smp_processor_id(), &callmap); -	if (!cpumask_empty(&callmap)) -		smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); - -	preempt_enable(); - -	return 0; +	send_ipi(cpumask_of(cpu), BFIN_IPI_CALL_FUNC_SINGLE);  } -EXPORT_SYMBOL_GPL(smp_call_function); -int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, -				int wait) +void arch_send_call_function_ipi_mask(const struct cpumask *mask)  { -	unsigned int cpu = cpuid; -	cpumask_t callmap; - -	if (cpu_is_offline(cpu)) -		return 0; -	cpumask_clear(&callmap); -	cpumask_set_cpu(cpu, &callmap); - -	smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait); - -	return 0; +	send_ipi(mask, BFIN_IPI_CALL_FUNC);  } -EXPORT_SYMBOL_GPL(smp_call_function_single);  void smp_send_reschedule(int cpu)  { -	cpumask_t callmap; -	/* simply trigger an ipi */ - -	cpumask_clear(&callmap); -	cpumask_set_cpu(cpu, &callmap); - -	smp_send_message(callmap, BFIN_IPI_RESCHEDULE, NULL, NULL, 0); +	send_ipi(cpumask_of(cpu), BFIN_IPI_RESCHEDULE);  	return;  }  void smp_send_msg(const struct cpumask *mask, unsigned long type)  { -	smp_send_message(*mask, type, NULL, NULL, 0); +	send_ipi(mask, type);  }  void smp_timer_broadcast(const struct cpumask *mask) @@ -333,7 +242,7 @@ void smp_send_stop(void)  	cpumask_copy(&callmap, cpu_online_mask);  	cpumask_clear_cpu(smp_processor_id(), &callmap);  	if (!cpumask_empty(&callmap)) -		smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0); +		send_ipi(&callmap, BFIN_IPI_CPU_STOP);  	preempt_enable(); @@ -436,7 +345,7 @@ void __init smp_prepare_boot_cpu(void)  void __init smp_prepare_cpus(unsigned int max_cpus)  {  	platform_prepare_cpus(max_cpus); -	ipi_queue_init(); +	bfin_ipi_init();  	platform_request_ipi(IRQ_SUPPLE_0, ipi_handler_int0);  	platform_request_ipi(IRQ_SUPPLE_1, ipi_handler_int1);  } diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index a1e9d69a9c9..584b93674ea 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -169,7 +169,7 @@ static ssize_t hw_interval_write(struct file *file, char const __user *buf,  	if (*offset)  		return -EINVAL;  	retval = oprofilefs_ulong_from_user(&val, buf, count); -	if (retval) +	if (retval <= 0)  		return retval;  	if (val < oprofile_min_interval)  		oprofile_hw_interval = oprofile_min_interval; @@ -212,7 +212,7 @@ static ssize_t hwsampler_zero_write(struct file *file, char const __user *buf,  		return -EINVAL;  	retval = oprofilefs_ulong_from_user(&val, buf, count); -	if (retval) +	if (retval <= 0)  		return retval;  	if (val != 0)  		return -EINVAL; @@ -243,7 +243,7 @@ static ssize_t hwsampler_kernel_write(struct file *file, char const __user *buf,  		return -EINVAL;  	retval = oprofilefs_ulong_from_user(&val, buf, count); -	if (retval) +	if (retval <= 0)  		return retval;  	if (val != 0 && val != 1) @@ -278,7 +278,7 @@ static ssize_t hwsampler_user_write(struct file *file, char const __user *buf,  		return -EINVAL;  	retval = oprofilefs_ulong_from_user(&val, buf, count); -	if (retval) +	if (retval <= 0)  		return retval;  	if (val != 0 && val != 1) @@ -317,7 +317,7 @@ static ssize_t timer_enabled_write(struct file *file, char const __user *buf,  		return -EINVAL;  	retval = oprofilefs_ulong_from_user(&val, buf, count); -	if (retval) +	if (retval <= 0)  		return retval;  	if (val != 0 && val != 1) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 7f2739e03e7..0d3d63afa76 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -2008,6 +2008,7 @@ __init int intel_pmu_init(void)  		break;  	case 28: /* Atom */ +	case 54: /* Cedariew */  		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,  		       sizeof(hw_cache_event_ids)); diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 520b4265fcd..da02e9cc375 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -686,7 +686,8 @@ void intel_pmu_lbr_init_atom(void)  	 * to have an operational LBR which can freeze  	 * on PMU interrupt  	 */ -	if (boot_cpu_data.x86_mask < 10) { +	if (boot_cpu_data.x86_model == 28 +	    && boot_cpu_data.x86_mask < 10) {  		pr_cont("LBR disabled due to erratum");  		return;  	} diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 4873e62db6a..9e5bcf1e237 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -225,6 +225,9 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,  	if (do_microcode_update(buf, len) == 0)  		ret = (ssize_t)len; +	if (ret > 0) +		perf_check_microcode(); +  	mutex_unlock(µcode_mutex);  	put_online_cpus(); diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index e498b18f010..9fc9aa7ac70 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -318,7 +318,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)  		if (val & 0x10) {  			u8 edge_irr = s->irr & ~s->elcr;  			int i; -			bool found; +			bool found = false;  			struct kvm_vcpu *vcpu;  			s->init4 = val & 1; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c00f03de1b7..b1eb202ee76 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3619,6 +3619,7 @@ static void seg_setup(int seg)  static int alloc_apic_access_page(struct kvm *kvm)  { +	struct page *page;  	struct kvm_userspace_memory_region kvm_userspace_mem;  	int r = 0; @@ -3633,7 +3634,13 @@ static int alloc_apic_access_page(struct kvm *kvm)  	if (r)  		goto out; -	kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); +	page = gfn_to_page(kvm, 0xfee00); +	if (is_error_page(page)) { +		r = -EFAULT; +		goto out; +	} + +	kvm->arch.apic_access_page = page;  out:  	mutex_unlock(&kvm->slots_lock);  	return r; @@ -3641,6 +3648,7 @@ out:  static int alloc_identity_pagetable(struct kvm *kvm)  { +	struct page *page;  	struct kvm_userspace_memory_region kvm_userspace_mem;  	int r = 0; @@ -3656,8 +3664,13 @@ static int alloc_identity_pagetable(struct kvm *kvm)  	if (r)  		goto out; -	kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, -			kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); +	page = gfn_to_page(kvm, kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); +	if (is_error_page(page)) { +		r = -EFAULT; +		goto out; +	} + +	kvm->arch.ept_identity_pagetable = page;  out:  	mutex_unlock(&kvm->slots_lock);  	return r; @@ -6575,7 +6588,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)  	/* Exposing INVPCID only when PCID is exposed */  	best = kvm_find_cpuid_entry(vcpu, 0x7, 0);  	if (vmx_invpcid_supported() && -	    best && (best->ecx & bit(X86_FEATURE_INVPCID)) && +	    best && (best->ebx & bit(X86_FEATURE_INVPCID)) &&  	    guest_cpuid_has_pcid(vcpu)) {  		exec_control |= SECONDARY_EXEC_ENABLE_INVPCID;  		vmcs_write32(SECONDARY_VM_EXEC_CONTROL, @@ -6585,7 +6598,7 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)  		vmcs_write32(SECONDARY_VM_EXEC_CONTROL,  			     exec_control);  		if (best) -			best->ecx &= ~bit(X86_FEATURE_INVPCID); +			best->ebx &= ~bit(X86_FEATURE_INVPCID);  	}  } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 148ed666e31..2966c847d48 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5113,17 +5113,20 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)  			!kvm_event_needs_reinjection(vcpu);  } -static void vapic_enter(struct kvm_vcpu *vcpu) +static int vapic_enter(struct kvm_vcpu *vcpu)  {  	struct kvm_lapic *apic = vcpu->arch.apic;  	struct page *page;  	if (!apic || !apic->vapic_addr) -		return; +		return 0;  	page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); +	if (is_error_page(page)) +		return -EFAULT;  	vcpu->arch.apic->vapic_page = page; +	return 0;  }  static void vapic_exit(struct kvm_vcpu *vcpu) @@ -5430,7 +5433,11 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)  	}  	vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); -	vapic_enter(vcpu); +	r = vapic_enter(vcpu); +	if (r) { +		srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); +		return r; +	}  	r = 1;  	while (r > 0) { diff --git a/crypto/authenc.c b/crypto/authenc.c index 5ef7ba6b6a7..d0583a4489e 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -336,7 +336,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,  		cryptlen += ivsize;  	} -	if (sg_is_last(assoc)) { +	if (req->assoclen && sg_is_last(assoc)) {  		authenc_ahash_fn = crypto_authenc_ahash;  		sg_init_table(asg, 2);  		sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); @@ -490,7 +490,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,  		cryptlen += ivsize;  	} -	if (sg_is_last(assoc)) { +	if (req->assoclen && sg_is_last(assoc)) {  		authenc_ahash_fn = crypto_authenc_ahash;  		sg_init_table(asg, 2);  		sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9628652e080..e0596954290 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state)  	} else if (result == ACPI_STATE_D3_HOT) {  		result = ACPI_STATE_D3;  	} + +	/* +	 * If we were unsure about the device parent's power state up to this +	 * point, the fact that the device is in D0 implies that the parent has +	 * to be in D0 too. +	 */ +	if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN +	    && result == ACPI_STATE_D0) +		device->parent->power.state = ACPI_STATE_D0; +  	*state = result;   out: diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fc180341462..40e38a06ba8 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -107,6 +107,7 @@ struct acpi_power_resource {  	/* List of devices relying on this power resource */  	struct acpi_power_resource_device *devices; +	struct mutex devices_lock;  };  static struct list_head acpi_power_resource_list; @@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device)  static int __acpi_power_on(struct acpi_power_resource *resource)  { -	struct acpi_power_resource_device *device_list = resource->devices;  	acpi_status status = AE_OK;  	status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); @@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource)  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",  			  resource->name)); -	while (device_list) { -		acpi_power_on_device(device_list->device); - -		device_list = device_list->next; -	} -  	return 0;  }  static int acpi_power_on(acpi_handle handle)  {  	int result = 0; +	bool resume_device = false;  	struct acpi_power_resource *resource = NULL; +	struct acpi_power_resource_device *device_list;  	result = acpi_power_get_context(handle, &resource);  	if (result) @@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle)  		result = __acpi_power_on(resource);  		if (result)  			resource->ref_count--; +		else +			resume_device = true;  	}  	mutex_unlock(&resource->resource_lock); +	if (!resume_device) +		return result; + +	mutex_lock(&resource->devices_lock); + +	device_list = resource->devices; +	while (device_list) { +		acpi_power_on_device(device_list->device); +		device_list = device_list->next; +	} + +	mutex_unlock(&resource->devices_lock); +  	return result;  } @@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,  	if (acpi_power_get_context(res_handle, &resource))  		return; -	mutex_lock(&resource->resource_lock); +	mutex_lock(&resource->devices_lock);  	prev = NULL;  	curr = resource->devices;  	while (curr) { @@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,  		prev = curr;  		curr = curr->next;  	} -	mutex_unlock(&resource->resource_lock); +	mutex_unlock(&resource->devices_lock);  }  /* Unlink dev from all power resources in _PR0 */ @@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device(  	power_resource_device->device = powered_device; -	mutex_lock(&resource->resource_lock); +	mutex_lock(&resource->devices_lock);  	power_resource_device->next = resource->devices;  	resource->devices = power_resource_device; -	mutex_unlock(&resource->resource_lock); +	mutex_unlock(&resource->devices_lock);  	return 0;  } @@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)  	return ret;  no_power_resource: -	printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); +	printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");  	return -ENODEV;  }  EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); @@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device)  	resource->device = device;  	mutex_init(&resource->resource_lock); +	mutex_init(&resource->devices_lock);  	strcpy(resource->name, device->pnp.bus_id);  	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);  	strcpy(acpi_device_class(device), ACPI_POWER_CLASS); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 50d5dea0ff5..7862d17976b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -268,6 +268,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	/* JMicron 360/1/3/5/6, match class to avoid IDE function */  	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,  	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, +	/* JMicron 362B and 362C have an AHCI function with IDE class code */ +	{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, +	{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },  	/* ATI */  	{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ @@ -393,6 +396,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */  	{ PCI_DEVICE(0x1b4b, 0x917a),  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */ +	{ PCI_DEVICE(0x1b4b, 0x9192), +	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 on some Gigabyte */  	{ PCI_DEVICE(0x1b4b, 0x91a3),  	  .driver_data = board_ahci_yes_fbs }, @@ -400,7 +405,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },	/* PDC42819 */  	/* Asmedia */ -	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1061 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci },	/* ASM1060 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci },	/* ASM1060 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci },	/* ASM1061 */ +	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */  	/* Generic, PCI class code for AHCI */  	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 11f36e50213..fc2de5528dc 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = {  	/* Atheros AR5BBU22 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE03C) }, +	{ USB_DEVICE(0x0489, 0xE036) },  	{ }	/* Terminating entry */  }; @@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {  	/* Atheros AR5BBU22 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },  	{ }	/* Terminating entry */  }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cef3bac1a54..654e248763e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = {  	/* Generic Bluetooth USB device */  	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, +	/* Apple-specific (Broadcom) devices */ +	{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, +  	/* Broadcom SoftSailing reporting vendor specific */  	{ USB_DEVICE(0x0a5c, 0x21e1) }, @@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = {  	/* Broadcom BCM20702A0 */  	{ USB_DEVICE(0x0489, 0xe042) }, -	{ USB_DEVICE(0x0a5c, 0x21e3) }, -	{ USB_DEVICE(0x0a5c, 0x21e6) }, -	{ USB_DEVICE(0x0a5c, 0x21e8) }, -	{ USB_DEVICE(0x0a5c, 0x21f3) }, -	{ USB_DEVICE(0x0a5c, 0x21f4) },  	{ USB_DEVICE(0x413c, 0x8197) },  	/* Foxconn - Hon Hai */  	{ USB_DEVICE(0x0489, 0xe033) }, +	/*Broadcom devices with vendor specific id */ +	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, +  	{ }	/* Terminating entry */  }; @@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = {  	/* Atheros AR5BBU12 with sflash firmware */  	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, +	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },  	/* Broadcom BCM2035 */  	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index 002888185f1..d216cd3cc56 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c @@ -120,3 +120,4 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,  	return ret;  } +EXPORT_SYMBOL(gen_split_key); diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 920a609b2c3..38f9e52f358 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)  	}  	info->dev = &pdev->dev;  	info->max77693 = max77693; -	info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, -					 &max77693_muic_regmap_config); -	if (IS_ERR(info->max77693->regmap_muic)) { -		ret = PTR_ERR(info->max77693->regmap_muic); -		dev_err(max77693->dev, -			"failed to allocate register map: %d\n", ret); -		goto err_regmap; +	if (info->max77693->regmap_muic) +		dev_dbg(&pdev->dev, "allocate register map\n"); +	else { +		info->max77693->regmap_muic = devm_regmap_init_i2c( +						info->max77693->muic, +						&max77693_muic_regmap_config); +		if (IS_ERR(info->max77693->regmap_muic)) { +			ret = PTR_ERR(info->max77693->regmap_muic); +			dev_err(max77693->dev, +				"failed to allocate register map: %d\n", ret); +			goto err_regmap; +		}  	}  	platform_set_drvdata(pdev, info);  	mutex_init(&info->mutex); diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49..36164806b9d 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -193,6 +193,9 @@ static const struct file_operations ast_fops = {  	.mmap = ast_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb5..a712cafcfa1 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev)  	ast->cursor_cache = obj;  	ast->cursor_cache_gpu_addr = gpu_addr; -	DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); +	DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr);  	return 0;  fail:  	return ret; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c659..b83a2d7ddd1 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = cirrus_mmap,  	.poll = drm_poll, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.fasync = drm_fasync,  };  static struct drm_driver driver = { diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7..59a26e577b5 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig @@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI  config DRM_EXYNOS_G2D  	bool "Exynos DRM G2D" -	depends on DRM_EXYNOS +	depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D  	help  	  Choose this option if you want to use Exynos G2D for DRM. diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b..ae13febe0ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,  	/* TODO */  } +static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, +	struct vm_area_struct *vma) +{ +	return -ENOTTY; +} +  static struct dma_buf_ops exynos_dmabuf_ops = {  	.map_dma_buf		= exynos_gem_map_dma_buf,  	.unmap_dma_buf		= exynos_gem_unmap_dma_buf, @@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = {  	.kmap_atomic		= exynos_gem_dmabuf_kmap_atomic,  	.kunmap			= exynos_gem_dmabuf_kunmap,  	.kunmap_atomic		= exynos_gem_dmabuf_kunmap_atomic, +	.mmap			= exynos_gem_dmabuf_mmap,  	.release		= exynos_dmabuf_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e4..d0707193745 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)  	if (!file_priv)  		return -ENOMEM; -	drm_prime_init_file_private(&file->prime);  	file->driver_priv = file_priv;  	return exynos_drm_subdrv_open(dev, file); @@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev,  			e->base.destroy(&e->base);  		}  	} -	drm_prime_destroy_file_private(&file->prime);  	spin_unlock_irqrestore(&dev->event_lock, flags);  	exynos_drm_subdrv_close(dev, file); @@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = {  	.poll		= drm_poll,  	.read		= drm_read,  	.unlocked_ioctl	= drm_ioctl, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.release	= drm_release,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f0..b19cd93e704 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to find registers\n"); -		ret = -ENOENT; -		goto err_clk; -	}  	ctx->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!ctx->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a03..1065e90d091 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -129,7 +129,6 @@ struct g2d_runqueue_node {  struct g2d_data {  	struct device			*dev;  	struct clk			*gate_clk; -	struct resource			*regs_res;  	void __iomem			*regs;  	int				irq;  	struct workqueue_struct		*g2d_workq; @@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	struct exynos_drm_subdrv *subdrv;  	int ret; -	g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); +	g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL);  	if (!g2d) {  		dev_err(dev, "failed to allocate driver data\n");  		return -ENOMEM; @@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",  			sizeof(struct g2d_runqueue_node), 0, 0, NULL); -	if (!g2d->runqueue_slab) { -		ret = -ENOMEM; -		goto err_free_mem; -	} +	if (!g2d->runqueue_slab) +		return -ENOMEM;  	g2d->dev = dev; @@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	pm_runtime_enable(dev);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(dev, "failed to get I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} -	g2d->regs_res = request_mem_region(res->start, resource_size(res), -					   dev_name(dev)); -	if (!g2d->regs_res) { -		dev_err(dev, "failed to request I/O memory\n"); -		ret = -ENOENT; -		goto err_put_clk; -	} - -	g2d->regs = ioremap(res->start, resource_size(res)); +	g2d->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!g2d->regs) {  		dev_err(dev, "failed to remap I/O memory\n");  		ret = -ENXIO; -		goto err_release_res; +		goto err_put_clk;  	}  	g2d->irq = platform_get_irq(pdev, 0);  	if (g2d->irq < 0) {  		dev_err(dev, "failed to get irq\n");  		ret = g2d->irq; -		goto err_unmap_base; +		goto err_put_clk;  	} -	ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); +	ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, +								"drm_g2d", g2d);  	if (ret < 0) {  		dev_err(dev, "irq request failed\n"); -		goto err_unmap_base; +		goto err_put_clk;  	}  	platform_set_drvdata(pdev, g2d); @@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	ret = exynos_drm_subdrv_register(subdrv);  	if (ret < 0) {  		dev_err(dev, "failed to register drm g2d device\n"); -		goto err_free_irq; +		goto err_put_clk;  	}  	dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", @@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev)  	return 0; -err_free_irq: -	free_irq(g2d->irq, g2d); -err_unmap_base: -	iounmap(g2d->regs); -err_release_res: -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res);  err_put_clk:  	pm_runtime_disable(dev);  	clk_put(g2d->gate_clk); @@ -862,8 +840,6 @@ err_destroy_workqueue:  	destroy_workqueue(g2d->g2d_workq);  err_destroy_slab:  	kmem_cache_destroy(g2d->runqueue_slab); -err_free_mem: -	kfree(g2d);  	return ret;  } @@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev)  	cancel_work_sync(&g2d->runqueue_work);  	exynos_drm_subdrv_unregister(&g2d->subdrv); -	free_irq(g2d->irq, g2d);  	while (g2d->runqueue_node) {  		g2d_free_runqueue_node(g2d, g2d->runqueue_node);  		g2d->runqueue_node = g2d_get_runqueue_node(g2d);  	} -	iounmap(g2d->regs); -	release_resource(g2d->regs_res); -	kfree(g2d->regs_res); -  	pm_runtime_disable(&pdev->dev);  	clk_put(g2d->gate_clk);  	g2d_fini_cmdlist(g2d);  	destroy_workqueue(g2d->g2d_workq);  	kmem_cache_destroy(g2d->runqueue_slab); -	kfree(g2d);  	return 0;  } @@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev)  }  #endif -SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); +static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);  struct platform_driver g2d_driver = {  	.probe		= g2d_probe, diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c09..a38051c95ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -122,7 +122,7 @@ fail:  		__free_page(pages[i]);  	drm_free_large(pages); -	return ERR_PTR(PTR_ERR(p)); +	return ERR_CAST(p);  }  static void exynos_gem_put_pages(struct drm_gem_object *obj, @@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,  	 */  	args->pitch = args->width * ((args->bpp + 7) / 8); -	args->size = PAGE_ALIGN(args->pitch * args->height); +	args->size = args->pitch * args->height;  	exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);  	if (IS_ERR(exynos_gem_obj)) diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e2..3fdf0b65f47 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx) {  		DRM_LOG_KMS("failed to alloc common hdmi context.\n");  		return -ENOMEM; @@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__);  	exynos_drm_subdrv_unregister(&ctx->subdrv); -	kfree(ctx);  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043..e1f94b746bd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -29,7 +29,6 @@ static const uint32_t formats[] = {  	DRM_FORMAT_XRGB8888,  	DRM_FORMAT_ARGB8888,  	DRM_FORMAT_NV12, -	DRM_FORMAT_NV12M,  	DRM_FORMAT_NV12MT,  }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd5..537027a74fd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev)  	DRM_DEBUG_KMS("%s\n", __FILE__); -	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); +	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);  	if (!ctx)  		return -ENOMEM; @@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev)  		ctx->raw_edid = NULL;  	} -	kfree(ctx); -  	return 0;  } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207..a6aea6f3ea1 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	DRM_DEBUG_KMS("HDMI resource init\n"); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	/* get clocks, power */  	res->hdmi = clk_get(dev, "hdmi"); @@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata)  	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);  	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * -		sizeof res->regul_bulk[0], GFP_KERNEL); +		sizeof(res->regul_bulk[0]), GFP_KERNEL);  	if (!res->regul_bulk) {  		DRM_ERROR("failed to get memory for regulators\n");  		goto fail; @@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata)  		clk_put(res->sclk_hdmi);  	if (!IS_ERR_OR_NULL(res->hdmi))  		clk_put(res->hdmi); -	memset(res, 0, sizeof *res); +	memset(res, 0, sizeof(*res));  	return 0;  } @@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev)  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		DRM_ERROR("failed to find registers\n"); -		ret = -ENOENT; -		goto err_resource; -	}  	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);  	if (!hdata->regs) { diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81d..25b97d5e5fc 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res,  static void vp_default_filter(struct mixer_resources *res)  {  	vp_filter_set(res, VP_POLY8_Y0_LL, -		filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); +		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));  	vp_filter_set(res, VP_POLY4_Y0_LL, -		filter_y_vert_tap4, sizeof filter_y_vert_tap4); +		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));  	vp_filter_set(res, VP_POLY4_C0_LL, -		filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); +		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));  }  static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6..cf49ba5a54b 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPAPOS,  		.surf = DSPASURF,  		.addr = MRST_DSPABASE, +		.base = MRST_DSPABASE,  		.status = PIPEASTAT,  		.linoff = DSPALINOFF,  		.tileoff = DSPATILEOFF, @@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = {  		.pos = DSPBPOS,  		.surf = DSPBSURF,  		.addr = DSPBBASE, +		.base = DSPBBASE,  		.status = PIPEBSTAT,  		.linoff = DSPBLINOFF,  		.tileoff = DSPBTILEOFF, diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6..463ec6871fe 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = {  	.unlocked_ioctl = drm_ioctl,  	.mmap = i810_mmap_buffers,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d0..48cfcca2b35 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b..914c0dfabe6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)  	spin_lock_init(&dev_priv->irq_lock);  	spin_lock_init(&dev_priv->error_lock);  	spin_lock_init(&dev_priv->rps_lock); +	spin_lock_init(&dev_priv->dpio_lock);  	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))  		dev_priv->num_pipe = 3; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9..5249640cce1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev)  			dev->driver->irq_handler = i8xx_irq_handler;  			dev->driver->irq_uninstall = i8xx_irq_uninstall;  		} else if (INTEL_INFO(dev)->gen == 3) { -			/* IIR "flip pending" means done if this bit is set */ -			I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); -  			dev->driver->irq_preinstall = i915_irq_preinstall;  			dev->driver->irq_postinstall = i915_irq_postinstall;  			dev->driver->irq_uninstall = i915_irq_uninstall; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2dfa6cf4886..bc2ad348e5d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,  	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 +	     && (val & DP_PIPEB_SELECT),  	     "IBX PCH dp port still using transcoder B\n");  } @@ -1388,7 +1389,8 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,  	     "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",  	     reg, pipe_name(pipe)); -	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), +	WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 +	     && (val & SDVO_PIPE_B_SELECT),  	     "IBX PCH hdmi port still using transcoder B\n");  } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426afaa7..ace757af913 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)  			break;  	} -	intel_dp_i2c_init(intel_dp, intel_connector, name); -  	/* Cache some DPCD data in the eDP case */  	if (is_edp(intel_dp)) { -		bool ret;  		struct edp_power_seq	cur, vbt;  		u32 pp_on, pp_off, pp_div; -		struct edid *edid;  		pp_on = I915_READ(PCH_PP_ON_DELAYS);  		pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg)  		DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",  			      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); +	} + +	intel_dp_i2c_init(intel_dp, intel_connector, name); + +	if (is_edp(intel_dp)) { +		bool ret; +		struct edid *edid;  		ironlake_edp_panel_vdd_on(intel_dp);  		ret = intel_dp_get_dpcd(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3df4f5fa892..e019b236986 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv)  	return val;  } -u32 intel_panel_get_max_backlight(struct drm_device *dev) +static u32 _intel_panel_get_max_backlight(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	u32 max;  	max = i915_read_blc_pwm_ctl(dev_priv); -	if (max == 0) { -		/* XXX add code here to query mode clock or hardware clock -		 * and program max PWM appropriately. -		 */ -		pr_warn_once("fixme: max PWM is zero\n"); -		return 1; -	}  	if (HAS_PCH_SPLIT(dev)) {  		max >>= 16; @@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev)  			max *= 0xff;  	} +	return max; +} + +u32 intel_panel_get_max_backlight(struct drm_device *dev) +{ +	u32 max; + +	max = _intel_panel_get_max_backlight(dev); +	if (max == 0) { +		/* XXX add code here to query mode clock or hardware clock +		 * and program max PWM appropriately. +		 */ +		pr_warn_once("fixme: max PWM is zero\n"); +		return 1; +	} +  	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);  	return max;  } @@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW; -	props.max_brightness = intel_panel_get_max_backlight(dev); +	props.max_brightness = _intel_panel_get_max_backlight(dev); +	if (props.max_brightness == 0) { +		DRM_ERROR("Failed to get maximum backlight value\n"); +		return -ENODEV; +	}  	dev_priv->backlight =  		backlight_device_register("intel_backlight",  					  &connector->kdev, dev, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0..ba8a27b1757 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev)  	if (IS_PINEVIEW(dev))  		I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); + +	/* IIR "flip pending" means done if this bit is set */ +	I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE));  }  static void i85x_init_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf288..123afd35761 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		hotplug_mask = intel_sdvo->is_sdvob ?  			SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;  	} -	dev_priv->hotplug_supported_mask |= hotplug_mask;  	drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); @@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))  		goto err; -	/* Set up hotplug command - note paranoia about contents of reply. -	 * We assume that the hardware is in a sane state, and only touch -	 * the bits we think we understand. -	 */ -	intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, -			     &intel_sdvo->hotplug_active, 2); -	intel_sdvo->hotplug_active[0] &= ~0x3; -  	if (intel_sdvo_output_setup(intel_sdvo,  				    intel_sdvo->caps.output_flags) != true) {  		DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", @@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)  		goto err;  	} +	/* Only enable the hotplug irq if we need it, to work around noisy +	 * hotplug lines. +	 */ +	if (intel_sdvo->hotplug_active[0]) +		dev_priv->hotplug_supported_mask |= hotplug_mask; +  	intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);  	/* Set the input timing to the screen. Assume always input 0. */ diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d7997..e5f145d2cb3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = {  	.mmap = mgag200_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.read = drm_read,  }; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf4..7e16dc5e646 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,  	args->size = args->pitch * args->height;  	args->size = roundup(args->size, PAGE_SIZE); -	ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); +	ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo);  	if (ret)  		return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7..f0349053489 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -115,6 +115,9 @@ nv50_gpio_init(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; +	/* initialise gpios and routing to vbios defaults */ +	nouveau_gpio_reset(dev); +  	/* disable, and ack any pending gpio interrupts */  	nv_wr32(dev, 0xe050, 0x00000000);  	nv_wr32(dev, 0xe054, 0xffffffff); diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index dac525b2994..8a2fc89b776 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,  	case OUTPUT_DP:  		if (nv_connector->base.display_info.bpc == 6) {  			nv_encoder->dp.datarate = mode->clock * 18 / 8; -			syncs |= 0x00000140; +			syncs |= 0x00000002 << 6;  		} else {  			nv_encoder->dp.datarate = mode->clock * 24 / 8; -			syncs |= 0x00000180; +			syncs |= 0x00000005 << 6;  		}  		if (nv_encoder->dcb->sorconf.link & 1) diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2817101fb16..e721e3087b9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1479,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)  	}  } +/** + * radeon_get_pll_use_mask - look up a mask of which pplls are in use + * + * @crtc: drm crtc + * + * Returns the mask of which PPLLs (Pixel PLLs) are in use. + */ +static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_crtc *test_crtc; +	struct radeon_crtc *radeon_test_crtc; +	u32 pll_in_use = 0; + +	list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { +		if (crtc == test_crtc) +			continue; + +		radeon_test_crtc = to_radeon_crtc(test_crtc); +		if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +			pll_in_use |= (1 << radeon_test_crtc->pll_id); +	} +	return pll_in_use; +} + +/** + * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is + * also in DP mode.  For DP, a single PPLL can be used for all DP + * crtcs/encoders. + */ +static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) +{ +	struct drm_device *dev = crtc->dev; +	struct drm_encoder *test_encoder; +	struct radeon_crtc *radeon_test_crtc; + +	list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { +		if (test_encoder->crtc && (test_encoder->crtc != crtc)) { +			if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +				/* for DP use the same PLL for all */ +				radeon_test_crtc = to_radeon_crtc(test_encoder->crtc); +				if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) +					return radeon_test_crtc->pll_id; +			} +		} +	} +	return ATOM_PPLL_INVALID; +} + +/** + * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. + * + * @crtc: drm crtc + * + * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors + * a single PPLL can be used for all DP crtcs/encoders.  For non-DP + * monitors a dedicated PPLL must be used.  If a particular board has + * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming + * as there is no need to program the PLL itself.  If we are not able to + * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to + * avoid messing up an existing monitor. + * + * Asic specific PLL information + * + * DCE 6.1 + * - PPLL2 is only available to UNIPHYA (both DP and non-DP) + * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) + * + * DCE 6.0 + * - PPLL0 is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 5.0 + * - DCPLL is available to all UNIPHY (DP only) + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + * DCE 3.0/4.0/4.1 + * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC + * + */  static int radeon_atom_pick_pll(struct drm_crtc *crtc)  {  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);  	struct drm_device *dev = crtc->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct drm_encoder *test_encoder; -	struct drm_crtc *test_crtc; -	uint32_t pll_in_use = 0; +	u32 pll_in_use; +	int pll;  	if (ASIC_IS_DCE61(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { @@ -1498,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				if ((test_radeon_encoder->encoder_id ==  				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && -				    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ +				    (dig->linkb == false)) +					/* UNIPHY A uses PPLL2 */  					return ATOM_PPLL2; +				else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { +					/* UNIPHY B/C/D/E/F */ +					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */ +						return ATOM_PPLL_INVALID; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					} +				} +				break;  			}  		}  		/* UNIPHY B/C/D/E/F */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || -			    (radeon_test_crtc->pll_id == ATOM_PPLL1)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 4)) +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL0)))  			return ATOM_PPLL0; -		return ATOM_PPLL1; +		if (!(pll_in_use & (1 << ATOM_PPLL1))) +			return ATOM_PPLL1; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else if (ASIC_IS_DCE4(rdev)) {  		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {  			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {  				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,  				 * depending on the asic:  				 * DCE4: PPLL or ext clock -				 * DCE5: DCPLL or ext clock +				 * DCE5: PPLL, DCPLL, or ext clock +				 * DCE6: PPLL, PPLL0, or ext clock  				 *  				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip  				 * PPLL/DCPLL programming and only program the DP DTO for the @@ -1531,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)  				 */  				if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {  					if (rdev->clock.dp_extclk) +						/* skip PPLL programming if using ext clock */  						return ATOM_PPLL_INVALID;  					else if (ASIC_IS_DCE6(rdev)) +						/* use PPLL0 for all DP */  						return ATOM_PPLL0;  					else if (ASIC_IS_DCE5(rdev)) +						/* use DCPLL for all DP */  						return ATOM_DCPLL; +					else { +						/* use the same PPLL for all DP monitors */ +						pll = radeon_get_shared_dp_ppll(crtc); +						if (pll != ATOM_PPLL_INVALID) +							return pll; +					}  				} +				break;  			}  		} - -		/* otherwise, pick one of the plls */ -		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { -			struct radeon_crtc *radeon_test_crtc; - -			if (crtc == test_crtc) -				continue; - -			radeon_test_crtc = to_radeon_crtc(test_crtc); -			if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && -			    (radeon_test_crtc->pll_id <= ATOM_PPLL2)) -				pll_in_use |= (1 << radeon_test_crtc->pll_id); -		} -		if (!(pll_in_use & 1)) +		/* all other cases */ +		pll_in_use = radeon_get_pll_use_mask(crtc); +		if (!(pll_in_use & (1 << ATOM_PPLL2))) +			return ATOM_PPLL2; +		if (!(pll_in_use & (1 << ATOM_PPLL1)))  			return ATOM_PPLL1; -		return ATOM_PPLL2; +		DRM_ERROR("unable to allocate a PPLL\n"); +		return ATOM_PPLL_INVALID;  	} else +		/* use PPLL1 or PPLL2 */  		return radeon_crtc->crtc_id;  } @@ -1697,7 +1792,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  		break;  	}  done: -	radeon_crtc->pll_id = -1; +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  }  static const struct drm_crtc_helper_funcs atombios_helper_funcs = { @@ -1746,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,  		else  			radeon_crtc->crtc_offset = 0;  	} -	radeon_crtc->pll_id = -1; +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);  } diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339a..2a59375dbe5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev,   */  void radeon_fence_process(struct radeon_device *rdev, int ring)  { -	uint64_t seq, last_seq; +	uint64_t seq, last_seq, last_emitted;  	unsigned count_loop = 0;  	bool wake = false; @@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring)  	 */  	last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq);  	do { +		last_emitted = rdev->fence_drv[ring].sync_seq[ring];  		seq = radeon_fence_read(rdev, ring);  		seq |= last_seq & 0xffffffff00000000LL;  		if (seq < last_seq) { -			seq += 0x100000000LL; +			seq &= 0xffffffff; +			seq |= last_emitted & 0xffffffff00000000LL;  		} -		if (seq == last_seq) { +		if (seq <= last_seq || seq > last_emitted) {  			break;  		}  		/* If we loop over we don't want to return without diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4..c5a164337bd 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c @@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147..867dc03000e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfa..a7f4d6bd133 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b..9f84128505b 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = {  	.unlocked_ioctl	= drm_ioctl,  	.release = drm_release,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f..af1b914b17e 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = {  	.mmap = drm_mmap,  	.poll = drm_poll,  	.fasync = drm_fasync, +#ifdef CONFIG_COMPAT +	.compat_ioctl = drm_compat_ioctl, +#endif  	.llseek = noop_llseek,  }; diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c570..b71bcd0bfbb 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -12,3 +12,11 @@ config DRM_VMWGFX  	  This is a KMS enabled DRM driver for the VMware SVGA2  	  virtual hardware.  	  The compiled module will be called "vmwgfx.ko". + +config DRM_VMWGFX_FBCON +	depends on DRM_VMWGFX +	bool "Enable framebuffer console under vmwgfx by default" +	help +	   Choose this option if you are shipping a new vmwgfx +	   userspace driver that supports using the kernel driver. + diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01a..ba2c35dbf10 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = {  	{0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},  	{0, 0, 0}  }; +MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); -static int enable_fbdev; +static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON);  static int vmw_probe(struct pci_dev *, const struct pci_device_id *);  static void vmw_master_init(struct vmw_master *); @@ -1154,6 +1155,11 @@ static struct drm_driver driver = {  	.open = vmw_driver_open,  	.preclose = vmw_preclose,  	.postclose = vmw_postclose, + +	.dumb_create = vmw_dumb_create, +	.dumb_map_offset = vmw_dumb_map_offset, +	.dumb_destroy = vmw_dumb_destroy, +  	.fops = &vmwgfx_driver_fops,  	.name = VMWGFX_DRIVER_NAME,  	.desc = VMWGFX_DRIVER_DESC, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee2..29c984ff7f2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv,  int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,  				struct drm_file *file_priv); +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args); + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset); +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle);  /**   * Overlay control - vmwgfx_overlay.c   */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec7..2c6ffe0e2c0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -1917,3 +1917,76 @@ err_ref:  	vmw_resource_unreference(&res);  	return ret;  } + + +int vmw_dumb_create(struct drm_file *file_priv, +		    struct drm_device *dev, +		    struct drm_mode_create_dumb *args) +{ +	struct vmw_private *dev_priv = vmw_priv(dev); +	struct vmw_master *vmaster = vmw_master(file_priv->master); +	struct vmw_user_dma_buffer *vmw_user_bo; +	struct ttm_buffer_object *tmp; +	int ret; + +	args->pitch = args->width * ((args->bpp + 7) / 8); +	args->size = args->pitch * args->height; + +	vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); +	if (vmw_user_bo == NULL) +		return -ENOMEM; + +	ret = ttm_read_lock(&vmaster->lock, true); +	if (ret != 0) { +		kfree(vmw_user_bo); +		return ret; +	} + +	ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, +			      &vmw_vram_sys_placement, true, +			      &vmw_user_dmabuf_destroy); +	if (ret != 0) +		goto out_no_dmabuf; + +	tmp = ttm_bo_reference(&vmw_user_bo->dma.base); +	ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, +				   &vmw_user_bo->base, +				   false, +				   ttm_buffer_type, +				   &vmw_user_dmabuf_release, NULL); +	if (unlikely(ret != 0)) +		goto out_no_base_object; + +	args->handle = vmw_user_bo->base.hash.key; + +out_no_base_object: +	ttm_bo_unref(&tmp); +out_no_dmabuf: +	ttm_read_unlock(&vmaster->lock); +	return ret; +} + +int vmw_dumb_map_offset(struct drm_file *file_priv, +			struct drm_device *dev, uint32_t handle, +			uint64_t *offset) +{ +	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; +	struct vmw_dma_buffer *out_buf; +	int ret; + +	ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); +	if (ret != 0) +		return -EINVAL; + +	*offset = out_buf->base.addr_space_offset; +	vmw_dmabuf_unreference(&out_buf); +	return 0; +} + +int vmw_dumb_destroy(struct drm_file *file_priv, +		     struct drm_device *dev, +		     uint32_t handle) +{ +	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, +					 handle, TTM_REF_USAGE); +} diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a38572..602148299f6 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -69,22 +69,6 @@ struct ina2xx_data {  	u16 regs[INA2XX_MAX_REGISTERS];  }; -int ina2xx_read_word(struct i2c_client *client, int reg) -{ -	int val = i2c_smbus_read_word_data(client, reg); -	if (unlikely(val < 0)) { -		dev_dbg(&client->dev, -			"Failed to read register: %d\n", reg); -		return val; -	} -	return be16_to_cpu(val); -} - -void ina2xx_write_word(struct i2c_client *client, int reg, int data) -{ -	i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); -} -  static struct ina2xx_data *ina2xx_update_device(struct device *dev)  {  	struct i2c_client *client = to_i2c_client(dev); @@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev)  		/* Read all registers */  		for (i = 0; i < data->registers; i++) { -			int rv = ina2xx_read_word(client, i); +			int rv = i2c_smbus_read_word_swapped(client, i);  			if (rv < 0) {  				ret = ERR_PTR(rv);  				goto abort; @@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client,  	switch (data->kind) {  	case ina219:  		/* device configuration */ -		ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); +		i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, +					     INA219_CONFIG_DEFAULT);  		/* set current LSB to 1mA, shunt is in uOhms */  		/* (equation 13 in datasheet) */ -		ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); +		i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, +					     40960000 / shunt);  		dev_info(&client->dev,  			 "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);  		data->registers = INA219_REGISTERS;  		break;  	case ina226:  		/* device configuration */ -		ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); +		i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, +					     INA226_CONFIG_DEFAULT);  		/* set current LSB to 1mA, shunt is in uOhms */  		/* (equation 1 in datasheet)*/ -		ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); +		i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, +					     5120000 / shunt);  		dev_info(&client->dev,  			 "power monitor INA226 (Rshunt = %li uOhm)\n", shunt);  		data->registers = INA226_REGISTERS; diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd009..1a174f0a3cd 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev,  			 struct device_attribute *devattr, char *buf)  {  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); -	struct twl4030_madc_request req; +	struct twl4030_madc_request req = { +		.channels = 1 << attr->index, +		.method = TWL4030_MADC_SW2, +		.type = TWL4030_MADC_WAIT, +	};  	long val; -	req.channels = (1 << attr->index); -	req.method = TWL4030_MADC_SW2; -	req.func_cb = NULL;  	val = twl4030_madc_conversion(&req);  	if (val < 0)  		return val; diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 73133b1063f..6f5f98d69af 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -476,17 +476,17 @@ static int pca_init(struct i2c_adapter *adap)  		/* To avoid integer overflow, use clock/100 for calculations */  		clock = pca_clock(pca_data) / 100; -		if (pca_data->i2c_clock > 10000) { +		if (pca_data->i2c_clock > 1000000) {  			mode = I2C_PCA_MODE_TURBO;  			min_tlow = 14;  			min_thi  = 5;  			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ -		} else if (pca_data->i2c_clock > 4000) { +		} else if (pca_data->i2c_clock > 400000) {  			mode = I2C_PCA_MODE_FASTP;  			min_tlow = 17;  			min_thi  = 9;  			raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ -		} else if (pca_data->i2c_clock > 1000) { +		} else if (pca_data->i2c_clock > 100000) {  			mode = I2C_PCA_MODE_FAST;  			min_tlow = 44;  			min_thi  = 20; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd672..970a1612e79 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -104,6 +104,7 @@ config I2C_I801  	    DH89xxCC (PCH)  	    Panther Point (PCH)  	    Lynx Point (PCH) +	    Lynx Point-LP (PCH)  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-i801. @@ -354,9 +355,13 @@ config I2C_DAVINCI  	  devices such as DaVinci NIC.  	  For details please see http://www.ti.com/davinci +config I2C_DESIGNWARE_CORE +	tristate +  config I2C_DESIGNWARE_PLATFORM  	tristate "Synopsys DesignWare Platform"  	depends on HAVE_CLK +	select I2C_DESIGNWARE_CORE  	help  	  If you say yes to this option, support will be included for the  	  Synopsys DesignWare I2C adapter. Only master mode is supported. @@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM  config I2C_DESIGNWARE_PCI  	tristate "Synopsys DesignWare PCI"  	depends on PCI +	select I2C_DESIGNWARE_CORE  	help  	  If you say yes to this option, support will be included for the  	  Synopsys DesignWare I2C adapter. Only master mode is supported. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb4..37c4182cc98 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o  obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o  obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o  obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o +obj-$(CONFIG_I2C_DESIGNWARE_CORE)	+= i2c-designware-core.o  obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM)	+= i2c-designware-platform.o -i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o +i2c-designware-platform-objs := i2c-designware-platdrv.o  obj-$(CONFIG_I2C_DESIGNWARE_PCI)	+= i2c-designware-pci.o -i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o +i2c-designware-pci-objs := i2c-designware-pcidrv.o  obj-$(CONFIG_I2C_EG20T)		+= i2c-eg20t.o  obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o  obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80ed..7b8ebbefb58 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -25,6 +25,7 @@   * ----------------------------------------------------------------------------   *   */ +#include <linux/export.h>  #include <linux/clk.h>  #include <linux/errno.h>  #include <linux/err.h> @@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	dw_writel(dev, dev->master_cfg , DW_IC_CON);  	return 0;  } +EXPORT_SYMBOL_GPL(i2c_dw_init);  /*   * Waiting for bus not busy @@ -568,12 +570,14 @@ done:  	return ret;  } +EXPORT_SYMBOL_GPL(i2c_dw_xfer);  u32 i2c_dw_func(struct i2c_adapter *adap)  {  	struct dw_i2c_dev *dev = i2c_get_adapdata(adap);  	return dev->functionality;  } +EXPORT_SYMBOL_GPL(i2c_dw_func);  static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)  { @@ -678,17 +682,20 @@ tx_aborted:  	return IRQ_HANDLED;  } +EXPORT_SYMBOL_GPL(i2c_dw_isr);  void i2c_dw_enable(struct dw_i2c_dev *dev)  {         /* Enable the adapter */  	dw_writel(dev, 1, DW_IC_ENABLE);  } +EXPORT_SYMBOL_GPL(i2c_dw_enable);  u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev)  {  	return dw_readl(dev, DW_IC_ENABLE);  } +EXPORT_SYMBOL_GPL(i2c_dw_is_enabled);  void i2c_dw_disable(struct dw_i2c_dev *dev)  { @@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev)  	dw_writel(dev, 0, DW_IC_INTR_MASK);  	dw_readl(dev, DW_IC_CLR_INTR);  } +EXPORT_SYMBOL_GPL(i2c_dw_disable);  void i2c_dw_clear_int(struct dw_i2c_dev *dev)  {  	dw_readl(dev, DW_IC_CLR_INTR);  } +EXPORT_SYMBOL_GPL(i2c_dw_clear_int);  void i2c_dw_disable_int(struct dw_i2c_dev *dev)  {  	dw_writel(dev, 0, DW_IC_INTR_MASK);  } +EXPORT_SYMBOL_GPL(i2c_dw_disable_int);  u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev)  {  	return dw_readl(dev, DW_IC_COMP_PARAM_1);  } +EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ad..33e9b0c09af 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -52,6 +52,7 @@    DH89xxCC (PCH)        0x2330     32     hard     yes     yes     yes    Panther Point (PCH)   0x1e22     32     hard     yes     yes     yes    Lynx Point (PCH)      0x8c22     32     hard     yes     yes     yes +  Lynx Point-LP (PCH)   0x9c22     32     hard     yes     yes     yes    Features supported by this driver:    Software PEC                     no @@ -155,6 +156,7 @@  #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS	0x2330  #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30  #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS	0x8c22 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS	0x9c22  struct i801_priv {  	struct i2c_adapter adapter; @@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) },  	{ 0, }  }; diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17..51f05b8520e 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)  	struct device_node *node = dev->of_node;  	int ret; -	if (!node) -		return -EINVAL; - -	i2c->speed = &mxs_i2c_95kHz_config;  	ret = of_property_read_u32(node, "clock-frequency", &speed);  	if (ret)  		dev_warn(dev, "No I2C speed selected, using 100kHz\n"); @@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)  		return err;  	i2c->dev = dev; +	i2c->speed = &mxs_i2c_95kHz_config; -	err = mxs_i2c_get_ofdata(i2c); -	if (err) -		return err; +	if (dev->of_node) { +		err = mxs_i2c_get_ofdata(i2c); +		if (err) +			return err; +	}  	platform_set_drvdata(pdev, i2c); diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b..8488bddfe46 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -48,8 +48,9 @@ enum {  	mcntrl_afie = 0x00000002,  	mcntrl_naie = 0x00000004,  	mcntrl_drmie = 0x00000008, -	mcntrl_daie = 0x00000020, -	mcntrl_rffie = 0x00000040, +	mcntrl_drsie = 0x00000010, +	mcntrl_rffie = 0x00000020, +	mcntrl_daie = 0x00000040,  	mcntrl_tffie = 0x00000080,  	mcntrl_reset = 0x00000100,  	mcntrl_cdbmode = 0x00000400, @@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)  	 * or we didn't 'ask' for it yet.  	 */  	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { -		dev_dbg(&alg_data->adapter.dev, -			"%s(): Write dummy data to fill Rx-fifo...\n", -			__func__); +		/* 'Asking' is done asynchronously, e.g. dummy TX of several +		 * bytes is done before the first actual RX arrives in FIFO. +		 * Therefore, ordered bytes (via TX) are counted separately. +		 */ +		if (alg_data->mif.order) { +			dev_dbg(&alg_data->adapter.dev, +				"%s(): Write dummy data to fill Rx-fifo...\n", +				__func__); -		if (alg_data->mif.len == 1) { -			/* Last byte, do not acknowledge next rcv. */ -			val |= stop_bit; +			if (alg_data->mif.order == 1) { +				/* Last byte, do not acknowledge next rcv. */ +				val |= stop_bit; + +				/* +				 * Enable interrupt RFDAIE (data in Rx fifo), +				 * and disable DRMIE (need data for Tx) +				 */ +				ctl = ioread32(I2C_REG_CTL(alg_data)); +				ctl |= mcntrl_rffie | mcntrl_daie; +				ctl &= ~mcntrl_drmie; +				iowrite32(ctl, I2C_REG_CTL(alg_data)); +			}  			/* -			 * Enable interrupt RFDAIE (data in Rx fifo), -			 * and disable DRMIE (need data for Tx) +			 * Now we'll 'ask' for data: +			 * For each byte we want to receive, we must +			 * write a (dummy) byte to the Tx-FIFO.  			 */ -			ctl = ioread32(I2C_REG_CTL(alg_data)); -			ctl |= mcntrl_rffie | mcntrl_daie; -			ctl &= ~mcntrl_drmie; -			iowrite32(ctl, I2C_REG_CTL(alg_data)); +			iowrite32(val, I2C_REG_TX(alg_data)); +			alg_data->mif.order--;  		} - -		/* -		 * Now we'll 'ask' for data: -		 * For each byte we want to receive, we must -		 * write a (dummy) byte to the Tx-FIFO. -		 */ -		iowrite32(val, I2C_REG_TX(alg_data)); -  		return 0;  	} @@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		alg_data->mif.buf = pmsg->buf;  		alg_data->mif.len = pmsg->len; +		alg_data->mif.order = pmsg->len;  		alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?  			I2C_SMBUS_READ : I2C_SMBUS_WRITE;  		alg_data->mif.ret = 0; @@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	/* Cleanup to be sure... */  	alg_data->mif.buf = NULL;  	alg_data->mif.len = 0; +	alg_data->mif.order = 0;  	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",  		__func__, ioread32(I2C_REG_STS(alg_data))); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2..2091ae8f539 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev)  }  /* + * This function is only needed for mutex_lock_nested, so it is never + * called unless locking correctness checking is enabled. Thus we + * make it inline to avoid a compiler warning. That's what gcc ends up + * doing anyway. + */ +static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) +{ +	unsigned int depth = 0; + +	while ((adapter = i2c_parent_is_i2c_adapter(adapter))) +		depth++; + +	return depth; +} + +/*   * Let users instantiate I2C devices through sysfs. This can be used when   * platform initialization code doesn't contain the proper data for   * whatever reason. Also useful for drivers that do device detection and @@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,  	/* Make sure the device was added through sysfs */  	res = -ENOENT; -	mutex_lock(&adap->userspace_clients_lock); +	mutex_lock_nested(&adap->userspace_clients_lock, +			  i2c_adapter_depth(adap));  	list_for_each_entry_safe(client, next, &adap->userspace_clients,  				 detected) {  		if (client->addr == addr) { @@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)  		return res;  	/* Remove devices instantiated from sysfs */ -	mutex_lock(&adap->userspace_clients_lock); +	mutex_lock_nested(&adap->userspace_clients_lock, +			  i2c_adapter_depth(adap));  	list_for_each_entry_safe(client, next, &adap->userspace_clients,  				 detected) {  		dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a0237..3bd5540238a 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -617,7 +617,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev)  	st->adc_clk = clk_get(&pdev->dev, "adc_op_clk");  	if (IS_ERR(st->adc_clk)) {  		dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); -		ret = PTR_ERR(st->clk); +		ret = PTR_ERR(st->adc_clk);  		goto error_disable_clk;  	} diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index fa6ca473372..dceaec821b0 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&fc->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		modehdlc(bch, ISDN_P_NONE);  		spin_unlock_irqrestore(&fc->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e79..f02794203bb 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,  				printk(KERN_INFO  				       "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",  				       E1_cnt + 1, pt); +				kfree(hc);  				return -EINVAL;  			}  			maskcheck |= hc->bmask[pt]; @@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,  	if ((poll >> 1) > sizeof(hc->silence_data)) {  		printk(KERN_ERR "HFCMULTI error: silence_data too small, "  		       "please fix\n"); +		kfree(hc);  		return -EINVAL;  	}  	for (i = 0; i < (poll >> 1); i++) diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591..ccd7d851be2 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(hx->ip->hwlock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		hscx_mode(hx, ISDN_P_NONE);  		spin_unlock_irqrestore(hx->ip->hwlock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d..182ecf0626c 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(ich->is->hwlock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		modeisar(ich, ISDN_P_NONE);  		spin_unlock_irqrestore(ich->is->hwlock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index c3e3e768627..9bcade59eb7 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&card->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		mode_tiger(bc, ISDN_P_NONE);  		spin_unlock_irqrestore(&card->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 26a86b84609..335fe645500 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)  	switch (cmd) {  	case CLOSE_CHANNEL:  		test_and_clear_bit(FLG_OPEN, &bch->Flags); +		cancel_work_sync(&bch->workq);  		spin_lock_irqsave(&card->lock, flags); -		mISDN_freebchannel(bch); +		mISDN_clear_bchannel(bch);  		w6692_mode(bc, ISDN_P_NONE);  		spin_unlock_irqrestore(&card->lock, flags);  		ch->protocol = ISDN_P_NONE; diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ef34fd40867..2602be23f34 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c @@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch)  	ch->next_minlen = ch->init_minlen;  	ch->maxlen = ch->init_maxlen;  	ch->next_maxlen = ch->init_maxlen; +	skb_queue_purge(&ch->rqueue); +	ch->rcount = 0;  }  EXPORT_SYMBOL(mISDN_clear_bchannel); -int +void  mISDN_freebchannel(struct bchannel *ch)  { +	cancel_work_sync(&ch->workq);  	mISDN_clear_bchannel(ch); -	skb_queue_purge(&ch->rqueue); -	ch->rcount = 0; -	flush_work_sync(&ch->workq); -	return 0;  }  EXPORT_SYMBOL(mISDN_freebchannel); diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index b67a3018b13..ce229ea933d 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip,  	ret =  	    mfd_add_devices(chip->dev, 0, &onkey_devs[0], -			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0); +			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0, +			    NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add onkey subdev\n");  		goto out_dev; @@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip,  		rtc_devs[0].platform_data = pdata->rtc;  		rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata);  		ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], -				      ARRAY_SIZE(rtc_devs), NULL, 0); +				      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add rtc subdev\n");  			goto out_dev; diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 6146583589f..c20a31136f0 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c @@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip)  	}  	ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], -			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0); +			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0, +			      NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add codec subdev\n");  		goto out_codec; diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index d09918cf1b1..b73f033b2c6 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip,  			bk_devs[i].resources = &bk_resources[j];  			ret = mfd_add_devices(chip->dev, 0,  					      &bk_devs[i], 1, -					      &bk_resources[j], 0); +					      &bk_resources[j], 0, NULL);  			if (ret < 0) {  				dev_err(chip->dev, "Failed to add "  					"backlight subdev\n"); @@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip,  			led_devs[i].resources = &led_resources[j],  			ret = mfd_add_devices(chip->dev, 0,  					      &led_devs[i], 1, -					      &led_resources[j], 0); +					      &led_resources[j], 0, NULL);  			if (ret < 0) {  				dev_err(chip->dev, "Failed to add "  					"led subdev\n"); @@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip,  		regulator_devs[i].resources = ®ulator_resources[seq];  		ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, -				      ®ulator_resources[seq], 0); +				      ®ulator_resources[seq], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add regulator subdev\n");  			goto out; @@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip,  	rtc_devs[0].resources = &rtc_resources[0];  	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],  			      ARRAY_SIZE(rtc_devs), &rtc_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add rtc subdev\n");  } @@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip,  	touch_devs[0].resources = &touch_resources[0];  	ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],  			      ARRAY_SIZE(touch_devs), &touch_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add touch subdev\n");  } @@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[0].num_resources = ARRAY_SIZE(battery_resources);  	power_devs[0].resources = &battery_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, -			      &battery_resources[0], chip->irq_base); +			      &battery_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add battery subdev\n"); @@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[1].num_resources = ARRAY_SIZE(charger_resources);  	power_devs[1].resources = &charger_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, -			      &charger_resources[0], chip->irq_base); +			      &charger_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add charger subdev\n"); @@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,  	power_devs[2].num_resources = ARRAY_SIZE(preg_resources);  	power_devs[2].resources = &preg_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, -			      &preg_resources[0], chip->irq_base); +			      &preg_resources[0], chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add preg subdev\n");  } @@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip,  	onkey_devs[0].resources = &onkey_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],  			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], -			      chip->irq_base); +			      chip->irq_base, NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add onkey subdev\n");  } @@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip,  	codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);  	codec_devs[0].resources = &codec_resources[0],  	ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], -			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0); +			      ARRAY_SIZE(codec_devs), &codec_resources[0], 0, +			      NULL);  	if (ret < 0)  		dev_err(chip->dev, "Failed to add codec subdev\n");  } diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 44a3fdbadef..f1beb4971f8 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c @@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, -			      ARRAY_SIZE(aat2870_devs), NULL, 0); +			      ARRAY_SIZE(aat2870_devs), NULL, 0, NULL);  	if (ret != 0) {  		dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret);  		goto out_disable; diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 78fca2902c8..01781ae5d0d 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,  	}  	err = mfd_add_devices(&client->dev, 0, ab3100_devs, -		ARRAY_SIZE(ab3100_devs), NULL, 0); +			      ARRAY_SIZE(ab3100_devs), NULL, 0, NULL);  	ab3100_setup_debugfs(ab3100); diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 626b4ecaf64..47adf800024 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev)  	ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,  			ARRAY_SIZE(abx500_common_devs), NULL, -			ab8500->irq_base); +			ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq;  	if (is_ab9540(ab8500))  		ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,  				ARRAY_SIZE(ab9540_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	else  		ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,  				ARRAY_SIZE(ab8500_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq;  	if (is_ab9540(ab8500) || is_ab8505(ab8500))  		ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs,  				ARRAY_SIZE(ab9540_ab8505_devs), NULL, -				ab8500->irq_base); +				ab8500->irq_base, ab8500->domain);  	if (ret)  		goto out_freeirq; @@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev)  		/* Add battery management devices */  		ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,  				      ARRAY_SIZE(ab8500_bm_devs), NULL, -				      ab8500->irq_base); +				      ab8500->irq_base, ab8500->domain);  		if (ret)  			dev_err(ab8500->dev, "error adding bm devices\n");  	} diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c7983e86254..1b48f209480 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)  	}  	ret = mfd_add_devices(arizona->dev, -1, early_devs, -			      ARRAY_SIZE(early_devs), NULL, 0); +			      ARRAY_SIZE(early_devs), NULL, 0, NULL);  	if (ret != 0) {  		dev_err(dev, "Failed to add early children: %d\n", ret);  		return ret; @@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona)  	switch (arizona->type) {  	case WM5102:  		ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, -				      ARRAY_SIZE(wm5102_devs), NULL, 0); +				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);  		break;  	case WM5110:  		ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, -				      ARRAY_SIZE(wm5102_devs), NULL, 0); +				      ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);  		break;  	} diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 683e18a2332..62f0883a763 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -913,14 +913,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,  	if (pdata->clock_rate) {  		ds1wm_pdata.clock_rate = pdata->clock_rate;  		ret = mfd_add_devices(&pdev->dev, pdev->id, -			&asic3_cell_ds1wm, 1, mem, asic->irq_base); +			&asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL);  		if (ret < 0)  			goto out;  	}  	if (mem_sdio && (irq >= 0)) {  		ret = mfd_add_devices(&pdev->dev, pdev->id, -			&asic3_cell_mmc, 1, mem_sdio, irq); +			&asic3_cell_mmc, 1, mem_sdio, irq, NULL);  		if (ret < 0)  			goto out;  	} @@ -934,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,  			asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);  		}  		ret = mfd_add_devices(&pdev->dev, 0, -			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); +			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL);  	}   out: diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 3419e726de4..2b282133c72 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c @@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,  	}  	err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, -			ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); +			      ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL);  	if (err) {  		dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);  		goto err_disable; diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 2544910e1fd..a0a62b24621 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)  		dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);  	ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, -			      ARRAY_SIZE(da9052_subdev_info), NULL, 0); +			      ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL);  	if (ret)  		goto err; diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 4e2af2cb2d2..45e83a68641 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)  	cell->pdata_size = sizeof(*davinci_vc);  	ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, -			      DAVINCI_VC_CELLS, NULL, 0); +			      DAVINCI_VC_CELLS, NULL, 0, NULL);  	if (ret != 0) {  		dev_err(&pdev->dev, "fail to register client devices\n");  		goto fail4; diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a008113..0e63cdd9b52 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -3010,7 +3010,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)  		prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);  	err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, -			ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); +			      ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);  	if (err) {  		pr_err("prcmu: Failed to add subdevices\n");  		return err; diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 04c7093d649..9e5453d21a6 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c @@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev)  		/* the first 5 PASIC3 registers control the DS1WM */  		ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;  		ret = mfd_add_devices(&pdev->dev, pdev->id, -				&ds1wm_cell, 1, r, irq); +				      &ds1wm_cell, 1, r, irq, NULL);  		if (ret < 0)  			dev_warn(dev, "failed to register DS1WM\n");  	} @@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev)  	if (pdata && pdata->led_pdata) {  		led_cell.platform_data = pdata->led_pdata;  		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); +		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, +				      0, NULL);  		if (ret < 0)  			dev_warn(dev, "failed to register LED device\n");  	} diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 59df5584cb5..266bdc5bd96 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c @@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic)  			continue;  		ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, -				      pdata->irq[i]); +				      pdata->irq[i], NULL);  		if (ret)  			goto fail;  	}  	ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, -			      ARRAY_SIZE(msic_other_devs), NULL, 0); +			      ARRAY_SIZE(msic_other_devs), NULL, 0, NULL);  	if (ret)  		goto fail; diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 2ea99989551..965c4801df8 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c @@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv)  	}  	return mfd_add_devices(&pdev->dev, 0, priv->cells, -			       num_probed, NULL, pdev->irq); +			       num_probed, NULL, pdev->irq, NULL);  }  /* diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 87662a17dec..c6b6d7dda51 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c @@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)  	writeb(0xff, adc->base + JZ_REG_ADC_CTRL);  	ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, -		ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); +			      ARRAY_SIZE(jz4740_adc_cells), mem_base, +			      irq_base, NULL);  	if (ret < 0)  		goto err_clk_put; diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0b2879b87fd..24212f45b20 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c @@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)  	lm3533_als_devs[0].platform_data = pdata->als;  	lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); -	ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); +	ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, +			      0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add ALS device\n");  		return ret; @@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)  	}  	ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, -					pdata->num_backlights, NULL, 0); +			      pdata->num_backlights, NULL, 0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add backlight devices\n");  		return ret; @@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)  	}  	ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, -						pdata->num_leds, NULL, 0); +			      pdata->num_leds, NULL, 0, NULL);  	if (ret) {  		dev_err(lm3533->dev, "failed to add LED devices\n");  		return ret; diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 027cc8f8613..092ad4b44b6 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -750,7 +750,7 @@ gpe0_done:  	lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);  	ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], -				1, NULL, 0); +			      1, NULL, 0, NULL);  gpio_done:  	if (acpi_conflict) @@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  	u32 base_addr_cfg;  	u32 base_addr;  	int ret; -	bool acpi_conflict = false;  	struct resource *res;  	/* Setup power management base register */ @@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  	res = wdt_io_res(ICH_RES_IO_TCO);  	res->start = base_addr + ACPIBASE_TCO_OFF;  	res->end = base_addr + ACPIBASE_TCO_END; -	ret = acpi_check_resource_conflict(res); -	if (ret) { -		acpi_conflict = true; -		goto wdt_done; -	}  	res = wdt_io_res(ICH_RES_IO_SMI);  	res->start = base_addr + ACPIBASE_SMI_OFF;  	res->end = base_addr + ACPIBASE_SMI_END; -	ret = acpi_check_resource_conflict(res); -	if (ret) { -		acpi_conflict = true; -		goto wdt_done; -	} +  	lpc_ich_enable_acpi_space(dev);  	/* @@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,  		res = wdt_mem_res(ICH_RES_MEM_GCS);  		res->start = base_addr + ACPIBASE_GCS_OFF;  		res->end = base_addr + ACPIBASE_GCS_END; -		ret = acpi_check_resource_conflict(res); -		if (ret) { -			acpi_conflict = true; -			goto wdt_done; -		}  	}  	lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id);  	ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], -				1, NULL, 0); +			      1, NULL, 0, NULL);  wdt_done: -	if (acpi_conflict) -		pr_warn("Resource conflict(s) found affecting %s\n", -				lpc_ich_cells[LPC_WDT].name);  	return ret;  } diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 9f20abc5e39..f6b9c5c96b2 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c @@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,  		lpc_sch_cells[i].id = id->device;  	ret = mfd_add_devices(&dev->dev, 0, -			lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); +			      lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, +			      0, NULL);  	if (ret)  		goto out_dev; @@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,  			tunnelcreek_cells[i].id = id->device;  		ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, -			ARRAY_SIZE(tunnelcreek_cells), NULL, 0); +				      ARRAY_SIZE(tunnelcreek_cells), NULL, +				      0, NULL);  	}  	return ret; diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index c03e12b5192..d9e24c849a0 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,  	max77686_irq_init(max77686);  	ret = mfd_add_devices(max77686->dev, -1, max77686_devs, -			      ARRAY_SIZE(max77686_devs), NULL, 0); +			      ARRAY_SIZE(max77686_devs), NULL, 0, NULL);  	if (ret < 0)  		goto err_mfd; diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 2b403569e0a..1029d018c73 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c @@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data)  	const struct max77693_irq_data *irq_data =  				irq_to_max77693_irq(max77693, data->irq); +	if (irq_data->group >= MAX77693_IRQ_GROUP_NR) +		return; +  	if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)  		max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;  	else @@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data)  	const struct max77693_irq_data *irq_data =  	    irq_to_max77693_irq(max77693, data->irq); +	if (irq_data->group >= MAX77693_IRQ_GROUP_NR) +		return; +  	if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)  		max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;  	else @@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data)  	if (irq_src & MAX77693_IRQSRC_MUIC)  		/* MUIC INT1 ~ INT3 */ -		max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, +		max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,  			MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);  	/* Apply masking */ @@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693)  {  	struct irq_domain *domain;  	int i; -	int ret; +	int ret = 0; +	u8 intsrc_mask;  	mutex_init(&max77693->irqlock); @@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693)  					&max77693_irq_domain_ops, max77693);  	if (!domain) {  		dev_err(max77693->dev, "could not create irq domain\n"); -		return -ENODEV; +		ret = -ENODEV; +		goto err_irq;  	}  	max77693->irq_domain = domain; +	/* Unmask max77693 interrupt */ +	ret = max77693_read_reg(max77693->regmap, +			MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); +	if (ret < 0) { +		dev_err(max77693->dev, "fail to read PMIC register\n"); +		goto err_irq; +	} + +	intsrc_mask &= ~(MAX77693_IRQSRC_CHG); +	intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); +	intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); +	ret = max77693_write_reg(max77693->regmap, +			MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); +	if (ret < 0) { +		dev_err(max77693->dev, "fail to write PMIC register\n"); +		goto err_irq; +	} +  	ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,  				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,  				   "max77693-irq", max77693); -  	if (ret)  		dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",  			max77693->irq, ret); -	return 0; +err_irq: +	return ret;  }  void max77693_irq_exit(struct max77693_dev *max77693) diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a1811cb50ec..cc5155e2049 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  	max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);  	i2c_set_clientdata(max77693->haptic, max77693); +	/* +	 * Initialize register map for MUIC device because use regmap-muic +	 * instance of MUIC device when irq of max77693 is initialized +	 * before call max77693-muic probe() function. +	 */ +	max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, +					 &max77693_regmap_config); +	if (IS_ERR(max77693->regmap_muic)) { +		ret = PTR_ERR(max77693->regmap_muic); +		dev_err(max77693->dev, +			"failed to allocate register map: %d\n", ret); +		goto err_regmap; +	} +  	ret = max77693_irq_init(max77693);  	if (ret < 0)  		goto err_irq; @@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,  	pm_runtime_set_active(max77693->dev);  	ret = mfd_add_devices(max77693->dev, -1, max77693_devs, -			ARRAY_SIZE(max77693_devs), NULL, 0); +			      ARRAY_SIZE(max77693_devs), NULL, 0, NULL);  	if (ret < 0)  		goto err_mfd; diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 825a7f06d9b..ee53757beca 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],  			      ARRAY_SIZE(rtc_devs), -			      &rtc_resources[0], chip->irq_base); +			      &rtc_resources[0], chip->irq_base, NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add rtc subdev\n");  		goto out; @@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],  			      ARRAY_SIZE(onkey_devs), -			      &onkey_resources[0], 0); +			      &onkey_resources[0], 0, NULL);  	if (ret < 0) {  		dev_err(chip->dev, "Failed to add onkey subdev\n");  		goto out_dev; @@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata) {  		ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0],  				      ARRAY_SIZE(regulator_devs), -				      ®ulator_resources[0], 0); +				      ®ulator_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add regulator subdev\n");  			goto out_dev; @@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->backlight) {  		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],  				      ARRAY_SIZE(backlight_devs), -				      &backlight_resources[0], 0); +				      &backlight_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add backlight subdev\n");  			goto out_dev; @@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->power) {  		ret = mfd_add_devices(chip->dev, 0, &power_devs[0],  					ARRAY_SIZE(power_devs), -					&power_supply_resources[0], 0); +				      &power_supply_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add power supply "  				"subdev\n"); @@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip,  	if (pdata && pdata->touch) {  		ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],  				      ARRAY_SIZE(touch_devs), -				      &touch_resources[0], 0); +				      &touch_resources[0], 0, NULL);  		if (ret < 0) {  			dev_err(chip->dev, "Failed to add touch subdev\n");  			goto out_dev; diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 10b629c245b..f123517065e 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c,  	mfd_add_devices(max8997->dev, -1, max8997_devs,  			ARRAY_SIZE(max8997_devs), -			NULL, 0); +			NULL, 0, NULL);  	/*  	 * TODO: enable others (flash, muic, rtc, battery, ...) and diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 6ef56d28c05..d7218cc9094 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c,  	switch (id->driver_data) {  	case TYPE_LP3974:  		ret = mfd_add_devices(max8998->dev, -1, -				lp3974_devs, ARRAY_SIZE(lp3974_devs), -				NULL, 0); +				      lp3974_devs, ARRAY_SIZE(lp3974_devs), +				      NULL, 0, NULL);  		break;  	case TYPE_MAX8998:  		ret = mfd_add_devices(max8998->dev, -1, -				max8998_devs, ARRAY_SIZE(max8998_devs), -				NULL, 0); +				      max8998_devs, ARRAY_SIZE(max8998_devs), +				      NULL, 0, NULL);  		break;  	default:  		ret = -EINVAL; diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index b801dc72f04..1ec79b54bd2 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,  	if (!cell.name)  		return -ENOMEM; -	return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); +	return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL);  }  static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0c3a01cde2f..f8b77711ad2 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev,  static int mfd_add_device(struct device *parent, int id,  			  const struct mfd_cell *cell,  			  struct resource *mem_base, -			  int irq_base) +			  int irq_base, struct irq_domain *domain)  {  	struct resource *res;  	struct platform_device *pdev;  	struct device_node *np = NULL; -	struct irq_domain *domain = NULL;  	int ret = -ENOMEM;  	int r; @@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id,  		for_each_child_of_node(parent->of_node, np) {  			if (of_device_is_compatible(np, cell->of_compatible)) {  				pdev->dev.of_node = np; -				domain = irq_find_host(parent->of_node);  				break;  			}  		} @@ -177,7 +175,7 @@ fail_alloc:  int mfd_add_devices(struct device *parent, int id,  		    struct mfd_cell *cells, int n_devs,  		    struct resource *mem_base, -		    int irq_base) +		    int irq_base, struct irq_domain *domain)  {  	int i;  	int ret = 0; @@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id,  	for (i = 0; i < n_devs; i++) {  		atomic_set(&cnts[i], 0);  		cells[i].usage_count = &cnts[i]; -		ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); +		ret = mfd_add_device(parent, id, cells + i, mem_base, +				     irq_base, domain);  		if (ret)  			break;  	} @@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)  	for (i = 0; i < n_clones; i++) {  		cell_entry.name = clones[i];  		/* don't give up if a single call fails; just report error */ -		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) +		if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0, +				   NULL))  			dev_err(dev, "failed to create platform device '%s'\n",  					clones[i]);  	} diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c4a69f193a1..a345f9bb7b4 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(palmas->dev, -1,  			      children, ARRAY_SIZE(palmas_children), -			      NULL, regmap_irq_chip_get_base(palmas->irq_data)); +			      NULL, regmap_irq_chip_get_base(palmas->irq_data), +			      NULL);  	kfree(children);  	if (ret < 0) diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index cdc1df7fa0e..3a8fa88567b 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,  	}  	ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, -			ARRAY_SIZE(rc5t583_subdevs), NULL, 0); +			      ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL);  	if (ret) {  		dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret);  		goto err_add_devs; diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 685d61e431a..0f70dce6116 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c @@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,  	rdc321x_wdt_pdata.sb_pdev = pdev;  	return mfd_add_devices(&pdev->dev, -1, -		rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); +			       rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), +			       NULL, 0, NULL);  }  static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 2988efde11e..49d361a618d 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c,  	switch (sec_pmic->device_type) {  	case S5M8751X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, -					ARRAY_SIZE(s5m8751_devs), NULL, 0); +				      ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL);  		break;  	case S5M8763X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, -					ARRAY_SIZE(s5m8763_devs), NULL, 0); +				      ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL);  		break;  	case S5M8767X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, -					ARRAY_SIZE(s5m8767_devs), NULL, 0); +				      ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);  		break;  	case S2MPS11X:  		ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, -					ARRAY_SIZE(s2mps11_devs), NULL, 0); +				      ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);  		break;  	default:  		/* If this happens the probe function is problem */ diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index d31fed07aef..d35da6820be 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c @@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,  			      sta2x11_mfd_bar0,  			      ARRAY_SIZE(sta2x11_mfd_bar0),  			      &pdev->resource[0], -			      0); +			      0, NULL);  	if (err) {  		dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err);  		goto err_disable; @@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,  			      sta2x11_mfd_bar1,  			      ARRAY_SIZE(sta2x11_mfd_bar1),  			      &pdev->resource[1], -			      0); +			      0, NULL);  	if (err) {  		dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err);  		goto err_disable; diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2dd8d49cb30..c94f521f392 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe,  				      struct mfd_cell *cell, int irq)  {  	return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, -			       NULL, stmpe->irq_base + irq); +			       NULL, stmpe->irq_base + irq, NULL);  }  static int __devinit stmpe_devices_init(struct stmpe *stmpe) diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 2d9e8799e73..b32940ec903 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev)  	ret = mfd_add_devices(&dev->dev, dev->id,  			      t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), -			      iomem, t7l66xb->irq_base); +			      iomem, t7l66xb->irq_base, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 048bf0532a0..b56ba6b4329 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)  	if (blocks & TC3589x_BLOCK_GPIO) {  		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, -				ARRAY_SIZE(tc3589x_dev_gpio), NULL, -				tc3589x->irq_base); +				      ARRAY_SIZE(tc3589x_dev_gpio), NULL, +				      tc3589x->irq_base, NULL);  		if (ret) {  			dev_err(tc3589x->dev, "failed to add gpio child\n");  			return ret; @@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)  	if (blocks & TC3589x_BLOCK_KEYPAD) {  		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, -				ARRAY_SIZE(tc3589x_dev_keypad), NULL, -				tc3589x->irq_base); +				      ARRAY_SIZE(tc3589x_dev_keypad), NULL, +				      tc3589x->irq_base, NULL);  		if (ret) {  			dev_err(tc3589x->dev, "failed to keypad child\n");  			return ret; diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index d20a284ad4b..413c891102f 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c @@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev)  	printk(KERN_INFO "Toshiba tc6387xb initialised\n");  	ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, -			      ARRAY_SIZE(tc6387xb_cells), iomem, irq); +			      ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 9612264f0e6..dcab026fcbb 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)  	tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);  	ret = mfd_add_devices(&dev->dev, dev->id, -			tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), -			iomem, tcpd->irq_base); +			      tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), +			      iomem, tcpd->irq_base, NULL);  	if (!ret)  		return 0; diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index 4fb0e6c8e8f..7c3675a74f9 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c @@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev)  		cells[id].data_size	= data->pdata_size;  	} -	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); +	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL);  	if (error < 0) {  		dev_err(dev, "cannot add mfd cells\n");  		goto error_enable; diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index a447f4ec11f..cccc626c83c 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev,  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg0,  			ARRAY_SIZE(timberdale_cells_bar0_cfg0), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER1:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg1,  			ARRAY_SIZE(timberdale_cells_bar0_cfg1), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER2:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg2,  			ARRAY_SIZE(timberdale_cells_bar0_cfg2), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	case TIMB_HW_VER3:  		err = mfd_add_devices(&dev->dev, -1,  			timberdale_cells_bar0_cfg3,  			ARRAY_SIZE(timberdale_cells_bar0_cfg3), -			&dev->resource[0], msix_entries[0].vector); +			&dev->resource[0], msix_entries[0].vector, NULL);  		break;  	default:  		dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", @@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev,  	err = mfd_add_devices(&dev->dev, 0,  		timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), -		&dev->resource[1], msix_entries[0].vector); +		&dev->resource[1], msix_entries[0].vector, NULL);  	if (err) {  		dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);  		goto err_mfd2; @@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev,  		((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) {  		err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2,  			ARRAY_SIZE(timberdale_cells_bar2), -			&dev->resource[2], msix_entries[0].vector); +			&dev->resource[2], msix_entries[0].vector, NULL);  		if (err) {  			dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err);  			goto err_mfd2; diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a293b978e27..14051bdc714 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, -		ARRAY_SIZE(tps6105x_cells), NULL, 0); +			      ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);  	if (ret)  		goto fail; diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 33ba7723c96..1b203499c74 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c @@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(tps6507x->dev, -1,  			      tps6507x_devs, ARRAY_SIZE(tps6507x_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0)  		goto err; diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 80e24f4b47b..50fd87c87a1 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(tps65090->dev, -1, tps65090s, -		ARRAY_SIZE(tps65090s), NULL, 0); +			      ARRAY_SIZE(tps65090s), NULL, 0, NULL);  	if (ret) {  		dev_err(&client->dev, "add mfd devices failed with err: %d\n",  			ret); diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 61c097a98f5..a95e9421b73 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -24,11 +24,18 @@  #include <linux/slab.h>  #include <linux/regmap.h>  #include <linux/err.h> -#include <linux/regulator/of_regulator.h> +#include <linux/of.h> +#include <linux/of_device.h>  #include <linux/mfd/core.h>  #include <linux/mfd/tps65217.h> +static struct mfd_cell tps65217s[] = { +	{ +		.name = "tps65217-pmic", +	}, +}; +  /**   * tps65217_reg_read: Read a single tps65217 register.   * @@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,  }  EXPORT_SYMBOL_GPL(tps65217_clear_bits); -#ifdef CONFIG_OF -static struct of_regulator_match reg_matches[] = { -	{ .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, -	{ .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, -	{ .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, -	{ .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, -	{ .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, -	{ .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, -	{ .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, -}; - -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ -	struct device_node *node = client->dev.of_node; -	struct tps65217_board *pdata; -	struct device_node *regs; -	int count = ARRAY_SIZE(reg_matches); -	int ret, i; - -	regs = of_find_node_by_name(node, "regulators"); -	if (!regs) -		return NULL; - -	ret = of_regulator_match(&client->dev, regs, reg_matches, count); -	of_node_put(regs); -	if ((ret < 0) || (ret > count)) -		return NULL; - -	count = ret; -	pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); -	if (!pdata) -		return NULL; - -	for (i = 0; i < count; i++) { -		if (!reg_matches[i].init_data || !reg_matches[i].of_node) -			continue; - -		pdata->tps65217_init_data[i] = reg_matches[i].init_data; -		pdata->of_node[i] = reg_matches[i].of_node; -	} - -	return pdata; -} - -static struct of_device_id tps65217_of_match[] = { -	{ .compatible = "ti,tps65217", }, -	{ }, -}; -#else -static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) -{ -	return NULL; -} -#endif -  static struct regmap_config tps65217_regmap_config = {  	.reg_bits = 8,  	.val_bits = 8,  }; +static const struct of_device_id tps65217_of_match[] = { +	{ .compatible = "ti,tps65217", .data = (void *)TPS65217 }, +	{ /* sentinel */ }, +}; +  static int __devinit tps65217_probe(struct i2c_client *client,  				const struct i2c_device_id *ids)  {  	struct tps65217 *tps; -	struct regulator_init_data *reg_data; -	struct tps65217_board *pdata = client->dev.platform_data; -	int i, ret;  	unsigned int version; +	unsigned int chip_id = ids->driver_data; +	const struct of_device_id *match; +	int ret; + +	if (client->dev.of_node) { +		match = of_match_device(tps65217_of_match, &client->dev); +		if (!match) { +			dev_err(&client->dev, +				"Failed to find matching dt id\n"); +			return -EINVAL; +		} +		chip_id = (unsigned int)match->data; +	} -	if (!pdata && client->dev.of_node) -		pdata = tps65217_parse_dt(client); +	if (!chip_id) { +		dev_err(&client->dev, "id is null.\n"); +		return -ENODEV; +	}  	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);  	if (!tps)  		return -ENOMEM; -	tps->pdata = pdata; +	i2c_set_clientdata(client, tps); +	tps->dev = &client->dev; +	tps->id = chip_id; +  	tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);  	if (IS_ERR(tps->regmap)) {  		ret = PTR_ERR(tps->regmap); @@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client,  		return ret;  	} -	i2c_set_clientdata(client, tps); -	tps->dev = &client->dev; +	ret = mfd_add_devices(tps->dev, -1, tps65217s, +			      ARRAY_SIZE(tps65217s), NULL, 0, NULL); +	if (ret < 0) { +		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); +		return ret; +	}  	ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);  	if (ret < 0) { @@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client,  			(version & TPS65217_CHIPID_CHIP_MASK) >> 4,  			version & TPS65217_CHIPID_REV_MASK); -	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { -		struct platform_device *pdev; - -		pdev = platform_device_alloc("tps65217-pmic", i); -		if (!pdev) { -			dev_err(tps->dev, "Cannot create regulator %d\n", i); -			continue; -		} - -		pdev->dev.parent = tps->dev; -		pdev->dev.of_node = pdata->of_node[i]; -		reg_data = pdata->tps65217_init_data[i]; -		platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); -		tps->regulator_pdev[i] = pdev; - -		platform_device_add(pdev); -	} -  	return 0;  }  static int __devexit tps65217_remove(struct i2c_client *client)  {  	struct tps65217 *tps = i2c_get_clientdata(client); -	int i; -	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) -		platform_device_unregister(tps->regulator_pdev[i]); +	mfd_remove_devices(tps->dev);  	return 0;  }  static const struct i2c_device_id tps65217_id_table[] = { -	{"tps65217", 0xF0}, -	{/* end of list */} +	{"tps65217", TPS65217}, +	{ /* sentinel */ }  };  MODULE_DEVICE_TABLE(i2c, tps65217_id_table); diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 353c3481212..5f58370ccf5 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -493,7 +493,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(tps6586x->dev, -1, -			tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0); +			      tps6586x_cell, ARRAY_SIZE(tps6586x_cell), +			      NULL, 0, NULL);  	if (ret < 0) {  		dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);  		goto err_mfd_add; diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1c563792c77..d3ce4d569de 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,  	ret = mfd_add_devices(tps65910->dev, -1,  			      tps65910s, ARRAY_SIZE(tps65910s), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0) {  		dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);  		return ret; diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 74fd8cb5f37..4658b5bdcd8 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c @@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912)  	ret = mfd_add_devices(tps65912->dev, -1,  			      tps65912s, ARRAY_SIZE(tps65912s), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret < 0)  		goto err; diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 838ce4eb444..77c9acb1458 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c @@ -223,7 +223,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)  	if (childs)  		ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, -				      childs, NULL, 0); +				      childs, NULL, 0, NULL);  	else {  		dev_err(&pdev->dev, "No platform data found for childs\n");  		ret = -ENODEV; diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b0fad0ffca5..3dca5c195a2 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client,  	}  	ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret)  		goto mfd_err; diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index 872aff21e4b..b9a636d44c7 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c @@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev,  	vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3;  	ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), -			NULL, 0); +			NULL, 0, NULL);  	/* we always return -ENODEV here in order to enable other  	 * drivers like old, not-yet-platform_device ported i2c-viapro */ diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f39b756df56..86e0e4309fc 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c @@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,  		__func__, children);  	r = mfd_add_devices(&client->dev, -1, core->cells, -			    children, NULL, 0); +			    children, NULL, 0, NULL);  	if (r)  		goto err; diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc..30173103594 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	case WM8310:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8310_devs, ARRAY_SIZE(wm8310_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		break;  	case WM8311:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8311_devs, ARRAY_SIZE(wm8311_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (!pdata || !pdata->disable_touch)  			mfd_add_devices(wm831x->dev, wm831x_num,  					touch_devs, ARRAY_SIZE(touch_devs), -					NULL, 0); +					NULL, 0, NULL);  		break;  	case WM8312:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8312_devs, ARRAY_SIZE(wm8312_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (!pdata || !pdata->disable_touch)  			mfd_add_devices(wm831x->dev, wm831x_num,  					touch_devs, ARRAY_SIZE(touch_devs), -					NULL, 0); +					NULL, 0, NULL);  		break;  	case WM8320: @@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	case WM8326:  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      wm8320_devs, ARRAY_SIZE(wm8320_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		break;  	default: @@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  	if (ret & WM831X_XTAL_ENA) {  		ret = mfd_add_devices(wm831x->dev, wm831x_num,  				      rtc_devs, ARRAY_SIZE(rtc_devs), -				      NULL, 0); +				      NULL, 0, NULL);  		if (ret != 0) {  			dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);  			goto err_irq; @@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)  		/* Treat errors as non-critical */  		ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,  				      ARRAY_SIZE(backlight_devs), NULL, -				      0); +				      0, NULL);  		if (ret < 0)  			dev_err(wm831x->dev, "Failed to add backlight: %d\n",  				ret); diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 4b7d378551d..639ca359242 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)  		.pdata_size = sizeof(*wm8400),  	}; -	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); +	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL);  }  /* diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index eec74aa55fd..2febf88cfce 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)  	ret = mfd_add_devices(wm8994->dev, -1,  			      wm8994_regulator_devs,  			      ARRAY_SIZE(wm8994_regulator_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret != 0) {  		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);  		goto err; @@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)  	ret = mfd_add_devices(wm8994->dev, -1,  			      wm8994_devs, ARRAY_SIZE(wm8994_devs), -			      NULL, 0); +			      NULL, 0, NULL);  	if (ret != 0) {  		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);  		goto err_irq; diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e50..26e7129332a 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -83,6 +83,11 @@  #define INSTRUCTION_LOAD_TXB(n)	(0x40 + 2 * (n))  #define INSTRUCTION_READ_RXB(n)	(((n) == 0) ? 0x90 : 0x94)  #define INSTRUCTION_RESET	0xC0 +#define RTS_TXB0		0x01 +#define RTS_TXB1		0x02 +#define RTS_TXB2		0x04 +#define INSTRUCTION_RTS(n)	(0x80 | ((n) & 0x07)) +  /* MPC251x registers */  #define CANSTAT	      0x0e @@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,  static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,  			  int tx_buf_idx)  { +	struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);  	u32 sid, eid, exide, rtr;  	u8 buf[SPI_TRANSFER_BUF_LEN]; @@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,  	buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;  	memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);  	mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); -	mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); + +	/* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ +	priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); +	mcp251x_spi_trans(priv->spi, 1);  }  static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 21b553229ea..dfd86a55f1d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp,  	prod = txdata->tx_bd_prod;  	cons = txdata->tx_bd_cons; -	/* NUM_TX_RINGS = number of "next-page" entries -	   It will be used as a threshold */ -	used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; +	used = SUB_S16(prod, cons);  #ifdef BNX2X_STOP_ON_ERROR  	WARN_ON(used < 0); -	WARN_ON(used > bp->tx_ring_size); -	WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); +	WARN_ON(used > txdata->tx_ring_size); +	WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL);  #endif -	return (s16)(bp->tx_ring_size) - used; +	return (s16)(txdata->tx_ring_size) - used;  }  static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) @@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp,  	txdata->txq_index = txq_index;  	txdata->tx_cons_sb = tx_cons_sb;  	txdata->parent_fp = fp; +	txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size;  	DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n",  	   txdata->cid, txdata->txq_index); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1eb..b926f58e983 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h @@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x70000, 8, RI_ALL_ONLINE },  	{ 0x70020, 8184, RI_ALL_OFFLINE },  	{ 0x78000, 8192, RI_E3E3B0_OFFLINE }, -	{ 0x85000, 3, RI_ALL_ONLINE }, -	{ 0x8501c, 7, RI_ALL_ONLINE }, -	{ 0x85048, 1, RI_ALL_ONLINE }, -	{ 0x85200, 32, RI_ALL_ONLINE }, -	{ 0xb0000, 16384, RI_E1H_ONLINE }, +	{ 0x85000, 3, RI_ALL_OFFLINE }, +	{ 0x8501c, 7, RI_ALL_OFFLINE }, +	{ 0x85048, 1, RI_ALL_OFFLINE }, +	{ 0x85200, 32, RI_ALL_OFFLINE }, +	{ 0xb0000, 16384, RI_E1H_OFFLINE },  	{ 0xc1000, 7, RI_ALL_ONLINE },  	{ 0xc103c, 2, RI_E2E3E3B0_ONLINE },  	{ 0xc1800, 2, RI_ALL_ONLINE }, @@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x140188, 3, RI_E1E1HE2E3_ONLINE },  	{ 0x140194, 13, RI_ALL_ONLINE },  	{ 0x140200, 6, RI_E1E1HE2E3_ONLINE }, -	{ 0x140220, 4, RI_E2E3_ONLINE }, -	{ 0x140240, 4, RI_E2E3_ONLINE },  	{ 0x140260, 4, RI_E2E3_ONLINE },  	{ 0x140280, 4, RI_E2E3_ONLINE }, -	{ 0x1402a0, 4, RI_E2E3_ONLINE }, -	{ 0x1402c0, 4, RI_E2E3_ONLINE },  	{ 0x1402e0, 2, RI_E2E3_ONLINE },  	{ 0x1402e8, 2, RI_E2E3E3B0_ONLINE },  	{ 0x1402f0, 9, RI_E2E3_ONLINE },  	{ 0x140314, 44, RI_E3B0_ONLINE }, -	{ 0x1403d0, 70, RI_E3B0_ONLINE },  	{ 0x144000, 4, RI_E1E1H_ONLINE },  	{ 0x148000, 4, RI_E1E1H_ONLINE },  	{ 0x14c000, 4, RI_E1E1H_ONLINE }, @@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x180398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x1803a0, 5, RI_E2E3E3B0_ONLINE },  	{ 0x1803b4, 2, RI_E3E3B0_ONLINE }, -	{ 0x180400, 1, RI_ALL_ONLINE },  	{ 0x180404, 255, RI_E1E1H_OFFLINE },  	{ 0x181000, 4, RI_ALL_ONLINE },  	{ 0x181010, 1020, RI_ALL_OFFLINE }, @@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x1b905c, 1, RI_E3E3B0_ONLINE },  	{ 0x1b9064, 1, RI_E3B0_ONLINE },  	{ 0x1b9080, 10, RI_E3B0_ONLINE }, -	{ 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, -	{ 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, -	{ 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, +	{ 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, +	{ 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, +	{ 0x1b9490, 10, RI_E2E3E3B0_OFFLINE },  	{ 0x1c0000, 2, RI_ALL_ONLINE },  	{ 0x200000, 65, RI_ALL_ONLINE },  	{ 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, @@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x200398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2003a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x200400, 1, RI_ALL_ONLINE },  	{ 0x200404, 255, RI_E1E1H_OFFLINE },  	{ 0x202000, 4, RI_ALL_ONLINE },  	{ 0x202010, 2044, RI_ALL_OFFLINE }, @@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x280398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2803a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x280400, 1, RI_ALL_ONLINE },  	{ 0x280404, 255, RI_E1E1H_OFFLINE },  	{ 0x282000, 4, RI_ALL_ONLINE },  	{ 0x282010, 2044, RI_ALL_OFFLINE }, @@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = {  	{ 0x300398, 1, RI_E2E3E3B0_ONLINE },  	{ 0x3003a0, 1, RI_E2E3E3B0_ONLINE },  	{ 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, -	{ 0x300400, 1, RI_ALL_ONLINE },  	{ 0x300404, 255, RI_E1E1H_OFFLINE },  	{ 0x302000, 4, RI_ALL_ONLINE },  	{ 0x302010, 2044, RI_ALL_OFFLINE }, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c37a68d6809..ebf40cd7aa1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev,  	struct bnx2x *bp = netdev_priv(dev);  	struct dump_hdr dump_hdr = {0}; -	regs->version = 0; +	regs->version = 1;  	memset(p, 0, regs->len);  	if (!netif_running(bp->dev)) @@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev,  			bp->link_params.req_flow_ctrl[cfg_idx] =  				BNX2X_FLOW_CTRL_AUTO;  		} +		bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; +		if (epause->rx_pause) +			bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; + +		if (epause->tx_pause) +			bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX;  	}  	DP(BNX2X_MSG_ETHTOOL, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c470..b046beb435b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params,  		return bnx2x_status;  	DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); -	if (CHIP_IS_E3(bp)) -		bnx2x_update_pfc_xmac(params, vars, 0); -	else { + +	if (CHIP_IS_E3(bp)) { +		if (vars->mac_type == MAC_TYPE_XMAC) +			bnx2x_update_pfc_xmac(params, vars, 0); +	} else {  		val = REG_RD(bp, MISC_REG_RESET_REG_2);  		if ((val &  		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) @@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		switch (speed_mask) {  		case GP_STATUS_10M:  			vars->line_speed = SPEED_10; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_10TFD;  			else  				vars->link_status |= LINK_10THD; @@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_100M:  			vars->line_speed = SPEED_100; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_100TXFD;  			else  				vars->link_status |= LINK_100TXHD; @@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_1G:  		case GP_STATUS_1G_KX:  			vars->line_speed = SPEED_1000; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_1000TFD;  			else  				vars->link_status |= LINK_1000THD; @@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,  		case GP_STATUS_2_5G:  			vars->line_speed = SPEED_2500; -			if (vars->duplex == DUPLEX_FULL) +			if (is_duplex == DUPLEX_FULL)  				vars->link_status |= LINK_2500TFD;  			else  				vars->link_status |= LINK_2500THD; @@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy,  	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {  		if (SINGLE_MEDIA_DIRECT(params)) { +			vars->duplex = duplex;  			bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);  			if (phy->req_line_speed == SPEED_AUTO_NEG)  				bnx2x_xgxs_an_resolve(phy, params, vars, @@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,  					LINK_STATUS_PARALLEL_DETECTION_USED;  			}  			bnx2x_ext_phy_resolve_fc(phy, params, vars); +			vars->duplex = duplex;  		}  	} diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 21054987257..211753e01f8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -7561,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac,  	}  	rc = bnx2x_config_vlan_mac(bp, &ramrod_param); -	if (rc < 0) + +	if (rc == -EEXIST) { +		DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); +		/* do not treat adding same MAC as error */ +		rc = 0; +	} else if (rc < 0)  		BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); +  	return rc;  } @@ -10294,13 +10300,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp)  				dev_info.port_hw_config[port].  				 fcoe_wwn_node_name_lower);  	} else if (!IS_MF_SD(bp)) { -		u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); -  		/*  		 * Read the WWN info only if the FCoE feature is enabled for  		 * this function.  		 */ -		if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) +		if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp))  			bnx2x_get_ext_wwn_info(bp, func);  	} else if (IS_MF_FCOE_SD(bp)) @@ -11073,7 +11077,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp)  	netdev_for_each_uc_addr(ha, dev) {  		rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true,  				       BNX2X_UC_LIST_MAC, &ramrod_flags); -		if (rc < 0) { +		if (rc == -EEXIST) { +			DP(BNX2X_MSG_SP, +			   "Failed to schedule ADD operations: %d\n", rc); +			/* do not treat adding same MAC as error */ +			rc = 0; + +		} else if (rc < 0) { +  			BNX2X_ERR("Failed to schedule ADD operations: %d\n",  				  rc);  			return rc; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5b..a1d0446b39b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)  	if (CHIP_REV_IS_SLOW(bp))  		return; +	/* Update MCP's statistics if possible */ +	if (bp->func_stx) +		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, +		       sizeof(bp->func_stats)); +  	/* loader */  	if (bp->executer_idx) {  		int loader_idx = PMF_DMAE_C(bp); @@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)  	} else if (bp->func_stx) {  		*stats_comp = 0; -		memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, -		       sizeof(bp->func_stats));  		bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));  	}  } @@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp)  	if (bp->port.pmf)  		bnx2x_hw_stats_update(bp); -	if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { -		BNX2X_ERR("storm stats were not updated for 3 times\n"); -		bnx2x_panic(); +	if (bnx2x_storm_stats_update(bp)) { +		if (bp->stats_pending++ == 3) { +			BNX2X_ERR("storm stats were not updated for 3 times\n"); +			bnx2x_panic(); +		}  		return;  	} diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e1..ba4e0cea350 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c @@ -139,8 +139,11 @@ struct znet_private {  /* Only one can be built-in;-> */  static struct net_device *znet_dev; +#define NETIDBLK_MAGIC		"NETIDBLK" +#define NETIDBLK_MAGIC_SIZE	8 +  struct netidblk { -	char magic[8];		/* The magic number (string) "NETIDBLK" */ +	char magic[NETIDBLK_MAGIC_SIZE];	/* The magic number (string) "NETIDBLK" */  	unsigned char netid[8]; /* The physical station address */  	char nettype, globalopt;  	char vendor[8];		/* The machine vendor and product name. */ @@ -373,14 +376,16 @@ static int __init znet_probe (void)  	struct znet_private *znet;  	struct net_device *dev;  	char *p; +	char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE);  	int err = -ENOMEM;  	/* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ -	for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) -		if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0) +	for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) +		if (*p == 'N' && +		    strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0)  			break; -	if (p >= (char *)phys_to_virt(0x100000)) { +	if (p > plast) {  		if (znet_debug > 1)  			printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");  		return -ENODEV; diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc..b68d28a130e 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)  	}  	if (adapter->rx_queue.queue_addr != NULL) { -		if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { -			dma_unmap_single(dev, -					adapter->rx_queue.queue_dma, -					adapter->rx_queue.queue_len, -					DMA_BIDIRECTIONAL); -			adapter->rx_queue.queue_dma = DMA_ERROR_CODE; -		} -		kfree(adapter->rx_queue.queue_addr); +		dma_free_coherent(dev, adapter->rx_queue.queue_len, +				  adapter->rx_queue.queue_addr, +				  adapter->rx_queue.queue_dma);  		adapter->rx_queue.queue_addr = NULL;  	} @@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev)  		goto err_out;  	} +	dev = &adapter->vdev->dev; +  	adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *  						rxq_entries; -	adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, -						GFP_KERNEL); +	adapter->rx_queue.queue_addr = +	    dma_alloc_coherent(dev, adapter->rx_queue.queue_len, +			       &adapter->rx_queue.queue_dma, GFP_KERNEL);  	if (!adapter->rx_queue.queue_addr) {  		netdev_err(netdev, "unable to allocate rx queue pages\n"); @@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev)  		goto err_out;  	} -	dev = &adapter->vdev->dev; -  	adapter->buffer_list_dma = dma_map_single(dev,  			adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);  	adapter->filter_list_dma = dma_map_single(dev,  			adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); -	adapter->rx_queue.queue_dma = dma_map_single(dev, -			adapter->rx_queue.queue_addr, -			adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);  	if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || -	    (dma_mapping_error(dev, adapter->filter_list_dma)) || -	    (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { +	    (dma_mapping_error(dev, adapter->filter_list_dma))) {  		netdev_err(netdev, "unable to map filter or buffer list "  			   "pages\n");  		rc = -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce9..2f816c6aed7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  				mlx4_info(dev, "non-primary physical function, skipping.\n");  			else  				mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); -			goto unmap_bf; +			return err;  		}  		err = mlx4_load_fw(dev);  		if (err) {  			mlx4_err(dev, "Failed to start FW, aborting.\n"); -			goto unmap_bf; +			return err;  		}  		mlx4_cfg.log_pg_sz_m = 1; @@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  		err = mlx4_init_slave(dev);  		if (err) {  			mlx4_err(dev, "Failed to initialize slave\n"); -			goto unmap_bf; +			return err;  		}  		err = mlx4_slave_cap(dev); @@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  	err = mlx4_QUERY_ADAPTER(dev, &adapter);  	if (err) {  		mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); -		goto err_close; +		goto unmap_bf;  	}  	priv->eq_table.inta_pin = adapter.inta_pin; @@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)  	return 0; +unmap_bf: +	unmap_bf_area(dev); +  err_close:  	mlx4_close_hca(dev); @@ -1344,8 +1347,6 @@ err_stop_fw:  		mlx4_UNMAP_FA(dev);  		mlx4_free_icm(dev, priv->fw.fw_icm, 0);  	} -unmap_bf: -	unmap_bf_area(dev);  	return err;  } @@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)  	}  slave_start: -	if (mlx4_cmd_init(dev)) { +	err = mlx4_cmd_init(dev); +	if (err) {  		mlx4_err(dev, "Failed to init command interface, aborting.\n");  		goto err_sriov;  	} diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43d..e151c21baf2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,  	return err;  } -static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, +static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,  					      enum mlx4_steer_type steer,  					      u32 qpn)  { -	struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; +	struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];  	struct mlx4_promisc_qp *pqp;  	list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { @@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,  	/* If the given qpn is also a promisc qp,  	 * it should be inserted to duplicates list  	 */ -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (pqp) {  		dqp = kmalloc(sizeof *dqp, GFP_KERNEL);  		if (!dqp) { @@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1]; -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (!pqp)  		return 0; /* nothing to do */ @@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1];  	/* if qp is not promisc, it cannot be duplicated */ -	if (!get_promisc_qp(dev, 0, steer, qpn)) +	if (!get_promisc_qp(dev, port, steer, qpn))  		return false;  	/* The qp is promisc qp so it is a duplicate on this index @@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,  	members_count = be32_to_cpu(mgm->members_count) & 0xffffff;  	for (i = 0;  i < members_count; i++) {  		qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; -		if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { +		if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {  			/* the qp is not promisc, the entry can't be removed */  			goto out;  		} @@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,  	mutex_lock(&priv->mcg_table.mutex); -	if (get_promisc_qp(dev, 0, steer, qpn)) { +	if (get_promisc_qp(dev, port, steer, qpn)) {  		err = 0;  /* Noting to do, already exists */  		goto out_mutex;  	} @@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,  	s_steer = &mlx4_priv(dev)->steer[port - 1];  	mutex_lock(&priv->mcg_table.mutex); -	pqp = get_promisc_qp(dev, 0, steer, qpn); +	pqp = get_promisc_qp(dev, port, steer, qpn);  	if (unlikely(!pqp)) {  		mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);  		/* nothing to do */ @@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port,  	return err;  } -struct mlx4_net_trans_rule_hw_ctrl { -	__be32 ctrl; -	__be32 vf_vep_port; -	__be32 qpn; -	__be32 reserved; -}; -  static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,  				  struct mlx4_net_trans_rule_hw_ctrl *hw)  { @@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,  	hw->qpn = cpu_to_be32(ctrl->qpn);  } -struct mlx4_net_trans_rule_hw_ib { -	u8	size; -	u8	rsvd1; -	__be16	id; -	u32	rsvd2; -	__be32	qpn; -	__be32	qpn_mask; -	u8	dst_gid[16]; -	u8	dst_gid_msk[16]; -} __packed; - -struct mlx4_net_trans_rule_hw_eth { -	u8	size; -	u8	rsvd; -	__be16	id; -	u8	rsvd1[6]; -	u8	dst_mac[6]; -	u16	rsvd2; -	u8	dst_mac_msk[6]; -	u16	rsvd3; -	u8	src_mac[6]; -	u16	rsvd4; -	u8	src_mac_msk[6]; -	u8      rsvd5; -	u8      ether_type_enable; -	__be16  ether_type; -	__be16  vlan_id_msk; -	__be16  vlan_id; -} __packed; - -struct mlx4_net_trans_rule_hw_tcp_udp { -	u8	size; -	u8	rsvd; -	__be16	id; -	__be16	rsvd1[3]; -	__be16	dst_port; -	__be16	rsvd2; -	__be16	dst_port_msk; -	__be16	rsvd3; -	__be16	src_port; -	__be16	rsvd4; -	__be16	src_port_msk; -} __packed; - -struct mlx4_net_trans_rule_hw_ipv4 { -	u8	size; -	u8	rsvd; -	__be16	id; -	__be32	rsvd1; -	__be32	dst_ip; -	__be32	dst_ip_msk; -	__be32	src_ip; -	__be32	src_ip_msk; -} __packed; - -struct _rule_hw { -	union { -		struct { -			u8 size; -			u8 rsvd; -			__be16 id; -		}; -		struct mlx4_net_trans_rule_hw_eth eth; -		struct mlx4_net_trans_rule_hw_ib ib; -		struct mlx4_net_trans_rule_hw_ipv4 ipv4; -		struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; -	}; +const u16 __sw_id_hw[] = { +	[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001, +	[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005, +	[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003, +	[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002, +	[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004, +	[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006  };  static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,  			    struct _rule_hw *rule_hw)  { -	static const u16 __sw_id_hw[] = { -		[MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001, -		[MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005, -		[MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003, -		[MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002, -		[MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004, -		[MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006 -	}; -  	static const size_t __rule_hw_sz[] = {  		[MLX4_NET_TRANS_RULE_ID_ETH] =  			sizeof(struct mlx4_net_trans_rule_hw_eth), diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 4d9df8f2a12..dba69d98734 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -690,6 +690,82 @@ struct mlx4_steer {  	struct list_head steer_entries[MLX4_NUM_STEERS];  }; +struct mlx4_net_trans_rule_hw_ctrl { +	__be32 ctrl; +	__be32 vf_vep_port; +	__be32 qpn; +	__be32 reserved; +}; + +struct mlx4_net_trans_rule_hw_ib { +	u8 size; +	u8 rsvd1; +	__be16 id; +	u32 rsvd2; +	__be32 qpn; +	__be32 qpn_mask; +	u8 dst_gid[16]; +	u8 dst_gid_msk[16]; +} __packed; + +struct mlx4_net_trans_rule_hw_eth { +	u8	size; +	u8	rsvd; +	__be16	id; +	u8	rsvd1[6]; +	u8	dst_mac[6]; +	u16	rsvd2; +	u8	dst_mac_msk[6]; +	u16	rsvd3; +	u8	src_mac[6]; +	u16	rsvd4; +	u8	src_mac_msk[6]; +	u8      rsvd5; +	u8      ether_type_enable; +	__be16  ether_type; +	__be16  vlan_id_msk; +	__be16  vlan_id; +} __packed; + +struct mlx4_net_trans_rule_hw_tcp_udp { +	u8	size; +	u8	rsvd; +	__be16	id; +	__be16	rsvd1[3]; +	__be16	dst_port; +	__be16	rsvd2; +	__be16	dst_port_msk; +	__be16	rsvd3; +	__be16	src_port; +	__be16	rsvd4; +	__be16	src_port_msk; +} __packed; + +struct mlx4_net_trans_rule_hw_ipv4 { +	u8	size; +	u8	rsvd; +	__be16	id; +	__be32	rsvd1; +	__be32	dst_ip; +	__be32	dst_ip_msk; +	__be32	src_ip; +	__be32	src_ip_msk; +} __packed; + +struct _rule_hw { +	union { +		struct { +			u8 size; +			u8 rsvd; +			__be16 id; +		}; +		struct mlx4_net_trans_rule_hw_eth eth; +		struct mlx4_net_trans_rule_hw_ib ib; +		struct mlx4_net_trans_rule_hw_ipv4 ipv4; +		struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; +	}; +}; +  struct mlx4_priv {  	struct mlx4_dev		dev; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab..293c9e820c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -42,6 +42,7 @@  #include <linux/mlx4/cmd.h>  #include <linux/mlx4/qp.h>  #include <linux/if_ether.h> +#include <linux/etherdevice.h>  #include "mlx4.h"  #include "fw.h" @@ -2776,18 +2777,133 @@ ex_put:  	return err;  } +/* + * MAC validation for Flow Steering rules. + * VF can attach rules only with a mac address which is assigned to it. + */ +static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, +				   struct list_head *rlist) +{ +	struct mac_res *res, *tmp; +	__be64 be_mac; + +	/* make sure it isn't multicast or broadcast mac*/ +	if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && +	    !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { +		list_for_each_entry_safe(res, tmp, rlist, list) { +			be_mac = cpu_to_be64(res->mac << 16); +			if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) +				return 0; +		} +		pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", +		       eth_header->eth.dst_mac, slave); +		return -EINVAL; +	} +	return 0; +} + +/* + * In case of missing eth header, append eth header with a MAC address + * assigned to the VF. + */ +static int add_eth_header(struct mlx4_dev *dev, int slave, +			  struct mlx4_cmd_mailbox *inbox, +			  struct list_head *rlist, int header_id) +{ +	struct mac_res *res, *tmp; +	u8 port; +	struct mlx4_net_trans_rule_hw_ctrl *ctrl; +	struct mlx4_net_trans_rule_hw_eth *eth_header; +	struct mlx4_net_trans_rule_hw_ipv4 *ip_header; +	struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; +	__be64 be_mac = 0; +	__be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); + +	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; +	port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; +	eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); + +	/* Clear a space in the inbox for eth header */ +	switch (header_id) { +	case MLX4_NET_TRANS_RULE_ID_IPV4: +		ip_header = +			(struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); +		memmove(ip_header, eth_header, +			sizeof(*ip_header) + sizeof(*l4_header)); +		break; +	case MLX4_NET_TRANS_RULE_ID_TCP: +	case MLX4_NET_TRANS_RULE_ID_UDP: +		l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) +			    (eth_header + 1); +		memmove(l4_header, eth_header, sizeof(*l4_header)); +		break; +	default: +		return -EINVAL; +	} +	list_for_each_entry_safe(res, tmp, rlist, list) { +		if (port == res->port) { +			be_mac = cpu_to_be64(res->mac << 16); +			break; +		} +	} +	if (!be_mac) { +		pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", +		       port); +		return -EINVAL; +	} + +	memset(eth_header, 0, sizeof(*eth_header)); +	eth_header->size = sizeof(*eth_header) >> 2; +	eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); +	memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); +	memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); + +	return 0; + +} +  int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,  					 struct mlx4_vhcr *vhcr,  					 struct mlx4_cmd_mailbox *inbox,  					 struct mlx4_cmd_mailbox *outbox,  					 struct mlx4_cmd_info *cmd)  { + +	struct mlx4_priv *priv = mlx4_priv(dev); +	struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; +	struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];  	int err; +	struct mlx4_net_trans_rule_hw_ctrl *ctrl; +	struct _rule_hw  *rule_header; +	int header_id;  	if (dev->caps.steering_mode !=  	    MLX4_STEERING_MODE_DEVICE_MANAGED)  		return -EOPNOTSUPP; +	ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; +	rule_header = (struct _rule_hw *)(ctrl + 1); +	header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); + +	switch (header_id) { +	case MLX4_NET_TRANS_RULE_ID_ETH: +		if (validate_eth_header_mac(slave, rule_header, rlist)) +			return -EINVAL; +		break; +	case MLX4_NET_TRANS_RULE_ID_IPV4: +	case MLX4_NET_TRANS_RULE_ID_TCP: +	case MLX4_NET_TRANS_RULE_ID_UDP: +		pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); +		if (add_eth_header(dev, slave, inbox, rlist, header_id)) +			return -EINVAL; +		vhcr->in_modifier += +			sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; +		break; +	default: +		pr_err("Corrupted mailbox.\n"); +		return -EINVAL; +	} +  	err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,  			   vhcr->in_modifier, 0,  			   MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122..4d15bf413bd 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev)  	sp->srings = sr;  	sp->rx_desc = sp->srings->rxvector;  	sp->tx_desc = sp->srings->txvector; +	spin_lock_init(&sp->tx_lock);  	/* A couple calculations now, saves many cycles later. */  	setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index adfab3fc547..b1ba68f1a04 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -297,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)  	if (ret < 0)  		goto err; -	if (info->subdriver && info->subdriver->suspend) +	if (intf == info->control && info->subdriver && info->subdriver->suspend)  		ret = info->subdriver->suspend(intf, message);  	if (ret < 0)  		usbnet_resume(intf); @@ -310,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf)  	struct usbnet *dev = usb_get_intfdata(intf);  	struct qmi_wwan_state *info = (void *)&dev->data;  	int ret = 0; +	bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); -	if (info->subdriver && info->subdriver->resume) +	if (callsub)  		ret = info->subdriver->resume(intf);  	if (ret < 0)  		goto err;  	ret = usbnet_resume(intf); -	if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) +	if (ret < 0 && callsub && info->subdriver->suspend)  		info->subdriver->suspend(intf, PMSG_SUSPEND);  err:  	return ret; @@ -398,7 +399,6 @@ static const struct usb_device_id products[] = {  	/* 4. Gobi 1000 devices */  	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */  	{QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */ -	{QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */  	{QMI_GOBI1K_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */  	{QMI_GOBI1K_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */  	{QMI_GOBI1K_DEVICE(0x1410, 0xa001)},	/* Novatel Gobi Modem device */ @@ -440,6 +440,7 @@ static const struct usb_device_id products[] = {  	{QMI_GOBI_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */  	{QMI_GOBI_DEVICE(0x05c6, 0x9205)},	/* Gobi 2000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x9013)},	/* Sierra Wireless Gobi 3000 Modem device (MC8355) */ +	{QMI_GOBI_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */  	{QMI_GOBI_DEVICE(0x1199, 0x9015)},	/* Sierra Wireless Gobi 3000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x9019)},	/* Sierra Wireless Gobi 3000 Modem device */  	{QMI_GOBI_DEVICE(0x1199, 0x901b)},	/* Sierra Wireless MC7770 */ diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 7be49ea60b6..8e22417fa6c 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)  		return -EIO;  	} -	*datap = *attrdata; +	*datap = le16_to_cpu(*attrdata);  	kfree(attrdata);  	return result; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fd4b26d46fd..fc9f578a1e2 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1201,19 +1201,26 @@ deferred:  }  EXPORT_SYMBOL_GPL(usbnet_start_xmit); -static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) +static int rx_alloc_submit(struct usbnet *dev, gfp_t flags)  {  	struct urb	*urb;  	int		i; +	int		ret = 0;  	/* don't refill the queue all at once */  	for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) {  		urb = usb_alloc_urb(0, flags);  		if (urb != NULL) { -			if (rx_submit(dev, urb, flags) == -ENOLINK) -				return; +			ret = rx_submit(dev, urb, flags); +			if (ret) +				goto err; +		} else { +			ret = -ENOMEM; +			goto err;  		}  	} +err: +	return ret;  }  /*-------------------------------------------------------------------------*/ @@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param)  		int	temp = dev->rxq.qlen;  		if (temp < RX_QLEN(dev)) { -			rx_alloc_submit(dev, GFP_ATOMIC); +			if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) +				return;  			if (temp != dev->rxq.qlen)  				netif_dbg(dev, link, dev->net,  					  "rxqlen %d --> %d\n", diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa229..3f575afd8cf 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -10,6 +10,7 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/module.h>  #include <linux/bitops.h>  #include <linux/cdev.h>  #include <linux/dma-mapping.h> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4c..0ed3846f9cb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)  	};  	int training_power;  	int i, val; +	u32 am2pm_mask = ah->paprd_ratemask;  	if (IS_CHAN_2GHZ(ah->curchan))  		training_power = ar9003_get_training_power_2g(ah); @@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)  	}  	ah->paprd_training_power = training_power; +	if (AR_SREV_9330(ah)) +		am2pm_mask = 0; +  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,  		      ah->paprd_ratemask);  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, -		      ah->paprd_ratemask); +		      am2pm_mask);  	REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,  		      ah->paprd_ratemask_ht40); @@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)  }  EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); +static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, +				       struct ath9k_hw_cal_data *caldata, +				       int chain) +{ +	u32 *pa_in = caldata->pa_table[chain]; +	int capdiv_offset, quick_drop_offset; +	int capdiv2g, quick_drop; +	int count = 0; +	int i; + +	if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) +		return false; + +	capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, +				  AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); + +	quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, +				    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); + +	if (quick_drop) +		quick_drop -= 0x40; + +	for (i = 0; i < NUM_BIN + 1; i++) { +		if (pa_in[i] == 1400) +			count++; +	} + +	if (AR_SREV_9485(ah)) { +		if (pa_in[23] < 800) { +			capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); +			capdiv2g += capdiv_offset; +			if (capdiv2g > 7) { +				capdiv2g = 7; +				if (pa_in[23] < 600) { +					quick_drop++; +					if (quick_drop > 0) +						quick_drop = 0; +				} +			} +		} else if (pa_in[23] == 1400) { +			quick_drop_offset = min_t(int, count / 3, 2); +			quick_drop += quick_drop_offset; +			capdiv2g += quick_drop_offset / 2; + +			if (capdiv2g > 7) +				capdiv2g = 7; + +			if (quick_drop > 0) { +				quick_drop = 0; +				capdiv2g -= quick_drop_offset; +				if (capdiv2g < 0) +					capdiv2g = 0; +			} +		} else { +			return false; +		} +	} else if (AR_SREV_9330(ah)) { +		if (pa_in[23] < 1000) { +			capdiv_offset = (1000 - pa_in[23]) / 100; +			capdiv2g += capdiv_offset; +			if (capdiv_offset > 3) { +				capdiv_offset = 1; +				quick_drop--; +			} + +			capdiv2g += capdiv_offset; +			if (capdiv2g > 6) +				capdiv2g = 6; +			if (quick_drop < -4) +				quick_drop = -4; +		} else if (pa_in[23] == 1400) { +			if (count > 3) { +				quick_drop++; +				capdiv2g -= count / 4; +				if (quick_drop > -2) +					quick_drop = -2; +			} else { +				capdiv2g--; +			} + +			if (capdiv2g < 0) +				capdiv2g = 0; +		} else { +			return false; +		} +	} + +	REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, +		      AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); +	REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, +		      AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, +		      quick_drop); + +	return true; +} +  int ar9003_paprd_create_curve(struct ath_hw *ah,  			      struct ath9k_hw_cal_data *caldata, int chain)  { @@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,  	if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))  		status = -2; +	if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) +		status = -EINPROGRESS; +  	REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,  		    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a4..84d3d495686 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -625,6 +625,10 @@  #define AR_PHY_AIC_CTRL_4_B0	(AR_SM_BASE + 0x4c0)  #define AR_PHY_AIC_STAT_2_B0	(AR_SM_BASE + 0x4cc) +#define AR_PHY_65NM_CH0_TXRF3       0x16048 +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G		0x0000001e +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S	1 +  #define AR_PHY_65NM_CH0_SYNTH4      0x1608c  #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)  #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef..9f83f71742a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)  {  	struct ath_btcoex *btcoex = &sc->btcoex; -	ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); +	if (btcoex->hw_timer_enabled) +		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);  }  u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7..48af40151d2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)  		ah->config.spurchans[i][1] = AR_NO_SPUR;  	} -	/* PAPRD needs some more work to be enabled */ -	ah->config.paprd_disable = 1; -  	ah->config.rx_intr_mitigation = true;  	ah->config.pcieSerDesWrite = true; @@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,  	else  		imr_reg |= AR_IMR_TXOK; -	if (opmode == NL80211_IFTYPE_AP) -		imr_reg |= AR_IMR_MIB; -  	ENABLE_REGWRITE_BUFFER(ah);  	REG_WRITE(ah, AR_IMR, imr_reg); @@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,  		/* Operating channel changed, reset channel calibration data */  		memset(caldata, 0, sizeof(*caldata));  		ath9k_init_nfcal_hist_buffer(ah, chan); +	} else if (caldata) { +		caldata->paprd_packet_sent = false;  	}  	ah->noise = ath9k_hw_getchan_noise(ah, chan); @@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)  		pCap->tx_desc_len = sizeof(struct ar9003_txc);  		pCap->txs_len = sizeof(struct ar9003_txs);  		if (!ah->config.paprd_disable && -		    ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) +		    ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && +		    !AR_SREV_9462(ah))  			pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;  	} else {  		pCap->tx_desc_len = sizeof(struct ath_desc); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64ef..6599a75f01f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -405,6 +405,7 @@ struct ath9k_hw_cal_data {  	int8_t iCoff;  	int8_t qCoff;  	bool rtt_done; +	bool paprd_packet_sent;  	bool paprd_done;  	bool nfcal_pending;  	bool nfcal_interference; diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5..825a29cc931 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work)  	int chain_ok = 0;  	int chain;  	int len = 1800; +	int ret; -	if (!caldata) +	if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)  		return;  	ath9k_ps_wakeup(sc); @@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work)  			continue;  		chain_ok = 0; - -		ath_dbg(common, CALIBRATE, -			"Sending PAPRD frame for thermal measurement on chain %d\n", -			chain); -		if (!ath_paprd_send_frame(sc, skb, chain)) -			goto fail_paprd; -  		ar9003_paprd_setup_gain_table(ah, chain);  		ath_dbg(common, CALIBRATE, @@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work)  			break;  		} -		if (ar9003_paprd_create_curve(ah, caldata, chain)) { +		ret = ar9003_paprd_create_curve(ah, caldata, chain); +		if (ret == -EINPROGRESS) { +			ath_dbg(common, CALIBRATE, +				"PAPRD curve on chain %d needs to be re-trained\n", +				chain); +			break; +		} else if (ret) {  			ath_dbg(common, CALIBRATE,  				"PAPRD create curve failed on chain %d\n",  				chain); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb..0d4155aec48 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,  	ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); +	if (sc->sc_ah->caldata) +		sc->sc_ah->caldata->paprd_packet_sent = true; +  	if (!(tx_flags & ATH_TX_ERROR))  		/* Frame was ACKed */  		tx_info->flags |= IEEE80211_TX_STAT_ACK; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e..58f89fa9c9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)  	else  		devinfo->bus_pub.bus->dstats.tx_errors++; -	dev_kfree_skb(req->skb); +	brcmu_pkt_buf_free_skb(req->skb);  	req->skb = NULL;  	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); @@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)  		devinfo->bus_pub.bus->dstats.rx_packets++;  	} else {  		devinfo->bus_pub.bus->dstats.rx_errors++; -		dev_kfree_skb(skb); +		brcmu_pkt_buf_free_skb(skb);  		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  		return;  	} @@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb)  		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {  			brcmf_dbg(ERROR, "rx protocol error\n");  			brcmu_pkt_buf_free_skb(skb); +			brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  			devinfo->bus_pub.bus->dstats.rx_errors++;  		} else {  			brcmf_rx_packet(devinfo->dev, ifidx, skb);  			brcmf_usb_rx_refill(devinfo, req);  		}  	} else { -		dev_kfree_skb(skb); +		brcmu_pkt_buf_free_skb(skb); +		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  	}  	return; @@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,  	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,  			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,  			  req); -	req->urb->transfer_flags |= URB_ZERO_PACKET;  	req->devinfo = devinfo; +	brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);  	ret = usb_submit_urb(req->urb, GFP_ATOMIC); -	if (ret == 0) { -		brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); -	} else { -		dev_kfree_skb(req->skb); +	if (ret) { +		brcmf_usb_del_fromq(devinfo, req); +		brcmu_pkt_buf_free_skb(req->skb);  		req->skb = NULL;  		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);  	} @@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)  	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);  	if (!req) { +		brcmu_pkt_buf_free_skb(skb);  		brcmf_dbg(ERROR, "no req to send\n");  		return -ENOMEM;  	} -	if (!req->urb) { -		brcmf_dbg(ERROR, "no urb for req %p\n", req); -		return -ENOBUFS; -	}  	req->skb = skb;  	req->devinfo = devinfo;  	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,  			  skb->data, skb->len, brcmf_usb_tx_complete, req);  	req->urb->transfer_flags |= URB_ZERO_PACKET; +	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);  	ret = usb_submit_urb(req->urb, GFP_ATOMIC); -	if (!ret) { -		brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); -	} else { +	if (ret) { +		brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); +		brcmf_usb_del_fromq(devinfo, req); +		brcmu_pkt_buf_free_skb(req->skb);  		req->skb = NULL;  		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);  	} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af2..c36e9231244 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,  	}  	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { -		scb_val.val = cpu_to_le32(0); +		memset(&scb_val, 0, sizeof(scb_val));  		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,  				      sizeof(struct brcmf_scb_val_le)); -		if (err) +		if (err) {  			WL_ERR("Could not get rssi (%d)\n", err); - -		rssi = le32_to_cpu(scb_val.val); -		sinfo->filled |= STATION_INFO_SIGNAL; -		sinfo->signal = rssi; -		WL_CONN("RSSI %d dBm\n", rssi); +		} else { +			rssi = le32_to_cpu(scb_val.val); +			sinfo->filled |= STATION_INFO_SIGNAL; +			sinfo->signal = rssi; +			WL_CONN("RSSI %d dBm\n", rssi); +		}  	}  done: diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e970897f6ab..4cb234349fb 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev)  	mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); +	/* If we're powered off anyway, just let the mmc layer remove the +	 * card. */ +	if (!lbs_iface_active(card->priv)) +		return -ENOSYS; +  	dev_info(dev, "%s: suspend: PM flags = 0x%x\n",  		 sdio_func_id(func), flags); diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8..565527aee0e 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,  	cmd_code = le16_to_cpu(host_cmd->command);  	cmd_size = le16_to_cpu(host_cmd->size); -	skb_trim(cmd_node->cmd_skb, cmd_size); +	/* Adjust skb length */ +	if (cmd_node->cmd_skb->len > cmd_size) +		/* +		 * cmd_size is less than sizeof(struct host_cmd_ds_command). +		 * Trim off the unused portion. +		 */ +		skb_trim(cmd_node->cmd_skb, cmd_size); +	else if (cmd_node->cmd_skb->len < cmd_size) +		/* +		 * cmd_size is larger than sizeof(struct host_cmd_ds_command) +		 * because we have appended custom IE TLV. Increase skb length +		 * accordingly. +		 */ +		skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);  	do_gettimeofday(&tstamp);  	dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a25..64328af496f 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); +	rt2x00_set_field32(®, GPIOCSR_BIT8, 1); +	rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2400pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc43..7564ae992b7 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -670,6 +670,7 @@  #define GPIOCSR_BIT5			FIELD32(0x00000020)  #define GPIOCSR_BIT6			FIELD32(0x00000040)  #define GPIOCSR_BIT7			FIELD32(0x00000080) +#define GPIOCSR_BIT8			FIELD32(0x00000100)  /*   * BBPPCSR: BBP Pin control register. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b..3de0406735f 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); +	rt2x00_set_field32(®, GPIOCSR_DIR0, 1); +	rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2500pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9..89fee311d8f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)  	u16 reg;  	rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); -	return rt2x00_get_field32(reg, MAC_CSR19_BIT7); +	return rt2x00_get_field16(reg, MAC_CSR19_BIT7);  }  #ifdef CONFIG_RT2X00_LIB_LEDS @@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u16 reg;  	/*  	 * Allocate eeprom data. @@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); +	rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); +	rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2500usb_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7ee..196bd5103e4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h @@ -189,14 +189,15 @@   * MAC_CSR19: GPIO control register.   */  #define MAC_CSR19			0x0426 -#define MAC_CSR19_BIT0			FIELD32(0x0001) -#define MAC_CSR19_BIT1			FIELD32(0x0002) -#define MAC_CSR19_BIT2			FIELD32(0x0004) -#define MAC_CSR19_BIT3			FIELD32(0x0008) -#define MAC_CSR19_BIT4			FIELD32(0x0010) -#define MAC_CSR19_BIT5			FIELD32(0x0020) -#define MAC_CSR19_BIT6			FIELD32(0x0040) -#define MAC_CSR19_BIT7			FIELD32(0x0080) +#define MAC_CSR19_BIT0			FIELD16(0x0001) +#define MAC_CSR19_BIT1			FIELD16(0x0002) +#define MAC_CSR19_BIT2			FIELD16(0x0004) +#define MAC_CSR19_BIT3			FIELD16(0x0008) +#define MAC_CSR19_BIT4			FIELD16(0x0010) +#define MAC_CSR19_BIT5			FIELD16(0x0020) +#define MAC_CSR19_BIT6			FIELD16(0x0040) +#define MAC_CSR19_BIT7			FIELD16(0x0080) +#define MAC_CSR19_BIT8			FIELD16(0x0100)  /*   * MAC_CSR20: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cb8c2aca54e..b93516d832f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)  		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);  		msleep(1);  		rt2800_register_read(rt2x00dev, LDO_CFG0, ®); +		rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0);  		rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);  		rt2800_register_write(rt2x00dev, LDO_CFG0, reg);  	} diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 98aa426a356..4765bbd654c 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)  static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); +	rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); +	rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2800_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e2..6b4226b7161 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,  	skb_pull(entry->skb, RXINFO_DESC_SIZE);  	/* -	 * FIXME: we need to check for rx_pkt_len validity +	 * Check for rx_pkt_len validity. Return if invalid, leaving +	 * rxdesc->size zeroed out by the upper level.  	 */ +	if (unlikely(rx_pkt_len == 0 || +			rx_pkt_len > entry->queue->data_size)) { +		ERROR(entry->queue->rt2x00dev, +			"Bad frame size %d, forcing to 0\n", rx_pkt_len); +		return; +	} +  	rxd = (__le32 *)(entry->skb->data + rx_pkt_len);  	/* @@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)  static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); +	rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); +	rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt2800_probe_hw_mode(rt2x00dev); @@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x1690, 0x0744) },  	{ USB_DEVICE(0x1690, 0x0761) },  	{ USB_DEVICE(0x1690, 0x0764) }, +	/* ASUS */ +	{ USB_DEVICE(0x0b05, 0x179d) },  	/* Cisco */  	{ USB_DEVICE(0x167b, 0x4001) },  	/* EnGenius */ @@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = {  	{ USB_DEVICE(0x0b05, 0x1760) },  	{ USB_DEVICE(0x0b05, 0x1761) },  	{ USB_DEVICE(0x0b05, 0x1790) }, -	{ USB_DEVICE(0x0b05, 0x179d) },  	/* AzureWave */  	{ USB_DEVICE(0x13d3, 0x3262) },  	{ USB_DEVICE(0x13d3, 0x3284) }, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a..3f07e36f462 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)  	 */  	if (unlikely(rxdesc.size == 0 ||  		     rxdesc.size > entry->queue->data_size)) { -		WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", +		ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",  			rxdesc.size, entry->queue->data_size);  		dev_kfree_skb(entry->skb);  		goto renew_skb; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9..b8ec9616392 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Disable power saving. @@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); +	rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); +	rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt61pci_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0..8f3da5a5676 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry {  #define MAC_CSR13_BIT10			FIELD32(0x00000400)  #define MAC_CSR13_BIT11			FIELD32(0x00000800)  #define MAC_CSR13_BIT12			FIELD32(0x00001000) +#define MAC_CSR13_BIT13			FIELD32(0x00002000)  /*   * MAC_CSR14: LED control register. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859..248436c13ce 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)  static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  {  	int retval; +	u32 reg;  	/*  	 * Allocate eeprom data. @@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)  		return retval;  	/* +	 * Enable rfkill polling by setting GPIO direction of the +	 * rfkill switch GPIO pin correctly. +	 */ +	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); +	rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); +	rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); + +	/*  	 * Initialize hw specifications.  	 */  	retval = rt73usb_probe_hw_mode(rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d..df1cc116b83 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry {  #define MAC_CSR13_BIT10			FIELD32(0x00000400)  #define MAC_CSR13_BIT11			FIELD32(0x00000800)  #define MAC_CSR13_BIT12			FIELD32(0x00001000) +#define MAC_CSR13_BIT13			FIELD32(0x00002000) +#define MAC_CSR13_BIT14			FIELD32(0x00004000) +#define MAC_CSR13_BIT15			FIELD32(0x00008000)  /*   * MAC_CSR14: LED control register. diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 3782e1cd369..934d861a323 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -2196,10 +2196,8 @@ static int __init acer_wmi_init(void)  		interface->capability &= ~ACER_CAP_BRIGHTNESS;  		pr_info("Brightness must be controlled by acpi video driver\n");  	} else { -#ifdef CONFIG_ACPI_VIDEO  		pr_info("Disabling ACPI video driver\n");  		acpi_video_unregister(); -#endif  	}  	if (wmi_has_guid(WMID_GUID3)) { diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index dfb1a92ce94..db8f63841b4 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -101,7 +101,7 @@ static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,  	for (i = 0; i < 4; i++) {  		tmpval = (val >> (i * 8)) & 0xff; -		outb(tmpval, port + i); +		outb(tmpval, gmux_data->iostart + port + i);  	}  } @@ -142,8 +142,9 @@ static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port)  	u8 val;  	mutex_lock(&gmux_data->index_lock); -	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);  	gmux_index_wait_ready(gmux_data); +	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); +	gmux_index_wait_complete(gmux_data);  	val = inb(gmux_data->iostart + GMUX_PORT_VALUE);  	mutex_unlock(&gmux_data->index_lock); @@ -166,8 +167,9 @@ static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port)  	u32 val;  	mutex_lock(&gmux_data->index_lock); -	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);  	gmux_index_wait_ready(gmux_data); +	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); +	gmux_index_wait_complete(gmux_data);  	val = inl(gmux_data->iostart + GMUX_PORT_VALUE);  	mutex_unlock(&gmux_data->index_lock); @@ -461,18 +463,22 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,  	ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);  	if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {  		if (gmux_is_indexed(gmux_data)) { +			u32 version;  			mutex_init(&gmux_data->index_lock);  			gmux_data->indexed = true; +			version = gmux_read32(gmux_data, +				GMUX_PORT_VERSION_MAJOR); +			ver_major = (version >> 24) & 0xff; +			ver_minor = (version >> 16) & 0xff; +			ver_release = (version >> 8) & 0xff;  		} else {  			pr_info("gmux device not present\n");  			ret = -ENODEV;  			goto err_release;  		} -		pr_info("Found indexed gmux\n"); -	} else { -		pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, -			ver_release);  	} +	pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, +		ver_release, (gmux_data->indexed ? "indexed" : "classic"));  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_PLATFORM; @@ -505,9 +511,7 @@ static int __devinit gmux_probe(struct pnp_dev *pnp,  	 * Disable the other backlight choices.  	 */  	acpi_video_dmi_promote_vendor(); -#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)  	acpi_video_unregister(); -#endif  	apple_bl_unregister();  	gmux_data->power_state = VGA_SWITCHEROO_ON; @@ -593,9 +597,7 @@ static void __devexit gmux_remove(struct pnp_dev *pnp)  	kfree(gmux_data);  	acpi_video_dmi_demote_vendor(); -#if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE)  	acpi_video_register(); -#endif  	apple_bl_register();  } diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e38f91be0b1..4b568df5664 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -85,7 +85,7 @@ static char *wled_type = "unknown";  static char *bled_type = "unknown";  module_param(wled_type, charp, 0444); -MODULE_PARM_DESC(wlan_status, "Set the wled type on boot " +MODULE_PARM_DESC(wled_type, "Set the wled type on boot "  		 "(unknown, led or rfkill). "  		 "default is unknown"); @@ -863,9 +863,9 @@ static ssize_t show_infos(struct device *dev,  	 * The significance of others is yet to be found.  	 * If we don't find the method, we assume the device are present.  	 */ -	rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); +	rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp);  	if (!ACPI_FAILURE(rv)) -		len += sprintf(page + len, "HRWS value         : %#x\n", +		len += sprintf(page + len, "HWRS value         : %#x\n",  			       (uint) temp);  	/*  	 * Another value for userspace: the ASYM method returns 0x02 for @@ -1751,9 +1751,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus)  	 * The significance of others is yet to be found.  	 */  	status = -	    acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); +	    acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result);  	if (!ACPI_FAILURE(status)) -		pr_notice("  HRWS returned %x", (int)hwrs_result); +		pr_notice("  HWRS returned %x", (int)hwrs_result);  	if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))  		asus->have_rsts = true; diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 2eb9fe8e8ef..c0e9ff489b2 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -47,9 +47,7 @@  #include <linux/thermal.h>  #include <acpi/acpi_bus.h>  #include <acpi/acpi_drivers.h> -#ifdef CONFIG_ACPI_VIDEO  #include <acpi/video.h> -#endif  #include "asus-wmi.h" @@ -1704,10 +1702,8 @@ static int asus_wmi_add(struct platform_device *pdev)  	if (asus->driver->quirks->wmi_backlight_power)  		acpi_video_dmi_promote_vendor();  	if (!acpi_video_backlight_support()) { -#ifdef CONFIG_ACPI_VIDEO  		pr_info("Disabling ACPI video driver\n");  		acpi_video_unregister(); -#endif  		err = asus_wmi_backlight_init(asus);  		if (err && err != -ENODEV)  			goto fail_backlight; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dab91b48d22..5ca264179f4 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -610,12 +610,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  		if (!bus) {  			pr_warn("Unable to find PCI bus 1?\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {  			pr_err("Unable to read PCI config space?\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		absent = (l == 0xffffffff); @@ -627,7 +627,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  				absent ? "absent" : "present");  			pr_warn("skipped wireless hotplug as probably "  				"inappropriate for this model\n"); -			goto out_unlock; +			goto out_put_dev;  		}  		if (!blocked) { @@ -635,7 +635,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  			if (dev) {  				/* Device already present */  				pci_dev_put(dev); -				goto out_unlock; +				goto out_put_dev;  			}  			dev = pci_scan_single_device(bus, 0);  			if (dev) { @@ -650,6 +650,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)  				pci_dev_put(dev);  			}  		} +out_put_dev: +		pci_dev_put(port);  	}  out_unlock: diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c1ca7bcebb6..dd90d15f521 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -26,9 +26,7 @@  #include <linux/seq_file.h>  #include <linux/debugfs.h>  #include <linux/ctype.h> -#ifdef CONFIG_ACPI_VIDEO  #include <acpi/video.h> -#endif  /*   * This driver is needed because a number of Samsung laptops do not hook @@ -1558,9 +1556,7 @@ static int __init samsung_init(void)  		samsung->handle_backlight = false;  	} else if (samsung->quirks->broken_acpi_video) {  		pr_info("Disabling ACPI video driver\n"); -#ifdef CONFIG_ACPI_VIDEO  		acpi_video_unregister(); -#endif  	}  #endif diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 80e37794931..52daaa816e5 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -545,7 +545,7 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */   */  static int acpi_evalf(acpi_handle handle, -		      void *res, char *method, char *fmt, ...) +		      int *res, char *method, char *fmt, ...)  {  	char *fmt0 = fmt;  	struct acpi_object_list params; @@ -606,7 +606,7 @@ static int acpi_evalf(acpi_handle handle,  		success = (status == AE_OK &&  			   out_obj.type == ACPI_TYPE_INTEGER);  		if (success && res) -			*(int *)res = out_obj.integer.value; +			*res = out_obj.integer.value;  		break;  	case 'v':		/* void */  		success = status == AE_OK; @@ -7386,17 +7386,18 @@ static int fan_get_status(u8 *status)  	 * Add TPACPI_FAN_RD_ACPI_FANS ? */  	switch (fan_status_access_mode) { -	case TPACPI_FAN_RD_ACPI_GFAN: +	case TPACPI_FAN_RD_ACPI_GFAN: {  		/* 570, 600e/x, 770e, 770x */ +		int res; -		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) +		if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d")))  			return -EIO;  		if (likely(status)) -			*status = s & 0x07; +			*status = res & 0x07;  		break; - +	}  	case TPACPI_FAN_RD_TPEC:  		/* all except 570, 600e/x, 770e, 770x */  		if (unlikely(!acpi_ec_read(fan_status_offset, &s))) diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 0b66d0f2592..4b6688909fe 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  		writel(period_cycles, pc->mmio_base + CAP3);  	} +	if (!test_bit(PWMF_ENABLED, &pwm->flags)) { +		reg_val = readw(pc->mmio_base + ECCTL2); +		/* Disable APWM mode to put APWM output Low */ +		reg_val &= ~ECCTL2_APWM_MODE; +		writew(reg_val, pc->mmio_base + ECCTL2); +	} +  	pm_runtime_put_sync(pc->chip.dev);  	return 0;  } diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index c3756d1be19..b1996bcd5b7 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip {  	struct pwm_chip	chip;  	unsigned int	clk_rate;  	void __iomem	*mmio_base; +	unsigned long period_cycles[NUM_PWM_CHANNEL];  };  static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) @@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  	unsigned long long c;  	unsigned long period_cycles, duty_cycles;  	unsigned short ps_divval, tb_divval; +	int i;  	if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)  		return -ERANGE; @@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,  		duty_cycles = (unsigned long)c;  	} +	/* +	 * Period values should be same for multiple PWM channels as IP uses +	 * same period register for multiple channels. +	 */ +	for (i = 0; i < NUM_PWM_CHANNEL; i++) { +		if (pc->period_cycles[i] && +				(pc->period_cycles[i] != period_cycles)) { +			/* +			 * Allow channel to reconfigure period if no other +			 * channels being configured. +			 */ +			if (i == pwm->hwpwm) +				continue; + +			dev_err(chip->dev, "Period value conflicts with channel %d\n", +					i); +			return -EINVAL; +		} +	} + +	pc->period_cycles[pwm->hwpwm] = period_cycles; +  	/* Configure clock prescaler to support Low frequency PWM wave */  	if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval,  				&tb_divval)) { @@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)  static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)  { +	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); +  	if (test_bit(PWMF_ENABLED, &pwm->flags)) {  		dev_warn(chip->dev, "Removing PWM device without disabling\n");  		pm_runtime_put_sync(chip->dev);  	} + +	/* set period value to zero on free */ +	pc->period_cycles[pwm->hwpwm] = 0;  }  static const struct pwm_ops ehrpwm_pwm_ops = { diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77..ab00cab905b 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -22,6 +22,7 @@  #include <linux/err.h>  #include <linux/platform_device.h> +#include <linux/regulator/of_regulator.h>  #include <linux/regulator/driver.h>  #include <linux/regulator/machine.h>  #include <linux/mfd/tps65217.h> @@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = {  			   NULL),  }; +#ifdef CONFIG_OF +static struct of_regulator_match reg_matches[] = { +	{ .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, +	{ .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, +	{ .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, +	{ .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, +	{ .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, +	{ .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, +	{ .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, +}; + +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ +	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); +	struct device_node *node = tps->dev->of_node; +	struct tps65217_board *pdata; +	struct device_node *regs; +	int i, count; + +	regs = of_find_node_by_name(node, "regulators"); +	if (!regs) +		return NULL; + +	count = of_regulator_match(pdev->dev.parent, regs, +				reg_matches, TPS65217_NUM_REGULATOR); +	of_node_put(regs); +	if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) +		return NULL; + +	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); +	if (!pdata) +		return NULL; + +	for (i = 0; i < count; i++) { +		if (!reg_matches[i].init_data || !reg_matches[i].of_node) +			continue; + +		pdata->tps65217_init_data[i] = reg_matches[i].init_data; +		pdata->of_node[i] = reg_matches[i].of_node; +	} + +	return pdata; +} +#else +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ +	return NULL; +} +#endif +  static int __devinit tps65217_regulator_probe(struct platform_device *pdev)  { +	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); +	struct tps65217_board *pdata = dev_get_platdata(tps->dev); +	struct regulator_init_data *reg_data;  	struct regulator_dev *rdev; -	struct tps65217 *tps; -	struct tps_info *info = &tps65217_pmic_regs[pdev->id];  	struct regulator_config config = { }; +	int i, ret; -	/* Already set by core driver */ -	tps = dev_to_tps65217(pdev->dev.parent); -	tps->info[pdev->id] = info; +	if (tps->dev->of_node) +		pdata = tps65217_parse_dt(pdev); -	config.dev = &pdev->dev; -	config.of_node = pdev->dev.of_node; -	config.init_data = pdev->dev.platform_data; -	config.driver_data = tps; +	if (!pdata) { +		dev_err(&pdev->dev, "Platform data not found\n"); +		return -EINVAL; +	} + +	if (tps65217_chip_id(tps) != TPS65217) { +		dev_err(&pdev->dev, "Invalid tps chip version\n"); +		return -ENODEV; +	} + +	platform_set_drvdata(pdev, tps); + +	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { + +		reg_data = pdata->tps65217_init_data[i]; -	rdev = regulator_register(®ulators[pdev->id], &config); -	if (IS_ERR(rdev)) -		return PTR_ERR(rdev); +		/* +		 * Regulator API handles empty constraints but not NULL +		 * constraints +		 */ +		if (!reg_data) +			continue; -	platform_set_drvdata(pdev, rdev); +		/* Register the regulators */ +		tps->info[i] = &tps65217_pmic_regs[i]; +		config.dev = tps->dev; +		config.init_data = reg_data; +		config.driver_data = tps; +		config.regmap = tps->regmap; +		if (tps->dev->of_node) +			config.of_node = pdata->of_node[i]; + +		rdev = regulator_register(®ulators[i], &config); +		if (IS_ERR(rdev)) { +			dev_err(tps->dev, "failed to register %s regulator\n", +				pdev->name); +			ret = PTR_ERR(rdev); +			goto err_unregister_regulator; +		} + +		/* Save regulator for cleanup */ +		tps->rdev[i] = rdev; +	}  	return 0; + +err_unregister_regulator: +	while (--i >= 0) +		regulator_unregister(tps->rdev[i]); + +	return ret;  }  static int __devexit tps65217_regulator_remove(struct platform_device *pdev)  { -	struct regulator_dev *rdev = platform_get_drvdata(pdev); +	struct tps65217 *tps = platform_get_drvdata(pdev); +	unsigned int i; + +	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) +		regulator_unregister(tps->rdev[i]);  	platform_set_drvdata(pdev, NULL); -	regulator_unregister(rdev);  	return 0;  } diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e..ed38454228c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4066,7 +4066,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)  	spin_lock_init(&instance->cmd_pool_lock);  	spin_lock_init(&instance->hba_lock);  	spin_lock_init(&instance->completion_lock); -	spin_lock_init(&poll_aen_lock);  	mutex_init(&instance->aen_mutex);  	mutex_init(&instance->reset_mutex); @@ -5392,6 +5391,8 @@ static int __init megasas_init(void)  	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,  	       MEGASAS_EXT_VERSION); +	spin_lock_init(&poll_aen_lock); +  	support_poll_for_event = 2;  	support_device_change = 1; diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe775..b25757d1e91 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)  	}  	/* command line tunables  for max controller queue depth */ -	if (max_queue_depth != -1) -		max_request_credit = (max_queue_depth < facts->RequestCredit) -		    ? max_queue_depth : facts->RequestCredit; -	else +	if (max_queue_depth != -1 && max_queue_depth != 0) { +		max_request_credit = min_t(u16, max_queue_depth + +			ioc->hi_priority_depth + ioc->internal_depth, +			facts->RequestCredit); +		if (max_request_credit > MAX_HBA_QUEUE_DEPTH) +			max_request_credit =  MAX_HBA_QUEUE_DEPTH; +	} else  		max_request_credit = min_t(u16, facts->RequestCredit,  		    MAX_HBA_QUEUE_DEPTH); @@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)  	/* set the scsi host can_queue depth  	 * with some internal commands that could be outstanding  	 */ -	ioc->shost->can_queue = ioc->scsiio_depth - (2); +	ioc->shost->can_queue = ioc->scsiio_depth;  	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "  	    "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4a6381c8725..de2337f255a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -42,6 +42,8 @@  #include <trace/events/scsi.h> +static void scsi_eh_done(struct scsi_cmnd *scmd); +  #define SENSE_TIMEOUT		(10*HZ)  /* @@ -241,6 +243,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)  	if (! scsi_command_normalize_sense(scmd, &sshdr))  		return FAILED;	/* no valid sense data */ +	if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) +		/* +		 * nasty: for mid-layer issued TURs, we need to return the +		 * actual sense data without any recovery attempt.  For eh +		 * issued ones, we need to try to recover and interpret +		 */ +		return SUCCESS; +  	if (scsi_sense_is_deferred(&sshdr))  		return NEEDS_RETRY; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffd77739ae3..faa790fba13 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -776,7 +776,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)  	}  	if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ -		req->errors = result;  		if (result) {  			if (sense_valid && req->sense) {  				/* @@ -792,6 +791,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)  			if (!sense_deferred)  				error = __scsi_error_from_host_byte(cmd, result);  		} +		/* +		 * __scsi_error_from_host_byte may have reset the host_byte +		 */ +		req->errors = cmd->result;  		req->resid_len = scsi_get_resid(cmd); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56a93794c47..d947ffc20ce 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -764,6 +764,16 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,  	sdev->model = (char *) (sdev->inquiry + 16);  	sdev->rev = (char *) (sdev->inquiry + 32); +	if (strncmp(sdev->vendor, "ATA     ", 8) == 0) { +		/* +		 * sata emulation layer device.  This is a hack to work around +		 * the SATL power management specifications which state that +		 * when the SATL detects the device has gone into standby +		 * mode, it shall respond with NOT READY. +		 */ +		sdev->allow_restart = 1; +	} +  	if (*bflags & BLIST_ISROM) {  		sdev->type = TYPE_ROM;  		sdev->removable = 1; diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index d0cafd63719..f2ffd963f1c 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -51,10 +51,12 @@ enum android_alarm_return_flags {  #define ANDROID_ALARM_WAIT                  _IO('a', 1)  #define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size) +#define ALARM_IOR(c, type, size)            _IOR('a', (c) | ((type) << 4), size) +  /* Set alarm */  #define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)  #define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOR(4, type, struct timespec)  #define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)  #define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))  #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377262..cc8931fde83 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1412,6 +1412,13 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in dio200_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via dio200_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return dio200_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba9886b7..f5028790303 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -565,6 +565,13 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pc236_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pc236_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pc236_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ffebba..8191c4e28e0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -298,6 +298,13 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev,  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pc263_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pc263_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pc263_pci_common_attach(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e17f13e57f..8bf109e7bb0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1503,6 +1503,13 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)  			DRIVER_NAME ": BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pci224_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pci224_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pci224_attach_common(dev, pci_dev, NULL);  } diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1b67d0c61fa..66e74bd1226 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2925,6 +2925,13 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev,  			"amplc_pci230: BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in pci230_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via pci230_attach() +	 * has been removed. +	 */ +	pci_dev_get(pci_dev);  	return pci230_attach_common(dev, pci_dev);  } diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 874e02e4766..67a914a10b5 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -378,7 +378,7 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,  	int chan;  	lsb = data[0] & 0xff; -	msb = (data[0] >> 8) & 0xf; +	msb = (data[0] >> 8) & 0xff;  	chan = CR_CHAN(insn->chanspec); @@ -623,7 +623,7 @@ static const struct das08_board_struct das08_boards[] = {  		.ai = das08_ai_rinsn,  		.ai_nbits = 16,  		.ai_pg = das08_pg_none, -		.ai_encoding = das08_encode12, +		.ai_encoding = das08_encode16,  		.ao = das08jr_ao_winsn,  		.ao_nbits = 16,  		.di = das08jr_di_rbits, @@ -922,6 +922,13 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev)  		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");  		return -EINVAL;  	} +	/* +	 * Need to 'get' the PCI device to match the 'put' in das08_detach(). +	 * TODO: Remove the pci_dev_get() and matching pci_dev_put() once +	 * support for manual attachment of PCI devices via das08_attach() +	 * has been removed. +	 */ +	pci_dev_get(pdev);  	return das08_pci_attach_common(dev, pdev);  } diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967..f3da59063ed 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -121,8 +121,10 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,  	if (rx_array == NULL)  		return -ENOMEM;  	ret = lis3l02dq_read_all(indio_dev, rx_array); -	if (ret < 0) +	if (ret < 0) { +		kfree(rx_array);  		return ret; +	}  	for (i = 0; i < scan_count; i++)  		data[i] = combine_8_to_16(rx_array[i*4+1],  					rx_array[i*4+3]); diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 095837285f4..19a064d649e 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -647,6 +647,8 @@ static ssize_t ad7192_write_frequency(struct device *dev,  	ret = strict_strtoul(buf, 10, &lval);  	if (ret)  		return ret; +	if (lval == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock);  	if (iio_buffer_enabled(indio_dev)) { diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431287a..eb8e9d69efd 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -195,6 +195,8 @@ static ssize_t adis16260_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock);  	if (spi_get_device_id(st->us)) { diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c17779b5..a618327e06e 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -234,6 +234,8 @@ static ssize_t adis16400_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2..3ccff189f25 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -425,6 +425,8 @@ static ssize_t ade7753_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a5e87..abb1e9c8d09 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -445,6 +445,8 @@ static ssize_t ade7754_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa961..eb0a2a98f38 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -385,6 +385,8 @@ static ssize_t ade7759_write_frequency(struct device *dev,  	ret = strict_strtol(buf, 10, &val);  	if (ret)  		return ret; +	if (val == 0) +		return -EINVAL;  	mutex_lock(&indio_dev->mlock); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35f75b..d0a7e408efe 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)  	}  	ret = mfd_add_devices(nvec->dev, -1, nvec_devices, -			      ARRAY_SIZE(nvec_devices), base, 0); +			      ARRAY_SIZE(nvec_devices), base, 0, NULL);  	if (ret)  		dev_err(nvec->dev, "error adding subdevices\n"); diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 5e2856c0e0b..55e9c865585 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c @@ -48,13 +48,20 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode,  	mode->vsync_end = mode->vsync_start + timings->vsw;  	mode->vtotal = mode->vsync_end + timings->vbp; -	/* note: whether or not it is interlaced, +/- h/vsync, etc, -	 * which should be set in the mode flags, is not exposed in -	 * the omap_video_timings struct.. but hdmi driver tracks -	 * those separately so all we have to have to set the mode -	 * is the way to recover these timings values, and the -	 * omap_dss_driver would do the rest. -	 */ +	mode->flags = 0; + +	if (timings->interlace) +		mode->flags |= DRM_MODE_FLAG_INTERLACE; + +	if (timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) +		mode->flags |= DRM_MODE_FLAG_PHSYNC; +	else +		mode->flags |= DRM_MODE_FLAG_NHSYNC; + +	if (timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) +		mode->flags |= DRM_MODE_FLAG_PVSYNC; +	else +		mode->flags |= DRM_MODE_FLAG_NVSYNC;  }  static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, @@ -71,6 +78,22 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings,  	timings->vfp = mode->vsync_start - mode->vdisplay;  	timings->vsw = mode->vsync_end - mode->vsync_start;  	timings->vbp = mode->vtotal - mode->vsync_end; + +	timings->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); + +	if (mode->flags & DRM_MODE_FLAG_PHSYNC) +		timings->hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; +	else +		timings->hsync_level = OMAPDSS_SIG_ACTIVE_LOW; + +	if (mode->flags & DRM_MODE_FLAG_PVSYNC) +		timings->vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; +	else +		timings->vsync_level = OMAPDSS_SIG_ACTIVE_LOW; + +	timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; +	timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; +	timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;  }  static void omap_connector_dpms(struct drm_connector *connector, int mode) @@ -187,7 +210,7 @@ static int omap_connector_get_modes(struct drm_connector *connector)  		}  	} else {  		struct drm_display_mode *mode = drm_mode_create(dev); -		struct omap_video_timings timings; +		struct omap_video_timings timings = {0};  		dssdrv->get_timings(dssdev, &timings); @@ -291,7 +314,7 @@ void omap_connector_mode_set(struct drm_connector *connector,  	struct omap_connector *omap_connector = to_omap_connector(connector);  	struct omap_dss_device *dssdev = omap_connector->dssdev;  	struct omap_dss_driver *dssdrv = dssdev->driver; -	struct omap_video_timings timings; +	struct omap_video_timings timings = {0};  	copy_timings_drm_to_omap(&timings, mode); diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index d9832194580..758ce0a8d82 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -8,6 +8,7 @@  #include <linux/cdev.h>  #include <linux/uaccess.h>  #include <linux/netdevice.h> +#include <linux/etherdevice.h>  #include <linux/poll.h>  #include <linux/sched.h>  #include "ozconfig.h" @@ -213,7 +214,7 @@ static int oz_set_active_pd(u8 *addr)  		if (old_pd)  			oz_pd_put(old_pd);  	} else { -		if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) { +		if (is_zero_ether_addr(addr)) {  			spin_lock_bh(&g_cdev.lock);  			pd = g_cdev.active_pd;  			g_cdev.active_pd = 0; diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 0e26d5f6cf2..495ee1205e0 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c @@ -117,13 +117,8 @@ void r8712_recv_indicatepkt(struct _adapter *padapter,  	if (skb == NULL)  		goto _recv_indicatepkt_drop;  	skb->data = precv_frame->u.hdr.rx_data; -#ifdef NET_SKBUFF_DATA_USES_OFFSET -	skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - -		     precv_frame->u.hdr.rx_head); -#else -	skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; -#endif  	skb->len = precv_frame->u.hdr.len; +	skb_set_tail_pointer(skb, skb->len);  	if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))  		skb->ip_summed = CHECKSUM_UNNECESSARY;  	else diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a2b58..3aa895ec650 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -200,7 +200,7 @@ s_vProcessRxMACHeader (      } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {          cbHeaderSize += 6;          pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); -	if ((*pwType == cpu_to_le16(ETH_P_IPX)) || +	if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||  	    (*pwType == cpu_to_le16(0xF380))) {  		cbHeaderSize -= 8;              pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb464527fc1..b6e04e7b629 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1699,7 +1699,7 @@ s_bPacketToWirelessUsb(      // 802.1H      if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) {  	if (pDevice->dwDiagRefCount == 0) { -		if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || +		if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) ||  		    (psEthHeader->wType == cpu_to_le16(0xF380))) {  			memcpy((PBYTE) (pbyPayloadHead),  			       abySNAP_Bridgetunnel, 6); @@ -2838,10 +2838,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)      Packet_Type = skb->data[ETH_HLEN+1];      Descriptor_type = skb->data[ETH_HLEN+1+1+2];      Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); -    if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { -	/* 802.1x OR eapol-key challenge frame transfer */ -	if (((Protocol_Version == 1) || (Protocol_Version == 2)) && -		(Packet_Type == 3)) { +	if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { +		/* 802.1x OR eapol-key challenge frame transfer */ +		if (((Protocol_Version == 1) || (Protocol_Version == 2)) && +			(Packet_Type == 3)) {                          bTxeapol_key = TRUE;                         if(!(Key_info & BIT3) &&  //WPA or RSN group-key challenge  			   (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key @@ -2987,19 +2987,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)          }      } -    if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { -        if (pDevice->byBBType != BB_TYPE_11A) { -            pDevice->wCurrentRate = RATE_1M; -            pDevice->byACKRate = RATE_1M; -            pDevice->byTopCCKBasicRate = RATE_1M; -            pDevice->byTopOFDMBasicRate = RATE_6M; -        } else { -            pDevice->wCurrentRate = RATE_6M; -            pDevice->byACKRate = RATE_6M; -            pDevice->byTopCCKBasicRate = RATE_1M; -            pDevice->byTopOFDMBasicRate = RATE_6M; -        } -    } +	if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { +		if (pDevice->byBBType != BB_TYPE_11A) { +			pDevice->wCurrentRate = RATE_1M; +			pDevice->byACKRate = RATE_1M; +			pDevice->byTopCCKBasicRate = RATE_1M; +			pDevice->byTopOFDMBasicRate = RATE_6M; +		} else { +			pDevice->wCurrentRate = RATE_6M; +			pDevice->byACKRate = RATE_6M; +			pDevice->byTopCCKBasicRate = RATE_1M; +			pDevice->byTopOFDMBasicRate = RATE_6M; +		} +	}      DBG_PRT(MSG_LEVEL_DEBUG,  	    KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", @@ -3015,7 +3015,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb)      if (bNeedEncryption == TRUE) {          DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); -	if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { +	if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) {  		bNeedEncryption = FALSE;              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));              if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index fabff4d650e..0970127344e 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -327,9 +327,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,  	return result;  } -int prism2_scan(struct wiphy *wiphy, struct net_device *dev, -		struct cfg80211_scan_request *request) +int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)  { +	struct net_device *dev = request->wdev->netdev;  	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);  	wlandevice_t *wlandev = dev->ml_priv;  	struct p80211msg_dot11req_scan msg1; diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index c214977b4ab..52b43b7b83d 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1251,13 +1251,12 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw,  					void *pampd, struct tmem_pool *pool,  					struct tmem_oid *oid, uint32_t index)  { -	int ret = 0; -  	BUG_ON(!is_ephemeral(pool)); -	zbud_decompress((struct page *)(data), pampd); +	if (zbud_decompress((struct page *)(data), pampd) < 0) +		return -EINVAL;  	zbud_free_and_delist((struct zbud_hdr *)pampd);  	atomic_dec(&zcache_curr_eph_pampd_count); -	return ret; +	return 0;  }  /* diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce..6aba4395e8d 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1(  {  	struct iscsi_session *sess = NULL;  	struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; +	int ret;  	sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);  	if (!sess) { @@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1(  		return -ENOMEM;  	}  	spin_lock(&sess_idr_lock); -	idr_get_new(&sess_idr, NULL, &sess->session_index); +	ret = idr_get_new(&sess_idr, NULL, &sess->session_index);  	spin_unlock(&sess_idr_lock); +	if (ret < 0) { +		pr_err("idr_get_new() for sess_idr failed\n"); +		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, +				ISCSI_LOGIN_STATUS_NO_RESOURCES); +		kfree(sess); +		return -ENOMEM; +	} +  	sess->creation_time = get_jiffies_64();  	spin_lock_init(&sess->session_stats_lock);  	/* diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081..41641ba5482 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)  		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return -EINVAL;  	} +	if (cmd->data_length < 4) { +		pr_warn("SET TARGET PORT GROUPS parameter list length %u too" +			" small\n", cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(cmd);  	/* diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index cf2c66f3c11..9fc9a6006ca 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd)  	unsigned char *buf;  	u32 lun_count = 0, offset = 8, i; +	if (se_cmd->data_length < 16) { +		pr_warn("REPORT LUNS allocation length %u too small\n", +			se_cmd->data_length); +		se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(se_cmd);  	if (!buf)  		return -ENOMEM; diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836e..9ba495477fd 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd)  	struct iblock_dev *ibd = dev->dev_ptr;  	unsigned char *buf, *ptr = NULL;  	sector_t lba; -	int size = cmd->data_length; +	int size;  	u32 range;  	int ret = 0;  	int dl, bd_dl; +	if (cmd->data_length < 8) { +		pr_warn("UNMAP parameter list length %u too small\n", +			cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		return -EINVAL; +	} +  	buf = transport_kmap_data_sg(cmd);  	dl = get_unaligned_be16(&buf[0]);  	bd_dl = get_unaligned_be16(&buf[2]); -	size = min(size - 8, bd_dl); +	size = cmd->data_length - 8; +	if (bd_dl > size) +		pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", +			cmd->data_length, bd_dl); +	else +		size = bd_dl; +  	if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {  		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;  		ret = -EINVAL; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c37..956c84c6b66 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port(  	tidh_new->dest_local_nexus = 1;  	list_add_tail(&tidh_new->dest_list, &tid_dest_list); +	if (cmd->data_length < 28) { +		pr_warn("SPC-PR: Received PR OUT parameter list" +			" length too small: %u\n", cmd->data_length); +		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; +		ret = -EINVAL; +		goto out; +	} +  	buf = transport_kmap_data_sg(cmd);  	/*  	 * For a PERSISTENT RESERVE OUT specify initiator ports payload, diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 5552fa7426b..9d7ce3daa26 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -667,7 +667,8 @@ static void pscsi_free_device(void *p)  	kfree(pdv);  } -static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) +static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, +				     unsigned char *sense_buffer)  {  	struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;  	struct scsi_device *sd = pdv->pdv_sd; @@ -679,7 +680,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	 * not been allocated because TCM is handling the emulation directly.  	 */  	if (!pt) -		return 0; +		return;  	cdb = &pt->pscsi_cdb[0];  	result = pt->pscsi_result; @@ -687,11 +688,11 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	 * Hack to make sure that Write-Protect modepage is set if R/O mode is  	 * forced.  	 */ +	if (!cmd->se_deve || !cmd->data_length) +		goto after_mode_sense; +  	if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) &&  	     (status_byte(result) << 1) == SAM_STAT_GOOD) { -		if (!cmd->se_deve) -			goto after_mode_sense; -  		if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) {  			unsigned char *buf = transport_kmap_data_sg(cmd); @@ -708,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg)  	}  after_mode_sense: -	if (sd->type != TYPE_TAPE) +	if (sd->type != TYPE_TAPE || !cmd->data_length)  		goto after_mode_select;  	/* @@ -750,10 +751,10 @@ after_mode_sense:  	}  after_mode_select: -	if (status_byte(result) & CHECK_CONDITION) -		return 1; - -	return 0; +	if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) { +		memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER); +		cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; +	}  }  enum { @@ -1184,13 +1185,6 @@ fail:  	return -ENOMEM;  } -static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) -{ -	struct pscsi_plugin_task *pt = cmd->priv; - -	return pt->pscsi_sense; -} -  /*	pscsi_get_device_rev():   *   * @@ -1273,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = {  	.check_configfs_dev_params = pscsi_check_configfs_dev_params,  	.set_configfs_dev_params = pscsi_set_configfs_dev_params,  	.show_configfs_dev_params = pscsi_show_configfs_dev_params, -	.get_sense_buffer	= pscsi_get_sense_buffer,  	.get_device_rev		= pscsi_get_device_rev,  	.get_device_type	= pscsi_get_device_type,  	.get_blocks		= pscsi_get_blocks, diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 4c861de538c..388a922c8f6 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd)  static int spc_emulate_request_sense(struct se_cmd *cmd)  {  	unsigned char *cdb = cmd->t_task_cdb; -	unsigned char *buf; +	unsigned char *rbuf;  	u8 ua_asc = 0, ua_ascq = 0; -	int err = 0; +	unsigned char buf[SE_SENSE_BUF]; + +	memset(buf, 0, SE_SENSE_BUF);  	if (cdb[1] & 0x01) {  		pr_err("REQUEST_SENSE description emulation not" @@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		return -ENOSYS;  	} -	buf = transport_kmap_data_sg(cmd); - -	if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { +	rbuf = transport_kmap_data_sg(cmd); +	if (cmd->scsi_sense_reason != 0) { +		/* +		 * Out of memory.  We will fail with CHECK CONDITION, so +		 * we must not clear the unit attention condition. +		 */ +		target_complete_cmd(cmd, CHECK_CONDITION); +		return 0; +	} else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {  		/*  		 * CURRENT ERROR, UNIT ATTENTION  		 */  		buf[0] = 0x70;  		buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; -		if (cmd->data_length < 18) { -			buf[7] = 0x00; -			err = -EINVAL; -			goto end; -		}  		/*  		 * The Additional Sense Code (ASC) from the UNIT ATTENTION  		 */ @@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		buf[0] = 0x70;  		buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; -		if (cmd->data_length < 18) { -			buf[7] = 0x00; -			err = -EINVAL; -			goto end; -		}  		/*  		 * NO ADDITIONAL SENSE INFORMATION  		 */ @@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)  		buf[7] = 0x0A;  	} -end: -	transport_kunmap_data_sg(cmd); +	if (rbuf) { +		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); +		transport_kunmap_data_sg(cmd); +	} +  	target_complete_cmd(cmd, GOOD);  	return 0;  } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4de3186dc44..269f5448839 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work)  	transport_generic_request_failure(cmd);  } +/* + * Used when asking transport to copy Sense Data from the underlying + * Linux/SCSI struct scsi_cmnd + */ +static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) +{ +	unsigned char *buffer = cmd->sense_buffer; +	struct se_device *dev = cmd->se_dev; +	u32 offset = 0; + +	WARN_ON(!cmd->se_lun); + +	if (!dev) +		return NULL; + +	if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) +		return NULL; + +	offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); + +	/* Automatically padded */ +	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; + +	pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", +		dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); +	return &buffer[offset]; +} +  void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)  {  	struct se_device *dev = cmd->se_dev; @@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)  	cmd->transport_state &= ~CMD_T_BUSY;  	if (dev && dev->transport->transport_complete) { -		if (dev->transport->transport_complete(cmd, -				cmd->t_data_sg) != 0) { -			cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; +		dev->transport->transport_complete(cmd, +				cmd->t_data_sg, +				transport_get_sense_buffer(cmd)); +		if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)  			success = 1; -		}  	}  	/* @@ -1181,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)  			/* Returns CHECK_CONDITION + INVALID_CDB_FIELD */  			goto out_invalid_cdb_field;  		} - +		/* +		 * For the overflow case keep the existing fabric provided +		 * ->data_length.  Otherwise for the underflow case, reset +		 * ->data_length to the smaller SCSI expected data transfer +		 * length. +		 */  		if (size > cmd->data_length) {  			cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;  			cmd->residual_count = (size - cmd->data_length);  		} else {  			cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;  			cmd->residual_count = (cmd->data_length - size); +			cmd->data_length = size;  		} -		cmd->data_length = size;  	}  	return 0; @@ -1816,61 +1849,6 @@ execute:  EXPORT_SYMBOL(target_execute_cmd);  /* - * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd - */ -static int transport_get_sense_data(struct se_cmd *cmd) -{ -	unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; -	struct se_device *dev = cmd->se_dev; -	unsigned long flags; -	u32 offset = 0; - -	WARN_ON(!cmd->se_lun); - -	if (!dev) -		return 0; - -	spin_lock_irqsave(&cmd->t_state_lock, flags); -	if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { -		spin_unlock_irqrestore(&cmd->t_state_lock, flags); -		return 0; -	} - -	if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) -		goto out; - -	if (!dev->transport->get_sense_buffer) { -		pr_err("dev->transport->get_sense_buffer is NULL\n"); -		goto out; -	} - -	sense_buffer = dev->transport->get_sense_buffer(cmd); -	if (!sense_buffer) { -		pr_err("ITT 0x%08x cmd %p: Unable to locate" -			" sense buffer for task with sense\n", -			cmd->se_tfo->get_task_tag(cmd), cmd); -		goto out; -	} - -	spin_unlock_irqrestore(&cmd->t_state_lock, flags); - -	offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); - -	memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); - -	/* Automatically padded */ -	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; - -	pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", -		dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); -	return 0; - -out: -	spin_unlock_irqrestore(&cmd->t_state_lock, flags); -	return -1; -} - -/*   * Process all commands up to the last received ORDERED task attribute which   * requires another blocking boundary   */ @@ -1985,7 +1963,7 @@ static void transport_handle_queue_full(  static void target_complete_ok_work(struct work_struct *work)  {  	struct se_cmd *cmd = container_of(work, struct se_cmd, work); -	int reason = 0, ret; +	int ret;  	/*  	 * Check if we need to move delayed/dormant tasks from cmds on the @@ -2002,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work)  		schedule_work(&cmd->se_dev->qf_work_queue);  	/* -	 * Check if we need to retrieve a sense buffer from +	 * Check if we need to send a sense buffer from  	 * the struct se_cmd in question.  	 */  	if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { -		if (transport_get_sense_data(cmd) < 0) -			reason = TCM_NON_EXISTENT_LUN; - -		if (cmd->scsi_status) { -			ret = transport_send_check_condition_and_sense( -					cmd, reason, 1); -			if (ret == -EAGAIN || ret == -ENOMEM) -				goto queue_full; +		WARN_ON(!cmd->scsi_status); +		ret = transport_send_check_condition_and_sense( +					cmd, 0, 1); +		if (ret == -EAGAIN || ret == -ENOMEM) +			goto queue_full; -			transport_lun_remove_cmd(cmd); -			transport_cmd_check_stop_to_fabric(cmd); -			return; -		} +		transport_lun_remove_cmd(cmd); +		transport_cmd_check_stop_to_fabric(cmd); +		return;  	}  	/*  	 * Check for a callback, used by amongst other things @@ -2216,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	struct page **pages;  	int i; -	BUG_ON(!sg);  	/*  	 * We need to take into account a possible offset here for fabrics like  	 * tcm_loop who may be using a contig buffer from the SCSI midlayer for @@ -2224,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	 */  	if (!cmd->t_data_nents)  		return NULL; -	else if (cmd->t_data_nents == 1) + +	BUG_ON(!sg); +	if (cmd->t_data_nents == 1)  		return kmap(sg_page(sg)) + sg->offset;  	/* >1 page. use vmap */  	pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); -	if (!pages) +	if (!pages) { +		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return NULL; +	}  	/* convert sg[] to pages[] */  	for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { @@ -2239,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)  	cmd->t_data_vmap = vmap(pages, cmd->t_data_nents,  VM_MAP, PAGE_KERNEL);  	kfree(pages); -	if (!cmd->t_data_vmap) +	if (!cmd->t_data_vmap) { +		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;  		return NULL; +	}  	return cmd->t_data_vmap + cmd->t_data_sg[0].offset;  } @@ -2326,19 +2305,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd)  	 * into the fabric for data transfers, go ahead and complete it right  	 * away.  	 */ -	if (!cmd->data_length) { +	if (!cmd->data_length && +	    cmd->t_task_cdb[0] != REQUEST_SENSE && +	    cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {  		spin_lock_irq(&cmd->t_state_lock);  		cmd->t_state = TRANSPORT_COMPLETE;  		cmd->transport_state |= CMD_T_ACTIVE;  		spin_unlock_irq(&cmd->t_state_lock); -		if (cmd->t_task_cdb[0] == REQUEST_SENSE) { -			u8 ua_asc = 0, ua_ascq = 0; - -			core_scsi3_ua_clear_for_request_sense(cmd, -					&ua_asc, &ua_ascq); -		} -  		INIT_WORK(&cmd->work, target_complete_ok_work);  		queue_work(target_completion_wq, &cmd->work);  		return 0; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 72ec56e6d42..5952b25c288 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -132,6 +132,7 @@  #define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */  #define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */  #define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */ +#define  UFCR_DCEDTE	 (1<<6)  /* DCE/DTE mode select */  #define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */  #define  UFCR_RFDIV_REG(x)	(((x) < 7 ? 6 - (x) : 6) << 7)  #define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */ @@ -667,22 +668,11 @@ static void imx_break_ctl(struct uart_port *port, int break_state)  static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)  {  	unsigned int val; -	unsigned int ufcr_rfdiv; - -	/* set receiver / transmitter trigger level. -	 * RFDIV is set such way to satisfy requested uartclk value -	 */ -	val = TXTL << 10 | RXTL; -	ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2) -			/ sport->port.uartclk; - -	if(!ufcr_rfdiv) -		ufcr_rfdiv = 1; - -	val |= UFCR_RFDIV_REG(ufcr_rfdiv); +	/* set receiver / transmitter trigger level */ +	val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); +	val |= TXTL << UFCR_TXTL_SHF | RXTL;  	writel(val, sport->port.membase + UFCR); -  	return 0;  } @@ -754,6 +744,7 @@ static int imx_startup(struct uart_port *port)  		}  	} +	spin_lock_irqsave(&sport->port.lock, flags);  	/*  	 * Finally, clear and enable interrupts  	 */ @@ -807,7 +798,6 @@ static int imx_startup(struct uart_port *port)  	/*  	 * Enable modem status interrupts  	 */ -	spin_lock_irqsave(&sport->port.lock,flags);  	imx_enable_ms(&sport->port);  	spin_unlock_irqrestore(&sport->port.lock,flags); @@ -837,10 +827,13 @@ static void imx_shutdown(struct uart_port *port)  {  	struct imx_port *sport = (struct imx_port *)port;  	unsigned long temp; +	unsigned long flags; +	spin_lock_irqsave(&sport->port.lock, flags);  	temp = readl(sport->port.membase + UCR2);  	temp &= ~(UCR2_TXEN);  	writel(temp, sport->port.membase + UCR2); +	spin_unlock_irqrestore(&sport->port.lock, flags);  	if (USE_IRDA(sport)) {  		struct imxuart_platform_data *pdata; @@ -869,12 +862,14 @@ static void imx_shutdown(struct uart_port *port)  	 * Disable all interrupts, port and break condition.  	 */ +	spin_lock_irqsave(&sport->port.lock, flags);  	temp = readl(sport->port.membase + UCR1);  	temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);  	if (USE_IRDA(sport))  		temp &= ~(UCR1_IREN);  	writel(temp, sport->port.membase + UCR1); +	spin_unlock_irqrestore(&sport->port.lock, flags);  }  static void @@ -1217,6 +1212,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	struct imx_port *sport = imx_ports[co->index];  	struct imx_port_ucrs old_ucr;  	unsigned int ucr1; +	unsigned long flags; + +	spin_lock_irqsave(&sport->port.lock, flags);  	/*  	 *	First, save UCR1/2/3 and then disable interrupts @@ -1242,6 +1240,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	while (!(readl(sport->port.membase + USR2) & USR2_TXDC));  	imx_port_ucrs_restore(&sport->port, &old_ucr); + +	spin_unlock_irqrestore(&sport->port.lock, flags);  }  /* diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c7a032a4f0c..d214448b677 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n)  }  /** - * hw_device_state: enables/disables interrupts & starts/stops device (execute - *                  without interruption) + * hw_device_state: enables/disables interrupts (execute without interruption)   * @dma: 0 => disable, !0 => enable and set dma engine   *   * This function returns an error code @@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma)  		/* interrupt, error, port change, reset, sleep/suspend */  		hw_write(ci, OP_USBINTR, ~0,  			     USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); -		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);  	} else { -		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);  		hw_write(ci, OP_USBINTR, ~0, 0);  	}  	return 0; @@ -774,10 +771,7 @@ __acquires(mEp->lock)  {  	struct ci13xxx_req *mReq, *mReqTemp;  	struct ci13xxx_ep *mEpTemp = mEp; -	int uninitialized_var(retval); - -	if (list_empty(&mEp->qh.queue)) -		return -EINVAL; +	int retval = 0;  	list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,  			queue) { @@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)  	return -ENOTSUPP;  } +/* Change Data+ pullup status + * this func is used by usb_gadget_connect/disconnet + */ +static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) +{ +	struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); + +	if (is_on) +		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); +	else +		hw_write(ci, OP_USBCMD, USBCMD_RS, 0); + +	return 0; +} +  static int ci13xxx_start(struct usb_gadget *gadget,  			 struct usb_gadget_driver *driver);  static int ci13xxx_stop(struct usb_gadget *gadget, @@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget,  static const struct usb_gadget_ops usb_gadget_ops = {  	.vbus_session	= ci13xxx_vbus_session,  	.wakeup		= ci13xxx_wakeup, +	.pullup		= ci13xxx_pullup,  	.vbus_draw	= ci13xxx_vbus_draw,  	.udc_start	= ci13xxx_start,  	.udc_stop	= ci13xxx_stop, @@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci)  			mEp->ep.name      = mEp->name;  			mEp->ep.ops       = &usb_ep_ops; -			mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; +			/* +			 * for ep0: maxP defined in desc, for other +			 * eps, maxP is set by epautoconfig() called +			 * by gadget layer +			 */ +			mEp->ep.maxpacket = (unsigned short)~0;  			INIT_LIST_HEAD(&mEp->qh.queue);  			mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, @@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci)  				else  					ci->ep0in = mEp; +				mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;  				continue;  			} @@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci)  	return retval;  } +static void destroy_eps(struct ci13xxx *ci) +{ +	int i; + +	for (i = 0; i < ci->hw_ep_max; i++) { +		struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; + +		dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); +	} +} +  /**   * ci13xxx_start: register a gadget driver   * @gadget: our gadget @@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci)  	if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) {  		if (ci->transceiver == NULL) {  			retval = -ENODEV; -			goto free_pools; +			goto destroy_eps;  		}  	} @@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci)  remove_trans:  	if (!IS_ERR_OR_NULL(ci->transceiver)) { -		otg_set_peripheral(ci->transceiver->otg, &ci->gadget); +		otg_set_peripheral(ci->transceiver->otg, NULL);  		if (ci->global_phy)  			usb_put_phy(ci->transceiver);  	} @@ -1742,6 +1769,8 @@ unreg_device:  put_transceiver:  	if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy)  		usb_put_phy(ci->transceiver); +destroy_eps: +	destroy_eps(ci);  free_pools:  	dma_pool_destroy(ci->td_pool);  free_qh_pool: @@ -1756,18 +1785,12 @@ free_qh_pool:   */  static void udc_stop(struct ci13xxx *ci)  { -	int i; -  	if (ci == NULL)  		return;  	usb_del_gadget_udc(&ci->gadget); -	for (i = 0; i < ci->hw_ep_max; i++) { -		struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; - -		dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); -	} +	destroy_eps(ci);  	dma_pool_destroy(ci->td_pool);  	dma_pool_destroy(ci->qh_pool); diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 65a55abb791..5f0cb417b73 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -109,12 +109,14 @@ static struct usb_driver wdm_driver;  /* return intfdata if we own the interface, else look up intf in the list */  static struct wdm_device *wdm_find_device(struct usb_interface *intf)  { -	struct wdm_device *desc = NULL; +	struct wdm_device *desc;  	spin_lock(&wdm_device_list_lock);  	list_for_each_entry(desc, &wdm_device_list, device_list)  		if (desc->intf == intf) -			break; +			goto found; +	desc = NULL; +found:  	spin_unlock(&wdm_device_list_lock);  	return desc; @@ -122,12 +124,14 @@ static struct wdm_device *wdm_find_device(struct usb_interface *intf)  static struct wdm_device *wdm_find_device_by_minor(int minor)  { -	struct wdm_device *desc = NULL; +	struct wdm_device *desc;  	spin_lock(&wdm_device_list_lock);  	list_for_each_entry(desc, &wdm_device_list, device_list)  		if (desc->intf->minor == minor) -			break; +			goto found; +	desc = NULL; +found:  	spin_unlock(&wdm_device_list_lock);  	return desc; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f15501f4c58..e77a8e8eaa2 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = {  	{ USB_DEVICE(0x04b4, 0x0526), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, +	/* Microchip Joss Optical infrared touchboard device */ +	{ USB_DEVICE(0x04d8, 0x000c), .driver_info = +			USB_QUIRK_CONFIG_INTF_STRINGS }, +  	/* Samsung Android phone modem - ID conflict with SPH-I500 */  	{ USB_DEVICE(0x04e8, 0x6601), .driver_info =  			USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c34452a7304..a68ff53124d 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -436,16 +436,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev)  		dev_err(dev, "missing IRQ\n");  		return -ENODEV;  	} -	dwc->xhci_resources[1] = *res; +	dwc->xhci_resources[1].start = res->start; +	dwc->xhci_resources[1].end = res->end; +	dwc->xhci_resources[1].flags = res->flags; +	dwc->xhci_resources[1].name = res->name;  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!res) {  		dev_err(dev, "missing memory resource\n");  		return -ENODEV;  	} -	dwc->xhci_resources[0] = *res; +	dwc->xhci_resources[0].start = res->start;  	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +  					DWC3_XHCI_REGS_END; +	dwc->xhci_resources[0].flags = res->flags; +	dwc->xhci_resources[0].name = res->name;  	 /*  	  * Request memory region but exclude xHCI regs, diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9b94886b66e..e4d5ca86b9d 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -720,7 +720,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,  		transferred = min_t(u32, ur->length,  				transfer_size - length);  		memcpy(ur->buf, dwc->ep0_bounce, transferred); -		dwc->ep0_bounced = false;  	} else {  		transferred = ur->length - length;  	} diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 58fdfad96b4..c2813c2b005 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,  	if (req->request.status == -EINPROGRESS)  		req->request.status = status; -	usb_gadget_unmap_request(&dwc->gadget, &req->request, -			req->direction); +	if (dwc->ep0_bounced && dep->number == 0) +		dwc->ep0_bounced = false; +	else +		usb_gadget_unmap_request(&dwc->gadget, &req->request, +				req->direction);  	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",  			req, dep->name, req->request.actual, @@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,  	if (list_empty(&dep->request_list)) {  		dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",  			dep->name); +		dep->flags |= DWC3_EP_PENDING_REQUEST;  		return;  	} @@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)  	if (dep->flags & DWC3_EP_PENDING_REQUEST) {  		int	ret; +		/* +		 * If xfernotready is already elapsed and it is a case +		 * of isoc transfer, then issue END TRANSFER, so that +		 * you can receive xfernotready again and can have +		 * notion of current microframe. +		 */ +		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { +			dwc3_stop_active_transfer(dwc, dep->number); +			return 0; +		} +  		ret = __dwc3_gadget_kick_transfer(dep, 0, true);  		if (ret && ret != -EBUSY) {  			struct dwc3	*dwc = dep->dwc; diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index c9e66dfb02e..1e35963bd4e 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,  	unsigned long	flags;  	if (!_ep || !ep -			|| !desc || ep->ep.desc -			|| _ep->name == ep0name +			|| !desc || _ep->name == ep0name  			|| desc->bDescriptorType != USB_DT_ENDPOINT  			|| (maxpacket = usb_endpoint_maxp(desc)) == 0  			|| maxpacket > ep->maxpacket) { @@ -530,7 +529,6 @@ ok:  	tmp |= AT91_UDP_EPEDS;  	__raw_writel(tmp, ep->creg); -	ep->ep.desc = desc;  	ep->ep.maxpacket = maxpacket;  	/* @@ -1635,7 +1633,6 @@ static int at91_start(struct usb_gadget *gadget,  	udc->driver = driver;  	udc->gadget.dev.driver = &driver->driver;  	udc->gadget.dev.of_node = udc->pdev->dev.of_node; -	dev_set_drvdata(&udc->gadget.dev, &driver->driver);  	udc->enabled = 1;  	udc->selfpowered = 1; @@ -1656,7 +1653,6 @@ static int at91_stop(struct usb_gadget *gadget,  	spin_unlock_irqrestore(&udc->lock, flags);  	udc->gadget.dev.driver = NULL; -	dev_set_drvdata(&udc->gadget.dev, NULL);  	udc->driver = NULL;  	DBG("unbound from %s\n", driver->driver.name); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027a..afdbb1cbf5d 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1916,6 +1916,27 @@ done:  	return retval;  } +/* usb 3.0 root hub device descriptor */ +struct { +	struct usb_bos_descriptor bos; +	struct usb_ss_cap_descriptor ss_cap; +} __packed usb3_bos_desc = { + +	.bos = { +		.bLength		= USB_DT_BOS_SIZE, +		.bDescriptorType	= USB_DT_BOS, +		.wTotalLength		= cpu_to_le16(sizeof(usb3_bos_desc)), +		.bNumDeviceCaps		= 1, +	}, +	.ss_cap = { +		.bLength		= USB_DT_USB_SS_CAP_SIZE, +		.bDescriptorType	= USB_DT_DEVICE_CAPABILITY, +		.bDevCapabilityType	= USB_SS_CAP_TYPE, +		.wSpeedSupported	= cpu_to_le16(USB_5GBPS_OPERATION), +		.bFunctionalitySupport	= ilog2(USB_5GBPS_OPERATION), +	}, +}; +  static inline void  ss_hub_descriptor(struct usb_hub_descriptor *desc)  { @@ -2006,6 +2027,18 @@ static int dummy_hub_control(  		else  			hub_descriptor((struct usb_hub_descriptor *) buf);  		break; + +	case DeviceRequest | USB_REQ_GET_DESCRIPTOR: +		if (hcd->speed != HCD_USB3) +			goto error; + +		if ((wValue >> 8) != USB_DT_BOS) +			goto error; + +		memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); +		retval = sizeof(usb3_bos_desc); +		break; +  	case GetHubStatus:  		*(__le32 *) buf = cpu_to_le32(0);  		break; @@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)  	hs_hcd->has_tt = 1;  	retval = usb_add_hcd(hs_hcd, 0, 0); -	if (retval != 0) { -		usb_put_hcd(hs_hcd); -		return retval; -	} +	if (retval) +		goto put_usb2_hcd;  	if (mod_data.is_super_speed) {  		ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, @@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev)  put_usb3_hcd:  	usb_put_hcd(ss_hcd);  dealloc_usb2_hcd: +	usb_remove_hcd(hs_hcd); +put_usb2_hcd:  	usb_put_hcd(hs_hcd);  	the_controller.hs_hcd = the_controller.ss_hcd = NULL;  	return retval; diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8adc79d1b40..829aba75a6d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -34,11 +34,15 @@  /* Debugging ****************************************************************/  #ifdef VERBOSE_DEBUG +#ifndef pr_vdebug  #  define pr_vdebug pr_debug +#endif /* pr_vdebug */  #  define ffs_dump_mem(prefix, ptr, len) \  	print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len)  #else +#ifndef pr_vdebug  #  define pr_vdebug(...)                 do { } while (0) +#endif /* pr_vdebug */  #  define ffs_dump_mem(prefix, ptr, len) do { } while (0)  #endif /* VERBOSE_DEBUG */ diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b13e0bb5f5b..0bb617e1dda 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3599,6 +3599,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)  	if (hsotg->num_of_eps == 0) {  		dev_err(dev, "wrong number of EPs (zero)\n"); +		ret = -EINVAL;  		goto err_supplies;  	} @@ -3606,6 +3607,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)  		      GFP_KERNEL);  	if (!eps) {  		dev_err(dev, "cannot get memory\n"); +		ret = -ENOMEM;  		goto err_supplies;  	} @@ -3622,6 +3624,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)  						     GFP_KERNEL);  	if (!hsotg->ctrl_req) {  		dev_err(dev, "failed to allocate ctrl req\n"); +		ret = -ENOMEM;  		goto err_ep_mem;  	} diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 2b5534c2ab8..f1739526820 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -132,11 +132,15 @@ static unsigned	n_ports;  #ifdef VERBOSE_DEBUG +#ifndef pr_vdebug  #define pr_vdebug(fmt, arg...) \  	pr_debug(fmt, ##arg) +#endif /* pr_vdebug */  #else +#ifndef pr_vdebig  #define pr_vdebug(fmt, arg...) \  	({ if (0) pr_debug(fmt, ##arg); }) +#endif /* pr_vdebug */  #endif  /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9bc39ca460c..4b66374bdc8 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)  	else {  		qtd = list_entry (qh->qtd_list.next,  				struct ehci_qtd, qtd_list); -		/* first qtd may already be partially processed */ -		if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) +		/* +		 * first qtd may already be partially processed. +		 * If we come here during unlink, the QH overlay region +		 * might have reference to the just unlinked qtd. The +		 * qtd is updated in qh_completions(). Update the QH +		 * overlay here. +		 */ +		if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { +			qh->hw->hw_qtd_next = qtd->hw_next;  			qtd = NULL; +		}  	}  	if (qtd) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a665b3eaa74..aaa8d2bce21 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -570,6 +570,16 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)  	if (pdata) {  		at91_for_each_port(i) { +			/* +			 * do not configure PIO if not in relation with +			 * real USB port on board +			 */ +			if (i >= pdata->ports) { +				pdata->vbus_pin[i] = -EINVAL; +				pdata->overcurrent_pin[i] = -EINVAL; +				break; +			} +  			if (!gpio_is_valid(pdata->vbus_pin[i]))  				continue;  			gpio = pdata->vbus_pin[i]; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c5e9e4a76f1..966d1484ee7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -75,7 +75,9 @@  #define	NB_PIF0_PWRDOWN_1	0x01100013  #define USB_INTEL_XUSB2PR      0xD0 +#define USB_INTEL_USB2PRM      0xD4  #define USB_INTEL_USB3_PSSEN   0xD8 +#define USB_INTEL_USB3PRM      0xDC  static struct amd_chipset_info {  	struct pci_dev	*nb_dev; @@ -772,10 +774,18 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)  		return;  	} -	ports_available = 0xffffffff; +	/* Read USB3PRM, the USB 3.0 Port Routing Mask Register +	 * Indicate the ports that can be changed from OS. +	 */ +	pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, +			&ports_available); + +	dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", +			ports_available); +  	/* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable -	 * Register, to turn on SuperSpeed terminations for all -	 * available ports. +	 * Register, to turn on SuperSpeed terminations for the +	 * switchable ports.  	 */  	pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,  			cpu_to_le32(ports_available)); @@ -785,7 +795,16 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)  	dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled "  			"under xHCI: 0x%x\n", ports_available); -	ports_available = 0xffffffff; +	/* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register +	 * Indicate the USB 2.0 ports to be controlled by the xHCI host. +	 */ + +	pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, +			&ports_available); + +	dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", +			ports_available); +  	/* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to  	 * switch the USB 2.0 power and data lines over to the xHCI  	 * host. @@ -822,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	void __iomem *op_reg_base;  	u32 val;  	int timeout; +	int len = pci_resource_len(pdev, 0);  	if (!mmio_resource_enabled(pdev, 0))  		return; -	base = ioremap_nocache(pci_resource_start(pdev, 0), -				pci_resource_len(pdev, 0)); +	base = ioremap_nocache(pci_resource_start(pdev, 0), len);  	if (base == NULL)  		return; @@ -837,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	 */  	ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET);  	do { +		if ((ext_cap_offset + sizeof(val)) > len) { +			/* We're reading garbage from the controller */ +			dev_warn(&pdev->dev, +				 "xHCI controller failing to respond"); +			return; +		} +  		if (!ext_cap_offset)  			/* We've reached the end of the extended capabilities */  			goto hc_init; +  		val = readl(base + ext_cap_offset);  		if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)  			break; @@ -870,9 +897,10 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)  	/* Disable any BIOS SMIs and clear all SMI events*/  	writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); +hc_init:  	if (usb_is_intel_switchable_xhci(pdev))  		usb_enable_xhci_ports(pdev); -hc_init: +  	op_reg_base = base + XHCI_HC_LENGTH(readl(base));  	/* Wait for the host controller to be ready before writing any diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ef004a5de20..7f69a39163c 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -15,6 +15,7 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);  static inline void usb_amd_quirk_pll_disable(void) {}  static inline void usb_amd_quirk_pll_enable(void) {}  static inline void usb_amd_dev_put(void) {} +static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}  #endif  /* CONFIG_PCI */  #endif  /*  __LINUX_USB_PCI_QUIRKS_H  */ diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 74bfc868b7a..d5eb357aa5c 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -493,11 +493,48 @@ static void xhci_hub_report_link_state(u32 *status, u32 status_reg)  		 * when this bit is set.  		 */  		pls |= USB_PORT_STAT_CONNECTION; +	} else { +		/* +		 * If CAS bit isn't set but the Port is already at +		 * Compliance Mode, fake a connection so the USB core +		 * notices the Compliance state and resets the port. +		 * This resolves an issue generated by the SN65LVPE502CP +		 * in which sometimes the port enters compliance mode +		 * caused by a delay on the host-device negotiation. +		 */ +		if (pls == USB_SS_PORT_LS_COMP_MOD) +			pls |= USB_PORT_STAT_CONNECTION;  	} +  	/* update status field */  	*status |= pls;  } +/* + * Function for Compliance Mode Quirk. + * + * This Function verifies if all xhc USB3 ports have entered U0, if so, + * the compliance mode timer is deleted. A port won't enter + * compliance mode if it has previously entered U0. + */ +void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) +{ +	u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1); +	bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); + +	if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) +		return; + +	if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { +		xhci->port_status_u0 |= 1 << wIndex; +		if (xhci->port_status_u0 == all_ports_seen_u0) { +			del_timer_sync(&xhci->comp_mode_recovery_timer); +			xhci_dbg(xhci, "All USB3 ports have entered U0 already!\n"); +			xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted.\n"); +		} +	} +} +  int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		u16 wIndex, char *buf, u16 wLength)  { @@ -651,6 +688,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		/* Update Port Link State for super speed ports*/  		if (hcd->speed == HCD_USB3) {  			xhci_hub_report_link_state(&status, temp); +			/* +			 * Verify if all USB3 Ports Have entered U0 already. +			 * Delete Compliance Mode Timer if so. +			 */ +			xhci_del_comp_mod_timer(xhci, temp, wIndex);  		}  		if (bus_state->port_c_suspend & (1 << wIndex))  			status |= 1 << USB_PORT_FEAT_C_SUSPEND; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 689bc18b051..df90fe51b4a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -118,7 +118,7 @@ static int xhci_plat_probe(struct platform_device *pdev)  		goto put_hcd;  	} -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); +	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);  	if (!hcd->regs) {  		dev_dbg(&pdev->dev, "error mapping memory\n");  		ret = -EFAULT; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c59d5b5b6c7..6ece0ed288d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -26,6 +26,7 @@  #include <linux/module.h>  #include <linux/moduleparam.h>  #include <linux/slab.h> +#include <linux/dmi.h>  #include "xhci.h" @@ -398,6 +399,95 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)  #endif +static void compliance_mode_recovery(unsigned long arg) +{ +	struct xhci_hcd *xhci; +	struct usb_hcd *hcd; +	u32 temp; +	int i; + +	xhci = (struct xhci_hcd *)arg; + +	for (i = 0; i < xhci->num_usb3_ports; i++) { +		temp = xhci_readl(xhci, xhci->usb3_ports[i]); +		if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { +			/* +			 * Compliance Mode Detected. Letting USB Core +			 * handle the Warm Reset +			 */ +			xhci_dbg(xhci, "Compliance Mode Detected->Port %d!\n", +					i + 1); +			xhci_dbg(xhci, "Attempting Recovery routine!\n"); +			hcd = xhci->shared_hcd; + +			if (hcd->state == HC_STATE_SUSPENDED) +				usb_hcd_resume_root_hub(hcd); + +			usb_hcd_poll_rh_status(hcd); +		} +	} + +	if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) +		mod_timer(&xhci->comp_mode_recovery_timer, +			jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); +} + +/* + * Quirk to work around issue generated by the SN65LVPE502CP USB3.0 re-driver + * that causes ports behind that hardware to enter compliance mode sometimes. + * The quirk creates a timer that polls every 2 seconds the link state of + * each host controller's port and recovers it by issuing a Warm reset + * if Compliance mode is detected, otherwise the port will become "dead" (no + * device connections or disconnections will be detected anymore). Becasue no + * status event is generated when entering compliance mode (per xhci spec), + * this quirk is needed on systems that have the failing hardware installed. + */ +static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) +{ +	xhci->port_status_u0 = 0; +	init_timer(&xhci->comp_mode_recovery_timer); + +	xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; +	xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; +	xhci->comp_mode_recovery_timer.expires = jiffies + +			msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); + +	set_timer_slack(&xhci->comp_mode_recovery_timer, +			msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); +	add_timer(&xhci->comp_mode_recovery_timer); +	xhci_dbg(xhci, "Compliance Mode Recovery Timer Initialized.\n"); +} + +/* + * This function identifies the systems that have installed the SN65LVPE502CP + * USB3.0 re-driver and that need the Compliance Mode Quirk. + * Systems: + * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 + */ +static bool compliance_mode_recovery_timer_quirk_check(void) +{ +	const char *dmi_product_name, *dmi_sys_vendor; + +	dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); +	dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); + +	if (!(strstr(dmi_sys_vendor, "Hewlett-Packard"))) +		return false; + +	if (strstr(dmi_product_name, "Z420") || +			strstr(dmi_product_name, "Z620") || +			strstr(dmi_product_name, "Z820")) +		return true; + +	return false; +} + +static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci) +{ +	return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1)); +} + +  /*   * Initialize memory for HCD and xHC (one-time init).   * @@ -421,6 +511,12 @@ int xhci_init(struct usb_hcd *hcd)  	retval = xhci_mem_init(xhci, GFP_KERNEL);  	xhci_dbg(xhci, "Finished xhci_init\n"); +	/* Initializing Compliance Mode Recovery Data If Needed */ +	if (compliance_mode_recovery_timer_quirk_check()) { +		xhci->quirks |= XHCI_COMP_MODE_QUIRK; +		compliance_mode_recovery_timer_init(xhci); +	} +  	return retval;  } @@ -629,6 +725,11 @@ void xhci_stop(struct usb_hcd *hcd)  	del_timer_sync(&xhci->event_ring_timer);  #endif +	/* Deleting Compliance Mode Recovery Timer */ +	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && +			(!(xhci_all_ports_seen_u0(xhci)))) +		del_timer_sync(&xhci->comp_mode_recovery_timer); +  	if (xhci->quirks & XHCI_AMD_PLL_FIX)  		usb_amd_dev_put(); @@ -659,7 +760,7 @@ void xhci_shutdown(struct usb_hcd *hcd)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd); -	if (xhci->quirks && XHCI_SPURIOUS_REBOOT) +	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)  		usb_disable_xhci_ports(to_pci_dev(hcd->self.controller));  	spin_lock_irq(&xhci->lock); @@ -806,6 +907,16 @@ int xhci_suspend(struct xhci_hcd *xhci)  	}  	spin_unlock_irq(&xhci->lock); +	/* +	 * Deleting Compliance Mode Recovery Timer because the xHCI Host +	 * is about to be suspended. +	 */ +	if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && +			(!(xhci_all_ports_seen_u0(xhci)))) { +		del_timer_sync(&xhci->comp_mode_recovery_timer); +		xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted!\n"); +	} +  	/* step 5: remove core well power */  	/* synchronize irq when using MSI-X */  	xhci_msix_sync_irqs(xhci); @@ -938,6 +1049,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  		usb_hcd_resume_root_hub(hcd);  		usb_hcd_resume_root_hub(xhci->shared_hcd);  	} + +	/* +	 * If system is subject to the Quirk, Compliance Mode Timer needs to +	 * be re-initialized Always after a system resume. Ports are subject +	 * to suffer the Compliance Mode issue again. It doesn't matter if +	 * ports have entered previously to U0 before system's suspension. +	 */ +	if (xhci->quirks & XHCI_COMP_MODE_QUIRK) +		compliance_mode_recovery_timer_init(xhci); +  	return retval;  }  #endif	/* CONFIG_PM */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c713256297a..1a05908c667 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1495,6 +1495,7 @@ struct xhci_hcd {  #define XHCI_LPM_SUPPORT	(1 << 11)  #define XHCI_INTEL_HOST		(1 << 12)  #define XHCI_SPURIOUS_REBOOT	(1 << 13) +#define XHCI_COMP_MODE_QUIRK	(1 << 14)  	unsigned int		num_active_eps;  	unsigned int		limit_active_eps;  	/* There are two roothubs to keep track of bus suspend info for */ @@ -1511,6 +1512,11 @@ struct xhci_hcd {  	unsigned		sw_lpm_support:1;  	/* support xHCI 1.0 spec USB2 hardware LPM */  	unsigned		hw_lpm_support:1; +	/* Compliance Mode Recovery Data */ +	struct timer_list	comp_mode_recovery_timer; +	u32			port_status_u0; +/* Compliance Mode Timer Triggered every 2 seconds */ +#define COMP_MODE_RCVRY_MSECS 2000  };  /* convert between an HCD pointer and the corresponding EHCI_HCD */ diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4bb717d0bd4..1ae378d5fc6 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2049,7 +2049,7 @@ static int musb_urb_enqueue(  	 * we only have work to do in the former case.  	 */  	spin_lock_irqsave(&musb->lock, flags); -	if (hep->hcpriv) { +	if (hep->hcpriv || !next_urb(qh)) {  		/* some concurrent activity submitted another urb to hep...  		 * odd, rare, error prone, but legal.  		 */ diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 57a608584e1..c1be687e00e 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -388,7 +388,7 @@ dma_controller_create(struct musb *musb, void __iomem *base)  	struct platform_device *pdev = to_platform_device(dev);  	int irq = platform_get_irq_byname(pdev, "dma"); -	if (irq == 0) { +	if (irq <= 0) {  		dev_err(dev, "No DMA interrupt line!\n");  		return NULL;  	} diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1a1bd9cf40c..34162544237 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1215,7 +1215,7 @@ static int __devinit tusb_probe(struct platform_device *pdev)  	ret = platform_device_add(musb);  	if (ret) {  		dev_err(&pdev->dev, "failed to register musb device\n"); -		goto err1; +		goto err2;  	}  	return 0; diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ecd173032fd..143c4e9e1be 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -818,7 +818,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)  	    usbhs_pipe_is_dcp(pipe))  		goto usbhsf_pio_prepare_push; -	if (len % 4) /* 32bit alignment */ +	if (len & 0x7) /* 8byte alignment */  		goto usbhsf_pio_prepare_push;  	if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ @@ -905,7 +905,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)  	/* use PIO if packet is less than pio_dma_border */  	len = usbhsf_fifo_rcv_len(priv, fifo);  	len = min(pkt->length - pkt->actual, len); -	if (len % 4) /* 32bit alignment */ +	if (len & 0x7) /* 8byte alignment */  		goto usbhsf_pio_prepare_pop_unselect;  	if (len < usbhs_get_dparam(priv, pio_dma_border)) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 24e3e19849a..0c8d1c22627 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -704,6 +704,7 @@ static struct usb_device_id id_table_combined [] = {  	{ USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },  	{ USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, +	{ USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },  	{ USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, @@ -804,13 +805,32 @@ static struct usb_device_id id_table_combined [] = {  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, -	{ USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, +					USB_CLASS_VENDOR_SPEC, +					USB_SUBCLASS_VENDOR_SPEC, 0x00) },  	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },  	{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),  		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },  	{ USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },  	{ USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, +	{ USB_DEVICE(FTDI_VID, PI_C865_PID) }, +	{ USB_DEVICE(FTDI_VID, PI_C857_PID) }, +	{ USB_DEVICE(PI_VID, PI_C866_PID) }, +	{ USB_DEVICE(PI_VID, PI_C663_PID) }, +	{ USB_DEVICE(PI_VID, PI_C725_PID) }, +	{ USB_DEVICE(PI_VID, PI_E517_PID) }, +	{ USB_DEVICE(PI_VID, PI_C863_PID) },  	{ USB_DEVICE(PI_VID, PI_E861_PID) }, +	{ USB_DEVICE(PI_VID, PI_C867_PID) }, +	{ USB_DEVICE(PI_VID, PI_E609_PID) }, +	{ USB_DEVICE(PI_VID, PI_E709_PID) }, +	{ USB_DEVICE(PI_VID, PI_100F_PID) }, +	{ USB_DEVICE(PI_VID, PI_1011_PID) }, +	{ USB_DEVICE(PI_VID, PI_1012_PID) }, +	{ USB_DEVICE(PI_VID, PI_1013_PID) }, +	{ USB_DEVICE(PI_VID, PI_1014_PID) }, +	{ USB_DEVICE(PI_VID, PI_1015_PID) }, +	{ USB_DEVICE(PI_VID, PI_1016_PID) },  	{ USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },  	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },  	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5dd96ca6c38..41fe5826100 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -75,6 +75,9 @@  #define FTDI_OPENDCC_GATEWAY_PID	0xBFDB  #define FTDI_OPENDCC_GBM_PID	0xBFDC +/* NZR SEM 16+ USB (http://www.nzr.de) */ +#define FTDI_NZR_SEM_USB_PID	0xC1E0	/* NZR SEM-LOG16+ */ +  /*   * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com)   */ @@ -539,7 +542,10 @@  /*   * Microchip Technology, Inc.   * - * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: + * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are + * used by single function CDC ACM class based firmware demo + * applications.  The VID/PID has also been used in firmware + * emulating FTDI serial chips by:   * Hornby Elite - Digital Command Control Console   * http://www.hornby.com/hornby-dcc/controllers/   */ @@ -791,8 +797,27 @@   * Physik Instrumente   * http://www.physikinstrumente.com/en/products/   */ +/* These two devices use the VID of FTDI */ +#define PI_C865_PID	0xe0a0  /* PI C-865 Piezomotor Controller */ +#define PI_C857_PID	0xe0a1  /* PI Encoder Trigger Box */ +  #define PI_VID              0x1a72  /* Vendor ID */ -#define PI_E861_PID         0x1008  /* E-861 piezo controller USB connection */ +#define PI_C866_PID	0x1000  /* PI C-866 Piezomotor Controller */ +#define PI_C663_PID	0x1001  /* PI C-663 Mercury-Step */ +#define PI_C725_PID	0x1002  /* PI C-725 Piezomotor Controller */ +#define PI_E517_PID	0x1005  /* PI E-517 Digital Piezo Controller Operation Module */ +#define PI_C863_PID	0x1007  /* PI C-863 */ +#define PI_E861_PID	0x1008  /* PI E-861 Piezomotor Controller */ +#define PI_C867_PID	0x1009  /* PI C-867 Piezomotor Controller */ +#define PI_E609_PID	0x100D  /* PI E-609 Digital Piezo Controller */ +#define PI_E709_PID	0x100E  /* PI E-709 Digital Piezo Controller */ +#define PI_100F_PID	0x100F  /* PI Digital Piezo Controller */ +#define PI_1011_PID	0x1011  /* PI Digital Piezo Controller */ +#define PI_1012_PID	0x1012  /* PI Motion Controller */ +#define PI_1013_PID	0x1013  /* PI Motion Controller */ +#define PI_1014_PID	0x1014  /* PI Device */ +#define PI_1015_PID	0x1015  /* PI Device */ +#define PI_1016_PID	0x1016  /* PI Digital Servo Module */  /*   * Kondo Kagaku Co.Ltd. diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index cc40f47ecea..5ce88d1bc6f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -886,8 +886,6 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),  	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, -	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), -	  .driver_info = (kernel_ulong_t)&net_intf3_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1092,6 +1090,10 @@ static const struct usb_device_id option_ids[] = {  	 .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },  	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),  	 .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, +	{ USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, +  	{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },  	{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },  	{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 38b42e7bc91..b6501558174 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1371,10 +1371,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,  	if (srcid) {  		srcgroup = find_qgroup_rb(fs_info, srcid); -		if (!srcgroup) { -			ret = -EINVAL; +		if (!srcgroup)  			goto unlock; -		}  		dstgroup->rfer = srcgroup->rfer - level_size;  		dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size;  		srcgroup->excl = level_size; @@ -1383,10 +1381,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,  		qgroup_dirty(fs_info, srcgroup);  	} -	if (!inherit) { -		ret = -EINVAL; +	if (!inherit)  		goto unlock; -	}  	i_qgroups = (u64 *)(inherit + 1);  	for (i = 0; i < inherit->num_qgroups; ++i) { diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 9154192b068..71e9ad9f596 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -917,7 +917,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)  	if (!buf) {  		mutex_unlock(&cinode->lock_mutex);  		free_xid(xid); -		return rc; +		return -ENOMEM;  	}  	for (i = 0; i < 2; i++) { diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index c5fbfac5d57..15dc8eea827 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -96,7 +96,7 @@   *   */ -#define SMB2_HEADER_STRUCTURE_SIZE __constant_le16_to_cpu(64) +#define SMB2_HEADER_STRUCTURE_SIZE __constant_cpu_to_le16(64)  struct smb2_hdr {  	__be32 smb2_buf_length;	/* big endian on wire */ @@ -140,7 +140,7 @@ struct smb2_pdu {   *   */ -#define SMB2_ERROR_STRUCTURE_SIZE2 __constant_le16_to_cpu(9) +#define SMB2_ERROR_STRUCTURE_SIZE2 __constant_cpu_to_le16(9)  struct smb2_err_rsp {  	struct smb2_hdr hdr; diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 44ce5c6a541..d45ba456812 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -275,8 +275,14 @@ out:  static int ecryptfs_flush(struct file *file, fl_owner_t td)  { -	return file->f_mode & FMODE_WRITE -	       ? filemap_write_and_wait(file->f_mapping) : 0; +	struct file *lower_file = ecryptfs_file_to_lower(file); + +	if (lower_file->f_op && lower_file->f_op->flush) { +		filemap_write_and_wait(file->f_mapping); +		return lower_file->f_op->flush(lower_file, td); +	} + +	return 0;  }  static int ecryptfs_release(struct inode *inode, struct file *file) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 534b129ea67..cc7709e7c50 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,  	struct dentry *lower_old_dir_dentry;  	struct dentry *lower_new_dir_dentry;  	struct dentry *trap = NULL; +	struct inode *target_inode;  	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);  	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); @@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,  	dget(lower_new_dentry);  	lower_old_dir_dentry = dget_parent(lower_old_dentry);  	lower_new_dir_dentry = dget_parent(lower_new_dentry); +	target_inode = new_dentry->d_inode;  	trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);  	/* source should not be ancestor of target */  	if (trap == lower_old_dentry) { @@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,  			lower_new_dir_dentry->d_inode, lower_new_dentry);  	if (rc)  		goto out_lock; +	if (target_inode) +		fsstack_copy_attr_all(target_inode, +				      ecryptfs_inode_to_lower(target_inode));  	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);  	if (new_dir != old_dir)  		fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 2768138eefe..9b627c15010 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode)  	inode_info = ecryptfs_inode_to_private(inode);  	if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count,  				      &inode_info->lower_file_mutex)) { +		filemap_write_and_wait(inode->i_mapping);  		fput(inode_info->lower_file);  		inode_info->lower_file = NULL;  		mutex_unlock(&inode_info->lower_file_mutex); diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a07597307fd..ff574b4e345 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -3072,6 +3072,8 @@ static int ext3_do_update_inode(handle_t *handle,  	struct ext3_inode_info *ei = EXT3_I(inode);  	struct buffer_head *bh = iloc->bh;  	int err = 0, rc, block; +	int need_datasync = 0; +	__le32 disksize;  	uid_t i_uid;  	gid_t i_gid; @@ -3113,7 +3115,11 @@ again:  		raw_inode->i_gid_high = 0;  	}  	raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); -	raw_inode->i_size = cpu_to_le32(ei->i_disksize); +	disksize = cpu_to_le32(ei->i_disksize); +	if (disksize != raw_inode->i_size) { +		need_datasync = 1; +		raw_inode->i_size = disksize; +	}  	raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);  	raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);  	raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); @@ -3129,8 +3135,11 @@ again:  	if (!S_ISREG(inode->i_mode)) {  		raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);  	} else { -		raw_inode->i_size_high = -			cpu_to_le32(ei->i_disksize >> 32); +		disksize = cpu_to_le32(ei->i_disksize >> 32); +		if (disksize != raw_inode->i_size_high) { +			raw_inode->i_size_high = disksize; +			need_datasync = 1; +		}  		if (ei->i_disksize > 0x7fffffffULL) {  			struct super_block *sb = inode->i_sb;  			if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, @@ -3183,6 +3192,8 @@ again:  	ext3_clear_inode_state(inode, EXT3_STATE_NEW);  	atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); +	if (need_datasync) +		atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid);  out_brelse:  	brelse (bh);  	ext3_std_error(inode->i_sb, err); diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 03ff5b1eba9..75a20c092dd 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -117,7 +117,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file,  					      const char __user *buf,  					      size_t count, loff_t *ppos)  { -	unsigned val; +	unsigned uninitialized_var(val);  	ssize_t ret;  	ret = fuse_conn_limit_write(file, buf, count, ppos, &val, @@ -154,7 +154,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file,  						    const char __user *buf,  						    size_t count, loff_t *ppos)  { -	unsigned val; +	unsigned uninitialized_var(val);  	ssize_t ret;  	ret = fuse_conn_limit_write(file, buf, count, ppos, &val, diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 3426521f320..ee8d5504229 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -396,7 +396,7 @@ err_device:  err_region:  	unregister_chrdev_region(devt, 1);  err: -	fc->conn_error = 1; +	fuse_conn_kill(fc);  	goto out;  } @@ -532,8 +532,6 @@ static int cuse_channel_release(struct inode *inode, struct file *file)  		cdev_del(cc->cdev);  	} -	/* kill connection and shutdown channel */ -	fuse_conn_kill(&cc->fc);  	rc = fuse_dev_release(inode, file);	/* puts the base reference */  	return rc; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 7df2b5e8fbe..f4246cfc8d8 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1576,6 +1576,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,  		req->pages[req->num_pages] = page;  		req->num_pages++; +		offset = 0;  		num -= this_num;  		total_len += this_num;  		index++; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ce0a2838ccd..fca222dabe3 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -367,11 +367,6 @@ void fuse_conn_kill(struct fuse_conn *fc)  	wake_up_all(&fc->waitq);  	wake_up_all(&fc->blocked_waitq);  	wake_up_all(&fc->reserved_req_waitq); -	mutex_lock(&fuse_mutex); -	list_del(&fc->entry); -	fuse_ctl_remove_conn(fc); -	mutex_unlock(&fuse_mutex); -	fuse_bdi_destroy(fc);  }  EXPORT_SYMBOL_GPL(fuse_conn_kill); @@ -380,7 +375,14 @@ static void fuse_put_super(struct super_block *sb)  	struct fuse_conn *fc = get_fuse_conn_super(sb);  	fuse_send_destroy(fc); +  	fuse_conn_kill(fc); +	mutex_lock(&fuse_mutex); +	list_del(&fc->entry); +	fuse_ctl_remove_conn(fc); +	mutex_unlock(&fuse_mutex); +	fuse_bdi_destroy(fc); +  	fuse_conn_put(fc);  } diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index d1d791ef38d..382000ffac1 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -323,6 +323,29 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  }  /** + * gfs2_size_hint - Give a hint to the size of a write request + * @file: The struct file + * @offset: The file offset of the write + * @size: The length of the write + * + * When we are about to do a write, this function records the total + * write size in order to provide a suitable hint to the lower layers + * about how many blocks will be required. + * + */ + +static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) +{ +	struct inode *inode = filep->f_dentry->d_inode; +	struct gfs2_sbd *sdp = GFS2_SB(inode); +	struct gfs2_inode *ip = GFS2_I(inode); +	size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; +	int hint = min_t(size_t, INT_MAX, blks); + +	atomic_set(&ip->i_res->rs_sizehint, hint); +} + +/**   * gfs2_allocate_page_backing - Use bmap to allocate blocks   * @page: The (locked) page to allocate backing for   * @@ -382,8 +405,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)  	if (ret)  		return ret; -	atomic_set(&ip->i_res->rs_sizehint, -		   PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); +	gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE);  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);  	ret = gfs2_glock_nq(&gh); @@ -663,7 +685,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  	if (ret)  		return ret; -	atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); +	gfs2_size_hint(file, pos, writesize); +  	if (file->f_flags & O_APPEND) {  		struct gfs2_holder gh; @@ -789,7 +812,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,  	if (unlikely(error))  		goto out_uninit; -	atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); +	gfs2_size_hint(file, offset, len);  	while (len > 0) {  		if (len < bytes) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 4ce22e54730..753af3d86bb 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1722,7 +1722,9 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);  	ret = gfs2_glock_nq(&gh);  	if (ret == 0) { -		ret = generic_setxattr(dentry, name, data, size, flags); +		ret = gfs2_rs_alloc(ip); +		if (ret == 0) +			ret = generic_setxattr(dentry, name, data, size, flags);  		gfs2_glock_dq(&gh);  	}  	gfs2_holder_uninit(&gh); @@ -1757,7 +1759,9 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);  	ret = gfs2_glock_nq(&gh);  	if (ret == 0) { -		ret = generic_removexattr(dentry, name); +		ret = gfs2_rs_alloc(ip); +		if (ret == 0) +			ret = generic_removexattr(dentry, name);  		gfs2_glock_dq(&gh);  	}  	gfs2_holder_uninit(&gh); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4d34887a601..c9ed814eeb6 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1961,7 +1961,7 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd)   * @dinode: 1 if this block is a dinode block, otherwise data block   * @nblocks: desired extent length   * - * Lay claim to previously allocated block reservation blocks. + * Lay claim to previously reserved blocks.   * Returns: Starting block number of the blocks claimed.   * Sets *nblocks to the actual extent length allocated.   */ @@ -1970,19 +1970,17 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode,  {  	struct gfs2_blkreserv *rs = ip->i_res;  	struct gfs2_rgrpd *rgd = rs->rs_rgd; -	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);  	struct gfs2_bitmap *bi;  	u64 start_block = gfs2_rs_startblk(rs);  	const unsigned int elen = *nblocks; -	/*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ -	gfs2_assert_withdraw(sdp, rgd); -	/*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/  	bi = rs->rs_bi;  	gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);  	for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { -		/* Make sure the bitmap hasn't changed */ +		if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, +				 bi->bi_len, rs->rs_biblk) != GFS2_BLKST_FREE) +			break;  		gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk,  			    dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);  		rs->rs_biblk++; @@ -1991,20 +1989,12 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode,  		BUG_ON(!rgd->rd_reserved);  		rgd->rd_reserved--;  		dinode = false; -		trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM);  	} -	if (!rs->rs_free) { -		struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; - +	trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); +	if (!rs->rs_free || *nblocks != elen)  		gfs2_rs_deltree(rs); -		/* -nblocks because we haven't returned to do the math yet. -		   I'm doing the math backwards to prevent negative numbers, -		   but think of it as: -		   if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ -		if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) -			rg_mblk_search(rgd, ip); -	} +  	return start_block;  } @@ -2037,34 +2027,34 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,  	if (ip->i_res->rs_requested == 0)  		return -ECANCELED; -	/* Check if we have a multi-block reservation, and if so, claim the -	   next free block from it. */ +	/* If we have a reservation, claim blocks from it. */  	if (gfs2_rs_active(ip->i_res)) {  		BUG_ON(!ip->i_res->rs_free);  		rgd = ip->i_res->rs_rgd;  		block = claim_reserved_blks(ip, dinode, nblocks); -	} else { -		rgd = ip->i_rgd; +		if (*nblocks) +			goto found_blocks; +	} -		if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) -			goal = ip->i_goal - rgd->rd_data0; -		else -			goal = rgd->rd_last_alloc; +	rgd = ip->i_rgd; -		blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); +	if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) +		goal = ip->i_goal - rgd->rd_data0; +	else +		goal = rgd->rd_last_alloc; -		/* Since all blocks are reserved in advance, this shouldn't -		   happen */ -		if (blk == BFITNOENT) { -			printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", -			       *nblocks); -			printk(KERN_WARNING "FULL=%d\n", -			       test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); -			goto rgrp_error; -		} +	blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); -		block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); +	/* Since all blocks are reserved in advance, this shouldn't happen */ +	if (blk == BFITNOENT) { +		printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); +		printk(KERN_WARNING "FULL=%d\n", +		       test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); +		goto rgrp_error;  	} + +	block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); +found_blocks:  	ndata = *nblocks;  	if (dinode)  		ndata--; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 75d6d0a3d32..6a7fcab7ecb 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -287,10 +287,12 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)  	struct inode *inode = file->f_path.dentry->d_inode;  	ret = filemap_write_and_wait_range(inode->i_mapping, start, end); +	if (ret != 0) +		goto out;  	mutex_lock(&inode->i_mutex);  	ret = nfs_file_fsync_commit(file, start, end, datasync);  	mutex_unlock(&inode->i_mutex); - +out:  	return ret;  } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c6e895f0fbf..9b47610338f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -154,7 +154,7 @@ static void nfs_zap_caches_locked(struct inode *inode)  	nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);  	nfsi->attrtimeo_timestamp = jiffies; -	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); +	memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf));  	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))  		nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;  	else diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d6b3b5f2d77..69322096c32 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -643,7 +643,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,  		  u64 cookie, struct page **pages, unsigned int count, int plus)  {  	struct inode		*dir = dentry->d_inode; -	__be32			*verf = NFS_COOKIEVERF(dir); +	__be32			*verf = NFS_I(dir)->cookieverf;  	struct nfs3_readdirargs	arg = {  		.fh		= NFS_FH(dir),  		.cookie		= cookie, diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index acb65e7887f..eb5eb8eef4d 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -96,13 +96,15 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)  	struct inode *inode = file->f_path.dentry->d_inode;  	ret = filemap_write_and_wait_range(inode->i_mapping, start, end); +	if (ret != 0) +		goto out;  	mutex_lock(&inode->i_mutex);  	ret = nfs_file_fsync_commit(file, start, end, datasync);  	if (!ret && !datasync)  		/* application has asked for meta-data sync */  		ret = pnfs_layoutcommit_inode(inode, true);  	mutex_unlock(&inode->i_mutex); - +out:  	return ret;  } diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 635274140b1..1e50326d00d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3215,11 +3215,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,  			dentry->d_parent->d_name.name,  			dentry->d_name.name,  			(unsigned long long)cookie); -	nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); +	nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args);  	res.pgbase = args.pgbase;  	status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);  	if (status >= 0) { -		memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); +		memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE);  		status += args.pgbase;  	} @@ -3653,11 +3653,11 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)  		&& (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL);  } -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on +/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that + * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on   * the stack.   */ -#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) +#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)  static int buf_to_pages_noslab(const void *buf, size_t buflen,  		struct page **pages, unsigned int *pgbase) @@ -3668,7 +3668,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen,  	spages = pages;  	do { -		len = min_t(size_t, PAGE_CACHE_SIZE, buflen); +		len = min_t(size_t, PAGE_SIZE, buflen);  		newpage = alloc_page(GFP_KERNEL);  		if (newpage == NULL) @@ -3739,7 +3739,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size  	struct nfs4_cached_acl *acl;  	size_t buflen = sizeof(*acl) + acl_len; -	if (pages && buflen <= PAGE_SIZE) { +	if (buflen <= PAGE_SIZE) {  		acl = kmalloc(buflen, GFP_KERNEL);  		if (acl == NULL)  			goto out; @@ -3782,17 +3782,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu  		.rpc_argp = &args,  		.rpc_resp = &res,  	}; -	int ret = -ENOMEM, npages, i; -	size_t acl_len = 0; +	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); +	int ret = -ENOMEM, i; -	npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;  	/* As long as we're doing a round trip to the server anyway,  	 * let's be prepared for a page of acl data. */  	if (npages == 0)  		npages = 1; - -	/* Add an extra page to handle the bitmap returned */ -	npages++; +	if (npages > ARRAY_SIZE(pages)) +		return -ERANGE;  	for (i = 0; i < npages; i++) {  		pages[i] = alloc_page(GFP_KERNEL); @@ -3808,11 +3806,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu  	args.acl_len = npages * PAGE_SIZE;  	args.acl_pgbase = 0; -	/* Let decode_getfacl know not to fail if the ACL data is larger than -	 * the page we send as a guess */ -	if (buf == NULL) -		res.acl_flags |= NFS4_ACL_LEN_REQUEST; -  	dprintk("%s  buf %p buflen %zu npages %d args.acl_len %zu\n",  		__func__, buf, buflen, npages, args.acl_len);  	ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), @@ -3820,20 +3813,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu  	if (ret)  		goto out_free; -	acl_len = res.acl_len; -	if (acl_len > args.acl_len) -		nfs4_write_cached_acl(inode, NULL, 0, acl_len); -	else -		nfs4_write_cached_acl(inode, pages, res.acl_data_offset, -				      acl_len); -	if (buf) { +	/* Handle the case where the passed-in buffer is too short */ +	if (res.acl_flags & NFS4_ACL_TRUNC) { +		/* Did the user only issue a request for the acl length? */ +		if (buf == NULL) +			goto out_ok;  		ret = -ERANGE; -		if (acl_len > buflen) -			goto out_free; -		_copy_from_pages(buf, pages, res.acl_data_offset, -				acl_len); +		goto out_free;  	} -	ret = acl_len; +	nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); +	if (buf) +		_copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); +out_ok: +	ret = res.acl_len;  out_free:  	for (i = 0; i < npages; i++)  		if (pages[i]) @@ -3891,10 +3883,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl  		.rpc_argp	= &arg,  		.rpc_resp	= &res,  	}; +	unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);  	int ret, i;  	if (!nfs4_server_supports_acls(server))  		return -EOPNOTSUPP; +	if (npages > ARRAY_SIZE(pages)) +		return -ERANGE;  	i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);  	if (i < 0)  		return i; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1bfbd67c556..8dba6bd4855 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5072,18 +5072,14 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,  		 * are stored with the acl data to handle the problem of  		 * variable length bitmaps.*/  		res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; - -		/* We ignore &savep and don't do consistency checks on -		 * the attr length.  Let userspace figure it out.... */  		res->acl_len = attrlen; -		if (attrlen > (xdr->nwords << 2)) { -			if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { -				/* getxattr interface called with a NULL buf */ -				goto out; -			} + +		/* Check for receive buffer overflow */ +		if (res->acl_len > (xdr->nwords << 2) || +		    res->acl_len + res->acl_data_offset > xdr->buf->page_len) { +			res->acl_flags |= NFS4_ACL_TRUNC;  			dprintk("NFS: acl reply: attrlen %u > page_len %u\n",  					attrlen, xdr->nwords << 2); -			return -EINVAL;  		}  	} else  		status = -EOPNOTSUPP; @@ -6229,7 +6225,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,  	status = decode_open(xdr, res);  	if (status)  		goto out; -	if (decode_getfh(xdr, &res->fh) != 0) +	status = decode_getfh(xdr, &res->fh); +	if (status)  		goto out;  	decode_getfattr(xdr, res->f_attr, res->server);  out: diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 239aff7338e..b8eda700584 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1867,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options,  		memcpy(sap, &data->addr, sizeof(data->addr));  		args->nfs_server.addrlen = sizeof(data->addr); +		args->nfs_server.port = ntohs(data->addr.sin_port);  		if (!nfs_verify_server_address(sap))  			goto out_no_address; @@ -2564,6 +2565,7 @@ static int nfs4_validate_mount_data(void *options,  			return -EFAULT;  		if (!nfs_verify_server_address(sap))  			goto out_no_address; +		args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);  		if (data->auth_flavourlen) {  			if (data->auth_flavourlen > 1) diff --git a/fs/stat.c b/fs/stat.c index b6ff11825fc..40780229a03 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -58,7 +58,7 @@ EXPORT_SYMBOL(vfs_getattr);  int vfs_fstat(unsigned int fd, struct kstat *stat)  {  	int fput_needed; -	struct file *f = fget_light(fd, &fput_needed); +	struct file *f = fget_raw_light(fd, &fput_needed);  	int error = -EBADF;  	if (f) { diff --git a/fs/udf/file.c b/fs/udf/file.c index 7f3f7ba3df6..d1c6093fd3d 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -39,20 +39,24 @@  #include "udf_i.h"  #include "udf_sb.h" -static int udf_adinicb_readpage(struct file *file, struct page *page) +static void __udf_adinicb_readpage(struct page *page)  {  	struct inode *inode = page->mapping->host;  	char *kaddr;  	struct udf_inode_info *iinfo = UDF_I(inode); -	BUG_ON(!PageLocked(page)); -  	kaddr = kmap(page); -	memset(kaddr, 0, PAGE_CACHE_SIZE);  	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); +	memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size);  	flush_dcache_page(page);  	SetPageUptodate(page);  	kunmap(page); +} + +static int udf_adinicb_readpage(struct file *file, struct page *page) +{ +	BUG_ON(!PageLocked(page)); +	__udf_adinicb_readpage(page);  	unlock_page(page);  	return 0; @@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct page *page,  	return 0;  } +static int udf_adinicb_write_begin(struct file *file, +			struct address_space *mapping, loff_t pos, +			unsigned len, unsigned flags, struct page **pagep, +			void **fsdata) +{ +	struct page *page; + +	if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE)) +		return -EIO; +	page = grab_cache_page_write_begin(mapping, 0, flags); +	if (!page) +		return -ENOMEM; +	*pagep = page; + +	if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) +		__udf_adinicb_readpage(page); +	return 0; +} +  static int udf_adinicb_write_end(struct file *file,  			struct address_space *mapping,  			loff_t pos, unsigned len, unsigned copied, @@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct file *file,  const struct address_space_operations udf_adinicb_aops = {  	.readpage	= udf_adinicb_readpage,  	.writepage	= udf_adinicb_writepage, -	.write_begin = simple_write_begin, -	.write_end = udf_adinicb_write_end, +	.write_begin	= udf_adinicb_write_begin, +	.write_end	= udf_adinicb_write_end,  };  static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h index bdf0152cbbe..f4621184a9b 100644 --- a/include/drm/drm_fourcc.h +++ b/include/drm/drm_fourcc.h @@ -107,8 +107,7 @@  #define DRM_FORMAT_NV16		fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */  #define DRM_FORMAT_NV61		fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ -/* 2 non contiguous plane YCbCr */ -#define DRM_FORMAT_NV12M	fourcc_code('N', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane */ +/* special NV12 tiled format */  #define DRM_FORMAT_NV12MT	fourcc_code('T', 'M', '1', '2') /* 2x2 subsampled Cr:Cb plane 64x32 macroblocks */  /* @@ -131,7 +130,4 @@  #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */  #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ -/* 3 non contiguous plane YCbCr */ -#define DRM_FORMAT_YUV420M	fourcc_code('Y', 'M', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ -  #endif /* DRM_FOURCC_H */ diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h index 06023393fba..4eb31752e2b 100644 --- a/include/linux/atmel-ssc.h +++ b/include/linux/atmel-ssc.h @@ -3,6 +3,7 @@  #include <linux/platform_device.h>  #include <linux/list.h> +#include <linux/io.h>  struct ssc_device {  	struct list_head	list; diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index 1bc74afe7a3..49ed17fdf05 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h @@ -22,6 +22,7 @@ struct i2c_pnx_mif {  	struct timer_list	timer;		/* Timeout */  	u8 *			buf;		/* Data buffer */  	int			len;		/* Length of data buffer */ +	int			order;		/* RX Bytes to order via TX */  };  struct i2c_pnx_algo_data { diff --git a/include/linux/kobject.h b/include/linux/kobject.h index fc615a97e2d..1e57449395b 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -224,7 +224,7 @@ static inline int kobject_uevent_env(struct kobject *kobj,  static inline __printf(2, 3)  int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...) -{ return 0; } +{ return -ENOMEM; }  static inline int kobject_action_type(const char *buf, size_t count,  				      enum kobject_action *type) diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h index d0752eca9b4..9d96d5d4dfe 100644 --- a/include/linux/mISDNhw.h +++ b/include/linux/mISDNhw.h @@ -183,7 +183,7 @@ extern int	mISDN_initbchannel(struct bchannel *, unsigned short,  				   unsigned short);  extern int	mISDN_freedchannel(struct dchannel *);  extern void	mISDN_clear_bchannel(struct bchannel *); -extern int	mISDN_freebchannel(struct bchannel *); +extern void	mISDN_freebchannel(struct bchannel *);  extern int	mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *);  extern void	queue_ch_frame(struct mISDNchannel *, u_int,  			int, struct sk_buff *); diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 3a8435a8058..cebe97ee98b 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -16,6 +16,8 @@  #include <linux/platform_device.h> +struct irq_domain; +  /*   * This struct describes the MFD part ("cell").   * After registration the copy of this structure will become the platform data @@ -98,7 +100,7 @@ static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)  extern int mfd_add_devices(struct device *parent, int id,  			   struct mfd_cell *cells, int n_devs,  			   struct resource *mem_base, -			   int irq_base); +			   int irq_base, struct irq_domain *irq_domain);  extern void mfd_remove_devices(struct device *parent); diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index 12c06870829..7cd83d826ed 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h @@ -22,6 +22,9 @@  #include <linux/regulator/driver.h>  #include <linux/regulator/machine.h> +/* TPS chip id list */ +#define TPS65217			0xF0 +  /* I2C ID for TPS65217 part */  #define TPS65217_I2C_ID			0x24 @@ -248,13 +251,11 @@ struct tps_info {  struct tps65217 {  	struct device *dev;  	struct tps65217_board *pdata; +	unsigned int id;  	struct regulator_desc desc[TPS65217_NUM_REGULATOR];  	struct regulator_dev *rdev[TPS65217_NUM_REGULATOR];  	struct tps_info *info[TPS65217_NUM_REGULATOR];  	struct regmap *regmap; - -	/* Client devices */ -	struct platform_device *regulator_pdev[TPS65217_NUM_REGULATOR];  };  static inline struct tps65217 *dev_to_tps65217(struct device *dev) @@ -262,6 +263,11 @@ static inline struct tps65217 *dev_to_tps65217(struct device *dev)  	return dev_get_drvdata(dev);  } +static inline int tps65217_chip_id(struct tps65217 *tps65217) +{ +	return tps65217->id; +} +  int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,  					unsigned int *val);  int tps65217_reg_write(struct tps65217 *tps, unsigned int reg, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index bd6c9fcdf2d..6e1b0f973a0 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -796,6 +796,19 @@ enum mlx4_net_trans_rule_id {  	MLX4_NET_TRANS_RULE_NUM, /* should be last */  }; +extern const u16 __sw_id_hw[]; + +static inline int map_hw_to_sw_id(u16 header_id) +{ + +	int i; +	for (i = 0; i < MLX4_NET_TRANS_RULE_NUM; i++) { +		if (header_id == __sw_id_hw[i]) +			return i; +	} +	return -EINVAL; +} +  enum mlx4_net_trans_promisc_mode {  	MLX4_FS_PROMISC_NONE = 0,  	MLX4_FS_PROMISC_UPLINK, diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 1f8fc7f9bcd..4b03f56e280 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -265,11 +265,6 @@ static inline const struct nfs_rpc_ops *NFS_PROTO(const struct inode *inode)  	return NFS_SERVER(inode)->nfs_client->rpc_ops;  } -static inline __be32 *NFS_COOKIEVERF(const struct inode *inode) -{ -	return NFS_I(inode)->cookieverf; -} -  static inline unsigned NFS_MINATTRTIMEO(const struct inode *inode)  {  	struct nfs_server *nfss = NFS_SERVER(inode); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index ac7c8ae254f..be9cf3c7e79 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -652,7 +652,7 @@ struct nfs_getaclargs {  };  /* getxattr ACL interface flags */ -#define NFS4_ACL_LEN_REQUEST	0x0001	/* zero length getxattr buffer */ +#define NFS4_ACL_TRUNC		0x0001	/* ACL was truncated */  struct nfs_getaclres {  	size_t				acl_len;  	size_t				acl_data_offset; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 7602ccb3f40..33ed9d605f9 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -926,7 +926,7 @@ struct perf_event {  	struct hw_perf_event		hw;  	struct perf_event_context	*ctx; -	struct file			*filp; +	atomic_long_t			refcount;  	/*  	 * These accumulate total time (in nanoseconds) that children @@ -1296,6 +1296,7 @@ extern int perf_swevent_get_recursion_context(void);  extern void perf_swevent_put_recursion_context(int rctx);  extern void perf_event_enable(struct perf_event *event);  extern void perf_event_disable(struct perf_event *event); +extern int __perf_event_disable(void *info);  extern void perf_event_task_tick(void);  #else  static inline void @@ -1334,6 +1335,7 @@ static inline int  perf_swevent_get_recursion_context(void)		{ return -1; }  static inline void perf_swevent_put_recursion_context(int rctx)		{ }  static inline void perf_event_enable(struct perf_event *event)		{ }  static inline void perf_event_disable(struct perf_event *event)		{ } +static inline int __perf_event_disable(void *info)			{ return -1; }  static inline void perf_event_task_tick(void)				{ }  #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index b8c86648a2f..23bddac4bad 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -954,7 +954,6 @@ struct sched_domain {  	unsigned int smt_gain;  	int flags;			/* See SD_* */  	int level; -	int idle_buddy;			/* cpu assigned to select_idle_sibling() */  	/* Runtime fields. */  	unsigned long last_balance;	/* init to jiffies. units in jiffies */ diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index cff40aa7db6..bf8c49ff753 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -114,6 +114,7 @@ struct rpc_xprt_ops {  	void		(*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);  	int		(*reserve_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);  	void		(*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); +	void		(*alloc_slot)(struct rpc_xprt *xprt, struct rpc_task *task);  	void		(*rpcbind)(struct rpc_task *task);  	void		(*set_port)(struct rpc_xprt *xprt, unsigned short port);  	void		(*connect)(struct rpc_task *task); @@ -281,6 +282,8 @@ void			xprt_connect(struct rpc_task *task);  void			xprt_reserve(struct rpc_task *task);  int			xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task);  int			xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); +void			xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task); +void			xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task);  int			xprt_prepare_transmit(struct rpc_task *task);  void			xprt_transmit(struct rpc_task *task);  void			xprt_end_transmit(struct rpc_task *task); diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h index ca356a73492..8b27927b2a5 100644 --- a/include/net/bluetooth/smp.h +++ b/include/net/bluetooth/smp.h @@ -136,7 +136,7 @@ struct smp_chan {  };  /* SMP Commands */ -int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level); +int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);  int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);  int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);  int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 976a81abe1a..639dd1316d3 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -273,6 +273,9 @@ struct xfrm_replay {  	int	(*check)(struct xfrm_state *x,  			 struct sk_buff *skb,  			 __be32 net_seq); +	int	(*recheck)(struct xfrm_state *x, +			   struct sk_buff *skb, +			   __be32 net_seq);  	void	(*notify)(struct xfrm_state *x, int event);  	int	(*overflow)(struct xfrm_state *x, struct sk_buff *skb);  }; diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index f1405d335a9..941c84bf106 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -23,7 +23,9 @@ struct se_subsystem_api {  	struct se_device *(*create_virtdevice)(struct se_hba *,  				struct se_subsystem_dev *, void *);  	void (*free_device)(void *); -	int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *); +	void (*transport_complete)(struct se_cmd *cmd, +				   struct scatterlist *, +				   unsigned char *);  	int (*parse_cdb)(struct se_cmd *cmd);  	ssize_t (*check_configfs_dev_params)(struct se_hba *, diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 015cea01ae3..5be89373cea 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -121,6 +121,7 @@  #define SE_INQUIRY_BUF				512  #define SE_MODE_PAGE_BUF			512 +#define SE_SENSE_BUF				96  /* struct se_hba->hba_flags */  enum hba_flags_table { diff --git a/kernel/events/core.c b/kernel/events/core.c index b7935fcec7d..7fee567153f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1253,7 +1253,7 @@ retry:  /*   * Cross CPU call to disable a performance event   */ -static int __perf_event_disable(void *info) +int __perf_event_disable(void *info)  {  	struct perf_event *event = info;  	struct perf_event_context *ctx = event->ctx; @@ -2935,12 +2935,12 @@ EXPORT_SYMBOL_GPL(perf_event_release_kernel);  /*   * Called when the last reference to the file is gone.   */ -static int perf_release(struct inode *inode, struct file *file) +static void put_event(struct perf_event *event)  { -	struct perf_event *event = file->private_data;  	struct task_struct *owner; -	file->private_data = NULL; +	if (!atomic_long_dec_and_test(&event->refcount)) +		return;  	rcu_read_lock();  	owner = ACCESS_ONCE(event->owner); @@ -2975,7 +2975,13 @@ static int perf_release(struct inode *inode, struct file *file)  		put_task_struct(owner);  	} -	return perf_event_release_kernel(event); +	perf_event_release_kernel(event); +} + +static int perf_release(struct inode *inode, struct file *file) +{ +	put_event(file->private_data); +	return 0;  }  u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) @@ -3227,7 +3233,7 @@ unlock:  static const struct file_operations perf_fops; -static struct perf_event *perf_fget_light(int fd, int *fput_needed) +static struct file *perf_fget_light(int fd, int *fput_needed)  {  	struct file *file; @@ -3241,7 +3247,7 @@ static struct perf_event *perf_fget_light(int fd, int *fput_needed)  		return ERR_PTR(-EBADF);  	} -	return file->private_data; +	return file;  }  static int perf_event_set_output(struct perf_event *event, @@ -3273,19 +3279,21 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  	case PERF_EVENT_IOC_SET_OUTPUT:  	{ +		struct file *output_file = NULL;  		struct perf_event *output_event = NULL;  		int fput_needed = 0;  		int ret;  		if (arg != -1) { -			output_event = perf_fget_light(arg, &fput_needed); -			if (IS_ERR(output_event)) -				return PTR_ERR(output_event); +			output_file = perf_fget_light(arg, &fput_needed); +			if (IS_ERR(output_file)) +				return PTR_ERR(output_file); +			output_event = output_file->private_data;  		}  		ret = perf_event_set_output(event, output_event);  		if (output_event) -			fput_light(output_event->filp, fput_needed); +			fput_light(output_file, fput_needed);  		return ret;  	} @@ -5950,6 +5958,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,  	mutex_init(&event->mmap_mutex); +	atomic_long_set(&event->refcount, 1);  	event->cpu		= cpu;  	event->attr		= *attr;  	event->group_leader	= group_leader; @@ -6260,12 +6269,12 @@ SYSCALL_DEFINE5(perf_event_open,  		return event_fd;  	if (group_fd != -1) { -		group_leader = perf_fget_light(group_fd, &fput_needed); -		if (IS_ERR(group_leader)) { -			err = PTR_ERR(group_leader); +		group_file = perf_fget_light(group_fd, &fput_needed); +		if (IS_ERR(group_file)) { +			err = PTR_ERR(group_file);  			goto err_fd;  		} -		group_file = group_leader->filp; +		group_leader = group_file->private_data;  		if (flags & PERF_FLAG_FD_OUTPUT)  			output_event = group_leader;  		if (flags & PERF_FLAG_FD_NO_GROUP) @@ -6402,7 +6411,6 @@ SYSCALL_DEFINE5(perf_event_open,  		put_ctx(gctx);  	} -	event->filp = event_file;  	WARN_ON_ONCE(ctx->parent_ctx);  	mutex_lock(&ctx->mutex); @@ -6496,7 +6504,6 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,  		goto err_free;  	} -	event->filp = NULL;  	WARN_ON_ONCE(ctx->parent_ctx);  	mutex_lock(&ctx->mutex);  	perf_install_in_context(ctx, event, cpu); @@ -6578,7 +6585,7 @@ static void sync_child_event(struct perf_event *child_event,  	 * Release the parent event, if this was the last  	 * reference to it.  	 */ -	fput(parent_event->filp); +	put_event(parent_event);  }  static void @@ -6654,9 +6661,8 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)  	 *  	 *   __perf_event_exit_task()  	 *     sync_child_event() -	 *       fput(parent_event->filp) -	 *         perf_release() -	 *           mutex_lock(&ctx->mutex) +	 *       put_event() +	 *         mutex_lock(&ctx->mutex)  	 *  	 * But since its the parent context it won't be the same instance.  	 */ @@ -6724,7 +6730,7 @@ static void perf_free_event(struct perf_event *event,  	list_del_init(&event->child_list);  	mutex_unlock(&parent->child_mutex); -	fput(parent->filp); +	put_event(parent);  	perf_group_detach(event);  	list_del_event(event, ctx); @@ -6804,6 +6810,12 @@ inherit_event(struct perf_event *parent_event,  				           NULL, NULL);  	if (IS_ERR(child_event))  		return child_event; + +	if (!atomic_long_inc_not_zero(&parent_event->refcount)) { +		free_event(child_event); +		return NULL; +	} +  	get_ctx(child_ctx);  	/* @@ -6845,14 +6857,6 @@ inherit_event(struct perf_event *parent_event,  	raw_spin_unlock_irqrestore(&child_ctx->lock, flags);  	/* -	 * Get a reference to the parent filp - we will fput it -	 * when the child event exits. This is safe to do because -	 * we are in the parent and we know that the filp still -	 * exists and has a nonzero count: -	 */ -	atomic_long_inc(&parent_event->filp->f_count); - -	/*  	 * Link this into the parent event's child list  	 */  	WARN_ON_ONCE(parent_event->ctx->parent_ctx); diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index bb38c4d3ee1..9a7b487c6fe 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -453,7 +453,16 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att  	int old_type = bp->attr.bp_type;  	int err = 0; -	perf_event_disable(bp); +	/* +	 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it +	 * will not be possible to raise IPIs that invoke __perf_event_disable. +	 * So call the function directly after making sure we are targeting the +	 * current task. +	 */ +	if (irqs_disabled() && bp->ctx && bp->ctx->task == current) +		__perf_event_disable(bp); +	else +		perf_event_disable(bp);  	bp->attr.bp_addr = attr->bp_addr;  	bp->attr.bp_type = attr->bp_type; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fbf1fd098dc..649c9f876cb 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5304,27 +5304,17 @@ void idle_task_exit(void)  }  /* - * While a dead CPU has no uninterruptible tasks queued at this point, - * it might still have a nonzero ->nr_uninterruptible counter, because - * for performance reasons the counter is not stricly tracking tasks to - * their home CPUs. So we just add the counter to another CPU's counter, - * to keep the global sum constant after CPU-down: - */ -static void migrate_nr_uninterruptible(struct rq *rq_src) -{ -	struct rq *rq_dest = cpu_rq(cpumask_any(cpu_active_mask)); - -	rq_dest->nr_uninterruptible += rq_src->nr_uninterruptible; -	rq_src->nr_uninterruptible = 0; -} - -/* - * remove the tasks which were accounted by rq from calc_load_tasks. + * Since this CPU is going 'away' for a while, fold any nr_active delta + * we might have. Assumes we're called after migrate_tasks() so that the + * nr_active count is stable. + * + * Also see the comment "Global load-average calculations".   */ -static void calc_global_load_remove(struct rq *rq) +static void calc_load_migrate(struct rq *rq)  { -	atomic_long_sub(rq->calc_load_active, &calc_load_tasks); -	rq->calc_load_active = 0; +	long delta = calc_load_fold_active(rq); +	if (delta) +		atomic_long_add(delta, &calc_load_tasks);  }  /* @@ -5352,9 +5342,6 @@ static void migrate_tasks(unsigned int dead_cpu)  	 */  	rq->stop = NULL; -	/* Ensure any throttled groups are reachable by pick_next_task */ -	unthrottle_offline_cfs_rqs(rq); -  	for ( ; ; ) {  		/*  		 * There's this thread running, bail when that's the only @@ -5618,8 +5605,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)  		BUG_ON(rq->nr_running != 1); /* the migration thread */  		raw_spin_unlock_irqrestore(&rq->lock, flags); -		migrate_nr_uninterruptible(rq); -		calc_global_load_remove(rq); +		calc_load_migrate(rq);  		break;  #endif  	} @@ -6028,11 +6014,6 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu)   * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this   * allows us to avoid some pointer chasing select_idle_sibling().   * - * Iterate domains and sched_groups downward, assigning CPUs to be - * select_idle_sibling() hw buddy.  Cross-wiring hw makes bouncing - * due to random perturbation self canceling, ie sw buddies pull - * their counterpart to their CPU's hw counterpart. - *   * Also keep a unique ID per domain (we use the first cpu number in   * the cpumask of the domain), this allows us to quickly tell if   * two cpus are in the same cache domain, see cpus_share_cache(). @@ -6046,40 +6027,8 @@ static void update_top_cache_domain(int cpu)  	int id = cpu;  	sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES); -	if (sd) { -		struct sched_domain *tmp = sd; -		struct sched_group *sg, *prev; -		bool right; - -		/* -		 * Traverse to first CPU in group, and count hops -		 * to cpu from there, switching direction on each -		 * hop, never ever pointing the last CPU rightward. -		 */ -		do { -			id = cpumask_first(sched_domain_span(tmp)); -			prev = sg = tmp->groups; -			right = 1; - -			while (cpumask_first(sched_group_cpus(sg)) != id) -				sg = sg->next; - -			while (!cpumask_test_cpu(cpu, sched_group_cpus(sg))) { -				prev = sg; -				sg = sg->next; -				right = !right; -			} - -			/* A CPU went down, never point back to domain start. */ -			if (right && cpumask_first(sched_group_cpus(sg->next)) == id) -				right = false; - -			sg = right ? sg->next : prev; -			tmp->idle_buddy = cpumask_first(sched_group_cpus(sg)); -		} while ((tmp = tmp->child)); - +	if (sd)  		id = cpumask_first(sched_domain_span(sd)); -	}  	rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);  	per_cpu(sd_llc_id, cpu) = id; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c219bf8d704..96e2b18b628 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2052,7 +2052,7 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)  	hrtimer_cancel(&cfs_b->slack_timer);  } -void unthrottle_offline_cfs_rqs(struct rq *rq) +static void unthrottle_offline_cfs_rqs(struct rq *rq)  {  	struct cfs_rq *cfs_rq; @@ -2106,7 +2106,7 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)  	return NULL;  }  static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} -void unthrottle_offline_cfs_rqs(struct rq *rq) {} +static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}  #endif /* CONFIG_CFS_BANDWIDTH */ @@ -2637,6 +2637,8 @@ static int select_idle_sibling(struct task_struct *p, int target)  	int cpu = smp_processor_id();  	int prev_cpu = task_cpu(p);  	struct sched_domain *sd; +	struct sched_group *sg; +	int i;  	/*  	 * If the task is going to be woken-up on this cpu and if it is @@ -2653,17 +2655,29 @@ static int select_idle_sibling(struct task_struct *p, int target)  		return prev_cpu;  	/* -	 * Otherwise, check assigned siblings to find an elegible idle cpu. +	 * Otherwise, iterate the domains and find an elegible idle cpu.  	 */  	sd = rcu_dereference(per_cpu(sd_llc, target)); -  	for_each_lower_domain(sd) { -		if (!cpumask_test_cpu(sd->idle_buddy, tsk_cpus_allowed(p))) -			continue; -		if (idle_cpu(sd->idle_buddy)) -			return sd->idle_buddy; -	} +		sg = sd->groups; +		do { +			if (!cpumask_intersects(sched_group_cpus(sg), +						tsk_cpus_allowed(p))) +				goto next; +			for_each_cpu(i, sched_group_cpus(sg)) { +				if (!idle_cpu(i)) +					goto next; +			} + +			target = cpumask_first_and(sched_group_cpus(sg), +					tsk_cpus_allowed(p)); +			goto done; +next: +			sg = sg->next; +		} while (sg != sd->groups); +	} +done:  	return target;  } @@ -3658,7 +3672,6 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group)   * @group: sched_group whose statistics are to be updated.   * @load_idx: Load index of sched_domain of this_cpu for load calc.   * @local_group: Does group contain this_cpu. - * @cpus: Set of cpus considered for load balancing.   * @balance: Should we balance.   * @sgs: variable to hold the statistics for this group.   */ @@ -3805,7 +3818,6 @@ static bool update_sd_pick_busiest(struct lb_env *env,  /**   * update_sd_lb_stats - Update sched_domain's statistics for load balancing.   * @env: The load balancing environment. - * @cpus: Set of cpus considered for load balancing.   * @balance: Should we balance.   * @sds: variable to hold the statistics for this sched_domain.   */ @@ -4956,6 +4968,9 @@ static void rq_online_fair(struct rq *rq)  static void rq_offline_fair(struct rq *rq)  {  	update_sysctl(); + +	/* Ensure any throttled groups are reachable by pick_next_task */ +	unthrottle_offline_cfs_rqs(rq);  }  #endif /* CONFIG_SMP */ diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 944cb68420e..e0b7ba9c040 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -691,6 +691,7 @@ balanced:  		 * runtime - in which case borrowing doesn't make sense.  		 */  		rt_rq->rt_runtime = RUNTIME_INF; +		rt_rq->rt_throttled = 0;  		raw_spin_unlock(&rt_rq->rt_runtime_lock);  		raw_spin_unlock(&rt_b->rt_runtime_lock);  	} diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index f6714d009e7..0848fa36c38 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1144,7 +1144,6 @@ extern void print_rt_stats(struct seq_file *m, int cpu);  extern void init_cfs_rq(struct cfs_rq *cfs_rq);  extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); -extern void unthrottle_offline_cfs_rqs(struct rq *rq);  extern void account_cfs_bandwidth_used(int enabled, int was_enabled); diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 024540f97f7..3a9e5d5c109 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -573,6 +573,7 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now)  	tick_do_update_jiffies64(now);  	update_cpu_load_nohz(); +	calc_load_exit_idle();  	touch_softlockup_watchdog();  	/*  	 * Cancel the scheduled timer and restore the tick diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 692d97628a1..1e1373bcb3e 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -66,6 +66,7 @@ enum {  	/* pool flags */  	POOL_MANAGE_WORKERS	= 1 << 0,	/* need to manage workers */ +	POOL_MANAGING_WORKERS   = 1 << 1,       /* managing workers */  	/* worker flags */  	WORKER_STARTED		= 1 << 0,	/* started */ @@ -652,7 +653,7 @@ static bool need_to_manage_workers(struct worker_pool *pool)  /* Do we have too many workers and should some go away? */  static bool too_many_workers(struct worker_pool *pool)  { -	bool managing = mutex_is_locked(&pool->manager_mutex); +	bool managing = pool->flags & POOL_MANAGING_WORKERS;  	int nr_idle = pool->nr_idle + managing; /* manager is considered idle */  	int nr_busy = pool->nr_workers - nr_idle; @@ -1326,6 +1327,15 @@ static void idle_worker_rebind(struct worker *worker)  	/* we did our part, wait for rebind_workers() to finish up */  	wait_event(gcwq->rebind_hold, !(worker->flags & WORKER_REBIND)); + +	/* +	 * rebind_workers() shouldn't finish until all workers passed the +	 * above WORKER_REBIND wait.  Tell it when done. +	 */ +	spin_lock_irq(&worker->pool->gcwq->lock); +	if (!--worker->idle_rebind->cnt) +		complete(&worker->idle_rebind->done); +	spin_unlock_irq(&worker->pool->gcwq->lock);  }  /* @@ -1396,12 +1406,15 @@ retry:  	/* set REBIND and kick idle ones, we'll wait for these later */  	for_each_worker_pool(pool, gcwq) {  		list_for_each_entry(worker, &pool->idle_list, entry) { +			unsigned long worker_flags = worker->flags; +  			if (worker->flags & WORKER_REBIND)  				continue; -			/* morph UNBOUND to REBIND */ -			worker->flags &= ~WORKER_UNBOUND; -			worker->flags |= WORKER_REBIND; +			/* morph UNBOUND to REBIND atomically */ +			worker_flags &= ~WORKER_UNBOUND; +			worker_flags |= WORKER_REBIND; +			ACCESS_ONCE(worker->flags) = worker_flags;  			idle_rebind.cnt++;  			worker->idle_rebind = &idle_rebind; @@ -1419,25 +1432,15 @@ retry:  		goto retry;  	} -	/* -	 * All idle workers are rebound and waiting for %WORKER_REBIND to -	 * be cleared inside idle_worker_rebind().  Clear and release. -	 * Clearing %WORKER_REBIND from this foreign context is safe -	 * because these workers are still guaranteed to be idle. -	 */ -	for_each_worker_pool(pool, gcwq) -		list_for_each_entry(worker, &pool->idle_list, entry) -			worker->flags &= ~WORKER_REBIND; - -	wake_up_all(&gcwq->rebind_hold); - -	/* rebind busy workers */ +	/* all idle workers are rebound, rebind busy workers */  	for_each_busy_worker(worker, i, pos, gcwq) {  		struct work_struct *rebind_work = &worker->rebind_work; +		unsigned long worker_flags = worker->flags; -		/* morph UNBOUND to REBIND */ -		worker->flags &= ~WORKER_UNBOUND; -		worker->flags |= WORKER_REBIND; +		/* morph UNBOUND to REBIND atomically */ +		worker_flags &= ~WORKER_UNBOUND; +		worker_flags |= WORKER_REBIND; +		ACCESS_ONCE(worker->flags) = worker_flags;  		if (test_and_set_bit(WORK_STRUCT_PENDING_BIT,  				     work_data_bits(rebind_work))) @@ -1449,6 +1452,34 @@ retry:  			    worker->scheduled.next,  			    work_color_to_flags(WORK_NO_COLOR));  	} + +	/* +	 * All idle workers are rebound and waiting for %WORKER_REBIND to +	 * be cleared inside idle_worker_rebind().  Clear and release. +	 * Clearing %WORKER_REBIND from this foreign context is safe +	 * because these workers are still guaranteed to be idle. +	 * +	 * We need to make sure all idle workers passed WORKER_REBIND wait +	 * in idle_worker_rebind() before returning; otherwise, workers can +	 * get stuck at the wait if hotplug cycle repeats. +	 */ +	idle_rebind.cnt = 1; +	INIT_COMPLETION(idle_rebind.done); + +	for_each_worker_pool(pool, gcwq) { +		list_for_each_entry(worker, &pool->idle_list, entry) { +			worker->flags &= ~WORKER_REBIND; +			idle_rebind.cnt++; +		} +	} + +	wake_up_all(&gcwq->rebind_hold); + +	if (--idle_rebind.cnt) { +		spin_unlock_irq(&gcwq->lock); +		wait_for_completion(&idle_rebind.done); +		spin_lock_irq(&gcwq->lock); +	}  }  static struct worker *alloc_worker(void) @@ -1794,9 +1825,45 @@ static bool manage_workers(struct worker *worker)  	struct worker_pool *pool = worker->pool;  	bool ret = false; -	if (!mutex_trylock(&pool->manager_mutex)) +	if (pool->flags & POOL_MANAGING_WORKERS)  		return ret; +	pool->flags |= POOL_MANAGING_WORKERS; + +	/* +	 * To simplify both worker management and CPU hotplug, hold off +	 * management while hotplug is in progress.  CPU hotplug path can't +	 * grab %POOL_MANAGING_WORKERS to achieve this because that can +	 * lead to idle worker depletion (all become busy thinking someone +	 * else is managing) which in turn can result in deadlock under +	 * extreme circumstances.  Use @pool->manager_mutex to synchronize +	 * manager against CPU hotplug. +	 * +	 * manager_mutex would always be free unless CPU hotplug is in +	 * progress.  trylock first without dropping @gcwq->lock. +	 */ +	if (unlikely(!mutex_trylock(&pool->manager_mutex))) { +		spin_unlock_irq(&pool->gcwq->lock); +		mutex_lock(&pool->manager_mutex); +		/* +		 * CPU hotplug could have happened while we were waiting +		 * for manager_mutex.  Hotplug itself can't handle us +		 * because manager isn't either on idle or busy list, and +		 * @gcwq's state and ours could have deviated. +		 * +		 * As hotplug is now excluded via manager_mutex, we can +		 * simply try to bind.  It will succeed or fail depending +		 * on @gcwq's current state.  Try it and adjust +		 * %WORKER_UNBOUND accordingly. +		 */ +		if (worker_maybe_bind_and_lock(worker)) +			worker->flags &= ~WORKER_UNBOUND; +		else +			worker->flags |= WORKER_UNBOUND; + +		ret = true; +	} +  	pool->flags &= ~POOL_MANAGE_WORKERS;  	/* @@ -1806,6 +1873,7 @@ static bool manage_workers(struct worker *worker)  	ret |= maybe_destroy_workers(pool);  	ret |= maybe_create_worker(pool); +	pool->flags &= ~POOL_MANAGING_WORKERS;  	mutex_unlock(&pool->manager_mutex);  	return ret;  } diff --git a/lib/digsig.c b/lib/digsig.c index 286d558033e..8c0e62975c8 100644 --- a/lib/digsig.c +++ b/lib/digsig.c @@ -163,9 +163,11 @@ static int digsig_verify_rsa(struct key *key,  	memcpy(out1 + head, p, l);  	err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); +	if (err) +		goto err; -	if (!err && len == hlen) -		err = memcmp(out2, h, hlen); +	if (len != hlen || memcmp(out2, h, hlen)) +		err = -EINVAL;  err:  	mpi_free(in); diff --git a/mm/memblock.c b/mm/memblock.c index 4d9393c7edc..82aa349d2f7 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -246,7 +246,7 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,  				min(new_area_start, memblock.current_limit),  				new_alloc_size, PAGE_SIZE); -		new_array = addr ? __va(addr) : 0; +		new_array = addr ? __va(addr) : NULL;  	}  	if (!addr) {  		pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n", diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5ad7da21747..3c094e78dde 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -29,6 +29,7 @@  #include <net/bluetooth/bluetooth.h>  #include <net/bluetooth/hci_core.h>  #include <net/bluetooth/a2mp.h> +#include <net/bluetooth/smp.h>  static void hci_le_connect(struct hci_conn *conn)  { @@ -619,6 +620,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)  {  	BT_DBG("hcon %p", conn); +	if (conn->type == LE_LINK) +		return smp_conn_security(conn, sec_level); +  	/* For sdp we don't need the link key. */  	if (sec_level == BT_SECURITY_SDP)  		return 1; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index daa149b7003..4ea1710a478 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1199,14 +1199,15 @@ clean:  static void l2cap_conn_ready(struct l2cap_conn *conn)  {  	struct l2cap_chan *chan; +	struct hci_conn *hcon = conn->hcon;  	BT_DBG("conn %p", conn); -	if (!conn->hcon->out && conn->hcon->type == LE_LINK) +	if (!hcon->out && hcon->type == LE_LINK)  		l2cap_le_conn_ready(conn); -	if (conn->hcon->out && conn->hcon->type == LE_LINK) -		smp_conn_security(conn, conn->hcon->pending_sec_level); +	if (hcon->out && hcon->type == LE_LINK) +		smp_conn_security(hcon, hcon->pending_sec_level);  	mutex_lock(&conn->chan_lock); @@ -1219,8 +1220,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)  			continue;  		} -		if (conn->hcon->type == LE_LINK) { -			if (smp_conn_security(conn, chan->sec_level)) +		if (hcon->type == LE_LINK) { +			if (smp_conn_security(hcon, chan->sec_level))  				l2cap_chan_ready(chan);  		} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1497edd191a..34bbe1c5e38 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -616,7 +616,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch  				break;  			} -			if (smp_conn_security(conn, sec.level)) +			if (smp_conn_security(conn->hcon, sec.level))  				break;  			sk->sk_state = BT_CONFIG;  			chan->state = BT_CONFIG; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 901a616c808..8c225ef349c 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -267,10 +267,10 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)  	mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,  			 hcon->dst_type, reason); -	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { -		cancel_delayed_work_sync(&conn->security_timer); +	cancel_delayed_work_sync(&conn->security_timer); + +	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))  		smp_chan_destroy(conn); -	}  }  #define JUST_WORKS	0x00 @@ -760,9 +760,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)  	return 0;  } -int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) +int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)  { -	struct hci_conn *hcon = conn->hcon; +	struct l2cap_conn *conn = hcon->l2cap_data;  	struct smp_chan *smp = conn->smp_chan;  	__u8 authreq; diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index f88ee537fb2..92de5e5f9db 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -80,7 +80,7 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,  	unsigned int bitmask;  	spin_lock_bh(&ebt_log_lock); -	printk("<%c>%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x", +	printk(KERN_SOH "%c%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x",  	       '0' + loginfo->u.log.level, prefix,  	       in ? in->name : "", out ? out->name : "",  	       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index dd485f6128e..ba217e90765 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c @@ -211,9 +211,10 @@ void caif_client_register_refcnt(struct cflayer *adapt_layer,  					void (*put)(struct cflayer *lyr))  {  	struct cfsrvl *service; -	service = container_of(adapt_layer->dn, struct cfsrvl, layer); -	WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL); +	if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL)) +		return; +	service = container_of(adapt_layer->dn, struct cfsrvl, layer);  	service->hold = hold;  	service->put = put;  } diff --git a/net/core/dev.c b/net/core/dev.c index 83988362805..d7fe32c946c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2647,15 +2647,16 @@ void __skb_get_rxhash(struct sk_buff *skb)  	if (!skb_flow_dissect(skb, &keys))  		return; -	if (keys.ports) { -		if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]) -			swap(keys.port16[0], keys.port16[1]); +	if (keys.ports)  		skb->l4_rxhash = 1; -	}  	/* get a consistent hash (same value on both flow directions) */ -	if ((__force u32)keys.dst < (__force u32)keys.src) +	if (((__force u32)keys.dst < (__force u32)keys.src) || +	    (((__force u32)keys.dst == (__force u32)keys.src) && +	     ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) {  		swap(keys.dst, keys.src); +		swap(keys.port16[0], keys.port16[1]); +	}  	hash = jhash_3words((__force u32)keys.dst,  			    (__force u32)keys.src, diff --git a/net/core/pktgen.c b/net/core/pktgen.c index cce9e53528b..148e73d2c45 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2721,7 +2721,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,  	/* Eth + IPh + UDPh + mpls */  	datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -  		  pkt_dev->pkt_overhead; -	if (datalen < sizeof(struct pktgen_hdr)) +	if (datalen < 0 || datalen < sizeof(struct pktgen_hdr))  		datalen = sizeof(struct pktgen_hdr);  	udph->source = htons(pkt_dev->cur_udp_src); diff --git a/net/core/sock.c b/net/core/sock.c index 8f67ced8d6a..30579207612 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1523,7 +1523,14 @@ EXPORT_SYMBOL(sock_rfree);  void sock_edemux(struct sk_buff *skb)  { -	sock_put(skb->sk); +	struct sock *sk = skb->sk; + +#ifdef CONFIG_INET +	if (sk->sk_state == TCP_TIME_WAIT) +		inet_twsk_put(inet_twsk(sk)); +	else +#endif +		sock_put(sk);  }  EXPORT_SYMBOL(sock_edemux); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6f6d1aca3c3..2814f66dac6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1226,6 +1226,11 @@ try_again:  	if (unlikely(err)) {  		trace_kfree_skb(skb, udp_recvmsg); +		if (!peeked) { +			atomic_inc(&sk->sk_drops); +			UDP_INC_STATS_USER(sock_net(sk), +					   UDP_MIB_INERRORS, is_udplite); +		}  		goto out_free;  	} diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a3e60cc04a8..acd32e3f1b6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -403,8 +403,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,  		tp->mtu_info = ntohl(info);  		if (!sock_owned_by_user(sk))  			tcp_v6_mtu_reduced(sk); -		else -			set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); +		else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, +					   &tp->tsq_flags)) +			sock_hold(sk);  		goto out;  	} diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 99d0077b56b..07e2bfef684 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -394,6 +394,17 @@ try_again:  	}  	if (unlikely(err)) {  		trace_kfree_skb(skb, udpv6_recvmsg); +		if (!peeked) { +			atomic_inc(&sk->sk_drops); +			if (is_udp4) +				UDP_INC_STATS_USER(sock_net(sk), +						   UDP_MIB_INERRORS, +						   is_udplite); +			else +				UDP6_INC_STATS_USER(sock_net(sk), +						    UDP_MIB_INERRORS, +						    is_udplite); +		}  		goto out_free;  	}  	if (!peeked) { diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 513cab08a98..1a9f3723c13 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1501,6 +1501,8 @@ out:  	return err;  } +static struct lock_class_key l2tp_socket_class; +  int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)  {  	struct l2tp_tunnel *tunnel = NULL; @@ -1605,6 +1607,8 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32  	tunnel->old_sk_destruct = sk->sk_destruct;  	sk->sk_destruct = &l2tp_tunnel_destruct;  	tunnel->sock = sk; +	lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock"); +  	sk->sk_allocation = GFP_ATOMIC;  	/* Add tunnel to our list */ diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index f9ee74deeac..3bfb34aaee2 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -153,7 +153,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,  		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);  	} -	if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) +	if (!pskb_may_pull(skb, ETH_HLEN))  		goto error;  	secpath_reset(skb); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d41974aacf5..a58c0b649ba 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1378,6 +1378,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,  	else  		memset(next_hop, 0, ETH_ALEN); +	memset(pinfo, 0, sizeof(*pinfo)); +  	pinfo->generation = mesh_paths_generation;  	pinfo->filled = MPATH_INFO_FRAME_QLEN | @@ -1396,7 +1398,6 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,  	pinfo->discovery_timeout =  			jiffies_to_msecs(mpath->discovery_timeout);  	pinfo->discovery_retries = mpath->discovery_retries; -	pinfo->flags = 0;  	if (mpath->flags & MESH_PATH_ACTIVE)  		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;  	if (mpath->flags & MESH_PATH_RESOLVING) @@ -1405,10 +1406,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,  		pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;  	if (mpath->flags & MESH_PATH_FIXED)  		pinfo->flags |= NL80211_MPATH_FLAG_FIXED; -	if (mpath->flags & MESH_PATH_RESOLVING) -		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; - -	pinfo->flags = mpath->flags; +	if (mpath->flags & MESH_PATH_RESOLVED) +		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;  }  static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a4a5acdbaa4..f76b83341cf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3248,6 +3248,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,  	goto out_unlock;   err_clear: +	memset(ifmgd->bssid, 0, ETH_ALEN); +	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);  	ifmgd->auth_data = NULL;   err_free:  	kfree(auth_data); @@ -3439,6 +3441,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,  	err = 0;  	goto out;   err_clear: +	memset(ifmgd->bssid, 0, ETH_ALEN); +	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);  	ifmgd->assoc_data = NULL;   err_free:  	kfree(assoc_data); diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index a5ac11ebef3..e046b3756aa 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -158,21 +158,18 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {   *	sCL -> sSS   */  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/ -/*synack*/ { sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR }, +/*synack*/ { sIV, sIV, sSR, sIV, sIV, sIV, sIV, sIV, sIV, sSR },  /*   *	sNO -> sIV	Too late and no reason to do anything   *	sSS -> sIV	Client can't send SYN and then SYN/ACK   *	sS2 -> sSR	SYN/ACK sent to SYN2 in simultaneous open - *	sSR -> sIG - *	sES -> sIG	Error: SYNs in window outside the SYN_SENT state - *			are errors. Receiver will reply with RST - *			and close the connection. - *			Or we are not in sync and hold a dead connection. - *	sFW -> sIG - *	sCW -> sIG - *	sLA -> sIG - *	sTW -> sIG - *	sCL -> sIG + *	sSR -> sSR	Late retransmitted SYN/ACK in simultaneous open + *	sES -> sIV	Invalid SYN/ACK packets sent by the client + *	sFW -> sIV + *	sCW -> sIV + *	sLA -> sIV + *	sTW -> sIV + *	sCL -> sIV   */  /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2	*/  /*fin*/    { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV }, @@ -633,15 +630,9 @@ static bool tcp_in_window(const struct nf_conn *ct,  		ack = sack = receiver->td_end;  	} -	if (seq == end -	    && (!tcph->rst -		|| (seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT))) +	if (tcph->rst && seq == 0 && state->state == TCP_CONNTRACK_SYN_SENT)  		/* -		 * Packets contains no data: we assume it is valid -		 * and check the ack value only. -		 * However RST segments are always validated by their -		 * SEQ number, except when seq == 0 (reset sent answering -		 * SYN. +		 * RST sent answering SYN.  		 */  		seq = end = sender->td_end; diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 14e2f390314..5cfb5bedb2b 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -381,6 +381,7 @@ __build_packet_message(struct nfulnl_instance *inst,  	struct nlmsghdr *nlh;  	struct nfgenmsg *nfmsg;  	sk_buff_data_t old_tail = inst->skb->tail; +	struct sock *sk;  	nlh = nlmsg_put(inst->skb, 0, 0,  			NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, @@ -499,18 +500,19 @@ __build_packet_message(struct nfulnl_instance *inst,  	}  	/* UID */ -	if (skb->sk) { -		read_lock_bh(&skb->sk->sk_callback_lock); -		if (skb->sk->sk_socket && skb->sk->sk_socket->file) { -			struct file *file = skb->sk->sk_socket->file; +	sk = skb->sk; +	if (sk && sk->sk_state != TCP_TIME_WAIT) { +		read_lock_bh(&sk->sk_callback_lock); +		if (sk->sk_socket && sk->sk_socket->file) { +			struct file *file = sk->sk_socket->file;  			__be32 uid = htonl(file->f_cred->fsuid);  			__be32 gid = htonl(file->f_cred->fsgid); -			read_unlock_bh(&skb->sk->sk_callback_lock); +			read_unlock_bh(&sk->sk_callback_lock);  			if (nla_put_be32(inst->skb, NFULA_UID, uid) ||  			    nla_put_be32(inst->skb, NFULA_GID, gid))  				goto nla_put_failure;  		} else -			read_unlock_bh(&skb->sk->sk_callback_lock); +			read_unlock_bh(&sk->sk_callback_lock);  	}  	/* local sequence number */ diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index ff5f75fddb1..91e9af4d1f4 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c @@ -145,6 +145,19 @@ static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,  	return 0;  } +static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk) +{ +	if (!sk || sk->sk_state == TCP_TIME_WAIT) +		return; + +	read_lock_bh(&sk->sk_callback_lock); +	if (sk->sk_socket && sk->sk_socket->file) +		sb_add(m, "UID=%u GID=%u ", +			sk->sk_socket->file->f_cred->fsuid, +			sk->sk_socket->file->f_cred->fsgid); +	read_unlock_bh(&sk->sk_callback_lock); +} +  /* One level of recursion won't kill us */  static void dump_ipv4_packet(struct sbuff *m,  			const struct nf_loginfo *info, @@ -361,14 +374,8 @@ static void dump_ipv4_packet(struct sbuff *m,  	}  	/* Max length: 15 "UID=4294967295 " */ -	if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { -		read_lock_bh(&skb->sk->sk_callback_lock); -		if (skb->sk->sk_socket && skb->sk->sk_socket->file) -			sb_add(m, "UID=%u GID=%u ", -				skb->sk->sk_socket->file->f_cred->fsuid, -				skb->sk->sk_socket->file->f_cred->fsgid); -		read_unlock_bh(&skb->sk->sk_callback_lock); -	} +	if ((logflags & XT_LOG_UID) && !iphoff) +		dump_sk_uid_gid(m, skb->sk);  	/* Max length: 16 "MARK=0xFFFFFFFF " */  	if (!iphoff && skb->mark) @@ -436,8 +443,8 @@ log_packet_common(struct sbuff *m,  		  const struct nf_loginfo *loginfo,  		  const char *prefix)  { -	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, -	       prefix, +	sb_add(m, KERN_SOH "%c%sIN=%s OUT=%s ", +	       '0' + loginfo->u.log.level, prefix,  	       in ? in->name : "",  	       out ? out->name : "");  #ifdef CONFIG_BRIDGE_NETFILTER @@ -717,14 +724,8 @@ static void dump_ipv6_packet(struct sbuff *m,  	}  	/* Max length: 15 "UID=4294967295 " */ -	if ((logflags & XT_LOG_UID) && recurse && skb->sk) { -		read_lock_bh(&skb->sk->sk_callback_lock); -		if (skb->sk->sk_socket && skb->sk->sk_socket->file) -			sb_add(m, "UID=%u GID=%u ", -				skb->sk->sk_socket->file->f_cred->fsuid, -				skb->sk->sk_socket->file->f_cred->fsgid); -		read_unlock_bh(&skb->sk->sk_callback_lock); -	} +	if ((logflags & XT_LOG_UID) && recurse) +		dump_sk_uid_gid(m, skb->sk);  	/* Max length: 16 "MARK=0xFFFFFFFF " */  	if (!recurse && skb->mark) diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 06592d8b4a2..1b9024ee963 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1169,7 +1169,12 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,  		msg->msg_flags |= MSG_TRUNC;  	} -	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); +	er = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); +	if (er < 0) { +		skb_free_datagram(sk, skb); +		release_sock(sk); +		return er; +	}  	if (sax != NULL) {  		sax->sax25_family = AF_NETROM; diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index f3f96badf5a..954405ceae9 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -45,7 +45,7 @@ static int make_writable(struct sk_buff *skb, int write_len)  	return pskb_expand_head(skb, 0, 0, GFP_ATOMIC);  } -/* remove VLAN header from packet and update csum accrodingly. */ +/* remove VLAN header from packet and update csum accordingly. */  static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)  {  	struct vlan_hdr *vhdr; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index d8277d29e71..cf58cedad08 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -425,10 +425,10 @@ static int validate_sample(const struct nlattr *attr,  static int validate_tp_port(const struct sw_flow_key *flow_key)  {  	if (flow_key->eth.type == htons(ETH_P_IP)) { -		if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) +		if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst)  			return 0;  	} else if (flow_key->eth.type == htons(ETH_P_IPV6)) { -		if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) +		if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)  			return 0;  	} @@ -460,7 +460,7 @@ static int validate_set(const struct nlattr *a,  		if (flow_key->eth.type != htons(ETH_P_IP))  			return -EINVAL; -		if (!flow_key->ipv4.addr.src || !flow_key->ipv4.addr.dst) +		if (!flow_key->ip.proto)  			return -EINVAL;  		ipv4_key = nla_data(ovs_key); diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 9b75617ca4e..c30df1a10c6 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h @@ -145,15 +145,17 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);   *  OVS_KEY_ATTR_PRIORITY      4    --     4      8   *  OVS_KEY_ATTR_IN_PORT       4    --     4      8   *  OVS_KEY_ATTR_ETHERNET     12    --     4     16 + *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (outer VLAN ethertype)   *  OVS_KEY_ATTR_8021Q         4    --     4      8 - *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8 + *  OVS_KEY_ATTR_ENCAP         0    --     4      4  (VLAN encapsulation) + *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (inner VLAN ethertype)   *  OVS_KEY_ATTR_IPV6         40    --     4     44   *  OVS_KEY_ATTR_ICMPV6        2     2     4      8   *  OVS_KEY_ATTR_ND           28    --     4     32   *  ------------------------------------------------- - *  total                                       132 + *  total                                       144   */ -#define FLOW_BUFSIZE 132 +#define FLOW_BUFSIZE 144  int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);  int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 6aabd77d1cf..564b9fc8efd 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -250,10 +250,11 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)  			else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL)  				cl = defmap[TC_PRIO_BESTEFFORT]; -			if (cl == NULL || cl->level >= head->level) +			if (cl == NULL)  				goto fallback;  		} - +		if (cl->level >= head->level) +			goto fallback;  #ifdef CONFIG_NET_CLS_ACT  		switch (result) {  		case TC_ACT_QUEUED: diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 9fc1c62ec80..4e606fcb253 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -191,7 +191,6 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)  	if (list_empty(&flow->flowchain)) {  		list_add_tail(&flow->flowchain, &q->new_flows); -		codel_vars_init(&flow->cvars);  		q->new_flow_count++;  		flow->deficit = q->quantum;  		flow->dropped = 0; @@ -418,6 +417,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)  			struct fq_codel_flow *flow = q->flows + i;  			INIT_LIST_HEAD(&flow->flowchain); +			codel_vars_init(&flow->cvars);  		}  	}  	if (sch->limit >= 1) diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index e901583e4ea..d42234c0f13 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -102,9 +102,8 @@ static inline int gred_wred_mode_check(struct Qdisc *sch)  		if (q == NULL)  			continue; -		for (n = 0; n < table->DPs; n++) -			if (table->tab[n] && table->tab[n] != q && -			    table->tab[n]->prio == q->prio) +		for (n = i + 1; n < table->DPs; n++) +			if (table->tab[n] && table->tab[n]->prio == q->prio)  				return 1;  	} @@ -137,6 +136,7 @@ static inline void gred_store_wred_set(struct gred_sched *table,  				       struct gred_sched_data *q)  {  	table->wred_set.qavg = q->vars.qavg; +	table->wred_set.qidlestart = q->vars.qidlestart;  }  static inline int gred_use_ecn(struct gred_sched *t) @@ -176,7 +176,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)  		skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp;  	} -	/* sum up all the qaves of prios <= to ours to get the new qave */ +	/* sum up all the qaves of prios < ours to get the new qave */  	if (!gred_wred_mode(t) && gred_rio_mode(t)) {  		int i; @@ -260,16 +260,18 @@ static struct sk_buff *gred_dequeue(struct Qdisc *sch)  		} else {  			q->backlog -= qdisc_pkt_len(skb); -			if (!q->backlog && !gred_wred_mode(t)) -				red_start_of_idle_period(&q->vars); +			if (gred_wred_mode(t)) { +				if (!sch->qstats.backlog) +					red_start_of_idle_period(&t->wred_set); +			} else { +				if (!q->backlog) +					red_start_of_idle_period(&q->vars); +			}  		}  		return skb;  	} -	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) -		red_start_of_idle_period(&t->wred_set); -  	return NULL;  } @@ -291,19 +293,20 @@ static unsigned int gred_drop(struct Qdisc *sch)  			q->backlog -= len;  			q->stats.other++; -			if (!q->backlog && !gred_wred_mode(t)) -				red_start_of_idle_period(&q->vars); +			if (gred_wred_mode(t)) { +				if (!sch->qstats.backlog) +					red_start_of_idle_period(&t->wred_set); +			} else { +				if (!q->backlog) +					red_start_of_idle_period(&q->vars); +			}  		}  		qdisc_drop(skb, sch);  		return len;  	} -	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) -		red_start_of_idle_period(&t->wred_set); -  	return 0; -  }  static void gred_reset(struct Qdisc *sch) @@ -535,6 +538,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)  	for (i = 0; i < MAX_DPs; i++) {  		struct gred_sched_data *q = table->tab[i];  		struct tc_gred_qopt opt; +		unsigned long qavg;  		memset(&opt, 0, sizeof(opt)); @@ -566,7 +570,9 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)  		if (gred_wred_mode(table))  			gred_load_wred_set(table, q); -		opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); +		qavg = red_calc_qavg(&q->parms, &q->vars, +				     q->vars.qavg >> q->parms.Wlog); +		opt.qave = qavg >> q->parms.Wlog;  append_opt:  		if (nla_append(skb, sizeof(opt), &opt) < 0) diff --git a/net/sctp/output.c b/net/sctp/output.c index 838e18b4d7e..be50aa234dc 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -364,6 +364,25 @@ finish:  	return retval;  } +static void sctp_packet_release_owner(struct sk_buff *skb) +{ +	sk_free(skb->sk); +} + +static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk) +{ +	skb_orphan(skb); +	skb->sk = sk; +	skb->destructor = sctp_packet_release_owner; + +	/* +	 * The data chunks have already been accounted for in sctp_sendmsg(), +	 * therefore only reserve a single byte to keep socket around until +	 * the packet has been transmitted. +	 */ +	atomic_inc(&sk->sk_wmem_alloc); +} +  /* All packets are sent to the network through this function from   * sctp_outq_tail().   * @@ -405,7 +424,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)  	/* Set the owning socket so that we know where to get the  	 * destination IP address.  	 */ -	skb_set_owner_w(nskb, sk); +	sctp_packet_set_owner_w(nskb, sk);  	if (!sctp_transport_dst_check(tp)) {  		sctp_transport_route(tp, NULL, sctp_sk(sk)); diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index a5a402a7d21..5d7f61d7559 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -969,11 +969,11 @@ static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)  	return false;  } -static void xprt_alloc_slot(struct rpc_task *task) +void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task)  { -	struct rpc_xprt	*xprt = task->tk_xprt;  	struct rpc_rqst *req; +	spin_lock(&xprt->reserve_lock);  	if (!list_empty(&xprt->free)) {  		req = list_entry(xprt->free.next, struct rpc_rqst, rq_list);  		list_del(&req->rq_list); @@ -994,12 +994,29 @@ static void xprt_alloc_slot(struct rpc_task *task)  	default:  		task->tk_status = -EAGAIN;  	} +	spin_unlock(&xprt->reserve_lock);  	return;  out_init_req:  	task->tk_status = 0;  	task->tk_rqstp = req;  	xprt_request_init(task, xprt); +	spin_unlock(&xprt->reserve_lock); +} +EXPORT_SYMBOL_GPL(xprt_alloc_slot); + +void xprt_lock_and_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) +{ +	/* Note: grabbing the xprt_lock_write() ensures that we throttle +	 * new slot allocation if the transport is congested (i.e. when +	 * reconnecting a stream transport or when out of socket write +	 * buffer space). +	 */ +	if (xprt_lock_write(xprt, task)) { +		xprt_alloc_slot(xprt, task); +		xprt_release_write(xprt, task); +	}  } +EXPORT_SYMBOL_GPL(xprt_lock_and_alloc_slot);  static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)  { @@ -1083,20 +1100,9 @@ void xprt_reserve(struct rpc_task *task)  	if (task->tk_rqstp != NULL)  		return; -	/* Note: grabbing the xprt_lock_write() here is not strictly needed, -	 * but ensures that we throttle new slot allocation if the transport -	 * is congested (e.g. if reconnecting or if we're out of socket -	 * write buffer space). -	 */  	task->tk_timeout = 0;  	task->tk_status = -EAGAIN; -	if (!xprt_lock_write(xprt, task)) -		return; - -	spin_lock(&xprt->reserve_lock); -	xprt_alloc_slot(task); -	spin_unlock(&xprt->reserve_lock); -	xprt_release_write(xprt, task); +	xprt->ops->alloc_slot(xprt, task);  }  static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 06cdbff79e4..5d9202dc7cb 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -713,6 +713,7 @@ static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)  static struct rpc_xprt_ops xprt_rdma_procs = {  	.reserve_xprt		= xprt_rdma_reserve_xprt,  	.release_xprt		= xprt_release_xprt_cong, /* sunrpc/xprt.c */ +	.alloc_slot		= xprt_alloc_slot,  	.release_request	= xprt_release_rqst_cong,       /* ditto */  	.set_retrans_timeout	= xprt_set_retrans_timeout_def, /* ditto */  	.rpcbind		= rpcb_getport_async,	/* sunrpc/rpcb_clnt.c */ diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 400567243f8..a35b8e52e55 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2473,6 +2473,7 @@ static void bc_destroy(struct rpc_xprt *xprt)  static struct rpc_xprt_ops xs_local_ops = {  	.reserve_xprt		= xprt_reserve_xprt,  	.release_xprt		= xs_tcp_release_xprt, +	.alloc_slot		= xprt_alloc_slot,  	.rpcbind		= xs_local_rpcbind,  	.set_port		= xs_local_set_port,  	.connect		= xs_connect, @@ -2489,6 +2490,7 @@ static struct rpc_xprt_ops xs_udp_ops = {  	.set_buffer_size	= xs_udp_set_buffer_size,  	.reserve_xprt		= xprt_reserve_xprt_cong,  	.release_xprt		= xprt_release_xprt_cong, +	.alloc_slot		= xprt_alloc_slot,  	.rpcbind		= rpcb_getport_async,  	.set_port		= xs_set_port,  	.connect		= xs_connect, @@ -2506,6 +2508,7 @@ static struct rpc_xprt_ops xs_udp_ops = {  static struct rpc_xprt_ops xs_tcp_ops = {  	.reserve_xprt		= xprt_reserve_xprt,  	.release_xprt		= xs_tcp_release_xprt, +	.alloc_slot		= xprt_lock_and_alloc_slot,  	.rpcbind		= rpcb_getport_async,  	.set_port		= xs_set_port,  	.connect		= xs_connect, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 97026f3b215..1e37dbf00cb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5633,8 +5633,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)  		       sizeof(connect.ht_capa_mask));  	if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { -		if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) +		if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { +			kfree(connkeys);  			return -EINVAL; +		}  		memcpy(&connect.ht_capa,  		       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),  		       sizeof(connect.ht_capa)); diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 54a0dc2e2f8..ab2bb42fe09 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -212,7 +212,7 @@ resume:  		/* only the first xfrm gets the encap type */  		encap_type = 0; -		if (async && x->repl->check(x, skb, seq)) { +		if (async && x->repl->recheck(x, skb, seq)) {  			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);  			goto drop_unlock;  		} diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 2f6d11d04a2..3efb07d3eb2 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -420,6 +420,18 @@ err:  	return -EINVAL;  } +static int xfrm_replay_recheck_esn(struct xfrm_state *x, +				   struct sk_buff *skb, __be32 net_seq) +{ +	if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi != +		     htonl(xfrm_replay_seqhi(x, net_seq)))) { +			x->stats.replay_window++; +			return -EINVAL; +	} + +	return xfrm_replay_check_esn(x, skb, net_seq); +} +  static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)  {  	unsigned int bitnr, nr, i; @@ -479,6 +491,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)  static struct xfrm_replay xfrm_replay_legacy = {  	.advance	= xfrm_replay_advance,  	.check		= xfrm_replay_check, +	.recheck	= xfrm_replay_check,  	.notify		= xfrm_replay_notify,  	.overflow	= xfrm_replay_overflow,  }; @@ -486,6 +499,7 @@ static struct xfrm_replay xfrm_replay_legacy = {  static struct xfrm_replay xfrm_replay_bmp = {  	.advance	= xfrm_replay_advance_bmp,  	.check		= xfrm_replay_check_bmp, +	.recheck	= xfrm_replay_check_bmp,  	.notify		= xfrm_replay_notify_bmp,  	.overflow	= xfrm_replay_overflow_bmp,  }; @@ -493,6 +507,7 @@ static struct xfrm_replay xfrm_replay_bmp = {  static struct xfrm_replay xfrm_replay_esn = {  	.advance	= xfrm_replay_advance_esn,  	.check		= xfrm_replay_check_esn, +	.recheck	= xfrm_replay_recheck_esn,  	.notify		= xfrm_replay_notify_bmp,  	.overflow	= xfrm_replay_overflow_esn,  }; diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 4235a6361fe..b3d907eb93a 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -74,8 +74,13 @@ kallsyms()  	info KSYM ${2}  	local kallsymopt; +	if [ -n "${CONFIG_SYMBOL_PREFIX}" ]; then +		kallsymopt="${kallsymopt} \ +			    --symbol-prefix=${CONFIG_SYMBOL_PREFIX}" +	fi +  	if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then -		kallsymopt=--all-symbols +		kallsymopt="${kallsymopt} --all-symbols"  	fi  	local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \ diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index ec2118d0e27..eb60cb8dbb8 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -80,14 +80,12 @@ static int snd_compr_open(struct inode *inode, struct file *f)  	int maj = imajor(inode);  	int ret; -	if (f->f_flags & O_WRONLY) +	if ((f->f_flags & O_ACCMODE) == O_WRONLY)  		dirn = SND_COMPRESS_PLAYBACK; -	else if (f->f_flags & O_RDONLY) +	else if ((f->f_flags & O_ACCMODE) == O_RDONLY)  		dirn = SND_COMPRESS_CAPTURE; -	else { -		pr_err("invalid direction\n"); +	else  		return -EINVAL; -	}  	if (maj == snd_major)  		compr = snd_lookup_minor_data(iminor(inode), diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f25c24c743f..1c65cc5e3a3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2353,6 +2353,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)  	}  	if (codec->patch_ops.free)  		codec->patch_ops.free(codec); +	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));  	snd_hda_jack_tbl_clear(codec);  	codec->proc_widget_hook = NULL;  	codec->spec = NULL; @@ -2368,7 +2369,6 @@ int snd_hda_codec_reset(struct hda_codec *codec)  	codec->num_pcms = 0;  	codec->pcm_info = NULL;  	codec->preset = NULL; -	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));  	codec->slave_dig_outs = NULL;  	codec->spdif_status_reset = 0;  	module_put(codec->owner); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 60882c62f18..c4763c52eaf 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2701,6 +2701,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {  	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),  	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),  	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), +	SND_PCI_QUIRK(0x1043, 0x1ac3, "ASUS X53S", POS_FIX_POSBUF), +	SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF),  	SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),  	SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),  	SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6f806d3e56b..3d4722f0a1c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1075,7 +1075,7 @@ static struct snd_kcontrol_new stac_smux_mixer = {  static const char * const slave_pfxs[] = {  	"Front", "Surround", "Center", "LFE", "Side", -	"Headphone", "Speaker", "IEC958", +	"Headphone", "Speaker", "IEC958", "PCM",  	NULL  }; diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 764cc93dbca..075d5aa1fee 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -297,6 +297,7 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem  }  static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); +static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);  static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {      { @@ -307,7 +308,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {  	.info = ak4396_dac_vol_info,  	.get = ak4396_dac_vol_get,  	.put = ak4396_dac_vol_put, -	.tlv = { .p = db_scale_wm_dac }, +	.tlv = { .p = ak4396_db_scale },      },  }; diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 5c9cacaf2d5..1cf7a32d1b2 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -426,7 +426,7 @@ static const int arizona_44k1_bclk_rates[] = {  	940800,  	1411200,  	1881600, -	2882400, +	2822400,  	3763200,  	5644800,  	7526400, diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 8f726c063f4..115a4030181 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -659,7 +659,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {  		.id = MC13783_ID_STEREO_DAC,  		.playback = {  			.stream_name = "Playback", -			.channels_min = 1, +			.channels_min = 2,  			.channels_max = 2,  			.rates = SNDRV_PCM_RATE_8000_96000,  			.formats = MC13783_FORMATS, @@ -670,7 +670,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {  		.id = MC13783_ID_STEREO_CODEC,  		.capture = {  			.stream_name = "Capture", -			.channels_min = 1, +			.channels_min = 2,  			.channels_max = 2,  			.rates = MC13783_RATES_RECORD,  			.formats = MC13783_FORMATS, @@ -692,14 +692,14 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {  		.id = MC13783_ID_SYNC,  		.playback = {  			.stream_name = "Playback", -			.channels_min = 1, +			.channels_min = 2,  			.channels_max = 2,  			.rates = SNDRV_PCM_RATE_8000_96000,  			.formats = MC13783_FORMATS,  		},  		.capture = {  			.stream_name = "Capture", -			.channels_min = 1, +			.channels_min = 2,  			.channels_max = 2,  			.rates = MC13783_RATES_RECORD,  			.formats = MC13783_FORMATS, diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 0013afe48e6..dc4262eea4b 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -100,7 +100,7 @@ static const struct reg_default wm8904_reg_defaults[] = {  	{ 14,  0x0000 },     /* R14  - Power Management 2 */  	{ 15,  0x0000 },     /* R15  - Power Management 3 */  	{ 18,  0x0000 },     /* R18  - Power Management 6 */ -	{ 19,  0x945E },     /* R20  - Clock Rates 0 */ +	{ 20,  0x945E },     /* R20  - Clock Rates 0 */  	{ 21,  0x0C05 },     /* R21  - Clock Rates 1 */  	{ 22,  0x0006 },     /* R22  - Clock Rates 2 */  	{ 24,  0x0050 },     /* R24  - Audio Interface 0 */ diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index fb21b17f17f..199408ec426 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -94,7 +94,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "audmux internal port setup failed\n");  		return ret;  	} -	imx_audmux_v2_configure_port(ext_port, +	ret = imx_audmux_v2_configure_port(ext_port,  			IMX_AUDMUX_V2_PTCR_SYN,  			IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));  	if (ret) { diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 009533ab8d1..df65f98211e 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -59,7 +59,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,  		return ret;  	} -	snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, +	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,  				SND_SOC_CLOCK_IN);  	if (ret < 0) {  		printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n"); diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index f3ebc38c10f..b70964ea448 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma_hardware = {  	.info			= SNDRV_PCM_INFO_INTERLEAVED |  				    SNDRV_PCM_INFO_BLOCK_TRANSFER |  				    SNDRV_PCM_INFO_MMAP | -				    SNDRV_PCM_INFO_MMAP_VALID | -				    SNDRV_PCM_INFO_PAUSE | -				    SNDRV_PCM_INFO_RESUME, +				    SNDRV_PCM_INFO_MMAP_VALID,  	.formats		= SNDRV_PCM_FMTBIT_S16_LE |  				    SNDRV_PCM_FMTBIT_U16_LE |  				    SNDRV_PCM_FMTBIT_U8 | @@ -248,15 +246,11 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)  	switch (cmd) {  	case SNDRV_PCM_TRIGGER_START: -	case SNDRV_PCM_TRIGGER_RESUME: -	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:  		prtd->state |= ST_RUNNING;  		prtd->params->ops->trigger(prtd->params->ch);  		break;  	case SNDRV_PCM_TRIGGER_STOP: -	case SNDRV_PCM_TRIGGER_SUSPEND: -	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:  		prtd->state &= ~ST_RUNNING;  		prtd->params->ops->stop(prtd->params->ch);  		break; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dd7c49fafd7..f90139b5f50 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -291,8 +291,11 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,  		if (dapm->codec->driver->set_bias_level)  			ret = dapm->codec->driver->set_bias_level(dapm->codec,  								  level); -	} else +		else +			dapm->bias_level = level; +	} else if (!card || dapm != &card->dapm) {  		dapm->bias_level = level; +	}  	if (ret != 0)  		goto out; diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 97c2cac8e92..8c7f2372944 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -138,7 +138,7 @@ static void spear_pcm_free(struct snd_pcm *pcm)  			continue;  		buf = &substream->dma_buffer; -		if (!buf && !buf->area) +		if (!buf || !buf->area)  			continue;  		dma_free_writecombine(pcm->card->dev, buf->bytes, diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index e463529b38b..76cb1b363b7 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -89,7 +89,6 @@ static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {  	.name = "Headset detection",  	.report = SND_JACK_HEADSET,  	.debounce_time = 150, -	.invert = 1,  };  static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 5658bcec193..8d6900c1ee4 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -334,11 +334,11 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {  		slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;  		slave_config.dst_addr = dmap->addr; -		slave_config.src_maxburst = 0; +		slave_config.dst_maxburst = 4;  	} else {  		slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;  		slave_config.src_addr = dmap->addr; -		slave_config.dst_maxburst = 0; +		slave_config.src_maxburst = 4;  	}  	slave_config.slave_id = dmap->req_sel; diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 5c472f335a6..eb85113d472 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -663,7 +663,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,  			struct ux500_msp **msp_p,  			struct msp_i2s_platform_data *platform_data)  { -	int ret = 0;  	struct resource *res = NULL;  	struct i2s_controller *i2s_cont;  	struct ux500_msp *msp; @@ -685,15 +684,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,  	if (res == NULL) {  		dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",  			__func__); -		ret = -ENOMEM; -		goto err_res; +		return -ENOMEM;  	} -	msp->registers = ioremap(res->start, (res->end - res->start + 1)); +	msp->registers = devm_ioremap(&pdev->dev, res->start, +				      resource_size(res));  	if (msp->registers == NULL) {  		dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__); -		ret = -ENOMEM; -		goto err_res; +		return -ENOMEM;  	}  	msp->msp_state = MSP_STATE_IDLE; @@ -705,7 +703,7 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,  		dev_err(&pdev->dev,  			"%s: ERROR: Failed to allocate I2S-controller!\n",  			__func__); -		goto err_i2s_cont; +		return -ENOMEM;  	}  	i2s_cont->dev.parent = &pdev->dev;  	i2s_cont->data = (void *)msp; @@ -716,14 +714,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,  	msp->i2s_cont = i2s_cont;  	return 0; - -err_i2s_cont: -	iounmap(msp->registers); - -err_res: -	devm_kfree(&pdev->dev, msp); - -	return ret;  }  void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, @@ -732,11 +722,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,  	dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);  	device_unregister(&msp->i2s_cont->dev); -	devm_kfree(&pdev->dev, msp->i2s_cont); - -	iounmap(msp->registers); - -	devm_kfree(&pdev->dev, msp);  }  MODULE_LICENSE("GPL v2"); diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index fd5e982fc98..f782ce19bf5 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1140,6 +1140,12 @@ static void retire_playback_urb(struct snd_usb_substream *subs,  	int processed = urb->transfer_buffer_length / stride;  	int est_delay; +	/* ignore the delay accounting when procssed=0 is given, i.e. +	 * silent payloads are procssed before handling the actual data +	 */ +	if (!processed) +		return; +  	spin_lock_irqsave(&subs->lock, flags);  	est_delay = snd_usb_pcm_delay(subs, runtime->rate);  	/* update delay with exact number of samples played */  |