diff options
722 files changed, 6019 insertions, 3422 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 34f51100f02..dff1f48d252 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -210,3 +210,15 @@ Users:  		firmware assigned instance number of the PCI  		device that can help in understanding the firmware  		intended order of the PCI device. + +What:		/sys/bus/pci/devices/.../d3cold_allowed +Date:		July 2012 +Contact:	Huang Ying <ying.huang@intel.com> +Description: +		d3cold_allowed is bit to control whether the corresponding PCI +		device can be put into D3Cold state.  If it is cleared, the +		device will never be put into D3Cold state.  If it is set, the +		device may be put into D3Cold state if other requirements are +		satisfied too.  Reading this attribute will show the current +		value of d3cold_allowed bit.  Writing this attribute will set +		the value of d3cold_allowed bit. diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX index d111e3b23db..d18ecd827c4 100644 --- a/Documentation/block/00-INDEX +++ b/Documentation/block/00-INDEX @@ -3,15 +3,21 @@  biodoc.txt  	- Notes on the Generic Block Layer Rewrite in Linux 2.5  capability.txt -	- Generic Block Device Capability (/sys/block/<disk>/capability) +	- Generic Block Device Capability (/sys/block/<device>/capability) +cfq-iosched.txt +	- CFQ IO scheduler tunables +data-integrity.txt +	- Block data integrity  deadline-iosched.txt  	- Deadline IO scheduler tunables  ioprio.txt  	- Block io priorities (in CFQ scheduler) +queue-sysfs.txt +	- Queue's sysfs entries  request.txt  	- The members of struct request (in include/linux/blkdev.h)  stat.txt -	- Block layer statistics in /sys/block/<dev>/stat +	- Block layer statistics in /sys/block/<device>/stat  switching-sched.txt  	- Switching I/O schedulers at runtime  writeback_cache_control.txt diff --git a/Documentation/block/cfq-iosched.txt b/Documentation/block/cfq-iosched.txt index 6d670f57045..d89b4fe724d 100644 --- a/Documentation/block/cfq-iosched.txt +++ b/Documentation/block/cfq-iosched.txt @@ -1,3 +1,14 @@ +CFQ (Complete Fairness Queueing) +=============================== + +The main aim of CFQ scheduler is to provide a fair allocation of the disk +I/O bandwidth for all the processes which requests an I/O operation. + +CFQ maintains the per process queue for the processes which request I/O +operation(syncronous requests). In case of asynchronous requests, all the +requests from all the processes are batched together according to their +process's I/O priority. +  CFQ ioscheduler tunables  ======================== @@ -25,6 +36,72 @@ there are multiple spindles behind single LUN (Host based hardware RAID  controller or for storage arrays), setting slice_idle=0 might end up in better  throughput and acceptable latencies. +back_seek_max +------------- +This specifies, given in Kbytes, the maximum "distance" for backward seeking. +The distance is the amount of space from the current head location to the +sectors that are backward in terms of distance. + +This parameter allows the scheduler to anticipate requests in the "backward" +direction and consider them as being the "next" if they are within this +distance from the current head location. + +back_seek_penalty +----------------- +This parameter is used to compute the cost of backward seeking. If the +backward distance of request is just 1/back_seek_penalty from a "front" +request, then the seeking cost of two requests is considered equivalent. + +So scheduler will not bias toward one or the other request (otherwise scheduler +will bias toward front request). Default value of back_seek_penalty is 2. + +fifo_expire_async +----------------- +This parameter is used to set the timeout of asynchronous requests. Default +value of this is 248ms. + +fifo_expire_sync +---------------- +This parameter is used to set the timeout of synchronous requests. Default +value of this is 124ms. In case to favor synchronous requests over asynchronous +one, this value should be decreased relative to fifo_expire_async. + +slice_async +----------- +This parameter is same as of slice_sync but for asynchronous queue. The +default value is 40ms. + +slice_async_rq +-------------- +This parameter is used to limit the dispatching of asynchronous request to +device request queue in queue's slice time. The maximum number of request that +are allowed to be dispatched also depends upon the io priority. Default value +for this is 2. + +slice_sync +---------- +When a queue is selected for execution, the queues IO requests are only +executed for a certain amount of time(time_slice) before switching to another +queue. This parameter is used to calculate the time slice of synchronous +queue. + +time_slice is computed using the below equation:- +time_slice = slice_sync + (slice_sync/5 * (4 - prio)). To increase the +time_slice of synchronous queue, increase the value of slice_sync. Default +value is 100ms. + +quantum +------- +This specifies the number of request dispatched to the device queue. In a +queue's time slice, a request will not be dispatched if the number of request +in the device exceeds this parameter. This parameter is used for synchronous +request. + +In case of storage with several disk, this setting can limit the parallel +processing of request. Therefore, increasing the value can imporve the +performace although this can cause the latency of some I/O to increase due +to more number of requests. +  CFQ IOPS Mode for group scheduling  ===================================  Basic CFQ design is to provide priority based time slices. Higher priority diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index 6518a55273e..e54ac1d5340 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt @@ -9,20 +9,71 @@ These files are the ones found in the /sys/block/xxx/queue/ directory.  Files denoted with a RO postfix are readonly and the RW postfix means  read-write. +add_random (RW) +---------------- +This file allows to trun off the disk entropy contribution. Default +value of this file is '1'(on). + +discard_granularity (RO) +----------------------- +This shows the size of internal allocation of the device in bytes, if +reported by the device. A value of '0' means device does not support +the discard functionality. + +discard_max_bytes (RO) +---------------------- +Devices that support discard functionality may have internal limits on +the number of bytes that can be trimmed or unmapped in a single operation. +The discard_max_bytes parameter is set by the device driver to the maximum +number of bytes that can be discarded in a single operation. Discard +requests issued to the device must not exceed this limit. A discard_max_bytes +value of 0 means that the device does not support discard functionality. + +discard_zeroes_data (RO) +------------------------ +When read, this file will show if the discarded block are zeroed by the +device or not. If its value is '1' the blocks are zeroed otherwise not. +  hw_sector_size (RO)  -------------------  This is the hardware sector size of the device, in bytes. +iostats (RW) +------------- +This file is used to control (on/off) the iostats accounting of the +disk. + +logical_block_size (RO) +----------------------- +This is the logcal block size of the device, in bytes. +  max_hw_sectors_kb (RO)  ----------------------  This is the maximum number of kilobytes supported in a single data transfer. +max_integrity_segments (RO) +--------------------------- +When read, this file shows the max limit of integrity segments as +set by block layer which a hardware controller can handle. +  max_sectors_kb (RW)  -------------------  This is the maximum number of kilobytes that the block layer will allow  for a filesystem request. Must be smaller than or equal to the maximum  size allowed by the hardware. +max_segments (RO) +----------------- +Maximum number of segments of the device. + +max_segment_size (RO) +--------------------- +Maximum segment size of the device. + +minimum_io_size (RO) +-------------------- +This is the smallest preferred io size reported by the device. +  nomerges (RW)  -------------  This enables the user to disable the lookup logic involved with IO @@ -45,11 +96,24 @@ per-block-cgroup request pool.  IOW, if there are N block cgroups,  each request queue may have upto N request pools, each independently  regulated by nr_requests. +optimal_io_size (RO) +-------------------- +This is the optimal io size reported by the device. + +physical_block_size (RO) +------------------------ +This is the physical block size of device, in bytes. +  read_ahead_kb (RW)  ------------------  Maximum number of kilobytes to read-ahead for filesystems on this block  device. +rotational (RW) +--------------- +This file is used to stat if the device is of rotational type or +non-rotational type. +  rq_affinity (RW)  ----------------  If this option is '1', the block layer will migrate request completions to the diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt index 70cd49b1caa..1dd622546d0 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt @@ -10,8 +10,8 @@ Required properties:  - compatible : Should be "fsl,<chip>-esdhc"  Optional properties: -- fsl,cd-internal : Indicate to use controller internal card detection -- fsl,wp-internal : Indicate to use controller internal write protection +- fsl,cd-controller : Indicate to use controller internal card detection +- fsl,wp-controller : Indicate to use controller internal write protection  Examples: @@ -19,8 +19,8 @@ esdhc@70004000 {  	compatible = "fsl,imx51-esdhc";  	reg = <0x70004000 0x4000>;  	interrupts = <1>; -	fsl,cd-internal; -	fsl,wp-internal; +	fsl,cd-controller; +	fsl,wp-controller;  };  esdhc@70008000 { diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index afaff312bf4..f4d8c7105fc 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -579,7 +579,7 @@ Why:	KVM tracepoints provide mostly equivalent information in a much more  ----------------------------  What:	at91-mci driver ("CONFIG_MMC_AT91") -When:	3.7 +When:	3.8  Why:	There are two mci drivers: at91-mci and atmel-mci. The PDC support  	was added to atmel-mci as a first step to support more chips.  	Then at91-mci was kept only for old IP versions (on at91rm9200 and 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/Documentation/watchdog/src/watchdog-test.c b/Documentation/watchdog/src/watchdog-test.c index 73ff5cc93e0..3da822967ee 100644 --- a/Documentation/watchdog/src/watchdog-test.c +++ b/Documentation/watchdog/src/watchdog-test.c @@ -31,7 +31,7 @@ static void keep_alive(void)   * or "-e" to enable the card.   */ -void term(int sig) +static void term(int sig)  {      close(fd);      fprintf(stderr, "Stopping watchdog ticks...\n"); diff --git a/MAINTAINERS b/MAINTAINERS index 78a1ee4710a..3ad19ab073c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3390,7 +3390,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 = -rc3 +EXTRAVERSION = -rc6  NAME = Saber-toothed Squirrel  # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6d6e18fee9f..2f88d8d9770 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -6,7 +6,7 @@ config ARM  	select HAVE_DMA_API_DEBUG  	select HAVE_IDE if PCI || ISA || PCMCIA  	select HAVE_DMA_ATTRS -	select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7) +	select HAVE_DMA_CONTIGUOUS if MMU  	select HAVE_MEMBLOCK  	select RTC_LIB  	select SYS_SUPPORTS_APM_EMULATION @@ -2144,6 +2144,7 @@ source "drivers/cpufreq/Kconfig"  config CPU_FREQ_IMX  	tristate "CPUfreq driver for i.MX CPUs"  	depends on ARCH_MXC && CPU_FREQ +	select CPU_FREQ_TABLE  	help  	  This enables the CPUfreq driver for i.MX CPUs. 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/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 59509c48d7e..bd0cff3f808 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -154,5 +154,10 @@  			#size-cells = <0>;  			ti,hwmods = "i2c3";  		}; + +		wdt2: wdt@44e35000 { +			compatible = "ti,omap3-wdt"; +			ti,hwmods = "wd_timer2"; +		};  	};  }; diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts index 7829a4d0cb2..96514c134e5 100644 --- a/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/arch/arm/boot/dts/at91sam9g25ek.dts @@ -15,7 +15,7 @@  	compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";  	chosen { -		bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; +		bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";  	};  	ahb { diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index cd86177a3ea..59d9789e550 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -25,8 +25,8 @@  		aips@70000000 { /* aips-1 */  			spba@70000000 {  				esdhc@70004000 { /* ESDHC1 */ -					fsl,cd-internal; -					fsl,wp-internal; +					fsl,cd-controller; +					fsl,wp-controller;  					status = "okay";  				}; diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 52d94704510..f8ca6fa8819 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -41,9 +41,13 @@  		};  		power-blue {  			label = "power:blue"; -			gpios = <&gpio1 11 0>; +			gpios = <&gpio1 10 0>;  			linux,default-trigger = "timer";  		}; +		power-red { +			label = "power:red"; +			gpios = <&gpio1 11 0>; +		};  		usb1 {  			label = "usb1:blue";  			gpios = <&gpio1 12 0>; diff --git a/arch/arm/boot/dts/twl6030.dtsi b/arch/arm/boot/dts/twl6030.dtsi index 3b2f3510d7e..d351b27d721 100644 --- a/arch/arm/boot/dts/twl6030.dtsi +++ b/arch/arm/boot/dts/twl6030.dtsi @@ -66,6 +66,7 @@  	vcxio: regulator@8 {  		compatible = "ti,twl6030-vcxio"; +		regulator-always-on;  	};  	vusb: regulator@9 { @@ -74,10 +75,12 @@  	v1v8: regulator@10 {  		compatible = "ti,twl6030-v1v8"; +		regulator-always-on;  	};  	v2v1: regulator@11 {  		compatible = "ti,twl6030-v2v1"; +		regulator-always-on;  	};  	clk32kg: regulator@12 { diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig index 7d8718468e0..90610c7030f 100644 --- a/arch/arm/configs/armadillo800eva_defconfig +++ b/arch/arm/configs/armadillo800eva_defconfig @@ -33,7 +33,7 @@ CONFIG_AEABI=y  CONFIG_FORCE_MAX_ZONEORDER=13  CONFIG_ZBOOT_ROM_TEXT=0x0  CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096" +CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw"  CONFIG_CMDLINE_FORCE=y  CONFIG_KEXEC=y  CONFIG_VFP=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 2d4f661d1cf..da6845493ca 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -86,6 +86,7 @@ CONFIG_NEW_LEDS=y  CONFIG_LEDS_CLASS=y  CONFIG_LEDS_LM3530=y  CONFIG_LEDS_LP5521=y +CONFIG_LEDS_GPIO=y  CONFIG_RTC_CLASS=y  CONFIG_RTC_DRV_AB8500=y  CONFIG_RTC_DRV_PL031=y 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/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 2ae842df455..5c44dcb0987 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -203,6 +203,13 @@ static inline void dma_free_writecombine(struct device *dev, size_t size,  }  /* + * This can be called during early boot to increase the size of the atomic + * coherent DMA pool above the default value of 256KiB. It must be called + * before postcore_initcall. + */ +extern void __init init_dma_coherent_pool_size(unsigned long size); + +/*   * This can be called during boot to increase the size of the consistent   * DMA region above it's default value of 2MB. It must be called before the   * memory allocator is initialised, i.e. before any core_initcall. 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-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 104ca40d8d1..aaa443b48c9 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -197,7 +197,7 @@ void __init at91rm9200_timer_init(void)  	at91_st_read(AT91_ST_SR);  	/* Make IRQs happen for the system timer */ -	setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); +	setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq);  	/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used  	 * directly for the clocksource and all clockevents, after adjusting diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 7b9c2ba396e..bce572a530e 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -726,6 +726,8 @@ static struct resource rtt_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	},  }; @@ -744,10 +746,12 @@ static void __init at91_add_device_rtt_rtc(void)  	 * The second resource is needed:  	 * GPBR will serve as the storage for RTC time offset  	 */ -	at91sam9260_rtt_device.num_resources = 2; +	at91sam9260_rtt_device.num_resources = 3;  	rtt_resources[1].start = AT91SAM9260_BASE_GPBR +  				 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;  	rtt_resources[1].end = rtt_resources[1].start + 3; +	rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; +	rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS;  }  #else  static void __init at91_add_device_rtt_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 8df5c1bdff9..bc2590d712d 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -609,6 +609,8 @@ static struct resource rtt_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	}  }; @@ -626,10 +628,12 @@ static void __init at91_add_device_rtt_rtc(void)  	 * The second resource is needed:  	 * GPBR will serve as the storage for RTC time offset  	 */ -	at91sam9261_rtt_device.num_resources = 2; +	at91sam9261_rtt_device.num_resources = 3;  	rtt_resources[1].start = AT91SAM9261_BASE_GPBR +  				 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;  	rtt_resources[1].end = rtt_resources[1].start + 3; +	rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; +	rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS;  }  #else  static void __init at91_add_device_rtt_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index eb6bbf86fb9..9b6ca734f1a 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -990,6 +990,8 @@ static struct resource rtt0_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	}  }; @@ -1006,6 +1008,8 @@ static struct resource rtt1_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	}  }; @@ -1027,14 +1031,14 @@ static void __init at91_add_device_rtt_rtc(void)  		 * The second resource is needed only for the chosen RTT:  		 * GPBR will serve as the storage for RTC time offset  		 */ -		at91sam9263_rtt0_device.num_resources = 2; +		at91sam9263_rtt0_device.num_resources = 3;  		at91sam9263_rtt1_device.num_resources = 1;  		pdev = &at91sam9263_rtt0_device;  		r = rtt0_resources;  		break;  	case 1:  		at91sam9263_rtt0_device.num_resources = 1; -		at91sam9263_rtt1_device.num_resources = 2; +		at91sam9263_rtt1_device.num_resources = 3;  		pdev = &at91sam9263_rtt1_device;  		r = rtt1_resources;  		break; @@ -1047,6 +1051,8 @@ static void __init at91_add_device_rtt_rtc(void)  	pdev->name = "rtc-at91sam9";  	r[1].start = AT91SAM9263_BASE_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;  	r[1].end = r[1].start + 3; +	r[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; +	r[2].end = NR_IRQS_LEGACY + AT91_ID_SYS;  }  #else  static void __init at91_add_device_rtt_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 06073996a38..1b47319ca00 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1293,6 +1293,8 @@ static struct resource rtt_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	}  }; @@ -1310,10 +1312,12 @@ static void __init at91_add_device_rtt_rtc(void)  	 * The second resource is needed:  	 * GPBR will serve as the storage for RTC time offset  	 */ -	at91sam9g45_rtt_device.num_resources = 2; +	at91sam9g45_rtt_device.num_resources = 3;  	rtt_resources[1].start = AT91SAM9G45_BASE_GPBR +  				 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;  	rtt_resources[1].end = rtt_resources[1].start + 3; +	rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; +	rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS;  }  #else  static void __init at91_add_device_rtt_rtc(void) diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index f09fff93217..b3d365dadef 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -688,6 +688,8 @@ static struct resource rtt_resources[] = {  		.flags	= IORESOURCE_MEM,  	}, {  		.flags	= IORESOURCE_MEM, +	}, { +		.flags  = IORESOURCE_IRQ,  	}  }; @@ -705,10 +707,12 @@ static void __init at91_add_device_rtt_rtc(void)  	 * The second resource is needed:  	 * GPBR will serve as the storage for RTC time offset  	 */ -	at91sam9rl_rtt_device.num_resources = 2; +	at91sam9rl_rtt_device.num_resources = 3;  	rtt_resources[1].start = AT91SAM9RL_BASE_GPBR +  				 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR;  	rtt_resources[1].end = rtt_resources[1].start + 3; +	rtt_resources[2].start = NR_IRQS_LEGACY + AT91_ID_SYS; +	rtt_resources[2].end = NR_IRQS_LEGACY + AT91_ID_SYS;  }  #else  static void __init at91_add_device_rtt_rtc(void) diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index de2ec6b8fea..188c82971eb 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -63,6 +63,12 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);  #define cpu_has_300M_plla()	(cpu_is_at91sam9g10()) +#define cpu_has_240M_plla()	(cpu_is_at91sam9261() \ +				|| cpu_is_at91sam9263() \ +				|| cpu_is_at91sam9rl()) + +#define cpu_has_210M_plla()	(cpu_is_at91sam9260()) +  #define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \  				|| cpu_is_at91sam9g45() \  				|| cpu_is_at91sam9x5() \ @@ -706,6 +712,12 @@ static int __init at91_pmc_init(unsigned long main_clock)  	} else if (cpu_has_800M_plla()) {  		if (plla.rate_hz > 800000000)  			pll_overclock = true; +	} else if (cpu_has_240M_plla()) { +		if (plla.rate_hz > 240000000) +			pll_overclock = true; +	} else if (cpu_has_210M_plla()) { +		if (plla.rate_hz > 210000000) +			pll_overclock = true;  	} else {  		if (plla.rate_hz > 209000000)  			pll_overclock = true; diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 4db5de54b6a..6321567d8ea 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -102,7 +102,8 @@ void __init dove_ehci1_init(void)  void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE, -			IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR); +			IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR, +			1600);  }  /***************************************************************************** diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c index 5ca80307d6d..4e574c24581 100644 --- a/arch/arm/mach-exynos/mach-origen.c +++ b/arch/arm/mach-exynos/mach-origen.c @@ -42,6 +42,7 @@  #include <plat/backlight.h>  #include <plat/fb.h>  #include <plat/mfc.h> +#include <plat/hdmi.h>  #include <mach/ohci.h>  #include <mach/map.h> @@ -734,6 +735,11 @@ static void __init origen_bt_setup(void)  	s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE);  } +/* I2C module and id for HDMIPHY */ +static struct i2c_board_info hdmiphy_info = { +	I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38), +}; +  static void s5p_tv_setup(void)  {  	/* Direct HPD to HDMI chip */ @@ -781,6 +787,7 @@ static void __init origen_machine_init(void)  	s5p_tv_setup();  	s5p_i2c_hdmiphy_set_platdata(NULL); +	s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);  #ifdef CONFIG_DRM_EXYNOS  	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata; diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c index 3cfa688d274..73f2bce097e 100644 --- a/arch/arm/mach-exynos/mach-smdkv310.c +++ b/arch/arm/mach-exynos/mach-smdkv310.c @@ -40,6 +40,7 @@  #include <plat/mfc.h>  #include <plat/ehci.h>  #include <plat/clock.h> +#include <plat/hdmi.h>  #include <mach/map.h>  #include <mach/ohci.h> @@ -354,6 +355,11 @@ static struct platform_pwm_backlight_data smdkv310_bl_data = {  	.pwm_period_ns  = 1000,  }; +/* I2C module and id for HDMIPHY */ +static struct i2c_board_info hdmiphy_info = { +	I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38), +}; +  static void s5p_tv_setup(void)  {  	/* direct HPD to HDMI chip */ @@ -388,6 +394,7 @@ static void __init smdkv310_machine_init(void)  	s5p_tv_setup();  	s5p_i2c_hdmiphy_set_platdata(NULL); +	s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);  	samsung_keypad_set_platdata(&smdkv310_keypad_data); diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c index ca70e5fcc7a..020852d3bdd 100644 --- a/arch/arm/mach-gemini/irq.c +++ b/arch/arm/mach-gemini/irq.c @@ -17,6 +17,7 @@  #include <linux/sched.h>  #include <asm/irq.h>  #include <asm/mach/irq.h> +#include <asm/system_misc.h>  #include <mach/hardware.h>  #define IRQ_SOURCE(base_addr)	(base_addr + 0x00) diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 07f7c226e4c..d004d37ad9d 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -9,7 +9,8 @@ obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o  obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o  obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o +imx5-pm-$(CONFIG_PM) += pm-imx5.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o  obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \  			    clk-pfd.o clk-busy.o @@ -70,14 +71,13 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o  obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o  obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o  obj-$(CONFIG_HAVE_IMX_SRC) += src.o -obj-$(CONFIG_CPU_V7) += head-v7.o -AFLAGS_head-v7.o :=-Wa,-march=armv7-a -obj-$(CONFIG_SMP) += platsmp.o +AFLAGS_headsmp.o :=-Wa,-march=armv7-a +obj-$(CONFIG_SMP) += headsmp.o platsmp.o  obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o  obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o  ifeq ($(CONFIG_PM),y) -obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o +obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o  endif  # i.MX5 based machines 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-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index ea89520b6e2..4233d9e3531 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -152,7 +152,7 @@ enum mx6q_clks {  	ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,  	usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,  	pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, -	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, +	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,  	clk_max  }; @@ -288,8 +288,10 @@ int __init mx6q_clocks_init(void)  	clk[gpu3d_shader]     = imx_clk_divider("gpu3d_shader",     "gpu3d_shader_sel",  base + 0x18, 29, 3);  	clk[ipu1_podf]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          base + 0x3c, 11, 3);  	clk[ipu2_podf]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          base + 0x3c, 16, 3); -	clk[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf",     "ldb_di0_sel",       base + 0x20, 10, 1); -	clk[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf",     "ldb_di1_sel",       base + 0x20, 11, 1); +	clk[ldb_di0_div_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); +	clk[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf",     "ldb_di0_div_3_5",       base + 0x20, 10, 1); +	clk[ldb_di1_div_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); +	clk[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf",     "ldb_di1_div_3_5",   base + 0x20, 11, 1);  	clk[ipu1_di0_pre]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  base + 0x34, 3,  3);  	clk[ipu1_di1_pre]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  base + 0x34, 12, 3);  	clk[ipu2_di0_pre]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  base + 0x38, 3,  3); diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/headsmp.S index 7e49deb128a..7e49deb128a 100644 --- a/arch/arm/mach-imx/head-v7.S +++ b/arch/arm/mach-imx/headsmp.S diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 20ed2d56c1a..f8f7437c83b 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -42,22 +42,6 @@ static inline void cpu_enter_lowpower(void)  	  : "cc");  } -static inline void cpu_leave_lowpower(void) -{ -	unsigned int v; - -	asm volatile( -		"mrc	p15, 0, %0, c1, c0, 0\n" -	"	orr	%0, %0, %1\n" -	"	mcr	p15, 0, %0, c1, c0, 0\n" -	"	mrc	p15, 0, %0, c1, c0, 1\n" -	"	orr	%0, %0, %2\n" -	"	mcr	p15, 0, %0, c1, c0, 1\n" -	  : "=&r" (v) -	  : "Ir" (CR_C), "Ir" (0x40) -	  : "cc"); -} -  /*   * platform-specific code to shutdown a CPU   * @@ -67,11 +51,10 @@ void platform_cpu_die(unsigned int cpu)  {  	cpu_enter_lowpower();  	imx_enable_cpu(cpu, false); -	cpu_do_idle(); -	cpu_leave_lowpower(); -	/* We should never return from idle */ -	panic("cpu %d unexpectedly exit from shutdown\n", cpu); +	/* spin here until hardware takes it down */ +	while (1) +		;  }  int platform_cpu_disable(unsigned int cpu) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 5ec0608f2a7..045b3f6a387 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -71,7 +71,7 @@ soft:  /* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */  static int ksz9021rn_phy_fixup(struct phy_device *phydev)  { -	if (IS_ENABLED(CONFIG_PHYLIB)) { +	if (IS_BUILTIN(CONFIG_PHYLIB)) {  		/* min rx data delay */  		phy_write(phydev, 0x0b, 0x8105);  		phy_write(phydev, 0x0c, 0x0000); @@ -112,7 +112,7 @@ put_clk:  static void __init imx6q_sabrelite_init(void)  { -	if (IS_ENABLED(CONFIG_PHYLIB)) +	if (IS_BUILTIN(CONFIG_PHYLIB))  		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,  				ksz9021rn_phy_fixup);  	imx6q_sabrelite_cko1_setup(); diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index a5717558ee8..a13299d758e 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot @@ -7,7 +7,8 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb  dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb  dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb  dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb -dtb-$(CONFIG_MACH_TS219_DT)	+= kirkwood-qnap-ts219.dtb +dtb-$(CONFIG_MACH_TS219_DT)	+= kirkwood-ts219-6281.dtb +dtb-$(CONFIG_MACH_TS219_DT)	+= kirkwood-ts219-6282.dtb  dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb  dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb  dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c4b64adcbfc..1201191d7f1 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -301,7 +301,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge00_init(eth_data,  			GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, -			IRQ_KIRKWOOD_GE00_ERR); +			IRQ_KIRKWOOD_GE00_ERR, 1600);  	/* The interface forgets the MAC address assigned by u-boot if  	the clock is turned off, so claim the clk now. */  	clk_prepare_enable(ge0); @@ -315,7 +315,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge01_init(eth_data,  			GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, -			IRQ_KIRKWOOD_GE01_ERR); +			IRQ_KIRKWOOD_GE01_ERR, 1600);  	clk_prepare_enable(ge1);  } @@ -517,6 +517,13 @@ void __init kirkwood_wdt_init(void)  void __init kirkwood_init_early(void)  {  	orion_time_set_base(TIMER_VIRT_BASE); + +	/* +	 * Some Kirkwood devices allocate their coherent buffers from atomic +	 * context. Increase size of atomic coherent pool to make sure such +	 * the allocations won't fail. +	 */ +	init_dma_coherent_pool_size(SZ_1M);  }  int kirkwood_tclk; diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c index d9335937959..be90b7d0e10 100644 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c @@ -10,6 +10,7 @@  #include <linux/kernel.h>  #include <linux/init.h> +#include <linux/sizes.h>  #include <linux/platform_device.h>  #include <linux/mtd/partitions.h>  #include <linux/ata_platform.h> diff --git a/arch/arm/mach-mmp/sram.c b/arch/arm/mach-mmp/sram.c index 4304f951937..7e8a5a2e1ec 100644 --- a/arch/arm/mach-mmp/sram.c +++ b/arch/arm/mach-mmp/sram.c @@ -68,7 +68,7 @@ static int __devinit sram_probe(struct platform_device *pdev)  	struct resource *res;  	int ret = 0; -	if (!pdata && !pdata->pool_name) +	if (!pdata || !pdata->pool_name)  		return -ENODEV;  	info = kzalloc(sizeof(*info), GFP_KERNEL); diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c index 62b53d710ef..a9bc84180d2 100644 --- a/arch/arm/mach-mv78xx0/addr-map.c +++ b/arch/arm/mach-mv78xx0/addr-map.c @@ -37,7 +37,7 @@  #define WIN0_OFF(n)		(BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))  #define WIN8_OFF(n)		(BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) -static void __init __iomem *win_cfg_base(int win) +static void __init __iomem *win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)  {  	/*  	 * Find the control register base address for this window. diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index b4c53b846c9..3057f7d4329 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -213,7 +213,8 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge00_init(eth_data,  			GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, -			IRQ_MV78XX0_GE_ERR); +			IRQ_MV78XX0_GE_ERR, +			MV643XX_TX_CSUM_DEFAULT_LIMIT);  } @@ -224,7 +225,8 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge01_init(eth_data,  			GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, -			NO_IRQ); +			NO_IRQ, +			MV643XX_TX_CSUM_DEFAULT_LIMIT);  } diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index dd2db025f77..346fd26f3aa 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -62,13 +62,14 @@ config ARCH_OMAP4  	select PM_OPP if PM  	select USB_ARCH_HAS_EHCI if USB_SUPPORT  	select ARM_CPU_SUSPEND if PM -	select ARCH_NEEDS_CPU_IDLE_COUPLED +	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP  config SOC_OMAP5  	bool "TI OMAP5"  	select CPU_V7  	select ARM_GIC  	select HAVE_SMP +	select ARM_CPU_SUSPEND if PM  comment "OMAP Core Type"  	depends on ARCH_OMAP2 @@ -231,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-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 74915295482..28214483aab 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -554,6 +554,8 @@ static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = {  #ifdef CONFIG_OMAP_MUX  static struct omap_board_mux board_mux[] __initdata = { +	/* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */ +	OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),  	{ .reg_offset = OMAP_MUX_TERMINATOR },  };  #endif diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index ef230a0eb5e..0d362e9f9cb 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -58,6 +58,7 @@  #include "hsmmc.h"  #include "common-board-devices.h" +#define OMAP3_EVM_TS_GPIO	175  #define OMAP3_EVM_EHCI_VBUS	22  #define OMAP3_EVM_EHCI_SELECT	61 diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c index 25bbcc7ca4d..ae27de8899a 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/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 14734746457..c1875862679 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -35,16 +35,6 @@ static struct omap2_mcspi_device_config ads7846_mcspi_config = {  	.turbo_mode	= 0,  }; -/* - * ADS7846 driver maybe request a gpio according to the value - * of pdata->get_pendown_state, but we have done this. So set - * get_pendown_state to avoid twice gpio requesting. - */ -static int omap3_get_pendown_state(void) -{ -	return !gpio_get_value(OMAP3_EVM_TS_GPIO); -} -  static struct ads7846_platform_data ads7846_config = {  	.x_max			= 0x0fff,  	.y_max			= 0x0fff, @@ -55,7 +45,6 @@ static struct ads7846_platform_data ads7846_config = {  	.debounce_rep		= 1,  	.gpio_pendown		= -EINVAL,  	.keep_vref_on		= 1, -	.get_pendown_state	= &omap3_get_pendown_state,  };  static struct spi_board_info ads7846_spi_board_info __initdata = { diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h index 4c4ef6a6166..a0b4a42836a 100644 --- a/arch/arm/mach-omap2/common-board-devices.h +++ b/arch/arm/mach-omap2/common-board-devices.h @@ -4,7 +4,6 @@  #include "twl-common.h"  #define NAND_BLOCK_SIZE	SZ_128K -#define OMAP3_EVM_TS_GPIO	175  struct mtd_partition;  struct ads7846_platform_data; diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index ee05e193fc6..288bee6cbb7 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -238,8 +238,9 @@ int __init omap4_idle_init(void)  	for_each_cpu(cpu_id, cpu_online_mask) {  		dev = &per_cpu(omap4_idle_dev, cpu_id);  		dev->cpu = cpu_id; +#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED  		dev->coupled_cpus = *cpu_online_mask; - +#endif  		cpuidle_register_driver(&omap4_idle_driver);  		if (cpuidle_register_device(dev)) { diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 471e62a74a1..76f9b3c2f58 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -127,7 +127,6 @@ struct omap_mux_partition {   * @gpio:	GPIO number   * @muxnames:	available signal modes for a ball   * @balls:	available balls on the package - * @partition:	mux partition   */  struct omap_mux {  	u16	reg_offset; diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 05fdebfaa19..330d4c6e746 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -46,7 +46,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 6ca8e519968..37afbd173c2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -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 c9e38200216..ce7e6068768 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 242aee498ce..afb60917a94 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -4210,7 +4210,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", @@ -4828,7 +4828,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", @@ -5362,7 +5362,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", @@ -6032,7 +6032,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, @@ -6068,7 +6068,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, @@ -6099,7 +6099,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/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index 2293ba27101..c95415da23c 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -94,7 +94,7 @@ int __init omap4_opp_init(void)  {  	int r = -ENODEV; -	if (!cpu_is_omap44xx()) +	if (!cpu_is_omap443x())  		return r;  	r = omap_init_opp_table(omap44xx_opp_def_list, diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index e4fc88c65db..05bd8f02723 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -272,21 +272,16 @@ void omap_sram_idle(void)  	per_next_state = pwrdm_read_next_pwrst(per_pwrdm);  	core_next_state = pwrdm_read_next_pwrst(core_pwrdm); -	if (mpu_next_state < PWRDM_POWER_ON) { -		pwrdm_pre_transition(mpu_pwrdm); -		pwrdm_pre_transition(neon_pwrdm); -	} +	pwrdm_pre_transition(NULL);  	/* PER */  	if (per_next_state < PWRDM_POWER_ON) { -		pwrdm_pre_transition(per_pwrdm);  		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;  		omap2_gpio_prepare_for_idle(per_going_off);  	}  	/* CORE */  	if (core_next_state < PWRDM_POWER_ON) { -		pwrdm_pre_transition(core_pwrdm);  		if (core_next_state == PWRDM_POWER_OFF) {  			omap3_core_save_context();  			omap3_cm_save_context(); @@ -339,20 +334,14 @@ void omap_sram_idle(void)  			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,  					       OMAP3430_GR_MOD,  					       OMAP3_PRM_VOLTCTRL_OFFSET); -		pwrdm_post_transition(core_pwrdm);  	}  	omap3_intc_resume_idle(); +	pwrdm_post_transition(NULL); +  	/* PER */ -	if (per_next_state < PWRDM_POWER_ON) { +	if (per_next_state < PWRDM_POWER_ON)  		omap2_gpio_resume_after_idle(); -		pwrdm_post_transition(per_pwrdm); -	} - -	if (mpu_next_state < PWRDM_POWER_ON) { -		pwrdm_post_transition(mpu_pwrdm); -		pwrdm_post_transition(neon_pwrdm); -	}  }  static void omap3_pm_idle(void) diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 9f6b83d1b19..91e71d8f46f 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -56,9 +56,13 @@ ppa_por_params:   * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.   * It returns to the caller for CPU INACTIVE and ON power states or in case   * CPU failed to transition to targeted OFF/DORMANT state. + * + * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save + * stack frame and it expects the caller to take care of it. Hence the entire + * stack frame is saved to avoid possible stack corruption.   */  ENTRY(omap4_finish_suspend) -	stmfd	sp!, {lr} +	stmfd	sp!, {r4-r12, lr}  	cmp	r0, #0x0  	beq	do_WFI				@ No lowpower state, jump to WFI @@ -226,7 +230,7 @@ scu_gp_clear:  skip_scu_gp_clear:  	isb  	dsb -	ldmfd	sp!, {pc} +	ldmfd	sp!, {r4-r12, pc}  ENDPROC(omap4_finish_suspend)  /* diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2ff6d41ec6c..2ba4f57dda8 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -260,6 +260,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)  { @@ -299,6 +300,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/twl-common.c b/arch/arm/mach-omap2/twl-common.c index de47f170ba5..db5ff664237 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -67,6 +67,7 @@ void __init omap_pmic_init(int bus, u32 clkrate,  			   const char *pmic_type, int pmic_irq,  			   struct twl4030_platform_data *pmic_data)  { +	omap_mux_init_signal("sys_nirq", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);  	strncpy(pmic_i2c_board_info.type, pmic_type,  		sizeof(pmic_i2c_board_info.type));  	pmic_i2c_board_info.irq = pmic_irq; diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 9148b229d0d..410291c6766 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -109,7 +109,8 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)  {  	orion_ge00_init(eth_data,  			ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, -			IRQ_ORION5X_ETH_ERR); +			IRQ_ORION5X_ETH_ERR, +			MV643XX_TX_CSUM_DEFAULT_LIMIT);  } diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h index 454831b6603..ee99fd56c04 100644 --- a/arch/arm/mach-s3c24xx/include/mach/dma.h +++ b/arch/arm/mach-s3c24xx/include/mach/dma.h @@ -24,7 +24,8 @@  */  enum dma_ch { -	DMACH_XD0, +	DMACH_DT_PROP = -1,	/* not yet supported, do not use */ +	DMACH_XD0 = 0,  	DMACH_XD1,  	DMACH_SDI,  	DMACH_SPI0, diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index cf10f92856d..453a6e50db8 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -520,13 +520,14 @@ static struct platform_device hdmi_lcdc_device = {  };  /* GPIO KEY */ -#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } +#define GPIO_KEY(c, g, d, ...) \ +	{ .code = c, .gpio = g, .desc = d, .active_low = 1, __VA_ARGS__ }  static struct gpio_keys_button gpio_buttons[] = { -	GPIO_KEY(KEY_POWER,	GPIO_PORT99,	"SW1"), -	GPIO_KEY(KEY_BACK,	GPIO_PORT100,	"SW2"), -	GPIO_KEY(KEY_MENU,	GPIO_PORT97,	"SW3"), -	GPIO_KEY(KEY_HOME,	GPIO_PORT98,	"SW4"), +	GPIO_KEY(KEY_POWER,	GPIO_PORT99,	"SW3", .wakeup = 1), +	GPIO_KEY(KEY_BACK,	GPIO_PORT100,	"SW4"), +	GPIO_KEY(KEY_MENU,	GPIO_PORT97,	"SW5"), +	GPIO_KEY(KEY_HOME,	GPIO_PORT98,	"SW6"),  };  static struct gpio_keys_platform_data gpio_key_info = { @@ -901,8 +902,8 @@ static struct platform_device *eva_devices[] __initdata = {  	&camera_device,  	&ceu0_device,  	&fsi_device, -	&fsi_hdmi_device,  	&fsi_wm8978_device, +	&fsi_hdmi_device,  };  static void __init eva_clock_init(void) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 7ea2b31e319..c129542f6ae 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -695,6 +695,7 @@ static struct platform_device usbhs0_device = {   *  - J30 "open"   *  - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET   *  - add .get_vbus = usbhs_get_vbus in usbhs1_private + *  - check usbhs0_device(pio)/usbhs1_device(irq) order in mackerel_devices.   */  #define IRQ8 evt2irq(0x0300)  #define USB_PHY_MODE		(1 << 4) @@ -1325,8 +1326,8 @@ static struct platform_device *mackerel_devices[] __initdata = {  	&nor_flash_device,  	&smc911x_device,  	&lcdc_device, -	&usbhs1_device,  	&usbhs0_device, +	&usbhs1_device,  	&leds_device,  	&fsi_device,  	&fsi_ak4643_device, diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 3a528cf4366..fcf5a47f477 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -67,7 +67,7 @@ static struct smsc911x_platform_config smsc911x_platdata = {  static struct platform_device eth_device = {  	.name		= "smsc911x", -	.id		= 0, +	.id		= -1,  	.dev  = {  		.platform_data = &smsc911x_platdata,  	}, diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index ee447404c85..588555a67d9 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -259,9 +259,9 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on)  	return 0; /* always allow wakeup */  } -#define RELOC_BASE 0x1000 +#define RELOC_BASE 0x1200 -/* INTCA IRQ pins at INTCS + 0x1000 to make space for GIC+INTC handling */ +/* INTCA IRQ pins at INTCS + RELOC_BASE to make space for GIC+INTC handling */  #define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE)  INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000, diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index c013bbf79ca..53d3d46dec1 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -41,7 +41,6 @@ config MACH_HREFV60  config MACH_SNOWBALL  	bool "U8500 Snowball platform"  	select MACH_MOP500 -	select LEDS_GPIO  	help  	  Include support for the snowball development platform. diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c index 99604803874..df15646036a 100644 --- a/arch/arm/mach-ux500/board-mop500-msp.c +++ b/arch/arm/mach-ux500/board-mop500-msp.c @@ -191,9 +191,9 @@ static struct platform_device *db8500_add_msp_i2s(struct device *parent,  	return pdev;  } -/* Platform device for ASoC U8500 machine */ -static struct platform_device snd_soc_u8500 = { -		.name = "snd-soc-u8500", +/* Platform device for ASoC MOP500 machine */ +static struct platform_device snd_soc_mop500 = { +		.name = "snd-soc-mop500",  		.id = 0,  		.dev = {  			.platform_data = NULL, @@ -227,8 +227,8 @@ int mop500_msp_init(struct device *parent)  {  	struct platform_device *msp1; -	pr_info("%s: Register platform-device 'snd-soc-u8500'.\n", __func__); -	platform_device_register(&snd_soc_u8500); +	pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__); +	platform_device_register(&snd_soc_mop500);  	pr_info("Initialize MSP I2S-devices.\n");  	db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 8674a890fd1..a534d8880de 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -797,6 +797,7 @@ static void __init u8500_init_machine(void)  				ARRAY_SIZE(mop500_platform_devs));  		mop500_sdi_init(parent); +		mop500_msp_init(parent);  		i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);  		i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);  		i2c_register_board_info(2, mop500_i2c2_devices, @@ -804,6 +805,8 @@ static void __init u8500_init_machine(void)  		mop500_uib_init(); +	} else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { +		mop500_msp_init(parent);  	} else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {  		/*  		 * The HREFv60 board removed a GPIO expander and routed @@ -815,6 +818,7 @@ static void __init u8500_init_machine(void)  				ARRAY_SIZE(mop500_platform_devs));  		hrefv60_sdi_init(parent); +		mop500_msp_init(parent);  		i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);  		i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; 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 4e7d1182e8a..e59c4ab71bc 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -267,17 +267,19 @@ static void __dma_free_remap(void *cpu_addr, size_t size)  	vunmap(cpu_addr);  } +#define DEFAULT_DMA_COHERENT_POOL_SIZE	SZ_256K +  struct dma_pool {  	size_t size;  	spinlock_t lock;  	unsigned long *bitmap;  	unsigned long nr_pages;  	void *vaddr; -	struct page *page; +	struct page **pages;  };  static struct dma_pool atomic_pool = { -	.size = SZ_256K, +	.size = DEFAULT_DMA_COHERENT_POOL_SIZE,  };  static int __init early_coherent_pool(char *p) @@ -287,6 +289,21 @@ static int __init early_coherent_pool(char *p)  }  early_param("coherent_pool", early_coherent_pool); +void __init init_dma_coherent_pool_size(unsigned long size) +{ +	/* +	 * Catch any attempt to set the pool size too late. +	 */ +	BUG_ON(atomic_pool.vaddr); + +	/* +	 * Set architecture specific coherent pool size only if +	 * it has not been changed by kernel command line parameter. +	 */ +	if (atomic_pool.size == DEFAULT_DMA_COHERENT_POOL_SIZE) +		atomic_pool.size = size; +} +  /*   * Initialise the coherent pool for atomic allocations.   */ @@ -297,6 +314,7 @@ static int __init atomic_pool_init(void)  	unsigned long nr_pages = pool->size >> PAGE_SHIFT;  	unsigned long *bitmap;  	struct page *page; +	struct page **pages;  	void *ptr;  	int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); @@ -304,21 +322,31 @@ static int __init atomic_pool_init(void)  	if (!bitmap)  		goto no_bitmap; +	pages = kzalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); +	if (!pages) +		goto no_pages; +  	if (IS_ENABLED(CONFIG_CMA))  		ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page);  	else  		ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,  					   &page, NULL);  	if (ptr) { +		int i; + +		for (i = 0; i < nr_pages; i++) +			pages[i] = page + i; +  		spin_lock_init(&pool->lock);  		pool->vaddr = ptr; -		pool->page = page; +		pool->pages = pages;  		pool->bitmap = bitmap;  		pool->nr_pages = nr_pages;  		pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n",  		       (unsigned)pool->size / 1024);  		return 0;  	} +no_pages:  	kfree(bitmap);  no_bitmap:  	pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", @@ -443,27 +471,45 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)  	if (pageno < pool->nr_pages) {  		bitmap_set(pool->bitmap, pageno, count);  		ptr = pool->vaddr + PAGE_SIZE * pageno; -		*ret_page = pool->page + pageno; +		*ret_page = pool->pages[pageno]; +	} else { +		pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" +			    "Please increase it with coherent_pool= kernel parameter!\n", +			    (unsigned)pool->size / 1024);  	}  	spin_unlock_irqrestore(&pool->lock, flags);  	return ptr;  } +static bool __in_atomic_pool(void *start, size_t size) +{ +	struct dma_pool *pool = &atomic_pool; +	void *end = start + size; +	void *pool_start = pool->vaddr; +	void *pool_end = pool->vaddr + pool->size; + +	if (start < pool_start || start >= pool_end) +		return false; + +	if (end <= pool_end) +		return true; + +	WARN(1, "Wrong coherent size(%p-%p) from atomic pool(%p-%p)\n", +	     start, end - 1, pool_start, pool_end - 1); + +	return false; +} +  static int __free_from_pool(void *start, size_t size)  {  	struct dma_pool *pool = &atomic_pool;  	unsigned long pageno, count;  	unsigned long flags; -	if (start < pool->vaddr || start > pool->vaddr + pool->size) +	if (!__in_atomic_pool(start, size))  		return 0; -	if (start + size > pool->vaddr + pool->size) { -		WARN(1, "freeing wrong coherent size from pool\n"); -		return 0; -	} -  	pageno = (start - pool->vaddr) >> PAGE_SHIFT;  	count = size >> PAGE_SHIFT; @@ -1090,10 +1136,22 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si  	return 0;  } +static struct page **__atomic_get_pages(void *addr) +{ +	struct dma_pool *pool = &atomic_pool; +	struct page **pages = pool->pages; +	int offs = (addr - pool->vaddr) >> PAGE_SHIFT; + +	return pages + offs; +} +  static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)  {  	struct vm_struct *area; +	if (__in_atomic_pool(cpu_addr, PAGE_SIZE)) +		return __atomic_get_pages(cpu_addr); +  	if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))  		return cpu_addr; @@ -1103,6 +1161,34 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)  	return NULL;  } +static void *__iommu_alloc_atomic(struct device *dev, size_t size, +				  dma_addr_t *handle) +{ +	struct page *page; +	void *addr; + +	addr = __alloc_from_pool(size, &page); +	if (!addr) +		return NULL; + +	*handle = __iommu_create_mapping(dev, &page, size); +	if (*handle == DMA_ERROR_CODE) +		goto err_mapping; + +	return addr; + +err_mapping: +	__free_from_pool(addr, size); +	return NULL; +} + +static void __iommu_free_atomic(struct device *dev, struct page **pages, +				dma_addr_t handle, size_t size) +{ +	__iommu_remove_mapping(dev, handle, size); +	__free_from_pool(page_address(pages[0]), size); +} +  static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,  	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)  { @@ -1113,6 +1199,9 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,  	*handle = DMA_ERROR_CODE;  	size = PAGE_ALIGN(size); +	if (gfp & GFP_ATOMIC) +		return __iommu_alloc_atomic(dev, size, handle); +  	pages = __iommu_alloc_buffer(dev, size, gfp);  	if (!pages)  		return NULL; @@ -1179,6 +1268,11 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,  		return;  	} +	if (__in_atomic_pool(cpu_addr, size)) { +		__iommu_free_atomic(dev, pages, handle, size); +		return; +	} +  	if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {  		unmap_kernel_range((unsigned long)cpu_addr, size);  		vunmap(cpu_addr); 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/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 626ad8cad7a..938b50a3343 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -189,6 +189,7 @@ struct omap_dm_timer *omap_dm_timer_request(void)  		timer->reserved = 1;  		break;  	} +	spin_unlock_irqrestore(&dm_timer_lock, flags);  	if (timer) {  		ret = omap_dm_timer_prepare(timer); @@ -197,7 +198,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)  			timer = NULL;  		}  	} -	spin_unlock_irqrestore(&dm_timer_lock, flags);  	if (!timer)  		pr_debug("%s: timer request failed!\n", __func__); @@ -220,6 +220,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)  			break;  		}  	} +	spin_unlock_irqrestore(&dm_timer_lock, flags);  	if (timer) {  		ret = omap_dm_timer_prepare(timer); @@ -228,7 +229,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)  			timer = NULL;  		}  	} -	spin_unlock_irqrestore(&dm_timer_lock, flags);  	if (!timer)  		pr_debug("%s: timer%d request failed!\n", __func__, id); @@ -258,7 +258,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_enable);  void omap_dm_timer_disable(struct omap_dm_timer *timer)  { -	pm_runtime_put(&timer->pdev->dev); +	pm_runtime_put_sync(&timer->pdev->dev);  }  EXPORT_SYMBOL_GPL(omap_dm_timer_disable); diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 68b180edcff..bb5d08a70db 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -372,7 +372,8 @@ IS_OMAP_TYPE(3430, 0x3430)  #define cpu_class_is_omap1()	(cpu_is_omap7xx() || cpu_is_omap15xx() || \  				cpu_is_omap16xx())  #define cpu_class_is_omap2()	(cpu_is_omap24xx() || cpu_is_omap34xx() || \ -				cpu_is_omap44xx() || soc_is_omap54xx()) +				cpu_is_omap44xx() || soc_is_omap54xx() || \ +				soc_is_am33xx())  /* Various silicon revisions for omap2 */  #define OMAP242X_CLASS		0x24200024 diff --git a/arch/arm/plat-omap/include/plat/multi.h b/arch/arm/plat-omap/include/plat/multi.h index 045e320f106..324d31b1485 100644 --- a/arch/arm/plat-omap/include/plat/multi.h +++ b/arch/arm/plat-omap/include/plat/multi.h @@ -108,4 +108,13 @@  # endif  #endif +#ifdef CONFIG_SOC_AM33XX +# ifdef OMAP_NAME +#  undef  MULTI_OMAP2 +#  define MULTI_OMAP2 +# else +#  define OMAP_NAME am33xx +# endif +#endif +  #endif	/* __PLAT_OMAP_MULTI_H */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index b8d19a13678..7f7b112accc 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -110,7 +110,7 @@ static inline void flush(void)  	_DEBUG_LL_ENTRY(mach, AM33XX_UART##p##_BASE, OMAP_PORT_SHIFT,	\  		AM33XXUART##p) -static inline void __arch_decomp_setup(unsigned long arch_id) +static inline void arch_decomp_setup(void)  {  	int port = 0; @@ -198,8 +198,6 @@ static inline void __arch_decomp_setup(unsigned long arch_id)  	} while (0);  } -#define arch_decomp_setup()	__arch_decomp_setup(arch_id) -  /*   * nothing to do   */ diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 766181cb5c9..024f3b08db2 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -68,6 +68,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; @@ -106,6 +107,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()) { @@ -113,6 +115,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 */  				} @@ -175,8 +178,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()) {  		/* @@ -203,8 +208,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);  }  /* @@ -218,7 +223,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/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index d245a87dc01..b8b747a9d36 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -291,10 +291,12 @@ static struct platform_device orion_ge00 = {  void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,  			    unsigned long mapbase,  			    unsigned long irq, -			    unsigned long irq_err) +			    unsigned long irq_err, +			    unsigned int tx_csum_limit)  {  	fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,  		       mapbase + 0x2000, SZ_16K - 1, irq_err); +	orion_ge00_shared_data.tx_csum_limit = tx_csum_limit;  	ge_complete(&orion_ge00_shared_data,  		    orion_ge00_resources, irq, &orion_ge00_shared,  		    eth_data, &orion_ge00); @@ -343,10 +345,12 @@ static struct platform_device orion_ge01 = {  void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,  			    unsigned long mapbase,  			    unsigned long irq, -			    unsigned long irq_err) +			    unsigned long irq_err, +			    unsigned int tx_csum_limit)  {  	fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,  		       mapbase + 0x2000, SZ_16K - 1, irq_err); +	orion_ge01_shared_data.tx_csum_limit = tx_csum_limit;  	ge_complete(&orion_ge01_shared_data,  		    orion_ge01_resources, irq, &orion_ge01_shared,  		    eth_data, &orion_ge01); diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index e00fdb21360..ae2377ef63e 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -39,12 +39,14 @@ void __init orion_rtc_init(unsigned long mapbase,  void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,  			    unsigned long mapbase,  			    unsigned long irq, -			    unsigned long irq_err); +			    unsigned long irq_err, +			    unsigned int tx_csum_limit);  void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,  			    unsigned long mapbase,  			    unsigned long irq, -			    unsigned long irq_err); +			    unsigned long irq_err, +			    unsigned int tx_csum_limit);  void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,  			    unsigned long mapbase, diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 28f898f7538..db98e7021f0 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -430,7 +430,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)   * when necessary.  */ -int s3c2410_dma_enqueue(unsigned int channel, void *id, +int s3c2410_dma_enqueue(enum dma_ch channel, void *id,  			dma_addr_t data, int size)  {  	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 74e31ce3553..fc49f3dabd7 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -32,6 +32,8 @@  #include <linux/platform_data/s3c-hsudc.h>  #include <linux/platform_data/s3c-hsotg.h> +#include <media/s5p_hdmi.h> +  #include <asm/irq.h>  #include <asm/pmu.h>  #include <asm/mach/arch.h> @@ -748,7 +750,8 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)  	if (!pd) {  		pd = &default_i2c_data; -		if (soc_is_exynos4210()) +		if (soc_is_exynos4210() || +		    soc_is_exynos4212() || soc_is_exynos4412())  			pd->bus_num = 8;  		else if (soc_is_s5pv210())  			pd->bus_num = 3; @@ -759,6 +762,30 @@ void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)  	npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),  			       &s5p_device_i2c_hdmiphy);  } + +struct s5p_hdmi_platform_data s5p_hdmi_def_platdata; + +void __init s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, +				  struct i2c_board_info *mhl_info, int mhl_bus) +{ +	struct s5p_hdmi_platform_data *pd = &s5p_hdmi_def_platdata; + +	if (soc_is_exynos4210() || +	    soc_is_exynos4212() || soc_is_exynos4412()) +		pd->hdmiphy_bus = 8; +	else if (soc_is_s5pv210()) +		pd->hdmiphy_bus = 3; +	else +		pd->hdmiphy_bus = 0; + +	pd->hdmiphy_info = hdmiphy_info; +	pd->mhl_info = mhl_info; +	pd->mhl_bus = mhl_bus; + +	s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platform_data), +			 &s5p_device_hdmi); +} +  #endif /* CONFIG_S5P_DEV_I2C_HDMIPHY */  /* I2S */ diff --git a/arch/arm/plat-samsung/include/plat/hdmi.h b/arch/arm/plat-samsung/include/plat/hdmi.h new file mode 100644 index 00000000000..331d046ac2c --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/hdmi.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2012 Samsung Electronics Co.Ltd + * + * This program is free software; you can redistribute  it and/or modify it + * under  the terms of  the GNU General  Public License as published by the + * Free Software Foundation;  either version 2 of the  License, or (at your + * option) any later version. + */ + +#ifndef __PLAT_SAMSUNG_HDMI_H +#define __PLAT_SAMSUNG_HDMI_H __FILE__ + +extern void s5p_hdmi_set_platdata(struct i2c_board_info *hdmiphy_info, +				  struct i2c_board_info *mhl_info, int mhl_bus); + +#endif /* __PLAT_SAMSUNG_HDMI_H */ diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 64ab65f0fdb..15070284343 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -74,7 +74,7 @@ unsigned char pm_uart_udivslot;  #ifdef CONFIG_SAMSUNG_PM_DEBUG -struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS]; +static struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];  static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)  { 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/mips/Kconfig b/arch/mips/Kconfig index 331d574df99..faf65286574 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -89,6 +89,7 @@ config ATH79  	select CEVT_R4K  	select CSRC_R4K  	select DMA_NONCOHERENT +	select HAVE_CLK  	select IRQ_CPU  	select MIPS_MACHINE  	select SYS_HAS_CPU_MIPS32_R2 diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 99969484c47..a124c251c0c 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -228,6 +228,8 @@ static int mtx1_pci_idsel(unsigned int devsel, int assert)  	 * adapter on the mtx-1 "singleboard" variant. It triggers a custom  	 * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.  	 */ +	udelay(1); +  	if (assert && devsel != 0)  		/* Suppress signal to Cardbus */  		alchemy_gpio_set_value(1, 0);	/* set EXT_IO3 OFF */ diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index 36e9570e7bc..b2a2311ec85 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void)  	ath79_ohci_resources[0].start = AR7240_OHCI_BASE;  	ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1; +	ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB; +	ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;  	platform_device_register(&ath79_ohci_device);  } diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index 29054f21183..48fe762d252 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c @@ -188,8 +188,10 @@ void __init ath79_gpio_init(void)  	if (soc_is_ar71xx())  		ath79_gpio_count = AR71XX_GPIO_COUNT; -	else if (soc_is_ar724x()) -		ath79_gpio_count = AR724X_GPIO_COUNT; +	else if (soc_is_ar7240()) +		ath79_gpio_count = AR7240_GPIO_COUNT; +	else if (soc_is_ar7241() || soc_is_ar7242()) +		ath79_gpio_count = AR7241_GPIO_COUNT;  	else if (soc_is_ar913x())  		ath79_gpio_count = AR913X_GPIO_COUNT;  	else if (soc_is_ar933x()) diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index e39f73048d4..f1c9c3e2f67 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c @@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void)  	if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {  		spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;  		spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; +		spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT; +		spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;  	}  	if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {  		spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;  		spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; +		spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; +		spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;  	}  	bcm63xx_spi_regs_init(); diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 7fb1f222b8a..274cd4fad30 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -61,6 +61,12 @@ static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,  	octeon_irq_ciu_to_irq[line][bit] = irq;  } +static void octeon_irq_force_ciu_mapping(struct irq_domain *domain, +					 int irq, int line, int bit) +{ +	irq_domain_associate(domain, irq, line << 6 | bit); +} +  static int octeon_coreid_for_cpu(int cpu)  {  #ifdef CONFIG_SMP @@ -183,19 +189,9 @@ static void __init octeon_irq_init_core(void)  		mutex_init(&cd->core_irq_mutex);  		irq = OCTEON_IRQ_SW0 + i; -		switch (irq) { -		case OCTEON_IRQ_TIMER: -		case OCTEON_IRQ_SW0: -		case OCTEON_IRQ_SW1: -		case OCTEON_IRQ_5: -		case OCTEON_IRQ_PERF: -			irq_set_chip_data(irq, cd); -			irq_set_chip_and_handler(irq, &octeon_irq_chip_core, -						 handle_percpu_irq); -			break; -		default: -			break; -		} +		irq_set_chip_data(irq, cd); +		irq_set_chip_and_handler(irq, &octeon_irq_chip_core, +					 handle_percpu_irq);  	}  } @@ -890,7 +886,6 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,  	unsigned int type;  	unsigned int pin;  	unsigned int trigger; -	struct octeon_irq_gpio_domain_data *gpiod;  	if (d->of_node != node)  		return -EINVAL; @@ -925,8 +920,7 @@ static int octeon_irq_gpio_xlat(struct irq_domain *d,  		break;  	}  	*out_type = type; -	gpiod = d->host_data; -	*out_hwirq = gpiod->base_hwirq + pin; +	*out_hwirq = pin;  	return 0;  } @@ -996,19 +990,21 @@ static int octeon_irq_ciu_map(struct irq_domain *d,  static int octeon_irq_gpio_map(struct irq_domain *d,  			       unsigned int virq, irq_hw_number_t hw)  { -	unsigned int line = hw >> 6; -	unsigned int bit = hw & 63; +	struct octeon_irq_gpio_domain_data *gpiod = d->host_data; +	unsigned int line, bit;  	if (!octeon_irq_virq_in_range(virq))  		return -EINVAL; +	hw += gpiod->base_hwirq; +	line = hw >> 6; +	bit = hw & 63;  	if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)  		return -EINVAL;  	octeon_irq_set_ciu_mapping(virq, line, bit,  				   octeon_irq_gpio_chip,  				   octeon_irq_handle_gpio); -  	return 0;  } @@ -1149,6 +1145,7 @@ static void __init octeon_irq_init_ciu(void)  	struct irq_chip *chip_wd;  	struct device_node *gpio_node;  	struct device_node *ciu_node; +	struct irq_domain *ciu_domain = NULL;  	octeon_irq_init_ciu_percpu();  	octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu; @@ -1177,31 +1174,6 @@ static void __init octeon_irq_init_ciu(void)  	/* Mips internal */  	octeon_irq_init_core(); -	/* CIU_0 */ -	for (i = 0; i < 16; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); - -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq); -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq); -	for (i = 0; i < 4; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq); -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq); - -	/* CIU_1 */ -	for (i = 0; i < 16; i++) -		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); - -	octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq); -  	gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");  	if (gpio_node) {  		struct octeon_irq_gpio_domain_data *gpiod; @@ -1219,10 +1191,35 @@ static void __init octeon_irq_init_ciu(void)  	ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");  	if (ciu_node) { -		irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL); +		ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);  		of_node_put(ciu_node);  	} else -		pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n"); +		panic("Cannot find device node for cavium,octeon-3860-ciu."); + +	/* CIU_0 */ +	for (i = 0; i < 16; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0); + +	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq); +	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq); + +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36); +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46); +	for (i = 0; i < 4; i++) +		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56); +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_BOOTDMA, 0, 63); + +	/* CIU_1 */ +	for (i = 0; i < 16; i++) +		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq); + +	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);  	/* Enable the CIU lines */  	set_c0_status(STATUSF_IP3 | STATUSF_IP2); diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 1caa78ad06d..dde504477fa 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -393,7 +393,8 @@  #define AR71XX_GPIO_REG_FUNC		0x28  #define AR71XX_GPIO_COUNT		16 -#define AR724X_GPIO_COUNT		18 +#define AR7240_GPIO_COUNT		18 +#define AR7241_GPIO_COUNT		20  #define AR913X_GPIO_COUNT		22  #define AR933X_GPIO_COUNT		30  #define AR934X_GPIO_COUNT		23 diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h index 4476fa03bf3..6ddae926bf7 100644 --- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h @@ -42,7 +42,6 @@  #define cpu_has_mips64r1	0  #define cpu_has_mips64r2	0 -#define cpu_has_dsp		0  #define cpu_has_mipsmt		0  #define cpu_has_64bits		0 diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 7d98dbe5d4b..c9bae136260 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h @@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void);  struct bcm63xx_spi_pdata {  	unsigned int	fifo_size; +	unsigned int	msg_type_shift; +	unsigned int	msg_ctl_width;  	int		bus_num;  	int		num_chipselect;  	u32		speed_hz; diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 4ccc2a748af..61f2a2a5099 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -1054,7 +1054,8 @@  #define SPI_6338_FILL_BYTE		0x07  #define SPI_6338_MSG_TAIL		0x09  #define SPI_6338_RX_TAIL		0x0b -#define SPI_6338_MSG_CTL		0x40 +#define SPI_6338_MSG_CTL		0x40	/* 8-bits register */ +#define SPI_6338_MSG_CTL_WIDTH		8  #define SPI_6338_MSG_DATA		0x41  #define SPI_6338_MSG_DATA_SIZE		0x3f  #define SPI_6338_RX_DATA		0x80 @@ -1070,7 +1071,8 @@  #define SPI_6348_FILL_BYTE		0x07  #define SPI_6348_MSG_TAIL		0x09  #define SPI_6348_RX_TAIL		0x0b -#define SPI_6348_MSG_CTL		0x40 +#define SPI_6348_MSG_CTL		0x40	/* 8-bits register */ +#define SPI_6348_MSG_CTL_WIDTH		8  #define SPI_6348_MSG_DATA		0x41  #define SPI_6348_MSG_DATA_SIZE		0x3f  #define SPI_6348_RX_DATA		0x80 @@ -1078,6 +1080,7 @@  /* BCM 6358 SPI core */  #define SPI_6358_MSG_CTL		0x00	/* 16-bits register */ +#define SPI_6358_MSG_CTL_WIDTH		16  #define SPI_6358_MSG_DATA		0x02  #define SPI_6358_MSG_DATA_SIZE		0x21e  #define SPI_6358_RX_DATA		0x400 @@ -1094,6 +1097,7 @@  /* BCM 6358 SPI core */  #define SPI_6368_MSG_CTL		0x00	/* 16-bits register */ +#define SPI_6368_MSG_CTL_WIDTH		16  #define SPI_6368_MSG_DATA		0x02  #define SPI_6368_MSG_DATA_SIZE		0x21e  #define SPI_6368_RX_DATA		0x400 @@ -1115,7 +1119,10 @@  #define SPI_HD_W			0x01  #define SPI_HD_R			0x02  #define SPI_BYTE_CNT_SHIFT		0 -#define SPI_MSG_TYPE_SHIFT		14 +#define SPI_6338_MSG_TYPE_SHIFT		6 +#define SPI_6348_MSG_TYPE_SHIFT		6 +#define SPI_6358_MSG_TYPE_SHIFT		14 +#define SPI_6368_MSG_TYPE_SHIFT		14  /* Command */  #define SPI_CMD_NOOP			0x00 diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h index 418992042f6..c22a3078bf1 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/irq.h +++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h @@ -21,14 +21,10 @@ enum octeon_irq {  	OCTEON_IRQ_TIMER,  /* sources in CIU_INTX_EN0 */  	OCTEON_IRQ_WORKQ0, -	OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16, -	OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16, +	OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16,  	OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,  	OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,  	OCTEON_IRQ_MBOX1, -	OCTEON_IRQ_UART0, -	OCTEON_IRQ_UART1, -	OCTEON_IRQ_UART2,  	OCTEON_IRQ_PCI_INT0,  	OCTEON_IRQ_PCI_INT1,  	OCTEON_IRQ_PCI_INT2, @@ -38,8 +34,6 @@ enum octeon_irq {  	OCTEON_IRQ_PCI_MSI2,  	OCTEON_IRQ_PCI_MSI3, -	OCTEON_IRQ_TWSI, -	OCTEON_IRQ_TWSI2,  	OCTEON_IRQ_RML,  	OCTEON_IRQ_TIMER0,  	OCTEON_IRQ_TIMER1, @@ -47,8 +41,6 @@ enum octeon_irq {  	OCTEON_IRQ_TIMER3,  	OCTEON_IRQ_USB0,  	OCTEON_IRQ_USB1, -	OCTEON_IRQ_MII0, -	OCTEON_IRQ_MII1,  	OCTEON_IRQ_BOOTDMA,  #ifndef CONFIG_PCI_MSI  	OCTEON_IRQ_LAST = 127 diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 7531ecd654d..dca8bce8c7a 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -10,6 +10,7 @@ struct mod_arch_specific {  	struct list_head dbe_list;  	const struct exception_table_entry *dbe_start;  	const struct exception_table_entry *dbe_end; +	struct mips_hi16 *r_mips_hi16_list;  };  typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */ diff --git a/arch/mips/include/asm/r4k-timer.h b/arch/mips/include/asm/r4k-timer.h index a37d12b3b61..afe9e0e03fe 100644 --- a/arch/mips/include/asm/r4k-timer.h +++ b/arch/mips/include/asm/r4k-timer.h @@ -12,16 +12,16 @@  #ifdef CONFIG_SYNC_R4K -extern void synchronise_count_master(void); -extern void synchronise_count_slave(void); +extern void synchronise_count_master(int cpu); +extern void synchronise_count_slave(int cpu);  #else -static inline void synchronise_count_master(void) +static inline void synchronise_count_master(int cpu)  {  } -static inline void synchronise_count_slave(void) +static inline void synchronise_count_slave(int cpu)  {  } diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index a5066b1c3de..4f8c3cba8c0 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -39,8 +39,6 @@ struct mips_hi16 {  	Elf_Addr value;  }; -static struct mips_hi16 *mips_hi16_list; -  static LIST_HEAD(dbe_list);  static DEFINE_SPINLOCK(dbe_lock); @@ -128,8 +126,8 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)  	n->addr = (Elf_Addr *)location;  	n->value = v; -	n->next = mips_hi16_list; -	mips_hi16_list = n; +	n->next = me->arch.r_mips_hi16_list; +	me->arch.r_mips_hi16_list = n;  	return 0;  } @@ -142,18 +140,28 @@ static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)  	return 0;  } +static void free_relocation_chain(struct mips_hi16 *l) +{ +	struct mips_hi16 *next; + +	while (l) { +		next = l->next; +		kfree(l); +		l = next; +	} +} +  static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)  {  	unsigned long insnlo = *location; +	struct mips_hi16 *l;  	Elf_Addr val, vallo;  	/* Sign extend the addend we extract from the lo insn.  */  	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; -	if (mips_hi16_list != NULL) { -		struct mips_hi16 *l; - -		l = mips_hi16_list; +	if (me->arch.r_mips_hi16_list != NULL) { +		l = me->arch.r_mips_hi16_list;  		while (l != NULL) {  			struct mips_hi16 *next;  			unsigned long insn; @@ -188,7 +196,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)  			l = next;  		} -		mips_hi16_list = NULL; +		me->arch.r_mips_hi16_list = NULL;  	}  	/* @@ -201,6 +209,9 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)  	return 0;  out_danger: +	free_relocation_chain(l); +	me->arch.r_mips_hi16_list = NULL; +  	pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name);  	return -ENOEXEC; @@ -273,6 +284,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,  	pr_debug("Applying relocate section %u to %u\n", relsec,  	       sechdrs[relsec].sh_info); +	me->arch.r_mips_hi16_list = NULL;  	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {  		/* This is where to make the change */  		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr @@ -296,6 +308,19 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,  			return res;  	} +	/* +	 * Normally the hi16 list should be deallocated at this point.  A +	 * malformed binary however could contain a series of R_MIPS_HI16 +	 * relocations not followed by a R_MIPS_LO16 relocation.  In that +	 * case, free up the list and return an error. +	 */ +	if (me->arch.r_mips_hi16_list) { +		free_relocation_chain(me->arch.r_mips_hi16_list); +		me->arch.r_mips_hi16_list = NULL; + +		return -ENOEXEC; +	} +  	return 0;  } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 31637d8c873..9005bf9fb85 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -130,7 +130,7 @@ asmlinkage __cpuinit void start_secondary(void)  	cpu_set(cpu, cpu_callin_map); -	synchronise_count_slave(); +	synchronise_count_slave(cpu);  	/*  	 * irq will be enabled in ->smp_finish(), enabling it too early @@ -173,7 +173,6 @@ void smp_send_stop(void)  void __init smp_cpus_done(unsigned int max_cpus)  {  	mp_ops->cpus_done(); -	synchronise_count_master();  }  /* called from main before smp_init() */ @@ -206,6 +205,7 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)  	while (!cpu_isset(cpu, cpu_callin_map))  		udelay(100); +	synchronise_count_master(cpu);  	return 0;  } diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 842d55e411f..7f1eca3858d 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c @@ -28,12 +28,11 @@ static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);  #define COUNTON	100  #define NR_LOOPS 5 -void __cpuinit synchronise_count_master(void) +void __cpuinit synchronise_count_master(int cpu)  {  	int i;  	unsigned long flags;  	unsigned int initcount; -	int nslaves;  #ifdef CONFIG_MIPS_MT_SMTC  	/* @@ -43,8 +42,7 @@ void __cpuinit synchronise_count_master(void)  	return;  #endif -	printk(KERN_INFO "Synchronize counters across %u CPUs: ", -	       num_online_cpus()); +	printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);  	local_irq_save(flags); @@ -52,7 +50,7 @@ void __cpuinit synchronise_count_master(void)  	 * Notify the slaves that it's time to start  	 */  	atomic_set(&count_reference, read_c0_count()); -	atomic_set(&count_start_flag, 1); +	atomic_set(&count_start_flag, cpu);  	smp_wmb();  	/* Count will be initialised to current timer for all CPU's */ @@ -69,10 +67,9 @@ void __cpuinit synchronise_count_master(void)  	 * two CPUs.  	 */ -	nslaves = num_online_cpus()-1;  	for (i = 0; i < NR_LOOPS; i++) { -		/* slaves loop on '!= ncpus' */ -		while (atomic_read(&count_count_start) != nslaves) +		/* slaves loop on '!= 2' */ +		while (atomic_read(&count_count_start) != 1)  			mb();  		atomic_set(&count_count_stop, 0);  		smp_wmb(); @@ -89,7 +86,7 @@ void __cpuinit synchronise_count_master(void)  		/*  		 * Wait for all slaves to leave the synchronization point:  		 */ -		while (atomic_read(&count_count_stop) != nslaves) +		while (atomic_read(&count_count_stop) != 1)  			mb();  		atomic_set(&count_count_start, 0);  		smp_wmb(); @@ -97,6 +94,7 @@ void __cpuinit synchronise_count_master(void)  	}  	/* Arrange for an interrupt in a short while */  	write_c0_compare(read_c0_count() + COUNTON); +	atomic_set(&count_start_flag, 0);  	local_irq_restore(flags); @@ -108,11 +106,10 @@ void __cpuinit synchronise_count_master(void)  	printk("done.\n");  } -void __cpuinit synchronise_count_slave(void) +void __cpuinit synchronise_count_slave(int cpu)  {  	int i;  	unsigned int initcount; -	int ncpus;  #ifdef CONFIG_MIPS_MT_SMTC  	/* @@ -127,16 +124,15 @@ void __cpuinit synchronise_count_slave(void)  	 * so we first wait for the master to say everyone is ready  	 */ -	while (!atomic_read(&count_start_flag)) +	while (atomic_read(&count_start_flag) != cpu)  		mb();  	/* Count will be initialised to next expire for all CPU's */  	initcount = atomic_read(&count_reference); -	ncpus = num_online_cpus();  	for (i = 0; i < NR_LOOPS; i++) {  		atomic_inc(&count_count_start); -		while (atomic_read(&count_count_start) != ncpus) +		while (atomic_read(&count_count_start) != 2)  			mb();  		/* @@ -146,7 +142,7 @@ void __cpuinit synchronise_count_slave(void)  			write_c0_count(initcount);  		atomic_inc(&count_count_stop); -		while (atomic_read(&count_count_stop) != ncpus) +		while (atomic_read(&count_count_stop) != 2)  			mb();  	}  	/* Arrange for an interrupt in a short while */ diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index 284dea54faf..2147cb34e70 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c @@ -252,16 +252,3 @@ void __init mips_pcibios_init(void)  	register_pci_controller(controller);  } - -/* Enable PCI 2.1 compatibility in PIIX4 */ -static void __devinit quirk_dlcsetup(struct pci_dev *dev) -{ -	u8 odlc, ndlc; -	(void) pci_read_config_byte(dev, 0x82, &odlc); -	/* Enable passive releases and delayed transaction */ -	ndlc = odlc | 7; -	(void) pci_write_config_byte(dev, 0x82, ndlc); -} - -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, -	quirk_dlcsetup); diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 414a7459858..86d77a66645 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -23,9 +23,12 @@  #define AR724X_PCI_MEM_BASE	0x10000000  #define AR724X_PCI_MEM_SIZE	0x08000000 +#define AR724X_PCI_REG_RESET		0x18  #define AR724X_PCI_REG_INT_STATUS	0x4c  #define AR724X_PCI_REG_INT_MASK		0x50 +#define AR724X_PCI_RESET_LINK_UP	BIT(0) +  #define AR724X_PCI_INT_DEV0		BIT(14)  #define AR724X_PCI_IRQ_COUNT		1 @@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_base;  static u32 ar724x_pci_bar0_value;  static bool ar724x_pci_bar0_is_cached; +static bool ar724x_pci_link_up; + +static inline bool ar724x_pci_check_link(void) +{ +	u32 reset; + +	reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); +	return reset & AR724X_PCI_RESET_LINK_UP; +}  static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,  			    int size, uint32_t *value) @@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,  	void __iomem *base;  	u32 data; +	if (!ar724x_pci_link_up) +		return PCIBIOS_DEVICE_NOT_FOUND; +  	if (devfn)  		return PCIBIOS_DEVICE_NOT_FOUND; @@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,  	u32 data;  	int s; +	if (!ar724x_pci_link_up) +		return PCIBIOS_DEVICE_NOT_FOUND; +  	if (devfn)  		return PCIBIOS_DEVICE_NOT_FOUND; @@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq)  	if (ar724x_pci_ctrl_base == NULL)  		goto err_unmap_devcfg; +	ar724x_pci_link_up = ar724x_pci_check_link(); +	if (!ar724x_pci_link_up) +		pr_warn("ar724x: PCIe link is down\n"); +  	ar724x_pci_irq_init(irq);  	register_pci_controller(&ar724x_pci_controller); diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 6c6defc2461..af9cf30ed47 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -141,7 +141,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)  #define atomic_sub_and_test(i,v)	(atomic_sub_return((i),(v)) == 0) -#define ATOMIC_INIT(i)	((atomic_t) { (i) }) +#define ATOMIC_INIT(i)	{ (i) }  #define smp_mb__before_atomic_dec()	smp_mb()  #define smp_mb__after_atomic_dec()	smp_mb() @@ -150,7 +150,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)  #ifdef CONFIG_64BIT -#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) +#define ATOMIC64_INIT(i) { (i) }  static __inline__ s64  __atomic64_add_return(s64 i, atomic64_t *v) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index d4b94b395c1..2c05a9292a8 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -309,7 +309,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,  		cregs->ksp = (unsigned long)stack  			+ (pregs->gr[21] & (THREAD_SIZE - 1));  		cregs->gr[30] = usp; -		if (p->personality == PER_HPUX) { +		if (personality(p->personality) == PER_HPUX) {  #ifdef CONFIG_HPUX  			cregs->kpc = (unsigned long) &hpux_child_return;  #else diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index c9b932260f4..7426e40699b 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -225,12 +225,12 @@ long parisc_personality(unsigned long personality)  	long err;  	if (personality(current->personality) == PER_LINUX32 -	    && personality == PER_LINUX) -		personality = PER_LINUX32; +	    && personality(personality) == PER_LINUX) +		personality = (personality & ~PER_MASK) | PER_LINUX32;  	err = sys_personality(personality); -	if (err == PER_LINUX32) -		err = PER_LINUX; +	if (personality(err) == PER_LINUX32) +		err = (err & ~PER_MASK) | PER_LINUX;  	return err;  } diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi index 8d35d2c1f69..4f9c9f682ec 100644 --- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi @@ -345,6 +345,13 @@  /include/ "qoriq-duart-1.dtsi"  /include/ "qoriq-gpio-0.dtsi"  /include/ "qoriq-usb2-mph-0.dtsi" +	usb@210000 { +		compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; +		port0; +	};  /include/ "qoriq-usb2-dr-0.dtsi" +	usb@211000 { +		compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; +	};  /include/ "qoriq-sec4.0-0.dtsi"  }; diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig index f4337bacd0e..26e541c4662 100644 --- a/arch/powerpc/configs/85xx/p1023rds_defconfig +++ b/arch/powerpc/configs/85xx/p1023rds_defconfig @@ -6,28 +6,27 @@ CONFIG_SYSVIPC=y  CONFIG_POSIX_MQUEUE=y  CONFIG_BSD_PROCESS_ACCT=y  CONFIG_AUDIT=y -CONFIG_SPARSE_IRQ=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y  CONFIG_IKCONFIG=y  CONFIG_IKCONFIG_PROC=y  CONFIG_LOG_BUF_SHIFT=14  CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set  CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y  CONFIG_EMBEDDED=y  CONFIG_MODULES=y  CONFIG_MODULE_UNLOAD=y  CONFIG_MODULE_FORCE_UNLOAD=y  CONFIG_MODVERSIONS=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y  CONFIG_P1023_RDS=y  CONFIG_QUICC_ENGINE=y  CONFIG_QE_GPIO=y  CONFIG_CPM2=y -CONFIG_GPIO_MPC8XXX=y  CONFIG_HIGHMEM=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y  # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set  CONFIG_BINFMT_MISC=m  CONFIG_MATH_EMULATION=y @@ -63,11 +62,11 @@ CONFIG_INET_ESP=y  CONFIG_IPV6=y  CONFIG_IP_SCTP=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  CONFIG_PROC_DEVICETREE=y  CONFIG_BLK_DEV_LOOP=y  CONFIG_BLK_DEV_RAM=y  CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_MISC_DEVICES=y  CONFIG_EEPROM_LEGACY=y  CONFIG_BLK_DEV_SD=y  CONFIG_CHR_DEV_ST=y @@ -80,15 +79,14 @@ CONFIG_SATA_FSL=y  CONFIG_SATA_SIL24=y  CONFIG_NETDEVICES=y  CONFIG_DUMMY=y +CONFIG_FS_ENET=y +CONFIG_FSL_PQ_MDIO=y +CONFIG_E1000E=y  CONFIG_MARVELL_PHY=y  CONFIG_DAVICOM_PHY=y  CONFIG_CICADA_PHY=y  CONFIG_VITESSE_PHY=y  CONFIG_FIXED_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_FS_ENET=y -CONFIG_E1000E=y -CONFIG_FSL_PQ_MDIO=y  CONFIG_INPUT_FF_MEMLESS=m  # CONFIG_INPUT_MOUSEDEV is not set  # CONFIG_INPUT_KEYBOARD is not set @@ -98,16 +96,15 @@ CONFIG_SERIAL_8250=y  CONFIG_SERIAL_8250_CONSOLE=y  CONFIG_SERIAL_8250_NR_UARTS=2  CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y  CONFIG_SERIAL_8250_MANY_PORTS=y  CONFIG_SERIAL_8250_DETECT_IRQ=y  CONFIG_SERIAL_8250_RSA=y  CONFIG_SERIAL_QE=m -CONFIG_HW_RANDOM=y  CONFIG_NVRAM=y  CONFIG_I2C=y  CONFIG_I2C_CPM=m  CONFIG_I2C_MPC=y +CONFIG_GPIO_MPC8XXX=y  # CONFIG_HWMON is not set  CONFIG_VIDEO_OUTPUT_CONTROL=y  CONFIG_SOUND=y @@ -123,7 +120,6 @@ CONFIG_DMADEVICES=y  CONFIG_FSL_DMA=y  # CONFIG_NET_DMA is not set  CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set  CONFIG_EXT2_FS=y  CONFIG_EXT3_FS=y  # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -150,22 +146,15 @@ CONFIG_QNX4FS_FS=m  CONFIG_SYSV_FS=m  CONFIG_UFS_FS=m  CONFIG_NFS_FS=y -CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  CONFIG_ROOT_NFS=y  CONFIG_NFSD=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y  CONFIG_CRC_T10DIF=y  CONFIG_FRAME_WARN=8092  CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y  CONFIG_DETECT_HUNG_TASK=y  # CONFIG_DEBUG_BUGVERBOSE is not set  CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_IRQ_DOMAIN_DEBUG=y  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_SHA256=y  CONFIG_CRYPTO_SHA512=y diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig index cbb98c1234f..8b3d57c1ebe 100644 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ b/arch/powerpc/configs/corenet32_smp_defconfig @@ -6,8 +6,8 @@ CONFIG_SYSVIPC=y  CONFIG_POSIX_MQUEUE=y  CONFIG_BSD_PROCESS_ACCT=y  CONFIG_AUDIT=y -CONFIG_SPARSE_IRQ=y -CONFIG_RCU_TRACE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y  CONFIG_IKCONFIG=y  CONFIG_IKCONFIG_PROC=y  CONFIG_LOG_BUF_SHIFT=14 @@ -21,23 +21,22 @@ CONFIG_MODULE_UNLOAD=y  CONFIG_MODULE_FORCE_UNLOAD=y  CONFIG_MODVERSIONS=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y  CONFIG_P2041_RDB=y  CONFIG_P3041_DS=y  CONFIG_P4080_DS=y  CONFIG_P5020_DS=y  CONFIG_HIGHMEM=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y  # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set  CONFIG_BINFMT_MISC=m  CONFIG_KEXEC=y  CONFIG_IRQ_ALL_CPUS=y  CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_FSL_LBC=y  CONFIG_PCI=y  CONFIG_PCIEPORTBUS=y -CONFIG_PCI_MSI=y  # CONFIG_PCIEASPM is not set +CONFIG_PCI_MSI=y  CONFIG_RAPIDIO=y  CONFIG_FSL_RIO=y  CONFIG_NET=y @@ -70,6 +69,7 @@ CONFIG_INET_IPCOMP=y  CONFIG_IPV6=y  CONFIG_IP_SCTP=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  CONFIG_MTD=y  CONFIG_MTD_CMDLINE_PARTS=y  CONFIG_MTD_CHAR=y @@ -77,17 +77,14 @@ CONFIG_MTD_BLOCK=y  CONFIG_MTD_CFI=y  CONFIG_MTD_CFI_AMDSTD=y  CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_M25P80=y  CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_FSL_IFC=y  CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_M25P80=y +CONFIG_MTD_NAND_FSL_IFC=y  CONFIG_PROC_DEVICETREE=y  CONFIG_BLK_DEV_LOOP=y  CONFIG_BLK_DEV_RAM=y  CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_MISC_DEVICES=y  CONFIG_BLK_DEV_SD=y  CONFIG_CHR_DEV_ST=y  CONFIG_BLK_DEV_SR=y @@ -115,11 +112,9 @@ CONFIG_SERIO_LIBPS2=y  CONFIG_PPC_EPAPR_HV_BYTECHAN=y  CONFIG_SERIAL_8250=y  CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_EXTENDED=y  CONFIG_SERIAL_8250_MANY_PORTS=y  CONFIG_SERIAL_8250_DETECT_IRQ=y  CONFIG_SERIAL_8250_RSA=y -CONFIG_HW_RANDOM=y  CONFIG_NVRAM=y  CONFIG_I2C=y  CONFIG_I2C_CHARDEV=y @@ -132,7 +127,6 @@ CONFIG_SPI_FSL_ESPI=y  CONFIG_VIDEO_OUTPUT_CONTROL=y  CONFIG_USB_HID=m  CONFIG_USB=y -CONFIG_USB_DEVICEFS=y  CONFIG_USB_MON=y  CONFIG_USB_EHCI_HCD=y  CONFIG_USB_EHCI_FSL=y @@ -142,8 +136,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_LE=y  CONFIG_USB_STORAGE=y  CONFIG_MMC=y  CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_OF=y -CONFIG_MMC_SDHCI_OF_ESDHC=y  CONFIG_EDAC=y  CONFIG_EDAC_MM_EDAC=y  CONFIG_EDAC_MPC85XX=y @@ -170,19 +162,16 @@ CONFIG_HUGETLBFS=y  CONFIG_JFFS2_FS=y  CONFIG_CRAMFS=y  CONFIG_NFS_FS=y -CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  CONFIG_ROOT_NFS=y  CONFIG_NFSD=m -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y  CONFIG_NLS_ISO8859_1=y  CONFIG_NLS_UTF8=m  CONFIG_MAGIC_SYSRQ=y  CONFIG_DEBUG_SHIRQ=y  CONFIG_DETECT_HUNG_TASK=y  CONFIG_DEBUG_INFO=y -CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_RCU_TRACE=y  CONFIG_CRYPTO_NULL=y  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_MD4=y diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index dd89de8b0b7..0516e22ca3d 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig @@ -56,6 +56,7 @@ CONFIG_INET_ESP=y  CONFIG_IPV6=y  CONFIG_IP_SCTP=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  CONFIG_MTD=y  CONFIG_MTD_CMDLINE_PARTS=y  CONFIG_MTD_CHAR=y diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 15130066e5e..07b7f2af2dc 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -1,8 +1,10 @@ +CONFIG_PPC64=y +CONFIG_ALTIVEC=y +CONFIG_SMP=y +CONFIG_NR_CPUS=4  CONFIG_EXPERIMENTAL=y  CONFIG_SYSVIPC=y  CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y  CONFIG_IKCONFIG=y  CONFIG_IKCONFIG_PROC=y  CONFIG_BLK_DEV_INITRD=y @@ -13,15 +15,16 @@ CONFIG_MODULES=y  CONFIG_MODULE_UNLOAD=y  CONFIG_MODVERSIONS=y  CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -CONFIG_SMP=y -CONFIG_NR_CPUS=4 -CONFIG_KEXEC=y -# CONFIG_RELOCATABLE is not set +# CONFIG_PPC_PSERIES is not set  CONFIG_CPU_FREQ=y  CONFIG_CPU_FREQ_GOV_POWERSAVE=y  CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_PMAC64=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_KEXEC=y +CONFIG_IRQ_ALL_CPUS=y +# CONFIG_MIGRATION is not set  CONFIG_PCI_MSI=y  CONFIG_NET=y  CONFIG_PACKET=y @@ -49,6 +52,7 @@ CONFIG_NF_CT_NETLINK=m  CONFIG_NF_CONNTRACK_IPV4=m  CONFIG_IP_NF_QUEUE=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_PROC_DEVICETREE=y  CONFIG_BLK_DEV_LOOP=y  CONFIG_BLK_DEV_NBD=m  CONFIG_BLK_DEV_RAM=y @@ -56,6 +60,8 @@ CONFIG_BLK_DEV_RAM_SIZE=65536  CONFIG_CDROM_PKTCDVD=m  CONFIG_IDE=y  CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y  CONFIG_BLK_DEV_SD=y  CONFIG_CHR_DEV_ST=y  CONFIG_BLK_DEV_SR=y @@ -79,24 +85,33 @@ CONFIG_DM_CRYPT=m  CONFIG_DM_SNAPSHOT=m  CONFIG_DM_MIRROR=m  CONFIG_DM_ZERO=m -CONFIG_MACINTOSH_DRIVERS=y +CONFIG_IEEE1394=y +CONFIG_IEEE1394_OHCI1394=y +CONFIG_IEEE1394_SBP2=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_RAWIO=y +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_ADB_PMU=y +CONFIG_PMAC_SMU=y  CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_THERM_PM72=y +CONFIG_WINDFARM=y +CONFIG_WINDFARM_PM81=y +CONFIG_WINDFARM_PM91=y +CONFIG_WINDFARM_PM112=y +CONFIG_WINDFARM_PM121=y  CONFIG_NETDEVICES=y -CONFIG_BONDING=m  CONFIG_DUMMY=m -CONFIG_MII=y +CONFIG_BONDING=m  CONFIG_TUN=m +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SUNGEM=y  CONFIG_ACENIC=m  CONFIG_ACENIC_OMIT_TIGON_I=y -CONFIG_TIGON3=y  CONFIG_E1000=y -CONFIG_SUNGEM=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m +CONFIG_TIGON3=y  CONFIG_USB_CATC=m  CONFIG_USB_KAWETH=m  CONFIG_USB_PEGASUS=m @@ -106,24 +121,36 @@ CONFIG_USB_USBNET=m  # CONFIG_USB_NET_NET1080 is not set  # CONFIG_USB_NET_CDC_SUBSET is not set  # CONFIG_USB_NET_ZAURUS is not set +CONFIG_PPP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m  # CONFIG_INPUT_MOUSEDEV_PSAUX is not set  CONFIG_INPUT_JOYDEV=m  CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set  # CONFIG_MOUSE_PS2 is not set +# CONFIG_SERIO_I8042 is not set  # CONFIG_SERIO_SERPORT is not set -CONFIG_VT_HW_CONSOLE_BINDING=y  # CONFIG_HW_RANDOM is not set  CONFIG_GEN_RTC=y  CONFIG_RAW_DRIVER=y  CONFIG_I2C_CHARDEV=y  # CONFIG_HWMON is not set -CONFIG_AGP=y -CONFIG_DRM=y -CONFIG_DRM_NOUVEAU=y +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m  CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y  CONFIG_FIRMWARE_EDID=y  CONFIG_FB_TILEBLITTING=y +CONFIG_FB_OF=y +CONFIG_FB_NVIDIA=y +CONFIG_FB_NVIDIA_I2C=y  CONFIG_FB_RADEON=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_FRAMEBUFFER_CONSOLE=y  CONFIG_LOGO=y  CONFIG_SOUND=m  CONFIG_SND=m @@ -131,7 +158,15 @@ CONFIG_SND_SEQUENCER=m  CONFIG_SND_MIXER_OSS=m  CONFIG_SND_PCM_OSS=m  CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_POWERMAC=m +CONFIG_SND_AOA=m +CONFIG_SND_AOA_FABRIC_LAYOUT=m +CONFIG_SND_AOA_ONYX=m +CONFIG_SND_AOA_TAS=m +CONFIG_SND_AOA_TOONIE=m  CONFIG_SND_USB_AUDIO=m +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y  CONFIG_HID_GYRATION=y  CONFIG_LOGITECH_FF=y  CONFIG_HID_PANTHERLORD=y @@ -139,12 +174,13 @@ CONFIG_HID_PETALYNX=y  CONFIG_HID_SAMSUNG=y  CONFIG_HID_SONY=y  CONFIG_HID_SUNPLUS=y -CONFIG_HID_PID=y -CONFIG_USB_HIDDEV=y  CONFIG_USB=y +CONFIG_USB_DEVICEFS=y  CONFIG_USB_MON=y  CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_HCD_PPC_OF is not set  CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y  CONFIG_USB_ACM=m  CONFIG_USB_PRINTER=y  CONFIG_USB_STORAGE=y @@ -208,6 +244,8 @@ CONFIG_REISERFS_FS_POSIX_ACL=y  CONFIG_REISERFS_FS_SECURITY=y  CONFIG_XFS_FS=m  CONFIG_XFS_POSIX_ACL=y +CONFIG_INOTIFY=y +CONFIG_AUTOFS_FS=m  CONFIG_ISO9660_FS=y  CONFIG_JOLIET=y  CONFIG_ZISOFS=y @@ -221,12 +259,14 @@ CONFIG_HFS_FS=m  CONFIG_HFSPLUS_FS=m  CONFIG_CRAMFS=y  CONFIG_NFS_FS=y +CONFIG_NFS_V3=y  CONFIG_NFS_V3_ACL=y  CONFIG_NFS_V4=y  CONFIG_NFSD=y  CONFIG_NFSD_V3_ACL=y  CONFIG_NFSD_V4=y  CONFIG_CIFS=m +CONFIG_PARTITION_ADVANCED=y  CONFIG_NLS_CODEPAGE_437=y  CONFIG_NLS_CODEPAGE_1250=y  CONFIG_NLS_CODEPAGE_1251=y @@ -234,23 +274,29 @@ CONFIG_NLS_ASCII=y  CONFIG_NLS_ISO8859_1=y  CONFIG_NLS_ISO8859_15=y  CONFIG_NLS_UTF8=y +CONFIG_CRC_T10DIF=y +CONFIG_LIBCRC32C=m  CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set  CONFIG_DEBUG_FS=y  CONFIG_DEBUG_KERNEL=y  CONFIG_DEBUG_MUTEXES=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set  CONFIG_LATENCYTOP=y -CONFIG_STRICT_DEVMEM=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_BOOTX_TEXT=y  CONFIG_CRYPTO_NULL=m  CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_ECB=m  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MD4=m  CONFIG_CRYPTO_MICHAEL_MIC=m  CONFIG_CRYPTO_SHA256=m  CONFIG_CRYPTO_SHA512=m  CONFIG_CRYPTO_WP512=m  CONFIG_CRYPTO_AES=m  CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m  CONFIG_CRYPTO_BLOWFISH=m  CONFIG_CRYPTO_CAST5=m  CONFIG_CRYPTO_CAST6=m @@ -260,6 +306,3 @@ CONFIG_CRYPTO_TEA=m  CONFIG_CRYPTO_TWOFISH=m  # CONFIG_CRYPTO_ANSI_CPRNG is not set  # CONFIG_CRYPTO_HW is not set -# CONFIG_VIRTUALIZATION is not set -CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=m diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index 5aac9a8bc53..9352e4430c3 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig @@ -2,12 +2,12 @@ CONFIG_EXPERIMENTAL=y  CONFIG_SYSVIPC=y  CONFIG_LOG_BUF_SHIFT=14  CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set  CONFIG_EXPERT=y  CONFIG_SLAB=y  CONFIG_MODULES=y  CONFIG_MODULE_UNLOAD=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y  # CONFIG_PPC_CHRP is not set  # CONFIG_PPC_PMAC is not set  CONFIG_PPC_83xx=y @@ -25,7 +25,6 @@ CONFIG_ASP834x=y  CONFIG_QUICC_ENGINE=y  CONFIG_QE_GPIO=y  CONFIG_MATH_EMULATION=y -CONFIG_SPARSE_IRQ=y  CONFIG_PCI=y  CONFIG_NET=y  CONFIG_PACKET=y @@ -42,10 +41,9 @@ CONFIG_INET_ESP=y  # CONFIG_INET_LRO is not set  # CONFIG_IPV6 is not set  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  # CONFIG_FW_LOADER is not set  CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_OF_PARTS=y  CONFIG_MTD_CHAR=y  CONFIG_MTD_BLOCK=y  CONFIG_MTD_CFI=y @@ -64,15 +62,14 @@ CONFIG_ATA=y  CONFIG_SATA_FSL=y  CONFIG_SATA_SIL=y  CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_UCC_GETH=y +CONFIG_GIANFAR=y  CONFIG_MARVELL_PHY=y  CONFIG_DAVICOM_PHY=y  CONFIG_VITESSE_PHY=y  CONFIG_ICPLUS_PHY=y  CONFIG_FIXED_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_GIANFAR=y -CONFIG_UCC_GETH=y  CONFIG_INPUT_FF_MEMLESS=m  # CONFIG_INPUT_MOUSEDEV is not set  # CONFIG_INPUT_KEYBOARD is not set @@ -112,17 +109,12 @@ CONFIG_RTC_DRV_DS1374=y  CONFIG_EXT2_FS=y  CONFIG_EXT3_FS=y  # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_INOTIFY=y  CONFIG_PROC_KCORE=y  CONFIG_TMPFS=y  CONFIG_NFS_FS=y -CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y  CONFIG_CRC_T10DIF=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y  CONFIG_CRYPTO_ECB=m  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_SHA256=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 03ee911c457..8b5bda27d24 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -5,7 +5,9 @@ CONFIG_SYSVIPC=y  CONFIG_POSIX_MQUEUE=y  CONFIG_BSD_PROCESS_ACCT=y  CONFIG_AUDIT=y -CONFIG_SPARSE_IRQ=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y  CONFIG_IKCONFIG=y  CONFIG_IKCONFIG_PROC=y  CONFIG_LOG_BUF_SHIFT=14 @@ -17,6 +19,8 @@ CONFIG_MODULE_UNLOAD=y  CONFIG_MODULE_FORCE_UNLOAD=y  CONFIG_MODVERSIONS=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y  CONFIG_MPC8540_ADS=y  CONFIG_MPC8560_ADS=y  CONFIG_MPC85xx_CDS=y @@ -40,8 +44,6 @@ CONFIG_SBC8548=y  CONFIG_QUICC_ENGINE=y  CONFIG_QE_GPIO=y  CONFIG_HIGHMEM=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y  CONFIG_BINFMT_MISC=m  CONFIG_MATH_EMULATION=y  CONFIG_FORCE_MAX_ZONEORDER=12 @@ -74,36 +76,25 @@ CONFIG_INET_ESP=y  CONFIG_IPV6=y  CONFIG_IP_SCTP=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  CONFIG_MTD=y  CONFIG_MTD_CMDLINE_PARTS=y  CONFIG_MTD_CHAR=y  CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y  CONFIG_FTL=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI=y  CONFIG_MTD_CFI_INTELEXT=y  CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_UTIL=y  CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_M25P80=y  CONFIG_MTD_NAND=y  CONFIG_MTD_NAND_FSL_ELBC=y  CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_M25P80=y  CONFIG_PROC_DEVICETREE=y  CONFIG_BLK_DEV_LOOP=y  CONFIG_BLK_DEV_NBD=y  CONFIG_BLK_DEV_RAM=y  CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_MISC_DEVICES=y  CONFIG_EEPROM_LEGACY=y  CONFIG_BLK_DEV_SD=y  CONFIG_CHR_DEV_ST=y @@ -115,6 +106,7 @@ CONFIG_ATA=y  CONFIG_SATA_AHCI=y  CONFIG_SATA_FSL=y  CONFIG_PATA_ALI=y +CONFIG_PATA_VIA=y  CONFIG_NETDEVICES=y  CONFIG_DUMMY=y  CONFIG_FS_ENET=y @@ -134,7 +126,6 @@ CONFIG_SERIAL_8250=y  CONFIG_SERIAL_8250_CONSOLE=y  CONFIG_SERIAL_8250_NR_UARTS=2  CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y  CONFIG_SERIAL_8250_MANY_PORTS=y  CONFIG_SERIAL_8250_DETECT_IRQ=y  CONFIG_SERIAL_8250_RSA=y @@ -183,7 +174,6 @@ CONFIG_HID_SAMSUNG=y  CONFIG_HID_SONY=y  CONFIG_HID_SUNPLUS=y  CONFIG_USB=y -CONFIG_USB_DEVICEFS=y  CONFIG_USB_MON=y  CONFIG_USB_EHCI_HCD=y  CONFIG_USB_EHCI_FSL=y @@ -229,18 +219,13 @@ CONFIG_QNX4FS_FS=m  CONFIG_SYSV_FS=m  CONFIG_UFS_FS=m  CONFIG_NFS_FS=y -CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  CONFIG_ROOT_NFS=y  CONFIG_NFSD=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y  CONFIG_CRC_T10DIF=y  CONFIG_DEBUG_FS=y  CONFIG_DETECT_HUNG_TASK=y  CONFIG_DEBUG_INFO=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_IRQ_DOMAIN_DEBUG=y  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_SHA256=y  CONFIG_CRYPTO_SHA512=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index fdfa84dc908..b0974e7e98a 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -7,7 +7,9 @@ CONFIG_SYSVIPC=y  CONFIG_POSIX_MQUEUE=y  CONFIG_BSD_PROCESS_ACCT=y  CONFIG_AUDIT=y -CONFIG_SPARSE_IRQ=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y  CONFIG_IKCONFIG=y  CONFIG_IKCONFIG_PROC=y  CONFIG_LOG_BUF_SHIFT=14 @@ -19,6 +21,8 @@ CONFIG_MODULE_UNLOAD=y  CONFIG_MODULE_FORCE_UNLOAD=y  CONFIG_MODVERSIONS=y  # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_MAC_PARTITION=y  CONFIG_MPC8540_ADS=y  CONFIG_MPC8560_ADS=y  CONFIG_MPC85xx_CDS=y @@ -42,8 +46,6 @@ CONFIG_SBC8548=y  CONFIG_QUICC_ENGINE=y  CONFIG_QE_GPIO=y  CONFIG_HIGHMEM=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y  CONFIG_BINFMT_MISC=m  CONFIG_MATH_EMULATION=y  CONFIG_IRQ_ALL_CPUS=y @@ -77,36 +79,25 @@ CONFIG_INET_ESP=y  CONFIG_IPV6=y  CONFIG_IP_SCTP=m  CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y  CONFIG_MTD=y  CONFIG_MTD_CMDLINE_PARTS=y  CONFIG_MTD_CHAR=y  CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y  CONFIG_FTL=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI=y  CONFIG_MTD_CFI_INTELEXT=y  CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_UTIL=y  CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_M25P80=y  CONFIG_MTD_NAND=y  CONFIG_MTD_NAND_FSL_ELBC=y  CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_M25P80=y  CONFIG_PROC_DEVICETREE=y  CONFIG_BLK_DEV_LOOP=y  CONFIG_BLK_DEV_NBD=y  CONFIG_BLK_DEV_RAM=y  CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_MISC_DEVICES=y  CONFIG_EEPROM_LEGACY=y  CONFIG_BLK_DEV_SD=y  CONFIG_CHR_DEV_ST=y @@ -137,7 +128,6 @@ CONFIG_SERIAL_8250=y  CONFIG_SERIAL_8250_CONSOLE=y  CONFIG_SERIAL_8250_NR_UARTS=2  CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y  CONFIG_SERIAL_8250_MANY_PORTS=y  CONFIG_SERIAL_8250_DETECT_IRQ=y  CONFIG_SERIAL_8250_RSA=y @@ -186,7 +176,6 @@ CONFIG_HID_SAMSUNG=y  CONFIG_HID_SONY=y  CONFIG_HID_SUNPLUS=y  CONFIG_USB=y -CONFIG_USB_DEVICEFS=y  CONFIG_USB_MON=y  CONFIG_USB_EHCI_HCD=y  CONFIG_USB_EHCI_FSL=y @@ -232,18 +221,13 @@ CONFIG_QNX4FS_FS=m  CONFIG_SYSV_FS=m  CONFIG_UFS_FS=m  CONFIG_NFS_FS=y -CONFIG_NFS_V3=y  CONFIG_NFS_V4=y  CONFIG_ROOT_NFS=y  CONFIG_NFSD=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y  CONFIG_CRC_T10DIF=y  CONFIG_DEBUG_FS=y  CONFIG_DETECT_HUNG_TASK=y  CONFIG_DEBUG_INFO=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_IRQ_DOMAIN_DEBUG=y  CONFIG_CRYPTO_PCBC=m  CONFIG_CRYPTO_SHA256=y  CONFIG_CRYPTO_SHA512=y diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 50d82c8a037..b3c083de17a 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -553,9 +553,7 @@ static inline int cpu_has_feature(unsigned long feature)  		& feature);  } -#ifdef CONFIG_HAVE_HW_BREAKPOINT  #define HBP_NUM 1 -#endif /* CONFIG_HAVE_HW_BREAKPOINT */  #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 50ea12fd7bf..a8bf5c673a3 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -33,6 +33,7 @@  #include <asm/kvm_asm.h>  #include <asm/processor.h>  #include <asm/page.h> +#include <asm/cacheflush.h>  #define KVM_MAX_VCPUS		NR_CPUS  #define KVM_MAX_VCORES		NR_CPUS diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 0124937a23b..e006f0bdea9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -219,4 +219,16 @@ void kvmppc_claim_lpid(long lpid);  void kvmppc_free_lpid(long lpid);  void kvmppc_init_lpid(unsigned long nr_lpids); +static inline void kvmppc_mmu_flush_icache(pfn_t pfn) +{ +	/* Clear i-cache for new pages */ +	struct page *page; +	page = pfn_to_page(pfn); +	if (!test_bit(PG_arch_1, &page->flags)) { +		flush_dcache_icache_page(page); +		set_bit(PG_arch_1, &page->flags); +	} +} + +  #endif /* __POWERPC_KVM_PPC_H__ */ diff --git a/arch/powerpc/include/asm/mpic_msgr.h b/arch/powerpc/include/asm/mpic_msgr.h index 326d33ca55c..d4f471fb103 100644 --- a/arch/powerpc/include/asm/mpic_msgr.h +++ b/arch/powerpc/include/asm/mpic_msgr.h @@ -14,6 +14,7 @@  #include <linux/types.h>  #include <linux/spinlock.h>  #include <asm/smp.h> +#include <asm/io.h>  struct mpic_msgr {  	u32 __iomem *base; diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 53b6dfa8334..54b73a28c20 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -386,6 +386,7 @@ extern unsigned long cpuidle_disable;  enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};  extern int powersave_nap;	/* set if nap mode can be used in idle loop */ +extern void power7_nap(void);  #ifdef CONFIG_PSERIES_IDLE  extern void update_smt_snooze_delay(int snooze); diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 85b05c463fa..e8995727b1c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -76,6 +76,7 @@ int main(void)  	DEFINE(SIGSEGV, SIGSEGV);  	DEFINE(NMI_MASK, NMI_MASK);  	DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr)); +	DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit));  #else  	DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));  #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 5b25c8060fd..a892680668d 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c @@ -28,6 +28,8 @@ void doorbell_setup_this_cpu(void)  void doorbell_cause_ipi(int cpu, unsigned long data)  { +	/* Order previous accesses vs. msgsnd, which is treated as a store */ +	mb();  	ppc_msgsnd(PPC_DBELL, 0, data);  } diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 2d7bb8ced13..e4897523de4 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -83,11 +83,10 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)  		return 0;  	} -	if ((tbl->it_offset + tbl->it_size) > (mask >> IOMMU_PAGE_SHIFT)) { -		dev_info(dev, "Warning: IOMMU window too big for device mask\n"); -		dev_info(dev, "mask: 0x%08llx, table end: 0x%08lx\n", -				mask, (tbl->it_offset + tbl->it_size) << -				IOMMU_PAGE_SHIFT); +	if (tbl->it_offset > (mask >> IOMMU_PAGE_SHIFT)) { +		dev_info(dev, "Warning: IOMMU offset too big for device mask\n"); +		dev_info(dev, "mask: 0x%08llx, table offset: 0x%08lx\n", +				mask, tbl->it_offset << IOMMU_PAGE_SHIFT);  		return 0;  	} else  		return 1; diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 4b01a25e29e..b40e0b4815b 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -370,6 +370,12 @@ _GLOBAL(ret_from_fork)  	li	r3,0  	b	syscall_exit +	.section	".toc","aw" +DSCR_DEFAULT: +	.tc dscr_default[TC],dscr_default + +	.section	".text" +  /*   * This routine switches between two different tasks.  The process   * state of one is saved on its kernel stack.  Then the state @@ -509,9 +515,6 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)  	mr	r1,r8		/* start using new stack pointer */  	std	r7,PACAKSAVE(r13) -	ld	r6,_CCR(r1) -	mtcrf	0xFF,r6 -  #ifdef CONFIG_ALTIVEC  BEGIN_FTR_SECTION  	ld	r0,THREAD_VRSAVE(r4) @@ -520,14 +523,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)  #endif /* CONFIG_ALTIVEC */  #ifdef CONFIG_PPC64  BEGIN_FTR_SECTION +	lwz	r6,THREAD_DSCR_INHERIT(r4) +	ld	r7,DSCR_DEFAULT@toc(2)  	ld	r0,THREAD_DSCR(r4) -	cmpd	r0,r25 -	beq	1f +	cmpwi	r6,0 +	bne	1f +	ld	r0,0(r7) +1:	cmpd	r0,r25 +	beq	2f  	mtspr	SPRN_DSCR,r0 -1:	 +2:  END_FTR_SECTION_IFSET(CPU_FTR_DSCR)  #endif +	ld	r6,_CCR(r1) +	mtcrf	0xFF,r6 +  	/* r3-r13 are destroyed -- Cort */  	REST_8GPRS(14, r1)  	REST_10GPRS(22, r1) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e894515e77b..39aa97d3ff8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -186,7 +186,7 @@ hardware_interrupt_hv:  	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x800)  	MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) -	MASKABLE_EXCEPTION_HV(0x980, 0x982, decrementer) +	STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)  	STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)  	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xa00) @@ -486,6 +486,7 @@ machine_check_common:  	STD_EXCEPTION_COMMON_ASYNC(0x500, hardware_interrupt, do_IRQ)  	STD_EXCEPTION_COMMON_ASYNC(0x900, decrementer, .timer_interrupt) +	STD_EXCEPTION_COMMON(0x980, hdecrementer, .hdec_interrupt)  	STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)  	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)  	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index f3a82dde61d..956a4c496de 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -253,7 +253,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)  	/* Do not emulate user-space instructions, instead single-step them */  	if (user_mode(regs)) { -		bp->ctx->task->thread.last_hit_ubp = bp; +		current->thread.last_hit_ubp = bp;  		regs->msr |= MSR_SE;  		goto out;  	} diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index 7140d838339..e11863f4e59 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -28,7 +28,9 @@ _GLOBAL(power7_idle)  	lwz	r4,ADDROFF(powersave_nap)(r3)  	cmpwi	0,r4,0  	beqlr +	/* fall through */ +_GLOBAL(power7_nap)  	/* NAP is a state loss, we create a regs frame on the  	 * stack, fill it up with the state we care about and  	 * stick a pointer to it in PACAR1. We really only diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 782bd0a3c2f..c470a40b29f 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -25,6 +25,7 @@  #include <asm/processor.h>  #include <asm/machdep.h>  #include <asm/debug.h> +#include <linux/slab.h>  /*   * This table contains the mapping between PowerPC hardware trap types, and @@ -101,6 +102,21 @@ static int computeSignal(unsigned int tt)  	return SIGHUP;		/* default for things we don't know about */  } +/** + * + *	kgdb_skipexception - Bail out of KGDB when we've been triggered. + *	@exception: Exception vector number + *	@regs: Current &struct pt_regs. + * + *	On some architectures we need to skip a breakpoint exception when + *	it occurs after a breakpoint has been removed. + * + */ +int kgdb_skipexception(int exception, struct pt_regs *regs) +{ +	return kgdb_isremovedbreak(regs->nip); +} +  static int kgdb_call_nmi_hook(struct pt_regs *regs)  {  	kgdb_nmicallback(raw_smp_processor_id(), regs); @@ -138,6 +154,8 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)  static int kgdb_singlestep(struct pt_regs *regs)  {  	struct thread_info *thread_info, *exception_thread_info; +	struct thread_info *backup_current_thread_info = \ +		(struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);  	if (user_mode(regs))  		return 0; @@ -155,13 +173,17 @@ static int kgdb_singlestep(struct pt_regs *regs)  	thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));  	exception_thread_info = current_thread_info(); -	if (thread_info != exception_thread_info) +	if (thread_info != exception_thread_info) { +		/* Save the original current_thread_info. */ +		memcpy(backup_current_thread_info, exception_thread_info, sizeof *thread_info);  		memcpy(exception_thread_info, thread_info, sizeof *thread_info); +	}  	kgdb_handle_exception(0, SIGTRAP, 0, regs);  	if (thread_info != exception_thread_info) -		memcpy(thread_info, exception_thread_info, sizeof *thread_info); +		/* Restore current_thread_info lastly. */ +		memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);  	return 1;  } @@ -410,7 +432,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,  #else  			linux_regs->msr |= MSR_SE;  #endif -			kgdb_single_step = 1;  			atomic_set(&kgdb_cpu_doing_single_step,  				   raw_smp_processor_id());  		} diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 710f400476d..1a1f2ddfb58 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -802,16 +802,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,  #endif /* CONFIG_PPC_STD_MMU_64 */  #ifdef CONFIG_PPC64   	if (cpu_has_feature(CPU_FTR_DSCR)) { -		if (current->thread.dscr_inherit) { -			p->thread.dscr_inherit = 1; -			p->thread.dscr = current->thread.dscr; -		} else if (0 != dscr_default) { -			p->thread.dscr_inherit = 1; -			p->thread.dscr = dscr_default; -		} else { -			p->thread.dscr_inherit = 0; -			p->thread.dscr = 0; -		} +		p->thread.dscr_inherit = current->thread.dscr_inherit; +		p->thread.dscr = current->thread.dscr;  	}  #endif diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 0321007086f..8d4214afc21 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -198,8 +198,15 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)  	struct cpu_messages *info = &per_cpu(ipi_message, cpu);  	char *message = (char *)&info->messages; +	/* +	 * Order previous accesses before accesses in the IPI handler. +	 */ +	smp_mb();  	message[msg] = 1; -	mb(); +	/* +	 * cause_ipi functions are required to include a full barrier +	 * before doing whatever causes the IPI. +	 */  	smp_ops->cause_ipi(cpu, info->data);  } @@ -211,7 +218,7 @@ irqreturn_t smp_ipi_demux(void)  	mb();	/* order any irq clear */  	do { -		all = xchg_local(&info->messages, 0); +		all = xchg(&info->messages, 0);  #ifdef __BIG_ENDIAN  		if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index f2496f2faec..4e3cc47f26b 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -107,11 +107,11 @@ long ppc64_personality(unsigned long personality)  	long ret;  	if (personality(current->personality) == PER_LINUX32 -	    && personality == PER_LINUX) -		personality = PER_LINUX32; +	    && personality(personality) == PER_LINUX) +		personality = (personality & ~PER_MASK) | PER_LINUX32;  	ret = sys_personality(personality); -	if (ret == PER_LINUX32) -		ret = PER_LINUX; +	if (personality(ret) == PER_LINUX32) +		ret = (ret & ~PER_MASK) | PER_LINUX;  	return ret;  }  #endif diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 3529446c2ab..8302af64921 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -194,6 +194,14 @@ static ssize_t show_dscr_default(struct device *dev,  	return sprintf(buf, "%lx\n", dscr_default);  } +static void update_dscr(void *dummy) +{ +	if (!current->thread.dscr_inherit) { +		current->thread.dscr = dscr_default; +		mtspr(SPRN_DSCR, dscr_default); +	} +} +  static ssize_t __used store_dscr_default(struct device *dev,  		struct device_attribute *attr, const char *buf,  		size_t count) @@ -206,6 +214,8 @@ static ssize_t __used store_dscr_default(struct device *dev,  		return -EINVAL;  	dscr_default = val; +	on_each_cpu(update_dscr, NULL, 1); +  	return count;  } diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index be171ee73bf..e49e93191b6 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -535,6 +535,15 @@ void timer_interrupt(struct pt_regs * regs)  	trace_timer_interrupt_exit(regs);  } +/* + * Hypervisor decrementer interrupts shouldn't occur but are sometimes + * left pending on exit from a KVM guest.  We don't need to do anything + * to clear them, as they are edge-triggered. + */ +void hdec_interrupt(struct pt_regs *regs) +{ +} +  #ifdef CONFIG_SUSPEND  static void generic_suspend_disable_irqs(void)  { diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 158972341a2..ae0843fa7a6 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -972,8 +972,9 @@ static int emulate_instruction(struct pt_regs *regs)  			cpu_has_feature(CPU_FTR_DSCR)) {  		PPC_WARN_EMULATED(mtdscr, regs);  		rd = (instword >> 21) & 0x1f; -		mtspr(SPRN_DSCR, regs->gpr[rd]); +		current->thread.dscr = regs->gpr[rd];  		current->thread.dscr_inherit = 1; +		mtspr(SPRN_DSCR, current->thread.dscr);  		return 0;  	}  #endif diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index f922c29bb23..837f13e7b6b 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -211,6 +211,9 @@ next_pteg:  		pteg1 |= PP_RWRX;  	} +	if (orig_pte->may_execute) +		kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); +  	local_irq_disable();  	if (pteg[rr]) { diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 10fc8ec9d2a..0688b6b3958 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -126,6 +126,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)  	if (!orig_pte->may_execute)  		rflags |= HPTE_R_N; +	else +		kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT);  	hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 5a84c8d3d04..44b72feaff7 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1421,13 +1421,13 @@ _GLOBAL(kvmppc_h_cede)  	sync			/* order setting ceded vs. testing prodded */  	lbz	r5,VCPU_PRODDED(r3)  	cmpwi	r5,0 -	bne	1f +	bne	kvm_cede_prodded  	li	r0,0		/* set trap to 0 to say hcall is handled */  	stw	r0,VCPU_TRAP(r3)  	li	r0,H_SUCCESS  	std	r0,VCPU_GPR(R3)(r3)  BEGIN_FTR_SECTION -	b	2f		/* just send it up to host on 970 */ +	b	kvm_cede_exit	/* just send it up to host on 970 */  END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)  	/* @@ -1446,7 +1446,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)  	or	r4,r4,r0  	PPC_POPCNTW(R7,R4)  	cmpw	r7,r8 -	bge	2f +	bge	kvm_cede_exit  	stwcx.	r4,0,r6  	bne	31b  	li	r0,1 @@ -1555,7 +1555,8 @@ kvm_end_cede:  	b	hcall_real_fallback  	/* cede when already previously prodded case */ -1:	li	r0,0 +kvm_cede_prodded: +	li	r0,0  	stb	r0,VCPU_PRODDED(r3)  	sync			/* order testing prodded vs. clearing ceded */  	stb	r0,VCPU_CEDED(r3) @@ -1563,7 +1564,8 @@ kvm_end_cede:  	blr  	/* we've ceded but we want to give control to the host */ -2:	li	r3,H_TOO_HARD +kvm_cede_exit: +	li	r3,H_TOO_HARD  	blr  secondary_too_late: diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index c510fc96130..a2b66717813 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c @@ -322,11 +322,11 @@ static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)  static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500)  {  	if (vcpu_e500->g2h_tlb1_map) -		memset(vcpu_e500->g2h_tlb1_map, -		       sizeof(u64) * vcpu_e500->gtlb_params[1].entries, 0); +		memset(vcpu_e500->g2h_tlb1_map, 0, +		       sizeof(u64) * vcpu_e500->gtlb_params[1].entries);  	if (vcpu_e500->h2g_tlb1_rmap) -		memset(vcpu_e500->h2g_tlb1_rmap, -		       sizeof(unsigned int) * host_tlb_params[1].entries, 0); +		memset(vcpu_e500->h2g_tlb1_rmap, 0, +		       sizeof(unsigned int) * host_tlb_params[1].entries);  }  static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) @@ -539,6 +539,9 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,  	kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,  				ref, gvaddr, stlbe); + +	/* Clear i-cache for new pages */ +	kvmppc_mmu_flush_icache(pfn);  }  /* XXX only map the one-one case, for now use TLB0 */ diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index dd223b3eb33..17e5b236431 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -20,7 +20,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr)  {  	int err; -	err = __put_user(instr, addr); +	__put_user_size(instr, addr, 4, err);  	if (err)  		return err;  	asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index f9ede7c6606..0d24ff15f5f 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -288,7 +288,7 @@ err1;	stb	r0,0(r3)  	std	r0,16(r1)  	stdu	r1,-STACKFRAMESIZE(r1)  	bl	.enter_vmx_usercopy -	cmpwi	r3,0 +	cmpwi	cr1,r3,0  	ld	r0,STACKFRAMESIZE+16(r1)  	ld	r3,STACKFRAMESIZE+48(r1)  	ld	r4,STACKFRAMESIZE+56(r1) @@ -326,38 +326,7 @@ err1;	stb	r0,0(r3)  	dcbt	r0,r8,0b01010	/* GO */  .machine pop -	/* -	 * We prefetch both the source and destination using enhanced touch -	 * instructions. We use a stream ID of 0 for the load side and -	 * 1 for the store side. -	 */ -	clrrdi	r6,r4,7 -	clrrdi	r9,r3,7 -	ori	r9,r9,1		/* stream=1 */ - -	srdi	r7,r5,7		/* length in cachelines, capped at 0x3FF */ -	cmpldi	cr1,r7,0x3FF -	ble	cr1,1f -	li	r7,0x3FF -1:	lis	r0,0x0E00	/* depth=7 */ -	sldi	r7,r7,7 -	or	r7,r7,r0 -	ori	r10,r7,1	/* stream=1 */ - -	lis	r8,0x8000	/* GO=1 */ -	clrldi	r8,r8,32 - -.machine push -.machine "power4" -	dcbt	r0,r6,0b01000 -	dcbt	r0,r7,0b01010 -	dcbtst	r0,r9,0b01000 -	dcbtst	r0,r10,0b01010 -	eieio -	dcbt	r0,r8,0b01010	/* GO */ -.machine pop - -	beq	.Lunwind_stack_nonvmx_copy +	beq	cr1,.Lunwind_stack_nonvmx_copy  	/*  	 * If source and destination are not relatively aligned we use a diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 0efdc51bc71..7ba6c96de77 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S @@ -222,7 +222,7 @@ _GLOBAL(memcpy_power7)  	std	r0,16(r1)  	stdu	r1,-STACKFRAMESIZE(r1)  	bl	.enter_vmx_copy -	cmpwi	r3,0 +	cmpwi	cr1,r3,0  	ld	r0,STACKFRAMESIZE+16(r1)  	ld	r3,STACKFRAMESIZE+48(r1)  	ld	r4,STACKFRAMESIZE+56(r1) @@ -260,7 +260,7 @@ _GLOBAL(memcpy_power7)  	dcbt	r0,r8,0b01010	/* GO */  .machine pop -	beq	.Lunwind_stack_nonvmx_copy +	beq	cr1,.Lunwind_stack_nonvmx_copy  	/*  	 * If source and destination are not relatively aligned we use a diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index baaafde7d13..fbdad0e3929 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -469,6 +469,7 @@ void flush_dcache_icache_page(struct page *page)  	__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);  #endif  } +EXPORT_SYMBOL(flush_dcache_icache_page);  void clear_user_page(void *page, unsigned long vaddr, struct page *pg)  { diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 39b159751c3..59213cfaeca 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1436,11 +1436,11 @@ static long vphn_get_associativity(unsigned long cpu,  /*   * Update the node maps and sysfs entries for each cpu whose home node - * has changed. + * has changed. Returns 1 when the topology has changed, and 0 otherwise.   */  int arch_update_cpu_topology(void)  { -	int cpu, nid, old_nid; +	int cpu, nid, old_nid, changed = 0;  	unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};  	struct device *dev; @@ -1466,9 +1466,10 @@ int arch_update_cpu_topology(void)  		dev = get_cpu_device(cpu);  		if (dev)  			kobject_uevent(&dev->kobj, KOBJ_CHANGE); +		changed = 1;  	} -	return 1; +	return changed;  }  static void topology_work_fn(struct work_struct *work) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 77b49ddda9d..7cd2dbd6e4c 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1431,7 +1431,7 @@ static void perf_event_interrupt(struct pt_regs *regs)  		if (!event->hw.idx || is_limited_pmc(event->hw.idx))  			continue;  		val = read_pmc(event->hw.idx); -		if ((int)val < 0) { +		if (pmc_overflow(val)) {  			/* event has overflowed */  			found = 1;  			record_and_restart(event, val, regs); diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 3ef46254c35..7698b6e13c5 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -106,14 +106,6 @@ static void pnv_smp_cpu_kill_self(void)  {  	unsigned int cpu; -	/* If powersave_nap is enabled, use NAP mode, else just -	 * spin aimlessly -	 */ -	if (!powersave_nap) { -		generic_mach_cpu_die(); -		return; -	} -  	/* Standard hot unplug procedure */  	local_irq_disable();  	idle_task_exit(); @@ -128,7 +120,7 @@ static void pnv_smp_cpu_kill_self(void)  	 */  	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);  	while (!generic_check_cpu_restart(cpu)) { -		power7_idle(); +		power7_nap();  		if (!generic_check_cpu_restart(cpu)) {  			DBG("CPU%d Unexpected exit while offline !\n", cpu);  			/* We may be getting an IPI, so we re-enable diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index a7b2a600d0a..c37f4613632 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -465,7 +465,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)  			iounmap(hose->cfg_data);  		iounmap(hose->cfg_addr);  		pcibios_free_controller(hose); -		return 0; +		return -ENODEV;  	}  	setup_pci_cmd(hose); @@ -827,6 +827,7 @@ struct device_node *fsl_pci_primary;  void __devinit fsl_pci_init(void)  { +	int ret;  	struct device_node *node;  	struct pci_controller *hose;  	dma_addr_t max = 0xffffffff; @@ -855,10 +856,12 @@ void __devinit fsl_pci_init(void)  			if (!fsl_pci_primary)  				fsl_pci_primary = node; -			fsl_add_bridge(node, fsl_pci_primary == node); -			hose = pci_find_hose_for_OF_device(node); -			max = min(max, hose->dma_window_base_cur + -					hose->dma_window_size); +			ret = fsl_add_bridge(node, fsl_pci_primary == node); +			if (ret == 0) { +				hose = pci_find_hose_for_OF_device(node); +				max = min(max, hose->dma_window_base_cur + +						hose->dma_window_size); +			}  		}  	} diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 483d8fa72e8..e961f8c4a8f 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -14,6 +14,9 @@  #include <linux/list.h>  #include <linux/of_platform.h>  #include <linux/errno.h> +#include <linux/err.h> +#include <linux/export.h> +#include <linux/slab.h>  #include <asm/prom.h>  #include <asm/hw_irq.h>  #include <asm/ppc-pci.h> diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c index 14469cf9df6..df0fc582146 100644 --- a/arch/powerpc/sysdev/xics/icp-hv.c +++ b/arch/powerpc/sysdev/xics/icp-hv.c @@ -65,7 +65,11 @@ static inline void icp_hv_set_xirr(unsigned int value)  static inline void icp_hv_set_qirr(int n_cpu , u8 value)  {  	int hw_cpu = get_hard_smp_processor_id(n_cpu); -	long rc = plpar_hcall_norets(H_IPI, hw_cpu, value); +	long rc; + +	/* Make sure all previous accesses are ordered before IPI sending */ +	mb(); +	rc = plpar_hcall_norets(H_IPI, hw_cpu, value);  	if (rc != H_SUCCESS) {  		pr_err("%s: bad return code qirr cpu=%d hw_cpu=%d mfrr=0x%x "  			"returned %ld\n", __func__, n_cpu, hw_cpu, value, rc); diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index eab3492a45c..9b49c65ee7a 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -17,6 +17,7 @@  #include <linux/reboot.h>  #include <linux/delay.h>  #include <linux/kallsyms.h> +#include <linux/kmsg_dump.h>  #include <linux/cpumask.h>  #include <linux/export.h>  #include <linux/sysrq.h> @@ -894,13 +895,13 @@ cmds(struct pt_regs *excp)  #endif  		default:  			printf("Unrecognized command: "); -		        do { +			do {  				if (' ' < cmd && cmd <= '~')  					putchar(cmd);  				else  					printf("\\x%x", cmd);  				cmd = inchar(); -		        } while (cmd != '\n');  +			} while (cmd != '\n');  			printf(" (type ? for help)\n");  			break;  		} @@ -1097,7 +1098,7 @@ static long check_bp_loc(unsigned long addr)  	return 1;  } -static char *breakpoint_help_string =  +static char *breakpoint_help_string =      "Breakpoint command usage:\n"      "b                show breakpoints\n"      "b <addr> [cnt]   set breakpoint at given instr addr\n" @@ -1193,7 +1194,7 @@ bpt_cmds(void)  	default:  		termch = cmd; -	        cmd = skipbl(); +		cmd = skipbl();  		if (cmd == '?') {  			printf(breakpoint_help_string);  			break; @@ -1359,7 +1360,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,  				       sp + REGS_OFFSET);  				break;  			} -                        printf("--- Exception: %lx %s at ", regs.trap, +			printf("--- Exception: %lx %s at ", regs.trap,  			       getvecname(TRAP(®s)));  			pc = regs.nip;  			lr = regs.link; @@ -1623,14 +1624,14 @@ static void super_regs(void)  	cmd = skipbl();  	if (cmd == '\n') { -	        unsigned long sp, toc; +		unsigned long sp, toc;  		asm("mr %0,1" : "=r" (sp) :);  		asm("mr %0,2" : "=r" (toc) :);  		printf("msr  = "REG"  sprg0= "REG"\n",  		       mfmsr(), mfspr(SPRN_SPRG0));  		printf("pvr  = "REG"  sprg1= "REG"\n", -		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));  +		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));  		printf("dec  = "REG"  sprg2= "REG"\n",  		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));  		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); @@ -1783,7 +1784,7 @@ byterev(unsigned char *val, int size)  static int brev;  static int mnoread; -static char *memex_help_string =  +static char *memex_help_string =      "Memory examine command usage:\n"      "m [addr] [flags] examine/change memory\n"      "  addr is optional.  will start where left off.\n" @@ -1798,7 +1799,7 @@ static char *memex_help_string =      "NOTE: flags are saved as defaults\n"      ""; -static char *memex_subcmd_help_string =  +static char *memex_subcmd_help_string =      "Memory examine subcommands:\n"      "  hexval   write this val to current location\n"      "  'string' write chars from string to this location\n" @@ -2064,7 +2065,7 @@ prdump(unsigned long adrs, long ndump)  		nr = mread(adrs, temp, r);  		adrs += nr;  		for (m = 0; m < r; ++m) { -		        if ((m & (sizeof(long) - 1)) == 0 && m > 0) +			if ((m & (sizeof(long) - 1)) == 0 && m > 0)  				putchar(' ');  			if (m < nr)  				printf("%.2x", temp[m]); @@ -2072,7 +2073,7 @@ prdump(unsigned long adrs, long ndump)  				printf("%s", fault_chars[fault_type]);  		}  		for (; m < 16; ++m) { -		        if ((m & (sizeof(long) - 1)) == 0) +			if ((m & (sizeof(long) - 1)) == 0)  				putchar(' ');  			printf("  ");  		} @@ -2148,45 +2149,28 @@ print_address(unsigned long addr)  void  dump_log_buf(void)  { -        const unsigned long size = 128; -        unsigned long end, addr; -        unsigned char buf[size + 1]; - -        addr = 0; -        buf[size] = '\0'; - -        if (setjmp(bus_error_jmp) != 0) { -                printf("Unable to lookup symbol __log_buf!\n"); -                return; -        } - -        catch_memory_errors = 1; -        sync(); -        addr = kallsyms_lookup_name("__log_buf"); - -        if (! addr) -                printf("Symbol __log_buf not found!\n"); -        else { -                end = addr + (1 << CONFIG_LOG_BUF_SHIFT); -                while (addr < end) { -                        if (! mread(addr, buf, size)) { -                                printf("Can't read memory at address 0x%lx\n", addr); -                                break; -                        } +	struct kmsg_dumper dumper = { .active = 1 }; +	unsigned char buf[128]; +	size_t len; -                        printf("%s", buf); +	if (setjmp(bus_error_jmp) != 0) { +		printf("Error dumping printk buffer!\n"); +		return; +	} -                        if (strlen(buf) < size) -                                break; +	catch_memory_errors = 1; +	sync(); -                        addr += size; -                } -        } +	kmsg_dump_rewind_nolock(&dumper); +	while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) { +		buf[len] = '\0'; +		printf("%s", buf); +	} -        sync(); -        /* wait a little while to see if we get a machine check */ -        __delay(200); -        catch_memory_errors = 0; +	sync(); +	/* wait a little while to see if we get a machine check */ +	__delay(200); +	catch_memory_errors = 0;  }  /* diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 32e8449640f..9b94a160fe7 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -180,7 +180,8 @@ extern char elf_platform[];  #define ELF_PLATFORM (elf_platform)  #ifndef CONFIG_64BIT -#define SET_PERSONALITY(ex) set_personality(PER_LINUX) +#define SET_PERSONALITY(ex) \ +	set_personality(PER_LINUX | (current->personality & (~PER_MASK)))  #else /* CONFIG_64BIT */  #define SET_PERSONALITY(ex)					\  do {								\ diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/asm/posix_types.h index 7bcc14e395f..bf2a2ad2f80 100644 --- a/arch/s390/include/asm/posix_types.h +++ b/arch/s390/include/asm/posix_types.h @@ -13,6 +13,7 @@   */  typedef unsigned long   __kernel_size_t; +typedef long            __kernel_ssize_t;  #define __kernel_size_t __kernel_size_t  typedef unsigned short	__kernel_old_dev_t; @@ -25,7 +26,6 @@ typedef unsigned short  __kernel_mode_t;  typedef unsigned short  __kernel_ipc_pid_t;  typedef unsigned short  __kernel_uid_t;  typedef unsigned short  __kernel_gid_t; -typedef int             __kernel_ssize_t;  typedef int             __kernel_ptrdiff_t;  #else /* __s390x__ */ @@ -35,7 +35,6 @@ typedef unsigned int    __kernel_mode_t;  typedef int             __kernel_ipc_pid_t;  typedef unsigned int    __kernel_uid_t;  typedef unsigned int    __kernel_gid_t; -typedef long            __kernel_ssize_t;  typedef long            __kernel_ptrdiff_t;  typedef unsigned long   __kernel_sigset_t;      /* at least 32 bits */ diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index a0a8340daaf..ce26ac3cb16 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -44,6 +44,7 @@ static inline void smp_call_online_cpu(void (*func)(void *), void *data)  }  static inline int smp_find_processor_id(int address) { return 0; } +static inline int smp_store_status(int cpu) { return 0; }  static inline int smp_vcpu_scheduled(int cpu) { return 1; }  static inline void smp_yield_cpu(int cpu) { }  static inline void smp_yield(void) { } 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/um/os-Linux/time.c b/arch/um/os-Linux/time.c index f60238559af..0748fe0c8a7 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -114,7 +114,7 @@ static void deliver_alarm(void)  	skew += this_tick - last_tick;  	while (skew >= one_tick) { -		alarm_handler(SIGVTALRM, NULL); +		alarm_handler(SIGVTALRM, NULL, NULL);  		skew -= one_tick;  	} diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index b315a33867f..33692eaabab 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -12,8 +12,7 @@   * Simple spin lock operations.  There are two variants, one clears IRQ's   * on the local processor, one does not.   * - * These are fair FIFO ticket locks, which are currently limited to 256 - * CPUs. + * These are fair FIFO ticket locks, which support up to 2^16 CPUs.   *   * (the type definitions are in asm/spinlock_types.h)   */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index afb7ff79a29..ced4534baed 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -165,7 +165,7 @@ static const unsigned char * const k7_nops[ASM_NOP_MAX+2] =  #endif  #ifdef P6_NOP1 -static const unsigned char  __initconst_or_module p6nops[] = +static const unsigned char p6nops[] =  {  	P6_NOP1,  	P6_NOP2, 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/irq.c b/arch/x86/kernel/irq.c index 7ad683d7864..d44f7829968 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -270,7 +270,7 @@ void fixup_irqs(void)  		if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {  			break_affinity = 1; -			affinity = cpu_all_mask; +			affinity = cpu_online_mask;  		}  		chip = irq_data_get_irq_chip(data); diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 8a2ce8fd41c..82746f942cd 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -143,11 +143,12 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr,  				  unsigned int *current_size)  {  	struct microcode_header_amd *mc_hdr; -	unsigned int actual_size; +	unsigned int actual_size, patch_size;  	u16 equiv_cpu_id;  	/* size of the current patch we're staring at */ -	*current_size = *(u32 *)(ucode_ptr + 4) + SECTION_HDR_SIZE; +	patch_size = *(u32 *)(ucode_ptr + 4); +	*current_size = patch_size + SECTION_HDR_SIZE;  	equiv_cpu_id = find_equiv_id();  	if (!equiv_cpu_id) @@ -174,7 +175,7 @@ static int get_matching_microcode(int cpu, const u8 *ucode_ptr,  	/*  	 * now that the header looks sane, verify its size  	 */ -	actual_size = verify_ucode_size(cpu, *current_size, leftover_size); +	actual_size = verify_ucode_size(cpu, patch_size, leftover_size);  	if (!actual_size)  		return 0; 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/emulate.c b/arch/x86/kvm/emulate.c index 97d9a9914ba..a3b57a27be8 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -475,13 +475,26 @@ register_address(struct x86_emulate_ctxt *ctxt, unsigned long reg)  	return address_mask(ctxt, reg);  } +static void masked_increment(ulong *reg, ulong mask, int inc) +{ +	assign_masked(reg, *reg + inc, mask); +} +  static inline void  register_address_increment(struct x86_emulate_ctxt *ctxt, unsigned long *reg, int inc)  { +	ulong mask; +  	if (ctxt->ad_bytes == sizeof(unsigned long)) -		*reg += inc; +		mask = ~0UL;  	else -		*reg = (*reg & ~ad_mask(ctxt)) | ((*reg + inc) & ad_mask(ctxt)); +		mask = ad_mask(ctxt); +	masked_increment(reg, mask, inc); +} + +static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) +{ +	masked_increment(&ctxt->regs[VCPU_REGS_RSP], stack_mask(ctxt), inc);  }  static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) @@ -1522,8 +1535,8 @@ static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)  {  	struct segmented_address addr; -	register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -bytes); -	addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); +	rsp_increment(ctxt, -bytes); +	addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);  	addr.seg = VCPU_SREG_SS;  	return segmented_write(ctxt, addr, data, bytes); @@ -1542,13 +1555,13 @@ static int emulate_pop(struct x86_emulate_ctxt *ctxt,  	int rc;  	struct segmented_address addr; -	addr.ea = register_address(ctxt, ctxt->regs[VCPU_REGS_RSP]); +	addr.ea = ctxt->regs[VCPU_REGS_RSP] & stack_mask(ctxt);  	addr.seg = VCPU_SREG_SS;  	rc = segmented_read(ctxt, addr, dest, len);  	if (rc != X86EMUL_CONTINUE)  		return rc; -	register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], len); +	rsp_increment(ctxt, len);  	return rc;  } @@ -1688,8 +1701,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)  	while (reg >= VCPU_REGS_RAX) {  		if (reg == VCPU_REGS_RSP) { -			register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], -							ctxt->op_bytes); +			rsp_increment(ctxt, ctxt->op_bytes);  			--reg;  		} @@ -2825,7 +2837,7 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)  	rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes);  	if (rc != X86EMUL_CONTINUE)  		return rc; -	register_address_increment(ctxt, &ctxt->regs[VCPU_REGS_RSP], ctxt->src.val); +	rsp_increment(ctxt, ctxt->src.val);  	return X86EMUL_CONTINUE;  } 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/mmu.c b/arch/x86/kvm/mmu.c index 01ca0042393..7fbd0d273ea 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -4113,16 +4113,21 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)  		LIST_HEAD(invalid_list);  		/* +		 * Never scan more than sc->nr_to_scan VM instances. +		 * Will not hit this condition practically since we do not try +		 * to shrink more than one VM and it is very unlikely to see +		 * !n_used_mmu_pages so many times. +		 */ +		if (!nr_to_scan--) +			break; +		/*  		 * n_used_mmu_pages is accessed without holding kvm->mmu_lock  		 * here. We may skip a VM instance errorneosly, but we do not  		 * want to shrink a VM that only started to populate its MMU  		 * anyway.  		 */ -		if (kvm->arch.n_used_mmu_pages > 0) { -			if (!nr_to_scan--) -				break; +		if (!kvm->arch.n_used_mmu_pages)  			continue; -		}  		idx = srcu_read_lock(&kvm->srcu);  		spin_lock(&kvm->mmu_lock); 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 42bce48f692..2966c847d48 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -806,7 +806,7 @@ EXPORT_SYMBOL_GPL(kvm_rdpmc);   * kvm-specific. Those are put in the beginning of the list.   */ -#define KVM_SAVE_MSRS_BEGIN	9 +#define KVM_SAVE_MSRS_BEGIN	10  static u32 msrs_to_save[] = {  	MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,  	MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, @@ -2000,6 +2000,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)  	case MSR_KVM_STEAL_TIME:  		data = vcpu->arch.st.msr_val;  		break; +	case MSR_KVM_PV_EOI_EN: +		data = vcpu->arch.pv_eoi.msr_val; +		break;  	case MSR_IA32_P5_MC_ADDR:  	case MSR_IA32_P5_MC_TYPE:  	case MSR_IA32_MCG_CAP: @@ -5110,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) @@ -5427,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/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index bf4bda6d3e9..9642d4a3860 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -31,7 +31,6 @@  #include <linux/pci.h>  #include <linux/gfp.h>  #include <linux/memblock.h> -#include <linux/syscore_ops.h>  #include <xen/xen.h>  #include <xen/interface/xen.h> @@ -1470,130 +1469,38 @@ asmlinkage void __init xen_start_kernel(void)  #endif  } -#ifdef CONFIG_XEN_PVHVM -/* - * The pfn containing the shared_info is located somewhere in RAM. This - * will cause trouble if the current kernel is doing a kexec boot into a - * new kernel. The new kernel (and its startup code) can not know where - * the pfn is, so it can not reserve the page. The hypervisor will - * continue to update the pfn, and as a result memory corruption occours - * in the new kernel. - * - * One way to work around this issue is to allocate a page in the - * xen-platform pci device's BAR memory range. But pci init is done very - * late and the shared_info page is already in use very early to read - * the pvclock. So moving the pfn from RAM to MMIO is racy because some - * code paths on other vcpus could access the pfn during the small - * window when the old pfn is moved to the new pfn. There is even a - * small window were the old pfn is not backed by a mfn, and during that - * time all reads return -1. - * - * Because it is not known upfront where the MMIO region is located it - * can not be used right from the start in xen_hvm_init_shared_info. - * - * To minimise trouble the move of the pfn is done shortly before kexec. - * This does not eliminate the race because all vcpus are still online - * when the syscore_ops will be called. But hopefully there is no work - * pending at this point in time. Also the syscore_op is run last which - * reduces the risk further. - */ - -static struct shared_info *xen_hvm_shared_info; - -static void xen_hvm_connect_shared_info(unsigned long pfn) +void __ref xen_hvm_init_shared_info(void)  { +	int cpu;  	struct xen_add_to_physmap xatp; +	static struct shared_info *shared_info_page = 0; +	if (!shared_info_page) +		shared_info_page = (struct shared_info *) +			extend_brk(PAGE_SIZE, PAGE_SIZE);  	xatp.domid = DOMID_SELF;  	xatp.idx = 0;  	xatp.space = XENMAPSPACE_shared_info; -	xatp.gpfn = pfn; +	xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;  	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))  		BUG(); -} -static void xen_hvm_set_shared_info(struct shared_info *sip) -{ -	int cpu; - -	HYPERVISOR_shared_info = sip; +	HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;  	/* xen_vcpu is a pointer to the vcpu_info struct in the shared_info  	 * page, we use it in the event channel upcall and in some pvclock  	 * related functions. We don't need the vcpu_info placement  	 * optimizations because we don't use any pv_mmu or pv_irq op on  	 * HVM. -	 * When xen_hvm_set_shared_info is run at boot time only vcpu 0 is -	 * online but xen_hvm_set_shared_info is run at resume time too and +	 * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is +	 * online but xen_hvm_init_shared_info is run at resume time too and  	 * in that case multiple vcpus might be online. */  	for_each_online_cpu(cpu) {  		per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];  	}  } -/* Reconnect the shared_info pfn to a mfn */ -void xen_hvm_resume_shared_info(void) -{ -	xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT); -} - -#ifdef CONFIG_KEXEC -static struct shared_info *xen_hvm_shared_info_kexec; -static unsigned long xen_hvm_shared_info_pfn_kexec; - -/* Remember a pfn in MMIO space for kexec reboot */ -void __devinit xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn) -{ -	xen_hvm_shared_info_kexec = sip; -	xen_hvm_shared_info_pfn_kexec = pfn; -} - -static void xen_hvm_syscore_shutdown(void) -{ -	struct xen_memory_reservation reservation = { -		.domid = DOMID_SELF, -		.nr_extents = 1, -	}; -	unsigned long prev_pfn; -	int rc; - -	if (!xen_hvm_shared_info_kexec) -		return; - -	prev_pfn = __pa(xen_hvm_shared_info) >> PAGE_SHIFT; -	set_xen_guest_handle(reservation.extent_start, &prev_pfn); - -	/* Move pfn to MMIO, disconnects previous pfn from mfn */ -	xen_hvm_connect_shared_info(xen_hvm_shared_info_pfn_kexec); - -	/* Update pointers, following hypercall is also a memory barrier */ -	xen_hvm_set_shared_info(xen_hvm_shared_info_kexec); - -	/* Allocate new mfn for previous pfn */ -	do { -		rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); -		if (rc == 0) -			msleep(123); -	} while (rc == 0); - -	/* Make sure the previous pfn is really connected to a (new) mfn */ -	BUG_ON(rc != 1); -} - -static struct syscore_ops xen_hvm_syscore_ops = { -	.shutdown = xen_hvm_syscore_shutdown, -}; -#endif - -/* Use a pfn in RAM, may move to MMIO before kexec. */ -static void __init xen_hvm_init_shared_info(void) -{ -	/* Remember pointer for resume */ -	xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE); -	xen_hvm_connect_shared_info(__pa(xen_hvm_shared_info) >> PAGE_SHIFT); -	xen_hvm_set_shared_info(xen_hvm_shared_info); -} - +#ifdef CONFIG_XEN_PVHVM  static void __init init_hvm_pv_info(void)  {  	int major, minor; @@ -1644,9 +1551,6 @@ static void __init xen_hvm_guest_init(void)  	init_hvm_pv_info();  	xen_hvm_init_shared_info(); -#ifdef CONFIG_KEXEC -	register_syscore_ops(&xen_hvm_syscore_ops); -#endif  	if (xen_feature(XENFEAT_hvm_callback_vector))  		xen_have_vector_callback = 1; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index b65a76133f4..5141d808e75 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1283,7 +1283,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,  	cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask));  	args->op.cmd = MMUEXT_TLB_FLUSH_MULTI; -	if (start != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) { +	if (end != TLB_FLUSH_ALL && (end - start) <= PAGE_SIZE) {  		args->op.cmd = MMUEXT_INVLPG_MULTI;  		args->op.arg1.linear_addr = start;  	} diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index b2e91d40a4c..76ba0e97e53 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -196,9 +196,11 @@ RESERVE_BRK(p2m_mid_identity, PAGE_SIZE * 2 * 3);  /* When we populate back during bootup, the amount of pages can vary. The   * max we have is seen is 395979, but that does not mean it can't be more. - * But some machines can have 3GB I/O holes even. So lets reserve enough - * for 4GB of I/O and E820 holes. */ -RESERVE_BRK(p2m_populated, PMD_SIZE * 4); + * Some machines can have 3GB I/O holes even. With early_can_reuse_p2m_middle + * it can re-use Xen provided mfn_list array, so we only need to allocate at + * most three P2M top nodes. */ +RESERVE_BRK(p2m_populated, PAGE_SIZE * 3); +  static inline unsigned p2m_top_index(unsigned long pfn)  {  	BUG_ON(pfn >= MAX_P2M_PFN); @@ -575,12 +577,99 @@ static bool __init early_alloc_p2m(unsigned long pfn)  	}  	return true;  } + +/* + * Skim over the P2M tree looking at pages that are either filled with + * INVALID_P2M_ENTRY or with 1:1 PFNs. If found, re-use that page and + * replace the P2M leaf with a p2m_missing or p2m_identity. + * Stick the old page in the new P2M tree location. + */ +bool __init early_can_reuse_p2m_middle(unsigned long set_pfn, unsigned long set_mfn) +{ +	unsigned topidx; +	unsigned mididx; +	unsigned ident_pfns; +	unsigned inv_pfns; +	unsigned long *p2m; +	unsigned long *mid_mfn_p; +	unsigned idx; +	unsigned long pfn; + +	/* We only look when this entails a P2M middle layer */ +	if (p2m_index(set_pfn)) +		return false; + +	for (pfn = 0; pfn < MAX_DOMAIN_PAGES; pfn += P2M_PER_PAGE) { +		topidx = p2m_top_index(pfn); + +		if (!p2m_top[topidx]) +			continue; + +		if (p2m_top[topidx] == p2m_mid_missing) +			continue; + +		mididx = p2m_mid_index(pfn); +		p2m = p2m_top[topidx][mididx]; +		if (!p2m) +			continue; + +		if ((p2m == p2m_missing) || (p2m == p2m_identity)) +			continue; + +		if ((unsigned long)p2m == INVALID_P2M_ENTRY) +			continue; + +		ident_pfns = 0; +		inv_pfns = 0; +		for (idx = 0; idx < P2M_PER_PAGE; idx++) { +			/* IDENTITY_PFNs are 1:1 */ +			if (p2m[idx] == IDENTITY_FRAME(pfn + idx)) +				ident_pfns++; +			else if (p2m[idx] == INVALID_P2M_ENTRY) +				inv_pfns++; +			else +				break; +		} +		if ((ident_pfns == P2M_PER_PAGE) || (inv_pfns == P2M_PER_PAGE)) +			goto found; +	} +	return false; +found: +	/* Found one, replace old with p2m_identity or p2m_missing */ +	p2m_top[topidx][mididx] = (ident_pfns ? p2m_identity : p2m_missing); +	/* And the other for save/restore.. */ +	mid_mfn_p = p2m_top_mfn_p[topidx]; +	/* NOTE: Even if it is a p2m_identity it should still be point to +	 * a page filled with INVALID_P2M_ENTRY entries. */ +	mid_mfn_p[mididx] = virt_to_mfn(p2m_missing); + +	/* Reset where we want to stick the old page in. */ +	topidx = p2m_top_index(set_pfn); +	mididx = p2m_mid_index(set_pfn); + +	/* This shouldn't happen */ +	if (WARN_ON(p2m_top[topidx] == p2m_mid_missing)) +		early_alloc_p2m(set_pfn); + +	if (WARN_ON(p2m_top[topidx][mididx] != p2m_missing)) +		return false; + +	p2m_init(p2m); +	p2m_top[topidx][mididx] = p2m; +	mid_mfn_p = p2m_top_mfn_p[topidx]; +	mid_mfn_p[mididx] = virt_to_mfn(p2m); + +	return true; +}  bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn)  {  	if (unlikely(!__set_phys_to_machine(pfn, mfn)))  {  		if (!early_alloc_p2m(pfn))  			return false; +		if (early_can_reuse_p2m_middle(pfn, mfn)) +			return __set_phys_to_machine(pfn, mfn); +  		if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/))  			return false; diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index ead85576d54..d11ca11d14f 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -78,9 +78,16 @@ static void __init xen_add_extra_mem(u64 start, u64 size)  	memblock_reserve(start, size);  	xen_max_p2m_pfn = PFN_DOWN(start + size); +	for (pfn = PFN_DOWN(start); pfn < xen_max_p2m_pfn; pfn++) { +		unsigned long mfn = pfn_to_mfn(pfn); + +		if (WARN(mfn == pfn, "Trying to over-write 1-1 mapping (pfn: %lx)\n", pfn)) +			continue; +		WARN(mfn != INVALID_P2M_ENTRY, "Trying to remove %lx which has %lx mfn!\n", +			pfn, mfn); -	for (pfn = PFN_DOWN(start); pfn <= xen_max_p2m_pfn; pfn++)  		__set_phys_to_machine(pfn, INVALID_P2M_ENTRY); +	}  }  static unsigned long __init xen_do_chunk(unsigned long start, diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index ae8a00c39de..45329c8c226 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -30,7 +30,7 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled)  {  #ifdef CONFIG_XEN_PVHVM  	int cpu; -	xen_hvm_resume_shared_info(); +	xen_hvm_init_shared_info();  	xen_callback_vector();  	xen_unplug_emulated_devices();  	if (xen_feature(XENFEAT_hvm_safe_pvclock)) { diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 1e4329e04e0..202d4c15015 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -41,7 +41,7 @@ void xen_enable_syscall(void);  void xen_vcpu_restore(void);  void xen_callback_vector(void); -void xen_hvm_resume_shared_info(void); +void xen_hvm_init_shared_info(void);  void xen_unplug_emulated_devices(void);  void __init xen_build_dynamic_phys_to_machine(void); diff --git a/block/blk-lib.c b/block/blk-lib.c index 2b461b496a7..19cc761cacb 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -44,6 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,  	struct request_queue *q = bdev_get_queue(bdev);  	int type = REQ_WRITE | REQ_DISCARD;  	unsigned int max_discard_sectors; +	unsigned int granularity, alignment, mask;  	struct bio_batch bb;  	struct bio *bio;  	int ret = 0; @@ -54,18 +55,20 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,  	if (!blk_queue_discard(q))  		return -EOPNOTSUPP; +	/* Zero-sector (unknown) and one-sector granularities are the same.  */ +	granularity = max(q->limits.discard_granularity >> 9, 1U); +	mask = granularity - 1; +	alignment = (bdev_discard_alignment(bdev) >> 9) & mask; +  	/*  	 * Ensure that max_discard_sectors is of the proper -	 * granularity +	 * granularity, so that requests stay aligned after a split.  	 */  	max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); +	max_discard_sectors = round_down(max_discard_sectors, granularity);  	if (unlikely(!max_discard_sectors)) {  		/* Avoid infinite loop below. Being cautious never hurts. */  		return -EOPNOTSUPP; -	} else if (q->limits.discard_granularity) { -		unsigned int disc_sects = q->limits.discard_granularity >> 9; - -		max_discard_sectors &= ~(disc_sects - 1);  	}  	if (flags & BLKDEV_DISCARD_SECURE) { @@ -79,25 +82,37 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,  	bb.wait = &wait;  	while (nr_sects) { +		unsigned int req_sects; +		sector_t end_sect; +  		bio = bio_alloc(gfp_mask, 1);  		if (!bio) {  			ret = -ENOMEM;  			break;  		} +		req_sects = min_t(sector_t, nr_sects, max_discard_sectors); + +		/* +		 * If splitting a request, and the next starting sector would be +		 * misaligned, stop the discard at the previous aligned sector. +		 */ +		end_sect = sector + req_sects; +		if (req_sects < nr_sects && (end_sect & mask) != alignment) { +			end_sect = +				round_down(end_sect - alignment, granularity) +				+ alignment; +			req_sects = end_sect - sector; +		} +  		bio->bi_sector = sector;  		bio->bi_end_io = bio_batch_end_io;  		bio->bi_bdev = bdev;  		bio->bi_private = &bb; -		if (nr_sects > max_discard_sectors) { -			bio->bi_size = max_discard_sectors << 9; -			nr_sects -= max_discard_sectors; -			sector += max_discard_sectors; -		} else { -			bio->bi_size = nr_sects << 9; -			nr_sects = 0; -		} +		bio->bi_size = req_sects << 9; +		nr_sects -= req_sects; +		sector = end_sect;  		atomic_inc(&bb.done);  		submit_bio(type, bio); diff --git a/block/blk-merge.c b/block/blk-merge.c index 160035f5488..e76279e4116 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -110,6 +110,49 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,  	return 0;  } +static void +__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec, +		     struct scatterlist *sglist, struct bio_vec **bvprv, +		     struct scatterlist **sg, int *nsegs, int *cluster) +{ + +	int nbytes = bvec->bv_len; + +	if (*bvprv && *cluster) { +		if ((*sg)->length + nbytes > queue_max_segment_size(q)) +			goto new_segment; + +		if (!BIOVEC_PHYS_MERGEABLE(*bvprv, bvec)) +			goto new_segment; +		if (!BIOVEC_SEG_BOUNDARY(q, *bvprv, bvec)) +			goto new_segment; + +		(*sg)->length += nbytes; +	} else { +new_segment: +		if (!*sg) +			*sg = sglist; +		else { +			/* +			 * If the driver previously mapped a shorter +			 * list, we could see a termination bit +			 * prematurely unless it fully inits the sg +			 * table on each mapping. We KNOW that there +			 * must be more entries here or the driver +			 * would be buggy, so force clear the +			 * termination bit to avoid doing a full +			 * sg_init_table() in drivers for each command. +			 */ +			(*sg)->page_link &= ~0x02; +			*sg = sg_next(*sg); +		} + +		sg_set_page(*sg, bvec->bv_page, nbytes, bvec->bv_offset); +		(*nsegs)++; +	} +	*bvprv = bvec; +} +  /*   * map a request to scatterlist, return number of sg entries setup. Caller   * must make sure sg can hold rq->nr_phys_segments entries @@ -131,41 +174,8 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,  	bvprv = NULL;  	sg = NULL;  	rq_for_each_segment(bvec, rq, iter) { -		int nbytes = bvec->bv_len; - -		if (bvprv && cluster) { -			if (sg->length + nbytes > queue_max_segment_size(q)) -				goto new_segment; - -			if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) -				goto new_segment; -			if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) -				goto new_segment; - -			sg->length += nbytes; -		} else { -new_segment: -			if (!sg) -				sg = sglist; -			else { -				/* -				 * If the driver previously mapped a shorter -				 * list, we could see a termination bit -				 * prematurely unless it fully inits the sg -				 * table on each mapping. We KNOW that there -				 * must be more entries here or the driver -				 * would be buggy, so force clear the -				 * termination bit to avoid doing a full -				 * sg_init_table() in drivers for each command. -				 */ -				sg->page_link &= ~0x02; -				sg = sg_next(sg); -			} - -			sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset); -			nsegs++; -		} -		bvprv = bvec; +		__blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg, +				     &nsegs, &cluster);  	} /* segments in rq */ @@ -199,6 +209,43 @@ new_segment:  }  EXPORT_SYMBOL(blk_rq_map_sg); +/** + * blk_bio_map_sg - map a bio to a scatterlist + * @q: request_queue in question + * @bio: bio being mapped + * @sglist: scatterlist being mapped + * + * Note: + *    Caller must make sure sg can hold bio->bi_phys_segments entries + * + * Will return the number of sg entries setup + */ +int blk_bio_map_sg(struct request_queue *q, struct bio *bio, +		   struct scatterlist *sglist) +{ +	struct bio_vec *bvec, *bvprv; +	struct scatterlist *sg; +	int nsegs, cluster; +	unsigned long i; + +	nsegs = 0; +	cluster = blk_queue_cluster(q); + +	bvprv = NULL; +	sg = NULL; +	bio_for_each_segment(bvec, bio, i) { +		__blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg, +				     &nsegs, &cluster); +	} /* segments in bio */ + +	if (sg) +		sg_mark_end(sg); + +	BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments); +	return nsegs; +} +EXPORT_SYMBOL(blk_bio_map_sg); +  static inline int ll_new_hw_segment(struct request_queue *q,  				    struct request *req,  				    struct bio *bio) diff --git a/block/genhd.c b/block/genhd.c index cac7366957c..d839723303c 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -835,7 +835,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)  static void *show_partition_start(struct seq_file *seqf, loff_t *pos)  { -	static void *p; +	void *p;  	p = disk_seqf_start(seqf, pos);  	if (!IS_ERR_OR_NULL(p) && !*pos) 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/Kconfig b/drivers/ata/Kconfig index 2be8ef1d309..27cecd313e7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -115,7 +115,7 @@ config SATA_SIL24  	  If unsure, say N.  config ATA_SFF -	bool "ATA SFF support" +	bool "ATA SFF support (for legacy IDE and PATA)"  	default y  	help  	  This option adds support for ATA controllers with SFF diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 062e6a1a248..7862d17976b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -256,10 +256,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {  	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */  	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */  	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ +	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ +	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ +	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */  	/* 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 */ @@ -385,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 }, @@ -392,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/ata/ahci.h b/drivers/ata/ahci.h index c2594ddf25b..57eb1c212a4 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -320,6 +320,7 @@ extern struct device_attribute *ahci_sdev_attrs[];  extern struct ata_port_operations ahci_ops;  extern struct ata_port_operations ahci_pmp_retry_srst_ops; +unsigned int ahci_dev_classify(struct ata_port *ap);  void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,  			u32 opts);  void ahci_save_initial_config(struct device *dev, diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3c809bfbccf..ef773e12af7 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -329,6 +329,14 @@ static const struct pci_device_id piix_pci_tbl[] = {  	{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },  	/* SATA Controller IDE (Lynx Point) */  	{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, +	/* SATA Controller IDE (Lynx Point-LP) */ +	{ 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },  	/* SATA Controller IDE (DH89xxCC) */  	{ 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },  	{ }	/* terminate list */ diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index f9eaa82311a..555c07afa05 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1139,7 +1139,7 @@ static void ahci_dev_config(struct ata_device *dev)  	}  } -static unsigned int ahci_dev_classify(struct ata_port *ap) +unsigned int ahci_dev_classify(struct ata_port *ap)  {  	void __iomem *port_mmio = ahci_port_base(ap);  	struct ata_taskfile tf; @@ -1153,6 +1153,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)  	return ata_dev_classify(&tf);  } +EXPORT_SYMBOL_GPL(ahci_dev_classify);  void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,  			u32 opts) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 902b5a45717..fd9ecf74e63 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -60,17 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap)  	if (ap->flags & ATA_FLAG_ACPI_SATA)  		return NULL; -	/* -	 * If acpi bind operation has already happened, we can get the handle -	 * for the port by checking the corresponding scsi_host device's -	 * firmware node, otherwise we will need to find out the handle from -	 * its parent's acpi node. -	 */ -	if (ap->scsi_host) -		return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev); -	else -		return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), -				ap->port_no); +	return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no);  }  EXPORT_SYMBOL(ata_ap_acpi_handle); @@ -1101,6 +1091,9 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle)  	if (!*handle)  		return -ENODEV; +	if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) +		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; +  	return 0;  } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fadd5866d40..8e1039c8e15 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4062,7 +4062,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {  	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },  	{ "SAMSUNG CD-ROM SN-124", "N001",	ATA_HORKAGE_NODMA },  	{ "Seagate STT20000A", NULL,		ATA_HORKAGE_NODMA }, -	{ "2GB ATA Flash Disk", "ADMA428M",	ATA_HORKAGE_NODMA }, +	{ " 2GB ATA Flash Disk", "ADMA428M",	ATA_HORKAGE_NODMA },  	/* Odd clown on sil3726/4726 PMPs */  	{ "Config  Disk",	NULL,		ATA_HORKAGE_DISABLE }, @@ -4128,6 +4128,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {  	/* Devices that do not need bridging limits applied */  	{ "MTRON MSP-SATA*",		NULL,	ATA_HORKAGE_BRIDGE_OK, }, +	{ "BUFFALO HD-QSU2/R5",		NULL,	ATA_HORKAGE_BRIDGE_OK, },  	/* Devices which aren't very happy with higher link speeds */  	{ "WD My Book",			NULL,	ATA_HORKAGE_1_5_GBPS, }, diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 361c75cea57..24e51056ac2 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -20,6 +20,7 @@  #include <linux/delay.h>  #include <scsi/scsi_host.h>  #include <linux/libata.h> +#include <linux/dmi.h>  #define DRV_NAME "pata_atiixp"  #define DRV_VERSION "0.4.6" @@ -33,11 +34,26 @@ enum {  	ATIIXP_IDE_UDMA_MODE 	= 0x56  }; +static const struct dmi_system_id attixp_cable_override_dmi_table[] = { +	{ +		/* Board has onboard PATA<->SATA converters */ +		.ident = "MSI E350DM-E33", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), +			DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"), +		}, +	}, +	{ } +}; +  static int atiixp_cable_detect(struct ata_port *ap)  {  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);  	u8 udma; +	if (dmi_check_system(attixp_cable_override_dmi_table)) +		return ATA_CBL_PATA40_SHORT; +  	/* Hack from drivers/ide/pci. Really we want to know how to do the  	   raw detection not play follow the bios mode guess */  	pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 78efb0306a4..34d94c762a1 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c @@ -250,7 +250,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size,  		return -EINVAL;  	/* Sanitise input arguments */ -	alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); +	alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);  	base = ALIGN(base, alignment);  	size = ALIGN(size, alignment);  	limit &= ~(alignment - 1); diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index ba91b408aba..d8456649674 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -889,6 +889,7 @@ struct bm_aio_ctx {  	unsigned int done;  	unsigned flags;  #define BM_AIO_COPY_PAGES	1 +#define BM_WRITE_ALL_PAGES	2  	int error;  	struct kref kref;  }; @@ -1059,7 +1060,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w  		if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)  			break;  		if (rw & WRITE) { -			if (bm_test_page_unchanged(b->bm_pages[i])) { +			if (!(flags & BM_WRITE_ALL_PAGES) && +			    bm_test_page_unchanged(b->bm_pages[i])) {  				dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i);  				continue;  			} @@ -1141,6 +1143,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)  }  /** + * drbd_bm_write_all() - Write the whole bitmap to its on disk location. + * @mdev:	DRBD device. + * + * Will write all pages. + */ +int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local) +{ +	return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0); +} + +/**   * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed.   * @mdev:	DRBD device.   * @upper_idx:	0: write all changed pages; +ve: page index to stop scanning for changed pages diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b2ca143d005..b953cc7c9c0 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1469,6 +1469,7 @@ extern int  drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr);  extern int  drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local);  extern int  drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);  extern int  drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); +extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local);  extern int  drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local);  extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev,  		unsigned long al_enr); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index dbe6135a2ab..f93a0320e95 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -79,6 +79,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);  static void md_sync_timer_fn(unsigned long data);  static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);  static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); +static void _tl_clear(struct drbd_conf *mdev);  MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "  	      "Lars Ellenberg <lars@linbit.com>"); @@ -432,19 +433,10 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)  	/* Actions operating on the disk state, also want to work on  	   requests that got barrier acked. */ -	switch (what) { -	case fail_frozen_disk_io: -	case restart_frozen_disk_io: -		list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { -			req = list_entry(le, struct drbd_request, tl_requests); -			_req_mod(req, what); -		} -	case connection_lost_while_pending: -	case resend: -		break; -	default: -		dev_err(DEV, "what = %d in _tl_restart()\n", what); +	list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { +		req = list_entry(le, struct drbd_request, tl_requests); +		_req_mod(req, what);  	}  } @@ -459,11 +451,16 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what)   */  void tl_clear(struct drbd_conf *mdev)  { +	spin_lock_irq(&mdev->req_lock); +	_tl_clear(mdev); +	spin_unlock_irq(&mdev->req_lock); +} + +static void _tl_clear(struct drbd_conf *mdev) +{  	struct list_head *le, *tle;  	struct drbd_request *r; -	spin_lock_irq(&mdev->req_lock); -  	_tl_restart(mdev, connection_lost_while_pending);  	/* we expect this list to be empty. */ @@ -482,7 +479,6 @@ void tl_clear(struct drbd_conf *mdev)  	memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); -	spin_unlock_irq(&mdev->req_lock);  }  void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) @@ -1476,12 +1472,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,  	if (ns.susp_fen) {  		/* case1: The outdate peer handler is successful: */  		if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) { -			tl_clear(mdev);  			if (test_bit(NEW_CUR_UUID, &mdev->flags)) {  				drbd_uuid_new_current(mdev);  				clear_bit(NEW_CUR_UUID, &mdev->flags);  			}  			spin_lock_irq(&mdev->req_lock); +			_tl_clear(mdev);  			_drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL);  			spin_unlock_irq(&mdev->req_lock);  		} diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fb9dce8daa2..edb490aad8b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -674,8 +674,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds  			 la_size_changed && md_moved ? "size changed and md moved" :  			 la_size_changed ? "size changed" : "md moved");  		/* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ -		err = drbd_bitmap_io(mdev, &drbd_bm_write, -				"size changed", BM_LOCKED_MASK); +		err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write, +				     "size changed", BM_LOCKED_MASK);  		if (err) {  			rv = dev_size_error;  			goto out; diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 910335c3092..01b2ac641c7 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what,  		break;  	case resend: +		/* Simply complete (local only) READs. */ +		if (!(req->rq_state & RQ_WRITE) && !req->w.cb) { +			_req_may_be_done(req, m); +			break; +		} +  		/* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK  		   before the connection loss (B&C only); only P_BARRIER_ACK was missing.  		   Trowing them out of the TL here by pretending we got a BARRIER_ACK @@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns  		req->private_bio = NULL;  	}  	if (rw == WRITE) { -		remote = 1; +		/* Need to replicate writes.  Unless it is an empty flush, +		 * which is better mapped to a DRBD P_BARRIER packet, +		 * also for drbd wire protocol compatibility reasons. */ +		if (unlikely(size == 0)) { +			/* The only size==0 bios we expect are empty flushes. */ +			D_ASSERT(bio->bi_rw & REQ_FLUSH); +			remote = 0; +		} else +			remote = 1;  	} else {  		/* READ || READA */  		if (local) { @@ -870,8 +884,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns  	 * extent.  This waits for any resync activity in the corresponding  	 * resync extent to finish, and, if necessary, pulls in the target  	 * extent into the activity log, which involves further disk io because -	 * of transactional on-disk meta data updates. */ -	if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { +	 * of transactional on-disk meta data updates. +	 * Empty flushes don't need to go into the activity log, they can only +	 * flush data for pending writes which are already in there. */ +	if (rw == WRITE && local && size +	&& !test_bit(AL_SUSPENDED, &mdev->flags)) {  		req->rq_state |= RQ_IN_ACT_LOG;  		drbd_al_begin_io(mdev, sector);  	} @@ -994,7 +1011,10 @@ allocate_barrier:  	if (rw == WRITE && _req_conflicts(req))  		goto fail_conflicting; -	list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); +	/* no point in adding empty flushes to the transfer log, +	 * they are mapped to drbd barriers already. */ +	if (likely(size!=0)) +		list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);  	/* NOTE remote first: to get the concurrent write detection right,  	 * we must register the request before start of local IO.  */ @@ -1014,6 +1034,14 @@ allocate_barrier:  	    mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)  		maybe_pull_ahead(mdev); +	/* If this was a flush, queue a drbd barrier/start a new epoch. +	 * Unless the current epoch was empty anyways, or we are not currently +	 * replicating, in which case there is no point. */ +	if (unlikely(bio->bi_rw & REQ_FLUSH) +		&& mdev->newest_tle->n_writes +		&& drbd_should_do_remote(mdev->state)) +		queue_barrier(mdev); +  	spin_unlock_irq(&mdev->req_lock);  	kfree(b); /* if someone else has beaten us to it... */ 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/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 17fa04d08be..b47034e650a 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -218,7 +218,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)  	policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); -	if (atomic_inc_return(&freq_table_users) == 1) +	if (!freq_table)  		result = opp_init_cpufreq_table(mpu_dev, &freq_table);  	if (result) { @@ -227,6 +227,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)  		goto fail_ck;  	} +	atomic_inc_return(&freq_table_users); +  	result = cpufreq_frequency_table_cpuinfo(policy, freq_table);  	if (result)  		goto fail_table; diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 53c8c51d588..93d14070141 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c @@ -63,7 +63,7 @@ static void caam_jr_dequeue(unsigned long devarg)  		head = ACCESS_ONCE(jrp->head); -		spin_lock_bh(&jrp->outlock); +		spin_lock(&jrp->outlock);  		sw_idx = tail = jrp->tail;  		hw_idx = jrp->out_ring_read_index; @@ -115,7 +115,7 @@ static void caam_jr_dequeue(unsigned long devarg)  			jrp->tail = tail;  		} -		spin_unlock_bh(&jrp->outlock); +		spin_unlock(&jrp->outlock);  		/* Finally, execute user's callback */  		usercall(dev, userdesc, userstatus, userarg); @@ -236,14 +236,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,  		return -EIO;  	} -	spin_lock(&jrp->inplock); +	spin_lock_bh(&jrp->inplock);  	head = jrp->head;  	tail = ACCESS_ONCE(jrp->tail);  	if (!rd_reg32(&jrp->rregs->inpring_avail) ||  	    CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { -		spin_unlock(&jrp->inplock); +		spin_unlock_bh(&jrp->inplock);  		dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE);  		return -EBUSY;  	} @@ -265,7 +265,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,  	wr_reg32(&jrp->rregs->inpring_jobadd, 1); -	spin_unlock(&jrp->inplock); +	spin_unlock_bh(&jrp->inplock);  	return 0;  } 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/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9c4befb5a8..df14358d7fa 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -821,8 +821,8 @@ static int hifn_register_rng(struct hifn_device *dev)  	/*  	 * We must wait at least 256 Pk_clk cycles between two reads of the rng.  	 */ -	dev->rng_wait_time	= DIV_ROUND_UP(NSEC_PER_SEC, dev->pk_clk_freq) * -				  256; +	dev->rng_wait_time	= DIV_ROUND_UP_ULL(NSEC_PER_SEC, +						   dev->pk_clk_freq) * 256;  	dev->rng.name		= dev->name;  	dev->rng.data_present	= hifn_rng_data_present, diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 758a871fcfd..e21387e2da5 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/gpio/Kconfig b/drivers/gpio/Kconfig index b16c8a72a2e..ba7926f5c09 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -294,7 +294,7 @@ config GPIO_MAX732X_IRQ  config GPIO_MC9S08DZ60  	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" -	depends on I2C && MACH_MX35_3DS +	depends on I2C=y && MACH_MX35_3DS  	help  	  Select this to enable the MC9S08DZ60 GPIO driver diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index ae37181798b..ec48ed51262 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -247,9 +247,9 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p)  	p->irq_base = irq_alloc_descs(pdata->irq_base, 0,  				      pdata->number_of_pins, numa_node_id()); -	if (IS_ERR_VALUE(p->irq_base)) { +	if (p->irq_base < 0) {  		dev_err(&pdev->dev, "cannot get irq_desc\n"); -		return -ENXIO; +		return p->irq_base;  	}  	pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n",  		 pdata->gpio_base, pdata->number_of_pins, p->irq_base); diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index e97016af644..b62d443e9a5 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -170,6 +170,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)  	rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;  	rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; +	rdc321x_gpio_dev->chip.owner = THIS_MODULE;  	rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;  	rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;  	rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a18c4aa68b1..f1a45997aea 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -82,7 +82,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,  	gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);  	of_node_put(gg_data.gpiospec.np); -	pr_debug("%s exited with status %d\n", __func__, ret); +	pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio);  	return gg_data.out_gpio;  }  EXPORT_SYMBOL(of_get_named_gpio_flags); 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/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6..6fbfc244748 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,  	if (!drm_core_check_feature(dev, DRIVER_MODESET))  		return -EINVAL; -	if (!req->flags) +	if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))  		return -EINVAL;  	mutex_lock(&dev->mode_config.mutex); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e8..b7ee230572b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -87,6 +87,9 @@ static struct edid_quirk {  	int product_id;  	u32 quirks;  } edid_quirk_list[] = { +	/* ASUS VW222S */ +	{ "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, +  	/* Acer AL1706 */  	{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },  	/* Acer F51 */ 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/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156..8033526bb53 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,  	    (struct drm_connector **) (psb_intel_crtc + 1);  	psb_intel_crtc->mode_set.num_connectors = 0;  	psb_intel_cursor_init(dev, psb_intel_crtc); + +	/* Set to true so that the pipe is forced off on initial config. */ +	psb_intel_crtc->active = true;  }  int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, 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_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d9a5372ec56..60815b861ec 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)  	/* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024  	 * entries. For aliasing ppgtt support we just steal them at the end for  	 * now. */ -	first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; +	first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES;  	ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);  	if (!ppgtt) 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 a69a3d0d3ac..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");  } @@ -1384,11 +1385,12 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,  				     enum pipe pipe, int reg)  {  	u32 val = I915_READ(reg); -	WARN(hdmi_pipe_enabled(dev_priv, val, pipe), +	WARN(hdmi_pipe_enabled(dev_priv, pipe, val),  	     "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");  } @@ -1404,13 +1406,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,  	reg = PCH_ADPA;  	val = I915_READ(reg); -	WARN(adpa_pipe_enabled(dev_priv, val, pipe), +	WARN(adpa_pipe_enabled(dev_priv, pipe, val),  	     "PCH VGA enabled on transcoder %c, should be disabled\n",  	     pipe_name(pipe));  	reg = PCH_LVDS;  	val = I915_READ(reg); -	WARN(lvds_pipe_enabled(dev_priv, val, pipe), +	WARN(lvds_pipe_enabled(dev_priv, pipe, val),  	     "PCH LVDS enabled on transcoder %c, should be disabled\n",  	     pipe_name(pipe)); @@ -1872,7 +1874,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,  			     enum pipe pipe, int reg)  {  	u32 val = I915_READ(reg); -	if (hdmi_pipe_enabled(dev_priv, val, pipe)) { +	if (hdmi_pipe_enabled(dev_priv, pipe, val)) {  		DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",  			      reg, pipe);  		I915_WRITE(reg, val & ~PORT_ENABLE); @@ -1894,12 +1896,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,  	reg = PCH_ADPA;  	val = I915_READ(reg); -	if (adpa_pipe_enabled(dev_priv, val, pipe)) +	if (adpa_pipe_enabled(dev_priv, pipe, val))  		I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);  	reg = PCH_LVDS;  	val = I915_READ(reg); -	if (lvds_pipe_enabled(dev_priv, val, pipe)) { +	if (lvds_pipe_enabled(dev_priv, pipe, val)) {  		DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);  		I915_WRITE(reg, val & ~LVDS_PORT_EN);  		POSTING_READ(reg); 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_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e344..e9a6f6aaed8 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = {  			DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),  		},  	}, +	{ +		.callback = intel_no_lvds_dmi_callback, +		.ident = "Gigabyte GA-D525TUD", +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), +			DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), +		}, +	},  	{ }	/* terminating entry */  }; 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/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d9..7644f31a377 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,  	switch (fb->pixel_format) {  	case DRM_FORMAT_XBGR8888: -		sprctl |= SPRITE_FORMAT_RGBX888; +		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;  		pixel_size = 4;  		break;  	case DRM_FORMAT_XRGB8888: -		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; +		sprctl |= SPRITE_FORMAT_RGBX888;  		pixel_size = 4;  		break;  	case DRM_FORMAT_YUYV: 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/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1866dbb4997..c61014442aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -736,9 +736,11 @@ nouveau_card_init(struct drm_device *dev)  			}  			break;  		case NV_C0: -			nvc0_copy_create(dev, 1); +			if (!(nv_rd32(dev, 0x022500) & 0x00000200)) +				nvc0_copy_create(dev, 1);  		case NV_D0: -			nvc0_copy_create(dev, 0); +			if (!(nv_rd32(dev, 0x022500) & 0x00000100)) +				nvc0_copy_create(dev, 0);  			break;  		default:  			break; 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 f4d4505fe83..e721e3087b9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)  		radeon_crtc->enabled = true;  		/* adjust pm to dpms changes BEFORE enabling crtcs */  		radeon_pm_compute_clocks(rdev); -		/* disable crtc pair power gating before programming */  		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)  			atombios_powergate_crtc(crtc, ATOM_DISABLE);  		atombios_enable_crtc(crtc, ATOM_ENABLE); @@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)  			atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);  		atombios_enable_crtc(crtc, ATOM_DISABLE);  		radeon_crtc->enabled = false; -		/* power gating is per-pair */ -		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { -			struct drm_crtc *other_crtc; -			struct radeon_crtc *other_radeon_crtc; -			list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { -				other_radeon_crtc = to_radeon_crtc(other_crtc); -				if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || -				    ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || -				    ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || -				    ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || -				    ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || -				    ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { -					/* if both crtcs in the pair are off, enable power gating */ -					if (other_radeon_crtc->enabled == false) -						atombios_powergate_crtc(crtc, ATOM_ENABLE); -					break; -				} -			} -		} +		if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) +			atombios_powergate_crtc(crtc, ATOM_ENABLE);  		/* adjust pm to dpms changes AFTER disabling crtcs */  		radeon_pm_compute_clocks(rdev);  		break; @@ -1497,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) { @@ -1516,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 @@ -1549,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;  } @@ -1682,9 +1759,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  	struct drm_device *dev = crtc->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_atom_ss ss; +	int i;  	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); +	for (i = 0; i < rdev->num_crtc; i++) { +		if (rdev->mode_info.crtcs[i] && +		    rdev->mode_info.crtcs[i]->enabled && +		    i != radeon_crtc->crtc_id && +		    radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { +			/* one other crtc is using this pll don't turn +			 * off the pll +			 */ +			goto done; +		} +	} +  	switch (radeon_crtc->pll_id) {  	case ATOM_PPLL1:  	case ATOM_PPLL2: @@ -1701,7 +1791,8 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)  	default:  		break;  	} -	radeon_crtc->pll_id = -1; +done: +	radeon_crtc->pll_id = ATOM_PPLL_INVALID;  }  static const struct drm_crtc_helper_funcs atombios_helper_funcs = { @@ -1750,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/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33..3623b98ed3f 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_connector *radeon_connector = to_radeon_connector(connector);  	int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; +	u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); +	u8 tmp;  	if (!ASIC_IS_DCE4(rdev))  		return panel_mode; -	if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == -	    ENCODER_OBJECT_ID_NUTMEG) -		panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; -	else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == -		 ENCODER_OBJECT_ID_TRAVIS) { -		u8 id[6]; -		int i; -		for (i = 0; i < 6; i++) -			id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); -		if (id[0] == 0x73 && -		    id[1] == 0x69 && -		    id[2] == 0x76 && -		    id[3] == 0x61 && -		    id[4] == 0x72 && -		    id[5] == 0x54) +	if (dp_bridge != ENCODER_OBJECT_ID_NONE) { +		/* DP bridge chips */ +		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); +		if (tmp & 1) +			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; +		else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || +			 (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))  			panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;  		else -			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; +			panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;  	} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { -		u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); +		/* eDP */ +		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);  		if (tmp & 1)  			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;  	} diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269..6e8803a1170 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +	struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);  	struct radeon_connector *radeon_connector = NULL;  	struct radeon_connector_atom_dig *radeon_dig_connector = NULL; @@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	switch (mode) {  	case DRM_MODE_DPMS_ON: -		/* some early dce3.2 boards have a bug in their transmitter control table */ -		if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || -		    ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { -			if (ASIC_IS_DCE6(rdev)) { -				/* It seems we need to call ATOM_ENCODER_CMD_SETUP again -				 * before reenabling encoder on DPMS ON, otherwise we never -				 * get picture -				 */ -				atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { +			if (!connector) +				dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; +			else +				dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); + +			/* setup and enable the encoder */ +			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +			atombios_dig_encoder_setup(encoder, +						   ATOM_ENCODER_CMD_SETUP_PANEL_MODE, +						   dig->panel_mode); +			if (ext_encoder) { +				if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) +					atombios_external_encoder_setup(encoder, ext_encoder, +									EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);  			}  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} else { +		} else if (ASIC_IS_DCE4(rdev)) { +			/* setup and enable the encoder */ +			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); +			/* enable the transmitter */ +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); +		} else { +			/* setup and enable the encoder and transmitter */ +			atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); +			/* some early dce3.2 boards have a bug in their transmitter control table */ +			if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) +				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);  		}  		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {  			if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { @@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)  	case DRM_MODE_DPMS_STANDBY:  	case DRM_MODE_DPMS_SUSPEND:  	case DRM_MODE_DPMS_OFF: -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) +		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { +			/* disable the transmitter */  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -		else +		} else if (ASIC_IS_DCE4(rdev)) { +			/* disable the transmitter */ +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); +		} else { +			/* disable the encoder and transmitter */  			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); +			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); +		}  		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {  			if (ASIC_IS_DCE4(rdev))  				atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); @@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);  	struct drm_encoder *test_encoder; -	struct radeon_encoder_atom_dig *dig; +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  	uint32_t dig_enc_in_use = 0; -	/* DCE4/5 */ -	if (ASIC_IS_DCE4(rdev)) { -		dig = radeon_encoder->enc_priv; -		if (ASIC_IS_DCE41(rdev)) { +	if (ASIC_IS_DCE6(rdev)) { +		/* DCE6 */ +		switch (radeon_encoder->encoder_id) { +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: +			if (dig->linkb) +				return 1; +			else +				return 0; +			break; +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: +			if (dig->linkb) +				return 3; +			else +				return 2; +			break; +		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: +			if (dig->linkb) +				return 5; +			else +				return 4; +			break; +		} +	} else if (ASIC_IS_DCE4(rdev)) { +		/* DCE4/5 */ +		if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {  			/* ontario follows DCE4 */  			if (rdev->family == CHIP_PALM) {  				if (dig->linkb) @@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);  	radeon_encoder->pixel_clock = adjusted_mode->clock; +	/* need to call this here rather than in prepare() since we need some crtc info */ +	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); +  	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {  		if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))  			atombios_yuv_setup(encoder, true); @@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { -			struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); -			struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - -			if (!connector) -				dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; -			else -				dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); - -			/* setup and enable the encoder */ -			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); -			atombios_dig_encoder_setup(encoder, -						   ATOM_ENCODER_CMD_SETUP_PANEL_MODE, -						   dig->panel_mode); -		} else if (ASIC_IS_DCE4(rdev)) { -			/* disable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			/* setup and enable the encoder */ -			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - -			/* enable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} else { -			/* disable the encoder and transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); - -			/* setup and enable the encoder and transmitter */ -			atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); -		} +		/* handled in dpms */  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DDI:  	case ENCODER_OBJECT_ID_INTERNAL_DVO1: @@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  		break;  	} -	if (ext_encoder) { -		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) -			atombios_external_encoder_setup(encoder, ext_encoder, -							EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); -		else -			atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); -	} -  	atombios_apply_encoder_quirks(encoder, adjusted_mode);  	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { @@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)  	}  	radeon_atom_output_lock(encoder, true); -	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);  	if (connector) {  		struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)  static void radeon_atom_encoder_commit(struct drm_encoder *encoder)  { +	/* need to call this here as we need the crtc set up */  	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON);  	radeon_atom_output_lock(encoder, false);  } @@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		if (ASIC_IS_DCE4(rdev)) -			/* disable the transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -		else { -			/* disable the encoder and transmitter */ -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); -			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); -		} +		/* handled in dpms */  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DDI:  	case ENCODER_OBJECT_ID_INTERNAL_DVO1: diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ab74e6b149e..f37676d7f21 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -63,6 +63,7 @@ struct r600_cs_track {  	u32			cb_color_size_idx[8]; /* unused */  	u32			cb_target_mask;  	u32			cb_shader_mask;  /* unused */ +	bool			is_resolve;  	u32			cb_color_size[8];  	u32			vgt_strmout_en;  	u32			vgt_strmout_buffer_en; @@ -315,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track)  		track->cb_color_bo[i] = NULL;  		track->cb_color_bo_offset[i] = 0xFFFFFFFF;  		track->cb_color_bo_mc[i] = 0xFFFFFFFF; +		track->cb_color_frag_bo[i] = NULL; +		track->cb_color_frag_offset[i] = 0xFFFFFFFF; +		track->cb_color_tile_bo[i] = NULL; +		track->cb_color_tile_offset[i] = 0xFFFFFFFF; +		track->cb_color_mask[i] = 0xFFFFFFFF;  	} +	track->is_resolve = false; +	track->nsamples = 16; +	track->log_nsamples = 4;  	track->cb_target_mask = 0xFFFFFFFF;  	track->cb_shader_mask = 0xFFFFFFFF;  	track->cb_dirty = true; @@ -352,6 +361,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	volatile u32 *ib = p->ib.ptr;  	unsigned array_mode;  	u32 format; +	/* When resolve is used, the second colorbuffer has always 1 sample. */ +	unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;  	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];  	format = G_0280A0_FORMAT(track->cb_color_info[i]); @@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	array_check.group_size = track->group_size;  	array_check.nbanks = track->nbanks;  	array_check.npipes = track->npipes; -	array_check.nsamples = track->nsamples; +	array_check.nsamples = nsamples;  	array_check.blocksize = r600_fmt_get_blocksize(format);  	if (r600_get_array_mode_alignment(&array_check,  					  &pitch_align, &height_align, &depth_align, &base_align)) { @@ -421,7 +432,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	/* check offset */  	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * -	      r600_fmt_get_blocksize(format) * track->nsamples; +	      r600_fmt_get_blocksize(format) * nsamples;  	switch (array_mode) {  	default:  	case V_0280A0_ARRAY_LINEAR_GENERAL: @@ -792,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)  	 */  	if (track->cb_dirty) {  		tmp = track->cb_target_mask; + +		/* We must check both colorbuffers for RESOLVE. */ +		if (track->is_resolve) { +			tmp |= 0xff; +		} +  		for (i = 0; i < 8; i++) {  			if ((tmp >> (i * 4)) & 0xF) {  				/* at least one component is enabled */ @@ -1281,6 +1298,11 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  		track->nsamples = 1 << tmp;  		track->cb_dirty = true;  		break; +	case R_028808_CB_COLOR_CONTROL: +		tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); +		track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; +		track->cb_dirty = true; +		break;  	case R_0280A0_CB_COLOR0_INFO:  	case R_0280A4_CB_COLOR1_INFO:  	case R_0280A8_CB_COLOR2_INFO: @@ -1416,7 +1438,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  	case R_028118_CB_COLOR6_MASK:  	case R_02811C_CB_COLOR7_MASK:  		tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; -		track->cb_color_mask[tmp] = ib[idx]; +		track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx);  		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) {  			track->cb_dirty = true;  		} diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bdb69a63062..fa6f37099ba 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -66,6 +66,14 @@  #define	CC_RB_BACKEND_DISABLE				0x98F4  #define		BACKEND_DISABLE(x)				((x) << 16) +#define R_028808_CB_COLOR_CONTROL			0x28808 +#define   S_028808_SPECIAL_OP(x)                       (((x) & 0x7) << 4) +#define   G_028808_SPECIAL_OP(x)                       (((x) >> 4) & 0x7) +#define   C_028808_SPECIAL_OP                          0xFFFFFF8F +#define     V_028808_SPECIAL_NORMAL                     0x00 +#define     V_028808_SPECIAL_DISABLE                    0x01 +#define     V_028808_SPECIAL_RESOLVE_BOX                0x07 +  #define	CB_COLOR0_BASE					0x28040  #define	CB_COLOR1_BASE					0x28044  #define	CB_COLOR2_BASE					0x28048 diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d2e243867ac..7a3daebd732 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1051,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev,  	if (rdev->flags & RADEON_IS_AGP)  		rdev->need_dma32 = true;  	if ((rdev->flags & RADEON_IS_PCI) && -	    (rdev->family < CHIP_RS400)) +	    (rdev->family <= CHIP_RS740))  		rdev->need_dma32 = true;  	dma_bits = rdev->need_dma32 ? 32 : 40; @@ -1346,12 +1346,15 @@ retry:  		for (i = 0; i < RADEON_NUM_RINGS; ++i) {  			radeon_ring_restore(rdev, &rdev->ring[i],  					    ring_sizes[i], ring_data[i]); +			ring_sizes[i] = 0; +			ring_data[i] = NULL;  		}  		r = radeon_ib_ring_tests(rdev);  		if (r) {  			dev_err(rdev->dev, "ib ring test failed (%d).\n", r);  			if (saved) { +				saved = false;  				radeon_suspend(rdev);  				goto retry;  			} diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 27d22d709c9..8c593ea82c4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -63,9 +63,10 @@   *   2.19.0 - r600-eg: MSAA textures   *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query   *   2.21.0 - r600-r700: FMASK and CMASK + *   2.22.0 - r600 only: RESOLVE_BOX allowed   */  #define KMS_DRIVER_MAJOR	2 -#define KMS_DRIVER_MINOR	21 +#define KMS_DRIVER_MINOR	22  #define KMS_DRIVER_PATCHLEVEL	0  int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);  int radeon_driver_unload_kms(struct drm_device *dev); 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/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index f93e45d869f..20bfbda7b3f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -744,7 +744,6 @@ r600 0x9400  0x00028C38 CB_CLRCMP_DST  0x00028C3C CB_CLRCMP_MSK  0x00028C34 CB_CLRCMP_SRC -0x00028808 CB_COLOR_CONTROL  0x0002842C CB_FOG_BLUE  0x00028428 CB_FOG_GREEN  0x00028424 CB_FOG_RED 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/hid/hid-core.c b/drivers/hid/hid-core.c index 60ea284407c..8bcd168fffa 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -996,7 +996,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,  	struct hid_driver *hdrv = hid->driver;  	int ret; -	hid_dump_input(hid, usage, value); +	if (!list_empty(&hid->debug_list)) +		hid_dump_input(hid, usage, value);  	if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {  		ret = hdrv->event(hid, field, usage, value); @@ -1558,7 +1559,9 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, - 	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, +#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD) +	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, +#endif  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, @@ -1624,7 +1627,6 @@ static const struct hid_device_id hid_have_special_driver[] = {  	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, -	{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },  	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 0f9c146fc00..4d524b5f52f 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -439,7 +439,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)  	struct dj_report *dj_report;  	int retval; -	dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); +	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);  	if (!dj_report)  		return -ENOMEM;  	dj_report->report_id = REPORT_ID_DJ_SHORT; @@ -456,7 +456,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,  	struct dj_report *dj_report;  	int retval; -	dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); +	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);  	if (!dj_report)  		return -ENOMEM;  	dj_report->report_id = REPORT_ID_DJ_SHORT; diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 903eef3d3e1..991e85c7325 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -70,6 +70,7 @@ static const struct hid_blacklist {  	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, +	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },  	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 351d1f4593e..4ee57894872 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = {  		.matches = {  			DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58")  		} +	}, { +		/* Old interface reads the same sensor for fan0 and fan1 */ +		.ident = "Asus M5A78L", +		.matches = { +			DMI_MATCH(DMI_BOARD_NAME, "M5A78L") +		}  	},  	{ }  }; 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/ide/ide-pm.c b/drivers/ide/ide-pm.c index 92406097efe..8d1e32d7cd9 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -4,7 +4,7 @@  int generic_ide_suspend(struct device *dev, pm_message_t mesg)  { -	ide_drive_t *drive = dev_get_drvdata(dev); +	ide_drive_t *drive = to_ide_device(dev);  	ide_drive_t *pair = ide_get_pair_dev(drive);  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq; @@ -40,7 +40,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)  int generic_ide_resume(struct device *dev)  { -	ide_drive_t *drive = dev_get_drvdata(dev); +	ide_drive_t *drive = to_ide_device(dev);  	ide_drive_t *pair = ide_get_pair_dev(drive);  	ide_hwif_t *hwif = drive->hwif;  	struct request *rq; 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/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25..ce68e361558 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)  	/* Inhibit KDI and KRI interrupts. */  	reg_val = readw(keypad->mmio_base + KPSR);  	reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); +	reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;  	writew(reg_val, keypad->mmio_base + KPSR);  	/* Colums as open drain and disable all rows */ @@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)  	input_set_drvdata(input_dev, keypad);  	/* Ensure that the keypad will stay dormant until opened */ +	clk_enable(keypad->clk);  	imx_keypad_inhibit(keypad); +	clk_disable(keypad->clk);  	error = request_irq(irq, imx_keypad_irq_handler, 0,  			    pdev->name, keypad); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82..6918773ce02 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -177,6 +177,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {  		},  	},  	{ +		/* Gigabyte T1005 - defines wrong chassis type ("Other") */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +			DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), +		}, +	}, +	{ +		/* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), +			DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), +		}, +	}, +	{  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),  			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 002041975de..532d067a9e0 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1848,7 +1848,10 @@ static const struct wacom_features wacom_features_0x2A =  	{ "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS,  44704, 27940, 2047,  	  63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };  static const struct wacom_features wacom_features_0xF4 = -	{ "Wacom Cintiq 24HD",    WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, +	{ "Wacom Cintiq 24HD",       WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, +	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; +static const struct wacom_features wacom_features_0xF8 = +	{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047,  	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };  static const struct wacom_features wacom_features_0x3F =  	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023, @@ -2091,6 +2094,7 @@ const struct usb_device_id wacom_ids[] = {  	{ USB_DEVICE_WACOM(0xEF) },  	{ USB_DEVICE_WACOM(0x47) },  	{ USB_DEVICE_WACOM(0xF4) }, +	{ USB_DEVICE_WACOM(0xF8) },  	{ USB_DEVICE_WACOM(0xFA) },  	{ USB_DEVICE_LENOVO(0x6004) },  	{ } diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 9afc777a40a..b06a5e3a665 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -602,6 +602,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)  {  	if (tsdata->debug_dir)  		debugfs_remove_recursive(tsdata->debug_dir); +	kfree(tsdata->raw_buffer);  }  #else @@ -843,7 +844,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client)  	if (gpio_is_valid(pdata->reset_pin))  		gpio_free(pdata->reset_pin); -	kfree(tsdata->raw_buffer);  	kfree(tsdata);  	return 0; 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/mmc/card/block.c b/drivers/mmc/card/block.c index f1c84decb19..172a768036d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)  		/* complete ongoing async transfer before issuing discard */  		if (card->host->areq)  			mmc_blk_issue_rw_rq(mq, NULL); -		if (req->cmd_flags & REQ_SECURE) +		if (req->cmd_flags & REQ_SECURE && +			!(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))  			ret = mmc_blk_issue_secdiscard_rq(mq, req);  		else  			ret = mmc_blk_issue_discard_rq(mq, req); @@ -1716,6 +1717,7 @@ force_ro_fail:  #define CID_MANFID_SANDISK	0x2  #define CID_MANFID_TOSHIBA	0x11  #define CID_MANFID_MICRON	0x13 +#define CID_MANFID_SAMSUNG	0x15  static const struct mmc_fixup blk_fixups[] =  { @@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] =  	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,  		  MMC_QUIRK_LONG_READ_TIME), +	/* +	 * On these Samsung MoviNAND parts, performing secure erase or +	 * secure trim can result in unrecoverable corruption due to a +	 * firmware bug. +	 */ +	MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +	MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, +		  MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), +  	END_FIXUP  }; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 322412cec4e..a53c7c478e0 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -81,6 +81,7 @@ struct atmel_mci_caps {  	bool	has_bad_data_ordering;  	bool	need_reset_after_xfer;  	bool	need_blksz_mul_4; +	bool	need_notbusy_for_read_ops;  };  struct atmel_mci_dma { @@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv)  				__func__);  			atmci_set_completed(host, EVENT_XFER_COMPLETE); -			if (host->data->flags & MMC_DATA_WRITE) { +			if (host->caps.need_notbusy_for_read_ops || +			   (host->data->flags & MMC_DATA_WRITE)) {  				atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);  				state = STATE_WAITING_NOTBUSY;  			} else if (host->mrq->stop) { @@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)  	host->caps.has_bad_data_ordering = 1;  	host->caps.need_reset_after_xfer = 1;  	host->caps.need_blksz_mul_4 = 1; +	host->caps.need_notbusy_for_read_ops = 0;  	/* keep only major version number */  	switch (version & 0xf00) { @@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)  	case 0x200:  		host->caps.has_rwproof = 1;  		host->caps.need_blksz_mul_4 = 0; +		host->caps.need_notbusy_for_read_ops = 1;  	case 0x100:  		host->caps.has_bad_data_ordering = 0;  		host->caps.need_reset_after_xfer = 0; diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 03666174ca4..a17dd7363ce 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c @@ -49,13 +49,6 @@  #define bfin_write_SDH_CFG		bfin_write_RSI_CFG  #endif -struct dma_desc_array { -	unsigned long	start_addr; -	unsigned short	cfg; -	unsigned short	x_count; -	short		x_modify; -} __packed; -  struct sdh_host {  	struct mmc_host		*mmc;  	spinlock_t		lock; diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 72dc3cde646..af40d227bec 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)  {  	struct dw_mci *host = slot->host;  	u32 div; +	u32 clk_en_a;  	if (slot->clock != host->current_speed) {  		div = host->bus_hz / slot->clock; @@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)  		mci_send_cmd(slot,  			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); -		/* enable clock */ -		mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE | -			   SDMMC_CLKEN_LOW_PWR) << slot->id)); +		/* enable clock; only low power if no SDIO */ +		clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; +		if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id))) +			clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; +		mci_writel(host, CLKENA, clk_en_a);  		/* inform CIU */  		mci_send_cmd(slot, @@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc)  	return present;  } +/* + * Disable lower power mode. + * + * Low power mode will stop the card clock when idle.  According to the + * description of the CLKENA register we should disable low power mode + * for SDIO cards if we need SDIO interrupts to work. + * + * This function is fast if low power mode is already disabled. + */ +static void dw_mci_disable_low_power(struct dw_mci_slot *slot) +{ +	struct dw_mci *host = slot->host; +	u32 clk_en_a; +	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; + +	clk_en_a = mci_readl(host, CLKENA); + +	if (clk_en_a & clken_low_pwr) { +		mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr); +		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | +			     SDMMC_CMD_PRV_DAT_WAIT, 0); +	} +} +  static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)  {  	struct dw_mci_slot *slot = mmc_priv(mmc); @@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)  	/* Enable/disable Slot Specific SDIO interrupt */  	int_mask = mci_readl(host, INTMASK);  	if (enb) { +		/* +		 * Turn off low power mode if it was enabled.  This is a bit of +		 * a heavy operation and we disable / enable IRQs a lot, so +		 * we'll leave low power mode disabled and it will get +		 * re-enabled again in dw_mci_setup_bus(). +		 */ +		dw_mci_disable_low_power(slot); +  		mci_writel(host, INTMASK,  			   (int_mask | SDMMC_INT_SDIO(slot->id)));  	} else { @@ -1429,22 +1464,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)  			nbytes += len;  			remain -= len;  		} while (remain); -		sg_miter->consumed = offset; +		sg_miter->consumed = offset;  		status = mci_readl(host, MINTSTS);  		mci_writel(host, RINTSTS, SDMMC_INT_RXDR); -		if (status & DW_MCI_DATA_ERROR_FLAGS) { -			host->data_status = status; -			data->bytes_xfered += nbytes; -			sg_miter_stop(sg_miter); -			host->sg = NULL; -			smp_wmb(); - -			set_bit(EVENT_DATA_ERROR, &host->pending_events); - -			tasklet_schedule(&host->tasklet); -			return; -		}  	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/  	data->bytes_xfered += nbytes; @@ -1497,23 +1520,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)  			nbytes += len;  			remain -= len;  		} while (remain); -		sg_miter->consumed = offset; +		sg_miter->consumed = offset;  		status = mci_readl(host, MINTSTS);  		mci_writel(host, RINTSTS, SDMMC_INT_TXDR); -		if (status & DW_MCI_DATA_ERROR_FLAGS) { -			host->data_status = status; -			data->bytes_xfered += nbytes; -			sg_miter_stop(sg_miter); -			host->sg = NULL; - -			smp_wmb(); - -			set_bit(EVENT_DATA_ERROR, &host->pending_events); - -			tasklet_schedule(&host->tasklet); -			return; -		}  	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */  	data->bytes_xfered += nbytes; @@ -1547,12 +1557,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)  static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  {  	struct dw_mci *host = dev_id; -	u32 status, pending; +	u32 pending;  	unsigned int pass_count = 0;  	int i;  	do { -		status = mci_readl(host, RINTSTS);  		pending = mci_readl(host, MINTSTS); /* read-only mask reg */  		/* @@ -1570,7 +1579,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & DW_MCI_CMD_ERROR_FLAGS) {  			mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); -			host->cmd_status = status; +			host->cmd_status = pending;  			smp_wmb();  			set_bit(EVENT_CMD_COMPLETE, &host->pending_events);  		} @@ -1578,18 +1587,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & DW_MCI_DATA_ERROR_FLAGS) {  			/* if there is an error report DATA_ERROR */  			mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); -			host->data_status = status; +			host->data_status = pending;  			smp_wmb();  			set_bit(EVENT_DATA_ERROR, &host->pending_events); -			if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | -					 SDMMC_INT_SBE | SDMMC_INT_EBE))) -				tasklet_schedule(&host->tasklet); +			tasklet_schedule(&host->tasklet);  		}  		if (pending & SDMMC_INT_DATA_OVER) {  			mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);  			if (!host->data_status) -				host->data_status = status; +				host->data_status = pending;  			smp_wmb();  			if (host->dir_status == DW_MCI_RECV_STATUS) {  				if (host->sg != NULL) @@ -1613,7 +1620,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)  		if (pending & SDMMC_INT_CMD_DONE) {  			mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); -			dw_mci_cmd_interrupt(host, status); +			dw_mci_cmd_interrupt(host, pending);  		}  		if (pending & SDMMC_INT_CD) { diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index a51f9309ffb..ad3fcea1269 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -285,11 +285,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)  	writel(stat & MXS_MMC_IRQ_BITS,  	       host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); +	spin_unlock(&host->lock); +  	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))  		mmc_signal_sdio_irq(host->mmc); -	spin_unlock(&host->lock); -  	if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)  		cmd->error = -ETIMEDOUT;  	else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) @@ -644,11 +644,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)  		       host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,  		       host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); - -		if (readl(host->base + HW_SSP_STATUS(host)) & -				BM_SSP_STATUS_SDIO_IRQ) -			mmc_signal_sdio_irq(host->mmc); -  	} else {  		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,  		       host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); @@ -657,6 +652,11 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)  	}  	spin_unlock_irqrestore(&host->lock, flags); + +	if (enable && readl(host->base + HW_SSP_STATUS(host)) & +			BM_SSP_STATUS_SDIO_IRQ) +		mmc_signal_sdio_irq(host->mmc); +  }  static const struct mmc_host_ops mxs_mmc_ops = { diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 50e08f03aa6..a5999a74496 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -668,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data)  static void  mmc_omap_xfer_data(struct mmc_omap_host *host, int write)  { -	int n; +	int n, nwords;  	if (host->buffer_bytes_left == 0) {  		host->sg_idx++; @@ -678,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)  	n = 64;  	if (n > host->buffer_bytes_left)  		n = host->buffer_bytes_left; + +	nwords = n / 2; +	nwords += n & 1; /* handle odd number of bytes to transfer */ +  	host->buffer_bytes_left -= n;  	host->total_bytes_left -= n;  	host->data->bytes_xfered += n;  	if (write) { -		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); +		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), +			      host->buffer, nwords);  	} else { -		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); +		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), +			     host->buffer, nwords);  	} + +	host->buffer += nwords;  }  static inline void mmc_omap_report_irq(u16 status) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index b97b2f5dafd..d25f9ab9a54 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)  	int div = 1;  	u32 temp; +	if (clock == 0) +		goto out; +  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);  	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN  		| ESDHC_CLOCK_MASK);  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); -	if (clock == 0) -		goto out; -  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)  		pre_div *= 2; diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 437bc193e17..568307cc7ca 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -340,7 +340,7 @@ retry:  	 * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'.  	 */  	err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); -	kfree(new_aeb); +	kmem_cache_free(ai->aeb_slab_cache, new_aeb);  	ubi_free_vid_hdr(ubi, vid_hdr);  	return err; @@ -353,7 +353,7 @@ write_error:  		list_add(&new_aeb->u.list, &ai->erase);  		goto retry;  	} -	kfree(new_aeb); +	kmem_cache_free(ai->aeb_slab_cache, new_aeb);  out_free:  	ubi_free_vid_hdr(ubi, vid_hdr);  	return err; 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/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 4f50145f648..662c5f7eb0c 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c @@ -109,7 +109,9 @@ static int sp_probe(struct platform_device *pdev)  	priv = netdev_priv(dev);  	dev->irq = res_irq->start; -	priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); +	priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; +	if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) +		priv->irq_flags |= IRQF_SHARED;  	priv->reg_base = addr;  	/* The CAN clock frequency is half the oscillator clock frequency */  	priv->can.clock.freq = pdata->osc_freq / 2; diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index 31059617567..b595d3422b9 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c @@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card,  	const uint8_t *mem, *end, *dat;  	uint16_t type, len;  	uint32_t addr; -	uint8_t *buf = NULL; +	uint8_t *buf = NULL, *new_buf;  	int buflen = 0;  	int8_t type_end = 0; @@ -199,11 +199,12 @@ int softing_load_fw(const char *file, struct softing *card,  		if (len > buflen) {  			/* align buflen */  			buflen = (len + (1024-1)) & ~(1024-1); -			buf = krealloc(buf, buflen, GFP_KERNEL); -			if (!buf) { +			new_buf = krealloc(buf, buflen, GFP_KERNEL); +			if (!new_buf) {  				ret = -ENOMEM;  				goto failed;  			} +			buf = new_buf;  		}  		/* verify record data */  		memcpy_fromio(buf, &dpram[addr + offset], len); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 463b9ec57d8..6d1a24acb77 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1708,9 +1708,6 @@ struct bnx2x_func_init_params {  			continue;		\  		else -#define for_each_napi_rx_queue(bp, var) \ -	for ((var) = 0; (var) < bp->num_napi_queues; (var)++) -  /* Skip OOO FP */  #define for_each_tx_queue(bp, var) \  	for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e879e19eb0d..af20c6ee2cd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2046,6 +2046,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)  	 */  	bnx2x_setup_tc(bp->dev, bp->max_cos); +	/* Add all NAPI objects */ +	bnx2x_add_all_napi(bp);  	bnx2x_napi_enable(bp);  	/* set pf load just before approaching the MCP */ @@ -2408,6 +2410,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)  		/* Disable HW interrupts, NAPI */  		bnx2x_netif_stop(bp, 1); +		/* Delete all NAPI objects */ +		bnx2x_del_all_napi(bp);  		/* Release IRQs */  		bnx2x_free_irq(bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index dfa757e7429..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) @@ -792,7 +790,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp)  	bp->num_napi_queues = bp->num_queues;  	/* Add NAPI objects */ -	for_each_napi_rx_queue(bp, i) +	for_each_rx_queue(bp, i)  		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),  			       bnx2x_poll, BNX2X_NAPI_WEIGHT);  } @@ -801,7 +799,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp)  {  	int i; -	for_each_napi_rx_queue(bp, i) +	for_each_rx_queue(bp, i)  		netif_napi_del(&bnx2x_fp(bp, i, napi));  } @@ -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 fc4e0e3885b..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, @@ -2888,11 +2894,9 @@ static void bnx2x_get_channels(struct net_device *dev,   */  static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss)  { -	bnx2x_del_all_napi(bp);  	bnx2x_disable_msi(bp);  	BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE;  	bnx2x_set_int_mode(bp); -	bnx2x_add_all_napi(bp);  }  /** 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 02b5a343b19..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;  } @@ -8427,6 +8433,8 @@ unload_error:  	/* Disable HW interrupts, NAPI */  	bnx2x_netif_stop(bp, 1); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	/* Release IRQs */  	bnx2x_free_irq(bp); @@ -10292,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)) @@ -11071,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; @@ -11229,10 +11242,12 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)  static void poll_bnx2x(struct net_device *dev)  {  	struct bnx2x *bp = netdev_priv(dev); +	int i; -	disable_irq(bp->pdev->irq); -	bnx2x_interrupt(bp->pdev->irq, dev); -	enable_irq(bp->pdev->irq); +	for_each_eth_queue(bp, i) { +		struct bnx2x_fastpath *fp = &bp->fp[i]; +		napi_schedule(&bnx2x_fp(bp, fp->index, napi)); +	}  }  #endif @@ -11899,9 +11914,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,  	 */  	bnx2x_set_int_mode(bp); -	/* Add all NAPI objects */ -	bnx2x_add_all_napi(bp); -  	rc = register_netdev(dev);  	if (rc) {  		dev_err(&pdev->dev, "Cannot register net device\n"); @@ -11976,9 +11988,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)  	unregister_netdev(dev); -	/* Delete all NAPI objects */ -	bnx2x_del_all_napi(bp); -  	/* Power on: we can't let PCI layer write to us while we are in D3 */  	bnx2x_set_power_state(bp, PCI_D0); @@ -12025,6 +12034,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)  	bnx2x_tx_disable(bp);  	bnx2x_netif_stop(bp, 0); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	del_timer_sync(&bp->timer); 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/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 845b2020f29..13844695778 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -1243,6 +1243,7 @@ static void set_multicast_list(struct net_device *dev)  {  	struct net_local *lp = netdev_priv(dev);  	unsigned long flags; +	u16 cfg;  	spin_lock_irqsave(&lp->lock, flags);  	if (dev->flags & IFF_PROMISC) @@ -1260,11 +1261,10 @@ static void set_multicast_list(struct net_device *dev)  	/* in promiscuous mode, we accept errored packets,  	 * so we have to enable interrupts on them also  	 */ -	writereg(dev, PP_RxCFG, -		 (lp->curr_rx_cfg | -		  (lp->rx_mode == RX_ALL_ACCEPT) -		  ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL) -		  : 0)); +	cfg = lp->curr_rx_cfg; +	if (lp->rx_mode == RX_ALL_ACCEPT) +		cfg |= RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL; +	writereg(dev, PP_RxCFG, cfg);  	spin_unlock_irqrestore(&lp->lock, flags);  } diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 7fac97b4bb5..8c63d06ab12 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -259,7 +259,7 @@ int be_process_mcc(struct be_adapter *adapter)  	int num = 0, status = 0;  	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; -	spin_lock_bh(&adapter->mcc_cq_lock); +	spin_lock(&adapter->mcc_cq_lock);  	while ((compl = be_mcc_compl_get(adapter))) {  		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {  			/* Interpret flags as an async trailer */ @@ -280,7 +280,7 @@ int be_process_mcc(struct be_adapter *adapter)  	if (num)  		be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); -	spin_unlock_bh(&adapter->mcc_cq_lock); +	spin_unlock(&adapter->mcc_cq_lock);  	return status;  } @@ -295,7 +295,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)  		if (be_error(adapter))  			return -EIO; +		local_bh_disable();  		status = be_process_mcc(adapter); +		local_bh_enable();  		if (atomic_read(&mcc_obj->q.used) == 0)  			break; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 90a903d83d8..78b8aa8069f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3763,7 +3763,9 @@ static void be_worker(struct work_struct *work)  	/* when interrupts are not yet enabled, just reap any pending  	* mcc completions */  	if (!netif_running(adapter->netdev)) { +		local_bh_disable();  		be_process_mcc(adapter); +		local_bh_enable();  		goto reschedule;  	} diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4605f724668..d3233f59a82 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1041,7 +1041,7 @@ static int gfar_probe(struct platform_device *ofdev)  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {  		dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +		dev->features |= NETIF_F_HW_VLAN_RX;  	}  	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { 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/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index cd153326c3c..cb3356c9af8 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -310,6 +310,7 @@ struct e1000_adapter {  	 */  	struct e1000_ring *tx_ring /* One per active queue */  						____cacheline_aligned_in_smp; +	u32 tx_fifo_limit;  	struct napi_struct napi; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 46c3b1f9ff8..d01a099475a 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3517,6 +3517,15 @@ void e1000e_reset(struct e1000_adapter *adapter)  	}  	/* +	 * Alignment of Tx data is on an arbitrary byte boundary with the +	 * maximum size per Tx descriptor limited only to the transmit +	 * allocation of the packet buffer minus 96 bytes with an upper +	 * limit of 24KB due to receive synchronization limitations. +	 */ +	adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96, +				       24 << 10); + +	/*  	 * Disable Adaptive Interrupt Moderation if 2 full packets cannot  	 * fit in receive buffer.  	 */ @@ -4785,12 +4794,9 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)  	return 1;  } -#define E1000_MAX_PER_TXD	8192 -#define E1000_MAX_TXD_PWR	12 -  static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,  			unsigned int first, unsigned int max_per_txd, -			unsigned int nr_frags, unsigned int mss) +			unsigned int nr_frags)  {  	struct e1000_adapter *adapter = tx_ring->adapter;  	struct pci_dev *pdev = adapter->pdev; @@ -5023,20 +5029,19 @@ static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)  static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)  { +	BUG_ON(size > tx_ring->count); +  	if (e1000_desc_unused(tx_ring) >= size)  		return 0;  	return __e1000_maybe_stop_tx(tx_ring, size);  } -#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1)  static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  				    struct net_device *netdev)  {  	struct e1000_adapter *adapter = netdev_priv(netdev);  	struct e1000_ring *tx_ring = adapter->tx_ring;  	unsigned int first; -	unsigned int max_per_txd = E1000_MAX_PER_TXD; -	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;  	unsigned int tx_flags = 0;  	unsigned int len = skb_headlen(skb);  	unsigned int nr_frags; @@ -5056,18 +5061,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  	}  	mss = skb_shinfo(skb)->gso_size; -	/* -	 * The controller does a simple calculation to -	 * make sure there is enough room in the FIFO before -	 * initiating the DMA for each buffer.  The calc is: -	 * 4 = ceil(buffer len/mss).  To make sure we don't -	 * overrun the FIFO, adjust the max buffer len if mss -	 * drops. -	 */  	if (mss) {  		u8 hdr_len; -		max_per_txd = min(mss << 2, max_per_txd); -		max_txd_pwr = fls(max_per_txd) - 1;  		/*  		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data @@ -5097,12 +5092,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  		count++;  	count++; -	count += TXD_USE_COUNT(len, max_txd_pwr); +	count += DIV_ROUND_UP(len, adapter->tx_fifo_limit);  	nr_frags = skb_shinfo(skb)->nr_frags;  	for (f = 0; f < nr_frags; f++) -		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), -				       max_txd_pwr); +		count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]), +				      adapter->tx_fifo_limit);  	if (adapter->hw.mac.tx_pkt_filtering)  		e1000_transfer_dhcp_info(adapter, skb); @@ -5144,15 +5139,18 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,  		tx_flags |= E1000_TX_FLAGS_NO_FCS;  	/* if count is 0 then mapping error has occurred */ -	count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); +	count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit, +			     nr_frags);  	if (count) {  		skb_tx_timestamp(skb);  		netdev_sent_queue(netdev, skb->len);  		e1000_tx_queue(tx_ring, tx_flags, count);  		/* Make sure there is space in the ring for the next send. */ -		e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); - +		e1000_maybe_stop_tx(tx_ring, +				    (MAX_SKB_FRAGS * +				     DIV_ROUND_UP(PAGE_SIZE, +						  adapter->tx_fifo_limit) + 2));  	} else {  		dev_kfree_skb_any(skb);  		tx_ring->buffer_info[first].time_stamp = 0; @@ -6327,8 +6325,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,  	adapter->hw.phy.autoneg_advertised = 0x2f;  	/* ring size defaults */ -	adapter->rx_ring->count = 256; -	adapter->tx_ring->count = 256; +	adapter->rx_ring->count = E1000_DEFAULT_RXD; +	adapter->tx_ring->count = E1000_DEFAULT_TXD;  	/*  	 * Initial Wake on LAN setting - If APM wake is enabled in 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/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 8cba2df82b1..5faedd855b7 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -863,8 +863,8 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx,  				       &ip_entry->ip4dst, &ip_entry->pdst);  	if (rc != 0) {  		rc = efx_filter_get_ipv4_full( -			&spec, &proto, &ip_entry->ip4src, &ip_entry->psrc, -			&ip_entry->ip4dst, &ip_entry->pdst); +			&spec, &proto, &ip_entry->ip4dst, &ip_entry->pdst, +			&ip_entry->ip4src, &ip_entry->psrc);  		EFX_WARN_ON_PARANOID(rc);  		ip_mask->ip4src = ~0;  		ip_mask->psrc = ~0; diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e2d083228f3..719be3912aa 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __COMMON_H__ +#define __COMMON_H__ +  #include <linux/etherdevice.h>  #include <linux/netdevice.h>  #include <linux/phy.h> @@ -366,3 +369,5 @@ extern void stmmac_set_mac(void __iomem *ioaddr, bool enable);  extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);  extern const struct stmmac_ring_mode_ops ring_mode_ops; + +#endif /* __COMMON_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 9820ec842cc..223adf95fd0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h @@ -20,6 +20,10 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ + +#ifndef __DESCS_H__ +#define __DESCS_H__ +  struct dma_desc {  	/* Receive descriptor */  	union { @@ -166,3 +170,5 @@ enum tdes_csum_insertion {  					 * is not calculated */  	cic_full = 3,		/* IP header and pseudoheader */  }; + +#endif /* __DESCS_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index dd8d6e19dff..7ee9499a6e3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h @@ -27,6 +27,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DESC_COM_H__ +#define __DESC_COM_H__ +  #if defined(CONFIG_STMMAC_RING)  static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end)  { @@ -124,3 +127,5 @@ static inline void norm_set_tx_desc_len(struct dma_desc *p, int len)  	p->des01.tx.buffer1_size = len;  }  #endif + +#endif /* __DESC_COM_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 7c6d857a9cc..2ec6aeae349 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC100_H__ +#define __DWMAC100_H__ +  #include <linux/phy.h>  #include "common.h" @@ -119,3 +122,5 @@ enum ttc_control {  #define DMA_MISSED_FRAME_M_CNTR	0x0000ffff	/* Missed Frame Couinter */  extern const struct stmmac_dma_ops dwmac100_dma_ops; + +#endif /* __DWMAC100_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index f90fcb5f957..0e4cacedc1f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -19,6 +19,8 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC1000_H__ +#define __DWMAC1000_H__  #include <linux/phy.h>  #include "common.h" @@ -229,6 +231,7 @@ enum rtc_control {  #define GMAC_MMC_RX_CSUM_OFFLOAD   0x208  /* Synopsys Core versions */ -#define	DWMAC_CORE_3_40	34 +#define	DWMAC_CORE_3_40	0x34  extern const struct stmmac_dma_ops dwmac1000_dma_ops; +#endif /* __DWMAC1000_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e678ce39d01..e49c9a0fd6f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __DWMAC_DMA_H__ +#define __DWMAC_DMA_H__ +  /* DMA CRS Control and Status Register Mapping */  #define DMA_BUS_MODE		0x00001000	/* Bus Mode */  #define DMA_XMT_POLL_DEMAND	0x00001004	/* Transmit Poll Demand */ @@ -109,3 +112,5 @@ extern void dwmac_dma_start_rx(void __iomem *ioaddr);  extern void dwmac_dma_stop_rx(void __iomem *ioaddr);  extern int dwmac_dma_interrupt(void __iomem *ioaddr,  				struct stmmac_extra_stats *x); + +#endif /* __DWMAC_DMA_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index a38352024cb..67995ef2525 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -22,6 +22,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __MMC_H__ +#define __MMC_H__ +  /* MMC control register */  /* When set, all counter are reset */  #define MMC_CNTRL_COUNTER_RESET		0x1 @@ -129,3 +132,5 @@ struct stmmac_counters {  extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode);  extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr);  extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); + +#endif /* __MMC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index c07cfe989f6..0c74a702d46 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -33,7 +33,7 @@  #define MMC_TX_INTR		0x00000108	/* MMC TX Interrupt */  #define MMC_RX_INTR_MASK	0x0000010c	/* MMC Interrupt Mask */  #define MMC_TX_INTR_MASK	0x00000110	/* MMC Interrupt Mask */ -#define MMC_DEFAUL_MASK		0xffffffff +#define MMC_DEFAULT_MASK		0xffffffff  /* MMC TX counter registers */ @@ -147,8 +147,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode)  /* To mask all all interrupts.*/  void dwmac_mmc_intr_all_mask(void __iomem *ioaddr)  { -	writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK); -	writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK); +	writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); +	writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK);  }  /* This reads the MAC core counters (if actaully supported). diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f2d3665430a..e872e1da313 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -20,6 +20,9 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __STMMAC_H__ +#define __STMMAC_H__ +  #define STMMAC_RESOURCE_NAME   "stmmaceth"  #define DRV_MODULE_VERSION	"March_2012" @@ -166,3 +169,5 @@ static inline void stmmac_unregister_pci(void)  {  }  #endif /* CONFIG_STMMAC_PCI */ + +#endif /* __STMMAC_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h index 6863590d184..aea9b14cdfb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h @@ -21,6 +21,8 @@    Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>  *******************************************************************************/ +#ifndef __STMMAC_TIMER_H__ +#define __STMMAC_TIMER_H__  struct stmmac_timer {  	void (*timer_start) (unsigned int new_freq); @@ -40,3 +42,5 @@ void stmmac_schedule(struct net_device *dev);  extern int tmu2_register_user(void *fnt, void *data);  extern void tmu2_unregister_user(void);  #endif + +#endif /* __STMMAC_TIMER_H__ */ diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index cd7ee204e94..a9ca4a03d31 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c @@ -394,8 +394,10 @@ static int __devexit davinci_mdio_remove(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct davinci_mdio_data *data = dev_get_drvdata(dev); -	if (data->bus) +	if (data->bus) { +		mdiobus_unregister(data->bus);  		mdiobus_free(data->bus); +	}  	if (data->clk)  		clk_put(data->clk); diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 24d8566cfd8..441b4dc7945 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c @@ -673,7 +673,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,  			sm_pm_get_ls(smc,port_to_mib(smc,port))) ;  		break ;  	case SMT_P_REASON : -		* (u_long *) to = 0 ; +		*(u32 *)to = 0 ;  		sp_len = 4 ;  		goto sp_done ;  	case SMT_P1033 :			/* time stamp */ diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 328397c6673..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 */ @@ -413,7 +413,9 @@ static const struct usb_device_id products[] = {  	/* 5. Gobi 2000 and 3000 devices */  	{QMI_GOBI_DEVICE(0x413c, 0x8186)},	/* Dell Gobi 2000 Modem device (N0218, VU936) */ +	{QMI_GOBI_DEVICE(0x413c, 0x8194)},	/* Dell Gobi 3000 Composite */  	{QMI_GOBI_DEVICE(0x05c6, 0x920b)},	/* Generic Gobi 2000 Modem device */ +	{QMI_GOBI_DEVICE(0x05c6, 0x920d)},	/* Gobi 3000 Composite */  	{QMI_GOBI_DEVICE(0x05c6, 0x9225)},	/* Sony Gobi 2000 Modem device (N0279, VU730) */  	{QMI_GOBI_DEVICE(0x05c6, 0x9245)},	/* Samsung Gobi 2000 Modem device (VL176) */  	{QMI_GOBI_DEVICE(0x03f0, 0x251d)},	/* HP Gobi 2000 Modem device (VP412) */ @@ -438,9 +440,12 @@ 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 */ +	{QMI_GOBI_DEVICE(0x12d1, 0x14f1)},	/* Sony Gobi 3000 Composite */ +	{QMI_GOBI_DEVICE(0x1410, 0xa021)},	/* Foxconn Gobi 3000 Modem device (Novatel E396) */  	{ }					/* END */  }; 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 8531c1caac2..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", @@ -1573,7 +1581,7 @@ int usbnet_resume (struct usb_interface *intf)  				netif_device_present(dev->net) &&  				!timer_pending(&dev->delay) &&  				!test_bit(EVENT_RX_HALT, &dev->flags)) -					rx_alloc_submit(dev, GFP_KERNEL); +					rx_alloc_submit(dev, GFP_NOIO);  			if (!(dev->txq.qlen >= TX_QLEN(dev)))  				netif_tx_wake_all_queues(dev->net); 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/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4026c906cc7..b7e0258887e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)  	case AR5K_EEPROM_MODE_11A:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);  		rate_pcal_info = ee->ee_rate_tpwr_a; -		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; +		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;  		break;  	case AR5K_EEPROM_MODE_11B:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index dc2bcfeadeb..94a9bbea687 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -182,6 +182,7 @@  #define AR5K_EEPROM_EEP_DELTA		10  #define AR5K_EEPROM_N_MODES		3  #define AR5K_EEPROM_N_5GHZ_CHAN		10 +#define AR5K_EEPROM_N_5GHZ_RATE_CHAN	8  #define AR5K_EEPROM_N_2GHZ_CHAN		3  #define AR5K_EEPROM_N_2GHZ_CHAN_2413	4  #define	AR5K_EEPROM_N_2GHZ_CHAN_MAX	4 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/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 192ad5c1fcc..a5edebeb0b4 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -1233,6 +1233,9 @@ uint brcms_reset(struct brcms_info *wl)  	/* dpc will not be rescheduled */  	wl->resched = false; +	/* inform publicly that interface is down */ +	wl->pub->up = false; +  	return 0;  } diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 95aa8e1683e..83324b32165 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -2042,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)  		return;  	}  	len = ETH_ALEN; -	ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); +	ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid, +				  &len);  	if (ret) {  		IPW_DEBUG_INFO("failed querying ordinals at line %d\n",  			       __LINE__); diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 46782f1102a..a47b306b522 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -124,6 +124,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,  	const struct fw_img *img;  	size_t bufsz; +	if (!iwl_is_ready_rf(priv)) +		return -EAGAIN; +  	/* default is to dump the entire data segment */  	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {  		priv->dbgfs_sram_offset = 0x800000; diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d9694c58208..4ffc18dc3a5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -350,7 +350,7 @@ int iwl_queue_space(const struct iwl_queue *q);  /*****************************************************  * Error handling  ******************************************************/ -int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); +int iwl_dump_fh(struct iwl_trans *trans, char **buf);  void iwl_dump_csr(struct iwl_trans *trans);  /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 39a6ca1f009..d1a61ba6247 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -555,7 +555,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)  	}  	iwl_dump_csr(trans); -	iwl_dump_fh(trans, NULL, false); +	iwl_dump_fh(trans, NULL);  	iwl_op_mode_nic_error(trans->op_mode);  } diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 939c2f78df5..1e86ea2266d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1649,13 +1649,9 @@ static const char *get_fh_string(int cmd)  #undef IWL_CMD  } -int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) +int iwl_dump_fh(struct iwl_trans *trans, char **buf)  {  	int i; -#ifdef CONFIG_IWLWIFI_DEBUG -	int pos = 0; -	size_t bufsz = 0; -#endif  	static const u32 fh_tbl[] = {  		FH_RSCSR_CHNL0_STTS_WPTR_REG,  		FH_RSCSR_CHNL0_RBDCB_BASE_REG, @@ -1667,29 +1663,35 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)  		FH_TSSR_TX_STATUS_REG,  		FH_TSSR_TX_ERROR_REG  	}; -#ifdef CONFIG_IWLWIFI_DEBUG -	if (display) { -		bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + +#ifdef CONFIG_IWLWIFI_DEBUGFS +	if (buf) { +		int pos = 0; +		size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; +  		*buf = kmalloc(bufsz, GFP_KERNEL);  		if (!*buf)  			return -ENOMEM; +  		pos += scnprintf(*buf + pos, bufsz - pos,  				"FH register values:\n"); -		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + +		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++)  			pos += scnprintf(*buf + pos, bufsz - pos,  				"  %34s: 0X%08x\n",  				get_fh_string(fh_tbl[i]),  				iwl_read_direct32(trans, fh_tbl[i])); -		} +  		return pos;  	}  #endif +  	IWL_ERR(trans, "FH register values:\n"); -	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) { +	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++)  		IWL_ERR(trans, "  %34s: 0X%08x\n",  			get_fh_string(fh_tbl[i]),  			iwl_read_direct32(trans, fh_tbl[i])); -	} +  	return 0;  } @@ -1982,11 +1984,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,  				     size_t count, loff_t *ppos)  {  	struct iwl_trans *trans = file->private_data; -	char *buf; +	char *buf = NULL;  	int pos = 0;  	ssize_t ret = -EFAULT; -	ret = pos = iwl_dump_fh(trans, &buf, true); +	ret = pos = iwl_dump_fh(trans, &buf);  	if (buf) {  		ret = simple_read_from_buffer(user_buf,  					      count, ppos, buf, pos); 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/net/xen-netfront.c b/drivers/net/xen-netfront.c index 30899901aef..650f79a1f2b 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -57,8 +57,7 @@  static const struct ethtool_ops xennet_ethtool_ops;  struct netfront_cb { -	struct page *page; -	unsigned offset; +	int pull_to;  };  #define NETFRONT_SKB_CB(skb)	((struct netfront_cb *)((skb)->cb)) @@ -867,15 +866,9 @@ static int handle_incoming_queue(struct net_device *dev,  	struct sk_buff *skb;  	while ((skb = __skb_dequeue(rxq)) != NULL) { -		struct page *page = NETFRONT_SKB_CB(skb)->page; -		void *vaddr = page_address(page); -		unsigned offset = NETFRONT_SKB_CB(skb)->offset; - -		memcpy(skb->data, vaddr + offset, -		       skb_headlen(skb)); +		int pull_to = NETFRONT_SKB_CB(skb)->pull_to; -		if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) -			__free_page(page); +		__pskb_pull_tail(skb, pull_to - skb_headlen(skb));  		/* Ethernet work: Delayed to here as it peeks the header. */  		skb->protocol = eth_type_trans(skb, dev); @@ -913,7 +906,6 @@ static int xennet_poll(struct napi_struct *napi, int budget)  	struct sk_buff_head errq;  	struct sk_buff_head tmpq;  	unsigned long flags; -	unsigned int len;  	int err;  	spin_lock(&np->rx_lock); @@ -955,24 +947,13 @@ err:  			}  		} -		NETFRONT_SKB_CB(skb)->page = -			skb_frag_page(&skb_shinfo(skb)->frags[0]); -		NETFRONT_SKB_CB(skb)->offset = rx->offset; - -		len = rx->status; -		if (len > RX_COPY_THRESHOLD) -			len = RX_COPY_THRESHOLD; -		skb_put(skb, len); +		NETFRONT_SKB_CB(skb)->pull_to = rx->status; +		if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD) +			NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD; -		if (rx->status > len) { -			skb_shinfo(skb)->frags[0].page_offset = -				rx->offset + len; -			skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); -			skb->data_len = rx->status - len; -		} else { -			__skb_fill_page_desc(skb, 0, NULL, 0, 0); -			skb_shinfo(skb)->nr_frags = 0; -		} +		skb_shinfo(skb)->frags[0].page_offset = rx->offset; +		skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); +		skb->data_len = rx->status;  		i = xennet_fill_frags(np, skb, &tmpq); @@ -999,7 +980,7 @@ err:  		 * receive throughout using the standard receive  		 * buffer size was cut by 25%(!!!).  		 */ -		skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); +		skb->truesize += skb->data_len - RX_COPY_THRESHOLD;  		skb->len += skb->data_len;  		if (rx->flags & XEN_NETRXF_csum_blank) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 5270f1a9932..d6fd6b6d9d4 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -280,8 +280,12 @@ static long local_pci_probe(void *_ddi)  {  	struct drv_dev_and_id *ddi = _ddi;  	struct device *dev = &ddi->dev->dev; +	struct device *parent = dev->parent;  	int rc; +	/* The parent bridge must be in active state when probing */ +	if (parent) +		pm_runtime_get_sync(parent);  	/* Unbound PCI devices are always set to disabled and suspended.  	 * During probe, the device is set to enabled and active and the  	 * usage count is incremented.  If the driver supports runtime PM, @@ -298,6 +302,8 @@ static long local_pci_probe(void *_ddi)  		pm_runtime_set_suspended(dev);  		pm_runtime_put_noidle(dev);  	} +	if (parent) +		pm_runtime_put(parent);  	return rc;  } diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6869009c739..02d107b1528 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)  }  struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static void +pci_config_pm_runtime_get(struct pci_dev *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device *parent = dev->parent; + +	if (parent) +		pm_runtime_get_sync(parent); +	pm_runtime_get_noresume(dev); +	/* +	 * pdev->current_state is set to PCI_D3cold during suspending, +	 * so wait until suspending completes +	 */ +	pm_runtime_barrier(dev); +	/* +	 * Only need to resume devices in D3cold, because config +	 * registers are still accessible for devices suspended but +	 * not in D3cold. +	 */ +	if (pdev->current_state == PCI_D3cold) +		pm_runtime_resume(dev); +} + +static void +pci_config_pm_runtime_put(struct pci_dev *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device *parent = dev->parent; + +	pm_runtime_put(dev); +	if (parent) +		pm_runtime_put_sync(parent); +} +  static ssize_t  pci_read_config(struct file *filp, struct kobject *kobj,  		struct bin_attribute *bin_attr, @@ -484,6 +518,8 @@ pci_read_config(struct file *filp, struct kobject *kobj,  		size = count;  	} +	pci_config_pm_runtime_get(dev); +  	if ((off & 1) && size) {  		u8 val;  		pci_user_read_config_byte(dev, off, &val); @@ -529,6 +565,8 @@ pci_read_config(struct file *filp, struct kobject *kobj,  		--size;  	} +	pci_config_pm_runtime_put(dev); +  	return count;  } @@ -549,6 +587,8 @@ pci_write_config(struct file* filp, struct kobject *kobj,  		count = size;  	} +	pci_config_pm_runtime_get(dev); +  	if ((off & 1) && size) {  		pci_user_write_config_byte(dev, off, data[off - init_off]);  		off++; @@ -587,6 +627,8 @@ pci_write_config(struct file* filp, struct kobject *kobj,  		--size;  	} +	pci_config_pm_runtime_put(dev); +  	return count;  } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f3ea977a5b1..ab4bf5a4c2f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1941,6 +1941,7 @@ void pci_pm_init(struct pci_dev *dev)  	dev->pm_cap = pm;  	dev->d3_delay = PCI_PM_D3_WAIT;  	dev->d3cold_delay = PCI_PM_D3COLD_WAIT; +	dev->d3cold_allowed = true;  	dev->d1_support = false;  	dev->d2_support = false; diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3a7eefcb270..e76b44777db 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -140,9 +140,17 @@ static int pcie_port_runtime_resume(struct device *dev)  {  	return 0;  } + +static int pcie_port_runtime_idle(struct device *dev) +{ +	/* Delay for a short while to prevent too frequent suspend/resume */ +	pm_schedule_suspend(dev, 10); +	return -EBUSY; +}  #else  #define pcie_port_runtime_suspend	NULL  #define pcie_port_runtime_resume	NULL +#define pcie_port_runtime_idle		NULL  #endif  static const struct dev_pm_ops pcie_portdrv_pm_ops = { @@ -155,6 +163,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {  	.resume_noirq	= pcie_port_resume_noirq,  	.runtime_suspend = pcie_port_runtime_suspend,  	.runtime_resume = pcie_port_runtime_resume, +	.runtime_idle	= pcie_port_runtime_idle,  };  #define PCIE_PORTDRV_PM_OPS	(&pcie_portdrv_pm_ops) @@ -200,6 +209,11 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,  		return status;  	pci_save_state(dev); +	/* +	 * D3cold may not work properly on some PCIe port, so disable +	 * it by default. +	 */ +	dev->d3cold_allowed = false;  	if (!pci_match_id(port_runtime_pm_black_list, dev))  		pm_runtime_put_noidle(&dev->dev); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6c143b4497c..9f8a6b79a8e 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -144,15 +144,13 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)  	case PCI_BASE_ADDRESS_MEM_TYPE_32:  		break;  	case PCI_BASE_ADDRESS_MEM_TYPE_1M: -		dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n"); +		/* 1M mem BAR treated as 32-bit BAR */  		break;  	case PCI_BASE_ADDRESS_MEM_TYPE_64:  		flags |= IORESOURCE_MEM_64;  		break;  	default: -		dev_warn(&dev->dev, -			 "mem unknown type %x treated as 32-bit BAR\n", -			 mem_type); +		/* mem unknown type treated as 32-bit BAR */  		break;  	}  	return flags; @@ -173,9 +171,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  	u32 l, sz, mask;  	u16 orig_cmd;  	struct pci_bus_region region; +	bool bar_too_big = false, bar_disabled = false;  	mask = type ? PCI_ROM_ADDRESS_MASK : ~0; +	/* No printks while decoding is disabled! */  	if (!dev->mmio_always_on) {  		pci_read_config_word(dev, PCI_COMMAND, &orig_cmd);  		pci_write_config_word(dev, PCI_COMMAND, @@ -240,8 +240,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  			goto fail;  		if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { -			dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", -				pos); +			bar_too_big = true;  			goto fail;  		} @@ -252,12 +251,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  			region.start = 0;  			region.end = sz64;  			pcibios_bus_to_resource(dev, res, ®ion); +			bar_disabled = true;  		} else {  			region.start = l64;  			region.end = l64 + sz64;  			pcibios_bus_to_resource(dev, res, ®ion); -			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", -				   pos, res);  		}  	} else {  		sz = pci_size(l, sz, mask); @@ -268,18 +266,23 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,  		region.start = l;  		region.end = l + sz;  		pcibios_bus_to_resource(dev, res, ®ion); - -		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);  	} - out: +	goto out; + + +fail: +	res->flags = 0; +out:  	if (!dev->mmio_always_on)  		pci_write_config_word(dev, PCI_COMMAND, orig_cmd); +	if (bar_too_big) +		dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos); +	if (res->flags && !bar_disabled) +		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); +  	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; - fail: -	res->flags = 0; -	goto out;  }  static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) 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/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 831868904e0..1dd61f402b0 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -58,6 +58,7 @@ struct sam9_rtc {  	struct rtc_device	*rtcdev;  	u32			imr;  	void __iomem		*gpbr; +	int 			irq;  };  #define rtt_readl(rtc, field) \ @@ -292,7 +293,7 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  {  	struct resource	*r, *r_gpbr;  	struct sam9_rtc	*rtc; -	int		ret; +	int		ret, irq;  	u32		mr;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -302,10 +303,18 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  		return -ENODEV;  	} +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(&pdev->dev, "failed to get interrupt resource\n"); +		return irq; +	} +  	rtc = kzalloc(sizeof *rtc, GFP_KERNEL);  	if (!rtc)  		return -ENOMEM; +	rtc->irq = irq; +  	/* platform setup code should have handled this; sigh */  	if (!device_can_wakeup(&pdev->dev))  		device_init_wakeup(&pdev->dev, 1); @@ -345,11 +354,10 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev)  	}  	/* register irq handler after we know what name we'll use */ -	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, -				IRQF_SHARED, +	ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED,  				dev_name(&rtc->rtcdev->dev), rtc);  	if (ret) { -		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); +		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq);  		rtc_device_unregister(rtc->rtcdev);  		goto fail_register;  	} @@ -386,7 +394,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev)  	/* disable all interrupts */  	rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); -	free_irq(AT91_ID_SYS, rtc); +	free_irq(rtc->irq, rtc);  	rtc_device_unregister(rtc->rtcdev); @@ -423,7 +431,7 @@ static int at91_rtc_suspend(struct platform_device *pdev,  	rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);  	if (rtc->imr) {  		if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { -			enable_irq_wake(AT91_ID_SYS); +			enable_irq_wake(rtc->irq);  			/* don't let RTTINC cause wakeups */  			if (mr & AT91_RTT_RTTINCIEN)  				rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); @@ -441,7 +449,7 @@ static int at91_rtc_resume(struct platform_device *pdev)  	if (rtc->imr) {  		if (device_may_wakeup(&pdev->dev)) -			disable_irq_wake(AT91_ID_SYS); +			disable_irq_wake(rtc->irq);  		mr = rtt_readl(rtc, MR);  		rtt_writel(rtc, MR, mr | rtc->imr);  	} diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 40a826a7295..2fb2b9ea97e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -3804,7 +3804,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)  	case BIODASDSYMMIO:  		return dasd_symm_io(device, argp);  	default: -		return -ENOIOCTLCMD; +		return -ENOTTY;  	}  } diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index cceae70279f..654c6921a6d 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,  		break;  	default:  		/* if the discipline has an ioctl method try it. */ -		if (base->discipline->ioctl) { +		rc = -ENOTTY; +		if (base->discipline->ioctl)  			rc = base->discipline->ioctl(block, cmd, argp); -			if (rc == -ENOIOCTLCMD) -				rc = -EINVAL; -		} else -			rc = -EINVAL;  	}  	dasd_put_device(base);  	return rc; 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/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index ea0aaa3f13d..a9f4049c676 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -47,6 +47,8 @@ struct bcm63xx_spi {  	/* Platform data */  	u32			speed_hz;  	unsigned		fifo_size; +	unsigned int		msg_type_shift; +	unsigned int		msg_ctl_width;  	/* Data buffers */  	const unsigned char	*tx_ptr; @@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,  	msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);  	if (t->rx_buf && t->tx_buf) -		msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);  	else if (t->rx_buf) -		msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_HD_R << bs->msg_type_shift);  	else if (t->tx_buf) -		msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); +		msg_ctl |= (SPI_HD_W << bs->msg_type_shift); -	bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); +	switch (bs->msg_ctl_width) { +	case 8: +		bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL); +		break; +	case 16: +		bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); +		break; +	}  	/* Issue the transfer */  	cmd = SPI_CMD_START_IMMEDIATE; @@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev)  	master->transfer_one_message = bcm63xx_spi_transfer_one;  	master->mode_bits = MODEBITS;  	bs->speed_hz = pdata->speed_hz; +	bs->msg_type_shift = pdata->msg_type_shift; +	bs->msg_ctl_width = pdata->msg_ctl_width;  	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));  	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); +	switch (bs->msg_ctl_width) { +	case 8: +	case 16: +		break; +	default: +		dev_err(dev, "unsupported MSG_CTL width: %d\n", +			 bs->msg_ctl_width); +		goto out_clk_disable; +	} +  	/* Initialize hardware */  	clk_enable(bs->clk);  	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); 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 d5c689d6217..e309e8b0aab 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 5b3f5fffea9..da6d479ff9a 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 5620db6469e..f906b3aec21 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/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 77da6a2f43d..c03ecdd31e4 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c @@ -987,7 +987,6 @@ err_regfb:  	fb_dealloc_cmap(&info->cmap);  err_cmap:  	fb_deferred_io_cleanup(info); -	kfree(info->fbdefio);  err_defio:  	vfree((void *)info->screen_base);  err_irq: @@ -1022,7 +1021,6 @@ int  __devexit auok190x_common_remove(struct platform_device *pdev)  	fb_dealloc_cmap(&info->cmap);  	fb_deferred_io_cleanup(info); -	kfree(info->fbdefio);  	vfree((void *)info->screen_base); diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 28b1a834906..61b182bf32a 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -162,7 +162,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,  	image.depth = 1;  	if (attribute) { -		buf = kmalloc(cellsize, GFP_KERNEL); +		buf = kmalloc(cellsize, GFP_ATOMIC);  		if (!buf)  			return;  	} diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 88e92041d8f..fdefa8fd72c 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -449,7 +449,7 @@ static int __init fb_console_setup(char *this_opt)  	while ((options = strsep(&this_opt, ",")) != NULL) {  		if (!strncmp(options, "font:", 5)) -			strcpy(fontname, options + 5); +			strlcpy(fontname, options + 5, sizeof(fontname));  		if (!strncmp(options, "scrollback:", 11)) {  			options += 11; diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c index 00ce1f34b49..57d940be5f3 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/mb862xx/mb862xxfbdrv.c @@ -328,6 +328,8 @@ static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd,  	case MB862XX_L1_SET_CFG:  		if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg)))  			return -EFAULT; +		if (l1_cfg->dh == 0 || l1_cfg->dw == 0) +			return -EINVAL;  		if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) {  			/* downscaling */  			outreg(cap, GC_CAP_CSC, diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 5d31699fbd3..f43bfe17b3b 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)  	sdi_config_lcd_manager(dssdev); +	/* +	 * LCLK and PCLK divisors are located in shadow registers, and we +	 * normally write them to DISPC registers when enabling the output. +	 * However, SDI uses pck-free as source clock for its PLL, and pck-free +	 * is affected by the divisors. And as we need the PLL before enabling +	 * the output, we need to write the divisors early. +	 * +	 * It seems just writing to the DISPC register is enough, and we don't +	 * need to care about the shadow register mechanism for pck-free. The +	 * exact reason for this is unknown. +	 */ +	dispc_mgr_set_clock_div(dssdev->manager->id, +			&sdi.mgr_config.clock_info); +  	dss_sdi_init(dssdev->phy.sdi.datapairs);  	r = dss_sdi_enable();  	if (r) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 08ec1a7103f..fc671d3d800 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1192,7 +1192,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,  			break;  		if (regno < 16) { -			u16 pal; +			u32 pal;  			pal = ((red >> (16 - var->red.length)) <<  					var->red.offset) |  				((green >> (16 - var->green.length)) << diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 3fe82d0e8ca..5b06d31ab6a 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -166,18 +166,17 @@ static long booke_wdt_ioctl(struct file *file,  	switch (cmd) {  	case WDIOC_GETSUPPORT: -		if (copy_to_user((void *)arg, &ident, sizeof(ident))) -			return -EFAULT; +		return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0;  	case WDIOC_GETSTATUS:  		return put_user(0, p);  	case WDIOC_GETBOOTSTATUS:  		/* XXX: something is clearing TSR */  		tmp = mfspr(SPRN_TSR) & TSR_WRS(3);  		/* returns CARDRESET if last reset was caused by the WDT */ -		return (tmp ? WDIOF_CARDRESET : 0); +		return put_user((tmp ? WDIOF_CARDRESET : 0), p);  	case WDIOC_SETOPTIONS:  		if (get_user(tmp, p)) -			return -EINVAL; +			return -EFAULT;  		if (tmp == WDIOS_ENABLECARD) {  			booke_wdt_ping();  			break; diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index 3f75129eb0a..f7abbaeebca 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c @@ -21,7 +21,6 @@  #include <linux/types.h>  #include <linux/kernel.h>  #include <linux/jiffies.h> -#include <linux/delay.h>  #include <linux/mfd/da9052/reg.h>  #include <linux/mfd/da9052/da9052.h> diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index d4c50d63acb..97ca359ae2b 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -101,19 +101,6 @@ static int platform_pci_resume(struct pci_dev *pdev)  	return 0;  } -static void __devinit prepare_shared_info(void) -{ -#ifdef CONFIG_KEXEC -	unsigned long addr; -	struct shared_info *hvm_shared_info; - -	addr = alloc_xen_mmio(PAGE_SIZE); -	hvm_shared_info = ioremap(addr, PAGE_SIZE); -	memset(hvm_shared_info, 0, PAGE_SIZE); -	xen_hvm_prepare_kexec(hvm_shared_info, addr >> PAGE_SHIFT); -#endif -} -  static int __devinit platform_pci_init(struct pci_dev *pdev,  				       const struct pci_device_id *ent)  { @@ -151,8 +138,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,  	platform_mmio = mmio_addr;  	platform_mmiolen = mmio_len; -	prepare_shared_info(); -  	if (!xen_have_vector_callback) {  		ret = xen_allocate_irq(pdev);  		if (ret) { diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 1afb4fba11b..4d519488d30 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -232,7 +232,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,  		return ret;  	if (hwdev && hwdev->coherent_dma_mask) -		dma_mask = hwdev->coherent_dma_mask; +		dma_mask = dma_alloc_coherent_mask(hwdev, flags);  	phys = virt_to_phys(ret);  	dev_addr = xen_phys_to_bus(phys); diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 097e536e867..03342728bf2 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -353,16 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)  	if (err)  		goto config_release; -	dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); -	__pci_reset_function_locked(dev); -  	/* We need the device active to save the state. */  	dev_dbg(&dev->dev, "save state of device\n");  	pci_save_state(dev);  	dev_data->pci_saved_state = pci_store_saved_state(dev);  	if (!dev_data->pci_saved_state)  		dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); - +	else { +		dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); +		__pci_reset_function_locked(dev); +	}  	/* Now disable the device (this also ensures some private device  	 * data is setup before we export)  	 */ @@ -73,7 +73,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)  {  	unsigned int sz = sizeof(struct bio) + extra_size;  	struct kmem_cache *slab = NULL; -	struct bio_slab *bslab; +	struct bio_slab *bslab, *new_bio_slabs;  	unsigned int i, entry = -1;  	mutex_lock(&bio_slab_lock); @@ -97,11 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)  	if (bio_slab_nr == bio_slab_max && entry == -1) {  		bio_slab_max <<= 1; -		bio_slabs = krealloc(bio_slabs, -				     bio_slab_max * sizeof(struct bio_slab), -				     GFP_KERNEL); -		if (!bio_slabs) +		new_bio_slabs = krealloc(bio_slabs, +					 bio_slab_max * sizeof(struct bio_slab), +					 GFP_KERNEL); +		if (!new_bio_slabs)  			goto out_unlock; +		bio_slabs = new_bio_slabs;  	}  	if (entry == -1)  		entry = bio_slab_nr++; diff --git a/fs/block_dev.c b/fs/block_dev.c index 1e519195d45..38e721b35d4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1578,10 +1578,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,  			 unsigned long nr_segs, loff_t pos)  {  	struct file *file = iocb->ki_filp; +	struct blk_plug plug;  	ssize_t ret;  	BUG_ON(iocb->ki_pos != pos); +	blk_start_plug(&plug);  	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);  	if (ret > 0 || ret == -EIOCBQUEUED) {  		ssize_t err; @@ -1590,6 +1592,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,  		if (err < 0 && ret > 0)  			ret = err;  	} +	blk_finish_plug(&plug);  	return ret;  }  EXPORT_SYMBOL_GPL(blkdev_aio_write); diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index a256f3b2a84..ff6475f409d 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1438,10 +1438,10 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,  	ret = extent_from_logical(fs_info, logical, path,  					&found_key);  	btrfs_release_path(path); -	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) -		ret = -EINVAL;  	if (ret < 0)  		return ret; +	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) +		return -EINVAL;  	extent_item_pos = logical - found_key.objectid;  	ret = iterate_extent_inodes(fs_info, found_key.objectid, diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 86eff48dab7..43d1c5a3a03 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -818,6 +818,7 @@ static void free_workspace(int type, struct list_head *workspace)  	btrfs_compress_op[idx]->free_workspace(workspace);  	atomic_dec(alloc_workspace);  wake: +	smp_mb();  	if (waitqueue_active(workspace_wait))  		wake_up(workspace_wait);  } diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 9d7621f271f..6d183f60d63 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -421,12 +421,6 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,  	spin_unlock(&fs_info->tree_mod_seq_lock);  	/* -	 * we removed the lowest blocker from the blocker list, so there may be -	 * more processible delayed refs. -	 */ -	wake_up(&fs_info->tree_mod_seq_wait); - -	/*  	 * anything that's lower than the lowest existing (read: blocked)  	 * sequence number can be removed from the tree.  	 */ @@ -631,6 +625,9 @@ __tree_mod_log_free_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb)  	u32 nritems;  	int ret; +	if (btrfs_header_level(eb) == 0) +		return; +  	nritems = btrfs_header_nritems(eb);  	for (i = nritems - 1; i >= 0; i--) {  		ret = tree_mod_log_insert_key_locked(fs_info, eb, i, diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 4bab807227a..0d195b50766 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1252,7 +1252,6 @@ struct btrfs_fs_info {  	atomic_t tree_mod_seq;  	struct list_head tree_mod_seq_list;  	struct seq_list tree_mod_seq_elem; -	wait_queue_head_t tree_mod_seq_wait;  	/* this protects tree_mod_log */  	rwlock_t tree_mod_log_lock; @@ -3192,7 +3191,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,  int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,  			  struct bio *bio, u32 *dst);  int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, -			      struct bio *bio, u64 logical_offset, u32 *dst); +			      struct bio *bio, u64 logical_offset);  int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,  			     struct btrfs_root *root,  			     u64 objectid, u64 pos, diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 335605c8cea..07d5eeb1e6f 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -512,8 +512,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)  	rb_erase(&delayed_item->rb_node, root);  	delayed_item->delayed_node->count--; -	atomic_dec(&delayed_root->items); -	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND && +	if (atomic_dec_return(&delayed_root->items) < +	    BTRFS_DELAYED_BACKGROUND &&  	    waitqueue_active(&delayed_root->wait))  		wake_up(&delayed_root->wait);  } @@ -1028,9 +1028,10 @@ do_again:  		btrfs_release_delayed_item(prev);  		ret = 0;  		btrfs_release_path(path); -		if (curr) +		if (curr) { +			mutex_unlock(&node->mutex);  			goto do_again; -		else +		} else  			goto delete_fail;  	} @@ -1055,8 +1056,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)  		delayed_node->count--;  		delayed_root = delayed_node->root->fs_info->delayed_root; -		atomic_dec(&delayed_root->items); -		if (atomic_read(&delayed_root->items) < +		if (atomic_dec_return(&delayed_root->items) <  		    BTRFS_DELAYED_BACKGROUND &&  		    waitqueue_active(&delayed_root->wait))  			wake_up(&delayed_root->wait); diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index da7419ed01b..ae941177339 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c @@ -38,17 +38,14 @@  static int comp_tree_refs(struct btrfs_delayed_tree_ref *ref2,  			  struct btrfs_delayed_tree_ref *ref1)  { -	if (ref1->node.type == BTRFS_TREE_BLOCK_REF_KEY) { -		if (ref1->root < ref2->root) -			return -1; -		if (ref1->root > ref2->root) -			return 1; -	} else { -		if (ref1->parent < ref2->parent) -			return -1; -		if (ref1->parent > ref2->parent) -			return 1; -	} +	if (ref1->root < ref2->root) +		return -1; +	if (ref1->root > ref2->root) +		return 1; +	if (ref1->parent < ref2->parent) +		return -1; +	if (ref1->parent > ref2->parent) +		return 1;  	return 0;  } @@ -85,7 +82,8 @@ static int comp_data_refs(struct btrfs_delayed_data_ref *ref2,   * type of the delayed backrefs and content of delayed backrefs.   */  static int comp_entry(struct btrfs_delayed_ref_node *ref2, -		      struct btrfs_delayed_ref_node *ref1) +		      struct btrfs_delayed_ref_node *ref1, +		      bool compare_seq)  {  	if (ref1->bytenr < ref2->bytenr)  		return -1; @@ -102,10 +100,12 @@ static int comp_entry(struct btrfs_delayed_ref_node *ref2,  	if (ref1->type > ref2->type)  		return 1;  	/* merging of sequenced refs is not allowed */ -	if (ref1->seq < ref2->seq) -		return -1; -	if (ref1->seq > ref2->seq) -		return 1; +	if (compare_seq) { +		if (ref1->seq < ref2->seq) +			return -1; +		if (ref1->seq > ref2->seq) +			return 1; +	}  	if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY ||  	    ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) {  		return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2), @@ -139,7 +139,7 @@ static struct btrfs_delayed_ref_node *tree_insert(struct rb_root *root,  		entry = rb_entry(parent_node, struct btrfs_delayed_ref_node,  				 rb_node); -		cmp = comp_entry(entry, ins); +		cmp = comp_entry(entry, ins, 1);  		if (cmp < 0)  			p = &(*p)->rb_left;  		else if (cmp > 0) @@ -233,6 +233,114 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans,  	return 0;  } +static void inline drop_delayed_ref(struct btrfs_trans_handle *trans, +				    struct btrfs_delayed_ref_root *delayed_refs, +				    struct btrfs_delayed_ref_node *ref) +{ +	rb_erase(&ref->rb_node, &delayed_refs->root); +	ref->in_tree = 0; +	btrfs_put_delayed_ref(ref); +	delayed_refs->num_entries--; +	if (trans->delayed_ref_updates) +		trans->delayed_ref_updates--; +} + +static int merge_ref(struct btrfs_trans_handle *trans, +		     struct btrfs_delayed_ref_root *delayed_refs, +		     struct btrfs_delayed_ref_node *ref, u64 seq) +{ +	struct rb_node *node; +	int merged = 0; +	int mod = 0; +	int done = 0; + +	node = rb_prev(&ref->rb_node); +	while (node) { +		struct btrfs_delayed_ref_node *next; + +		next = rb_entry(node, struct btrfs_delayed_ref_node, rb_node); +		node = rb_prev(node); +		if (next->bytenr != ref->bytenr) +			break; +		if (seq && next->seq >= seq) +			break; +		if (comp_entry(ref, next, 0)) +			continue; + +		if (ref->action == next->action) { +			mod = next->ref_mod; +		} else { +			if (ref->ref_mod < next->ref_mod) { +				struct btrfs_delayed_ref_node *tmp; + +				tmp = ref; +				ref = next; +				next = tmp; +				done = 1; +			} +			mod = -next->ref_mod; +		} + +		merged++; +		drop_delayed_ref(trans, delayed_refs, next); +		ref->ref_mod += mod; +		if (ref->ref_mod == 0) { +			drop_delayed_ref(trans, delayed_refs, ref); +			break; +		} else { +			/* +			 * You can't have multiples of the same ref on a tree +			 * block. +			 */ +			WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY || +				ref->type == BTRFS_SHARED_BLOCK_REF_KEY); +		} + +		if (done) +			break; +		node = rb_prev(&ref->rb_node); +	} + +	return merged; +} + +void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, +			      struct btrfs_fs_info *fs_info, +			      struct btrfs_delayed_ref_root *delayed_refs, +			      struct btrfs_delayed_ref_head *head) +{ +	struct rb_node *node; +	u64 seq = 0; + +	spin_lock(&fs_info->tree_mod_seq_lock); +	if (!list_empty(&fs_info->tree_mod_seq_list)) { +		struct seq_list *elem; + +		elem = list_first_entry(&fs_info->tree_mod_seq_list, +					struct seq_list, list); +		seq = elem->seq; +	} +	spin_unlock(&fs_info->tree_mod_seq_lock); + +	node = rb_prev(&head->node.rb_node); +	while (node) { +		struct btrfs_delayed_ref_node *ref; + +		ref = rb_entry(node, struct btrfs_delayed_ref_node, +			       rb_node); +		if (ref->bytenr != head->node.bytenr) +			break; + +		/* We can't merge refs that are outside of our seq count */ +		if (seq && ref->seq >= seq) +			break; +		if (merge_ref(trans, delayed_refs, ref, seq)) +			node = rb_prev(&head->node.rb_node); +		else +			node = rb_prev(node); +	} +} +  int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,  			    struct btrfs_delayed_ref_root *delayed_refs,  			    u64 seq) @@ -336,18 +444,11 @@ update_existing_ref(struct btrfs_trans_handle *trans,  		 * every changing the extent allocation tree.  		 */  		existing->ref_mod--; -		if (existing->ref_mod == 0) { -			rb_erase(&existing->rb_node, -				 &delayed_refs->root); -			existing->in_tree = 0; -			btrfs_put_delayed_ref(existing); -			delayed_refs->num_entries--; -			if (trans->delayed_ref_updates) -				trans->delayed_ref_updates--; -		} else { +		if (existing->ref_mod == 0) +			drop_delayed_ref(trans, delayed_refs, existing); +		else  			WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY ||  				existing->type == BTRFS_SHARED_BLOCK_REF_KEY); -		}  	} else {  		WARN_ON(existing->type == BTRFS_TREE_BLOCK_REF_KEY ||  			existing->type == BTRFS_SHARED_BLOCK_REF_KEY); @@ -662,9 +763,6 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,  	add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr,  				   num_bytes, parent, ref_root, level, action,  				   for_cow); -	if (!need_ref_seq(for_cow, ref_root) && -	    waitqueue_active(&fs_info->tree_mod_seq_wait)) -		wake_up(&fs_info->tree_mod_seq_wait);  	spin_unlock(&delayed_refs->lock);  	if (need_ref_seq(for_cow, ref_root))  		btrfs_qgroup_record_ref(trans, &ref->node, extent_op); @@ -713,9 +811,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,  	add_delayed_data_ref(fs_info, trans, &ref->node, bytenr,  				   num_bytes, parent, ref_root, owner, offset,  				   action, for_cow); -	if (!need_ref_seq(for_cow, ref_root) && -	    waitqueue_active(&fs_info->tree_mod_seq_wait)) -		wake_up(&fs_info->tree_mod_seq_wait);  	spin_unlock(&delayed_refs->lock);  	if (need_ref_seq(for_cow, ref_root))  		btrfs_qgroup_record_ref(trans, &ref->node, extent_op); @@ -744,8 +839,6 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,  				   num_bytes, BTRFS_UPDATE_DELAYED_HEAD,  				   extent_op->is_data); -	if (waitqueue_active(&fs_info->tree_mod_seq_wait)) -		wake_up(&fs_info->tree_mod_seq_wait);  	spin_unlock(&delayed_refs->lock);  	return 0;  } diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index 0d7c90c366b..ab530059584 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h @@ -167,6 +167,10 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,  				struct btrfs_trans_handle *trans,  				u64 bytenr, u64 num_bytes,  				struct btrfs_delayed_extent_op *extent_op); +void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, +			      struct btrfs_fs_info *fs_info, +			      struct btrfs_delayed_ref_root *delayed_refs, +			      struct btrfs_delayed_ref_head *head);  struct btrfs_delayed_ref_head *  btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62e0cafd6e2..22e98e04c2e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -377,9 +377,13 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,  		ret = read_extent_buffer_pages(io_tree, eb, start,  					       WAIT_COMPLETE,  					       btree_get_extent, mirror_num); -		if (!ret && !verify_parent_transid(io_tree, eb, +		if (!ret) { +			if (!verify_parent_transid(io_tree, eb,  						   parent_transid, 0)) -			break; +				break; +			else +				ret = -EIO; +		}  		/*  		 * This buffer's crc is fine, but its contents are corrupted, so @@ -754,9 +758,7 @@ static void run_one_async_done(struct btrfs_work *work)  	limit = btrfs_async_submit_limit(fs_info);  	limit = limit * 2 / 3; -	atomic_dec(&fs_info->nr_async_submits); - -	if (atomic_read(&fs_info->nr_async_submits) < limit && +	if (atomic_dec_return(&fs_info->nr_async_submits) < limit &&  	    waitqueue_active(&fs_info->async_submit_wait))  		wake_up(&fs_info->async_submit_wait); @@ -2032,8 +2034,6 @@ int open_ctree(struct super_block *sb,  	fs_info->free_chunk_space = 0;  	fs_info->tree_mod_log = RB_ROOT; -	init_waitqueue_head(&fs_info->tree_mod_seq_wait); -  	/* readahead state */  	INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);  	spin_lock_init(&fs_info->reada_lock); @@ -2528,8 +2528,7 @@ retry_root_backup:  		goto fail_trans_kthread;  	/* do not make disk changes in broken FS */ -	if (btrfs_super_log_root(disk_super) != 0 && -	    !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) { +	if (btrfs_super_log_root(disk_super) != 0) {  		u64 bytenr = btrfs_super_log_root(disk_super);  		if (fs_devices->rw_devices == 0) { @@ -3189,30 +3188,14 @@ int close_ctree(struct btrfs_root *root)  	/* clear out the rbtree of defraggable inodes */  	btrfs_run_defrag_inodes(fs_info); -	/* -	 * Here come 2 situations when btrfs is broken to flip readonly: -	 * -	 * 1. when btrfs flips readonly somewhere else before -	 * btrfs_commit_super, sb->s_flags has MS_RDONLY flag, -	 * and btrfs will skip to write sb directly to keep -	 * ERROR state on disk. -	 * -	 * 2. when btrfs flips readonly just in btrfs_commit_super, -	 * and in such case, btrfs cannot write sb via btrfs_commit_super, -	 * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag, -	 * btrfs will cleanup all FS resources first and write sb then. -	 */  	if (!(fs_info->sb->s_flags & MS_RDONLY)) {  		ret = btrfs_commit_super(root);  		if (ret)  			printk(KERN_ERR "btrfs: commit super ret %d\n", ret);  	} -	if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { -		ret = btrfs_error_commit_super(root); -		if (ret) -			printk(KERN_ERR "btrfs: commit super ret %d\n", ret); -	} +	if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) +		btrfs_error_commit_super(root);  	btrfs_put_block_group_cache(fs_info); @@ -3434,18 +3417,11 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,  	if (read_only)  		return 0; -	if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { -		printk(KERN_WARNING "warning: mount fs with errors, " -		       "running btrfsck is recommended\n"); -	} -  	return 0;  } -int btrfs_error_commit_super(struct btrfs_root *root) +void btrfs_error_commit_super(struct btrfs_root *root)  { -	int ret; -  	mutex_lock(&root->fs_info->cleaner_mutex);  	btrfs_run_delayed_iputs(root);  	mutex_unlock(&root->fs_info->cleaner_mutex); @@ -3455,10 +3431,6 @@ int btrfs_error_commit_super(struct btrfs_root *root)  	/* cleanup FS via transaction */  	btrfs_cleanup_transaction(root); - -	ret = write_ctree_super(NULL, root, 0); - -	return ret;  }  static void btrfs_destroy_ordered_operations(struct btrfs_root *root) @@ -3782,14 +3754,17 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)  		/* FIXME: cleanup wait for commit */  		t->in_commit = 1;  		t->blocked = 1; +		smp_mb();  		if (waitqueue_active(&root->fs_info->transaction_blocked_wait))  			wake_up(&root->fs_info->transaction_blocked_wait);  		t->blocked = 0; +		smp_mb();  		if (waitqueue_active(&root->fs_info->transaction_wait))  			wake_up(&root->fs_info->transaction_wait);  		t->commit_done = 1; +		smp_mb();  		if (waitqueue_active(&t->commit_wait))  			wake_up(&t->commit_wait); diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 95e147eea23..c5b00a735fe 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h @@ -54,7 +54,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans,  		      struct btrfs_root *root, int max_mirrors);  struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);  int btrfs_commit_super(struct btrfs_root *root); -int btrfs_error_commit_super(struct btrfs_root *root); +void btrfs_error_commit_super(struct btrfs_root *root);  struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,  					    u64 bytenr, u32 blocksize);  struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4e1b153b7c4..ba58024d40d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2252,6 +2252,16 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,  		}  		/* +		 * We need to try and merge add/drops of the same ref since we +		 * can run into issues with relocate dropping the implicit ref +		 * and then it being added back again before the drop can +		 * finish.  If we merged anything we need to re-loop so we can +		 * get a good ref. +		 */ +		btrfs_merge_delayed_refs(trans, fs_info, delayed_refs, +					 locked_ref); + +		/*  		 * locked_ref is the head node, so we have to go one  		 * node back for any delayed ref updates  		 */ @@ -2318,12 +2328,23 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,  		ref->in_tree = 0;  		rb_erase(&ref->rb_node, &delayed_refs->root);  		delayed_refs->num_entries--; -		/* -		 * we modified num_entries, but as we're currently running -		 * delayed refs, skip -		 *     wake_up(&delayed_refs->seq_wait); -		 * here. -		 */ +		if (locked_ref) { +			/* +			 * when we play the delayed ref, also correct the +			 * ref_mod on head +			 */ +			switch (ref->action) { +			case BTRFS_ADD_DELAYED_REF: +			case BTRFS_ADD_DELAYED_EXTENT: +				locked_ref->node.ref_mod -= ref->ref_mod; +				break; +			case BTRFS_DROP_DELAYED_REF: +				locked_ref->node.ref_mod += ref->ref_mod; +				break; +			default: +				WARN_ON(1); +			} +		}  		spin_unlock(&delayed_refs->lock);  		ret = run_one_delayed_ref(trans, root, ref, extent_op, @@ -2350,22 +2371,6 @@ next:  	return count;  } -static void wait_for_more_refs(struct btrfs_fs_info *fs_info, -			       struct btrfs_delayed_ref_root *delayed_refs, -			       unsigned long num_refs, -			       struct list_head *first_seq) -{ -	spin_unlock(&delayed_refs->lock); -	pr_debug("waiting for more refs (num %ld, first %p)\n", -		 num_refs, first_seq); -	wait_event(fs_info->tree_mod_seq_wait, -		   num_refs != delayed_refs->num_entries || -		   fs_info->tree_mod_seq_list.next != first_seq); -	pr_debug("done waiting for more refs (num %ld, first %p)\n", -		 delayed_refs->num_entries, fs_info->tree_mod_seq_list.next); -	spin_lock(&delayed_refs->lock); -} -  #ifdef SCRAMBLE_DELAYED_REFS  /*   * Normally delayed refs get processed in ascending bytenr order. This @@ -2460,13 +2465,11 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,  	struct btrfs_delayed_ref_root *delayed_refs;  	struct btrfs_delayed_ref_node *ref;  	struct list_head cluster; -	struct list_head *first_seq = NULL;  	int ret;  	u64 delayed_start;  	int run_all = count == (unsigned long)-1;  	int run_most = 0; -	unsigned long num_refs = 0; -	int consider_waiting; +	int loops;  	/* We'll clean this up in btrfs_cleanup_transaction */  	if (trans->aborted) @@ -2484,7 +2487,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,  	delayed_refs = &trans->transaction->delayed_refs;  	INIT_LIST_HEAD(&cluster);  again: -	consider_waiting = 0; +	loops = 0;  	spin_lock(&delayed_refs->lock);  #ifdef SCRAMBLE_DELAYED_REFS @@ -2512,31 +2515,6 @@ again:  		if (ret)  			break; -		if (delayed_start >= delayed_refs->run_delayed_start) { -			if (consider_waiting == 0) { -				/* -				 * btrfs_find_ref_cluster looped. let's do one -				 * more cycle. if we don't run any delayed ref -				 * during that cycle (because we can't because -				 * all of them are blocked) and if the number of -				 * refs doesn't change, we avoid busy waiting. -				 */ -				consider_waiting = 1; -				num_refs = delayed_refs->num_entries; -				first_seq = root->fs_info->tree_mod_seq_list.next; -			} else { -				wait_for_more_refs(root->fs_info, delayed_refs, -						   num_refs, first_seq); -				/* -				 * after waiting, things have changed. we -				 * dropped the lock and someone else might have -				 * run some refs, built new clusters and so on. -				 * therefore, we restart staleness detection. -				 */ -				consider_waiting = 0; -			} -		} -  		ret = run_clustered_refs(trans, root, &cluster);  		if (ret < 0) {  			spin_unlock(&delayed_refs->lock); @@ -2549,9 +2527,26 @@ again:  		if (count == 0)  			break; -		if (ret || delayed_refs->run_delayed_start == 0) { +		if (delayed_start >= delayed_refs->run_delayed_start) { +			if (loops == 0) { +				/* +				 * btrfs_find_ref_cluster looped. let's do one +				 * more cycle. if we don't run any delayed ref +				 * during that cycle (because we can't because +				 * all of them are blocked), bail out. +				 */ +				loops = 1; +			} else { +				/* +				 * no runnable refs left, stop trying +				 */ +				BUG_ON(run_all); +				break; +			} +		} +		if (ret) {  			/* refs were run, let's reset staleness detection */ -			consider_waiting = 0; +			loops = 0;  		}  	} @@ -3007,17 +3002,16 @@ again:  	}  	spin_unlock(&block_group->lock); -	num_pages = (int)div64_u64(block_group->key.offset, 1024 * 1024 * 1024); +	/* +	 * Try to preallocate enough space based on how big the block group is. +	 * Keep in mind this has to include any pinned space which could end up +	 * taking up quite a bit since it's not folded into the other space +	 * cache. +	 */ +	num_pages = (int)div64_u64(block_group->key.offset, 256 * 1024 * 1024);  	if (!num_pages)  		num_pages = 1; -	/* -	 * Just to make absolutely sure we have enough space, we're going to -	 * preallocate 12 pages worth of space for each block group.  In -	 * practice we ought to use at most 8, but we need extra space so we can -	 * add our header and have a terminator between the extents and the -	 * bitmaps. -	 */  	num_pages *= 16;  	num_pages *= PAGE_CACHE_SIZE; @@ -4571,8 +4565,10 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)  	if (root->fs_info->quota_enabled) {  		ret = btrfs_qgroup_reserve(root, num_bytes +  					   nr_extents * root->leafsize); -		if (ret) +		if (ret) { +			mutex_unlock(&BTRFS_I(inode)->delalloc_mutex);  			return ret; +		}  	}  	ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush); @@ -5294,9 +5290,6 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,  	rb_erase(&head->node.rb_node, &delayed_refs->root);  	delayed_refs->num_entries--; -	smp_mb(); -	if (waitqueue_active(&root->fs_info->tree_mod_seq_wait)) -		wake_up(&root->fs_info->tree_mod_seq_wait);  	/*  	 * we don't take a ref on the node because we're removing it from the diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 45c81bb4ac8..4c878476bb9 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2330,23 +2330,10 @@ static void end_bio_extent_readpage(struct bio *bio, int err)  		if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {  			ret = tree->ops->readpage_end_io_hook(page, start, end,  							      state, mirror); -			if (ret) { -				/* no IO indicated but software detected errors -				 * in the block, either checksum errors or -				 * issues with the contents */ -				struct btrfs_root *root = -					BTRFS_I(page->mapping->host)->root; -				struct btrfs_device *device; - +			if (ret)  				uptodate = 0; -				device = btrfs_find_device_for_logical( -						root, start, mirror); -				if (device) -					btrfs_dev_stat_inc_and_print(device, -						BTRFS_DEV_STAT_CORRUPTION_ERRS); -			} else { +			else  				clean_io_failure(start, page); -			}  		}  		if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index b45b9de0c21..857d93cd01d 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -272,9 +272,9 @@ int btrfs_lookup_bio_sums(struct btrfs_root *root, struct inode *inode,  }  int btrfs_lookup_bio_sums_dio(struct btrfs_root *root, struct inode *inode, -			      struct bio *bio, u64 offset, u32 *dst) +			      struct bio *bio, u64 offset)  { -	return __btrfs_lookup_bio_sums(root, inode, bio, offset, dst, 1); +	return __btrfs_lookup_bio_sums(root, inode, bio, offset, NULL, 1);  }  int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6e8f416773d..ec154f95464 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1008,9 +1008,7 @@ static noinline void async_cow_submit(struct btrfs_work *work)  	nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >>  		PAGE_CACHE_SHIFT; -	atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages); - -	if (atomic_read(&root->fs_info->async_delalloc_pages) < +	if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) <  	    5 * 1024 * 1024 &&  	    waitqueue_active(&root->fs_info->async_submit_wait))  		wake_up(&root->fs_info->async_submit_wait); @@ -1885,8 +1883,11 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)  				trans = btrfs_join_transaction_nolock(root);  			else  				trans = btrfs_join_transaction(root); -			if (IS_ERR(trans)) -				return PTR_ERR(trans); +			if (IS_ERR(trans)) { +				ret = PTR_ERR(trans); +				trans = NULL; +				goto out; +			}  			trans->block_rsv = &root->fs_info->delalloc_block_rsv;  			ret = btrfs_update_inode_fallback(trans, root, inode);  			if (ret) /* -ENOMEM or corruption */ @@ -3174,7 +3175,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,  	btrfs_i_size_write(dir, dir->i_size - name_len * 2);  	inode_inc_iversion(dir);  	dir->i_mtime = dir->i_ctime = CURRENT_TIME; -	ret = btrfs_update_inode(trans, root, dir); +	ret = btrfs_update_inode_fallback(trans, root, dir);  	if (ret)  		btrfs_abort_transaction(trans, root, ret);  out: @@ -5774,18 +5775,112 @@ out:  	return ret;  } +static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend, +			      struct extent_state **cached_state, int writing) +{ +	struct btrfs_ordered_extent *ordered; +	int ret = 0; + +	while (1) { +		lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, +				 0, cached_state); +		/* +		 * We're concerned with the entire range that we're going to be +		 * doing DIO to, so we need to make sure theres no ordered +		 * extents in this range. +		 */ +		ordered = btrfs_lookup_ordered_range(inode, lockstart, +						     lockend - lockstart + 1); + +		/* +		 * We need to make sure there are no buffered pages in this +		 * range either, we could have raced between the invalidate in +		 * generic_file_direct_write and locking the extent.  The +		 * invalidate needs to happen so that reads after a write do not +		 * get stale data. +		 */ +		if (!ordered && (!writing || +		    !test_range_bit(&BTRFS_I(inode)->io_tree, +				    lockstart, lockend, EXTENT_UPTODATE, 0, +				    *cached_state))) +			break; + +		unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, +				     cached_state, GFP_NOFS); + +		if (ordered) { +			btrfs_start_ordered_extent(inode, ordered, 1); +			btrfs_put_ordered_extent(ordered); +		} else { +			/* Screw you mmap */ +			ret = filemap_write_and_wait_range(inode->i_mapping, +							   lockstart, +							   lockend); +			if (ret) +				break; + +			/* +			 * If we found a page that couldn't be invalidated just +			 * fall back to buffered. +			 */ +			ret = invalidate_inode_pages2_range(inode->i_mapping, +					lockstart >> PAGE_CACHE_SHIFT, +					lockend >> PAGE_CACHE_SHIFT); +			if (ret) +				break; +		} + +		cond_resched(); +	} + +	return ret; +} +  static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,  				   struct buffer_head *bh_result, int create)  {  	struct extent_map *em;  	struct btrfs_root *root = BTRFS_I(inode)->root; +	struct extent_state *cached_state = NULL;  	u64 start = iblock << inode->i_blkbits; +	u64 lockstart, lockend;  	u64 len = bh_result->b_size;  	struct btrfs_trans_handle *trans; +	int unlock_bits = EXTENT_LOCKED; +	int ret; + +	if (create) { +		ret = btrfs_delalloc_reserve_space(inode, len); +		if (ret) +			return ret; +		unlock_bits |= EXTENT_DELALLOC | EXTENT_DIRTY; +	} else { +		len = min_t(u64, len, root->sectorsize); +	} + +	lockstart = start; +	lockend = start + len - 1; + +	/* +	 * If this errors out it's because we couldn't invalidate pagecache for +	 * this range and we need to fallback to buffered. +	 */ +	if (lock_extent_direct(inode, lockstart, lockend, &cached_state, create)) +		return -ENOTBLK; + +	if (create) { +		ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, +				     lockend, EXTENT_DELALLOC, NULL, +				     &cached_state, GFP_NOFS); +		if (ret) +			goto unlock_err; +	}  	em = btrfs_get_extent(inode, NULL, 0, start, len, 0); -	if (IS_ERR(em)) -		return PTR_ERR(em); +	if (IS_ERR(em)) { +		ret = PTR_ERR(em); +		goto unlock_err; +	}  	/*  	 * Ok for INLINE and COMPRESSED extents we need to fallback on buffered @@ -5804,17 +5899,16 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,  	if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) ||  	    em->block_start == EXTENT_MAP_INLINE) {  		free_extent_map(em); -		return -ENOTBLK; +		ret = -ENOTBLK; +		goto unlock_err;  	}  	/* Just a good old fashioned hole, return */  	if (!create && (em->block_start == EXTENT_MAP_HOLE ||  			test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {  		free_extent_map(em); -		/* DIO will do one hole at a time, so just unlock a sector */ -		unlock_extent(&BTRFS_I(inode)->io_tree, start, -			      start + root->sectorsize - 1); -		return 0; +		ret = 0; +		goto unlock_err;  	}  	/* @@ -5827,8 +5921,9 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,  	 *  	 */  	if (!create) { -		len = em->len - (start - em->start); -		goto map; +		len = min(len, em->len - (start - em->start)); +		lockstart = start + len; +		goto unlock;  	}  	if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) || @@ -5860,7 +5955,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,  			btrfs_end_transaction(trans, root);  			if (ret) {  				free_extent_map(em); -				return ret; +				goto unlock_err;  			}  			goto unlock;  		} @@ -5873,14 +5968,12 @@ must_cow:  	 */  	len = bh_result->b_size;  	em = btrfs_new_extent_direct(inode, em, start, len); -	if (IS_ERR(em)) -		return PTR_ERR(em); +	if (IS_ERR(em)) { +		ret = PTR_ERR(em); +		goto unlock_err; +	}  	len = min(len, em->len - (start - em->start));  unlock: -	clear_extent_bit(&BTRFS_I(inode)->io_tree, start, start + len - 1, -			  EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DIRTY, 1, -			  0, NULL, GFP_NOFS); -map:  	bh_result->b_blocknr = (em->block_start + (start - em->start)) >>  		inode->i_blkbits;  	bh_result->b_size = len; @@ -5898,9 +5991,44 @@ map:  			i_size_write(inode, start + len);  	} +	/* +	 * In the case of write we need to clear and unlock the entire range, +	 * in the case of read we need to unlock only the end area that we +	 * aren't using if there is any left over space. +	 */ +	if (lockstart < lockend) { +		if (create && len < lockend - lockstart) { +			clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, +					 lockstart + len - 1, unlock_bits, 1, 0, +					 &cached_state, GFP_NOFS); +			/* +			 * Beside unlock, we also need to cleanup reserved space +			 * for the left range by attaching EXTENT_DO_ACCOUNTING. +			 */ +			clear_extent_bit(&BTRFS_I(inode)->io_tree, +					 lockstart + len, lockend, +					 unlock_bits | EXTENT_DO_ACCOUNTING, +					 1, 0, NULL, GFP_NOFS); +		} else { +			clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, +					 lockend, unlock_bits, 1, 0, +					 &cached_state, GFP_NOFS); +		} +	} else { +		free_extent_state(cached_state); +	} +  	free_extent_map(em);  	return 0; + +unlock_err: +	if (create) +		unlock_bits |= EXTENT_DO_ACCOUNTING; + +	clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, +			 unlock_bits, 1, 0, &cached_state, GFP_NOFS); +	return ret;  }  struct btrfs_dio_private { @@ -5908,7 +6036,6 @@ struct btrfs_dio_private {  	u64 logical_offset;  	u64 disk_bytenr;  	u64 bytes; -	u32 *csums;  	void *private;  	/* number of bios pending for this dio */ @@ -5928,7 +6055,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)  	struct inode *inode = dip->inode;  	struct btrfs_root *root = BTRFS_I(inode)->root;  	u64 start; -	u32 *private = dip->csums;  	start = dip->logical_offset;  	do { @@ -5936,8 +6062,12 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)  			struct page *page = bvec->bv_page;  			char *kaddr;  			u32 csum = ~(u32)0; +			u64 private = ~(u32)0;  			unsigned long flags; +			if (get_state_private(&BTRFS_I(inode)->io_tree, +					      start, &private)) +				goto failed;  			local_irq_save(flags);  			kaddr = kmap_atomic(page);  			csum = btrfs_csum_data(root, kaddr + bvec->bv_offset, @@ -5947,18 +6077,18 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)  			local_irq_restore(flags);  			flush_dcache_page(bvec->bv_page); -			if (csum != *private) { +			if (csum != private) { +failed:  				printk(KERN_ERR "btrfs csum failed ino %llu off"  				      " %llu csum %u private %u\n",  				      (unsigned long long)btrfs_ino(inode),  				      (unsigned long long)start, -				      csum, *private); +				      csum, (unsigned)private);  				err = -EIO;  			}  		}  		start += bvec->bv_len; -		private++;  		bvec++;  	} while (bvec <= bvec_end); @@ -5966,7 +6096,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)  		      dip->logical_offset + dip->bytes - 1);  	bio->bi_private = dip->private; -	kfree(dip->csums);  	kfree(dip);  	/* If we had a csum failure make sure to clear the uptodate flag */ @@ -6072,7 +6201,7 @@ static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev,  static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,  					 int rw, u64 file_offset, int skip_sum, -					 u32 *csums, int async_submit) +					 int async_submit)  {  	int write = rw & REQ_WRITE;  	struct btrfs_root *root = BTRFS_I(inode)->root; @@ -6105,8 +6234,7 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,  		if (ret)  			goto err;  	} else if (!skip_sum) { -		ret = btrfs_lookup_bio_sums_dio(root, inode, bio, -					  file_offset, csums); +		ret = btrfs_lookup_bio_sums_dio(root, inode, bio, file_offset);  		if (ret)  			goto err;  	} @@ -6132,10 +6260,8 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,  	u64 submit_len = 0;  	u64 map_length;  	int nr_pages = 0; -	u32 *csums = dip->csums;  	int ret = 0;  	int async_submit = 0; -	int write = rw & REQ_WRITE;  	map_length = orig_bio->bi_size;  	ret = btrfs_map_block(map_tree, READ, start_sector << 9, @@ -6171,16 +6297,13 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,  			atomic_inc(&dip->pending_bios);  			ret = __btrfs_submit_dio_bio(bio, inode, rw,  						     file_offset, skip_sum, -						     csums, async_submit); +						     async_submit);  			if (ret) {  				bio_put(bio);  				atomic_dec(&dip->pending_bios);  				goto out_err;  			} -			/* Write's use the ordered csums */ -			if (!write && !skip_sum) -				csums = csums + nr_pages;  			start_sector += submit_len >> 9;  			file_offset += submit_len; @@ -6210,7 +6333,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,  submit:  	ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, -				     csums, async_submit); +				     async_submit);  	if (!ret)  		return 0; @@ -6246,17 +6369,6 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,  		ret = -ENOMEM;  		goto free_ordered;  	} -	dip->csums = NULL; - -	/* Write's use the ordered csum stuff, so we don't need dip->csums */ -	if (!write && !skip_sum) { -		dip->csums = kmalloc(sizeof(u32) * bio->bi_vcnt, GFP_NOFS); -		if (!dip->csums) { -			kfree(dip); -			ret = -ENOMEM; -			goto free_ordered; -		} -	}  	dip->private = bio->bi_private;  	dip->inode = inode; @@ -6341,132 +6453,22 @@ static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *io  out:  	return retval;  } +  static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,  			const struct iovec *iov, loff_t offset,  			unsigned long nr_segs)  {  	struct file *file = iocb->ki_filp;  	struct inode *inode = file->f_mapping->host; -	struct btrfs_ordered_extent *ordered; -	struct extent_state *cached_state = NULL; -	u64 lockstart, lockend; -	ssize_t ret; -	int writing = rw & WRITE; -	int write_bits = 0; -	size_t count = iov_length(iov, nr_segs);  	if (check_direct_IO(BTRFS_I(inode)->root, rw, iocb, iov, -			    offset, nr_segs)) { +			    offset, nr_segs))  		return 0; -	} - -	lockstart = offset; -	lockend = offset + count - 1; - -	if (writing) { -		ret = btrfs_delalloc_reserve_space(inode, count); -		if (ret) -			goto out; -	} - -	while (1) { -		lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, -				 0, &cached_state); -		/* -		 * We're concerned with the entire range that we're going to be -		 * doing DIO to, so we need to make sure theres no ordered -		 * extents in this range. -		 */ -		ordered = btrfs_lookup_ordered_range(inode, lockstart, -						     lockend - lockstart + 1); - -		/* -		 * We need to make sure there are no buffered pages in this -		 * range either, we could have raced between the invalidate in -		 * generic_file_direct_write and locking the extent.  The -		 * invalidate needs to happen so that reads after a write do not -		 * get stale data. -		 */ -		if (!ordered && (!writing || -		    !test_range_bit(&BTRFS_I(inode)->io_tree, -				    lockstart, lockend, EXTENT_UPTODATE, 0, -				    cached_state))) -			break; - -		unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, -				     &cached_state, GFP_NOFS); - -		if (ordered) { -			btrfs_start_ordered_extent(inode, ordered, 1); -			btrfs_put_ordered_extent(ordered); -		} else { -			/* Screw you mmap */ -			ret = filemap_write_and_wait_range(file->f_mapping, -							   lockstart, -							   lockend); -			if (ret) -				goto out; - -			/* -			 * If we found a page that couldn't be invalidated just -			 * fall back to buffered. -			 */ -			ret = invalidate_inode_pages2_range(file->f_mapping, -					lockstart >> PAGE_CACHE_SHIFT, -					lockend >> PAGE_CACHE_SHIFT); -			if (ret) { -				if (ret == -EBUSY) -					ret = 0; -				goto out; -			} -		} - -		cond_resched(); -	} -	/* -	 * we don't use btrfs_set_extent_delalloc because we don't want -	 * the dirty or uptodate bits -	 */ -	if (writing) { -		write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING; -		ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, -				     EXTENT_DELALLOC, NULL, &cached_state, -				     GFP_NOFS); -		if (ret) { -			clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, -					 lockend, EXTENT_LOCKED | write_bits, -					 1, 0, &cached_state, GFP_NOFS); -			goto out; -		} -	} - -	free_extent_state(cached_state); -	cached_state = NULL; - -	ret = __blockdev_direct_IO(rw, iocb, inode, +	return __blockdev_direct_IO(rw, iocb, inode,  		   BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,  		   iov, offset, nr_segs, btrfs_get_blocks_direct, NULL,  		   btrfs_submit_direct, 0); - -	if (ret < 0 && ret != -EIOCBQUEUED) { -		clear_extent_bit(&BTRFS_I(inode)->io_tree, offset, -			      offset + iov_length(iov, nr_segs) - 1, -			      EXTENT_LOCKED | write_bits, 1, 0, -			      &cached_state, GFP_NOFS); -	} else if (ret >= 0 && ret < iov_length(iov, nr_segs)) { -		/* -		 * We're falling back to buffered, unlock the section we didn't -		 * do IO on. -		 */ -		clear_extent_bit(&BTRFS_I(inode)->io_tree, offset + ret, -			      offset + iov_length(iov, nr_segs) - 1, -			      EXTENT_LOCKED | write_bits, 1, 0, -			      &cached_state, GFP_NOFS); -	} -out: -	free_extent_state(cached_state); -	return ret;  }  static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7bb755677a2..9df50fa8a07 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -424,7 +424,7 @@ static noinline int create_subvol(struct btrfs_root *root,  	uuid_le_gen(&new_uuid);  	memcpy(root_item.uuid, new_uuid.b, BTRFS_UUID_SIZE);  	root_item.otime.sec = cpu_to_le64(cur_time.tv_sec); -	root_item.otime.nsec = cpu_to_le64(cur_time.tv_nsec); +	root_item.otime.nsec = cpu_to_le32(cur_time.tv_nsec);  	root_item.ctime = root_item.otime;  	btrfs_set_root_ctransid(&root_item, trans->transid);  	btrfs_set_root_otransid(&root_item, trans->transid); diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index a44eff07480..2a1762c6604 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -67,7 +67,7 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)  {  	if (eb->lock_nested) {  		read_lock(&eb->lock); -		if (&eb->lock_nested && current->pid == eb->lock_owner) { +		if (eb->lock_nested && current->pid == eb->lock_owner) {  			read_unlock(&eb->lock);  			return;  		} diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index bc424ae5a81..b6501558174 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1364,8 +1364,10 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,  	spin_lock(&fs_info->qgroup_lock);  	dstgroup = add_qgroup_rb(fs_info, objectid); -	if (!dstgroup) +	if (IS_ERR(dstgroup)) { +		ret = PTR_ERR(dstgroup);  		goto unlock; +	}  	if (srcid) {  		srcgroup = find_qgroup_rb(fs_info, srcid); diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 6bb465cca20..10d8e4d8807 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -544,8 +544,8 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans,  	struct timespec ct = CURRENT_TIME;  	spin_lock(&root->root_times_lock); -	item->ctransid = trans->transid; +	item->ctransid = cpu_to_le64(trans->transid);  	item->ctime.sec = cpu_to_le64(ct.tv_sec); -	item->ctime.nsec = cpu_to_le64(ct.tv_nsec); +	item->ctime.nsec = cpu_to_le32(ct.tv_nsec);  	spin_unlock(&root->root_times_lock);  } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f2eb24c477a..83d6f9f9c22 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -838,7 +838,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)  	struct btrfs_trans_handle *trans;  	struct btrfs_fs_info *fs_info = btrfs_sb(sb);  	struct btrfs_root *root = fs_info->tree_root; -	int ret;  	trace_btrfs_sync_fs(wait); @@ -849,11 +848,17 @@ int btrfs_sync_fs(struct super_block *sb, int wait)  	btrfs_wait_ordered_extents(root, 0, 0); -	trans = btrfs_start_transaction(root, 0); +	spin_lock(&fs_info->trans_lock); +	if (!fs_info->running_transaction) { +		spin_unlock(&fs_info->trans_lock); +		return 0; +	} +	spin_unlock(&fs_info->trans_lock); + +	trans = btrfs_join_transaction(root);  	if (IS_ERR(trans))  		return PTR_ERR(trans); -	ret = btrfs_commit_transaction(trans, root); -	return ret; +	return btrfs_commit_transaction(trans, root);  }  static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) @@ -1530,6 +1535,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)  	while (cur_devices) {  		head = &cur_devices->devices;  		list_for_each_entry(dev, head, dev_list) { +			if (dev->missing) +				continue;  			if (!first_dev || dev->devid < first_dev->devid)  				first_dev = dev;  		} diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 17be3dedacb..27c26004e05 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1031,6 +1031,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,  	btrfs_i_size_write(parent_inode, parent_inode->i_size +  					 dentry->d_name.len * 2); +	parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;  	ret = btrfs_update_inode(trans, parent_root, parent_inode);  	if (ret)  		goto abort_trans_dput; @@ -1066,7 +1067,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,  	memcpy(new_root_item->parent_uuid, root->root_item.uuid,  			BTRFS_UUID_SIZE);  	new_root_item->otime.sec = cpu_to_le64(cur_time.tv_sec); -	new_root_item->otime.nsec = cpu_to_le64(cur_time.tv_nsec); +	new_root_item->otime.nsec = cpu_to_le32(cur_time.tv_nsec);  	btrfs_set_root_otransid(new_root_item, trans->transid);  	memset(&new_root_item->stime, 0, sizeof(new_root_item->stime));  	memset(&new_root_item->rtime, 0, sizeof(new_root_item->rtime)); diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e86ae04abe6..88b969aeeb7 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -227,9 +227,8 @@ loop_lock:  		cur = pending;  		pending = pending->bi_next;  		cur->bi_next = NULL; -		atomic_dec(&fs_info->nr_async_bios); -		if (atomic_read(&fs_info->nr_async_bios) < limit && +		if (atomic_dec_return(&fs_info->nr_async_bios) < limit &&  		    waitqueue_active(&fs_info->async_submit_wait))  			wake_up(&fs_info->async_submit_wait); @@ -569,9 +568,11 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)  		memcpy(new_device, device, sizeof(*new_device));  		/* Safe because we are under uuid_mutex */ -		name = rcu_string_strdup(device->name->str, GFP_NOFS); -		BUG_ON(device->name && !name); /* -ENOMEM */ -		rcu_assign_pointer(new_device->name, name); +		if (device->name) { +			name = rcu_string_strdup(device->name->str, GFP_NOFS); +			BUG_ON(device->name && !name); /* -ENOMEM */ +			rcu_assign_pointer(new_device->name, name); +		}  		new_device->bdev = NULL;  		new_device->writeable = 0;  		new_device->in_fs_metadata = 0; @@ -4605,28 +4606,6 @@ int btrfs_read_sys_array(struct btrfs_root *root)  	return ret;  } -struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root, -						   u64 logical, int mirror_num) -{ -	struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; -	int ret; -	u64 map_length = 0; -	struct btrfs_bio *bbio = NULL; -	struct btrfs_device *device; - -	BUG_ON(mirror_num == 0); -	ret = btrfs_map_block(map_tree, WRITE, logical, &map_length, &bbio, -			      mirror_num); -	if (ret) { -		BUG_ON(bbio != NULL); -		return NULL; -	} -	BUG_ON(mirror_num != bbio->mirror_num); -	device = bbio->stripes[mirror_num - 1].dev; -	kfree(bbio); -	return device; -} -  int btrfs_read_chunk_tree(struct btrfs_root *root)  {  	struct btrfs_path *path; diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 5479325987b..53c06af92e8 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -289,8 +289,6 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);  int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);  int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,  			 u64 *start, u64 *max_avail); -struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root, -						   u64 logical, int mirror_num);  void btrfs_dev_stat_print_on_error(struct btrfs_device *device);  void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);  int btrfs_get_dev_stats(struct btrfs_root *root, diff --git a/fs/buffer.c b/fs/buffer.c index 9f6d2e41281..58e2e7b7737 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -914,7 +914,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head)  /*   * Initialise the state of a blockdev page's buffers.   */  -static void +static sector_t  init_page_buffers(struct page *page, struct block_device *bdev,  			sector_t block, int size)  { @@ -936,33 +936,41 @@ init_page_buffers(struct page *page, struct block_device *bdev,  		block++;  		bh = bh->b_this_page;  	} while (bh != head); + +	/* +	 * Caller needs to validate requested block against end of device. +	 */ +	return end_block;  }  /*   * Create the page-cache page that contains the requested block.   * - * This is user purely for blockdev mappings. + * This is used purely for blockdev mappings.   */ -static struct page * +static int  grow_dev_page(struct block_device *bdev, sector_t block, -		pgoff_t index, int size) +		pgoff_t index, int size, int sizebits)  {  	struct inode *inode = bdev->bd_inode;  	struct page *page;  	struct buffer_head *bh; +	sector_t end_block; +	int ret = 0;		/* Will call free_more_memory() */  	page = find_or_create_page(inode->i_mapping, index,  		(mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE);  	if (!page) -		return NULL; +		return ret;  	BUG_ON(!PageLocked(page));  	if (page_has_buffers(page)) {  		bh = page_buffers(page);  		if (bh->b_size == size) { -			init_page_buffers(page, bdev, block, size); -			return page; +			end_block = init_page_buffers(page, bdev, +						index << sizebits, size); +			goto done;  		}  		if (!try_to_free_buffers(page))  			goto failed; @@ -982,14 +990,14 @@ grow_dev_page(struct block_device *bdev, sector_t block,  	 */  	spin_lock(&inode->i_mapping->private_lock);  	link_dev_buffers(page, bh); -	init_page_buffers(page, bdev, block, size); +	end_block = init_page_buffers(page, bdev, index << sizebits, size);  	spin_unlock(&inode->i_mapping->private_lock); -	return page; - +done: +	ret = (block < end_block) ? 1 : -ENXIO;  failed:  	unlock_page(page);  	page_cache_release(page); -	return NULL; +	return ret;  }  /* @@ -999,7 +1007,6 @@ failed:  static int  grow_buffers(struct block_device *bdev, sector_t block, int size)  { -	struct page *page;  	pgoff_t index;  	int sizebits; @@ -1023,22 +1030,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)  			bdevname(bdev, b));  		return -EIO;  	} -	block = index << sizebits; +  	/* Create a page with the proper size buffers.. */ -	page = grow_dev_page(bdev, block, index, size); -	if (!page) -		return 0; -	unlock_page(page); -	page_cache_release(page); -	return 1; +	return grow_dev_page(bdev, block, index, size, sizebits);  }  static struct buffer_head *  __getblk_slow(struct block_device *bdev, sector_t block, int size)  { -	int ret; -	struct buffer_head *bh; -  	/* Size must be multiple of hard sectorsize */  	if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||  			(size < 512 || size > PAGE_SIZE))) { @@ -1051,21 +1050,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)  		return NULL;  	} -retry: -	bh = __find_get_block(bdev, block, size); -	if (bh) -		return bh; +	for (;;) { +		struct buffer_head *bh; +		int ret; -	ret = grow_buffers(bdev, block, size); -	if (ret == 0) { -		free_more_memory(); -		goto retry; -	} else if (ret > 0) {  		bh = __find_get_block(bdev, block, size);  		if (bh)  			return bh; + +		ret = grow_buffers(bdev, block, size); +		if (ret < 0) +			return NULL; +		if (ret == 0) +			free_more_memory();  	} -	return NULL;  }  /* @@ -1321,10 +1319,6 @@ EXPORT_SYMBOL(__find_get_block);   * which corresponds to the passed block_device, block and size. The   * returned buffer has its reference count incremented.   * - * __getblk() cannot fail - it just keeps trying.  If you pass it an - * illegal block number, __getblk() will happily return a buffer_head - * which represents the non-existent block.  Very weird. - *   * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers()   * attempt is failing.  FIXME, perhaps?   */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 074923ce593..f0cf934ba87 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1576,9 +1576,14 @@ cifs_readv_callback(struct mid_q_entry *mid)  		/* result already set, check signature */  		if (server->sec_mode &  		    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { -			if (cifs_verify_signature(rdata->iov, rdata->nr_iov, -					  server, mid->sequence_number + 1)) -				cERROR(1, "Unexpected SMB signature"); +			int rc = 0; + +			rc = cifs_verify_signature(rdata->iov, rdata->nr_iov, +						   server, +						   mid->sequence_number + 1); +			if (rc) +				cERROR(1, "SMB signature verification returned " +				       "error = %d", rc);  		}  		/* FIXME: should this be counted toward the initiating task? */  		task_io_account_read(rdata->bytes); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index cbe709ad666..781025be48b 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -356,19 +356,12 @@ cifs_create_get_file_info:  cifs_create_set_dentry:  	if (rc != 0) {  		cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); +		CIFSSMBClose(xid, tcon, *fileHandle);  		goto out;  	}  	d_drop(direntry);  	d_add(direntry, newinode); -	/* ENOENT for create?  How weird... */ -	rc = -ENOENT; -	if (!newinode) { -		CIFSSMBClose(xid, tcon, *fileHandle); -		goto out; -	} -	rc = 0; -  out:  	kfree(buf);  	kfree(full_path); 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/inode.c b/fs/cifs/inode.c index 7354877fa3b..cb79c7edecb 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -124,10 +124,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)  {  	struct cifsInodeInfo *cifs_i = CIFS_I(inode);  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); -	unsigned long oldtime = cifs_i->time;  	cifs_revalidate_cache(inode, fattr); +	spin_lock(&inode->i_lock);  	inode->i_atime = fattr->cf_atime;  	inode->i_mtime = fattr->cf_mtime;  	inode->i_ctime = fattr->cf_ctime; @@ -148,9 +148,6 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)  	else  		cifs_i->time = jiffies; -	cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode, -		 oldtime, cifs_i->time); -  	cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;  	cifs_i->server_eof = fattr->cf_eof; @@ -158,7 +155,6 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)  	 * Can't safely change the file size here if the client is writing to  	 * it due to potential races.  	 */ -	spin_lock(&inode->i_lock);  	if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {  		i_size_write(inode, fattr->cf_eof); @@ -859,12 +855,14 @@ struct inode *cifs_root_iget(struct super_block *sb)  	if (rc && tcon->ipc) {  		cFYI(1, "ipc connection - fake read inode"); +		spin_lock(&inode->i_lock);  		inode->i_mode |= S_IFDIR;  		set_nlink(inode, 2);  		inode->i_op = &cifs_ipc_inode_ops;  		inode->i_fop = &simple_dir_operations;  		inode->i_uid = cifs_sb->mnt_uid;  		inode->i_gid = cifs_sb->mnt_gid; +		spin_unlock(&inode->i_lock);  	} else if (rc) {  		iget_failed(inode);  		inode = ERR_PTR(rc); @@ -1110,6 +1108,15 @@ undo_setattr:  	goto out_close;  } +/* copied from fs/nfs/dir.c with small changes */ +static void +cifs_drop_nlink(struct inode *inode) +{ +	spin_lock(&inode->i_lock); +	if (inode->i_nlink > 0) +		drop_nlink(inode); +	spin_unlock(&inode->i_lock); +}  /*   * If dentry->d_inode is null (usually meaning the cached dentry @@ -1166,13 +1173,13 @@ retry_std_delete:  psx_del_no_retry:  	if (!rc) {  		if (inode) -			drop_nlink(inode); +			cifs_drop_nlink(inode);  	} else if (rc == -ENOENT) {  		d_drop(dentry);  	} else if (rc == -ETXTBSY) {  		rc = cifs_rename_pending_delete(full_path, dentry, xid);  		if (rc == 0) -			drop_nlink(inode); +			cifs_drop_nlink(inode);  	} else if ((rc == -EACCES) && (dosattr == 0) && inode) {  		attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);  		if (attrs == NULL) { @@ -1241,9 +1248,10 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,  	 * setting nlink not necessary except in cases where we failed to get it  	 * from the server or was set bogus  	 */ +	spin_lock(&dentry->d_inode->i_lock);  	if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2))  		set_nlink(dentry->d_inode, 2); - +	spin_unlock(&dentry->d_inode->i_lock);  	mode &= ~current_umask();  	/* must turn on setgid bit if parent dir has it */  	if (inode->i_mode & S_ISGID) diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 09e4b3ae456..e6ce3b11287 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -433,7 +433,9 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,  	if (old_file->d_inode) {  		cifsInode = CIFS_I(old_file->d_inode);  		if (rc == 0) { +			spin_lock(&old_file->d_inode->i_lock);  			inc_nlink(old_file->d_inode); +			spin_unlock(&old_file->d_inode->i_lock);  /* BB should we make this contingent on superblock flag NOATIME? */  /*			old_file->d_inode->i_ctime = CURRENT_TIME;*/  			/* parent dir timestamps will update from srv diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index a4ff5d54755..e4d3b996416 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -52,7 +52,8 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)  			cERROR(1, "Bad protocol string signature header %x",  				  *(unsigned int *) hdr->ProtocolId);  		if (mid != hdr->MessageId) -			cERROR(1, "Mids do not match"); +			cERROR(1, "Mids do not match: %llu and %llu", mid, +				  hdr->MessageId);  	}  	cERROR(1, "Bad SMB detected. The Mid=%llu", hdr->MessageId);  	return 1; @@ -107,7 +108,7 @@ smb2_check_message(char *buf, unsigned int length)  	 * ie Validate the wct via smb2_struct_sizes table above  	 */ -	if (length < 2 + sizeof(struct smb2_hdr)) { +	if (length < sizeof(struct smb2_pdu)) {  		if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {  			pdu->StructureSize2 = 0;  			/* @@ -121,15 +122,15 @@ smb2_check_message(char *buf, unsigned int length)  		return 1;  	}  	if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) { -		cERROR(1, "SMB length greater than maximum, mid=%lld", mid); +		cERROR(1, "SMB length greater than maximum, mid=%llu", mid);  		return 1;  	}  	if (check_smb2_hdr(hdr, mid))  		return 1; -	if (hdr->StructureSize != SMB2_HEADER_SIZE) { -		cERROR(1, "Illegal structure size %d", +	if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) { +		cERROR(1, "Illegal structure size %u",  			  le16_to_cpu(hdr->StructureSize));  		return 1;  	} @@ -161,8 +162,9 @@ smb2_check_message(char *buf, unsigned int length)  	if (4 + len != clc_len) {  		cFYI(1, "Calculated size %u length %u mismatch mid %llu",  			clc_len, 4 + len, mid); -		if (clc_len == 4 + len + 1) /* BB FIXME (fix samba) */ -			return 0; /* BB workaround Samba 3 bug SessSetup rsp */ +		/* server can return one byte more */ +		if (clc_len == 4 + len + 1) +			return 0;  		return 1;  	}  	return 0; diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index f37a1b41b40..15dc8eea827 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -87,10 +87,6 @@  #define SMB2_PROTO_NUMBER __constant_cpu_to_le32(0x424d53fe) -#define SMB2_HEADER_SIZE __constant_le16_to_cpu(64) - -#define SMB2_ERROR_STRUCTURE_SIZE2 __constant_le16_to_cpu(9) -  /*   * SMB2 Header Definition   * @@ -99,6 +95,9 @@   * "PDU" :  "Protocol Data Unit" (ie a network "frame")   *   */ + +#define SMB2_HEADER_STRUCTURE_SIZE __constant_cpu_to_le16(64) +  struct smb2_hdr {  	__be32 smb2_buf_length;	/* big endian on wire */  				/* length is only two or three bytes - with @@ -140,6 +139,9 @@ struct smb2_pdu {   *  command code name for the struct. Note that structures must be packed.   *   */ + +#define SMB2_ERROR_STRUCTURE_SIZE2 __constant_cpu_to_le16(9) +  struct smb2_err_rsp {  	struct smb2_hdr hdr;  	__le16 StructureSize; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 83867ef348d..d9b639b95fa 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -503,13 +503,16 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,  	/* convert the length into a more usable form */  	if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {  		struct kvec iov; +		int rc = 0;  		iov.iov_base = mid->resp_buf;  		iov.iov_len = len;  		/* FIXME: add code to kill session */ -		if (cifs_verify_signature(&iov, 1, server, -					  mid->sequence_number + 1) != 0) -			cERROR(1, "Unexpected SMB signature"); +		rc = cifs_verify_signature(&iov, 1, server, +					   mid->sequence_number + 1); +		if (rc) +			cERROR(1, "SMB signature verification returned error = " +			       "%d", rc);  	}  	/* BB special case reconnect tid and uid here? */ diff --git a/fs/direct-io.c b/fs/direct-io.c index 1faf4cb56f3..f86c720dba0 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1062,6 +1062,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,  	unsigned long user_addr;  	size_t bytes;  	struct buffer_head map_bh = { 0, }; +	struct blk_plug plug;  	if (rw & WRITE)  		rw = WRITE_ODIRECT; @@ -1177,6 +1178,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,  				PAGE_SIZE - user_addr / PAGE_SIZE);  	} +	blk_start_plug(&plug); +  	for (seg = 0; seg < nr_segs; seg++) {  		user_addr = (unsigned long)iov[seg].iov_base;  		sdio.size += bytes = iov[seg].iov_len; @@ -1235,6 +1238,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,  	if (sdio.bio)  		dio_bio_submit(dio, &sdio); +	blk_finish_plug(&plug); +  	/*  	 * It is possible that, we return short IO due to end of file.  	 * In that case, we need to release all the pages we got hold on. 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/jbd/journal.c b/fs/jbd/journal.c index 09357508ec9..a2862339323 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -1113,6 +1113,11 @@ static void mark_journal_empty(journal_t *journal)  	BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));  	spin_lock(&journal->j_state_lock); +	/* Is it already empty? */ +	if (sb->s_start == 0) { +		spin_unlock(&journal->j_state_lock); +		return; +	}  	jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n",          	  journal->j_tail_sequence); diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index df0de27c273..e784a217b50 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -26,6 +26,7 @@ static int sync_request(struct page *page, struct block_device *bdev, int rw)  	struct completion complete;  	bio_init(&bio); +	bio.bi_max_vecs = 1;  	bio.bi_io_vec = &bio_vec;  	bio_vec.bv_page = page;  	bio_vec.bv_len = PAGE_SIZE; @@ -95,12 +96,11 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,  	struct address_space *mapping = super->s_mapping_inode->i_mapping;  	struct bio *bio;  	struct page *page; -	struct request_queue *q = bdev_get_queue(sb->s_bdev); -	unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); +	unsigned int max_pages;  	int i; -	if (max_pages > BIO_MAX_PAGES) -		max_pages = BIO_MAX_PAGES; +	max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); +  	bio = bio_alloc(GFP_NOFS, max_pages);  	BUG_ON(!bio); @@ -190,12 +190,11 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,  {  	struct logfs_super *super = logfs_super(sb);  	struct bio *bio; -	struct request_queue *q = bdev_get_queue(sb->s_bdev); -	unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); +	unsigned int max_pages;  	int i; -	if (max_pages > BIO_MAX_PAGES) -		max_pages = BIO_MAX_PAGES; +	max_pages = min(nr_pages, (size_t) bio_get_nr_vecs(super->s_bdev)); +  	bio = bio_alloc(GFP_NOFS, max_pages);  	BUG_ON(!bio); diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index a422f42238b..6984562738d 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c @@ -156,10 +156,26 @@ static void __logfs_destroy_inode(struct inode *inode)  	call_rcu(&inode->i_rcu, logfs_i_callback);  } +static void __logfs_destroy_meta_inode(struct inode *inode) +{ +	struct logfs_inode *li = logfs_inode(inode); +	BUG_ON(li->li_block); +	call_rcu(&inode->i_rcu, logfs_i_callback); +} +  static void logfs_destroy_inode(struct inode *inode)  {  	struct logfs_inode *li = logfs_inode(inode); +	if (inode->i_ino < LOGFS_RESERVED_INOS) { +		/* +		 * The reserved inodes are never destroyed unless we are in +		 * unmont path. +		 */ +		__logfs_destroy_meta_inode(inode); +		return; +	} +  	BUG_ON(list_empty(&li->li_freeing_list));  	spin_lock(&logfs_inode_lock);  	li->li_refcount--; @@ -373,8 +389,8 @@ static void logfs_put_super(struct super_block *sb)  {  	struct logfs_super *super = logfs_super(sb);  	/* kill the meta-inodes */ -	iput(super->s_master_inode);  	iput(super->s_segfile_inode); +	iput(super->s_master_inode);  	iput(super->s_mapping_inode);  } diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 1e1c369df22..2a09b8d7398 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c @@ -565,7 +565,7 @@ static void write_wbuf(struct super_block *sb, struct logfs_area *area,  	index = ofs >> PAGE_SHIFT;  	page_ofs = ofs & (PAGE_SIZE - 1); -	page = find_lock_page(mapping, index); +	page = find_or_create_page(mapping, index, GFP_NOFS);  	BUG_ON(!page);  	memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);  	unlock_page(page); diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index f1cb512c501..5be0abef603 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -2189,7 +2189,6 @@ void logfs_evict_inode(struct inode *inode)  		return;  	} -	BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);  	page = inode_to_page(inode);  	BUG_ON(!page); /* FIXME: Use emergency page */  	logfs_put_write_page(page); diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index e28d090c98d..038da099179 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c @@ -886,7 +886,7 @@ static struct logfs_area *alloc_area(struct super_block *sb)  static void map_invalidatepage(struct page *page, unsigned long l)  { -	BUG(); +	return;  }  static int map_releasepage(struct page *page, gfp_t g) 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/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index cbaf4f8bb7b..4c7bd35b187 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -651,12 +651,12 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c  	if (clp->cl_minorversion == 0) {  		if (!clp->cl_cred.cr_principal && -				(clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) +				(clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5))  			return -EINVAL;  		args.client_name = clp->cl_cred.cr_principal;  		args.prognumber	= conn->cb_prog,  		args.protocol = XPRT_TRANSPORT_TCP; -		args.authflavor = clp->cl_flavor; +		args.authflavor = clp->cl_cred.cr_flavor;  		clp->cl_cb_ident = conn->cb_ident;  	} else {  		if (!conn->cb_xprt) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index e6173147f98..22bd0a66c35 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -231,7 +231,6 @@ struct nfs4_client {  	nfs4_verifier		cl_verifier; 	/* generated by client */  	time_t                  cl_time;        /* time of last lease renewal */  	struct sockaddr_storage	cl_addr; 	/* client ipaddress */ -	u32			cl_flavor;	/* setclientid pseudoflavor */  	struct svc_cred		cl_cred; 	/* setclientid principal */  	clientid_t		cl_clientid;	/* generated by server */  	nfs4_verifier		cl_confirm;	/* generated by server */ diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 36a29b753c7..c495a3055e2 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1589,10 +1589,10 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)  		goto out;  	} -	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)  		warn[cnt].w_type = QUOTA_NL_NOWARN; +	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);  	spin_lock(&dq_data_lock);  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {  		if (!dquots[cnt]) diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4c0c7d163d1..a98b7740a0f 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -1334,9 +1334,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,  	else if (bitmap == 0)  		block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; -	reiserfs_write_unlock(sb);  	bh = sb_bread(sb, block); -	reiserfs_write_lock(sb);  	if (bh == NULL)  		reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) "  		                 "reading failed", __func__, block); diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a6d4268fb6c..855da58db14 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -76,10 +76,10 @@ void reiserfs_evict_inode(struct inode *inode)  		;  	}        out: +	reiserfs_write_unlock_once(inode->i_sb, depth);  	clear_inode(inode);	/* note this must go after the journal_end to prevent deadlock */  	dquot_drop(inode);  	inode->i_blocks = 0; -	reiserfs_write_unlock_once(inode->i_sb, depth);  	return;  no_delete: 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/ubifs/debug.h b/fs/ubifs/debug.h index 8b8cc4e945f..760de723dad 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h @@ -167,7 +167,7 @@ struct ubifs_global_debug_info {  #define ubifs_dbg_msg(type, fmt, ...) \  	pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) -#define DBG_KEY_BUF_LEN 32 +#define DBG_KEY_BUF_LEN 48  #define ubifs_dbg_msg_key(type, key, fmt, ...) do {                            \  	char __tmp_key_buf[DBG_KEY_BUF_LEN];                                   \  	pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__,             \ diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index ce33b2beb15..8640920766e 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c @@ -1749,7 +1749,10 @@ int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr)  	return 0;  out_err: -	ubifs_lpt_free(c, 0); +	if (wr) +		ubifs_lpt_free(c, 1); +	if (rd) +		ubifs_lpt_free(c, 0);  	return err;  } diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index c30d976b4be..edeec499c04 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -788,7 +788,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,  corrupted_rescan:  	/* Re-scan the corrupted data with verbose messages */ -	ubifs_err("corruptio %d", ret); +	ubifs_err("corruption %d", ret);  	ubifs_scan_a_node(c, buf, len, lnum, offs, 1);  corrupted:  	ubifs_scanned_corruption(c, lnum, offs, buf); diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index eba46d4a761..94d78fc5d4e 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -1026,7 +1026,6 @@ int ubifs_replay_journal(struct ubifs_info *c)  	c->replaying = 1;  	lnum = c->ltail_lnum = c->lhead_lnum; -	lnum = UBIFS_LOG_LNUM;  	do {  		err = replay_log_leb(c, lnum, 0, c->sbuf);  		if (err == 1) @@ -1035,7 +1034,7 @@ int ubifs_replay_journal(struct ubifs_info *c)  		if (err)  			goto out;  		lnum = ubifs_next_log_lnum(c, lnum); -	} while (lnum != UBIFS_LOG_LNUM); +	} while (lnum != c->ltail_lnum);  	err = replay_buds(c);  	if (err) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index c3fa6c5327a..71a197f0f93 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1157,9 +1157,6 @@ static int check_free_space(struct ubifs_info *c)   *   * This function mounts UBIFS file system. Returns zero in case of success and   * a negative error code in case of failure. - * - * Note, the function does not de-allocate resources it it fails half way - * through, and the caller has to do this instead.   */  static int mount_ubifs(struct ubifs_info *c)  { 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/fs/udf/inode.c b/fs/udf/inode.c index fafaad795cd..aa233469b3c 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1124,14 +1124,17 @@ int udf_setsize(struct inode *inode, loff_t newsize)  				if (err)  					return err;  				down_write(&iinfo->i_data_sem); -			} else +			} else {  				iinfo->i_lenAlloc = newsize; +				goto set_size; +			}  		}  		err = udf_extend_file(inode, newsize);  		if (err) {  			up_write(&iinfo->i_data_sem);  			return err;  		} +set_size:  		truncate_setsize(inode, newsize);  		up_write(&iinfo->i_data_sem);  	} else { diff --git a/fs/udf/super.c b/fs/udf/super.c index dcbf98722af..18fc038a438 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1344,6 +1344,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,  		udf_err(sb, "error loading logical volume descriptor: "  			"Partition table too long (%u > %lu)\n", table_len,  			sb->s_blocksize - sizeof(*lvd)); +		ret = 1;  		goto out_bh;  	} @@ -1388,8 +1389,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block,  						UDF_ID_SPARABLE,  						strlen(UDF_ID_SPARABLE))) {  				if (udf_load_sparable_map(sb, map, -				    (struct sparablePartitionMap *)gpm) < 0) +				    (struct sparablePartitionMap *)gpm) < 0) { +					ret = 1;  					goto out_bh; +				}  			} else if (!strncmp(upm2->partIdent.ident,  						UDF_ID_METADATA,  						strlen(UDF_ID_METADATA))) { @@ -2000,6 +2003,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)  			if (!silent)  				pr_notice("Rescanning with blocksize %d\n",  					  UDF_DEFAULT_BLOCKSIZE); +			brelse(sbi->s_lvid_bh); +			sbi->s_lvid_bh = NULL;  			uopt.blocksize = UDF_DEFAULT_BLOCKSIZE;  			ret = udf_load_vrs(sb, &uopt, silent, &fileset);  		} diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index f9c3fe304a1..69cf4fcde03 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -179,12 +179,14 @@ xfs_ioc_trim(  	 * used by the fstrim application.  In the end it really doesn't  	 * matter as trimming blocks is an advisory interface.  	 */ +	if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) || +	    range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp))) +		return -XFS_ERROR(EINVAL); +  	start = BTOBB(range.start);  	end = start + BTOBBT(range.len) - 1;  	minlen = BTOBB(max_t(u64, granularity, range.minlen)); -	if (XFS_BB_TO_FSB(mp, start) >= mp->m_sb.sb_dblocks) -		return -XFS_ERROR(EINVAL);  	if (end > XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) - 1)  		end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)- 1; diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 21e37b55f7e..5aceb3f8ecd 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -962,23 +962,22 @@ xfs_dialloc(  		if (!pag->pagi_freecount && !okalloc)  			goto nextag; +		/* +		 * Then read in the AGI buffer and recheck with the AGI buffer +		 * lock held. +		 */  		error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);  		if (error)  			goto out_error; -		/* -		 * Once the AGI has been read in we have to recheck -		 * pagi_freecount with the AGI buffer lock held. -		 */  		if (pag->pagi_freecount) {  			xfs_perag_put(pag);  			goto out_alloc;  		} -		if (!okalloc) { -			xfs_trans_brelse(tp, agbp); -			goto nextag; -		} +		if (!okalloc) +			goto nextag_relse_buffer; +  		error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced);  		if (error) { @@ -1007,6 +1006,8 @@ xfs_dialloc(  			return 0;  		} +nextag_relse_buffer: +		xfs_trans_brelse(tp, agbp);  nextag:  		xfs_perag_put(pag);  		if (++agno == mp->m_sb.sb_agcount) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 92d4331cd4f..ca28a4ba4b5 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -857,7 +857,7 @@ xfs_rtbuf_get(  	xfs_buf_t	*bp;		/* block buffer, result */  	xfs_inode_t	*ip;		/* bitmap or summary inode */  	xfs_bmbt_irec_t	map; -	int		nmap; +	int		nmap = 1;  	int		error;		/* error value */  	ip = issum ? mp->m_rsumip : mp->m_rbmip; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ced362533e3..bfacf0d5a22 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -118,7 +118,8 @@ enum drm_mode_status {  	.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \  	.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \  	.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ -	.vscan = (vs), .flags = (f), .vrefresh = 0 +	.vscan = (vs), .flags = (f), .vrefresh = 0, \ +	.base.type = DRM_MODE_OBJECT_MODE  #define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ 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/drm/drm_mode.h b/include/drm/drm_mode.h index 5581980b14f..3d6301b6ec1 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -359,8 +359,9 @@ struct drm_mode_mode_cmd {  	struct drm_mode_modeinfo mode;  }; -#define DRM_MODE_CURSOR_BO	(1<<0) -#define DRM_MODE_CURSOR_MOVE	(1<<1) +#define DRM_MODE_CURSOR_BO	0x01 +#define DRM_MODE_CURSOR_MOVE	0x02 +#define DRM_MODE_CURSOR_FLAGS	0x03  /*   * depending on the value in flags different members are used. 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/blkdev.h b/include/linux/blkdev.h index 4e72a9d4823..4a2ab7c8539 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -601,7 +601,7 @@ static inline void blk_clear_rl_full(struct request_list *rl, bool sync)   * it already be started by driver.   */  #define RQ_NOMERGE_FLAGS	\ -	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) +	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD)  #define rq_mergeable(rq)	\  	(!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \  	 (((rq)->cmd_flags & REQ_DISCARD) || \ @@ -894,6 +894,8 @@ extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);  extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);  extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); +extern int blk_bio_map_sg(struct request_queue *q, struct bio *bio, +			  struct scatterlist *sglist);  extern void blk_dump_rq_flags(struct request *, char *);  extern long nr_blockdev_pages(void); @@ -1139,6 +1141,16 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector  		& (lim->discard_granularity - 1);  } +static inline int bdev_discard_alignment(struct block_device *bdev) +{ +	struct request_queue *q = bdev_get_queue(bdev); + +	if (bdev != bdev->bd_contains) +		return bdev->bd_part->discard_alignment; + +	return q->limits.discard_alignment; +} +  static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)  {  	if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 040b13b5c14..279b1eaa8b7 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -194,6 +194,10 @@ static inline int cpuidle_play_dead(void) {return -ENODEV; }  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED  void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a); +#else +static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a) +{ +}  #endif  /****************************** 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/kernel.h b/include/linux/kernel.h index 604382143bc..594b419b7d2 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -82,10 +82,18 @@  	__x - (__x % (y));				\  }							\  ) + +/* + * Divide positive or negative dividend by positive divisor and round + * to closest integer. Result is undefined for negative divisors. + */  #define DIV_ROUND_CLOSEST(x, divisor)(			\  {							\ -	typeof(divisor) __divisor = divisor;		\ -	(((x) + ((__divisor) / 2)) / (__divisor));	\ +	typeof(x) __x = x;				\ +	typeof(divisor) __d = divisor;			\ +	(((typeof(x))-1) >= 0 || (__x) >= 0) ?		\ +		(((__x) + ((__d) / 2)) / (__d)) :	\ +		(((__x) - ((__d) / 2)) / (__d));	\  }							\  ) 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/ktime.h b/include/linux/ktime.h index 603bec2913b..06177ba10a1 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -58,13 +58,6 @@ union ktime {  typedef union ktime ktime_t;		/* Kill this */ -#define KTIME_MAX			((s64)~((u64)1 << 63)) -#if (BITS_PER_LONG == 64) -# define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC) -#else -# define KTIME_SEC_MAX			LONG_MAX -#endif -  /*   * ktime_t definitions when using the 64-bit scalar representation:   */ 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/mmc/card.h b/include/linux/mmc/card.h index 111aca5e97f..4b27f9f503e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -239,6 +239,7 @@ struct mmc_card {  #define MMC_QUIRK_BLK_NO_CMD23	(1<<7)		/* Avoid CMD23 for regular multiblock */  #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8)	/* Avoid sending 512 bytes in */  #define MMC_QUIRK_LONG_READ_TIME (1<<9)		/* Data read time > CSD says */ +#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)	/* Skip secure for erase/trim */  						/* byte mode */  	unsigned int    poweroff_notify_state;	/* eMMC4.5 notify feature */  #define MMC_NO_POWER_NOTIFICATION	0 diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 51bf8ada6dc..49258e0ed1c 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -15,6 +15,8 @@  #define MV643XX_ETH_SIZE_REG_4		0x2224  #define MV643XX_ETH_BASE_ADDR_ENABLE_REG	0x2290 +#define MV643XX_TX_CSUM_DEFAULT_LIMIT	0 +  struct mv643xx_eth_shared_platform_data {  	struct mbus_dram_target_info	*dram;  	struct platform_device	*shared_smi; 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/pci_ids.h b/include/linux/pci_ids.h index fc352607734..6b4565c440c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2149,7 +2149,7 @@  #define PCI_DEVICE_ID_TIGON3_5704S	0x16a8  #define PCI_DEVICE_ID_NX2_57800_VF	0x16a9  #define PCI_DEVICE_ID_NX2_5706S		0x16aa -#define PCI_DEVICE_ID_NX2_57840_MF	0x16ab +#define PCI_DEVICE_ID_NX2_57840_MF	0x16a4  #define PCI_DEVICE_ID_NX2_5708S		0x16ac  #define PCI_DEVICE_ID_NX2_57840_VF	0x16ad  #define PCI_DEVICE_ID_NX2_57810_MF	0x16ae 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/linux/time.h b/include/linux/time.h index c81c5e40fcb..b51e664c83e 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -107,11 +107,36 @@ static inline struct timespec timespec_sub(struct timespec lhs,  	return ts_delta;  } +#define KTIME_MAX			((s64)~((u64)1 << 63)) +#if (BITS_PER_LONG == 64) +# define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC) +#else +# define KTIME_SEC_MAX			LONG_MAX +#endif +  /*   * Returns true if the timespec is norm, false if denorm:   */ -#define timespec_valid(ts) \ -	(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC)) +static inline bool timespec_valid(const struct timespec *ts) +{ +	/* Dates before 1970 are bogus */ +	if (ts->tv_sec < 0) +		return false; +	/* Can't have more nanoseconds then a second */ +	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) +		return false; +	return true; +} + +static inline bool timespec_valid_strict(const struct timespec *ts) +{ +	if (!timespec_valid(ts)) +		return false; +	/* Disallow values that could overflow ktime_t */ +	if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX) +		return false; +	return true; +}  extern void read_persistent_clock(struct timespec *ts);  extern void read_boot_clock(struct timespec *ts); 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/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index e1ce1048fe5..4a045cda9c6 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -18,6 +18,7 @@ struct nf_conntrack_ecache {  	u16 ctmask;		/* bitmask of ct events to be delivered */  	u16 expmask;		/* bitmask of expect events to be delivered */  	u32 pid;		/* netlink pid of destroyer */ +	struct timer_list timeout;  };  static inline struct nf_conntrack_ecache * 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/include/xen/events.h b/include/xen/events.h index 9c641deb65d..04399b28e82 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -58,8 +58,6 @@ void notify_remote_via_irq(int irq);  void xen_irq_resume(void); -void xen_hvm_prepare_kexec(struct shared_info *sip, unsigned long pfn); -  /* Clear an irq's pending state, in preparation for polling on it */  void xen_clear_irq_pending(int irq);  void xen_set_irq_pending(int irq); 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/fork.c b/kernel/fork.c index 3bd2280d79f..2c8857e1285 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -455,8 +455,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)  		if (retval)  			goto out; -		if (file && uprobe_mmap(tmp)) -			goto out; +		if (file) +			uprobe_mmap(tmp);  	}  	/* a new mm has just been created */  	arch_dup_mmap(oldmm, mm); 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/time/timekeeping.c b/kernel/time/timekeeping.c index e16af197a2b..34e5eac8142 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -115,6 +115,7 @@ static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts)  {  	tk->xtime_sec += ts->tv_sec;  	tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift; +	tk_normalize_xtime(tk);  }  static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) @@ -276,7 +277,7 @@ static void timekeeping_forward_now(struct timekeeper *tk)  	tk->xtime_nsec += cycle_delta * tk->mult;  	/* If arch requires, add in gettimeoffset() */ -	tk->xtime_nsec += arch_gettimeoffset() << tk->shift; +	tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift;  	tk_normalize_xtime(tk); @@ -427,7 +428,7 @@ int do_settimeofday(const struct timespec *tv)  	struct timespec ts_delta, xt;  	unsigned long flags; -	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) +	if (!timespec_valid_strict(tv))  		return -EINVAL;  	write_seqlock_irqsave(&tk->lock, flags); @@ -463,6 +464,8 @@ int timekeeping_inject_offset(struct timespec *ts)  {  	struct timekeeper *tk = &timekeeper;  	unsigned long flags; +	struct timespec tmp; +	int ret = 0;  	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)  		return -EINVAL; @@ -471,10 +474,17 @@ int timekeeping_inject_offset(struct timespec *ts)  	timekeeping_forward_now(tk); +	/* Make sure the proposed value is valid */ +	tmp = timespec_add(tk_xtime(tk),  *ts); +	if (!timespec_valid_strict(&tmp)) { +		ret = -EINVAL; +		goto error; +	}  	tk_xtime_add(tk, ts);  	tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); +error: /* even if we error out, we forwarded the time, so call update */  	timekeeping_update(tk, true);  	write_sequnlock_irqrestore(&tk->lock, flags); @@ -482,7 +492,7 @@ int timekeeping_inject_offset(struct timespec *ts)  	/* signal hrtimers about time change */  	clock_was_set(); -	return 0; +	return ret;  }  EXPORT_SYMBOL(timekeeping_inject_offset); @@ -649,7 +659,20 @@ void __init timekeeping_init(void)  	struct timespec now, boot, tmp;  	read_persistent_clock(&now); +	if (!timespec_valid_strict(&now)) { +		pr_warn("WARNING: Persistent clock returned invalid value!\n" +			"         Check your CMOS/BIOS settings.\n"); +		now.tv_sec = 0; +		now.tv_nsec = 0; +	} +  	read_boot_clock(&boot); +	if (!timespec_valid_strict(&boot)) { +		pr_warn("WARNING: Boot clock returned invalid value!\n" +			"         Check your CMOS/BIOS settings.\n"); +		boot.tv_sec = 0; +		boot.tv_nsec = 0; +	}  	seqlock_init(&tk->lock); @@ -690,7 +713,7 @@ static struct timespec timekeeping_suspend_time;  static void __timekeeping_inject_sleeptime(struct timekeeper *tk,  							struct timespec *delta)  { -	if (!timespec_valid(delta)) { +	if (!timespec_valid_strict(delta)) {  		printk(KERN_WARNING "__timekeeping_inject_sleeptime: Invalid "  					"sleep delta value!\n");  		return; @@ -1129,6 +1152,10 @@ static void update_wall_time(void)  	offset = (clock->read(clock) - clock->cycle_last) & clock->mask;  #endif +	/* Check if there's really nothing to do */ +	if (offset < tk->cycle_interval) +		goto out; +  	/*  	 * With NO_HZ we may have to accumulate many cycle_intervals  	 * (think "ticks") worth of time at once. To do this efficiently, @@ -1161,9 +1188,9 @@ static void update_wall_time(void)  	* the vsyscall implementations are converted to use xtime_nsec  	* (shifted nanoseconds), this can be killed.  	*/ -	remainder = tk->xtime_nsec & ((1 << tk->shift) - 1); +	remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1);  	tk->xtime_nsec -= remainder; -	tk->xtime_nsec += 1 << tk->shift; +	tk->xtime_nsec += 1ULL << tk->shift;  	tk->ntp_error += remainder << tk->ntp_error_shift;  	/* diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 60e4d787567..6b245f64c8d 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -506,6 +506,8 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)  	int size;  	syscall_nr = syscall_get_nr(current, regs); +	if (syscall_nr < 0) +		return;  	if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))  		return; @@ -580,6 +582,8 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)  	int size;  	syscall_nr = syscall_get_nr(current, regs); +	if (syscall_nr < 0) +		return;  	if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))  		return; 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/filemap.c b/mm/filemap.c index fa5ca304148..384344575c3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1412,12 +1412,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,  			retval = filemap_write_and_wait_range(mapping, pos,  					pos + iov_length(iov, nr_segs) - 1);  			if (!retval) { -				struct blk_plug plug; - -				blk_start_plug(&plug);  				retval = mapping->a_ops->direct_IO(READ, iocb,  							iov, pos, nr_segs); -				blk_finish_plug(&plug);  			}  			if (retval > 0) {  				*ppos = pos + retval; @@ -2527,14 +2523,12 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  {  	struct file *file = iocb->ki_filp;  	struct inode *inode = file->f_mapping->host; -	struct blk_plug plug;  	ssize_t ret;  	BUG_ON(iocb->ki_pos != pos);  	sb_start_write(inode->i_sb);  	mutex_lock(&inode->i_mutex); -	blk_start_plug(&plug);  	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);  	mutex_unlock(&inode->i_mutex); @@ -2545,7 +2539,6 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  		if (err < 0 && ret > 0)  			ret = err;  	} -	blk_finish_plug(&plug);  	sb_end_write(inode->i_sb);  	return ret;  } 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/mm/mempolicy.c b/mm/mempolicy.c index bd92431d4c4..4ada3be6e25 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2562,7 +2562,7 @@ int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol, int no_context)  		break;  	default: -		BUG(); +		return -EINVAL;  	}  	l = strlen(policy_modes[mode]); diff --git a/mm/mmap.c b/mm/mmap.c index 9adee9fc0d8..ae18a48e7e4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1356,9 +1356,8 @@ out:  	} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))  		make_pages_present(addr, addr + len); -	if (file && uprobe_mmap(vma)) -		/* matching probes but cannot insert */ -		goto unmap_and_free_vma; +	if (file) +		uprobe_mmap(vma);  	return addr; diff --git a/mm/slab.c b/mm/slab.c index f8b0d539b48..811af03a14e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -3260,6 +3260,7 @@ force_grow:  		/* cache_grow can reenable interrupts, then ac could change. */  		ac = cpu_cache_get(cachep); +		node = numa_mem_id();  		/* no objects in sight? abort */  		if (!x && (ac->avail == 0 || force_refill)) 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/netpoll.c b/net/core/netpoll.c index 346b1eb83a1..e4ba3e70c17 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -168,24 +168,16 @@ static void poll_napi(struct net_device *dev)  	struct napi_struct *napi;  	int budget = 16; -	WARN_ON_ONCE(!irqs_disabled()); -  	list_for_each_entry(napi, &dev->napi_list, dev_list) { -		local_irq_enable();  		if (napi->poll_owner != smp_processor_id() &&  		    spin_trylock(&napi->poll_lock)) { -			rcu_read_lock_bh();  			budget = poll_one_napi(rcu_dereference_bh(dev->npinfo),  					       napi, budget); -			rcu_read_unlock_bh();  			spin_unlock(&napi->poll_lock); -			if (!budget) { -				local_irq_disable(); +			if (!budget)  				break; -			}  		} -		local_irq_disable();  	}  } 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/ipmr.c b/net/ipv4/ipmr.c index 8eec8f4a053..ebdf06f938b 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -124,6 +124,8 @@ static DEFINE_SPINLOCK(mfc_unres_lock);  static struct kmem_cache *mrt_cachep __read_mostly;  static struct mr_table *ipmr_new_table(struct net *net, u32 id); +static void ipmr_free_table(struct mr_table *mrt); +  static int ip_mr_forward(struct net *net, struct mr_table *mrt,  			 struct sk_buff *skb, struct mfc_cache *cache,  			 int local); @@ -131,6 +133,7 @@ static int ipmr_cache_report(struct mr_table *mrt,  			     struct sk_buff *pkt, vifi_t vifi, int assert);  static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,  			      struct mfc_cache *c, struct rtmsg *rtm); +static void mroute_clean_tables(struct mr_table *mrt);  static void ipmr_expire_process(unsigned long arg);  #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES @@ -271,7 +274,7 @@ static void __net_exit ipmr_rules_exit(struct net *net)  	list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {  		list_del(&mrt->list); -		kfree(mrt); +		ipmr_free_table(mrt);  	}  	fib_rules_unregister(net->ipv4.mr_rules_ops);  } @@ -299,7 +302,7 @@ static int __net_init ipmr_rules_init(struct net *net)  static void __net_exit ipmr_rules_exit(struct net *net)  { -	kfree(net->ipv4.mrt); +	ipmr_free_table(net->ipv4.mrt);  }  #endif @@ -336,6 +339,13 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)  	return mrt;  } +static void ipmr_free_table(struct mr_table *mrt) +{ +	del_timer_sync(&mrt->ipmr_expire_timer); +	mroute_clean_tables(mrt); +	kfree(mrt); +} +  /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */  static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 4ad9cf17399..9c87cde28ff 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -502,7 +502,10 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,  		ret = nf_ct_expect_related(rtcp_exp);  		if (ret == 0)  			break; -		else if (ret != -EBUSY) { +		else if (ret == -EBUSY) { +			nf_ct_unexpect_related(rtp_exp); +			continue; +		} else if (ret < 0) {  			nf_ct_unexpect_related(rtp_exp);  			port = 0;  			break; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index fd9ecb52c66..82cf2a722b2 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -934,12 +934,14 @@ static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)  	if (mtu < ip_rt_min_pmtu)  		mtu = ip_rt_min_pmtu; +	rcu_read_lock();  	if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) {  		struct fib_nh *nh = &FIB_RES_NH(res);  		update_or_create_fnhe(nh, fl4->daddr, 0, mtu,  				      jiffies + ip_rt_mtu_expires);  	} +	rcu_read_unlock();  	return mtu;  } @@ -956,7 +958,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,  		dst->obsolete = DST_OBSOLETE_KILL;  	} else {  		rt->rt_pmtu = mtu; -		dst_set_expires(&rt->dst, ip_rt_mtu_expires); +		rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires);  	}  } @@ -1263,7 +1265,7 @@ static void ipv4_dst_destroy(struct dst_entry *dst)  {  	struct rtable *rt = (struct rtable *) dst; -	if (dst->flags & DST_NOCACHE) { +	if (!list_empty(&rt->rt_uncached)) {  		spin_lock_bh(&rt_uncached_lock);  		list_del(&rt->rt_uncached);  		spin_unlock_bh(&rt_uncached_lock); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 85308b90df8..6e38c6c23ca 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2926,13 +2926,14 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack)   * tcp_xmit_retransmit_queue().   */  static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, -				  int newly_acked_sacked, bool is_dupack, +				  int prior_sacked, bool is_dupack,  				  int flag)  {  	struct inet_connection_sock *icsk = inet_csk(sk);  	struct tcp_sock *tp = tcp_sk(sk);  	int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) &&  				    (tcp_fackets_out(tp) > tp->reordering)); +	int newly_acked_sacked = 0;  	int fast_rexmit = 0;  	if (WARN_ON(!tp->packets_out && tp->sacked_out)) @@ -2992,6 +2993,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,  				tcp_add_reno_sack(sk);  		} else  			do_lost = tcp_try_undo_partial(sk, pkts_acked); +		newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;  		break;  	case TCP_CA_Loss:  		if (flag & FLAG_DATA_ACKED) @@ -3013,6 +3015,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,  			if (is_dupack)  				tcp_add_reno_sack(sk);  		} +		newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked;  		if (icsk->icsk_ca_state <= TCP_CA_Disorder)  			tcp_try_undo_dsack(sk); @@ -3590,7 +3593,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  	int prior_packets;  	int prior_sacked = tp->sacked_out;  	int pkts_acked = 0; -	int newly_acked_sacked = 0;  	bool frto_cwnd = false;  	/* If the ack is older than previous acks @@ -3666,8 +3668,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  	flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);  	pkts_acked = prior_packets - tp->packets_out; -	newly_acked_sacked = (prior_packets - prior_sacked) - -			     (tp->packets_out - tp->sacked_out);  	if (tp->frto_counter)  		frto_cwnd = tcp_process_frto(sk, flag); @@ -3681,7 +3681,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  		    tcp_may_raise_cwnd(sk, flag))  			tcp_cong_avoid(sk, ack, prior_in_flight);  		is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); -		tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, +		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,  				      is_dupack, flag);  	} else {  		if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) @@ -3698,7 +3698,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)  no_queue:  	/* If data was DSACKed, see if we can undo a cwnd reduction. */  	if (flag & FLAG_DSACKING_ACK) -		tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, +		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,  				      is_dupack, flag);  	/* If this ack opens up a zero window, clear backoff.  It was  	 * being used to time the probes, and is probably far higher than @@ -3718,8 +3718,7 @@ old_ack:  	 */  	if (TCP_SKB_CB(skb)->sacked) {  		flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); -		newly_acked_sacked = tp->sacked_out - prior_sacked; -		tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, +		tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,  				      is_dupack, flag);  	} 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/esp6.c b/net/ipv6/esp6.c index 6dc7fd353ef..282f3723ee1 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -167,8 +167,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)  	struct esp_data *esp = x->data;  	/* skb is pure payload to encrypt */ -	err = -ENOMEM; -  	aead = esp->aead;  	alen = crypto_aead_authsize(aead); @@ -203,8 +201,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)  	}  	tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); -	if (!tmp) +	if (!tmp) { +		err = -ENOMEM;  		goto error; +	}  	seqhi = esp_tmp_seqhi(tmp);  	iv = esp_tmp_iv(aead, tmp, seqhilen); 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 393355d37b4..1a9f3723c13 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1347,11 +1347,10 @@ static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)  	/* Remove from tunnel list */  	spin_lock_bh(&pn->l2tp_tunnel_list_lock);  	list_del_rcu(&tunnel->list); +	kfree_rcu(tunnel, rcu);  	spin_unlock_bh(&pn->l2tp_tunnel_list_lock); -	synchronize_rcu();  	atomic_dec(&l2tp_tunnel_count); -	kfree(tunnel);  }  /* Create a socket for the tunnel, if one isn't set up by @@ -1502,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; @@ -1606,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_core.h b/net/l2tp/l2tp_core.h index a38ec6cdeee..56d583e083a 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -163,6 +163,7 @@ struct l2tp_tunnel_cfg {  struct l2tp_tunnel {  	int			magic;		/* Should be L2TP_TUNNEL_MAGIC */ +	struct rcu_head rcu;  	rwlock_t		hlist_lock;	/* protect session_hlist */  	struct hlist_head	session_hlist[L2TP_HASH_SIZE];  						/* hashed list of sessions, 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/mac80211/tx.c b/net/mac80211/tx.c index acf712ffb5e..c5e8c9c31f7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1811,37 +1811,31 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,  			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,  					sdata, NULL, NULL);  		} else { -			int is_mesh_mcast = 1; -			const u8 *mesh_da; +			/* DS -> MBSS (802.11-2012 13.11.3.3). +			 * For unicast with unknown forwarding information, +			 * destination might be in the MBSS or if that fails +			 * forwarded to another mesh gate. In either case +			 * resolution will be handled in ieee80211_xmit(), so +			 * leave the original DA. This also works for mcast */ +			const u8 *mesh_da = skb->data; + +			if (mppath) +				mesh_da = mppath->mpp; +			else if (mpath) +				mesh_da = mpath->dst; +			rcu_read_unlock(); -			if (is_multicast_ether_addr(skb->data)) -				/* DA TA mSA AE:SA */ -				mesh_da = skb->data; -			else { -				static const u8 bcast[ETH_ALEN] = -					{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -				if (mppath) { -					/* RA TA mDA mSA AE:DA SA */ -					mesh_da = mppath->mpp; -					is_mesh_mcast = 0; -				} else if (mpath) { -					mesh_da = mpath->dst; -					is_mesh_mcast = 0; -				} else { -					/* DA TA mSA AE:SA */ -					mesh_da = bcast; -				} -			}  			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,  					mesh_da, sdata->vif.addr); -			rcu_read_unlock(); -			if (is_mesh_mcast) +			if (is_multicast_ether_addr(mesh_da)) +				/* DA TA mSA AE:SA */  				meshhdrlen =  					ieee80211_new_mesh_header(&mesh_hdr,  							sdata,  							skb->data + ETH_ALEN,  							NULL);  			else +				/* RA TA mDA mSA AE:DA SA */  				meshhdrlen =  					ieee80211_new_mesh_header(&mesh_hdr,  							sdata, diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 72bf32a8487..f51013c07b9 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1171,8 +1171,10 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u,  		goto out_err;  	}  	svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); -	if (!svc->stats.cpustats) +	if (!svc->stats.cpustats) { +		ret = -ENOMEM;  		goto out_err; +	}  	/* I'm the first user of the service */  	atomic_set(&svc->usecnt, 0); diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index cf4875565d6..2ceec64b19f 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -249,12 +249,15 @@ static void death_by_event(unsigned long ul_conntrack)  {  	struct nf_conn *ct = (void *)ul_conntrack;  	struct net *net = nf_ct_net(ct); +	struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); + +	BUG_ON(ecache == NULL);  	if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {  		/* bad luck, let's retry again */ -		ct->timeout.expires = jiffies + +		ecache->timeout.expires = jiffies +  			(random32() % net->ct.sysctl_events_retry_timeout); -		add_timer(&ct->timeout); +		add_timer(&ecache->timeout);  		return;  	}  	/* we've got the event delivered, now it's dying */ @@ -268,6 +271,9 @@ static void death_by_event(unsigned long ul_conntrack)  void nf_ct_insert_dying_list(struct nf_conn *ct)  {  	struct net *net = nf_ct_net(ct); +	struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); + +	BUG_ON(ecache == NULL);  	/* add this conntrack to the dying list */  	spin_lock_bh(&nf_conntrack_lock); @@ -275,10 +281,10 @@ void nf_ct_insert_dying_list(struct nf_conn *ct)  			     &net->ct.dying);  	spin_unlock_bh(&nf_conntrack_lock);  	/* set a new timer to retry event delivery */ -	setup_timer(&ct->timeout, death_by_event, (unsigned long)ct); -	ct->timeout.expires = jiffies + +	setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); +	ecache->timeout.expires = jiffies +  		(random32() % net->ct.sysctl_events_retry_timeout); -	add_timer(&ct->timeout); +	add_timer(&ecache->timeout);  }  EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index da4fc37a857..9807f3278fc 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -2790,7 +2790,8 @@ static int __init ctnetlink_init(void)  		goto err_unreg_subsys;  	} -	if (register_pernet_subsys(&ctnetlink_net_ops)) { +	ret = register_pernet_subsys(&ctnetlink_net_ops); +	if (ret < 0) {  		pr_err("ctnetlink_init: cannot register pernet operations\n");  		goto err_unreg_exp_subsys;  	} 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 169ab59ed9d..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, @@ -480,7 +481,7 @@ __build_packet_message(struct nfulnl_instance *inst,  	}  	if (indev && skb_mac_header_was_set(skb)) { -		if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || +		if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||  		    nla_put_be16(inst->skb, NFULA_HWLEN,  				 htons(skb->dev->hard_header_len)) ||  		    nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, @@ -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 */ @@ -996,8 +998,10 @@ static int __init nfnetlink_log_init(void)  #ifdef CONFIG_PROC_FS  	if (!proc_create("nfnetlink_log", 0440, -			 proc_net_netfilter, &nful_file_ops)) +			 proc_net_netfilter, &nful_file_ops)) { +		status = -ENOMEM;  		goto cleanup_logger; +	}  #endif  	return status; 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/netlink/af_netlink.c b/net/netlink/af_netlink.c index 1445d73533e..527023823b5 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1373,7 +1373,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,  		dst_pid = addr->nl_pid;  		dst_group = ffs(addr->nl_groups);  		err =  -EPERM; -		if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) +		if ((dst_group || dst_pid) && +		    !netlink_capable(sock, NL_NONROOT_SEND))  			goto out;  	} else {  		dst_pid = nlk->dst_pid; @@ -2147,6 +2148,7 @@ static void __init netlink_add_usersock_entry(void)  	rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);  	nl_table[NETLINK_USERSOCK].module = THIS_MODULE;  	nl_table[NETLINK_USERSOCK].registered = 1; +	nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND;  	netlink_table_ungrab();  } 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/packet/af_packet.c b/net/packet/af_packet.c index aee7196aac3..c5c9e2a5421 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1273,7 +1273,7 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po)  	spin_unlock(&f->lock);  } -bool match_fanout_group(struct packet_type *ptype, struct sock * sk) +static bool match_fanout_group(struct packet_type *ptype, struct sock * sk)  {  	if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout)  		return true; 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/socket.c b/net/socket.c index a5471f804d9..edc3c4af908 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2604,7 +2604,7 @@ static int do_siocgstamp(struct net *net, struct socket *sock,  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);  	set_fs(old_fs);  	if (!err) -		err = compat_put_timeval(up, &ktv); +		err = compat_put_timeval(&ktv, up);  	return err;  } @@ -2620,7 +2620,7 @@ static int do_siocgstampns(struct net *net, struct socket *sock,  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);  	set_fs(old_fs);  	if (!err) -		err = compat_put_timespec(up, &kts); +		err = compat_put_timespec(&kts, up);  	return err;  } diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 88f2bf67196..bac973a3136 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -316,7 +316,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)   */  void svc_xprt_enqueue(struct svc_xprt *xprt)  { -	struct svc_serv	*serv = xprt->xpt_server;  	struct svc_pool *pool;  	struct svc_rqst	*rqstp;  	int cpu; @@ -362,8 +361,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)  				rqstp, rqstp->rq_xprt);  		rqstp->rq_xprt = xprt;  		svc_xprt_get(xprt); -		rqstp->rq_reserved = serv->sv_max_mesg; -		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  		pool->sp_stats.threads_woken++;  		wake_up(&rqstp->rq_wait);  	} else { @@ -640,8 +637,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)  	if (xprt) {  		rqstp->rq_xprt = xprt;  		svc_xprt_get(xprt); -		rqstp->rq_reserved = serv->sv_max_mesg; -		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  		/* As there is a shortage of threads and this request  		 * had to be queued, don't allow the thread to wait so @@ -738,6 +733,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)  		else  			len = xprt->xpt_ops->xpo_recvfrom(rqstp);  		dprintk("svc: got len=%d\n", len); +		rqstp->rq_reserved = serv->sv_max_mesg; +		atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);  	}  	svc_xprt_received(xprt); @@ -794,7 +791,8 @@ int svc_send(struct svc_rqst *rqstp)  	/* Grab mutex to serialize outgoing data. */  	mutex_lock(&xprt->xpt_mutex); -	if (test_bit(XPT_DEAD, &xprt->xpt_flags)) +	if (test_bit(XPT_DEAD, &xprt->xpt_flags) +			|| test_bit(XPT_CLOSE, &xprt->xpt_flags))  		len = -ENOTCONN;  	else  		len = xprt->xpt_ops->xpo_sendto(rqstp); diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 18bc130255a..998aa8c1807 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1129,9 +1129,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)  	if (len >= 0)  		svsk->sk_tcplen += len;  	if (len != want) { +		svc_tcp_save_pages(svsk, rqstp);  		if (len < 0 && len != -EAGAIN)  			goto err_other; -		svc_tcp_save_pages(svsk, rqstp);  		dprintk("svc: incomplete TCP record (%d of %d)\n",  			svsk->sk_tcplen, svsk->sk_reclen);  		goto err_noclose; 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/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 87cd0e4d428..210be48d8ae 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1994,8 +1994,10 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay)  		goto error;  	x->outer_mode = xfrm_get_mode(x->props.mode, family); -	if (x->outer_mode == NULL) +	if (x->outer_mode == NULL) { +		err = -EPROTONOSUPPORT;  		goto error; +	}  	if (init_replay) {  		err = xfrm_init_replay(x); diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst index 6bf8e87f1dc..c3f69ae275d 100644 --- a/scripts/Makefile.fwinst +++ b/scripts/Makefile.fwinst @@ -42,7 +42,7 @@ quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)  $(installed-fw-dirs):  	$(call cmd,mkdir) -$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %) +$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $$(dir $(INSTALL_FW_PATH)/%)  	$(call cmd,install)  PHONY +=  __fw_install __fw_modinst FORCE diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 4629038c9e5..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}               \ @@ -211,7 +216,7 @@ if [ -n "${CONFIG_KALLSYMS}" ]; then  	if ! cmp -s System.map .tmp_System.map; then  		echo >&2 Inconsistent kallsyms data -		echo >&2 echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround +		echo >&2 Try "make KALLSYMS_EXTRA_PASS=1" as a workaround  		cleanup  		exit 1  	fi 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 f560051a949..1c65cc5e3a3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1209,6 +1209,9 @@ static void snd_hda_codec_free(struct hda_codec *codec)  	kfree(codec);  } +static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, +				hda_nid_t fg, unsigned int power_state); +  static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,  				unsigned int power_state); @@ -1317,6 +1320,10 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,  					   AC_VERB_GET_SUBSYSTEM_ID, 0);  	} +	codec->epss = snd_hda_codec_get_supported_ps(codec, +					codec->afg ? codec->afg : codec->mfg, +					AC_PWRST_EPSS); +  	/* power-up all before initialization */  	hda_set_power_state(codec,  			    codec->afg ? codec->afg : codec->mfg, @@ -2346,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; @@ -2361,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); @@ -3543,8 +3550,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,  	/* this delay seems necessary to avoid click noise at power-down */  	if (power_state == AC_PWRST_D3) {  		/* transition time less than 10ms for power down */ -		bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); -		msleep(epss ? 10 : 100); +		msleep(codec->epss ? 10 : 100);  	}  	/* repeat power states setting at most 10 times*/ diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 7fbc1bcaf1a..e5a7e19a807 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -862,6 +862,7 @@ struct hda_codec {  	unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */  	unsigned int no_jack_detect:1;	/* Machine has no jack-detection */  	unsigned int pcm_format_first:1; /* PCM format must be set first */ +	unsigned int epss:1;		/* supporting EPSS? */  #ifdef CONFIG_SND_HDA_POWER_SAVE  	unsigned int power_on :1;	/* current (global) power-state */  	int power_transition;	/* power-state in transition */ 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 ea5775a1a7d..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  }; @@ -4543,6 +4543,9 @@ static void stac92xx_line_out_detect(struct hda_codec *codec,  	struct auto_pin_cfg *cfg = &spec->autocfg;  	int i; +	if (cfg->speaker_outs == 0) +		return; +  	for (i = 0; i < cfg->line_outs; i++) {  		if (presence)  			break; @@ -5531,6 +5534,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)  		snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);  	} +	codec->epss = 0; /* longer delay needed for D3 */  	codec->no_trigger_sense = 1;  	codec->spec = spec; 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/card.c b/sound/usb/card.c index d5b5c3388e2..4a469f0cb6d 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -553,7 +553,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  				     struct snd_usb_audio *chip)  {  	struct snd_card *card; -	struct list_head *p; +	struct list_head *p, *n;  	if (chip == (void *)-1L)  		return; @@ -570,7 +570,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,  			snd_usb_stream_disconnect(p);  		}  		/* release the endpoint resources */ -		list_for_each(p, &chip->ep_list) { +		list_for_each_safe(p, n, &chip->ep_list) {  			snd_usb_endpoint_free(p);  		}  		/* release the midi resources */ diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index c4118120268..d6e2bb49c59 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -141,7 +141,7 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep)   *   * For implicit feedback, next_packet_size() is unused.   */ -static int next_packet_size(struct snd_usb_endpoint *ep) +int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)  {  	unsigned long flags;  	int ret; @@ -177,15 +177,6 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,  		ep->retire_data_urb(ep->data_subs, urb);  } -static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep, -				       struct snd_urb_ctx *ctx) -{ -	int i; - -	for (i = 0; i < ctx->packets; ++i) -		ctx->packet_size[i] = next_packet_size(ep); -} -  /*   * Prepare a PLAYBACK urb for submission to the bus.   */ @@ -370,7 +361,6 @@ static void snd_complete_urb(struct urb *urb)  			goto exit_clear;  		} -		prepare_outbound_urb_sizes(ep, ctx);  		prepare_outbound_urb(ep, ctx);  	} else {  		retire_inbound_urb(ep, ctx); @@ -799,7 +789,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  /**   * snd_usb_endpoint_start: start an snd_usb_endpoint   * - * @ep: the endpoint to start + * @ep:		the endpoint to start + * @can_sleep:	flag indicating whether the operation is executed in + * 		non-atomic context   *   * A call to this function will increment the use count of the endpoint.   * In case it is not already running, the URBs for this endpoint will be @@ -809,7 +801,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,   *   * Returns an error if the URB submission failed, 0 in all other cases.   */ -int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) +int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)  {  	int err;  	unsigned int i; @@ -821,6 +813,11 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)  	if (++ep->use_count != 1)  		return 0; +	/* just to be sure */ +	deactivate_urbs(ep, 0, can_sleep); +	if (can_sleep) +		wait_clear_urbs(ep); +  	ep->active_mask = 0;  	ep->unlink_mask = 0;  	ep->phase = 0; @@ -850,7 +847,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)  			goto __error;  		if (usb_pipeout(ep->pipe)) { -			prepare_outbound_urb_sizes(ep, urb->context);  			prepare_outbound_urb(ep, urb->context);  		} else {  			prepare_inbound_urb(ep, urb->context); diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index ee2723fb174..cbbbdf226d6 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -13,7 +13,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,  				struct audioformat *fmt,  				struct snd_usb_endpoint *sync_ep); -int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep); +int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);  void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,  			   int force, int can_sleep, int wait);  int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); @@ -21,6 +21,7 @@ int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);  void snd_usb_endpoint_free(struct list_head *head);  int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep); +int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);  void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,  			     struct snd_usb_endpoint *sender, diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 62ec808ed79..f782ce19bf5 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -212,7 +212,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,  	}  } -static int start_endpoints(struct snd_usb_substream *subs) +static int start_endpoints(struct snd_usb_substream *subs, int can_sleep)  {  	int err; @@ -225,7 +225,7 @@ static int start_endpoints(struct snd_usb_substream *subs)  		snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep);  		ep->data_subs = subs; -		err = snd_usb_endpoint_start(ep); +		err = snd_usb_endpoint_start(ep, can_sleep);  		if (err < 0) {  			clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);  			return err; @@ -236,10 +236,25 @@ static int start_endpoints(struct snd_usb_substream *subs)  	    !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {  		struct snd_usb_endpoint *ep = subs->sync_endpoint; +		if (subs->data_endpoint->iface != subs->sync_endpoint->iface || +		    subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { +			err = usb_set_interface(subs->dev, +						subs->sync_endpoint->iface, +						subs->sync_endpoint->alt_idx); +			if (err < 0) { +				snd_printk(KERN_ERR +					   "%d:%d:%d: cannot set interface (%d)\n", +					   subs->dev->devnum, +					   subs->sync_endpoint->iface, +					   subs->sync_endpoint->alt_idx, err); +				return -EIO; +			} +		} +  		snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep);  		ep->sync_slave = subs->data_endpoint; -		err = snd_usb_endpoint_start(ep); +		err = snd_usb_endpoint_start(ep, can_sleep);  		if (err < 0) {  			clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);  			return err; @@ -544,13 +559,10 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)  	subs->last_frame_number = 0;  	runtime->delay = 0; -	/* clear the pending deactivation on the target EPs */ -	deactivate_endpoints(subs); -  	/* for playback, submit the URBs now; otherwise, the first hwptr_done  	 * updates for all URBs would happen at the same time when starting */  	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) -		return start_endpoints(subs); +		return start_endpoints(subs, 1);  	return 0;  } @@ -1032,6 +1044,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  				 struct urb *urb)  {  	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; +	struct snd_usb_endpoint *ep = subs->data_endpoint;  	struct snd_urb_ctx *ctx = urb->context;  	unsigned int counts, frames, bytes;  	int i, stride, period_elapsed = 0; @@ -1043,7 +1056,11 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  	urb->number_of_packets = 0;  	spin_lock_irqsave(&subs->lock, flags);  	for (i = 0; i < ctx->packets; i++) { -		counts = ctx->packet_size[i]; +		if (ctx->packet_size[i]) +			counts = ctx->packet_size[i]; +		else +			counts = snd_usb_endpoint_next_packet_size(ep); +  		/* set up descriptor */  		urb->iso_frame_desc[i].offset = frames * stride;  		urb->iso_frame_desc[i].length = counts * stride; @@ -1094,7 +1111,16 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,  	subs->hwptr_done += bytes;  	if (subs->hwptr_done >= runtime->buffer_size * stride)  		subs->hwptr_done -= runtime->buffer_size * stride; + +	/* update delay with exact number of samples queued */ +	runtime->delay = subs->last_delay;  	runtime->delay += frames; +	subs->last_delay = runtime->delay; + +	/* realign last_frame_number */ +	subs->last_frame_number = usb_get_current_frame_number(subs->dev); +	subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ +  	spin_unlock_irqrestore(&subs->lock, flags);  	urb->transfer_buffer_length = bytes;  	if (period_elapsed) @@ -1112,12 +1138,32 @@ static void retire_playback_urb(struct snd_usb_substream *subs,  	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;  	int stride = runtime->frame_bits >> 3;  	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); -	if (processed > runtime->delay) -		runtime->delay = 0; +	est_delay = snd_usb_pcm_delay(subs, runtime->rate); +	/* update delay with exact number of samples played */ +	if (processed > subs->last_delay) +		subs->last_delay = 0;  	else -		runtime->delay -= processed; +		subs->last_delay -= processed; +	runtime->delay = subs->last_delay; + +	/* +	 * Report when delay estimate is off by more than 2ms. +	 * The error should be lower than 2ms since the estimate relies +	 * on two reads of a counter updated every ms. +	 */ +	if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) +		snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n", +			est_delay, subs->last_delay); +  	spin_unlock_irqrestore(&subs->lock, flags);  } @@ -1175,7 +1221,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream  	switch (cmd) {  	case SNDRV_PCM_TRIGGER_START: -		err = start_endpoints(subs); +		err = start_endpoints(subs, 0);  		if (err < 0)  			return err; diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 2884e67ee62..213362850ab 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,10 +10,12 @@ util/ctype.c  util/evlist.c  util/evsel.c  util/cpumap.c +util/hweight.c  util/thread_map.c  util/util.c  util/xyarray.c  util/cgroup.c  util/debugfs.c +util/rblist.c  util/strlist.c  ../../lib/rbtree.c diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 246852397e3..d617f69131d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1976,9 +1976,10 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,  			if (copy_from_user(&csigset, sigmask_arg->sigset,  					   sizeof csigset))  				goto out; -		} -		sigset_from_compat(&sigset, &csigset); -		r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); +			sigset_from_compat(&sigset, &csigset); +			r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); +		} else +			r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL);  		break;  	}  	default:  |