소스 검색

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Conflicts:
	drivers/net/team/team.c
	drivers/net/usb/qmi_wwan.c
	net/batman-adv/bat_iv_ogm.c
	net/ipv4/fib_frontend.c
	net/ipv4/route.c
	net/l2tp/l2tp_netlink.c

The team, fib_frontend, route, and l2tp_netlink conflicts were simply
overlapping changes.

qmi_wwan and bat_iv_ogm were of the "use HEAD" variety.

With help from Antonio Quartulli.

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 12 년 전
부모
커밋
6a06e5e1bb
100개의 변경된 파일736개의 추가작업 그리고 598개의 파일을 삭제
  1. 1 1
      Documentation/vfio.txt
  2. 9 5
      MAINTAINERS
  3. 2 2
      Makefile
  4. 1 0
      arch/arm/boot/compressed/head.S
  5. 3 0
      arch/arm/boot/dts/at91sam9260.dtsi
  6. 5 0
      arch/arm/boot/dts/at91sam9263.dtsi
  7. 5 0
      arch/arm/boot/dts/at91sam9g45.dtsi
  8. 4 0
      arch/arm/boot/dts/at91sam9n12.dtsi
  9. 4 0
      arch/arm/boot/dts/at91sam9x5.dtsi
  10. 2 0
      arch/arm/include/asm/unistd.h
  11. 1 0
      arch/arm/kernel/calls.S
  12. 46 2
      arch/arm/kernel/smp_twd.c
  13. 1 1
      arch/arm/mach-imx/clk-imx25.c
  14. 2 1
      arch/arm/mach-imx/mach-armadillo5x0.c
  15. 1 1
      arch/arm/mach-mxs/mach-mxs.c
  16. 7 0
      arch/arm/mach-orion5x/common.c
  17. 2 2
      arch/arm/mach-shmobile/board-kzm9g.c
  18. 2 0
      arch/arm/mm/dma-mapping.c
  19. 1 0
      arch/arm/plat-mxc/include/mach/mx25.h
  20. 6 4
      arch/arm/plat-samsung/clock.c
  21. 1 0
      arch/c6x/include/asm/Kbuild
  22. 0 27
      arch/c6x/include/asm/barrier.h
  23. 0 6
      arch/m68k/platform/coldfire/clk.c
  24. 1 1
      arch/mips/kernel/smp-cmp.c
  25. 2 0
      arch/mips/mm/gup.c
  26. 6 3
      arch/mips/mti-malta/malta-int.c
  27. 0 5
      arch/mips/mti-malta/malta-platform.c
  28. 10 14
      arch/s390/include/asm/hugetlb.h
  29. 0 2
      arch/s390/include/asm/tlbflush.h
  30. 2 0
      arch/s390/kernel/setup.c
  31. 63 79
      arch/s390/lib/uaccess_pt.c
  32. 1 1
      arch/sh/kernel/cpu/sh5/entry.S
  33. 1 1
      arch/sh/kernel/entry-common.S
  34. 5 8
      arch/sparc/kernel/module.c
  35. 13 11
      arch/tile/include/gxio/iorpc_trio.h
  36. 0 9
      arch/um/include/asm/processor-generic.h
  37. 0 10
      arch/um/include/shared/common-offsets.h
  38. 11 0
      arch/um/include/shared/user.h
  39. 6 19
      arch/um/kernel/exec.c
  40. 4 4
      arch/um/kernel/process.c
  41. 5 1
      arch/um/kernel/signal.c
  42. 12 12
      arch/um/kernel/syscall.c
  43. 1 1
      arch/um/scripts/Makefile.rules
  44. 4 4
      arch/x86/Kconfig
  45. 1 1
      arch/x86/Makefile
  46. 2 1
      arch/x86/include/asm/xen/page.h
  47. 2 0
      arch/x86/kernel/cpu/perf_event.h
  48. 12 0
      arch/x86/kernel/cpu/perf_event_amd_ibs.c
  49. 23 1
      arch/x86/kernel/cpu/perf_event_intel.c
  50. 14 0
      arch/x86/kernel/cpu/perf_event_intel_ds.c
  51. 6 0
      arch/x86/kernel/cpu/perf_event_intel_uncore.c
  52. 1 1
      arch/x86/mm/init.c
  53. 1 0
      arch/x86/um/Kconfig
  54. 0 3
      arch/x86/um/shared/sysdep/kernel-offsets.h
  55. 2 0
      arch/x86/um/shared/sysdep/syscalls.h
  56. 0 6
      arch/x86/um/signal.c
  57. 1 1
      arch/x86/um/sys_call_table_32.c
  58. 7 20
      arch/x86/um/syscalls_32.c
  59. 3 20
      arch/x86/um/syscalls_64.c
  60. 4 0
      arch/x86/xen/enlighten.c
  61. 11 16
      arch/x86/xen/p2m.c
  62. 4 0
      arch/x86/xen/setup.c
  63. 5 3
      block/blk-core.c
  64. 1 1
      block/ioctl.c
  65. 10 0
      drivers/acpi/bus.c
  66. 24 12
      drivers/acpi/power.c
  67. 1 0
      drivers/block/aoe/aoecmd.c
  68. 1 0
      drivers/block/cciss_scsi.c
  69. 23 15
      drivers/block/mtip32xx/mtip32xx.c
  70. 9 1
      drivers/block/mtip32xx/mtip32xx.h
  71. 9 0
      drivers/block/nbd.c
  72. 3 4
      drivers/block/rbd.c
  73. 1 1
      drivers/block/xen-blkback/blkback.c
  74. 1 0
      drivers/clk/Makefile
  75. 55 0
      drivers/clk/clk-devres.c
  76. 0 45
      drivers/clk/clkdev.c
  77. 34 29
      drivers/cpufreq/powernow-k8.c
  78. 12 1
      drivers/dma/at_hdmac.c
  79. 14 7
      drivers/dma/pl330.c
  80. 39 18
      drivers/edac/edac_mc.c
  81. 1 1
      drivers/edac/i3200_edac.c
  82. 4 0
      drivers/edac/i5000_edac.c
  83. 4 3
      drivers/edac/sb_edac.c
  84. 12 7
      drivers/extcon/extcon-max77693.c
  85. 5 0
      drivers/gpio/gpio-lpc32xx.c
  86. 2 1
      drivers/gpu/drm/i915/i915_gem.c
  87. 6 6
      drivers/gpu/drm/i915/intel_display.c
  88. 1 1
      drivers/gpu/drm/i915/intel_hdmi.c
  89. 1 1
      drivers/gpu/drm/nouveau/nouveau_abi16.c
  90. 14 1
      drivers/gpu/drm/nouveau/nv50_gpio.c
  91. 1 0
      drivers/gpu/drm/nouveau/nvc0_fb.c
  92. 2 1
      drivers/gpu/drm/nouveau/nvc0_fifo.c
  93. 2 1
      drivers/gpu/drm/nouveau/nve0_fifo.c
  94. 34 129
      drivers/gpu/drm/radeon/atombios_crtc.c
  95. 2 1
      drivers/gpu/drm/radeon/r100.c
  96. 7 0
      drivers/gpu/drm/udl/udl_connector.c
  97. 1 1
      drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
  98. 2 0
      drivers/hid/hid-lenovo-tpkbd.c
  99. 45 0
      drivers/hid/hid-logitech-dj.c
  100. 1 0
      drivers/hid/hid-logitech-dj.h

+ 1 - 1
Documentation/vfio.txt

@@ -133,7 +133,7 @@ character devices for this group:
 $ lspci -n -s 0000:06:0d.0
 $ lspci -n -s 0000:06:0d.0
 06:0d.0 0401: 1102:0002 (rev 08)
 06:0d.0 0401: 1102:0002 (rev 08)
 # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
 # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
-# echo 1102 0002 > /sys/bus/pci/drivers/vfio/new_id
+# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
 
 
 Now we need to look at what other devices are in the group to free
 Now we need to look at what other devices are in the group to free
 it for use by VFIO:
 it for use by VFIO:

+ 9 - 5
MAINTAINERS

@@ -3552,11 +3552,12 @@ K:	\b(ABS|SYN)_MT_
 
 
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:	Intel SCU Linux support <intel-linux-scu@intel.com>
 M:	Intel SCU Linux support <intel-linux-scu@intel.com>
+M:	Lukasz Dorau <lukasz.dorau@intel.com>
+M:	Maciej Patelczyk <maciej.patelczyk@intel.com>
 M:	Dave Jiang <dave.jiang@intel.com>
 M:	Dave Jiang <dave.jiang@intel.com>
-M:	Ed Nadolski <edmund.nadolski@intel.com>
 L:	linux-scsi@vger.kernel.org
 L:	linux-scsi@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
-S:	Maintained
+T:	git git://git.code.sf.net/p/intel-sas/isci
+S:	Supported
 F:	drivers/scsi/isci/
 F:	drivers/scsi/isci/
 F:	firmware/isci/
 F:	firmware/isci/
 
 
@@ -3666,11 +3667,12 @@ F:	Documentation/networking/README.ipw2200
 F:	drivers/net/wireless/ipw2x00/
 F:	drivers/net/wireless/ipw2x00/
 
 
 INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
 INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
-M:	Joseph Cihula <joseph.cihula@intel.com>
+M:	Richard L Maliszewski <richard.l.maliszewski@intel.com>
+M:	Gang Wei <gang.wei@intel.com>
 M:	Shane Wang <shane.wang@intel.com>
 M:	Shane Wang <shane.wang@intel.com>
 L:	tboot-devel@lists.sourceforge.net
 L:	tboot-devel@lists.sourceforge.net
 W:	http://tboot.sourceforge.net
 W:	http://tboot.sourceforge.net
-T:	Mercurial http://www.bughost.org/repos.hg/tboot.hg
+T:	hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
 S:	Supported
 S:	Supported
 F:	Documentation/intel_txt.txt
 F:	Documentation/intel_txt.txt
 F:	include/linux/tboot.h
 F:	include/linux/tboot.h
@@ -5543,6 +5545,8 @@ F:	Documentation/devicetree/bindings/pwm/
 F:	include/linux/pwm.h
 F:	include/linux/pwm.h
 F:	include/linux/of_pwm.h
 F:	include/linux/of_pwm.h
 F:	drivers/pwm/
 F:	drivers/pwm/
+F:	drivers/video/backlight/pwm_bl.c
+F:	include/linux/pwm_backlight.h
 
 
 PXA2xx/PXA3xx SUPPORT
 PXA2xx/PXA3xx SUPPORT
 M:	Eric Miao <eric.y.miao@gmail.com>
 M:	Eric Miao <eric.y.miao@gmail.com>

+ 2 - 2
Makefile

@@ -1,8 +1,8 @@
 VERSION = 3
 VERSION = 3
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
-NAME = Saber-toothed Squirrel
+EXTRAVERSION = -rc7
+NAME = Terrified Chipmunk
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
 # To see a list of typical targets execute "make help"

+ 1 - 0
arch/arm/boot/compressed/head.S

@@ -653,6 +653,7 @@ __armv7_mmu_cache_on:
 		mcrne	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
 		mcrne	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
 #endif
 #endif
 		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
 		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
+		bic	r0, r0, #1 << 28	@ clear SCTLR.TRE
 		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
 		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
 		orr	r0, r0, #0x003c		@ write buffer
 		orr	r0, r0, #0x003c		@ write buffer
 #ifdef CONFIG_MMU
 #ifdef CONFIG_MMU

+ 3 - 0
arch/arm/boot/dts/at91sam9260.dtsi

@@ -104,6 +104,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioB: gpio@fffff600 {
 			pioB: gpio@fffff600 {
@@ -113,6 +114,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioC: gpio@fffff800 {
 			pioC: gpio@fffff800 {
@@ -122,6 +124,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			dbgu: serial@fffff200 {
 			dbgu: serial@fffff200 {

+ 5 - 0
arch/arm/boot/dts/at91sam9263.dtsi

@@ -95,6 +95,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioB: gpio@fffff400 {
 			pioB: gpio@fffff400 {
@@ -104,6 +105,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioC: gpio@fffff600 {
 			pioC: gpio@fffff600 {
@@ -113,6 +115,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioD: gpio@fffff800 {
 			pioD: gpio@fffff800 {
@@ -122,6 +125,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioE: gpio@fffffa00 {
 			pioE: gpio@fffffa00 {
@@ -131,6 +135,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			dbgu: serial@ffffee00 {
 			dbgu: serial@ffffee00 {

+ 5 - 0
arch/arm/boot/dts/at91sam9g45.dtsi

@@ -113,6 +113,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioB: gpio@fffff400 {
 			pioB: gpio@fffff400 {
@@ -122,6 +123,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioC: gpio@fffff600 {
 			pioC: gpio@fffff600 {
@@ -131,6 +133,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioD: gpio@fffff800 {
 			pioD: gpio@fffff800 {
@@ -140,6 +143,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioE: gpio@fffffa00 {
 			pioE: gpio@fffffa00 {
@@ -149,6 +153,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			dbgu: serial@ffffee00 {
 			dbgu: serial@ffffee00 {

+ 4 - 0
arch/arm/boot/dts/at91sam9n12.dtsi

@@ -107,6 +107,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioB: gpio@fffff600 {
 			pioB: gpio@fffff600 {
@@ -116,6 +117,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioC: gpio@fffff800 {
 			pioC: gpio@fffff800 {
@@ -125,6 +127,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioD: gpio@fffffa00 {
 			pioD: gpio@fffffa00 {
@@ -134,6 +137,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			dbgu: serial@fffff200 {
 			dbgu: serial@fffff200 {

+ 4 - 0
arch/arm/boot/dts/at91sam9x5.dtsi

@@ -115,6 +115,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioB: gpio@fffff600 {
 			pioB: gpio@fffff600 {
@@ -124,6 +125,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioC: gpio@fffff800 {
 			pioC: gpio@fffff800 {
@@ -133,6 +135,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			pioD: gpio@fffffa00 {
 			pioD: gpio@fffffa00 {
@@ -142,6 +145,7 @@
 				#gpio-cells = <2>;
 				#gpio-cells = <2>;
 				gpio-controller;
 				gpio-controller;
 				interrupt-controller;
 				interrupt-controller;
+				#interrupt-cells = <2>;
 			};
 			};
 
 
 			dbgu: serial@fffff200 {
 			dbgu: serial@fffff200 {

+ 2 - 0
arch/arm/include/asm/unistd.h

@@ -404,6 +404,7 @@
 #define __NR_setns			(__NR_SYSCALL_BASE+375)
 #define __NR_setns			(__NR_SYSCALL_BASE+375)
 #define __NR_process_vm_readv		(__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_readv		(__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev		(__NR_SYSCALL_BASE+377)
 #define __NR_process_vm_writev		(__NR_SYSCALL_BASE+377)
+					/* 378 for kcmp */
 
 
 /*
 /*
  * The following SWIs are ARM private.
  * The following SWIs are ARM private.
@@ -483,6 +484,7 @@
  */
  */
 #define __IGNORE_fadvise64_64
 #define __IGNORE_fadvise64_64
 #define __IGNORE_migrate_pages
 #define __IGNORE_migrate_pages
+#define __IGNORE_kcmp
 
 
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_UNISTD_H */
 #endif /* __ASM_ARM_UNISTD_H */

+ 1 - 0
arch/arm/kernel/calls.S

@@ -387,6 +387,7 @@
 /* 375 */	CALL(sys_setns)
 /* 375 */	CALL(sys_setns)
 		CALL(sys_process_vm_readv)
 		CALL(sys_process_vm_readv)
 		CALL(sys_process_vm_writev)
 		CALL(sys_process_vm_writev)
+		CALL(sys_ni_syscall)	/* reserved for sys_kcmp */
 #ifndef syscalls_counted
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
 #define syscalls_counted

+ 46 - 2
arch/arm/kernel/smp_twd.c

@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
-#include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/err.h>
@@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
 	disable_percpu_irq(clk->irq);
 	disable_percpu_irq(clk->irq);
 }
 }
 
 
-#ifdef CONFIG_CPU_FREQ
+#ifdef CONFIG_COMMON_CLK
+
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *new_rate)
+{
+	twd_timer_rate = *((unsigned long *) new_rate);
+
+	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
+}
+
+static int twd_rate_change(struct notifier_block *nb,
+	unsigned long flags, void *data)
+{
+	struct clk_notifier_data *cnd = data;
+
+	/*
+	 * The twd clock events must be reprogrammed to account for the new
+	 * frequency.  The timer is local to a cpu, so cross-call to the
+	 * changing cpu.
+	 */
+	if (flags == POST_RATE_CHANGE)
+		smp_call_function(twd_update_frequency,
+				  (void *)&cnd->new_rate, 1);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block twd_clk_nb = {
+	.notifier_call = twd_rate_change,
+};
+
+static int twd_clk_init(void)
+{
+	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
+		return clk_notifier_register(twd_clk, &twd_clk_nb);
+
+	return 0;
+}
+core_initcall(twd_clk_init);
+
+#elif defined (CONFIG_CPU_FREQ)
+
+#include <linux/cpufreq.h>
 
 
 /*
 /*
  * Updates clockevent frequency when the cpu frequency changes.
  * Updates clockevent frequency when the cpu frequency changes.

+ 1 - 1
arch/arm/mach-imx/clk-imx25.c

@@ -241,6 +241,6 @@ int __init mx25_clocks_init(void)
 	clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
 	clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
 	clk_register_clkdev(clk[iim_ipg], "iim", NULL);
 	clk_register_clkdev(clk[iim_ipg], "iim", NULL);
 
 
-	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
 	return 0;
 	return 0;
 }
 }

+ 2 - 1
arch/arm/mach-imx/mach-armadillo5x0.c

@@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)
 	imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
 	imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
 
 
 	/* set NAND page size to 2k if not configured via boot mode pins */
 	/* set NAND page size to 2k if not configured via boot mode pins */
-	__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+	__raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) |
+					(1 << 30), mx3_ccm_base + MXC_CCM_RCSR);
 
 
 	/* RTC */
 	/* RTC */
 	/* Get RTC IRQ and register the chip */
 	/* Get RTC IRQ and register the chip */

+ 1 - 1
arch/arm/mach-mxs/mach-mxs.c

@@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)
 	enable_clk_enet_out();
 	enable_clk_enet_out();
 
 
 	if (IS_BUILTIN(CONFIG_PHYLIB))
 	if (IS_BUILTIN(CONFIG_PHYLIB))
-		phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
+		phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
 					   apx4devkit_phy_fixup);
 					   apx4devkit_phy_fixup);
 
 
 	mxsfb_pdata.mode_list = apx4devkit_video_modes;
 	mxsfb_pdata.mode_list = apx4devkit_video_modes;

+ 7 - 0
arch/arm/mach-orion5x/common.c

@@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)
 void __init orion5x_init_early(void)
 void __init orion5x_init_early(void)
 {
 {
 	orion_time_set_base(TIMER_VIRT_BASE);
 	orion_time_set_base(TIMER_VIRT_BASE);
+
+	/*
+	 * Some Orion5x 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 orion5x_tclk;
 int orion5x_tclk;

+ 2 - 2
arch/arm/mach-shmobile/board-kzm9g.c

@@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {
 		.flags	= IORESOURCE_MEM,
 		.flags	= IORESOURCE_MEM,
 	},
 	},
 	[1] = {
 	[1] = {
-		.start	= gic_spi(141),
+		.start	= gic_spi(140),
 		.flags	= IORESOURCE_IRQ,
 		.flags	= IORESOURCE_IRQ,
 	},
 	},
 	[2] = {
 	[2] = {
-		.start	= gic_spi(140),
+		.start	= gic_spi(141),
 		.flags	= IORESOURCE_IRQ,
 		.flags	= IORESOURCE_IRQ,
 	},
 	},
 };
 };

+ 2 - 0
arch/arm/mm/dma-mapping.c

@@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)
 		       (unsigned)pool->size / 1024);
 		       (unsigned)pool->size / 1024);
 		return 0;
 		return 0;
 	}
 	}
+
+	kfree(pages);
 no_pages:
 no_pages:
 	kfree(bitmap);
 	kfree(bitmap);
 no_bitmap:
 no_bitmap:

+ 1 - 0
arch/arm/plat-mxc/include/mach/mx25.h

@@ -98,6 +98,7 @@
 #define MX25_INT_UART1		(NR_IRQS_LEGACY + 45)
 #define MX25_INT_UART1		(NR_IRQS_LEGACY + 45)
 #define MX25_INT_GPIO2		(NR_IRQS_LEGACY + 51)
 #define MX25_INT_GPIO2		(NR_IRQS_LEGACY + 51)
 #define MX25_INT_GPIO1		(NR_IRQS_LEGACY + 52)
 #define MX25_INT_GPIO1		(NR_IRQS_LEGACY + 52)
+#define MX25_INT_GPT1		(NR_IRQS_LEGACY + 54)
 #define MX25_INT_FEC		(NR_IRQS_LEGACY + 57)
 #define MX25_INT_FEC		(NR_IRQS_LEGACY + 57)
 
 
 #define MX25_DMA_REQ_SSI2_RX1	22
 #define MX25_DMA_REQ_SSI2_RX1	22

+ 6 - 4
arch/arm/plat-samsung/clock.c

@@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
 {
+	unsigned long flags;
 	int ret;
 	int ret;
 
 
 	if (IS_ERR(clk))
 	if (IS_ERR(clk))
@@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	if (clk->ops == NULL || clk->ops->set_rate == NULL)
 	if (clk->ops == NULL || clk->ops->set_rate == NULL)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	spin_lock(&clocks_lock);
+	spin_lock_irqsave(&clocks_lock, flags);
 	ret = (clk->ops->set_rate)(clk, rate);
 	ret = (clk->ops->set_rate)(clk, rate);
-	spin_unlock(&clocks_lock);
+	spin_unlock_irqrestore(&clocks_lock, flags);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)
 
 
 int clk_set_parent(struct clk *clk, struct clk *parent)
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
 {
+	unsigned long flags;
 	int ret = 0;
 	int ret = 0;
 
 
 	if (IS_ERR(clk))
 	if (IS_ERR(clk))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	spin_lock(&clocks_lock);
+	spin_lock_irqsave(&clocks_lock, flags);
 
 
 	if (clk->ops && clk->ops->set_parent)
 	if (clk->ops && clk->ops->set_parent)
 		ret = (clk->ops->set_parent)(clk, parent);
 		ret = (clk->ops->set_parent)(clk, parent);
 
 
-	spin_unlock(&clocks_lock);
+	spin_unlock_irqrestore(&clocks_lock, flags);
 
 
 	return ret;
 	return ret;
 }
 }

+ 1 - 0
arch/c6x/include/asm/Kbuild

@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
 
 
 generic-y += atomic.h
 generic-y += atomic.h
 generic-y += auxvec.h
 generic-y += auxvec.h
+generic-y += barrier.h
 generic-y += bitsperlong.h
 generic-y += bitsperlong.h
 generic-y += bugs.h
 generic-y += bugs.h
 generic-y += cputime.h
 generic-y += cputime.h

+ 0 - 27
arch/c6x/include/asm/barrier.h

@@ -1,27 +0,0 @@
-/*
- *  Port on Texas Instruments TMS320C6x architecture
- *
- *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
- *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
-#ifndef _ASM_C6X_BARRIER_H
-#define _ASM_C6X_BARRIER_H
-
-#define nop()                    asm("NOP\n");
-
-#define mb()                     barrier()
-#define rmb()                    barrier()
-#define wmb()                    barrier()
-#define set_mb(var, value)       do { var = value;  mb(); } while (0)
-#define set_wmb(var, value)      do { var = value; wmb(); } while (0)
-
-#define smp_mb()	         barrier()
-#define smp_rmb()	         barrier()
-#define smp_wmb()	         barrier()
-#define smp_read_barrier_depends()	do { } while (0)
-
-#endif /* _ASM_C6X_BARRIER_H */

+ 0 - 6
arch/m68k/platform/coldfire/clk.c

@@ -146,9 +146,3 @@ struct clk_ops clk_ops1 = {
 };
 };
 #endif /* MCFPM_PPMCR1 */
 #endif /* MCFPM_PPMCR1 */
 #endif /* MCFPM_PPMCR0 */
 #endif /* MCFPM_PPMCR0 */
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-	return NULL;
-}
-EXPORT_SYMBOL(devm_clk_get);

+ 1 - 1
arch/mips/kernel/smp-cmp.c

@@ -102,7 +102,7 @@ static void cmp_init_secondary(void)
 	c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
 	c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
 #endif
 #endif
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC
-	c->tc_id  = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
+	c->tc_id  = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
 #endif
 #endif
 }
 }
 
 

+ 2 - 0
arch/mips/mm/gup.c

@@ -152,6 +152,8 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
 	do {
 	do {
 		VM_BUG_ON(compound_head(page) != head);
 		VM_BUG_ON(compound_head(page) != head);
 		pages[*nr] = page;
 		pages[*nr] = page;
+		if (PageTail(page))
+			get_huge_page_tail(page);
 		(*nr)++;
 		(*nr)++;
 		page++;
 		page++;
 		refs++;
 		refs++;

+ 6 - 3
arch/mips/mti-malta/malta-int.c

@@ -273,16 +273,19 @@ asmlinkage void plat_irq_dispatch(void)
 	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 	int irq;
 	int irq;
 
 
+	if (unlikely(!pending)) {
+		spurious_interrupt();
+		return;
+	}
+
 	irq = irq_ffs(pending);
 	irq = irq_ffs(pending);
 
 
 	if (irq == MIPSCPU_INT_I8259A)
 	if (irq == MIPSCPU_INT_I8259A)
 		malta_hw0_irqdispatch();
 		malta_hw0_irqdispatch();
 	else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
 	else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
 		malta_ipi_irqdispatch();
 		malta_ipi_irqdispatch();
-	else if (irq >= 0)
-		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 	else
 	else
-		spurious_interrupt();
+		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 }
 }
 
 
 #ifdef CONFIG_MIPS_MT_SMP
 #ifdef CONFIG_MIPS_MT_SMP

+ 0 - 5
arch/mips/mti-malta/malta-platform.c

@@ -138,11 +138,6 @@ static int __init malta_add_devices(void)
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	/*
-	 * Set RTC to BCD mode to support current alarm code.
-	 */
-	CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 10 - 14
arch/s390/include/asm/hugetlb.h

@@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
 	return pte;
 	return pte;
 }
 }
 
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
-					    unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = huge_ptep_get(ptep);
-
-	mm->context.flush_mm = 1;
-	pmd_clear((pmd_t *) ptep);
-	return pte;
-}
-
 static inline void __pmd_csp(pmd_t *pmdp)
 static inline void __pmd_csp(pmd_t *pmdp)
 {
 {
 	register unsigned long reg2 asm("2") = pmd_val(*pmdp);
 	register unsigned long reg2 asm("2") = pmd_val(*pmdp);
@@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
 		__pmd_csp(pmdp);
 		__pmd_csp(pmdp);
 }
 }
 
 
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+					    unsigned long addr, pte_t *ptep)
+{
+	pte_t pte = huge_ptep_get(ptep);
+
+	huge_ptep_invalidate(mm, addr, ptep);
+	return pte;
+}
+
 #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
 #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
 ({									    \
 ({									    \
 	int __changed = !pte_same(huge_ptep_get(__ptep), __entry);	    \
 	int __changed = !pte_same(huge_ptep_get(__ptep), __entry);	    \
@@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
 ({									\
 ({									\
 	pte_t __pte = huge_ptep_get(__ptep);				\
 	pte_t __pte = huge_ptep_get(__ptep);				\
 	if (pte_write(__pte)) {						\
 	if (pte_write(__pte)) {						\
-		(__mm)->context.flush_mm = 1;				\
-		if (atomic_read(&(__mm)->context.attach_count) > 1 ||	\
-		    (__mm) != current->active_mm)			\
-			huge_ptep_invalidate(__mm, __addr, __ptep);	\
+		huge_ptep_invalidate(__mm, __addr, __ptep);		\
 		set_huge_pte_at(__mm, __addr, __ptep,			\
 		set_huge_pte_at(__mm, __addr, __ptep,			\
 				huge_pte_wrprotect(__pte));		\
 				huge_pte_wrprotect(__pte));		\
 	}								\
 	}								\

+ 0 - 2
arch/s390/include/asm/tlbflush.h

@@ -90,12 +90,10 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
 
 
 static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 {
 {
-	spin_lock(&mm->page_table_lock);
 	if (mm->context.flush_mm) {
 	if (mm->context.flush_mm) {
 		__tlb_flush_mm(mm);
 		__tlb_flush_mm(mm);
 		mm->context.flush_mm = 0;
 		mm->context.flush_mm = 0;
 	}
 	}
-	spin_unlock(&mm->page_table_lock);
 }
 }
 
 
 /*
 /*

+ 2 - 0
arch/s390/kernel/setup.c

@@ -974,11 +974,13 @@ static void __init setup_hwcaps(void)
 	if (MACHINE_HAS_HPAGE)
 	if (MACHINE_HAS_HPAGE)
 		elf_hwcap |= HWCAP_S390_HPAGE;
 		elf_hwcap |= HWCAP_S390_HPAGE;
 
 
+#if defined(CONFIG_64BIT)
 	/*
 	/*
 	 * 64-bit register support for 31-bit processes
 	 * 64-bit register support for 31-bit processes
 	 * HWCAP_S390_HIGH_GPRS is bit 9.
 	 * HWCAP_S390_HIGH_GPRS is bit 9.
 	 */
 	 */
 	elf_hwcap |= HWCAP_S390_HIGH_GPRS;
 	elf_hwcap |= HWCAP_S390_HIGH_GPRS;
+#endif
 
 
 	get_cpu_id(&cpu_id);
 	get_cpu_id(&cpu_id);
 	switch (cpu_id.machine) {
 	switch (cpu_id.machine) {

+ 63 - 79
arch/s390/lib/uaccess_pt.c

@@ -2,69 +2,82 @@
  *  User access functions based on page table walks for enhanced
  *  User access functions based on page table walks for enhanced
  *  system layout without hardware support.
  *  system layout without hardware support.
  *
  *
- *    Copyright IBM Corp. 2006
+ *    Copyright IBM Corp. 2006, 2012
  *    Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
  *    Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
  */
  */
 
 
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/hardirq.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/futex.h>
 #include <asm/futex.h>
 #include "uaccess.h"
 #include "uaccess.h"
 
 
-static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+
+/*
+ * Returns kernel address for user virtual address. If the returned address is
+ * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
+ * contains the (negative) exception code.
+ */
+static __always_inline unsigned long follow_table(struct mm_struct *mm,
+						  unsigned long addr, int write)
 {
 {
 	pgd_t *pgd;
 	pgd_t *pgd;
 	pud_t *pud;
 	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
+	pte_t *ptep;
 
 
 	pgd = pgd_offset(mm, addr);
 	pgd = pgd_offset(mm, addr);
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
 	if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-		return (pte_t *) 0x3a;
+		return -0x3aUL;
 
 
 	pud = pud_offset(pgd, addr);
 	pud = pud_offset(pgd, addr);
 	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
 	if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-		return (pte_t *) 0x3b;
+		return -0x3bUL;
 
 
 	pmd = pmd_offset(pud, addr);
 	pmd = pmd_offset(pud, addr);
-	if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-		return (pte_t *) 0x10;
+	if (pmd_none(*pmd))
+		return -0x10UL;
+	if (pmd_huge(*pmd)) {
+		if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
+			return -0x04UL;
+		return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
+	}
+	if (unlikely(pmd_bad(*pmd)))
+		return -0x10UL;
+
+	ptep = pte_offset_map(pmd, addr);
+	if (!pte_present(*ptep))
+		return -0x11UL;
+	if (write && !pte_write(*ptep))
+		return -0x04UL;
 
 
-	return pte_offset_map(pmd, addr);
+	return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
 }
 }
 
 
 static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
 static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
 					     size_t n, int write_user)
 					     size_t n, int write_user)
 {
 {
 	struct mm_struct *mm = current->mm;
 	struct mm_struct *mm = current->mm;
-	unsigned long offset, pfn, done, size;
-	pte_t *pte;
+	unsigned long offset, done, size, kaddr;
 	void *from, *to;
 	void *from, *to;
 
 
 	done = 0;
 	done = 0;
 retry:
 retry:
 	spin_lock(&mm->page_table_lock);
 	spin_lock(&mm->page_table_lock);
 	do {
 	do {
-		pte = follow_table(mm, uaddr);
-		if ((unsigned long) pte < 0x1000)
+		kaddr = follow_table(mm, uaddr, write_user);
+		if (IS_ERR_VALUE(kaddr))
 			goto fault;
 			goto fault;
-		if (!pte_present(*pte)) {
-			pte = (pte_t *) 0x11;
-			goto fault;
-		} else if (write_user && !pte_write(*pte)) {
-			pte = (pte_t *) 0x04;
-			goto fault;
-		}
 
 
-		pfn = pte_pfn(*pte);
-		offset = uaddr & (PAGE_SIZE - 1);
+		offset = uaddr & ~PAGE_MASK;
 		size = min(n - done, PAGE_SIZE - offset);
 		size = min(n - done, PAGE_SIZE - offset);
 		if (write_user) {
 		if (write_user) {
-			to = (void *)((pfn << PAGE_SHIFT) + offset);
+			to = (void *) kaddr;
 			from = kptr + done;
 			from = kptr + done;
 		} else {
 		} else {
-			from = (void *)((pfn << PAGE_SHIFT) + offset);
+			from = (void *) kaddr;
 			to = kptr + done;
 			to = kptr + done;
 		}
 		}
 		memcpy(to, from, size);
 		memcpy(to, from, size);
@@ -75,7 +88,7 @@ retry:
 	return n - done;
 	return n - done;
 fault:
 fault:
 	spin_unlock(&mm->page_table_lock);
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(uaddr, (unsigned long) pte, write_user))
+	if (__handle_fault(uaddr, -kaddr, write_user))
 		return n - done;
 		return n - done;
 	goto retry;
 	goto retry;
 }
 }
@@ -84,27 +97,22 @@ fault:
  * Do DAT for user address by page table walk, return kernel address.
  * Do DAT for user address by page table walk, return kernel address.
  * This function needs to be called with current->mm->page_table_lock held.
  * This function needs to be called with current->mm->page_table_lock held.
  */
  */
-static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
+static __always_inline unsigned long __dat_user_addr(unsigned long uaddr,
+						     int write)
 {
 {
 	struct mm_struct *mm = current->mm;
 	struct mm_struct *mm = current->mm;
-	unsigned long pfn;
-	pte_t *pte;
+	unsigned long kaddr;
 	int rc;
 	int rc;
 
 
 retry:
 retry:
-	pte = follow_table(mm, uaddr);
-	if ((unsigned long) pte < 0x1000)
-		goto fault;
-	if (!pte_present(*pte)) {
-		pte = (pte_t *) 0x11;
+	kaddr = follow_table(mm, uaddr, write);
+	if (IS_ERR_VALUE(kaddr))
 		goto fault;
 		goto fault;
-	}
 
 
-	pfn = pte_pfn(*pte);
-	return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
+	return kaddr;
 fault:
 fault:
 	spin_unlock(&mm->page_table_lock);
 	spin_unlock(&mm->page_table_lock);
-	rc = __handle_fault(uaddr, (unsigned long) pte, 0);
+	rc = __handle_fault(uaddr, -kaddr, write);
 	spin_lock(&mm->page_table_lock);
 	spin_lock(&mm->page_table_lock);
 	if (!rc)
 	if (!rc)
 		goto retry;
 		goto retry;
@@ -159,11 +167,9 @@ static size_t clear_user_pt(size_t n, void __user *to)
 
 
 static size_t strnlen_user_pt(size_t count, const char __user *src)
 static size_t strnlen_user_pt(size_t count, const char __user *src)
 {
 {
-	char *addr;
 	unsigned long uaddr = (unsigned long) src;
 	unsigned long uaddr = (unsigned long) src;
 	struct mm_struct *mm = current->mm;
 	struct mm_struct *mm = current->mm;
-	unsigned long offset, pfn, done, len;
-	pte_t *pte;
+	unsigned long offset, done, len, kaddr;
 	size_t len_str;
 	size_t len_str;
 
 
 	if (segment_eq(get_fs(), KERNEL_DS))
 	if (segment_eq(get_fs(), KERNEL_DS))
@@ -172,19 +178,13 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
 retry:
 retry:
 	spin_lock(&mm->page_table_lock);
 	spin_lock(&mm->page_table_lock);
 	do {
 	do {
-		pte = follow_table(mm, uaddr);
-		if ((unsigned long) pte < 0x1000)
-			goto fault;
-		if (!pte_present(*pte)) {
-			pte = (pte_t *) 0x11;
+		kaddr = follow_table(mm, uaddr, 0);
+		if (IS_ERR_VALUE(kaddr))
 			goto fault;
 			goto fault;
-		}
 
 
-		pfn = pte_pfn(*pte);
-		offset = uaddr & (PAGE_SIZE-1);
-		addr = (char *)(pfn << PAGE_SHIFT) + offset;
+		offset = uaddr & ~PAGE_MASK;
 		len = min(count - done, PAGE_SIZE - offset);
 		len = min(count - done, PAGE_SIZE - offset);
-		len_str = strnlen(addr, len);
+		len_str = strnlen((char *) kaddr, len);
 		done += len_str;
 		done += len_str;
 		uaddr += len_str;
 		uaddr += len_str;
 	} while ((len_str == len) && (done < count));
 	} while ((len_str == len) && (done < count));
@@ -192,7 +192,7 @@ retry:
 	return done + 1;
 	return done + 1;
 fault:
 fault:
 	spin_unlock(&mm->page_table_lock);
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(uaddr, (unsigned long) pte, 0))
+	if (__handle_fault(uaddr, -kaddr, 0))
 		return 0;
 		return 0;
 	goto retry;
 	goto retry;
 }
 }
@@ -225,11 +225,10 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
 			      const void __user *from)
 			      const void __user *from)
 {
 {
 	struct mm_struct *mm = current->mm;
 	struct mm_struct *mm = current->mm;
-	unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
-		      uaddr, done, size, error_code;
+	unsigned long offset_max, uaddr, done, size, error_code;
 	unsigned long uaddr_from = (unsigned long) from;
 	unsigned long uaddr_from = (unsigned long) from;
 	unsigned long uaddr_to = (unsigned long) to;
 	unsigned long uaddr_to = (unsigned long) to;
-	pte_t *pte_from, *pte_to;
+	unsigned long kaddr_to, kaddr_from;
 	int write_user;
 	int write_user;
 
 
 	if (segment_eq(get_fs(), KERNEL_DS)) {
 	if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -242,38 +241,23 @@ retry:
 	do {
 	do {
 		write_user = 0;
 		write_user = 0;
 		uaddr = uaddr_from;
 		uaddr = uaddr_from;
-		pte_from = follow_table(mm, uaddr_from);
-		error_code = (unsigned long) pte_from;
-		if (error_code < 0x1000)
-			goto fault;
-		if (!pte_present(*pte_from)) {
-			error_code = 0x11;
+		kaddr_from = follow_table(mm, uaddr_from, 0);
+		error_code = kaddr_from;
+		if (IS_ERR_VALUE(error_code))
 			goto fault;
 			goto fault;
-		}
 
 
 		write_user = 1;
 		write_user = 1;
 		uaddr = uaddr_to;
 		uaddr = uaddr_to;
-		pte_to = follow_table(mm, uaddr_to);
-		error_code = (unsigned long) pte_to;
-		if (error_code < 0x1000)
-			goto fault;
-		if (!pte_present(*pte_to)) {
-			error_code = 0x11;
+		kaddr_to = follow_table(mm, uaddr_to, 1);
+		error_code = (unsigned long) kaddr_to;
+		if (IS_ERR_VALUE(error_code))
 			goto fault;
 			goto fault;
-		} else if (!pte_write(*pte_to)) {
-			error_code = 0x04;
-			goto fault;
-		}
 
 
-		pfn_from = pte_pfn(*pte_from);
-		pfn_to = pte_pfn(*pte_to);
-		offset_from = uaddr_from & (PAGE_SIZE-1);
-		offset_to = uaddr_from & (PAGE_SIZE-1);
-		offset_max = max(offset_from, offset_to);
+		offset_max = max(uaddr_from & ~PAGE_MASK,
+				 uaddr_to & ~PAGE_MASK);
 		size = min(n - done, PAGE_SIZE - offset_max);
 		size = min(n - done, PAGE_SIZE - offset_max);
 
 
-		memcpy((void *)(pfn_to << PAGE_SHIFT) + offset_to,
-		       (void *)(pfn_from << PAGE_SHIFT) + offset_from, size);
+		memcpy((void *) kaddr_to, (void *) kaddr_from, size);
 		done += size;
 		done += size;
 		uaddr_from += size;
 		uaddr_from += size;
 		uaddr_to += size;
 		uaddr_to += size;
@@ -282,7 +266,7 @@ retry:
 	return n - done;
 	return n - done;
 fault:
 fault:
 	spin_unlock(&mm->page_table_lock);
 	spin_unlock(&mm->page_table_lock);
-	if (__handle_fault(uaddr, error_code, write_user))
+	if (__handle_fault(uaddr, -error_code, write_user))
 		return n - done;
 		return n - done;
 	goto retry;
 	goto retry;
 }
 }
@@ -341,7 +325,7 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
 		return __futex_atomic_op_pt(op, uaddr, oparg, old);
 		return __futex_atomic_op_pt(op, uaddr, oparg, old);
 	spin_lock(&current->mm->page_table_lock);
 	spin_lock(&current->mm->page_table_lock);
 	uaddr = (u32 __force __user *)
 	uaddr = (u32 __force __user *)
-		__dat_user_addr((__force unsigned long) uaddr);
+		__dat_user_addr((__force unsigned long) uaddr, 1);
 	if (!uaddr) {
 	if (!uaddr) {
 		spin_unlock(&current->mm->page_table_lock);
 		spin_unlock(&current->mm->page_table_lock);
 		return -EFAULT;
 		return -EFAULT;
@@ -378,7 +362,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
 		return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
 		return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
 	spin_lock(&current->mm->page_table_lock);
 	spin_lock(&current->mm->page_table_lock);
 	uaddr = (u32 __force __user *)
 	uaddr = (u32 __force __user *)
-		__dat_user_addr((__force unsigned long) uaddr);
+		__dat_user_addr((__force unsigned long) uaddr, 1);
 	if (!uaddr) {
 	if (!uaddr) {
 		spin_unlock(&current->mm->page_table_lock);
 		spin_unlock(&current->mm->page_table_lock);
 		return -EFAULT;
 		return -EFAULT;

+ 1 - 1
arch/sh/kernel/cpu/sh5/entry.S

@@ -933,7 +933,7 @@ ret_with_reschedule:
 
 
 	pta	restore_all, tr1
 	pta	restore_all, tr1
 
 
-	movi	_TIF_SIGPENDING, r8
+	movi	(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
 	and	r8, r7, r8
 	and	r8, r7, r8
 	pta	work_notifysig, tr0
 	pta	work_notifysig, tr0
 	bne	r8, ZERO, tr0
 	bne	r8, ZERO, tr0

+ 1 - 1
arch/sh/kernel/entry-common.S

@@ -139,7 +139,7 @@ work_pending:
 	! r8: current_thread_info
 	! r8: current_thread_info
 	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
 	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
 	bf/s	work_resched
 	bf/s	work_resched
-	 tst	#_TIF_SIGPENDING, r0
+	 tst	#(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
 work_notifysig:
 work_notifysig:
 	bt/s	__restore_all
 	bt/s	__restore_all
 	 mov	r15, r4
 	 mov	r15, r4

+ 5 - 8
arch/sparc/kernel/module.c

@@ -48,9 +48,7 @@ void *module_alloc(unsigned long size)
 		return NULL;
 		return NULL;
 
 
 	ret = module_map(size);
 	ret = module_map(size);
-	if (!ret)
-		ret = ERR_PTR(-ENOMEM);
-	else
+	if (ret)
 		memset(ret, 0, size);
 		memset(ret, 0, size);
 
 
 	return ret;
 	return ret;
@@ -116,6 +114,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
 		v = sym->st_value + rel[i].r_addend;
 		v = sym->st_value + rel[i].r_addend;
 
 
 		switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
 		switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
+		case R_SPARC_DISP32:
+			v -= (Elf_Addr) location;
+			*loc32 = v;
+			break;
 #ifdef CONFIG_SPARC64
 #ifdef CONFIG_SPARC64
 		case R_SPARC_64:
 		case R_SPARC_64:
 			location[0] = v >> 56;
 			location[0] = v >> 56;
@@ -128,11 +130,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
 			location[7] = v >>  0;
 			location[7] = v >>  0;
 			break;
 			break;
 
 
-		case R_SPARC_DISP32:
-			v -= (Elf_Addr) location;
-			*loc32 = v;
-			break;
-
 		case R_SPARC_WDISP19:
 		case R_SPARC_WDISP19:
 			v -= (Elf_Addr) location;
 			v -= (Elf_Addr) location;
 			*loc32 = (*loc32 & ~0x7ffff) |
 			*loc32 = (*loc32 & ~0x7ffff) |

+ 13 - 11
arch/tile/include/gxio/iorpc_trio.h

@@ -25,21 +25,23 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <asm/pgtable.h>
 #include <asm/pgtable.h>
 
 
-#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_DEALLOC_ASID      IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1401)
 
 
-#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1402)
+#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
 
 
-#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e)
-#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140f)
+#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
 
 
-#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1417)
-#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1418)
-#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1419)
-#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x141a)
+#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
 
 
-#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141c)
-#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141d)
-#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141f)
+#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1420)
+#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1421)
+
+#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1423)
+#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1424)
+#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1425)
 #define GXIO_TRIO_OP_GET_MMIO_BASE     IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
 #define GXIO_TRIO_OP_GET_MMIO_BASE     IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
 #define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
 #define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
 
 

+ 0 - 9
arch/um/include/asm/processor-generic.h

@@ -20,14 +20,6 @@ struct mm_struct;
 
 
 struct thread_struct {
 struct thread_struct {
 	struct task_struct *saved_task;
 	struct task_struct *saved_task;
-	/*
-	 * This flag is set to 1 before calling do_fork (and analyzed in
-	 * copy_thread) to mark that we are begin called from userspace (fork /
-	 * vfork / clone), and reset to 0 after. It is left to 0 when called
-	 * from kernelspace (i.e. kernel_thread() or fork_idle(),
-	 * as of 2.6.11).
-	 */
-	int forking;
 	struct pt_regs regs;
 	struct pt_regs regs;
 	int singlestep_syscall;
 	int singlestep_syscall;
 	void *fault_addr;
 	void *fault_addr;
@@ -58,7 +50,6 @@ struct thread_struct {
 
 
 #define INIT_THREAD \
 #define INIT_THREAD \
 { \
 { \
-	.forking		= 0, \
 	.regs		   	= EMPTY_REGS,	\
 	.regs		   	= EMPTY_REGS,	\
 	.fault_addr		= NULL, \
 	.fault_addr		= NULL, \
 	.prev_sched		= NULL, \
 	.prev_sched		= NULL, \

+ 0 - 10
arch/um/include/shared/common-offsets.h

@@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 
 
-DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
-DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
-DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
-DEFINE_STR(UM_KERN_ERR, KERN_ERR);
-DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
-DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
-DEFINE_STR(UM_KERN_INFO, KERN_INFO);
-DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
-DEFINE_STR(UM_KERN_CONT, KERN_CONT);
-
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);

+ 11 - 0
arch/um/include/shared/user.h

@@ -26,6 +26,17 @@
 extern void panic(const char *fmt, ...)
 extern void panic(const char *fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
 	__attribute__ ((format (printf, 1, 2)));
 
 
+/* Requires preincluding include/linux/kern_levels.h */
+#define UM_KERN_EMERG	KERN_EMERG
+#define UM_KERN_ALERT	KERN_ALERT
+#define UM_KERN_CRIT	KERN_CRIT
+#define UM_KERN_ERR	KERN_ERR
+#define UM_KERN_WARNING	KERN_WARNING
+#define UM_KERN_NOTICE	KERN_NOTICE
+#define UM_KERN_INFO	KERN_INFO
+#define UM_KERN_DEBUG	KERN_DEBUG
+#define UM_KERN_CONT	KERN_CONT
+
 #ifdef UML_CONFIG_PRINTK
 #ifdef UML_CONFIG_PRINTK
 extern int printk(const char *fmt, ...)
 extern int printk(const char *fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
 	__attribute__ ((format (printf, 1, 2)));

+ 6 - 19
arch/um/kernel/exec.c

@@ -39,34 +39,21 @@ void flush_thread(void)
 
 
 void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 {
 {
+	get_safe_registers(regs->regs.gp, regs->regs.fp);
 	PT_REGS_IP(regs) = eip;
 	PT_REGS_IP(regs) = eip;
 	PT_REGS_SP(regs) = esp;
 	PT_REGS_SP(regs) = esp;
-}
-EXPORT_SYMBOL(start_thread);
-
-static long execve1(const char *file,
-		    const char __user *const __user *argv,
-		    const char __user *const __user *env)
-{
-	long error;
-
-	error = do_execve(file, argv, env, &current->thread.regs);
-	if (error == 0) {
-		task_lock(current);
-		current->ptrace &= ~PT_DTRACE;
+	current->ptrace &= ~PT_DTRACE;
 #ifdef SUBARCH_EXECVE1
 #ifdef SUBARCH_EXECVE1
-		SUBARCH_EXECVE1(&current->thread.regs.regs);
+	SUBARCH_EXECVE1(regs->regs);
 #endif
 #endif
-		task_unlock(current);
-	}
-	return error;
 }
 }
+EXPORT_SYMBOL(start_thread);
 
 
 long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
 long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
 {
 {
 	long err;
 	long err;
 
 
-	err = execve1(file, argv, env);
+	err = do_execve(file, argv, env, &current->thread.regs);
 	if (!err)
 	if (!err)
 		UML_LONGJMP(current->thread.exec_buf, 1);
 		UML_LONGJMP(current->thread.exec_buf, 1);
 	return err;
 	return err;
@@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
 	filename = getname(file);
 	filename = getname(file);
 	error = PTR_ERR(filename);
 	error = PTR_ERR(filename);
 	if (IS_ERR(filename)) goto out;
 	if (IS_ERR(filename)) goto out;
-	error = execve1(filename, argv, env);
+	error = do_execve(filename, argv, env, &current->thread.regs);
 	putname(filename);
 	putname(filename);
  out:
  out:
 	return error;
 	return error;

+ 4 - 4
arch/um/kernel/process.c

@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 		struct pt_regs *regs)
 		struct pt_regs *regs)
 {
 {
 	void (*handler)(void);
 	void (*handler)(void);
+	int kthread = current->flags & PF_KTHREAD;
 	int ret = 0;
 	int ret = 0;
 
 
 	p->thread = (struct thread_struct) INIT_THREAD;
 	p->thread = (struct thread_struct) INIT_THREAD;
 
 
-	if (current->thread.forking) {
+	if (!kthread) {
 	  	memcpy(&p->thread.regs.regs, &regs->regs,
 	  	memcpy(&p->thread.regs.regs, &regs->regs,
 		       sizeof(p->thread.regs.regs));
 		       sizeof(p->thread.regs.regs));
 		PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
 		PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
@@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 		handler = fork_handler;
 		handler = fork_handler;
 
 
 		arch_copy_thread(&current->thread.arch, &p->thread.arch);
 		arch_copy_thread(&current->thread.arch, &p->thread.arch);
-	}
-	else {
+	} else {
 		get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
 		get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
 		p->thread.request.u.thread = current->thread.request.u.thread;
 		p->thread.request.u.thread = current->thread.request.u.thread;
 		handler = new_thread_handler;
 		handler = new_thread_handler;
@@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
 
 	new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
 	new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
 
 
-	if (current->thread.forking) {
+	if (!kthread) {
 		clear_flushed_tls(p);
 		clear_flushed_tls(p);
 
 
 		/*
 		/*

+ 5 - 1
arch/um/kernel/signal.c

@@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
 			 struct k_sigaction *ka, siginfo_t *info)
 			 struct k_sigaction *ka, siginfo_t *info)
 {
 {
 	sigset_t *oldset = sigmask_to_save();
 	sigset_t *oldset = sigmask_to_save();
+	int singlestep = 0;
 	unsigned long sp;
 	unsigned long sp;
 	int err;
 	int err;
 
 
+	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
+		singlestep = 1;
+
 	/* Did we come from a system call? */
 	/* Did we come from a system call? */
 	if (PT_REGS_SYSCALL_NR(regs) >= 0) {
 	if (PT_REGS_SYSCALL_NR(regs) >= 0) {
 		/* If so, check system call restarting.. */
 		/* If so, check system call restarting.. */
@@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
 	if (err)
 	if (err)
 		force_sigsegv(signr, current);
 		force_sigsegv(signr, current);
 	else
 	else
-		signal_delivered(signr, info, ka, regs, 0);
+		signal_delivered(signr, info, ka, regs, singlestep);
 }
 }
 
 
 static int kern_do_signal(struct pt_regs *regs)
 static int kern_do_signal(struct pt_regs *regs)

+ 12 - 12
arch/um/kernel/syscall.c

@@ -17,25 +17,25 @@
 
 
 long sys_fork(void)
 long sys_fork(void)
 {
 {
-	long ret;
-
-	current->thread.forking = 1;
-	ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
+	return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
 		      &current->thread.regs, 0, NULL, NULL);
 		      &current->thread.regs, 0, NULL, NULL);
-	current->thread.forking = 0;
-	return ret;
 }
 }
 
 
 long sys_vfork(void)
 long sys_vfork(void)
 {
 {
-	long ret;
-
-	current->thread.forking = 1;
-	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
 		      UPT_SP(&current->thread.regs.regs),
 		      UPT_SP(&current->thread.regs.regs),
 		      &current->thread.regs, 0, NULL, NULL);
 		      &current->thread.regs, 0, NULL, NULL);
-	current->thread.forking = 0;
-	return ret;
+}
+
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+	       void __user *parent_tid, void __user *child_tid)
+{
+	if (!newsp)
+		newsp = UPT_SP(&current->thread.regs.regs);
+
+	return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+		      child_tid);
 }
 }
 
 
 long old_mmap(unsigned long addr, unsigned long len,
 long old_mmap(unsigned long addr, unsigned long len,

+ 1 - 1
arch/um/scripts/Makefile.rules

@@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m)  $(USER_SINGLE_OBJS))
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 
 $(USER_OBJS:.o=.%): \
 $(USER_OBJS:.o=.%): \
-	c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o)
+	c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o)
 
 
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # using it directly.
 # using it directly.

+ 4 - 4
arch/x86/Kconfig

@@ -746,10 +746,10 @@ config SWIOTLB
 	def_bool y if X86_64
 	def_bool y if X86_64
 	---help---
 	---help---
 	  Support for software bounce buffers used on x86-64 systems
 	  Support for software bounce buffers used on x86-64 systems
-	  which don't have a hardware IOMMU (e.g. the current generation
-	  of Intel's x86-64 CPUs). Using this PCI devices which can only
-	  access 32-bits of memory can be used on systems with more than
-	  3 GB of memory. If unsure, say Y.
+	  which don't have a hardware IOMMU. Using this PCI devices
+	  which can only access 32-bits of memory can be used on systems
+	  with more than 3 GB of memory.
+	  If unsure, say Y.
 
 
 config IOMMU_HELPER
 config IOMMU_HELPER
 	def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
 	def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)

+ 1 - 1
arch/x86/Makefile

@@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 
 
-archscripts:
+archscripts: scripts_basic
 	$(Q)$(MAKE) $(build)=arch/x86/tools relocs
 	$(Q)$(MAKE) $(build)=arch/x86/tools relocs
 
 
 ###
 ###

+ 2 - 1
arch/x86/include/asm/xen/page.h

@@ -51,7 +51,8 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
 
 
 extern int m2p_add_override(unsigned long mfn, struct page *page,
 extern int m2p_add_override(unsigned long mfn, struct page *page,
 			    struct gnttab_map_grant_ref *kmap_op);
 			    struct gnttab_map_grant_ref *kmap_op);
-extern int m2p_remove_override(struct page *page, bool clear_pte);
+extern int m2p_remove_override(struct page *page,
+				struct gnttab_map_grant_ref *kmap_op);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 
 

+ 2 - 0
arch/x86/kernel/cpu/perf_event.h

@@ -586,6 +586,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
 
 
 extern struct event_constraint intel_snb_pebs_event_constraints[];
 extern struct event_constraint intel_snb_pebs_event_constraints[];
 
 
+extern struct event_constraint intel_ivb_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 
 void intel_pmu_pebs_enable(struct perf_event *event);
 void intel_pmu_pebs_enable(struct perf_event *event);

+ 12 - 0
arch/x86/kernel/cpu/perf_event_amd_ibs.c

@@ -209,6 +209,15 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
 	return -EOPNOTSUPP;
 	return -EOPNOTSUPP;
 }
 }
 
 
+static const struct perf_event_attr ibs_notsupp = {
+	.exclude_user	= 1,
+	.exclude_kernel	= 1,
+	.exclude_hv	= 1,
+	.exclude_idle	= 1,
+	.exclude_host	= 1,
+	.exclude_guest	= 1,
+};
+
 static int perf_ibs_init(struct perf_event *event)
 static int perf_ibs_init(struct perf_event *event)
 {
 {
 	struct hw_perf_event *hwc = &event->hw;
 	struct hw_perf_event *hwc = &event->hw;
@@ -229,6 +238,9 @@ static int perf_ibs_init(struct perf_event *event)
 	if (event->pmu != &perf_ibs->pmu)
 	if (event->pmu != &perf_ibs->pmu)
 		return -ENOENT;
 		return -ENOENT;
 
 
+	if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+		return -EINVAL;
+
 	if (config & ~perf_ibs->config_mask)
 	if (config & ~perf_ibs->config_mask)
 		return -EINVAL;
 		return -EINVAL;
 
 

+ 23 - 1
arch/x86/kernel/cpu/perf_event_intel.c

@@ -2048,7 +2048,6 @@ __init int intel_pmu_init(void)
 	case 42: /* SandyBridge */
 	case 42: /* SandyBridge */
 	case 45: /* SandyBridge, "Romely-EP" */
 	case 45: /* SandyBridge, "Romely-EP" */
 		x86_add_quirk(intel_sandybridge_quirk);
 		x86_add_quirk(intel_sandybridge_quirk);
-	case 58: /* IvyBridge */
 		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
 		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 		       sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
 		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
@@ -2073,6 +2072,29 @@ __init int intel_pmu_init(void)
 
 
 		pr_cont("SandyBridge events, ");
 		pr_cont("SandyBridge events, ");
 		break;
 		break;
+	case 58: /* IvyBridge */
+		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+		       sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_snb();
+
+		x86_pmu.event_constraints = intel_snb_event_constraints;
+		x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		x86_pmu.extra_regs = intel_snb_extra_regs;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.er_flags |= ERF_HAS_RSP_1;
+		x86_pmu.er_flags |= ERF_NO_HT_SHARING;
+
+		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+			X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+
+		pr_cont("IvyBridge events, ");
+		break;
+
 
 
 	default:
 	default:
 		switch (x86_pmu.version) {
 		switch (x86_pmu.version) {

+ 14 - 0
arch/x86/kernel/cpu/perf_event_intel_ds.c

@@ -407,6 +407,20 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
 	EVENT_CONSTRAINT_END
 	EVENT_CONSTRAINT_END
 };
 };
 
 
+struct event_constraint intel_ivb_pebs_event_constraints[] = {
+        INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+        INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+        INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+        INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+        EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
 {
 	struct event_constraint *c;
 	struct event_constraint *c;

+ 6 - 0
arch/x86/kernel/cpu/perf_event_intel_uncore.c

@@ -661,6 +661,11 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
 	}
 	}
 }
 }
 
 
+static struct uncore_event_desc snb_uncore_events[] = {
+	INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+	{ /* end: all zeroes */ },
+};
+
 static struct attribute *snb_uncore_formats_attr[] = {
 static struct attribute *snb_uncore_formats_attr[] = {
 	&format_attr_event.attr,
 	&format_attr_event.attr,
 	&format_attr_umask.attr,
 	&format_attr_umask.attr,
@@ -704,6 +709,7 @@ static struct intel_uncore_type snb_uncore_cbox = {
 	.constraints	= snb_uncore_cbox_constraints,
 	.constraints	= snb_uncore_cbox_constraints,
 	.ops		= &snb_uncore_msr_ops,
 	.ops		= &snb_uncore_msr_ops,
 	.format_group	= &snb_uncore_format_group,
 	.format_group	= &snb_uncore_format_group,
+	.event_descs	= snb_uncore_events,
 };
 };
 
 
 static struct intel_uncore_type *snb_msr_uncores[] = {
 static struct intel_uncore_type *snb_msr_uncores[] = {

+ 1 - 1
arch/x86/mm/init.c

@@ -319,7 +319,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
  */
  */
 int devmem_is_allowed(unsigned long pagenr)
 int devmem_is_allowed(unsigned long pagenr)
 {
 {
-	if (pagenr <= 256)
+	if (pagenr < 256)
 		return 1;
 		return 1;
 	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
 	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
 		return 0;
 		return 0;

+ 1 - 0
arch/x86/um/Kconfig

@@ -21,6 +21,7 @@ config 64BIT
 config X86_32
 config X86_32
 	def_bool !64BIT
 	def_bool !64BIT
 	select HAVE_AOUT
 	select HAVE_AOUT
+	select ARCH_WANT_IPC_PARSE_VERSION
 
 
 config X86_64
 config X86_64
 	def_bool 64BIT
 	def_bool 64BIT

+ 0 - 3
arch/x86/um/shared/sysdep/kernel-offsets.h

@@ -7,9 +7,6 @@
 #define DEFINE(sym, val) \
 #define DEFINE(sym, val) \
 	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 
-#define STR(x) #x
-#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
-
 #define BLANK() asm volatile("\n->" : : )
 #define BLANK() asm volatile("\n->" : : )
 
 
 #define OFFSET(sym, str, mem) \
 #define OFFSET(sym, str, mem) \

+ 2 - 0
arch/x86/um/shared/sysdep/syscalls.h

@@ -1,3 +1,5 @@
+extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
+	       void __user *parent_tid, void __user *child_tid);
 #ifdef __i386__
 #ifdef __i386__
 #include "syscalls_32.h"
 #include "syscalls_32.h"
 #else
 #else

+ 0 - 6
arch/x86/um/signal.c

@@ -416,9 +416,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
 	PT_REGS_AX(regs) = (unsigned long) sig;
 	PT_REGS_AX(regs) = (unsigned long) sig;
 	PT_REGS_DX(regs) = (unsigned long) 0;
 	PT_REGS_DX(regs) = (unsigned long) 0;
 	PT_REGS_CX(regs) = (unsigned long) 0;
 	PT_REGS_CX(regs) = (unsigned long) 0;
-
-	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-		ptrace_notify(SIGTRAP);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -466,9 +463,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 	PT_REGS_AX(regs) = (unsigned long) sig;
 	PT_REGS_AX(regs) = (unsigned long) sig;
 	PT_REGS_DX(regs) = (unsigned long) &frame->info;
 	PT_REGS_DX(regs) = (unsigned long) &frame->info;
 	PT_REGS_CX(regs) = (unsigned long) &frame->uc;
 	PT_REGS_CX(regs) = (unsigned long) &frame->uc;
-
-	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-		ptrace_notify(SIGTRAP);
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
arch/x86/um/sys_call_table_32.c

@@ -28,7 +28,7 @@
 #define ptregs_execve sys_execve
 #define ptregs_execve sys_execve
 #define ptregs_iopl sys_iopl
 #define ptregs_iopl sys_iopl
 #define ptregs_vm86old sys_vm86old
 #define ptregs_vm86old sys_vm86old
-#define ptregs_clone sys_clone
+#define ptregs_clone i386_clone
 #define ptregs_vm86 sys_vm86
 #define ptregs_vm86 sys_vm86
 #define ptregs_sigaltstack sys_sigaltstack
 #define ptregs_sigaltstack sys_sigaltstack
 #define ptregs_vfork sys_vfork
 #define ptregs_vfork sys_vfork

+ 7 - 20
arch/x86/um/syscalls_32.c

@@ -3,37 +3,24 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
-#include "linux/sched.h"
-#include "linux/shm.h"
-#include "linux/ipc.h"
-#include "linux/syscalls.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "asm/unistd.h"
+#include <linux/syscalls.h>
+#include <sysdep/syscalls.h>
 
 
 /*
 /*
  * The prototype on i386 is:
  * The prototype on i386 is:
  *
  *
- *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
+ *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
  *
  *
  * and the "newtls" arg. on i386 is read by copy_thread directly from the
  * and the "newtls" arg. on i386 is read by copy_thread directly from the
  * register saved on the stack.
  * register saved on the stack.
  */
  */
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-	       int __user *parent_tid, void *newtls, int __user *child_tid)
+long i386_clone(unsigned long clone_flags, unsigned long newsp,
+		int __user *parent_tid, void *newtls, int __user *child_tid)
 {
 {
-	long ret;
-
-	if (!newsp)
-		newsp = UPT_SP(&current->thread.regs.regs);
-
-	current->thread.forking = 1;
-	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-		      child_tid);
-	current->thread.forking = 0;
-	return ret;
+	return sys_clone(clone_flags, newsp, parent_tid, child_tid);
 }
 }
 
 
+
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
 			 struct old_sigaction __user *oact)
 			 struct old_sigaction __user *oact)
 {
 {

+ 3 - 20
arch/x86/um/syscalls_64.c

@@ -5,12 +5,9 @@
  * Licensed under the GPL
  * Licensed under the GPL
  */
  */
 
 
-#include "linux/linkage.h"
-#include "linux/personality.h"
-#include "linux/utsname.h"
-#include "asm/prctl.h" /* XXX This should get the constants from libc */
-#include "asm/uaccess.h"
-#include "os.h"
+#include <linux/sched.h>
+#include <asm/prctl.h> /* XXX This should get the constants from libc */
+#include <os.h>
 
 
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
 {
@@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
 	return arch_prctl(current, code, (unsigned long __user *) addr);
 	return arch_prctl(current, code, (unsigned long __user *) addr);
 }
 }
 
 
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-	       void __user *parent_tid, void __user *child_tid)
-{
-	long ret;
-
-	if (!newsp)
-		newsp = UPT_SP(&current->thread.regs.regs);
-	current->thread.forking = 1;
-	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-		      child_tid);
-	current->thread.forking = 0;
-	return ret;
-}
-
 void arch_switch_to(struct task_struct *to)
 void arch_switch_to(struct task_struct *to)
 {
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))

+ 4 - 0
arch/x86/xen/enlighten.c

@@ -1452,6 +1452,10 @@ asmlinkage void __init xen_start_kernel(void)
 		pci_request_acs();
 		pci_request_acs();
 
 
 		xen_acpi_sleep_register();
 		xen_acpi_sleep_register();
+
+		/* Avoid searching for BIOS MP tables */
+		x86_init.mpparse.find_smp_config = x86_init_noop;
+		x86_init.mpparse.get_smp_config = x86_init_uint_noop;
 	}
 	}
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 	/* PCI BIOS service won't work from a PV guest. */
 	/* PCI BIOS service won't work from a PV guest. */

+ 11 - 16
arch/x86/xen/p2m.c

@@ -828,9 +828,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
 
 
 			xen_mc_issue(PARAVIRT_LAZY_MMU);
 			xen_mc_issue(PARAVIRT_LAZY_MMU);
 		}
 		}
-		/* let's use dev_bus_addr to record the old mfn instead */
-		kmap_op->dev_bus_addr = page->index;
-		page->index = (unsigned long) kmap_op;
 	}
 	}
 	spin_lock_irqsave(&m2p_override_lock, flags);
 	spin_lock_irqsave(&m2p_override_lock, flags);
 	list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
 	list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
@@ -857,7 +854,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(m2p_add_override);
 EXPORT_SYMBOL_GPL(m2p_add_override);
-int m2p_remove_override(struct page *page, bool clear_pte)
+int m2p_remove_override(struct page *page,
+		struct gnttab_map_grant_ref *kmap_op)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	unsigned long mfn;
 	unsigned long mfn;
@@ -887,10 +885,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
 	WARN_ON(!PagePrivate(page));
 	WARN_ON(!PagePrivate(page));
 	ClearPagePrivate(page);
 	ClearPagePrivate(page);
 
 
-	if (clear_pte) {
-		struct gnttab_map_grant_ref *map_op =
-			(struct gnttab_map_grant_ref *) page->index;
-		set_phys_to_machine(pfn, map_op->dev_bus_addr);
+	set_phys_to_machine(pfn, page->index);
+	if (kmap_op != NULL) {
 		if (!PageHighMem(page)) {
 		if (!PageHighMem(page)) {
 			struct multicall_space mcs;
 			struct multicall_space mcs;
 			struct gnttab_unmap_grant_ref *unmap_op;
 			struct gnttab_unmap_grant_ref *unmap_op;
@@ -902,13 +898,13 @@ int m2p_remove_override(struct page *page, bool clear_pte)
 			 * issued. In this case handle is going to -1 because
 			 * issued. In this case handle is going to -1 because
 			 * it hasn't been modified yet.
 			 * it hasn't been modified yet.
 			 */
 			 */
-			if (map_op->handle == -1)
+			if (kmap_op->handle == -1)
 				xen_mc_flush();
 				xen_mc_flush();
 			/*
 			/*
-			 * Now if map_op->handle is negative it means that the
+			 * Now if kmap_op->handle is negative it means that the
 			 * hypercall actually returned an error.
 			 * hypercall actually returned an error.
 			 */
 			 */
-			if (map_op->handle == GNTST_general_error) {
+			if (kmap_op->handle == GNTST_general_error) {
 				printk(KERN_WARNING "m2p_remove_override: "
 				printk(KERN_WARNING "m2p_remove_override: "
 						"pfn %lx mfn %lx, failed to modify kernel mappings",
 						"pfn %lx mfn %lx, failed to modify kernel mappings",
 						pfn, mfn);
 						pfn, mfn);
@@ -918,8 +914,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
 			mcs = xen_mc_entry(
 			mcs = xen_mc_entry(
 					sizeof(struct gnttab_unmap_grant_ref));
 					sizeof(struct gnttab_unmap_grant_ref));
 			unmap_op = mcs.args;
 			unmap_op = mcs.args;
-			unmap_op->host_addr = map_op->host_addr;
-			unmap_op->handle = map_op->handle;
+			unmap_op->host_addr = kmap_op->host_addr;
+			unmap_op->handle = kmap_op->handle;
 			unmap_op->dev_bus_addr = 0;
 			unmap_op->dev_bus_addr = 0;
 
 
 			MULTI_grant_table_op(mcs.mc,
 			MULTI_grant_table_op(mcs.mc,
@@ -930,10 +926,9 @@ int m2p_remove_override(struct page *page, bool clear_pte)
 			set_pte_at(&init_mm, address, ptep,
 			set_pte_at(&init_mm, address, ptep,
 					pfn_pte(pfn, PAGE_KERNEL));
 					pfn_pte(pfn, PAGE_KERNEL));
 			__flush_tlb_single(address);
 			__flush_tlb_single(address);
-			map_op->host_addr = 0;
+			kmap_op->host_addr = 0;
 		}
 		}
-	} else
-		set_phys_to_machine(pfn, page->index);
+	}
 
 
 	/* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
 	/* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
 	 * somewhere in this domain, even before being added to the
 	 * somewhere in this domain, even before being added to the

+ 4 - 0
arch/x86/xen/setup.c

@@ -17,6 +17,7 @@
 #include <asm/e820.h>
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
 #include <asm/acpi.h>
 #include <asm/acpi.h>
+#include <asm/numa.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypercall.h>
 
 
@@ -544,4 +545,7 @@ void __init xen_arch_setup(void)
 	disable_cpufreq();
 	disable_cpufreq();
 	WARN_ON(set_pm_idle_to_default());
 	WARN_ON(set_pm_idle_to_default());
 	fiddle_vdso();
 	fiddle_vdso();
+#ifdef CONFIG_NUMA
+	numa_off = 1;
+#endif
 }
 }

+ 5 - 3
block/blk-core.c

@@ -2254,9 +2254,11 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
 			error_type = "I/O";
 			error_type = "I/O";
 			break;
 			break;
 		}
 		}
-		printk(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
-		       error_type, req->rq_disk ? req->rq_disk->disk_name : "?",
-		       (unsigned long long)blk_rq_pos(req));
+		printk_ratelimited(KERN_ERR "end_request: %s error, dev %s, sector %llu\n",
+				   error_type, req->rq_disk ?
+				   req->rq_disk->disk_name : "?",
+				   (unsigned long long)blk_rq_pos(req));
+
 	}
 	}
 
 
 	blk_account_io_completion(req, nr_bytes);
 	blk_account_io_completion(req, nr_bytes);

+ 1 - 1
block/ioctl.c

@@ -41,7 +41,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
 			    sizeof(long long) > sizeof(long)) {
 			    sizeof(long long) > sizeof(long)) {
 				long pstart = start, plength = length;
 				long pstart = start, plength = length;
 				if (pstart != start || plength != length
 				if (pstart != start || plength != length
-				    || pstart < 0 || plength < 0)
+				    || pstart < 0 || plength < 0 || partno > 65535)
 					return -EINVAL;
 					return -EINVAL;
 			}
 			}
 
 

+ 10 - 0
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) {
 	} else if (result == ACPI_STATE_D3_HOT) {
 		result = ACPI_STATE_D3;
 		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;
 	*state = result;
 
 
  out:
  out:

+ 24 - 12
drivers/acpi/power.c

@@ -107,6 +107,7 @@ struct acpi_power_resource {
 
 
 	/* List of devices relying on this power resource */
 	/* List of devices relying on this power resource */
 	struct acpi_power_resource_device *devices;
 	struct acpi_power_resource_device *devices;
+	struct mutex devices_lock;
 };
 };
 
 
 static struct list_head acpi_power_resource_list;
 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)
 static int __acpi_power_on(struct acpi_power_resource *resource)
 {
 {
-	struct acpi_power_resource_device *device_list = resource->devices;
 	acpi_status status = AE_OK;
 	acpi_status status = AE_OK;
 
 
 	status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
 	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",
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
 			  resource->name));
 			  resource->name));
 
 
-	while (device_list) {
-		acpi_power_on_device(device_list->device);
-
-		device_list = device_list->next;
-	}
-
 	return 0;
 	return 0;
 }
 }
 
 
 static int acpi_power_on(acpi_handle handle)
 static int acpi_power_on(acpi_handle handle)
 {
 {
 	int result = 0;
 	int result = 0;
+	bool resume_device = false;
 	struct acpi_power_resource *resource = NULL;
 	struct acpi_power_resource *resource = NULL;
+	struct acpi_power_resource_device *device_list;
 
 
 	result = acpi_power_get_context(handle, &resource);
 	result = acpi_power_get_context(handle, &resource);
 	if (result)
 	if (result)
@@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle)
 		result = __acpi_power_on(resource);
 		result = __acpi_power_on(resource);
 		if (result)
 		if (result)
 			resource->ref_count--;
 			resource->ref_count--;
+		else
+			resume_device = true;
 	}
 	}
 
 
 	mutex_unlock(&resource->resource_lock);
 	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;
 	return result;
 }
 }
 
 
@@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
 	if (acpi_power_get_context(res_handle, &resource))
 	if (acpi_power_get_context(res_handle, &resource))
 		return;
 		return;
 
 
-	mutex_lock(&resource->resource_lock);
+	mutex_lock(&resource->devices_lock);
 	prev = NULL;
 	prev = NULL;
 	curr = resource->devices;
 	curr = resource->devices;
 	while (curr) {
 	while (curr) {
@@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev,
 		prev = curr;
 		prev = curr;
 		curr = curr->next;
 		curr = curr->next;
 	}
 	}
-	mutex_unlock(&resource->resource_lock);
+	mutex_unlock(&resource->devices_lock);
 }
 }
 
 
 /* Unlink dev from all power resources in _PR0 */
 /* 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;
 	power_resource_device->device = powered_device;
 
 
-	mutex_lock(&resource->resource_lock);
+	mutex_lock(&resource->devices_lock);
 	power_resource_device->next = resource->devices;
 	power_resource_device->next = resource->devices;
 	resource->devices = power_resource_device;
 	resource->devices = power_resource_device;
-	mutex_unlock(&resource->resource_lock);
+	mutex_unlock(&resource->devices_lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
 	return ret;
 	return ret;
 
 
 no_power_resource:
 no_power_resource:
-	printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
+	printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!");
 	return -ENODEV;
 	return -ENODEV;
 }
 }
 EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
 EXPORT_SYMBOL_GPL(acpi_power_resource_register_device);
@@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device)
 
 
 	resource->device = device;
 	resource->device = device;
 	mutex_init(&resource->resource_lock);
 	mutex_init(&resource->resource_lock);
+	mutex_init(&resource->devices_lock);
 	strcpy(resource->name, device->pnp.bus_id);
 	strcpy(resource->name, device->pnp.bus_id);
 	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 	strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
 	strcpy(acpi_device_class(device), ACPI_POWER_CLASS);

+ 1 - 0
drivers/block/aoe/aoecmd.c

@@ -35,6 +35,7 @@ new_skb(ulong len)
 		skb_reset_mac_header(skb);
 		skb_reset_mac_header(skb);
 		skb_reset_network_header(skb);
 		skb_reset_network_header(skb);
 		skb->protocol = __constant_htons(ETH_P_AOE);
 		skb->protocol = __constant_htons(ETH_P_AOE);
+		skb_checksum_none_assert(skb);
 	}
 	}
 	return skb;
 	return skb;
 }
 }

+ 1 - 0
drivers/block/cciss_scsi.c

@@ -795,6 +795,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
 				}
 				}
 			break;
 			break;
 			case CMD_PROTOCOL_ERR:
 			case CMD_PROTOCOL_ERR:
+				cmd->result = DID_ERROR << 16;
 				dev_warn(&h->pdev->dev,
 				dev_warn(&h->pdev->dev,
 					"%p has protocol error\n", c);
 					"%p has protocol error\n", c);
                         break;
                         break;

+ 23 - 15
drivers/block/mtip32xx/mtip32xx.c

@@ -1148,11 +1148,15 @@ static bool mtip_pause_ncq(struct mtip_port *port,
 	reply = port->rxfis + RX_FIS_D2H_REG;
 	reply = port->rxfis + RX_FIS_D2H_REG;
 	task_file_data = readl(port->mmio+PORT_TFDATA);
 	task_file_data = readl(port->mmio+PORT_TFDATA);
 
 
-	if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
+	if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
+		clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
+
+	if ((task_file_data & 1))
 		return false;
 		return false;
 
 
 	if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
 	if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
 		set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
 		set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+		set_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag);
 		port->ic_pause_timer = jiffies;
 		port->ic_pause_timer = jiffies;
 		return true;
 		return true;
 	} else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
 	} else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
@@ -1900,7 +1904,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
 	int rv = 0, xfer_sz = command[3];
 	int rv = 0, xfer_sz = command[3];
 
 
 	if (xfer_sz) {
 	if (xfer_sz) {
-		if (user_buffer)
+		if (!user_buffer)
 			return -EFAULT;
 			return -EFAULT;
 
 
 		buf = dmam_alloc_coherent(&port->dd->pdev->dev,
 		buf = dmam_alloc_coherent(&port->dd->pdev->dev,
@@ -2043,7 +2047,7 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout)
 		*timeout = 240000; /* 4 minutes */
 		*timeout = 240000; /* 4 minutes */
 		break;
 		break;
 	case ATA_CMD_STANDBYNOW1:
 	case ATA_CMD_STANDBYNOW1:
-		*timeout = 10000;  /* 10 seconds */
+		*timeout = 120000;  /* 2 minutes */
 		break;
 		break;
 	case 0xF7:
 	case 0xF7:
 	case 0xFA:
 	case 0xFA:
@@ -2588,9 +2592,6 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
 	if (!len || size)
 	if (!len || size)
 		return 0;
 		return 0;
 
 
-	if (size < 0)
-		return -EINVAL;
-
 	size += sprintf(&buf[size], "H/ S ACTive      : [ 0x");
 	size += sprintf(&buf[size], "H/ S ACTive      : [ 0x");
 
 
 	for (n = dd->slot_groups-1; n >= 0; n--)
 	for (n = dd->slot_groups-1; n >= 0; n--)
@@ -2660,9 +2661,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf,
 	if (!len || size)
 	if (!len || size)
 		return 0;
 		return 0;
 
 
-	if (size < 0)
-		return -EINVAL;
-
 	size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n",
 	size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n",
 							dd->port->flags);
 							dd->port->flags);
 	size += sprintf(&buf[size], "Flag-dd   : [ %08lX ]\n",
 	size += sprintf(&buf[size], "Flag-dd   : [ %08lX ]\n",
@@ -3214,8 +3212,8 @@ static int mtip_hw_init(struct driver_data *dd)
 				"Unable to check write protect progress\n");
 				"Unable to check write protect progress\n");
 	else
 	else
 		dev_info(&dd->pdev->dev,
 		dev_info(&dd->pdev->dev,
-				"Write protect progress: %d%% (%d blocks)\n",
-				attr242.cur, attr242.data);
+				"Write protect progress: %u%% (%u blocks)\n",
+				attr242.cur, le32_to_cpu(attr242.data));
 	return rv;
 	return rv;
 
 
 out3:
 out3:
@@ -3619,6 +3617,10 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 			bio_endio(bio, -ENODATA);
 			bio_endio(bio, -ENODATA);
 			return;
 			return;
 		}
 		}
+		if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) {
+			bio_endio(bio, -ENODATA);
+			return;
+		}
 	}
 	}
 
 
 	if (unlikely(!bio_has_data(bio))) {
 	if (unlikely(!bio_has_data(bio))) {
@@ -4168,7 +4170,13 @@ static void mtip_pci_shutdown(struct pci_dev *pdev)
 
 
 /* Table of device ids supported by this driver. */
 /* Table of device ids supported by this driver. */
 static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
 static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
-	{  PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320H_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320M_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320S_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P325M_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420H_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420M_DEVICE_ID) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P425M_DEVICE_ID) },
 	{ 0 }
 	{ 0 }
 };
 };
 
 
@@ -4199,12 +4207,12 @@ static int __init mtip_init(void)
 {
 {
 	int error;
 	int error;
 
 
-	printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
+	pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
 
 	/* Allocate a major block device number to use with this driver. */
 	/* Allocate a major block device number to use with this driver. */
 	error = register_blkdev(0, MTIP_DRV_NAME);
 	error = register_blkdev(0, MTIP_DRV_NAME);
 	if (error <= 0) {
 	if (error <= 0) {
-		printk(KERN_ERR "Unable to register block device (%d)\n",
+		pr_err("Unable to register block device (%d)\n",
 		error);
 		error);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -4213,7 +4221,7 @@ static int __init mtip_init(void)
 	if (!dfs_parent) {
 	if (!dfs_parent) {
 		dfs_parent = debugfs_create_dir("rssd", NULL);
 		dfs_parent = debugfs_create_dir("rssd", NULL);
 		if (IS_ERR_OR_NULL(dfs_parent)) {
 		if (IS_ERR_OR_NULL(dfs_parent)) {
-			printk(KERN_WARNING "Error creating debugfs parent\n");
+			pr_warn("Error creating debugfs parent\n");
 			dfs_parent = NULL;
 			dfs_parent = NULL;
 		}
 		}
 	}
 	}

+ 9 - 1
drivers/block/mtip32xx/mtip32xx.h

@@ -76,7 +76,13 @@
 
 
 /* Micron Vendor ID & P320x SSD Device ID */
 /* Micron Vendor ID & P320x SSD Device ID */
 #define PCI_VENDOR_ID_MICRON    0x1344
 #define PCI_VENDOR_ID_MICRON    0x1344
-#define P320_DEVICE_ID		0x5150
+#define P320H_DEVICE_ID		0x5150
+#define P320M_DEVICE_ID		0x5151
+#define P320S_DEVICE_ID		0x5152
+#define P325M_DEVICE_ID		0x5153
+#define P420H_DEVICE_ID		0x5160
+#define P420M_DEVICE_ID		0x5161
+#define P425M_DEVICE_ID		0x5163
 
 
 /* Driver name and version strings */
 /* Driver name and version strings */
 #define MTIP_DRV_NAME		"mtip32xx"
 #define MTIP_DRV_NAME		"mtip32xx"
@@ -131,10 +137,12 @@ enum {
 	MTIP_PF_SVC_THD_STOP_BIT    = 8,
 	MTIP_PF_SVC_THD_STOP_BIT    = 8,
 
 
 	/* below are bit numbers in 'dd_flag' defined in driver_data */
 	/* below are bit numbers in 'dd_flag' defined in driver_data */
+	MTIP_DDF_SEC_LOCK_BIT	    = 0,
 	MTIP_DDF_REMOVE_PENDING_BIT = 1,
 	MTIP_DDF_REMOVE_PENDING_BIT = 1,
 	MTIP_DDF_OVER_TEMP_BIT      = 2,
 	MTIP_DDF_OVER_TEMP_BIT      = 2,
 	MTIP_DDF_WRITE_PROTECT_BIT  = 3,
 	MTIP_DDF_WRITE_PROTECT_BIT  = 3,
 	MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
 	MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
+				(1 << MTIP_DDF_SEC_LOCK_BIT) | \
 				(1 << MTIP_DDF_OVER_TEMP_BIT) | \
 				(1 << MTIP_DDF_OVER_TEMP_BIT) | \
 				(1 << MTIP_DDF_WRITE_PROTECT_BIT)),
 				(1 << MTIP_DDF_WRITE_PROTECT_BIT)),
 
 

+ 9 - 0
drivers/block/nbd.c

@@ -449,6 +449,14 @@ static void nbd_clear_que(struct nbd_device *nbd)
 		req->errors++;
 		req->errors++;
 		nbd_end_request(req);
 		nbd_end_request(req);
 	}
 	}
+
+	while (!list_empty(&nbd->waiting_queue)) {
+		req = list_entry(nbd->waiting_queue.next, struct request,
+				 queuelist);
+		list_del_init(&req->queuelist);
+		req->errors++;
+		nbd_end_request(req);
+	}
 }
 }
 
 
 
 
@@ -598,6 +606,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
 		nbd->file = NULL;
 		nbd->file = NULL;
 		nbd_clear_que(nbd);
 		nbd_clear_que(nbd);
 		BUG_ON(!list_empty(&nbd->queue_head));
 		BUG_ON(!list_empty(&nbd->queue_head));
+		BUG_ON(!list_empty(&nbd->waiting_queue));
 		if (file)
 		if (file)
 			fput(file);
 			fput(file);
 		return 0;
 		return 0;

+ 3 - 4
drivers/block/rbd.c

@@ -246,13 +246,12 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
 {
 	struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 	struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 
 
-	rbd_get_dev(rbd_dev);
-
-	set_device_ro(bdev, rbd_dev->read_only);
-
 	if ((mode & FMODE_WRITE) && rbd_dev->read_only)
 	if ((mode & FMODE_WRITE) && rbd_dev->read_only)
 		return -EROFS;
 		return -EROFS;
 
 
+	rbd_get_dev(rbd_dev);
+	set_device_ro(bdev, rbd_dev->read_only);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/block/xen-blkback/blkback.c

@@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pending_req *req)
 		invcount++;
 		invcount++;
 	}
 	}
 
 
-	ret = gnttab_unmap_refs(unmap, pages, invcount, false);
+	ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
 	BUG_ON(ret);
 	BUG_ON(ret);
 }
 }
 
 

+ 1 - 0
drivers/clk/Makefile

@@ -1,4 +1,5 @@
 # common clock types
 # common clock types
+obj-$(CONFIG_HAVE_CLK)		+= clk-devres.o
 obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
 obj-$(CONFIG_CLKDEV_LOOKUP)	+= clkdev.o
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-fixed-rate.o clk-gate.o \
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-fixed-rate.o clk-gate.o \
 				   clk-mux.o clk-divider.o clk-fixed-factor.o
 				   clk-mux.o clk-divider.o clk-fixed-factor.o

+ 55 - 0
drivers/clk/clk-devres.c

@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/gfp.h>
+
+static void devm_clk_release(struct device *dev, void *res)
+{
+	clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+	struct clk **ptr, *clk;
+
+	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	clk = clk_get(dev, id);
+	if (!IS_ERR(clk)) {
+		*ptr = clk;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(devm_clk_get);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+	struct clk **c = res;
+	if (!c || !*c) {
+		WARN_ON(!c || !*c);
+		return 0;
+	}
+	return *c == data;
+}
+
+void devm_clk_put(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
+
+	WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_clk_put);

+ 0 - 45
drivers/clk/clkdev.c

@@ -171,51 +171,6 @@ void clk_put(struct clk *clk)
 }
 }
 EXPORT_SYMBOL(clk_put);
 EXPORT_SYMBOL(clk_put);
 
 
-static void devm_clk_release(struct device *dev, void *res)
-{
-	clk_put(*(struct clk **)res);
-}
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-	struct clk **ptr, *clk;
-
-	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return ERR_PTR(-ENOMEM);
-
-	clk = clk_get(dev, id);
-	if (!IS_ERR(clk)) {
-		*ptr = clk;
-		devres_add(dev, ptr);
-	} else {
-		devres_free(ptr);
-	}
-
-	return clk;
-}
-EXPORT_SYMBOL(devm_clk_get);
-
-static int devm_clk_match(struct device *dev, void *res, void *data)
-{
-	struct clk **c = res;
-	if (!c || !*c) {
-		WARN_ON(!c || !*c);
-		return 0;
-	}
-	return *c == data;
-}
-
-void devm_clk_put(struct device *dev, struct clk *clk)
-{
-	int ret;
-
-	ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
-
-	WARN_ON(ret);
-}
-EXPORT_SYMBOL(devm_clk_put);
-
 void clkdev_add(struct clk_lookup *cl)
 void clkdev_add(struct clk_lookup *cl)
 {
 {
 	mutex_lock(&clocks_mutex);
 	mutex_lock(&clocks_mutex);

+ 34 - 29
drivers/cpufreq/powernow-k8.c

@@ -35,7 +35,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/cpumask.h>
 #include <linux/cpumask.h>
-#include <linux/sched.h>	/* for current / set_cpus_allowed() */
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 
 
@@ -1139,16 +1138,23 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
 	return res;
 	return res;
 }
 }
 
 
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
-		unsigned targfreq, unsigned relation)
+struct powernowk8_target_arg {
+	struct cpufreq_policy		*pol;
+	unsigned			targfreq;
+	unsigned			relation;
+};
+
+static long powernowk8_target_fn(void *arg)
 {
 {
-	cpumask_var_t oldmask;
+	struct powernowk8_target_arg *pta = arg;
+	struct cpufreq_policy *pol = pta->pol;
+	unsigned targfreq = pta->targfreq;
+	unsigned relation = pta->relation;
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
 	u32 checkfid;
 	u32 checkfid;
 	u32 checkvid;
 	u32 checkvid;
 	unsigned int newstate;
 	unsigned int newstate;
-	int ret = -EIO;
+	int ret;
 
 
 	if (!data)
 	if (!data)
 		return -EINVAL;
 		return -EINVAL;
@@ -1156,29 +1162,16 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 	checkfid = data->currfid;
 	checkfid = data->currfid;
 	checkvid = data->currvid;
 	checkvid = data->currvid;
 
 
-	/* only run on specific CPU from here on. */
-	/* This is poor form: use a workqueue or smp_call_function_single */
-	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
-		return -ENOMEM;
-
-	cpumask_copy(oldmask, tsk_cpus_allowed(current));
-	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
-
-	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
-		goto err_out;
-	}
-
 	if (pending_bit_stuck()) {
 	if (pending_bit_stuck()) {
 		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
 		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
-		goto err_out;
+		return -EIO;
 	}
 	}
 
 
 	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
 	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
 		pol->cpu, targfreq, pol->min, pol->max, relation);
 		pol->cpu, targfreq, pol->min, pol->max, relation);
 
 
 	if (query_current_values_with_pending_wait(data))
 	if (query_current_values_with_pending_wait(data))
-		goto err_out;
+		return -EIO;
 
 
 	if (cpu_family != CPU_HW_PSTATE) {
 	if (cpu_family != CPU_HW_PSTATE) {
 		pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
 		pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
@@ -1196,7 +1189,7 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 
 
 	if (cpufreq_frequency_table_target(pol, data->powernow_table,
 	if (cpufreq_frequency_table_target(pol, data->powernow_table,
 				targfreq, relation, &newstate))
 				targfreq, relation, &newstate))
-		goto err_out;
+		return -EIO;
 
 
 	mutex_lock(&fidvid_mutex);
 	mutex_lock(&fidvid_mutex);
 
 
@@ -1209,9 +1202,8 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 		ret = transition_frequency_fidvid(data, newstate);
 		ret = transition_frequency_fidvid(data, newstate);
 	if (ret) {
 	if (ret) {
 		printk(KERN_ERR PFX "transition frequency failed\n");
 		printk(KERN_ERR PFX "transition frequency failed\n");
-		ret = 1;
 		mutex_unlock(&fidvid_mutex);
 		mutex_unlock(&fidvid_mutex);
-		goto err_out;
+		return 1;
 	}
 	}
 	mutex_unlock(&fidvid_mutex);
 	mutex_unlock(&fidvid_mutex);
 
 
@@ -1220,12 +1212,25 @@ static int powernowk8_target(struct cpufreq_policy *pol,
 				data->powernow_table[newstate].index);
 				data->powernow_table[newstate].index);
 	else
 	else
 		pol->cur = find_khz_freq_from_fid(data->currfid);
 		pol->cur = find_khz_freq_from_fid(data->currfid);
-	ret = 0;
 
 
-err_out:
-	set_cpus_allowed_ptr(current, oldmask);
-	free_cpumask_var(oldmask);
-	return ret;
+	return 0;
+}
+
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+		unsigned targfreq, unsigned relation)
+{
+	struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
+					     .relation = relation };
+
+	/*
+	 * Must run on @pol->cpu.  cpufreq core is responsible for ensuring
+	 * that we're bound to the current CPU and pol->cpu stays online.
+	 */
+	if (smp_processor_id() == pol->cpu)
+		return powernowk8_target_fn(&pta);
+	else
+		return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
 }
 }
 
 
 /* Driver entry point to verify the policy and range of frequencies */
 /* Driver entry point to verify the policy and range of frequencies */

+ 12 - 1
drivers/dma/at_hdmac.c

@@ -661,7 +661,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 			flags);
 			flags);
 
 
 	if (unlikely(!atslave || !sg_len)) {
 	if (unlikely(!atslave || !sg_len)) {
-		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+		dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n");
 		return NULL;
 		return NULL;
 	}
 	}
 
 
@@ -689,6 +689,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 
 			mem = sg_dma_address(sg);
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 			len = sg_dma_len(sg);
+			if (unlikely(!len)) {
+				dev_dbg(chan2dev(chan),
+					"prep_slave_sg: sg(%d) data length is zero\n", i);
+				goto err;
+			}
 			mem_width = 2;
 			mem_width = 2;
 			if (unlikely(mem & 3 || len & 3))
 			if (unlikely(mem & 3 || len & 3))
 				mem_width = 0;
 				mem_width = 0;
@@ -724,6 +729,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 
 			mem = sg_dma_address(sg);
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 			len = sg_dma_len(sg);
+			if (unlikely(!len)) {
+				dev_dbg(chan2dev(chan),
+					"prep_slave_sg: sg(%d) data length is zero\n", i);
+				goto err;
+			}
 			mem_width = 2;
 			mem_width = 2;
 			if (unlikely(mem & 3 || len & 3))
 			if (unlikely(mem & 3 || len & 3))
 				mem_width = 0;
 				mem_width = 0;
@@ -757,6 +767,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 
 err_desc_get:
 err_desc_get:
 	dev_err(chan2dev(chan), "not enough descriptors available\n");
 	dev_err(chan2dev(chan), "not enough descriptors available\n");
+err:
 	atc_desc_put(atchan, first);
 	atc_desc_put(atchan, first);
 	return NULL;
 	return NULL;
 }
 }

+ 14 - 7
drivers/dma/pl330.c

@@ -1567,17 +1567,19 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r)
 		goto xfer_exit;
 		goto xfer_exit;
 	}
 	}
 
 
-	/* Prefer Secure Channel */
-	if (!_manager_ns(thrd))
-		r->cfg->nonsecure = 0;
-	else
-		r->cfg->nonsecure = 1;
 
 
 	/* Use last settings, if not provided */
 	/* Use last settings, if not provided */
-	if (r->cfg)
+	if (r->cfg) {
+		/* Prefer Secure Channel */
+		if (!_manager_ns(thrd))
+			r->cfg->nonsecure = 0;
+		else
+			r->cfg->nonsecure = 1;
+
 		ccr = _prepare_ccr(r->cfg);
 		ccr = _prepare_ccr(r->cfg);
-	else
+	} else {
 		ccr = readl(regs + CC(thrd->id));
 		ccr = readl(regs + CC(thrd->id));
+	}
 
 
 	/* If this req doesn't have valid xfer settings */
 	/* If this req doesn't have valid xfer settings */
 	if (!_is_valid(ccr)) {
 	if (!_is_valid(ccr)) {
@@ -2928,6 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 		num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
 		num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
 
 
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
 	pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
+	if (!pdmac->peripherals) {
+		ret = -ENOMEM;
+		dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
+		goto probe_err5;
+	}
 
 
 	for (i = 0; i < num_chan; i++) {
 	for (i = 0; i < num_chan; i++) {
 		pch = &pdmac->peripherals[i];
 		pch = &pdmac->peripherals[i];

+ 39 - 18
drivers/edac/edac_mc.c

@@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
 	return (void *)(((unsigned long)ptr) + align - r);
 	return (void *)(((unsigned long)ptr) + align - r);
 }
 }
 
 
+static void _edac_mc_free(struct mem_ctl_info *mci)
+{
+	int i, chn, row;
+	struct csrow_info *csr;
+	const unsigned int tot_dimms = mci->tot_dimms;
+	const unsigned int tot_channels = mci->num_cschannel;
+	const unsigned int tot_csrows = mci->nr_csrows;
+
+	if (mci->dimms) {
+		for (i = 0; i < tot_dimms; i++)
+			kfree(mci->dimms[i]);
+		kfree(mci->dimms);
+	}
+	if (mci->csrows) {
+		for (row = 0; row < tot_csrows; row++) {
+			csr = mci->csrows[row];
+			if (csr) {
+				if (csr->channels) {
+					for (chn = 0; chn < tot_channels; chn++)
+						kfree(csr->channels[chn]);
+					kfree(csr->channels);
+				}
+				kfree(csr);
+			}
+		}
+		kfree(mci->csrows);
+	}
+	kfree(mci);
+}
+
 /**
 /**
  * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
  * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
  * @mc_num:		Memory controller number
  * @mc_num:		Memory controller number
@@ -413,24 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
 	return mci;
 	return mci;
 
 
 error:
 error:
-	if (mci->dimms) {
-		for (i = 0; i < tot_dimms; i++)
-			kfree(mci->dimms[i]);
-		kfree(mci->dimms);
-	}
-	if (mci->csrows) {
-		for (chn = 0; chn < tot_channels; chn++) {
-			csr = mci->csrows[chn];
-			if (csr) {
-				for (chn = 0; chn < tot_channels; chn++)
-					kfree(csr->channels[chn]);
-				kfree(csr);
-			}
-			kfree(mci->csrows[i]);
-		}
-		kfree(mci->csrows);
-	}
-	kfree(mci);
+	_edac_mc_free(mci);
 
 
 	return NULL;
 	return NULL;
 }
 }
@@ -445,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
 {
 {
 	edac_dbg(1, "\n");
 	edac_dbg(1, "\n");
 
 
+	/* If we're not yet registered with sysfs free only what was allocated
+	 * in edac_mc_alloc().
+	 */
+	if (!device_is_registered(&mci->dev)) {
+		_edac_mc_free(mci);
+		return;
+	}
+
 	/* the mci instance is freed here, when the sysfs object is dropped */
 	/* the mci instance is freed here, when the sysfs object is dropped */
 	edac_unregister_sysfs(mci);
 	edac_unregister_sysfs(mci);
 }
 }

+ 1 - 1
drivers/edac/i3200_edac.c

@@ -391,7 +391,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
 		for (j = 0; j < nr_channels; j++) {
 		for (j = 0; j < nr_channels; j++) {
 			struct dimm_info *dimm = csrow->channels[j]->dimm;
 			struct dimm_info *dimm = csrow->channels[j]->dimm;
 
 
-			dimm->nr_pages = nr_pages / nr_channels;
+			dimm->nr_pages = nr_pages;
 			dimm->grain = nr_pages << PAGE_SHIFT;
 			dimm->grain = nr_pages << PAGE_SHIFT;
 			dimm->mtype = MEM_DDR2;
 			dimm->mtype = MEM_DDR2;
 			dimm->dtype = DEV_UNKNOWN;
 			dimm->dtype = DEV_UNKNOWN;

+ 4 - 0
drivers/edac/i5000_edac.c

@@ -1012,6 +1012,10 @@ static void handle_channel(struct i5000_pvt *pvt, int slot, int channel,
 			/* add the number of COLUMN bits */
 			/* add the number of COLUMN bits */
 			addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
 			addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
 
 
+			/* Dual-rank memories have twice the size */
+			if (dinfo->dual_rank)
+				addrBits++;
+
 			addrBits += 6;	/* add 64 bits per DIMM */
 			addrBits += 6;	/* add 64 bits per DIMM */
 			addrBits -= 20;	/* divide by 2^^20 */
 			addrBits -= 20;	/* divide by 2^^20 */
 			addrBits -= 3;	/* 8 bits per bytes */
 			addrBits -= 3;	/* 8 bits per bytes */

+ 4 - 3
drivers/edac/sb_edac.c

@@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 {
 {
 	struct sbridge_pvt *pvt = mci->pvt_info;
 	struct sbridge_pvt *pvt = mci->pvt_info;
 	struct dimm_info *dimm;
 	struct dimm_info *dimm;
-	int i, j, banks, ranks, rows, cols, size, npages;
+	unsigned i, j, banks, ranks, rows, cols, npages;
+	u64 size;
 	u32 reg;
 	u32 reg;
 	enum edac_type mode;
 	enum edac_type mode;
 	enum mem_type mtype;
 	enum mem_type mtype;
@@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 				cols = numcol(mtr);
 				cols = numcol(mtr);
 
 
 				/* DDR3 has 8 I/O banks */
 				/* DDR3 has 8 I/O banks */
-				size = (rows * cols * banks * ranks) >> (20 - 3);
+				size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
 				npages = MiB_TO_PAGES(size);
 				npages = MiB_TO_PAGES(size);
 
 
-				edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+				edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
 					 pvt->sbridge_dev->mc, i, j,
 					 pvt->sbridge_dev->mc, i, j,
 					 size, npages,
 					 size, npages,
 					 banks, ranks, rows, cols);
 					 banks, ranks, rows, cols);

+ 12 - 7
drivers/extcon/extcon-max77693.c

@@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
 	}
 	}
 	info->dev = &pdev->dev;
 	info->dev = &pdev->dev;
 	info->max77693 = max77693;
 	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);
 	platform_set_drvdata(pdev, info);
 	mutex_init(&info->mutex);
 	mutex_init(&info->mutex);

+ 5 - 0
drivers/gpio/gpio-lpc32xx.c

@@ -308,6 +308,7 @@ static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
 {
 {
 	struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 	struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
 
+	__set_gpio_level_p012(group, pin, value);
 	__set_gpio_dir_p012(group, pin, 0);
 	__set_gpio_dir_p012(group, pin, 0);
 
 
 	return 0;
 	return 0;
@@ -318,6 +319,7 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 {
 {
 	struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 	struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
 
+	__set_gpio_level_p3(group, pin, value);
 	__set_gpio_dir_p3(group, pin, 0);
 	__set_gpio_dir_p3(group, pin, 0);
 
 
 	return 0;
 	return 0;
@@ -326,6 +328,9 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
 	int value)
 	int value)
 {
 {
+	struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+	__set_gpo_level_p3(group, pin, value);
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 1
drivers/gpu/drm/i915/i915_gem.c

@@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
 {
 {
 	int ret;
 	int ret;
 
 
-	BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
+	if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
+		return -EBUSY;
 
 
 	if (obj->gtt_space != NULL) {
 	if (obj->gtt_space != NULL) {
 		if ((alignment && obj->gtt_offset & (alignment - 1)) ||
 		if ((alignment && obj->gtt_offset & (alignment - 1)) ||

+ 6 - 6
drivers/gpu/drm/i915/intel_display.c

@@ -4191,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
 	POSTING_READ(DPLL(pipe));
 	POSTING_READ(DPLL(pipe));
 	udelay(150);
 	udelay(150);
 
 
-	I915_WRITE(DPLL(pipe), dpll);
-
-	/* Wait for the clocks to stabilize. */
-	POSTING_READ(DPLL(pipe));
-	udelay(150);
-
 	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
 	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
 	 * This is an exception to the general rule that mode_set doesn't turn
 	 * This is an exception to the general rule that mode_set doesn't turn
 	 * things on.
 	 * things on.
@@ -4204,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 		intel_update_lvds(crtc, clock, adjusted_mode);
 		intel_update_lvds(crtc, clock, adjusted_mode);
 
 
+	I915_WRITE(DPLL(pipe), dpll);
+
+	/* Wait for the clocks to stabilize. */
+	POSTING_READ(DPLL(pipe));
+	udelay(150);
+
 	/* The pixel multiplier can only be updated once the
 	/* The pixel multiplier can only be updated once the
 	 * DPLL is enabled and the clocks are stable.
 	 * DPLL is enabled and the clocks are stable.
 	 *
 	 *

+ 1 - 1
drivers/gpu/drm/i915/intel_hdmi.c

@@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
 	u32 temp;
 	u32 temp;
 	u32 enable_bits = SDVO_ENABLE;
 	u32 enable_bits = SDVO_ENABLE;
 
 
-	if (intel_hdmi->has_audio)
+	if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
 		enable_bits |= SDVO_AUDIO_ENABLE;
 		enable_bits |= SDVO_AUDIO_ENABLE;
 
 
 	temp = I915_READ(intel_hdmi->sdvox_reg);
 	temp = I915_READ(intel_hdmi->sdvox_reg);

+ 1 - 1
drivers/gpu/drm/nouveau/nouveau_abi16.c

@@ -179,7 +179,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
 			return 0;
 			return 0;
 	} else
 	} else
 	if (init->class == 0x906e) {
 	if (init->class == 0x906e) {
-		NV_ERROR(dev, "906e not supported yet\n");
+		NV_DEBUG(dev, "906e not supported yet\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 

+ 14 - 1
drivers/gpu/drm/nouveau/nv50_gpio.c

@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs
  * Authors: Ben Skeggs
  */
  */
 
 
+#include <linux/dmi.h>
 #include "drmP.h"
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include "nouveau_drv.h"
 #include "nouveau_hw.h"
 #include "nouveau_hw.h"
@@ -110,13 +111,25 @@ nv50_gpio_isr(struct drm_device *dev)
 		nv_wr32(dev, 0xe074, intr1);
 		nv_wr32(dev, 0xe074, intr1);
 }
 }
 
 
+static struct dmi_system_id gpio_reset_ids[] = {
+	{
+		.ident = "Apple Macbook 10,1",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
+		}
+	},
+	{ }
+};
+
 int
 int
 nv50_gpio_init(struct drm_device *dev)
 nv50_gpio_init(struct drm_device *dev)
 {
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 
 
 	/* initialise gpios and routing to vbios defaults */
 	/* initialise gpios and routing to vbios defaults */
-	nouveau_gpio_reset(dev);
+	if (dmi_check_system(gpio_reset_ids))
+		nouveau_gpio_reset(dev);
 
 
 	/* disable, and ack any pending gpio interrupts */
 	/* disable, and ack any pending gpio interrupts */
 	nv_wr32(dev, 0xe050, 0x00000000);
 	nv_wr32(dev, 0xe050, 0x00000000);

+ 1 - 0
drivers/gpu/drm/nouveau/nvc0_fb.c

@@ -124,6 +124,7 @@ nvc0_fb_init(struct drm_device *dev)
 	priv = dev_priv->engine.fb.priv;
 	priv = dev_priv->engine.fb.priv;
 
 
 	nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
 	nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
+	nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 1
drivers/gpu/drm/nouveau/nvc0_fifo.c

@@ -373,7 +373,8 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 static void
 nvc0_fifo_isr(struct drm_device *dev)
 nvc0_fifo_isr(struct drm_device *dev)
 {
 {
-	u32 stat = nv_rd32(dev, 0x002100);
+	u32 mask = nv_rd32(dev, 0x002140);
+	u32 stat = nv_rd32(dev, 0x002100) & mask;
 
 
 	if (stat & 0x00000100) {
 	if (stat & 0x00000100) {
 		NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
 		NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");

+ 2 - 1
drivers/gpu/drm/nouveau/nve0_fifo.c

@@ -345,7 +345,8 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 static void
 nve0_fifo_isr(struct drm_device *dev)
 nve0_fifo_isr(struct drm_device *dev)
 {
 {
-	u32 stat = nv_rd32(dev, 0x002100);
+	u32 mask = nv_rd32(dev, 0x002140);
+	u32 stat = nv_rd32(dev, 0x002100) & mask;
 
 
 	if (stat & 0x00000100) {
 	if (stat & 0x00000100) {
 		NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
 		NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");

+ 34 - 129
drivers/gpu/drm/radeon/atombios_crtc.c

@@ -1479,98 +1479,14 @@ 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)
 static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 {
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_encoder *test_encoder;
 	struct drm_encoder *test_encoder;
-	u32 pll_in_use;
-	int pll;
+	struct drm_crtc *test_crtc;
+	uint32_t pll_in_use = 0;
 
 
 	if (ASIC_IS_DCE61(rdev)) {
 	if (ASIC_IS_DCE61(rdev)) {
 		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
 		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
@@ -1582,40 +1498,32 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 
 
 				if ((test_radeon_encoder->encoder_id ==
 				if ((test_radeon_encoder->encoder_id ==
 				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
 				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
-				    (dig->linkb == false))
-					/* UNIPHY A uses PPLL2 */
+				    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
 					return ATOM_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 */
 		/* UNIPHY B/C/D/E/F */
-		pll_in_use = radeon_get_pll_use_mask(crtc);
-		if (!(pll_in_use & (1 << ATOM_PPLL0)))
+		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))
 			return ATOM_PPLL0;
 			return ATOM_PPLL0;
-		if (!(pll_in_use & (1 << ATOM_PPLL1)))
-			return ATOM_PPLL1;
-		DRM_ERROR("unable to allocate a PPLL\n");
-		return ATOM_PPLL_INVALID;
+		return ATOM_PPLL1;
 	} else if (ASIC_IS_DCE4(rdev)) {
 	} else if (ASIC_IS_DCE4(rdev)) {
 		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
 		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
 			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
 			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
 				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
 				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
 				 * depending on the asic:
 				 * depending on the asic:
 				 * DCE4: PPLL or ext clock
 				 * DCE4: PPLL or ext clock
-				 * DCE5: PPLL, DCPLL, or ext clock
-				 * DCE6: PPLL, PPLL0, or ext clock
+				 * DCE5: DCPLL or ext clock
 				 *
 				 *
 				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
 				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
 				 * PPLL/DCPLL programming and only program the DP DTO for the
 				 * PPLL/DCPLL programming and only program the DP DTO for the
@@ -1623,34 +1531,31 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 				 */
 				 */
 				if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
 				if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
 					if (rdev->clock.dp_extclk)
 					if (rdev->clock.dp_extclk)
-						/* skip PPLL programming if using ext clock */
 						return ATOM_PPLL_INVALID;
 						return ATOM_PPLL_INVALID;
 					else if (ASIC_IS_DCE6(rdev))
 					else if (ASIC_IS_DCE6(rdev))
-						/* use PPLL0 for all DP */
 						return ATOM_PPLL0;
 						return ATOM_PPLL0;
 					else if (ASIC_IS_DCE5(rdev))
 					else if (ASIC_IS_DCE5(rdev))
-						/* use DCPLL for all DP */
 						return ATOM_DCPLL;
 						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;
 			}
 			}
 		}
 		}
-		/* 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)))
+
+		/* 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))
 			return ATOM_PPLL1;
 			return ATOM_PPLL1;
-		DRM_ERROR("unable to allocate a PPLL\n");
-		return ATOM_PPLL_INVALID;
+		return ATOM_PPLL2;
 	} else
 	} else
-		/* use PPLL1 or PPLL2 */
 		return radeon_crtc->crtc_id;
 		return radeon_crtc->crtc_id;
 
 
 }
 }
@@ -1792,7 +1697,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
 		break;
 		break;
 	}
 	}
 done:
 done:
-	radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+	radeon_crtc->pll_id = -1;
 }
 }
 
 
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1841,6 +1746,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
 		else
 		else
 			radeon_crtc->crtc_offset = 0;
 			radeon_crtc->crtc_offset = 0;
 	}
 	}
-	radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+	radeon_crtc->pll_id = -1;
 	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 	drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }
 }

+ 2 - 1
drivers/gpu/drm/radeon/r100.c

@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
 	ring->ready = true;
 	ring->ready = true;
 	radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
 	radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
 
 
-	if (radeon_ring_supports_scratch_reg(rdev, ring)) {
+	if (!ring->rptr_save_reg /* not resuming from suspend */
+	    && radeon_ring_supports_scratch_reg(rdev, ring)) {
 		r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
 		r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
 		if (r) {
 		if (r) {
 			DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
 			DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);

+ 7 - 0
drivers/gpu/drm/udl/udl_connector.c

@@ -69,6 +69,13 @@ static int udl_get_modes(struct drm_connector *connector)
 static int udl_mode_valid(struct drm_connector *connector,
 static int udl_mode_valid(struct drm_connector *connector,
 			  struct drm_display_mode *mode)
 			  struct drm_display_mode *mode)
 {
 {
+	struct udl_device *udl = connector->dev->dev_private;
+	if (!udl->sku_pixel_limit)
+		return 0;
+
+	if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
+		return MODE_VIRTUAL_Y;
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c

@@ -1018,7 +1018,7 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
 	}
 	}
 
 
 
 
-	event = kzalloc(sizeof(event->event), GFP_KERNEL);
+	event = kzalloc(sizeof(*event), GFP_KERNEL);
 	if (unlikely(event == NULL)) {
 	if (unlikely(event == NULL)) {
 		DRM_ERROR("Failed to allocate an event.\n");
 		DRM_ERROR("Failed to allocate an event.\n");
 		ret = -ENOMEM;
 		ret = -ENOMEM;

+ 2 - 0
drivers/hid/hid-lenovo-tpkbd.c

@@ -519,6 +519,8 @@ static void tpkbd_remove_tp(struct hid_device *hdev)
 	led_classdev_unregister(&data_pointer->led_mute);
 	led_classdev_unregister(&data_pointer->led_mute);
 
 
 	hid_set_drvdata(hdev, NULL);
 	hid_set_drvdata(hdev, NULL);
+	kfree(data_pointer->led_micmute.name);
+	kfree(data_pointer->led_mute.name);
 	kfree(data_pointer);
 	kfree(data_pointer);
 }
 }
 
 

+ 45 - 0
drivers/hid/hid-logitech-dj.c

@@ -193,6 +193,7 @@ static struct hid_ll_driver logi_dj_ll_driver;
 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
 					size_t count,
 					size_t count,
 					unsigned char report_type);
 					unsigned char report_type);
+static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
 
 
 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
 						struct dj_report *dj_report)
 						struct dj_report *dj_report)
@@ -233,6 +234,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
 	if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
 	if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
 	    SPFUNCTION_DEVICE_LIST_EMPTY) {
 	    SPFUNCTION_DEVICE_LIST_EMPTY) {
 		dbg_hid("%s: device list is empty\n", __func__);
 		dbg_hid("%s: device list is empty\n", __func__);
+		djrcv_dev->querying_devices = false;
 		return;
 		return;
 	}
 	}
 
 
@@ -243,6 +245,12 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
 		return;
 		return;
 	}
 	}
 
 
+	if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
+		/* The device is already known. No need to reallocate it. */
+		dbg_hid("%s: device is already known\n", __func__);
+		return;
+	}
+
 	dj_hiddev = hid_allocate_device();
 	dj_hiddev = hid_allocate_device();
 	if (IS_ERR(dj_hiddev)) {
 	if (IS_ERR(dj_hiddev)) {
 		dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
 		dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@ -306,6 +314,7 @@ static void delayedwork_callback(struct work_struct *work)
 	struct dj_report dj_report;
 	struct dj_report dj_report;
 	unsigned long flags;
 	unsigned long flags;
 	int count;
 	int count;
+	int retval;
 
 
 	dbg_hid("%s\n", __func__);
 	dbg_hid("%s\n", __func__);
 
 
@@ -338,6 +347,25 @@ static void delayedwork_callback(struct work_struct *work)
 		logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
 		logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
 		break;
 		break;
 	default:
 	default:
+	/* A normal report (i. e. not belonging to a pair/unpair notification)
+	 * arriving here, means that the report arrived but we did not have a
+	 * paired dj_device associated to the report's device_index, this
+	 * means that the original "device paired" notification corresponding
+	 * to this dj_device never arrived to this driver. The reason is that
+	 * hid-core discards all packets coming from a device while probe() is
+	 * executing. */
+	if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
+		/* ok, we don't know the device, just re-ask the
+		 * receiver for the list of connected devices. */
+		retval = logi_dj_recv_query_paired_devices(djrcv_dev);
+		if (!retval) {
+			/* everything went fine, so just leave */
+			break;
+		}
+		dev_err(&djrcv_dev->hdev->dev,
+			"%s:logi_dj_recv_query_paired_devices "
+			"error:%d\n", __func__, retval);
+		}
 		dbg_hid("%s: unexpected report type\n", __func__);
 		dbg_hid("%s: unexpected report type\n", __func__);
 	}
 	}
 }
 }
@@ -368,6 +396,12 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
 	if (!djdev) {
 	if (!djdev) {
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 			" is NULL, index %d\n", dj_report->device_index);
 			" is NULL, index %d\n", dj_report->device_index);
+		kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+		if (schedule_work(&djrcv_dev->work) == 0) {
+			dbg_hid("%s: did not schedule the work item, was already "
+			"queued\n", __func__);
+		}
 		return;
 		return;
 	}
 	}
 
 
@@ -398,6 +432,12 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
 	if (dj_device == NULL) {
 	if (dj_device == NULL) {
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 			" is NULL, index %d\n", dj_report->device_index);
 			" is NULL, index %d\n", dj_report->device_index);
+		kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+		if (schedule_work(&djrcv_dev->work) == 0) {
+			dbg_hid("%s: did not schedule the work item, was already "
+			"queued\n", __func__);
+		}
 		return;
 		return;
 	}
 	}
 
 
@@ -439,6 +479,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
 	struct dj_report *dj_report;
 	struct dj_report *dj_report;
 	int retval;
 	int retval;
 
 
+	/* no need to protect djrcv_dev->querying_devices */
+	if (djrcv_dev->querying_devices)
+		return 0;
+
 	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
 	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
 	if (!dj_report)
 	if (!dj_report)
 		return -ENOMEM;
 		return -ENOMEM;
@@ -450,6 +494,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
 	return retval;
 	return retval;
 }
 }
 
 
+
 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
 					  unsigned timeout)
 					  unsigned timeout)
 {
 {

+ 1 - 0
drivers/hid/hid-logitech-dj.h

@@ -101,6 +101,7 @@ struct dj_receiver_dev {
 	struct work_struct work;
 	struct work_struct work;
 	struct kfifo notif_fifo;
 	struct kfifo notif_fifo;
 	spinlock_t lock;
 	spinlock_t lock;
+	bool querying_devices;
 };
 };
 
 
 struct dj_device {
 struct dj_device {

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.