Răsfoiți Sursa

Merge branch 'sched/urgent' into sched/core, to pick up dependency

Signed-off-by: Ingo Molnar <mingo@kernel.org>
Ingo Molnar 9 ani în urmă
părinte
comite
067b4f9342
100 a modificat fișierele cu 686 adăugiri și 570 ștergeri
  1. 1 0
      Documentation/arm64/silicon-errata.txt
  2. 1 0
      Documentation/devicetree/bindings/display/imx/ldb.txt
  3. 15 130
      Documentation/filesystems/devpts.txt
  4. 82 11
      Documentation/kdump/gdbmacros.txt
  5. 4 1
      Documentation/security/keys.txt
  6. 1 0
      MAINTAINERS
  7. 1 1
      Makefile
  8. 1 1
      arch/arm/kernel/ptrace.c
  9. 1 1
      arch/arm/mach-vexpress/spc.c
  10. 21 0
      arch/arm64/Kconfig
  11. 13 12
      arch/arm64/Kconfig.debug
  12. 3 1
      arch/arm64/Makefile
  13. 2 2
      arch/arm64/include/asm/elf.h
  14. 2 1
      arch/arm64/include/asm/memory.h
  15. 2 10
      arch/arm64/include/asm/page.h
  16. 0 13
      arch/arm64/include/asm/uaccess.h
  17. 1 1
      arch/arm64/include/asm/unistd.h
  18. 8 0
      arch/arm64/include/asm/unistd32.h
  19. 7 1
      arch/arm64/kernel/cpuinfo.c
  20. 3 2
      arch/arm64/kernel/traps.c
  21. 21 15
      arch/arm64/kvm/hyp/vgic-v3-sr.c
  22. 12 1
      arch/arm64/kvm/sys_regs.c
  23. 7 1
      arch/arm64/mm/dump.c
  24. 14 0
      arch/arm64/mm/hugetlbpage.c
  25. 2 0
      arch/parisc/include/asm/traps.h
  26. 3 2
      arch/parisc/kernel/processor.c
  27. 0 5
      arch/parisc/kernel/time.c
  28. 10 3
      arch/parisc/kernel/unaligned.c
  29. 14 8
      arch/parisc/kernel/unwind.c
  30. 3 3
      arch/powerpc/include/asm/reg.h
  31. 1 0
      arch/powerpc/kernel/prom_init.c
  32. 20 2
      arch/powerpc/mm/hash_utils_64.c
  33. 1 4
      arch/powerpc/mm/pgtable-book3s64.c
  34. 10 13
      arch/powerpc/mm/pgtable-radix.c
  35. 1 1
      arch/powerpc/platforms/512x/clock-commonclk.c
  36. 1 1
      arch/powerpc/platforms/cell/spufs/coredump.c
  37. 33 16
      arch/powerpc/platforms/pseries/eeh_pseries.c
  38. 12 10
      arch/x86/kvm/cpuid.c
  39. 4 4
      arch/x86/kvm/mmu.c
  40. 11 1
      arch/x86/kvm/x86.c
  41. 0 9
      drivers/acpi/acpi_processor.c
  42. 6 3
      drivers/acpi/acpi_video.c
  43. 9 14
      drivers/acpi/acpica/hwregs.c
  44. 9 0
      drivers/acpi/processor_throttling.c
  45. 1 0
      drivers/clk/Kconfig
  46. 5 5
      drivers/clk/microchip/clk-pic32mzda.c
  47. 1 1
      drivers/cpufreq/cpufreq.c
  48. 1 1
      drivers/cpufreq/intel_pstate.c
  49. 2 1
      drivers/edac/edac_mc.c
  50. 22 13
      drivers/edac/sb_edac.c
  51. 48 38
      drivers/gpu/drm/arm/hdlcd_crtc.c
  52. 29 39
      drivers/gpu/drm/arm/hdlcd_drv.c
  53. 1 4
      drivers/gpu/drm/arm/hdlcd_drv.h
  54. 5 5
      drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
  55. 2 1
      drivers/gpu/drm/drm_atomic.c
  56. 2 3
      drivers/gpu/drm/drm_crtc.c
  57. 1 1
      drivers/gpu/drm/drm_fb_cma_helper.c
  58. 3 9
      drivers/gpu/drm/drm_gem_cma_helper.c
  59. 2 0
      drivers/gpu/drm/drm_modes.c
  60. 8 5
      drivers/gpu/drm/imx/imx-drm-core.c
  61. 4 3
      drivers/gpu/drm/imx/imx-drm.h
  62. 53 25
      drivers/gpu/drm/imx/imx-ldb.c
  63. 4 2
      drivers/gpu/drm/imx/imx-tve.c
  64. 7 3
      drivers/gpu/drm/imx/ipuv3-crtc.c
  65. 3 2
      drivers/gpu/drm/imx/ipuv3-plane.c
  66. 14 26
      drivers/gpu/drm/imx/parallel-display.c
  67. 0 5
      drivers/gpu/drm/mediatek/mtk_dpi.c
  68. 1 3
      drivers/gpu/drm/mediatek/mtk_dsi.c
  69. 9 1
      drivers/gpu/drm/mgag200/mgag200_mode.c
  70. 1 0
      drivers/gpu/drm/omapdrm/Kconfig
  71. 1 0
      drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
  72. 1 1
      drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
  73. 1 1
      drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
  74. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-dpi.c
  75. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
  76. 1 0
      drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
  77. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
  78. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
  79. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
  80. 1 1
      drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
  81. 0 9
      drivers/gpu/drm/omapdrm/dss/dsi.c
  82. 1 0
      drivers/gpu/drm/omapdrm/dss/dss.c
  83. 1 10
      drivers/gpu/drm/omapdrm/dss/hdmi4.c
  84. 1 1
      drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
  85. 1 9
      drivers/gpu/drm/omapdrm/dss/hdmi5.c
  86. 3 3
      drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
  87. 1 0
      drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
  88. 1 0
      drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
  89. 1 0
      drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
  90. 2 0
      drivers/gpu/drm/omapdrm/omap_debugfs.c
  91. 1 0
      drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
  92. 2 0
      drivers/gpu/drm/omapdrm/omap_fb.c
  93. 1 0
      drivers/gpu/drm/omapdrm/omap_gem.c
  94. 0 10
      drivers/gpu/drm/sti/sti_crtc.c
  95. 47 2
      drivers/irqchip/irq-gic-v3-its.c
  96. 1 1
      drivers/irqchip/irq-gic-v3.c
  97. 1 1
      drivers/irqchip/irq-pic32-evic.c
  98. 2 2
      drivers/mmc/core/mmc.c
  99. 2 7
      drivers/mmc/host/sunxi-mmc.c
  100. 5 7
      drivers/perf/arm_pmu.c

+ 1 - 0
Documentation/arm64/silicon-errata.txt

@@ -56,6 +56,7 @@ stable kernels.
 | ARM            | MMU-500         | #841119,#826419 | N/A                     |
 | ARM            | MMU-500         | #841119,#826419 | N/A                     |
 |                |                 |                 |                         |
 |                |                 |                 |                         |
 | Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375    |
 | Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375    |
+| Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144    |
 | Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
 | Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
 | Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
 | Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
 | Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
 | Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |

+ 1 - 0
Documentation/devicetree/bindings/display/imx/ldb.txt

@@ -62,6 +62,7 @@ Required properties:
    display-timings are used instead.
    display-timings are used instead.
 
 
 Optional properties (required if display-timings are used):
 Optional properties (required if display-timings are used):
+ - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
  - display-timings : A node that describes the display timings as defined in
  - display-timings : A node that describes the display timings as defined in
    Documentation/devicetree/bindings/display/display-timing.txt.
    Documentation/devicetree/bindings/display/display-timing.txt.
  - fsl,data-mapping : should be "spwg" or "jeida"
  - fsl,data-mapping : should be "spwg" or "jeida"

+ 15 - 130
Documentation/filesystems/devpts.txt

@@ -1,141 +1,26 @@
+Each mount of the devpts filesystem is now distinct such that ptys
+and their indicies allocated in one mount are independent from ptys
+and their indicies in all other mounts.
 
 
-To support containers, we now allow multiple instances of devpts filesystem,
-such that indices of ptys allocated in one instance are independent of indices
-allocated in other instances of devpts.
+All mounts of the devpts filesystem now create a /dev/pts/ptmx node
+with permissions 0000.
 
 
-To preserve backward compatibility, this support for multiple instances is
-enabled only if:
+To retain backwards compatibility the a ptmx device node (aka any node
+created with "mknod name c 5 2") when opened will look for an instance
+of devpts under the name "pts" in the same directory as the ptmx device
+node.
 
 
-	- CONFIG_DEVPTS_MULTIPLE_INSTANCES=y, and
-	- '-o newinstance' mount option is specified while mounting devpts
-
-IOW, devpts now supports both single-instance and multi-instance semantics.
-
-If CONFIG_DEVPTS_MULTIPLE_INSTANCES=n, there is no change in behavior and
-this referred to as the "legacy" mode. In this mode, the new mount options
-(-o newinstance and -o ptmxmode) will be ignored with a 'bogus option' message
-on console.
-
-If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and devpts is mounted without the
-'newinstance' option (as in current start-up scripts) the new mount binds
-to the initial kernel mount of devpts. This mode is referred to as the
-'single-instance' mode and the current, single-instance semantics are
-preserved, i.e PTYs are common across the system.
-
-The only difference between this single-instance mode and the legacy mode
-is the presence of new, '/dev/pts/ptmx' node with permissions 0000, which
-can safely be ignored.
-
-If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and 'newinstance' option is specified,
-the mount is considered to be in the multi-instance mode and a new instance
-of the devpts fs is created. Any ptys created in this instance are independent
-of ptys in other instances of devpts. Like in the single-instance mode, the
-/dev/pts/ptmx node is present. To effectively use the multi-instance mode,
-open of /dev/ptmx must be a redirected to '/dev/pts/ptmx' using a symlink or
-bind-mount.
-
-Eg: A container startup script could do the following:
-
-	$ chmod 0666 /dev/pts/ptmx
-	$ rm /dev/ptmx
-	$ ln -s pts/ptmx /dev/ptmx
-	$ ns_exec -cm /bin/bash
-
-	# We are now in new container
-
-	$ umount /dev/pts
-	$ mount -t devpts -o newinstance lxcpts /dev/pts
-	$ sshd -p 1234
-
-where 'ns_exec -cm /bin/bash' calls clone() with CLONE_NEWNS flag and execs
-/bin/bash in the child process.  A pty created by the sshd is not visible in
-the original mount of /dev/pts.
+As an option instead of placing a /dev/ptmx device node at /dev/ptmx
+it is possible to place a symlink to /dev/pts/ptmx at /dev/ptmx or
+to bind mount /dev/ptx/ptmx to /dev/ptmx.  If you opt for using
+the devpts filesystem in this manner devpts should be mounted with
+the ptmxmode=0666, or chmod 0666 /dev/pts/ptmx should be called.
 
 
 Total count of pty pairs in all instances is limited by sysctls:
 Total count of pty pairs in all instances is limited by sysctls:
 kernel.pty.max = 4096		- global limit
 kernel.pty.max = 4096		- global limit
-kernel.pty.reserve = 1024	- reserve for initial instance
+kernel.pty.reserve = 1024	- reserved for filesystems mounted from the initial mount namespace
 kernel.pty.nr			- current count of ptys
 kernel.pty.nr			- current count of ptys
 
 
 Per-instance limit could be set by adding mount option "max=<count>".
 Per-instance limit could be set by adding mount option "max=<count>".
 This feature was added in kernel 3.4 together with sysctl kernel.pty.reserve.
 This feature was added in kernel 3.4 together with sysctl kernel.pty.reserve.
 In kernels older than 3.4 sysctl kernel.pty.max works as per-instance limit.
 In kernels older than 3.4 sysctl kernel.pty.max works as per-instance limit.
-
-User-space changes
-------------------
-
-In multi-instance mode (i.e '-o newinstance' mount option is specified at least
-once), following user-space issues should be noted.
-
-1. If -o newinstance mount option is never used, /dev/pts/ptmx can be ignored
-   and no change is needed to system-startup scripts.
-
-2. To effectively use multi-instance mode (i.e -o newinstance is specified)
-   administrators or startup scripts should "redirect" open of /dev/ptmx to
-   /dev/pts/ptmx using either a bind mount or symlink.
-
-	$ mount -t devpts -o newinstance devpts /dev/pts
-
-   followed by either
-
-	$ rm /dev/ptmx
-	$ ln -s pts/ptmx /dev/ptmx
-	$ chmod 666 /dev/pts/ptmx
-   or
-	$ mount -o bind /dev/pts/ptmx /dev/ptmx
-
-3. The '/dev/ptmx -> pts/ptmx' symlink is the preferred method since it
-   enables better error-reporting and treats both single-instance and
-   multi-instance mounts similarly.
-
-   But this method requires that system-startup scripts set the mode of
-   /dev/pts/ptmx correctly (default mode is 0000). The scripts can set the
-   mode by, either
-
-   	- adding ptmxmode mount option to devpts entry in /etc/fstab, or
-	- using 'chmod 0666 /dev/pts/ptmx'
-
-4. If multi-instance mode mount is needed for containers, but the system
-   startup scripts have not yet been updated, container-startup scripts
-   should bind mount /dev/ptmx to /dev/pts/ptmx to avoid breaking single-
-   instance mounts.
-
-   Or, in general, container-startup scripts should use:
-
-	mount -t devpts -o newinstance -o ptmxmode=0666 devpts /dev/pts
-	if [ ! -L /dev/ptmx ]; then
-		mount -o bind /dev/pts/ptmx /dev/ptmx
-	fi
-
-   When all devpts mounts are multi-instance, /dev/ptmx can permanently be
-   a symlink to pts/ptmx and the bind mount can be ignored.
-
-5. A multi-instance mount that is not accompanied by the /dev/ptmx to
-   /dev/pts/ptmx redirection would result in an unusable/unreachable pty.
-
-	mount -t devpts -o newinstance lxcpts /dev/pts
-
-   immediately followed by:
-
-	open("/dev/ptmx")
-
-    would create a pty, say /dev/pts/7, in the initial kernel mount.
-    But /dev/pts/7 would be invisible in the new mount.
-
-6. The permissions for /dev/pts/ptmx node should be specified when mounting
-   /dev/pts, using the '-o ptmxmode=%o' mount option (default is 0000).
-
-	mount -t devpts -o newinstance -o ptmxmode=0644 devpts /dev/pts
-
-   The permissions can be later be changed as usual with 'chmod'.
-
-	chmod 666 /dev/pts/ptmx
-
-7. A mount of devpts without the 'newinstance' option results in binding to
-   initial kernel mount.  This behavior while preserving legacy semantics,
-   does not provide strict isolation in a container environment. i.e by
-   mounting devpts without the 'newinstance' option, a container could
-   get visibility into the 'host' or root container's devpts.
-   
-   To workaround this and have strict isolation, all mounts of devpts,
-   including the mount in the root container, should use the newinstance
-   option.

+ 82 - 11
Documentation/kdump/gdbmacros.txt

@@ -170,21 +170,92 @@ document trapinfo
 	address the kernel panicked.
 	address the kernel panicked.
 end
 end
 
 
+define dump_log_idx
+	set $idx = $arg0
+	if ($argc > 1)
+		set $prev_flags = $arg1
+	else
+		set $prev_flags = 0
+	end
+	set $msg = ((struct printk_log *) (log_buf + $idx))
+	set $prefix = 1
+	set $newline = 1
+	set $log = log_buf + $idx + sizeof(*$msg)
 
 
-define dmesg
-	set $i = 0
-	set $end_idx = (log_end - 1) & (log_buf_len - 1)
+	# prev & LOG_CONT && !(msg->flags & LOG_PREIX)
+	if (($prev_flags & 8) && !($msg->flags & 4))
+		set $prefix = 0
+	end
+
+	# msg->flags & LOG_CONT
+	if ($msg->flags & 8)
+		# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
+		if (($prev_flags & 8) && !($prev_flags & 2))
+			set $prefix = 0
+		end
+		# (!(msg->flags & LOG_NEWLINE))
+		if (!($msg->flags & 2))
+			set $newline = 0
+		end
+	end
+
+	if ($prefix)
+		printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000
+	end
+	if ($msg->text_len != 0)
+		eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len
+	end
+	if ($newline)
+		printf "\n"
+	end
+	if ($msg->dict_len > 0)
+		set $dict = $log + $msg->text_len
+		set $idx = 0
+		set $line = 1
+		while ($idx < $msg->dict_len)
+			if ($line)
+				printf " "
+				set $line = 0
+			end
+			set $c = $dict[$idx]
+			if ($c == '\0')
+				printf "\n"
+				set $line = 1
+			else
+				if ($c < ' ' || $c >= 127 || $c == '\\')
+					printf "\\x%02x", $c
+				else
+					printf "%c", $c
+				end
+			end
+			set $idx = $idx + 1
+		end
+		printf "\n"
+	end
+end
+document dump_log_idx
+	Dump a single log given its index in the log buffer.  The first
+	parameter is the index into log_buf, the second is optional and
+	specified the previous log buffer's flags, used for properly
+	formatting continued lines.
+end
 
 
-	while ($i < logged_chars)
-		set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)
+define dmesg
+	set $i = log_first_idx
+	set $end_idx = log_first_idx
+	set $prev_flags = 0
 
 
-		if ($idx + 100 <= $end_idx) || \
-		   ($end_idx <= $idx && $idx + 100 < log_buf_len)
-			printf "%.100s", &log_buf[$idx]
-			set $i = $i + 100
+	while (1)
+		set $msg = ((struct printk_log *) (log_buf + $i))
+		if ($msg->len == 0)
+			set $i = 0
 		else
 		else
-			printf "%c", log_buf[$idx]
-			set $i = $i + 1
+			dump_log_idx $i $prev_flags
+			set $i = $i + $msg->len
+			set $prev_flags = $msg->flags
+		end
+		if ($i == $end_idx)
+			loop_break
 		end
 		end
 	end
 	end
 end
 end

+ 4 - 1
Documentation/security/keys.txt

@@ -826,7 +826,8 @@ The keyctl syscall functions are:
  (*) Compute a Diffie-Hellman shared secret or public key
  (*) Compute a Diffie-Hellman shared secret or public key
 
 
        long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
        long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
-		   char *buffer, size_t buflen);
+		   char *buffer, size_t buflen,
+		   void *reserved);
 
 
      The params struct contains serial numbers for three keys:
      The params struct contains serial numbers for three keys:
 
 
@@ -843,6 +844,8 @@ The keyctl syscall functions are:
      public key.  If the base is the remote public key, the result is
      public key.  If the base is the remote public key, the result is
      the shared secret.
      the shared secret.
 
 
+     The reserved argument must be set to NULL.
+
      The buffer length must be at least the length of the prime, or zero.
      The buffer length must be at least the length of the prime, or zero.
 
 
      If the buffer length is nonzero, the length of the result is
      If the buffer length is nonzero, the length of the result is

+ 1 - 0
MAINTAINERS

@@ -3086,6 +3086,7 @@ M:	Stephen Boyd <sboyd@codeaurora.org>
 L:	linux-clk@vger.kernel.org
 L:	linux-clk@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
 S:	Maintained
 S:	Maintained
+F:	Documentation/devicetree/bindings/clock/
 F:	drivers/clk/
 F:	drivers/clk/
 X:	drivers/clk/clkdev.c
 X:	drivers/clk/clkdev.c
 F:	include/linux/clk-pr*
 F:	include/linux/clk-pr*

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 4
 VERSION = 4
 PATCHLEVEL = 7
 PATCHLEVEL = 7
 SUBLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Psychotic Stoned Sheep
 NAME = Psychotic Stoned Sheep
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 1 - 1
arch/arm/kernel/ptrace.c

@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	vfp_flush_hwstate(thread);
 	thread->vfpstate.hard = new_vfp;
 	thread->vfpstate.hard = new_vfp;
+	vfp_flush_hwstate(thread);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 1
arch/arm/mach-vexpress/spc.c

@@ -547,7 +547,7 @@ static struct clk *ve_spc_clk_register(struct device *cpu_dev)
 
 
 	init.name = dev_name(cpu_dev);
 	init.name = dev_name(cpu_dev);
 	init.ops = &clk_spc_ops;
 	init.ops = &clk_spc_ops;
-	init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+	init.flags = CLK_GET_RATE_NOCACHE;
 	init.num_parents = 0;
 	init.num_parents = 0;
 
 
 	return devm_clk_register(cpu_dev, &spc->hw);
 	return devm_clk_register(cpu_dev, &spc->hw);

+ 21 - 0
arch/arm64/Kconfig

@@ -113,6 +113,18 @@ config ARCH_PHYS_ADDR_T_64BIT
 config MMU
 config MMU
 	def_bool y
 	def_bool y
 
 
+config ARM64_PAGE_SHIFT
+	int
+	default 16 if ARM64_64K_PAGES
+	default 14 if ARM64_16K_PAGES
+	default 12
+
+config ARM64_CONT_SHIFT
+	int
+	default 5 if ARM64_64K_PAGES
+	default 7 if ARM64_16K_PAGES
+	default 4
+
 config ARCH_MMAP_RND_BITS_MIN
 config ARCH_MMAP_RND_BITS_MIN
        default 14 if ARM64_64K_PAGES
        default 14 if ARM64_64K_PAGES
        default 16 if ARM64_16K_PAGES
        default 16 if ARM64_16K_PAGES
@@ -426,6 +438,15 @@ config CAVIUM_ERRATUM_22375
 
 
 	  If unsure, say Y.
 	  If unsure, say Y.
 
 
+config CAVIUM_ERRATUM_23144
+	bool "Cavium erratum 23144: ITS SYNC hang on dual socket system"
+	depends on NUMA
+	default y
+	help
+	  ITS SYNC command hang for cross node io and collections/cpu mapping.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_23154
 config CAVIUM_ERRATUM_23154
 	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
 	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
 	default y
 	default y

+ 13 - 12
arch/arm64/Kconfig.debug

@@ -12,7 +12,8 @@ config ARM64_PTDUMP
 	  who are working in architecture specific areas of the kernel.
 	  who are working in architecture specific areas of the kernel.
 	  It is probably not a good idea to enable this feature in a production
 	  It is probably not a good idea to enable this feature in a production
 	  kernel.
 	  kernel.
-	  If in doubt, say "N"
+
+	  If in doubt, say N.
 
 
 config PID_IN_CONTEXTIDR
 config PID_IN_CONTEXTIDR
 	bool "Write the current PID to the CONTEXTIDR register"
 	bool "Write the current PID to the CONTEXTIDR register"
@@ -38,15 +39,15 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
 	  value.
 	  value.
 
 
 config DEBUG_SET_MODULE_RONX
 config DEBUG_SET_MODULE_RONX
-        bool "Set loadable kernel module data as NX and text as RO"
-        depends on MODULES
-        help
-          This option helps catch unintended modifications to loadable
-          kernel module's text and read-only data. It also prevents execution
-          of module data. Such protection may interfere with run-time code
-          patching and dynamic kernel tracing - and they might also protect
-          against certain classes of kernel exploits.
-          If in doubt, say "N".
+	bool "Set loadable kernel module data as NX and text as RO"
+	depends on MODULES
+	default y
+	help
+	  Is this is set, kernel module text and rodata will be made read-only.
+	  This is to help catch accidental or malicious attempts to change the
+	  kernel's executable code.
+
+	  If in doubt, say Y.
 
 
 config DEBUG_RODATA
 config DEBUG_RODATA
 	bool "Make kernel text and rodata read-only"
 	bool "Make kernel text and rodata read-only"
@@ -56,7 +57,7 @@ config DEBUG_RODATA
 	  is to help catch accidental or malicious attempts to change the
 	  is to help catch accidental or malicious attempts to change the
 	  kernel's executable code.
 	  kernel's executable code.
 
 
-	  If in doubt, say Y
+	  If in doubt, say Y.
 
 
 config DEBUG_ALIGN_RODATA
 config DEBUG_ALIGN_RODATA
 	depends on DEBUG_RODATA
 	depends on DEBUG_RODATA
@@ -69,7 +70,7 @@ config DEBUG_ALIGN_RODATA
 	  alignment and potentially wasted space. Turn on this option if
 	  alignment and potentially wasted space. Turn on this option if
 	  performance is more important than memory pressure.
 	  performance is more important than memory pressure.
 
 
-	  If in doubt, say N
+	  If in doubt, say N.
 
 
 source "drivers/hwtracing/coresight/Kconfig"
 source "drivers/hwtracing/coresight/Kconfig"
 
 

+ 3 - 1
arch/arm64/Makefile

@@ -60,7 +60,9 @@ head-y		:= arch/arm64/kernel/head.o
 
 
 # The byte offset of the kernel image in RAM from the start of RAM.
 # The byte offset of the kernel image in RAM from the start of RAM.
 ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
 ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
-TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}')
+TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
+		 int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
+		 rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
 else
 else
 TEXT_OFFSET := 0x00080000
 TEXT_OFFSET := 0x00080000
 endif
 endif

+ 2 - 2
arch/arm64/include/asm/elf.h

@@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #define STACK_RND_MASK			(0x3ffff >> (PAGE_SHIFT - 12))
 #define STACK_RND_MASK			(0x3ffff >> (PAGE_SHIFT - 12))
 #endif
 #endif
 
 
-#ifdef CONFIG_COMPAT
-
 #ifdef __AARCH64EB__
 #ifdef __AARCH64EB__
 #define COMPAT_ELF_PLATFORM		("v8b")
 #define COMPAT_ELF_PLATFORM		("v8b")
 #else
 #else
 #define COMPAT_ELF_PLATFORM		("v8l")
 #define COMPAT_ELF_PLATFORM		("v8l")
 #endif
 #endif
 
 
+#ifdef CONFIG_COMPAT
+
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
 
 /* AArch32 registers. */
 /* AArch32 registers. */

+ 2 - 1
arch/arm64/include/asm/memory.h

@@ -55,8 +55,9 @@
 #define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT))
 #define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT))
 
 
 /*
 /*
- * PAGE_OFFSET - the virtual address of the start of the kernel image (top
+ * PAGE_OFFSET - the virtual address of the start of the linear map (top
  *		 (VA_BITS - 1))
  *		 (VA_BITS - 1))
+ * KIMAGE_VADDR - the virtual address of the start of the kernel image
  * VA_BITS - the maximum number of bits for virtual addresses.
  * VA_BITS - the maximum number of bits for virtual addresses.
  * VA_START - the first kernel virtual address.
  * VA_START - the first kernel virtual address.
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_SIZE - the maximum size of a user space task.

+ 2 - 10
arch/arm64/include/asm/page.h

@@ -23,16 +23,8 @@
 
 
 /* PAGE_SHIFT determines the page size */
 /* PAGE_SHIFT determines the page size */
 /* CONT_SHIFT determines the number of pages which can be tracked together  */
 /* CONT_SHIFT determines the number of pages which can be tracked together  */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define PAGE_SHIFT		16
-#define CONT_SHIFT		5
-#elif defined(CONFIG_ARM64_16K_PAGES)
-#define PAGE_SHIFT		14
-#define CONT_SHIFT		7
-#else
-#define PAGE_SHIFT		12
-#define CONT_SHIFT		4
-#endif
+#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT
+#define CONT_SHIFT		CONFIG_ARM64_CONT_SHIFT
 #define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 
 

+ 0 - 13
arch/arm64/include/asm/uaccess.h

@@ -80,19 +80,6 @@ static inline void set_fs(mm_segment_t fs)
 
 
 #define segment_eq(a, b)	((a) == (b))
 #define segment_eq(a, b)	((a) == (b))
 
 
-/*
- * Return 1 if addr < current->addr_limit, 0 otherwise.
- */
-#define __addr_ok(addr)							\
-({									\
-	unsigned long flag;						\
-	asm("cmp %1, %0; cset %0, lo"					\
-		: "=&r" (flag)						\
-		: "r" (addr), "0" (current_thread_info()->addr_limit)	\
-		: "cc");						\
-	flag;								\
-})
-
 /*
 /*
  * Test whether a block of memory is a valid user space address.
  * Test whether a block of memory is a valid user space address.
  * Returns 1 if the range is valid, 0 otherwise.
  * Returns 1 if the range is valid, 0 otherwise.

+ 1 - 1
arch/arm64/include/asm/unistd.h

@@ -44,7 +44,7 @@
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 
 
-#define __NR_compat_syscalls		390
+#define __NR_compat_syscalls		394
 #endif
 #endif
 
 
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_CLONE

+ 8 - 0
arch/arm64/include/asm/unistd32.h

@@ -801,6 +801,14 @@ __SYSCALL(__NR_execveat, compat_sys_execveat)
 __SYSCALL(__NR_userfaultfd, sys_userfaultfd)
 __SYSCALL(__NR_userfaultfd, sys_userfaultfd)
 #define __NR_membarrier 389
 #define __NR_membarrier 389
 __SYSCALL(__NR_membarrier, sys_membarrier)
 __SYSCALL(__NR_membarrier, sys_membarrier)
+#define __NR_mlock2 390
+__SYSCALL(__NR_mlock2, sys_mlock2)
+#define __NR_copy_file_range 391
+__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
+#define __NR_preadv2 392
+__SYSCALL(__NR_preadv2, compat_sys_preadv2)
+#define __NR_pwritev2 393
+__SYSCALL(__NR_pwritev2, compat_sys_pwritev2)
 
 
 /*
 /*
  * Please add new compat syscalls above this comment and update
  * Please add new compat syscalls above this comment and update

+ 7 - 1
arch/arm64/kernel/cpuinfo.c

@@ -22,6 +22,8 @@
 
 
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
+#include <linux/compat.h>
+#include <linux/elf.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/personality.h>
 #include <linux/personality.h>
@@ -104,6 +106,7 @@ static const char *const compat_hwcap2_str[] = {
 static int c_show(struct seq_file *m, void *v)
 static int c_show(struct seq_file *m, void *v)
 {
 {
 	int i, j;
 	int i, j;
+	bool compat = personality(current->personality) == PER_LINUX32;
 
 
 	for_each_online_cpu(i) {
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
@@ -115,6 +118,9 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 * "processor".  Give glibc what it expects.
 		 */
 		 */
 		seq_printf(m, "processor\t: %d\n", i);
 		seq_printf(m, "processor\t: %d\n", i);
+		if (compat)
+			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
 
 
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 			   loops_per_jiffy / (500000UL/HZ),
 			   loops_per_jiffy / (500000UL/HZ),
@@ -127,7 +133,7 @@ static int c_show(struct seq_file *m, void *v)
 		 * software which does already (at least for 32-bit).
 		 * software which does already (at least for 32-bit).
 		 */
 		 */
 		seq_puts(m, "Features\t:");
 		seq_puts(m, "Features\t:");
-		if (personality(current->personality) == PER_LINUX32) {
+		if (compat) {
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 			for (j = 0; compat_hwcap_str[j]; j++)
 			for (j = 0; compat_hwcap_str[j]; j++)
 				if (compat_elf_hwcap & (1 << j))
 				if (compat_elf_hwcap & (1 << j))

+ 3 - 2
arch/arm64/kernel/traps.c

@@ -477,8 +477,9 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
 	void __user *pc = (void __user *)instruction_pointer(regs);
 	void __user *pc = (void __user *)instruction_pointer(regs);
 	console_verbose();
 	console_verbose();
 
 
-	pr_crit("Bad mode in %s handler detected, code 0x%08x -- %s\n",
-		handler[reason], esr, esr_get_class_string(esr));
+	pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n",
+		handler[reason], smp_processor_id(), esr,
+		esr_get_class_string(esr));
 	__show_regs(regs);
 	__show_regs(regs);
 
 
 	info.si_signo = SIGILL;
 	info.si_signo = SIGILL;

+ 21 - 15
arch/arm64/kvm/hyp/vgic-v3-sr.c

@@ -169,7 +169,8 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 	 * Make sure stores to the GIC via the memory mapped interface
 	 * Make sure stores to the GIC via the memory mapped interface
 	 * are now visible to the system register interface.
 	 * are now visible to the system register interface.
 	 */
 	 */
-	dsb(st);
+	if (!cpu_if->vgic_sre)
+		dsb(st);
 
 
 	cpu_if->vgic_vmcr  = read_gicreg(ICH_VMCR_EL2);
 	cpu_if->vgic_vmcr  = read_gicreg(ICH_VMCR_EL2);
 
 
@@ -190,12 +191,11 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 			if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
 			if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
 				continue;
 				continue;
 
 
-			if (cpu_if->vgic_elrsr & (1 << i)) {
+			if (cpu_if->vgic_elrsr & (1 << i))
 				cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
 				cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
-				continue;
-			}
+			else
+				cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
 
 
-			cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
 			__gic_v3_set_lr(0, i);
 			__gic_v3_set_lr(0, i);
 		}
 		}
 
 
@@ -236,8 +236,12 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 
 
 	val = read_gicreg(ICC_SRE_EL2);
 	val = read_gicreg(ICC_SRE_EL2);
 	write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
 	write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
-	isb(); /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
-	write_gicreg(1, ICC_SRE_EL1);
+
+	if (!cpu_if->vgic_sre) {
+		/* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
+		isb();
+		write_gicreg(1, ICC_SRE_EL1);
+	}
 }
 }
 
 
 void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
@@ -256,8 +260,10 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 	 * been actually programmed with the value we want before
 	 * been actually programmed with the value we want before
 	 * starting to mess with the rest of the GIC.
 	 * starting to mess with the rest of the GIC.
 	 */
 	 */
-	write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1);
-	isb();
+	if (!cpu_if->vgic_sre) {
+		write_gicreg(0, ICC_SRE_EL1);
+		isb();
+	}
 
 
 	val = read_gicreg(ICH_VTR_EL2);
 	val = read_gicreg(ICH_VTR_EL2);
 	max_lr_idx = vtr_to_max_lr_idx(val);
 	max_lr_idx = vtr_to_max_lr_idx(val);
@@ -306,18 +312,18 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
 	 * (re)distributors. This ensure the guest will read the
 	 * (re)distributors. This ensure the guest will read the
 	 * correct values from the memory-mapped interface.
 	 * correct values from the memory-mapped interface.
 	 */
 	 */
-	isb();
-	dsb(sy);
+	if (!cpu_if->vgic_sre) {
+		isb();
+		dsb(sy);
+	}
 	vcpu->arch.vgic_cpu.live_lrs = live_lrs;
 	vcpu->arch.vgic_cpu.live_lrs = live_lrs;
 
 
 	/*
 	/*
 	 * Prevent the guest from touching the GIC system registers if
 	 * Prevent the guest from touching the GIC system registers if
 	 * SRE isn't enabled for GICv3 emulation.
 	 * SRE isn't enabled for GICv3 emulation.
 	 */
 	 */
-	if (!cpu_if->vgic_sre) {
-		write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
-			     ICC_SRE_EL2);
-	}
+	write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
+		     ICC_SRE_EL2);
 }
 }
 
 
 void __hyp_text __vgic_v3_init_lrs(void)
 void __hyp_text __vgic_v3_init_lrs(void)

+ 12 - 1
arch/arm64/kvm/sys_regs.c

@@ -134,6 +134,17 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
 	return true;
 	return true;
 }
 }
 
 
+static bool access_gic_sre(struct kvm_vcpu *vcpu,
+			   struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+	return true;
+}
+
 static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 			struct sys_reg_params *p,
 			struct sys_reg_params *p,
 			const struct sys_reg_desc *r)
 			const struct sys_reg_desc *r)
@@ -958,7 +969,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	  access_gic_sgi },
 	  access_gic_sgi },
 	/* ICC_SRE_EL1 */
 	/* ICC_SRE_EL1 */
 	{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
 	{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101),
-	  trap_raz_wi },
+	  access_gic_sre },
 
 
 	/* CONTEXTIDR_EL1 */
 	/* CONTEXTIDR_EL1 */
 	{ Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001),
 	{ Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001),

+ 7 - 1
arch/arm64/mm/dump.c

@@ -150,6 +150,7 @@ static const struct prot_bits pte_bits[] = {
 
 
 struct pg_level {
 struct pg_level {
 	const struct prot_bits *bits;
 	const struct prot_bits *bits;
+	const char *name;
 	size_t num;
 	size_t num;
 	u64 mask;
 	u64 mask;
 };
 };
@@ -157,15 +158,19 @@ struct pg_level {
 static struct pg_level pg_level[] = {
 static struct pg_level pg_level[] = {
 	{
 	{
 	}, { /* pgd */
 	}, { /* pgd */
+		.name	= "PGD",
 		.bits	= pte_bits,
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pud */
 	}, { /* pud */
+		.name	= (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
 		.bits	= pte_bits,
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pmd */
 	}, { /* pmd */
+		.name	= (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD",
 		.bits	= pte_bits,
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 		.num	= ARRAY_SIZE(pte_bits),
 	}, { /* pte */
 	}, { /* pte */
+		.name	= "PTE",
 		.bits	= pte_bits,
 		.bits	= pte_bits,
 		.num	= ARRAY_SIZE(pte_bits),
 		.num	= ARRAY_SIZE(pte_bits),
 	},
 	},
@@ -214,7 +219,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
 				delta >>= 10;
 				delta >>= 10;
 				unit++;
 				unit++;
 			}
 			}
-			seq_printf(st->seq, "%9lu%c", delta, *unit);
+			seq_printf(st->seq, "%9lu%c %s", delta, *unit,
+				   pg_level[st->level].name);
 			if (pg_level[st->level].bits)
 			if (pg_level[st->level].bits)
 				dump_prot(st, pg_level[st->level].bits,
 				dump_prot(st, pg_level[st->level].bits,
 					  pg_level[st->level].num);
 					  pg_level[st->level].num);

+ 14 - 0
arch/arm64/mm/hugetlbpage.c

@@ -306,6 +306,10 @@ static __init int setup_hugepagesz(char *opt)
 		hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
 		hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
 	} else if (ps == PUD_SIZE) {
 	} else if (ps == PUD_SIZE) {
 		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
 		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
+	} else if (ps == (PAGE_SIZE * CONT_PTES)) {
+		hugetlb_add_hstate(CONT_PTE_SHIFT);
+	} else if (ps == (PMD_SIZE * CONT_PMDS)) {
+		hugetlb_add_hstate((PMD_SHIFT + CONT_PMD_SHIFT) - PAGE_SHIFT);
 	} else {
 	} else {
 		hugetlb_bad_size();
 		hugetlb_bad_size();
 		pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10);
 		pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10);
@@ -314,3 +318,13 @@ static __init int setup_hugepagesz(char *opt)
 	return 1;
 	return 1;
 }
 }
 __setup("hugepagesz=", setup_hugepagesz);
 __setup("hugepagesz=", setup_hugepagesz);
+
+#ifdef CONFIG_ARM64_64K_PAGES
+static __init int add_default_hugepagesz(void)
+{
+	if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL)
+		hugetlb_add_hstate(CONT_PMD_SHIFT);
+	return 0;
+}
+arch_initcall(add_default_hugepagesz);
+#endif

+ 2 - 0
arch/parisc/include/asm/traps.h

@@ -8,6 +8,8 @@ struct pt_regs;
 void parisc_terminate(char *msg, struct pt_regs *regs,
 void parisc_terminate(char *msg, struct pt_regs *regs,
 		int code, unsigned long offset) __noreturn __cold;
 		int code, unsigned long offset) __noreturn __cold;
 
 
+void die_if_kernel(char *str, struct pt_regs *regs, long err);
+
 /* mm/fault.c */
 /* mm/fault.c */
 void do_page_fault(struct pt_regs *regs, unsigned long code,
 void do_page_fault(struct pt_regs *regs, unsigned long code,
 		unsigned long address);
 		unsigned long address);

+ 3 - 2
arch/parisc/kernel/processor.c

@@ -324,8 +324,9 @@ int init_per_cpu(int cpunum)
 		per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
 		per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
 		per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
 		per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
 
 
-		printk(KERN_INFO  "FP[%d] enabled: Rev %ld Model %ld\n",
-			cpunum, coproc_cfg.revision, coproc_cfg.model);
+		if (cpunum == 0)
+			printk(KERN_INFO  "FP[%d] enabled: Rev %ld Model %ld\n",
+				cpunum, coproc_cfg.revision, coproc_cfg.model);
 
 
 		/*
 		/*
 		** store status register to stack (hopefully aligned)
 		** store status register to stack (hopefully aligned)

+ 0 - 5
arch/parisc/kernel/time.c

@@ -309,11 +309,6 @@ void __init time_init(void)
 	clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz,
 	clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz,
 				NSEC_PER_MSEC, 0);
 				NSEC_PER_MSEC, 0);
 
 
-#if defined(CONFIG_HAVE_UNSTABLE_SCHED_CLOCK) && defined(CONFIG_64BIT)
-	/* At bootup only one 64bit CPU is online and cr16 is "stable" */
-	set_sched_clock_stable();
-#endif
-
 	start_cpu_itimer();	/* get CPU 0 started */
 	start_cpu_itimer();	/* get CPU 0 started */
 
 
 	/* register at clocksource framework */
 	/* register at clocksource framework */

+ 10 - 3
arch/parisc/kernel/unaligned.c

@@ -28,6 +28,7 @@
 #include <linux/ratelimit.h>
 #include <linux/ratelimit.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 #include <asm/hardirq.h>
+#include <asm/traps.h>
 
 
 /* #define DEBUG_UNALIGNED 1 */
 /* #define DEBUG_UNALIGNED 1 */
 
 
@@ -130,8 +131,6 @@
 
 
 int unaligned_enabled __read_mostly = 1;
 int unaligned_enabled __read_mostly = 1;
 
 
-void die_if_kernel (char *str, struct pt_regs *regs, long err);
-
 static int emulate_ldh(struct pt_regs *regs, int toreg)
 static int emulate_ldh(struct pt_regs *regs, int toreg)
 {
 {
 	unsigned long saddr = regs->ior;
 	unsigned long saddr = regs->ior;
@@ -666,7 +665,7 @@ void handle_unaligned(struct pt_regs *regs)
 		break;
 		break;
 	}
 	}
 
 
-	if (modify && R1(regs->iir))
+	if (ret == 0 && modify && R1(regs->iir))
 		regs->gr[R1(regs->iir)] = newbase;
 		regs->gr[R1(regs->iir)] = newbase;
 
 
 
 
@@ -677,6 +676,14 @@ void handle_unaligned(struct pt_regs *regs)
 
 
 	if (ret)
 	if (ret)
 	{
 	{
+		/*
+		 * The unaligned handler failed.
+		 * If we were called by __get_user() or __put_user() jump
+		 * to it's exception fixup handler instead of crashing.
+		 */
+		if (!user_mode(regs) && fixup_exception(regs))
+			return;
+
 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
 		die_if_kernel("Unaligned data reference", regs, 28);
 		die_if_kernel("Unaligned data reference", regs, 28);
 
 

+ 14 - 8
arch/parisc/kernel/unwind.c

@@ -75,7 +75,10 @@ find_unwind_entry(unsigned long addr)
 	if (addr >= kernel_unwind_table.start && 
 	if (addr >= kernel_unwind_table.start && 
 	    addr <= kernel_unwind_table.end)
 	    addr <= kernel_unwind_table.end)
 		e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
 		e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
-	else 
+	else {
+		unsigned long flags;
+
+		spin_lock_irqsave(&unwind_lock, flags);
 		list_for_each_entry(table, &unwind_tables, list) {
 		list_for_each_entry(table, &unwind_tables, list) {
 			if (addr >= table->start && 
 			if (addr >= table->start && 
 			    addr <= table->end)
 			    addr <= table->end)
@@ -86,6 +89,8 @@ find_unwind_entry(unsigned long addr)
 				break;
 				break;
 			}
 			}
 		}
 		}
+		spin_unlock_irqrestore(&unwind_lock, flags);
+	}
 
 
 	return e;
 	return e;
 }
 }
@@ -303,18 +308,16 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
 
 
 			insn = *(unsigned int *)npc;
 			insn = *(unsigned int *)npc;
 
 
-			if ((insn & 0xffffc000) == 0x37de0000 ||
-			    (insn & 0xffe00000) == 0x6fc00000) {
+			if ((insn & 0xffffc001) == 0x37de0000 ||
+			    (insn & 0xffe00001) == 0x6fc00000) {
 				/* ldo X(sp), sp, or stwm X,D(sp) */
 				/* ldo X(sp), sp, or stwm X,D(sp) */
-				frame_size += (insn & 0x1 ? -1 << 13 : 0) | 
-					((insn & 0x3fff) >> 1);
+				frame_size += (insn & 0x3fff) >> 1;
 				dbg("analyzing func @ %lx, insn=%08x @ "
 				dbg("analyzing func @ %lx, insn=%08x @ "
 				    "%lx, frame_size = %ld\n", info->ip,
 				    "%lx, frame_size = %ld\n", info->ip,
 				    insn, npc, frame_size);
 				    insn, npc, frame_size);
-			} else if ((insn & 0xffe00008) == 0x73c00008) {
+			} else if ((insn & 0xffe00009) == 0x73c00008) {
 				/* std,ma X,D(sp) */
 				/* std,ma X,D(sp) */
-				frame_size += (insn & 0x1 ? -1 << 13 : 0) | 
-					(((insn >> 4) & 0x3ff) << 3);
+				frame_size += ((insn >> 4) & 0x3ff) << 3;
 				dbg("analyzing func @ %lx, insn=%08x @ "
 				dbg("analyzing func @ %lx, insn=%08x @ "
 				    "%lx, frame_size = %ld\n", info->ip,
 				    "%lx, frame_size = %ld\n", info->ip,
 				    insn, npc, frame_size);
 				    insn, npc, frame_size);
@@ -333,6 +336,9 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
 			}
 			}
 		}
 		}
 
 
+		if (frame_size > e->Total_frame_size << 3)
+			frame_size = e->Total_frame_size << 3;
+
 		if (!unwind_special(info, e->region_start, frame_size)) {
 		if (!unwind_special(info, e->region_start, frame_size)) {
 			info->prev_sp = info->sp - frame_size;
 			info->prev_sp = info->sp - frame_size;
 			if (e->Millicode)
 			if (e->Millicode)

+ 3 - 3
arch/powerpc/include/asm/reg.h

@@ -717,7 +717,7 @@
 #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
 #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
 #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
 #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
 #define SPRN_MMCR1	798
 #define SPRN_MMCR1	798
-#define SPRN_MMCR2	769
+#define SPRN_MMCR2	785
 #define SPRN_MMCRA	0x312
 #define SPRN_MMCRA	0x312
 #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
 #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
 #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
 #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
@@ -754,13 +754,13 @@
 #define SPRN_PMC6	792
 #define SPRN_PMC6	792
 #define SPRN_PMC7	793
 #define SPRN_PMC7	793
 #define SPRN_PMC8	794
 #define SPRN_PMC8	794
-#define SPRN_SIAR	780
-#define SPRN_SDAR	781
 #define SPRN_SIER	784
 #define SPRN_SIER	784
 #define   SIER_SIPR		0x2000000	/* Sampled MSR_PR */
 #define   SIER_SIPR		0x2000000	/* Sampled MSR_PR */
 #define   SIER_SIHV		0x1000000	/* Sampled MSR_HV */
 #define   SIER_SIHV		0x1000000	/* Sampled MSR_HV */
 #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
 #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
 #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
 #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
+#define SPRN_SIAR	796
+#define SPRN_SDAR	797
 #define SPRN_TACR	888
 #define SPRN_TACR	888
 #define SPRN_TCSCR	889
 #define SPRN_TCSCR	889
 #define SPRN_CSIGR	890
 #define SPRN_CSIGR	890

+ 1 - 0
arch/powerpc/kernel/prom_init.c

@@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
 	W(0xffff0000), W(0x003f0000),	/* POWER7 */
 	W(0xffff0000), W(0x003f0000),	/* POWER7 */
 	W(0xffff0000), W(0x004b0000),	/* POWER8E */
 	W(0xffff0000), W(0x004b0000),	/* POWER8E */
+	W(0xffff0000), W(0x004c0000),   /* POWER8NVL */
 	W(0xffff0000), W(0x004d0000),	/* POWER8 */
 	W(0xffff0000), W(0x004d0000),	/* POWER8 */
 	W(0xffffffff), W(0x0f000004),	/* all 2.07-compliant */
 	W(0xffffffff), W(0x0f000004),	/* all 2.07-compliant */
 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */
 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */

+ 20 - 2
arch/powerpc/mm/hash_utils_64.c

@@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
 	},
 	},
 };
 };
 
 
+/*
+ * 'R' and 'C' update notes:
+ *  - Under pHyp or KVM, the updatepp path will not set C, thus it *will*
+ *     create writeable HPTEs without C set, because the hcall H_PROTECT
+ *     that we use in that case will not update C
+ *  - The above is however not a problem, because we also don't do that
+ *     fancy "no flush" variant of eviction and we use H_REMOVE which will
+ *     do the right thing and thus we don't have the race I described earlier
+ *
+ *    - Under bare metal,  we do have the race, so we need R and C set
+ *    - We make sure R is always set and never lost
+ *    - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping
+ */
 unsigned long htab_convert_pte_flags(unsigned long pteflags)
 unsigned long htab_convert_pte_flags(unsigned long pteflags)
 {
 {
 	unsigned long rflags = 0;
 	unsigned long rflags = 0;
@@ -186,9 +199,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
 			rflags |= 0x1;
 			rflags |= 0x1;
 	}
 	}
 	/*
 	/*
-	 * Always add "C" bit for perf. Memory coherence is always enabled
+	 * We can't allow hardware to update hpte bits. Hence always
+	 * set 'R' bit and set 'C' if it is a write fault
+	 * Memory coherence is always enabled
 	 */
 	 */
-	rflags |=  HPTE_R_C | HPTE_R_M;
+	rflags |=  HPTE_R_R | HPTE_R_M;
+
+	if (pteflags & _PAGE_DIRTY)
+		rflags |= HPTE_R_C;
 	/*
 	/*
 	 * Add in WIG bits
 	 * Add in WIG bits
 	 */
 	 */

+ 1 - 4
arch/powerpc/mm/pgtable-book3s64.c

@@ -33,10 +33,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 	changed = !pmd_same(*(pmdp), entry);
 	changed = !pmd_same(*(pmdp), entry);
 	if (changed) {
 	if (changed) {
 		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
 		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
-		/*
-		 * Since we are not supporting SW TLB systems, we don't
-		 * have any thing similar to flush_tlb_page_nohash()
-		 */
+		flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	}
 	}
 	return changed;
 	return changed;
 }
 }

+ 10 - 13
arch/powerpc/mm/pgtable-radix.c

@@ -296,11 +296,6 @@ found:
 void __init radix__early_init_mmu(void)
 void __init radix__early_init_mmu(void)
 {
 {
 	unsigned long lpcr;
 	unsigned long lpcr;
-	/*
-	 * setup LPCR UPRT based on mmu_features
-	 */
-	lpcr = mfspr(SPRN_LPCR);
-	mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
 
 
 #ifdef CONFIG_PPC_64K_PAGES
 #ifdef CONFIG_PPC_64K_PAGES
 	/* PAGE_SIZE mappings */
 	/* PAGE_SIZE mappings */
@@ -343,8 +338,11 @@ void __init radix__early_init_mmu(void)
 	__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
 	__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
 
 
 	radix_init_page_sizes();
 	radix_init_page_sizes();
-	if (!firmware_has_feature(FW_FEATURE_LPAR))
+	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+		lpcr = mfspr(SPRN_LPCR);
+		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
 		radix_init_partition_table();
 		radix_init_partition_table();
+	}
 
 
 	radix_init_pgtable();
 	radix_init_pgtable();
 }
 }
@@ -353,16 +351,15 @@ void radix__early_init_mmu_secondary(void)
 {
 {
 	unsigned long lpcr;
 	unsigned long lpcr;
 	/*
 	/*
-	 * setup LPCR UPRT based on mmu_features
+	 * update partition table control register and UPRT
 	 */
 	 */
-	lpcr = mfspr(SPRN_LPCR);
-	mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
-	/*
-	 * update partition table control register, 64 K size.
-	 */
-	if (!firmware_has_feature(FW_FEATURE_LPAR))
+	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+		lpcr = mfspr(SPRN_LPCR);
+		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
+
 		mtspr(SPRN_PTCR,
 		mtspr(SPRN_PTCR,
 		      __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
 		      __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+	}
 }
 }
 
 
 void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
 void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,

+ 1 - 1
arch/powerpc/platforms/512x/clock-commonclk.c

@@ -221,7 +221,7 @@ static bool soc_has_mclk_mux0_canin(void)
 /* convenience wrappers around the common clk API */
 /* convenience wrappers around the common clk API */
 static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)
 static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)
 {
 {
-	return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+	return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
 }
 }
 
 
 static inline struct clk *mpc512x_clk_factor(
 static inline struct clk *mpc512x_clk_factor(

+ 1 - 1
arch/powerpc/platforms/cell/spufs/coredump.c

@@ -172,7 +172,7 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i,
 	if (rc < 0)
 	if (rc < 0)
 		goto out;
 		goto out;
 
 
-	skip = roundup(cprm->file->f_pos - total + sz, 4) - cprm->file->f_pos;
+	skip = roundup(cprm->pos - total + sz, 4) - cprm->pos;
 	if (!dump_skip(cprm, skip))
 	if (!dump_skip(cprm, skip))
 		goto Eio;
 		goto Eio;
 out:
 out:

+ 33 - 16
arch/powerpc/platforms/pseries/eeh_pseries.c

@@ -53,7 +53,6 @@ static int ibm_read_slot_reset_state2;
 static int ibm_slot_error_detail;
 static int ibm_slot_error_detail;
 static int ibm_get_config_addr_info;
 static int ibm_get_config_addr_info;
 static int ibm_get_config_addr_info2;
 static int ibm_get_config_addr_info2;
-static int ibm_configure_bridge;
 static int ibm_configure_pe;
 static int ibm_configure_pe;
 
 
 /*
 /*
@@ -81,7 +80,14 @@ static int pseries_eeh_init(void)
 	ibm_get_config_addr_info2	= rtas_token("ibm,get-config-addr-info2");
 	ibm_get_config_addr_info2	= rtas_token("ibm,get-config-addr-info2");
 	ibm_get_config_addr_info	= rtas_token("ibm,get-config-addr-info");
 	ibm_get_config_addr_info	= rtas_token("ibm,get-config-addr-info");
 	ibm_configure_pe		= rtas_token("ibm,configure-pe");
 	ibm_configure_pe		= rtas_token("ibm,configure-pe");
-	ibm_configure_bridge		= rtas_token("ibm,configure-bridge");
+
+	/*
+	 * ibm,configure-pe and ibm,configure-bridge have the same semantics,
+	 * however ibm,configure-pe can be faster.  If we can't find
+	 * ibm,configure-pe then fall back to using ibm,configure-bridge.
+	 */
+	if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
+		ibm_configure_pe 	= rtas_token("ibm,configure-bridge");
 
 
 	/*
 	/*
 	 * Necessary sanity check. We needn't check "get-config-addr-info"
 	 * Necessary sanity check. We needn't check "get-config-addr-info"
@@ -93,8 +99,7 @@ static int pseries_eeh_init(void)
 	    (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
 	    (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
 	     ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE)	||
 	     ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE)	||
 	    ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE	||
 	    ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE	||
-	    (ibm_configure_pe == RTAS_UNKNOWN_SERVICE		&&
-	     ibm_configure_bridge == RTAS_UNKNOWN_SERVICE)) {
+	    ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
 		pr_info("EEH functionality not supported\n");
 		pr_info("EEH functionality not supported\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -615,29 +620,41 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
 {
 {
 	int config_addr;
 	int config_addr;
 	int ret;
 	int ret;
+	/* Waiting 0.2s maximum before skipping configuration */
+	int max_wait = 200;
 
 
 	/* Figure out the PE address */
 	/* Figure out the PE address */
 	config_addr = pe->config_addr;
 	config_addr = pe->config_addr;
 	if (pe->addr)
 	if (pe->addr)
 		config_addr = pe->addr;
 		config_addr = pe->addr;
 
 
-	/* Use new configure-pe function, if supported */
-	if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
+	while (max_wait > 0) {
 		ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
 		ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
 				config_addr, BUID_HI(pe->phb->buid),
 				config_addr, BUID_HI(pe->phb->buid),
 				BUID_LO(pe->phb->buid));
 				BUID_LO(pe->phb->buid));
-	} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
-		ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
-				config_addr, BUID_HI(pe->phb->buid),
-				BUID_LO(pe->phb->buid));
-	} else {
-		return -EFAULT;
-	}
 
 
-	if (ret)
-		pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
-			__func__, pe->phb->global_number, pe->addr, ret);
+		if (!ret)
+			return ret;
+
+		/*
+		 * If RTAS returns a delay value that's above 100ms, cut it
+		 * down to 100ms in case firmware made a mistake.  For more
+		 * on how these delay values work see rtas_busy_delay_time
+		 */
+		if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
+		    ret <= RTAS_EXTENDED_DELAY_MAX)
+			ret = RTAS_EXTENDED_DELAY_MIN+2;
+
+		max_wait -= rtas_busy_delay_time(ret);
+
+		if (max_wait < 0)
+			break;
+
+		rtas_busy_delay(ret);
+	}
 
 
+	pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
+		__func__, pe->phb->global_number, pe->addr, ret);
 	return ret;
 	return ret;
 }
 }
 
 

+ 12 - 10
arch/x86/kvm/cpuid.c

@@ -181,19 +181,22 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 			     struct kvm_cpuid_entry __user *entries)
 			     struct kvm_cpuid_entry __user *entries)
 {
 {
 	int r, i;
 	int r, i;
-	struct kvm_cpuid_entry *cpuid_entries;
+	struct kvm_cpuid_entry *cpuid_entries = NULL;
 
 
 	r = -E2BIG;
 	r = -E2BIG;
 	if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
 	if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
 		goto out;
 		goto out;
 	r = -ENOMEM;
 	r = -ENOMEM;
-	cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
-	if (!cpuid_entries)
-		goto out;
-	r = -EFAULT;
-	if (copy_from_user(cpuid_entries, entries,
-			   cpuid->nent * sizeof(struct kvm_cpuid_entry)))
-		goto out_free;
+	if (cpuid->nent) {
+		cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) *
+					cpuid->nent);
+		if (!cpuid_entries)
+			goto out;
+		r = -EFAULT;
+		if (copy_from_user(cpuid_entries, entries,
+				   cpuid->nent * sizeof(struct kvm_cpuid_entry)))
+			goto out;
+	}
 	for (i = 0; i < cpuid->nent; i++) {
 	for (i = 0; i < cpuid->nent; i++) {
 		vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
 		vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
 		vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
 		vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -212,9 +215,8 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 	kvm_x86_ops->cpuid_update(vcpu);
 	kvm_x86_ops->cpuid_update(vcpu);
 	r = kvm_update_cpuid(vcpu);
 	r = kvm_update_cpuid(vcpu);
 
 
-out_free:
-	vfree(cpuid_entries);
 out:
 out:
+	vfree(cpuid_entries);
 	return r;
 	return r;
 }
 }
 
 

+ 4 - 4
arch/x86/kvm/mmu.c

@@ -336,12 +336,12 @@ static gfn_t pse36_gfn_delta(u32 gpte)
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64
 static void __set_spte(u64 *sptep, u64 spte)
 static void __set_spte(u64 *sptep, u64 spte)
 {
 {
-	*sptep = spte;
+	WRITE_ONCE(*sptep, spte);
 }
 }
 
 
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
 {
 {
-	*sptep = spte;
+	WRITE_ONCE(*sptep, spte);
 }
 }
 
 
 static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
 static u64 __update_clear_spte_slow(u64 *sptep, u64 spte)
@@ -390,7 +390,7 @@ static void __set_spte(u64 *sptep, u64 spte)
 	 */
 	 */
 	smp_wmb();
 	smp_wmb();
 
 
-	ssptep->spte_low = sspte.spte_low;
+	WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
 }
 }
 
 
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
 static void __update_clear_spte_fast(u64 *sptep, u64 spte)
@@ -400,7 +400,7 @@ static void __update_clear_spte_fast(u64 *sptep, u64 spte)
 	ssptep = (union split_spte *)sptep;
 	ssptep = (union split_spte *)sptep;
 	sspte = (union split_spte)spte;
 	sspte = (union split_spte)spte;
 
 
-	ssptep->spte_low = sspte.spte_low;
+	WRITE_ONCE(ssptep->spte_low, sspte.spte_low);
 
 
 	/*
 	/*
 	 * If we map the spte from present to nonpresent, we should clear
 	 * If we map the spte from present to nonpresent, we should clear

+ 11 - 1
arch/x86/kvm/x86.c

@@ -2314,6 +2314,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_AMD64_NB_CFG:
 	case MSR_AMD64_NB_CFG:
 	case MSR_FAM10H_MMIO_CONF_BASE:
 	case MSR_FAM10H_MMIO_CONF_BASE:
 	case MSR_AMD64_BU_CFG2:
 	case MSR_AMD64_BU_CFG2:
+	case MSR_IA32_PERF_CTL:
 		msr_info->data = 0;
 		msr_info->data = 0;
 		break;
 		break;
 	case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
 	case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
@@ -2972,6 +2973,10 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
 			      | KVM_VCPUEVENT_VALID_SMM))
 			      | KVM_VCPUEVENT_VALID_SMM))
 		return -EINVAL;
 		return -EINVAL;
 
 
+	if (events->exception.injected &&
+	    (events->exception.nr > 31 || events->exception.nr == NMI_VECTOR))
+		return -EINVAL;
+
 	process_nmi(vcpu);
 	process_nmi(vcpu);
 	vcpu->arch.exception.pending = events->exception.injected;
 	vcpu->arch.exception.pending = events->exception.injected;
 	vcpu->arch.exception.nr = events->exception.nr;
 	vcpu->arch.exception.nr = events->exception.nr;
@@ -3036,6 +3041,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
 	if (dbgregs->flags)
 	if (dbgregs->flags)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	if (dbgregs->dr6 & ~0xffffffffull)
+		return -EINVAL;
+	if (dbgregs->dr7 & ~0xffffffffull)
+		return -EINVAL;
+
 	memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
 	memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
 	kvm_update_dr0123(vcpu);
 	kvm_update_dr0123(vcpu);
 	vcpu->arch.dr6 = dbgregs->dr6;
 	vcpu->arch.dr6 = dbgregs->dr6;
@@ -7815,7 +7825,7 @@ int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size)
 
 
 	slot = id_to_memslot(slots, id);
 	slot = id_to_memslot(slots, id);
 	if (size) {
 	if (size) {
-		if (WARN_ON(slot->npages))
+		if (slot->npages)
 			return -EEXIST;
 			return -EEXIST;
 
 
 		/*
 		/*

+ 0 - 9
drivers/acpi/acpi_processor.c

@@ -331,15 +331,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
 		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
 		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
 
 
 		pr->pblk = object.processor.pblk_address;
 		pr->pblk = object.processor.pblk_address;
-
-		/*
-		 * We don't care about error returns - we just try to mark
-		 * these reserved so that nobody else is confused into thinking
-		 * that this region might be unused..
-		 *
-		 * (In particular, allocating the IO range for Cardbus)
-		 */
-		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
 	}
 	}
 
 
 	/*
 	/*

+ 6 - 3
drivers/acpi/acpi_video.c

@@ -754,7 +754,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device,
 }
 }
 
 
 int acpi_video_get_levels(struct acpi_device *device,
 int acpi_video_get_levels(struct acpi_device *device,
-			  struct acpi_video_device_brightness **dev_br)
+			  struct acpi_video_device_brightness **dev_br,
+			  int *pmax_level)
 {
 {
 	union acpi_object *obj = NULL;
 	union acpi_object *obj = NULL;
 	int i, max_level = 0, count = 0, level_ac_battery = 0;
 	int i, max_level = 0, count = 0, level_ac_battery = 0;
@@ -841,6 +842,8 @@ int acpi_video_get_levels(struct acpi_device *device,
 
 
 	br->count = count;
 	br->count = count;
 	*dev_br = br;
 	*dev_br = br;
+	if (pmax_level)
+		*pmax_level = max_level;
 
 
 out:
 out:
 	kfree(obj);
 	kfree(obj);
@@ -869,7 +872,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
 	struct acpi_video_device_brightness *br = NULL;
 	struct acpi_video_device_brightness *br = NULL;
 	int result = -EINVAL;
 	int result = -EINVAL;
 
 
-	result = acpi_video_get_levels(device->dev, &br);
+	result = acpi_video_get_levels(device->dev, &br, &max_level);
 	if (result)
 	if (result)
 		return result;
 		return result;
 	device->brightness = br;
 	device->brightness = br;
@@ -1737,7 +1740,7 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)
 
 
 	mutex_lock(&video->device_list_lock);
 	mutex_lock(&video->device_list_lock);
 	list_for_each_entry(dev, &video->video_device_list, entry) {
 	list_for_each_entry(dev, &video->video_device_list, entry) {
-		if (!acpi_video_device_lcd_query_levels(dev, &levels))
+		if (!acpi_video_device_lcd_query_levels(dev->dev->handle, &levels))
 			kfree(levels);
 			kfree(levels);
 	}
 	}
 	mutex_unlock(&video->device_list_lock);
 	mutex_unlock(&video->device_list_lock);

+ 9 - 14
drivers/acpi/acpica/hwregs.c

@@ -83,27 +83,22 @@ acpi_hw_write_multiple(u32 value,
 static u8
 static u8
 acpi_hw_get_access_bit_width(struct acpi_generic_address *reg, u8 max_bit_width)
 acpi_hw_get_access_bit_width(struct acpi_generic_address *reg, u8 max_bit_width)
 {
 {
-	u64 address;
-
 	if (!reg->access_width) {
 	if (!reg->access_width) {
+		if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+			max_bit_width = 32;
+		}
+
 		/*
 		/*
 		 * Detect old register descriptors where only the bit_width field
 		 * Detect old register descriptors where only the bit_width field
-		 * makes senses. The target address is copied to handle possible
-		 * alignment issues.
+		 * makes senses.
 		 */
 		 */
-		ACPI_MOVE_64_TO_64(&address, &reg->address);
-		if (!reg->bit_offset && reg->bit_width &&
+		if (reg->bit_width < max_bit_width &&
+		    !reg->bit_offset && reg->bit_width &&
 		    ACPI_IS_POWER_OF_TWO(reg->bit_width) &&
 		    ACPI_IS_POWER_OF_TWO(reg->bit_width) &&
-		    ACPI_IS_ALIGNED(reg->bit_width, 8) &&
-		    ACPI_IS_ALIGNED(address, reg->bit_width)) {
+		    ACPI_IS_ALIGNED(reg->bit_width, 8)) {
 			return (reg->bit_width);
 			return (reg->bit_width);
-		} else {
-			if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
-				return (32);
-			} else {
-				return (max_bit_width);
-			}
 		}
 		}
+		return (max_bit_width);
 	} else {
 	} else {
 		return (1 << (reg->access_width + 2));
 		return (1 << (reg->access_width + 2));
 	}
 	}

+ 9 - 0
drivers/acpi/processor_throttling.c

@@ -676,6 +676,15 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
 	if (!pr->flags.throttling)
 	if (!pr->flags.throttling)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	/*
+	 * We don't care about error returns - we just try to mark
+	 * these reserved so that nobody else is confused into thinking
+	 * that this region might be unused..
+	 *
+	 * (In particular, allocating the IO range for Cardbus)
+	 */
+	request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+
 	pr->throttling.state = 0;
 	pr->throttling.state = 0;
 
 
 	duty_mask = pr->throttling.state_count - 1;
 	duty_mask = pr->throttling.state_count - 1;

+ 1 - 0
drivers/clk/Kconfig

@@ -175,6 +175,7 @@ config COMMON_CLK_KEYSTONE
 config COMMON_CLK_NXP
 config COMMON_CLK_NXP
 	def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
 	def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
 	select REGMAP_MMIO if ARCH_LPC32XX
 	select REGMAP_MMIO if ARCH_LPC32XX
+	select MFD_SYSCON if ARCH_LPC18XX
 	---help---
 	---help---
 	  Support for clock providers on NXP platforms.
 	  Support for clock providers on NXP platforms.
 
 

+ 5 - 5
drivers/clk/microchip/clk-pic32mzda.c

@@ -180,15 +180,15 @@ static int pic32mzda_clk_probe(struct platform_device *pdev)
 
 
 	/* register fixed rate clocks */
 	/* register fixed rate clocks */
 	clks[POSCCLK] = clk_register_fixed_rate(&pdev->dev, "posc_clk", NULL,
 	clks[POSCCLK] = clk_register_fixed_rate(&pdev->dev, "posc_clk", NULL,
-						CLK_IS_ROOT, 24000000);
+						0, 24000000);
 	clks[FRCCLK] =  clk_register_fixed_rate(&pdev->dev, "frc_clk", NULL,
 	clks[FRCCLK] =  clk_register_fixed_rate(&pdev->dev, "frc_clk", NULL,
-						CLK_IS_ROOT, 8000000);
+						0, 8000000);
 	clks[BFRCCLK] = clk_register_fixed_rate(&pdev->dev, "bfrc_clk", NULL,
 	clks[BFRCCLK] = clk_register_fixed_rate(&pdev->dev, "bfrc_clk", NULL,
-						CLK_IS_ROOT, 8000000);
+						0, 8000000);
 	clks[LPRCCLK] = clk_register_fixed_rate(&pdev->dev, "lprc_clk", NULL,
 	clks[LPRCCLK] = clk_register_fixed_rate(&pdev->dev, "lprc_clk", NULL,
-						CLK_IS_ROOT, 32000);
+						0, 32000);
 	clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL,
 	clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL,
-						CLK_IS_ROOT, 24000000);
+						0, 24000000);
 	/* fixed rate (optional) clock */
 	/* fixed rate (optional) clock */
 	if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) {
 	if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) {
 		pr_info("pic32-clk: dt requests SOSC.\n");
 		pr_info("pic32-clk: dt requests SOSC.\n");

+ 1 - 1
drivers/cpufreq/cpufreq.c

@@ -1832,7 +1832,7 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier);
 unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
 unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
 					unsigned int target_freq)
 					unsigned int target_freq)
 {
 {
-	clamp_val(target_freq, policy->min, policy->max);
+	target_freq = clamp_val(target_freq, policy->min, policy->max);
 
 
 	return cpufreq_driver->fast_switch(policy, target_freq);
 	return cpufreq_driver->fast_switch(policy, target_freq);
 }
 }

+ 1 - 1
drivers/cpufreq/intel_pstate.c

@@ -449,7 +449,7 @@ static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
 		cpu->acpi_perf_data.states[0].core_frequency =
 		cpu->acpi_perf_data.states[0].core_frequency =
 					policy->cpuinfo.max_freq / 1000;
 					policy->cpuinfo.max_freq / 1000;
 	cpu->valid_pss_table = true;
 	cpu->valid_pss_table = true;
-	pr_info("_PPC limits will be enforced\n");
+	pr_debug("_PPC limits will be enforced\n");
 
 
 	return;
 	return;
 
 

+ 2 - 1
drivers/edac/edac_mc.c

@@ -565,7 +565,8 @@ void edac_mc_reset_delay_period(unsigned long value)
 	list_for_each(item, &mc_devices) {
 	list_for_each(item, &mc_devices) {
 		mci = list_entry(item, struct mem_ctl_info, link);
 		mci = list_entry(item, struct mem_ctl_info, link);
 
 
-		edac_mod_work(&mci->work, value);
+		if (mci->op_state == OP_RUNNING_POLL)
+			edac_mod_work(&mci->work, value);
 	}
 	}
 	mutex_unlock(&mem_ctls_mutex);
 	mutex_unlock(&mem_ctls_mutex);
 }
 }

+ 22 - 13
drivers/edac/sb_edac.c

@@ -239,8 +239,11 @@ static const u32 rir_offset[MAX_RIR_RANGES][MAX_RIR_WAY] = {
 	{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
 	{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
 };
 };
 
 
-#define RIR_RNK_TGT(reg)		GET_BITFIELD(reg, 16, 19)
-#define RIR_OFFSET(reg)		GET_BITFIELD(reg,  2, 14)
+#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \
+	GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19))
+
+#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \
+	GET_BITFIELD(reg,  2, 15) : GET_BITFIELD(reg,  2, 14))
 
 
 /* Device 16, functions 2-7 */
 /* Device 16, functions 2-7 */
 
 
@@ -326,6 +329,7 @@ struct pci_id_descr {
 struct pci_id_table {
 struct pci_id_table {
 	const struct pci_id_descr	*descr;
 	const struct pci_id_descr	*descr;
 	int				n_devs;
 	int				n_devs;
+	enum type			type;
 };
 };
 
 
 struct sbridge_dev {
 struct sbridge_dev {
@@ -394,9 +398,14 @@ static const struct pci_id_descr pci_dev_descr_sbridge[] = {
 	{ PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_BR, 0)		},
 	{ PCI_DESCR(PCI_DEVICE_ID_INTEL_SBRIDGE_BR, 0)		},
 };
 };
 
 
-#define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) }
+#define PCI_ID_TABLE_ENTRY(A, T) {	\
+	.descr = A,			\
+	.n_devs = ARRAY_SIZE(A),	\
+	.type = T			\
+}
+
 static const struct pci_id_table pci_dev_descr_sbridge_table[] = {
 static const struct pci_id_table pci_dev_descr_sbridge_table[] = {
-	PCI_ID_TABLE_ENTRY(pci_dev_descr_sbridge),
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_sbridge, SANDY_BRIDGE),
 	{0,}			/* 0 terminated list. */
 	{0,}			/* 0 terminated list. */
 };
 };
 
 
@@ -463,7 +472,7 @@ static const struct pci_id_descr pci_dev_descr_ibridge[] = {
 };
 };
 
 
 static const struct pci_id_table pci_dev_descr_ibridge_table[] = {
 static const struct pci_id_table pci_dev_descr_ibridge_table[] = {
-	PCI_ID_TABLE_ENTRY(pci_dev_descr_ibridge),
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_ibridge, IVY_BRIDGE),
 	{0,}			/* 0 terminated list. */
 	{0,}			/* 0 terminated list. */
 };
 };
 
 
@@ -536,7 +545,7 @@ static const struct pci_id_descr pci_dev_descr_haswell[] = {
 };
 };
 
 
 static const struct pci_id_table pci_dev_descr_haswell_table[] = {
 static const struct pci_id_table pci_dev_descr_haswell_table[] = {
-	PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell),
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell, HASWELL),
 	{0,}			/* 0 terminated list. */
 	{0,}			/* 0 terminated list. */
 };
 };
 
 
@@ -580,7 +589,7 @@ static const struct pci_id_descr pci_dev_descr_knl[] = {
 };
 };
 
 
 static const struct pci_id_table pci_dev_descr_knl_table[] = {
 static const struct pci_id_table pci_dev_descr_knl_table[] = {
-	PCI_ID_TABLE_ENTRY(pci_dev_descr_knl),
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_knl, KNIGHTS_LANDING),
 	{0,}
 	{0,}
 };
 };
 
 
@@ -648,7 +657,7 @@ static const struct pci_id_descr pci_dev_descr_broadwell[] = {
 };
 };
 
 
 static const struct pci_id_table pci_dev_descr_broadwell_table[] = {
 static const struct pci_id_table pci_dev_descr_broadwell_table[] = {
-	PCI_ID_TABLE_ENTRY(pci_dev_descr_broadwell),
+	PCI_ID_TABLE_ENTRY(pci_dev_descr_broadwell, BROADWELL),
 	{0,}			/* 0 terminated list. */
 	{0,}			/* 0 terminated list. */
 };
 };
 
 
@@ -1894,14 +1903,14 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
 				pci_read_config_dword(pvt->pci_tad[i],
 				pci_read_config_dword(pvt->pci_tad[i],
 						      rir_offset[j][k],
 						      rir_offset[j][k],
 						      &reg);
 						      &reg);
-				tmp_mb = RIR_OFFSET(reg) << 6;
+				tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6;
 
 
 				gb = div_u64_rem(tmp_mb, 1024, &mb);
 				gb = div_u64_rem(tmp_mb, 1024, &mb);
 				edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
 				edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
 					 i, j, k,
 					 i, j, k,
 					 gb, (mb*1000)/1024,
 					 gb, (mb*1000)/1024,
 					 ((u64)tmp_mb) << 20L,
 					 ((u64)tmp_mb) << 20L,
-					 (u32)RIR_RNK_TGT(reg),
+					 (u32)RIR_RNK_TGT(pvt->info.type, reg),
 					 reg);
 					 reg);
 			}
 			}
 		}
 		}
@@ -2234,7 +2243,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
 	pci_read_config_dword(pvt->pci_tad[ch_add + base_ch],
 	pci_read_config_dword(pvt->pci_tad[ch_add + base_ch],
 			      rir_offset[n_rir][idx],
 			      rir_offset[n_rir][idx],
 			      &reg);
 			      &reg);
-	*rank = RIR_RNK_TGT(reg);
+	*rank = RIR_RNK_TGT(pvt->info.type, reg);
 
 
 	edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
 	edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
 		 n_rir,
 		 n_rir,
@@ -3357,12 +3366,12 @@ fail0:
 #define ICPU(model, table) \
 #define ICPU(model, table) \
 	{ X86_VENDOR_INTEL, 6, model, 0, (unsigned long)&table }
 	{ X86_VENDOR_INTEL, 6, model, 0, (unsigned long)&table }
 
 
-/* Order here must match "enum type" */
 static const struct x86_cpu_id sbridge_cpuids[] = {
 static const struct x86_cpu_id sbridge_cpuids[] = {
 	ICPU(0x2d, pci_dev_descr_sbridge_table),	/* SANDY_BRIDGE */
 	ICPU(0x2d, pci_dev_descr_sbridge_table),	/* SANDY_BRIDGE */
 	ICPU(0x3e, pci_dev_descr_ibridge_table),	/* IVY_BRIDGE */
 	ICPU(0x3e, pci_dev_descr_ibridge_table),	/* IVY_BRIDGE */
 	ICPU(0x3f, pci_dev_descr_haswell_table),	/* HASWELL */
 	ICPU(0x3f, pci_dev_descr_haswell_table),	/* HASWELL */
 	ICPU(0x4f, pci_dev_descr_broadwell_table),	/* BROADWELL */
 	ICPU(0x4f, pci_dev_descr_broadwell_table),	/* BROADWELL */
+	ICPU(0x56, pci_dev_descr_broadwell_table),	/* BROADWELL-DE */
 	ICPU(0x57, pci_dev_descr_knl_table),		/* KNIGHTS_LANDING */
 	ICPU(0x57, pci_dev_descr_knl_table),		/* KNIGHTS_LANDING */
 	{ }
 	{ }
 };
 };
@@ -3398,7 +3407,7 @@ static int sbridge_probe(const struct x86_cpu_id *id)
 			 mc, mc + 1, num_mc);
 			 mc, mc + 1, num_mc);
 
 
 		sbridge_dev->mc = mc++;
 		sbridge_dev->mc = mc++;
-		rc = sbridge_register_mci(sbridge_dev, id - sbridge_cpuids);
+		rc = sbridge_register_mci(sbridge_dev, ptable->type);
 		if (unlikely(rc < 0))
 		if (unlikely(rc < 0))
 			goto fail1;
 			goto fail1;
 	}
 	}

+ 48 - 38
drivers/gpu/drm/arm/hdlcd_crtc.c

@@ -33,8 +33,17 @@
  *
  *
  */
  */
 
 
+static void hdlcd_crtc_cleanup(struct drm_crtc *crtc)
+{
+	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+	/* stop the controller on cleanup */
+	hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+	drm_crtc_cleanup(crtc);
+}
+
 static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
 static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
-	.destroy = drm_crtc_cleanup,
+	.destroy = hdlcd_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
 	.reset = drm_atomic_helper_crtc_reset,
@@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 	struct drm_display_mode *m = &crtc->state->adjusted_mode;
 	struct drm_display_mode *m = &crtc->state->adjusted_mode;
 	struct videomode vm;
 	struct videomode vm;
-	unsigned int polarities, line_length, err;
+	unsigned int polarities, err;
 
 
 	vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
 	vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
 	vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
 	vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
@@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	if (m->flags & DRM_MODE_FLAG_PVSYNC)
 	if (m->flags & DRM_MODE_FLAG_PVSYNC)
 		polarities |= HDLCD_POLARITY_VSYNC;
 		polarities |= HDLCD_POLARITY_VSYNC;
 
 
-	line_length = crtc->primary->state->fb->pitches[0];
-
 	/* Allow max number of outstanding requests and largest burst size */
 	/* Allow max number of outstanding requests and largest burst size */
 	hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
 	hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
 		    HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
 		    HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
 
 
-	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
-	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
-	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
-	hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
 	hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
 
 
 	err = hdlcd_set_pxl_fmt(crtc);
 	err = hdlcd_set_pxl_fmt(crtc);
@@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 
 
 	clk_prepare_enable(hdlcd->clk);
 	clk_prepare_enable(hdlcd->clk);
+	hdlcd_crtc_mode_set_nofb(crtc);
 	hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
 	hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
-	drm_crtc_vblank_on(crtc);
 }
 }
 
 
 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 {
 {
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 
 
-	if (!crtc->primary->fb)
+	if (!crtc->state->active)
 		return;
 		return;
 
 
-	clk_disable_unprepare(hdlcd->clk);
 	hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
 	hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
-	drm_crtc_vblank_off(crtc);
+	clk_disable_unprepare(hdlcd->clk);
 }
 }
 
 
 static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
 static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
@@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
 static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
 static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
 				    struct drm_crtc_state *state)
 				    struct drm_crtc_state *state)
 {
 {
-	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
 
+	if (event) {
 		crtc->state->event = NULL;
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
-
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
 
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &hdlcd->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 	}
 }
 }
 
 
@@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 				    struct drm_plane_state *state)
 {
 {
+	u32 src_w, src_h;
+
+	src_w = state->src_w >> 16;
+	src_h = state->src_h >> 16;
+
+	/* we can't do any scaling of the plane source */
+	if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+		return -EINVAL;
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
 {
 {
 	struct hdlcd_drm_private *hdlcd;
 	struct hdlcd_drm_private *hdlcd;
 	struct drm_gem_cma_object *gem;
 	struct drm_gem_cma_object *gem;
+	unsigned int depth, bpp;
+	u32 src_w, src_h, dest_w, dest_h;
 	dma_addr_t scanout_start;
 	dma_addr_t scanout_start;
 
 
-	if (!plane->state->crtc || !plane->state->fb)
+	if (!plane->state->fb)
 		return;
 		return;
 
 
-	hdlcd = crtc_to_hdlcd_priv(plane->state->crtc);
+	drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
+	src_w = plane->state->src_w >> 16;
+	src_h = plane->state->src_h >> 16;
+	dest_w = plane->state->crtc_w;
+	dest_h = plane->state->crtc_h;
 	gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
 	gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
-	scanout_start = gem->paddr;
+	scanout_start = gem->paddr + plane->state->fb->offsets[0] +
+		plane->state->crtc_y * plane->state->fb->pitches[0] +
+		plane->state->crtc_x * bpp / 8;
+
+	hdlcd = plane->dev->dev_private;
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]);
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]);
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1);
 	hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
 	hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
 }
 }
 
 
 static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
 static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
-	.prepare_fb = NULL,
-	.cleanup_fb = NULL,
 	.atomic_check = hdlcd_plane_atomic_check,
 	.atomic_check = hdlcd_plane_atomic_check,
 	.atomic_update = hdlcd_plane_atomic_update,
 	.atomic_update = hdlcd_plane_atomic_update,
 };
 };
@@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
 	return plane;
 	return plane;
 }
 }
 
 
-void hdlcd_crtc_suspend(struct drm_crtc *crtc)
-{
-	hdlcd_crtc_disable(crtc);
-}
-
-void hdlcd_crtc_resume(struct drm_crtc *crtc)
-{
-	hdlcd_crtc_enable(crtc);
-}
-
 int hdlcd_setup_crtc(struct drm_device *drm)
 int hdlcd_setup_crtc(struct drm_device *drm)
 {
 {
 	struct hdlcd_drm_private *hdlcd = drm->dev_private;
 	struct hdlcd_drm_private *hdlcd = drm->dev_private;

+ 29 - 39
drivers/gpu/drm/arm/hdlcd_drv.c

@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 	atomic_set(&hdlcd->dma_end_count, 0);
 	atomic_set(&hdlcd->dma_end_count, 0);
 #endif
 #endif
 
 
-	INIT_LIST_HEAD(&hdlcd->event_list);
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
 	hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
 	if (IS_ERR(hdlcd->mmio)) {
 	if (IS_ERR(hdlcd->mmio)) {
@@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 		goto setup_fail;
 		goto setup_fail;
 	}
 	}
 
 
-	pm_runtime_enable(drm->dev);
-
-	pm_runtime_get_sync(drm->dev);
 	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
 	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
-	pm_runtime_put_sync(drm->dev);
 	if (ret < 0) {
 	if (ret < 0) {
 		DRM_ERROR("failed to install IRQ handler\n");
 		DRM_ERROR("failed to install IRQ handler\n");
 		goto irq_fail;
 		goto irq_fail;
@@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
 		atomic_inc(&hdlcd->vsync_count);
 		atomic_inc(&hdlcd->vsync_count);
 
 
 #endif
 #endif
-	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-		bool events_sent = false;
-		unsigned long flags;
-		struct drm_pending_vblank_event	*e, *t;
-
+	if (irq_status & HDLCD_INTERRUPT_VSYNC)
 		drm_crtc_handle_vblank(&hdlcd->crtc);
 		drm_crtc_handle_vblank(&hdlcd->crtc);
 
 
-		spin_lock_irqsave(&drm->event_lock, flags);
-		list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
-			list_del(&e->base.link);
-			drm_crtc_send_vblank_event(&hdlcd->crtc, e);
-			events_sent = true;
-		}
-		if (events_sent)
-			drm_crtc_vblank_put(&hdlcd->crtc);
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-	}
-
 	/* acknowledge interrupt(s) */
 	/* acknowledge interrupt(s) */
 	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
 	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
 
 
@@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg)
 static struct drm_info_list hdlcd_debugfs_list[] = {
 static struct drm_info_list hdlcd_debugfs_list[] = {
 	{ "interrupt_count", hdlcd_show_underrun_count, 0 },
 	{ "interrupt_count", hdlcd_show_underrun_count, 0 },
 	{ "clocks", hdlcd_show_pxlclock, 0 },
 	{ "clocks", hdlcd_show_pxlclock, 0 },
+	{ "fb", drm_fb_cma_debugfs_show, 0 },
 };
 };
 
 
 static int hdlcd_debugfs_init(struct drm_minor *minor)
 static int hdlcd_debugfs_init(struct drm_minor *minor)
@@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	drm->dev_private = hdlcd;
 	drm->dev_private = hdlcd;
+	dev_set_drvdata(dev, drm);
+
 	hdlcd_setup_mode_config(drm);
 	hdlcd_setup_mode_config(drm);
 	ret = hdlcd_load(drm, 0);
 	ret = hdlcd_load(drm, 0);
 	if (ret)
 	if (ret)
@@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev)
 	if (ret)
 	if (ret)
 		goto err_unload;
 		goto err_unload;
 
 
-	dev_set_drvdata(dev, drm);
-
 	ret = component_bind_all(dev, drm);
 	ret = component_bind_all(dev, drm);
 	if (ret) {
 	if (ret) {
 		DRM_ERROR("Failed to bind all components\n");
 		DRM_ERROR("Failed to bind all components\n");
 		goto err_unregister;
 		goto err_unregister;
 	}
 	}
 
 
+	ret = pm_runtime_set_active(dev);
+	if (ret)
+		goto err_pm_active;
+
+	pm_runtime_enable(dev);
+
 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	if (ret < 0) {
 	if (ret < 0) {
 		DRM_ERROR("failed to initialise vblank\n");
 		DRM_ERROR("failed to initialise vblank\n");
@@ -399,16 +385,16 @@ err_fbdev:
 	drm_mode_config_cleanup(drm);
 	drm_mode_config_cleanup(drm);
 	drm_vblank_cleanup(drm);
 	drm_vblank_cleanup(drm);
 err_vblank:
 err_vblank:
+	pm_runtime_disable(drm->dev);
+err_pm_active:
 	component_unbind_all(dev, drm);
 	component_unbind_all(dev, drm);
 err_unregister:
 err_unregister:
 	drm_dev_unregister(drm);
 	drm_dev_unregister(drm);
 err_unload:
 err_unload:
-	pm_runtime_get_sync(drm->dev);
 	drm_irq_uninstall(drm);
 	drm_irq_uninstall(drm);
-	pm_runtime_put_sync(drm->dev);
-	pm_runtime_disable(drm->dev);
 	of_reserved_mem_device_release(drm->dev);
 	of_reserved_mem_device_release(drm->dev);
 err_free:
 err_free:
+	dev_set_drvdata(dev, NULL);
 	drm_dev_unref(drm);
 	drm_dev_unref(drm);
 
 
 	return ret;
 	return ret;
@@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
 static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
 static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
 {
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct drm_crtc *crtc;
+	struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
 
 
-	if (pm_runtime_suspended(dev))
+	if (!hdlcd)
 		return 0;
 		return 0;
 
 
-	drm_modeset_lock_all(drm);
-	list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-		hdlcd_crtc_suspend(crtc);
-	drm_modeset_unlock_all(drm);
+	drm_kms_helper_poll_disable(drm);
+
+	hdlcd->state = drm_atomic_helper_suspend(drm);
+	if (IS_ERR(hdlcd->state)) {
+		drm_kms_helper_poll_enable(drm);
+		return PTR_ERR(hdlcd->state);
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
 static int __maybe_unused hdlcd_pm_resume(struct device *dev)
 static int __maybe_unused hdlcd_pm_resume(struct device *dev)
 {
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct drm_crtc *crtc;
+	struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
 
 
-	if (!pm_runtime_suspended(dev))
+	if (!hdlcd)
 		return 0;
 		return 0;
 
 
-	drm_modeset_lock_all(drm);
-	list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-		hdlcd_crtc_resume(crtc);
-	drm_modeset_unlock_all(drm);
+	drm_atomic_helper_resume(drm, hdlcd->state);
+	drm_kms_helper_poll_enable(drm);
+	pm_runtime_set_active(dev);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 4
drivers/gpu/drm/arm/hdlcd_drv.h

@@ -9,10 +9,9 @@ struct hdlcd_drm_private {
 	void __iomem			*mmio;
 	void __iomem			*mmio;
 	struct clk			*clk;
 	struct clk			*clk;
 	struct drm_fbdev_cma		*fbdev;
 	struct drm_fbdev_cma		*fbdev;
-	struct drm_framebuffer		*fb;
-	struct list_head		event_list;
 	struct drm_crtc			crtc;
 	struct drm_crtc			crtc;
 	struct drm_plane		*plane;
 	struct drm_plane		*plane;
+	struct drm_atomic_state		*state;
 #ifdef CONFIG_DEBUG_FS
 #ifdef CONFIG_DEBUG_FS
 	atomic_t buffer_underrun_count;
 	atomic_t buffer_underrun_count;
 	atomic_t bus_error_count;
 	atomic_t bus_error_count;
@@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg)
 
 
 int hdlcd_setup_crtc(struct drm_device *dev);
 int hdlcd_setup_crtc(struct drm_device *dev);
 void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd);
 void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd);
-void hdlcd_crtc_suspend(struct drm_crtc *crtc);
-void hdlcd_crtc_resume(struct drm_crtc *crtc);
 
 
 #endif /* __HDLCD_DRV_H__ */
 #endif /* __HDLCD_DRV_H__ */

+ 5 - 5
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c

@@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc)
 {
 {
 	struct atmel_hlcdc_crtc_state *state;
 	struct atmel_hlcdc_crtc_state *state;
 
 
-	if (crtc->state && crtc->state->mode_blob)
-		drm_property_unreference_blob(crtc->state->mode_blob);
-
 	if (crtc->state) {
 	if (crtc->state) {
+		__drm_atomic_helper_crtc_destroy_state(crtc->state);
 		state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
 		state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
 		kfree(state);
 		kfree(state);
+		crtc->state = NULL;
 	}
 	}
 
 
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
 		return NULL;
 		return NULL;
 
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
-	if (state)
-		__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+	if (!state)
+		return NULL;
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
 
 
 	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
 	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
 	state->output_mode = cur->output_mode;
 	state->output_mode = cur->output_mode;

+ 2 - 1
drivers/gpu/drm/drm_atomic.c

@@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
 	drm_property_unreference_blob(state->mode_blob);
 	drm_property_unreference_blob(state->mode_blob);
 	state->mode_blob = NULL;
 	state->mode_blob = NULL;
 
 
+	memset(&state->mode, 0, sizeof(state->mode));
+
 	if (blob) {
 	if (blob) {
 		if (blob->length != sizeof(struct drm_mode_modeinfo) ||
 		if (blob->length != sizeof(struct drm_mode_modeinfo) ||
 		    drm_mode_convert_umode(&state->mode,
 		    drm_mode_convert_umode(&state->mode,
@@ -363,7 +365,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
 		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
 		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
 				 state->mode.name, state);
 				 state->mode.name, state);
 	} else {
 	} else {
-		memset(&state->mode, 0, sizeof(state->mode));
 		state->enable = false;
 		state->enable = false;
 		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
 		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
 				 state);
 				 state);

+ 2 - 3
drivers/gpu/drm/drm_crtc.c

@@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			goto out;
 			goto out;
 		}
 		}
 
 
-		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-
 		/*
 		/*
 		 * Check whether the primary plane supports the fb pixel format.
 		 * Check whether the primary plane supports the fb pixel format.
 		 * Drivers not implementing the universal planes API use a
 		 * Drivers not implementing the universal planes API use a
@@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property,
 		if (value == 0)
 		if (value == 0)
 			return true;
 			return true;
 
 
-		return _object_find(property->dev, value, property->values[0]) != NULL;
+		*ref = _object_find(property->dev, value, property->values[0]);
+		return *ref != NULL;
 	}
 	}
 
 
 	for (i = 0; i < property->num_values; i++)
 	for (i = 0; i < property->num_values; i++)

+ 1 - 1
drivers/gpu/drm/drm_fb_cma_helper.c

@@ -445,7 +445,7 @@ err_cma_destroy:
 err_fb_info_destroy:
 err_fb_info_destroy:
 	drm_fb_helper_release_fbi(helper);
 	drm_fb_helper_release_fbi(helper);
 err_gem_free_object:
 err_gem_free_object:
-	dev->driver->gem_free_object(&obj->base);
+	drm_gem_object_unreference_unlocked(&obj->base);
 	return ret;
 	return ret;
 }
 }
 EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs);
 EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs);

+ 3 - 9
drivers/gpu/drm/drm_gem_cma_helper.c

@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
 	return cma_obj;
 	return cma_obj;
 
 
 error:
 error:
-	drm->driver->gem_free_object(&cma_obj->base);
+	drm_gem_object_unreference_unlocked(&cma_obj->base);
 	return ERR_PTR(ret);
 	return ERR_PTR(ret);
 }
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
 	 * and handle has the id what user can see.
 	 * and handle has the id what user can see.
 	 */
 	 */
 	ret = drm_gem_handle_create(file_priv, gem_obj, handle);
 	ret = drm_gem_handle_create(file_priv, gem_obj, handle);
-	if (ret)
-		goto err_handle_create;
-
 	/* drop reference from allocate - handle holds it now. */
 	/* drop reference from allocate - handle holds it now. */
 	drm_gem_object_unreference_unlocked(gem_obj);
 	drm_gem_object_unreference_unlocked(gem_obj);
+	if (ret)
+		return ERR_PTR(ret);
 
 
 	return cma_obj;
 	return cma_obj;
-
-err_handle_create:
-	drm->driver->gem_free_object(gem_obj);
-
-	return ERR_PTR(ret);
 }
 }
 
 
 /**
 /**

+ 2 - 0
drivers/gpu/drm/drm_modes.c

@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
 	if (out->status != MODE_OK)
 	if (out->status != MODE_OK)
 		goto out;
 		goto out;
 
 
+	drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
+
 	ret = 0;
 	ret = 0;
 
 
 out:
 out:

+ 8 - 5
drivers/gpu/drm/imx/imx-drm-core.c

@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
 	return NULL;
 	return NULL;
 }
 }
 
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
-		int hsync_pin, int vsync_pin)
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+		int hsync_pin, int vsync_pin, u32 bus_flags)
 {
 {
 	struct imx_drm_crtc_helper_funcs *helper;
 	struct imx_drm_crtc_helper_funcs *helper;
 	struct imx_drm_crtc *imx_crtc;
 	struct imx_drm_crtc *imx_crtc;
@@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
 	helper = &imx_crtc->imx_drm_helper_funcs;
 	helper = &imx_crtc->imx_drm_helper_funcs;
 	if (helper->set_interface_pix_fmt)
 	if (helper->set_interface_pix_fmt)
 		return helper->set_interface_pix_fmt(encoder->crtc,
 		return helper->set_interface_pix_fmt(encoder->crtc,
-					bus_format, hsync_pin, vsync_pin);
+					bus_format, hsync_pin, vsync_pin,
+					bus_flags);
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins);
+EXPORT_SYMBOL_GPL(imx_drm_set_bus_config);
 
 
 int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
 int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
 {
 {
-	return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3);
+	return imx_drm_set_bus_config(encoder, bus_format, 2, 3,
+				      DRM_BUS_FLAG_DE_HIGH |
+				      DRM_BUS_FLAG_PIXDATA_NEGEDGE);
 }
 }
 EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
 EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
 
 

+ 4 - 3
drivers/gpu/drm/imx/imx-drm.h

@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
 	int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
-			u32 bus_format, int hsync_pin, int vsync_pin);
+			u32 bus_format, int hsync_pin, int vsync_pin,
+			u32 bus_flags);
 	const struct drm_crtc_helper_funcs *crtc_helper_funcs;
 	const struct drm_crtc_helper_funcs *crtc_helper_funcs;
 	const struct drm_crtc_funcs *crtc_funcs;
 	const struct drm_crtc_funcs *crtc_funcs;
 };
 };
@@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm);
 
 
 struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
 struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
 
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
-		u32 bus_format, int hsync_pin, int vsync_pin);
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+		int hsync_pin, int vsync_pin, u32 bus_flags);
 int imx_drm_set_bus_format(struct drm_encoder *encoder,
 int imx_drm_set_bus_format(struct drm_encoder *encoder,
 		u32 bus_format);
 		u32 bus_format);
 
 

+ 53 - 25
drivers/gpu/drm/imx/imx-ldb.c

@@ -25,6 +25,7 @@
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/of_graph.h>
+#include <video/of_display_timing.h>
 #include <video/of_videomode.h>
 #include <video/of_videomode.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
@@ -59,6 +60,7 @@ struct imx_ldb_channel {
 	struct drm_encoder encoder;
 	struct drm_encoder encoder;
 	struct drm_panel *panel;
 	struct drm_panel *panel;
 	struct device_node *child;
 	struct device_node *child;
+	struct i2c_adapter *ddc;
 	int chno;
 	int chno;
 	void *edid;
 	void *edid;
 	int edid_len;
 	int edid_len;
@@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
 			return num_modes;
 			return num_modes;
 	}
 	}
 
 
+	if (!imx_ldb_ch->edid && imx_ldb_ch->ddc)
+		imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
+
 	if (imx_ldb_ch->edid) {
 	if (imx_ldb_ch->edid) {
 		drm_mode_connector_update_edid_property(connector,
 		drm_mode_connector_update_edid_property(connector,
 							imx_ldb_ch->edid);
 							imx_ldb_ch->edid);
@@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 
 
 	for_each_child_of_node(np, child) {
 	for_each_child_of_node(np, child) {
 		struct imx_ldb_channel *channel;
 		struct imx_ldb_channel *channel;
-		struct device_node *port;
+		struct device_node *ddc_node;
+		struct device_node *ep;
 
 
 		ret = of_property_read_u32(child, "reg", &i);
 		ret = of_property_read_u32(child, "reg", &i);
 		if (ret || i < 0 || i > 1)
 		if (ret || i < 0 || i > 1)
@@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 		 * The output port is port@4 with an external 4-port mux or
 		 * The output port is port@4 with an external 4-port mux or
 		 * port@2 with the internal 2-port mux.
 		 * port@2 with the internal 2-port mux.
 		 */
 		 */
-		port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2);
-		if (port) {
-			struct device_node *endpoint, *remote;
-
-			endpoint = of_get_child_by_name(port, "endpoint");
-			if (endpoint) {
-				remote = of_graph_get_remote_port_parent(endpoint);
-				if (remote)
-					channel->panel = of_drm_find_panel(remote);
-				else
-					return -EPROBE_DEFER;
-				if (!channel->panel) {
-					dev_err(dev, "panel not found: %s\n",
-						remote->full_name);
-					return -EPROBE_DEFER;
-				}
+		ep = of_graph_get_endpoint_by_regs(child,
+						   imx_ldb->lvds_mux ? 4 : 2,
+						   -1);
+		if (ep) {
+			struct device_node *remote;
+
+			remote = of_graph_get_remote_port_parent(ep);
+			of_node_put(ep);
+			if (remote)
+				channel->panel = of_drm_find_panel(remote);
+			else
+				return -EPROBE_DEFER;
+			of_node_put(remote);
+			if (!channel->panel) {
+				dev_err(dev, "panel not found: %s\n",
+					remote->full_name);
+				return -EPROBE_DEFER;
 			}
 			}
 		}
 		}
 
 
-		edidp = of_get_property(child, "edid", &channel->edid_len);
-		if (edidp) {
-			channel->edid = kmemdup(edidp, channel->edid_len,
-						GFP_KERNEL);
-		} else if (!channel->panel) {
-			ret = of_get_drm_display_mode(child, &channel->mode, 0);
-			if (!ret)
-				channel->mode_valid = 1;
+		ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
+		if (ddc_node) {
+			channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
+			of_node_put(ddc_node);
+			if (!channel->ddc) {
+				dev_warn(dev, "failed to get ddc i2c adapter\n");
+				return -EPROBE_DEFER;
+			}
+		}
+
+		if (!channel->ddc) {
+			/* if no DDC available, fallback to hardcoded EDID */
+			dev_dbg(dev, "no ddc available\n");
+
+			edidp = of_get_property(child, "edid",
+						&channel->edid_len);
+			if (edidp) {
+				channel->edid = kmemdup(edidp,
+							channel->edid_len,
+							GFP_KERNEL);
+			} else if (!channel->panel) {
+				/* fallback to display-timings node */
+				ret = of_get_drm_display_mode(child,
+							      &channel->mode,
+							      OF_USE_NATIVE_MODE);
+				if (!ret)
+					channel->mode_valid = 1;
+			}
 		}
 		}
 
 
 		channel->bus_format = of_get_bus_format(dev, child);
 		channel->bus_format = of_get_bus_format(dev, child);
@@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
 		channel->encoder.funcs->destroy(&channel->encoder);
 		channel->encoder.funcs->destroy(&channel->encoder);
 
 
 		kfree(channel->edid);
 		kfree(channel->edid);
+		i2c_put_adapter(channel->ddc);
 	}
 	}
 }
 }
 
 

+ 4 - 2
drivers/gpu/drm/imx/imx-tve.c

@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
 
 
 	switch (tve->mode) {
 	switch (tve->mode) {
 	case TVE_MODE_VGA:
 	case TVE_MODE_VGA:
-		imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24,
-					    tve->hsync_pin, tve->vsync_pin);
+		imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24,
+				       tve->hsync_pin, tve->vsync_pin,
+				       DRM_BUS_FLAG_DE_HIGH |
+				       DRM_BUS_FLAG_PIXDATA_NEGEDGE);
 		break;
 		break;
 	case TVE_MODE_TVOUT:
 	case TVE_MODE_TVOUT:
 		imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
 		imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);

+ 7 - 3
drivers/gpu/drm/imx/ipuv3-crtc.c

@@ -66,6 +66,7 @@ struct ipu_crtc {
 	struct ipu_flip_work	*flip_work;
 	struct ipu_flip_work	*flip_work;
 	int			irq;
 	int			irq;
 	u32			bus_format;
 	u32			bus_format;
+	u32			bus_flags;
 	int			di_hsync_pin;
 	int			di_hsync_pin;
 	int			di_vsync_pin;
 	int			di_vsync_pin;
 };
 };
@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
 	else
 	else
 		sig_cfg.clkflags = 0;
 		sig_cfg.clkflags = 0;
 
 
-	sig_cfg.enable_pol = 1;
-	sig_cfg.clk_pol = 0;
+	sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW);
+	/* Default to driving pixel data on negative clock edges */
+	sig_cfg.clk_pol = !!(ipu_crtc->bus_flags &
+			     DRM_BUS_FLAG_PIXDATA_POSEDGE);
 	sig_cfg.bus_format = ipu_crtc->bus_format;
 	sig_cfg.bus_format = ipu_crtc->bus_format;
 	sig_cfg.v_to_h_sync = 0;
 	sig_cfg.v_to_h_sync = 0;
 	sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
 	sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
@@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
 }
 }
 
 
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
-		u32 bus_format, int hsync_pin, int vsync_pin)
+		u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags)
 {
 {
 	struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 	struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 
 
 	ipu_crtc->bus_format = bus_format;
 	ipu_crtc->bus_format = bus_format;
+	ipu_crtc->bus_flags = bus_flags;
 	ipu_crtc->di_hsync_pin = hsync_pin;
 	ipu_crtc->di_hsync_pin = hsync_pin;
 	ipu_crtc->di_vsync_pin = vsync_pin;
 	ipu_crtc->di_vsync_pin = vsync_pin;
 
 

+ 3 - 2
drivers/gpu/drm/imx/ipuv3-plane.c

@@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = {
 	DRM_FORMAT_RGBX8888,
 	DRM_FORMAT_RGBX8888,
 	DRM_FORMAT_BGRA8888,
 	DRM_FORMAT_BGRA8888,
 	DRM_FORMAT_BGRA8888,
 	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_VYUY,
 	DRM_FORMAT_YUYV,
 	DRM_FORMAT_YUYV,
 	DRM_FORMAT_YVYU,
 	DRM_FORMAT_YVYU,
 	DRM_FORMAT_YUV420,
 	DRM_FORMAT_YUV420,
@@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (crtc != plane->crtc)
 	if (crtc != plane->crtc)
 		dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n",
 		dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n",
 				plane->crtc, crtc);
 				plane->crtc, crtc);
-	plane->crtc = crtc;
 
 
 	if (!ipu_plane->enabled)
 	if (!ipu_plane->enabled)
 		ipu_plane_enable(ipu_plane);
 		ipu_plane_enable(ipu_plane);
@@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
 	kfree(ipu_plane);
 	kfree(ipu_plane);
 }
 }
 
 
-static struct drm_plane_funcs ipu_plane_funcs = {
+static const struct drm_plane_funcs ipu_plane_funcs = {
 	.update_plane	= ipu_update_plane,
 	.update_plane	= ipu_update_plane,
 	.disable_plane	= ipu_disable_plane,
 	.disable_plane	= ipu_disable_plane,
 	.destroy	= ipu_plane_destroy,
 	.destroy	= ipu_plane_destroy,

+ 14 - 26
drivers/gpu/drm/imx/parallel-display.c

@@ -35,7 +35,6 @@ struct imx_parallel_display {
 	void *edid;
 	void *edid;
 	int edid_len;
 	int edid_len;
 	u32 bus_format;
 	u32 bus_format;
-	int mode_valid;
 	struct drm_display_mode mode;
 	struct drm_display_mode mode;
 	struct drm_panel *panel;
 	struct drm_panel *panel;
 };
 };
@@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
 		num_modes = drm_add_edid_modes(connector, imxpd->edid);
 		num_modes = drm_add_edid_modes(connector, imxpd->edid);
 	}
 	}
 
 
-	if (imxpd->mode_valid) {
-		struct drm_display_mode *mode = drm_mode_create(connector->dev);
-
-		if (!mode)
-			return -EINVAL;
-		drm_mode_copy(mode, &imxpd->mode);
-		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-		drm_mode_probed_add(connector, mode);
-		num_modes++;
-	}
-
 	if (np) {
 	if (np) {
 		struct drm_display_mode *mode = drm_mode_create(connector->dev);
 		struct drm_display_mode *mode = drm_mode_create(connector->dev);
 
 
@@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
 static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 {
 {
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
 	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
-
-	imx_drm_set_bus_format(encoder, imxpd->bus_format);
+	imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
+			       imxpd->connector.display_info.bus_flags);
 }
 }
 
 
 static void imx_pd_encoder_commit(struct drm_encoder *encoder)
 static void imx_pd_encoder_commit(struct drm_encoder *encoder)
@@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 {
 {
 	struct drm_device *drm = data;
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
 	struct device_node *np = dev->of_node;
-	struct device_node *port;
+	struct device_node *ep;
 	const u8 *edidp;
 	const u8 *edidp;
 	struct imx_parallel_display *imxpd;
 	struct imx_parallel_display *imxpd;
 	int ret;
 	int ret;
@@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 	}
 	}
 
 
 	/* port@1 is the output port */
 	/* port@1 is the output port */
-	port = of_graph_get_port_by_id(np, 1);
-	if (port) {
-		struct device_node *endpoint, *remote;
-
-		endpoint = of_get_child_by_name(port, "endpoint");
-		if (endpoint) {
-			remote = of_graph_get_remote_port_parent(endpoint);
-			if (remote)
-				imxpd->panel = of_drm_find_panel(remote);
-			if (!imxpd->panel)
-				return -EPROBE_DEFER;
+	ep = of_graph_get_endpoint_by_regs(np, 1, -1);
+	if (ep) {
+		struct device_node *remote;
+
+		remote = of_graph_get_remote_port_parent(ep);
+		of_node_put(ep);
+		if (remote) {
+			imxpd->panel = of_drm_find_panel(remote);
+			of_node_put(remote);
 		}
 		}
+		if (!imxpd->panel)
+			return -EPROBE_DEFER;
 	}
 	}
 
 
 	imxpd->dev = dev;
 	imxpd->dev = dev;

+ 0 - 5
drivers/gpu/drm/mediatek/mtk_dpi.c

@@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	unsigned long pll_rate;
 	unsigned long pll_rate;
 	unsigned int factor;
 	unsigned int factor;
 
 
-	if (!dpi) {
-		dev_err(dpi->dev, "invalid argument\n");
-		return -EINVAL;
-	}
-
 	pix_rate = 1000UL * mode->clock;
 	pix_rate = 1000UL * mode->clock;
 	if (mode->clock <= 74000)
 	if (mode->clock <= 74000)
 		factor = 8 * 3;
 		factor = 8 * 3;

+ 1 - 3
drivers/gpu/drm/mediatek/mtk_dsi.c

@@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
 {
 {
 	drm_encoder_cleanup(&dsi->encoder);
 	drm_encoder_cleanup(&dsi->encoder);
 	/* Skip connector cleanup if creation was delegated to the bridge */
 	/* Skip connector cleanup if creation was delegated to the bridge */
-	if (dsi->conn.dev) {
-		drm_connector_unregister(&dsi->conn);
+	if (dsi->conn.dev)
 		drm_connector_cleanup(&dsi->conn);
 		drm_connector_cleanup(&dsi->conn);
-	}
 }
 }
 
 
 static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
 static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)

+ 9 - 1
drivers/gpu/drm/mgag200/mgag200_mode.c

@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
 			}
 			}
 		}
 		}
 
 
-		fvv = pllreffreq * testn / testm;
+		fvv = pllreffreq * (n + 1) / (m + 1);
 		fvv = (fvv - 800000) / 50000;
 		fvv = (fvv - 800000) / 50000;
 
 
 		if (fvv > 15)
 		if (fvv > 15)
@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
 	WREG_DAC(MGA1064_PIX_PLLC_M, m);
 	WREG_DAC(MGA1064_PIX_PLLC_M, m);
 	WREG_DAC(MGA1064_PIX_PLLC_N, n);
 	WREG_DAC(MGA1064_PIX_PLLC_N, n);
 	WREG_DAC(MGA1064_PIX_PLLC_P, p);
 	WREG_DAC(MGA1064_PIX_PLLC_P, p);
+
+	if (mdev->unique_rev_id >= 0x04) {
+		WREG_DAC(0x1a, 0x09);
+		msleep(20);
+		WREG_DAC(0x1a, 0x01);
+
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
drivers/gpu/drm/omapdrm/Kconfig

@@ -2,6 +2,7 @@ config DRM_OMAP
 	tristate "OMAP DRM"
 	tristate "OMAP DRM"
 	depends on DRM
 	depends on DRM
 	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
 	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
+	select OMAP2_DSS
 	select DRM_KMS_HELPER
 	select DRM_KMS_HELPER
 	select DRM_KMS_FB_HELPER
 	select DRM_KMS_FB_HELPER
 	select FB_SYS_FILLRECT
 	select FB_SYS_FILLRECT

+ 1 - 0
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c

@@ -9,6 +9,7 @@
  * the Free Software Foundation.
  * the Free Software Foundation.
  */
  */
 
 
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/encoder-opa362.c

@@ -14,7 +14,7 @@
  * the Free Software Foundation.
  * the Free Software Foundation.
  */
  */
 
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c

@@ -9,7 +9,7 @@
  * the Free Software Foundation.
  * the Free Software Foundation.
  */
  */
 
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-dpi.c

@@ -9,7 +9,7 @@
  * the Free Software Foundation.
  * the Free Software Foundation.
  */
  */
 
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c

@@ -14,7 +14,7 @@
 #include <linux/backlight.h>
 #include <linux/backlight.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/module.h>

+ 1 - 0
drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c

@@ -15,6 +15,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-data.h>
 #include <video/omap-panel-data.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c

@@ -15,7 +15,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/fb.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 
 
 #include <video/omapdss.h>
 #include <video/omapdss.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c

@@ -10,7 +10,7 @@
  */
  */
 
 
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c

@@ -29,7 +29,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/backlight.h>
 #include <linux/backlight.h>
 #include <linux/fb.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 
 

+ 1 - 1
drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c

@@ -14,7 +14,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>

+ 0 - 9
drivers/gpu/drm/omapdrm/dss/dsi.c

@@ -1180,15 +1180,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
 		return PTR_ERR(vdds_dsi);
 		return PTR_ERR(vdds_dsi);
 	}
 	}
 
 
-	if (regulator_can_change_voltage(vdds_dsi)) {
-		r = regulator_set_voltage(vdds_dsi, 1800000, 1800000);
-		if (r) {
-			devm_regulator_put(vdds_dsi);
-			DSSERR("can't set the DSI regulator voltage\n");
-			return r;
-		}
-	}
-
 	dsi->vdds_dsi_reg = vdds_dsi;
 	dsi->vdds_dsi_reg = vdds_dsi;
 
 
 	return 0;
 	return 0;

+ 1 - 0
drivers/gpu/drm/omapdrm/dss/dss.c

@@ -30,6 +30,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/gfp.h>
 #include <linux/gfp.h>

+ 1 - 10
drivers/gpu/drm/omapdrm/dss/hdmi4.c

@@ -33,6 +33,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <linux/component.h>
+#include <linux/of.h>
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 #include <sound/omap-hdmi-audio.h>
 #include <sound/omap-hdmi-audio.h>
 
 
@@ -100,7 +101,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
 
 
 static int hdmi_init_regulator(void)
 static int hdmi_init_regulator(void)
 {
 {
-	int r;
 	struct regulator *reg;
 	struct regulator *reg;
 
 
 	if (hdmi.vdda_reg != NULL)
 	if (hdmi.vdda_reg != NULL)
@@ -114,15 +114,6 @@ static int hdmi_init_regulator(void)
 		return PTR_ERR(reg);
 		return PTR_ERR(reg);
 	}
 	}
 
 
-	if (regulator_can_change_voltage(reg)) {
-		r = regulator_set_voltage(reg, 1800000, 1800000);
-		if (r) {
-			devm_regulator_put(reg);
-			DSSWARN("can't set the regulator voltage\n");
-			return r;
-		}
-	}
-
 	hdmi.vdda_reg = reg;
 	hdmi.vdda_reg = reg;
 
 
 	return 0;
 	return 0;

+ 1 - 1
drivers/gpu/drm/omapdrm/dss/hdmi4_core.c

@@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
 static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
 static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
 {
 {
 	DSSDBG("Enter hdmi_core_powerdown_disable\n");
 	DSSDBG("Enter hdmi_core_powerdown_disable\n");
-	REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);
+	REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0);
 }
 }
 
 
 static void hdmi_core_swreset_release(struct hdmi_core_data *core)
 static void hdmi_core_swreset_release(struct hdmi_core_data *core)

+ 1 - 9
drivers/gpu/drm/omapdrm/dss/hdmi5.c

@@ -38,6 +38,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/component.h>
 #include <linux/component.h>
+#include <linux/of.h>
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 #include <sound/omap-hdmi-audio.h>
 #include <sound/omap-hdmi-audio.h>
 
 
@@ -131,15 +132,6 @@ static int hdmi_init_regulator(void)
 		return PTR_ERR(reg);
 		return PTR_ERR(reg);
 	}
 	}
 
 
-	if (regulator_can_change_voltage(reg)) {
-		r = regulator_set_voltage(reg, 1800000, 1800000);
-		if (r) {
-			devm_regulator_put(reg);
-			DSSWARN("can't set the regulator voltage\n");
-			return r;
-		}
-	}
-
 	hdmi.vdda_reg = reg;
 	hdmi.vdda_reg = reg;
 
 
 	return 0;
 	return 0;

+ 3 - 3
drivers/gpu/drm/omapdrm/dss/hdmi5_core.c

@@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
 {
 {
 	void __iomem *base = core->base;
 	void __iomem *base = core->base;
 	const unsigned long long iclk = 266000000;	/* DSS L3 ICLK */
 	const unsigned long long iclk = 266000000;	/* DSS L3 ICLK */
-	const unsigned ss_scl_high = 4000;		/* ns */
-	const unsigned ss_scl_low = 4700;		/* ns */
+	const unsigned ss_scl_high = 4600;		/* ns */
+	const unsigned ss_scl_low = 5400;		/* ns */
 	const unsigned fs_scl_high = 600;		/* ns */
 	const unsigned fs_scl_high = 600;		/* ns */
 	const unsigned fs_scl_low = 1300;		/* ns */
 	const unsigned fs_scl_low = 1300;		/* ns */
 	const unsigned sda_hold = 1000;			/* ns */
 	const unsigned sda_hold = 1000;			/* ns */
@@ -458,7 +458,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
 
 
 	c = (ptr[1] >> 6) & 0x3;
 	c = (ptr[1] >> 6) & 0x3;
 	m = (ptr[1] >> 4) & 0x3;
 	m = (ptr[1] >> 4) & 0x3;
-	r = (ptr[1] >> 0) & 0x3;
+	r = (ptr[1] >> 0) & 0xf;
 
 
 	itc = (ptr[2] >> 7) & 0x1;
 	itc = (ptr[2] >> 7) & 0x1;
 	ec = (ptr[2] >> 4) & 0x7;
 	ec = (ptr[2] >> 4) & 0x7;

+ 1 - 0
drivers/gpu/drm/omapdrm/dss/hdmi_phy.c

@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/seq_file.h>
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 
 
 #include "dss.h"
 #include "dss.h"

+ 1 - 0
drivers/gpu/drm/omapdrm/dss/hdmi_pll.c

@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/seq_file.h>
 
 
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 
 

+ 1 - 0
drivers/gpu/drm/omapdrm/dss/hdmi_wp.c

@@ -14,6 +14,7 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/seq_file.h>
 #include <video/omapdss.h>
 #include <video/omapdss.h>
 
 
 #include "dss.h"
 #include "dss.h"

+ 2 - 0
drivers/gpu/drm/omapdrm/omap_debugfs.c

@@ -17,6 +17,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  */
 
 
+#include <linux/seq_file.h>
+
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_fb_helper.h>
 
 

+ 1 - 0
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c

@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h> /* platform_device() */
 #include <linux/platform_device.h> /* platform_device() */
 #include <linux/sched.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>

+ 2 - 0
drivers/gpu/drm/omapdrm/omap_fb.c

@@ -17,6 +17,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  */
 
 
+#include <linux/seq_file.h>
+
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_crtc_helper.h>
 
 

+ 1 - 0
drivers/gpu/drm/omapdrm/omap_gem.c

@@ -17,6 +17,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
  */
 
 
+#include <linux/seq_file.h>
 #include <linux/shmem_fs.h>
 #include <linux/shmem_fs.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/pfn_t.h>
 #include <linux/pfn_t.h>

+ 0 - 10
drivers/gpu/drm/sti/sti_crtc.c

@@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc)
 	mixer->status = STI_MIXER_DISABLING;
 	mixer->status = STI_MIXER_DISABLING;
 }
 }
 
 
-static bool sti_crtc_mode_fixup(struct drm_crtc *crtc,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	/* accept the provided drm_display_mode, do not fix it up */
-	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
-	return true;
-}
-
 static int
 static int
 sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
 sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
 {
 {
@@ -230,7 +221,6 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
 static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
 static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
 	.enable = sti_crtc_enable,
 	.enable = sti_crtc_enable,
 	.disable = sti_crtc_disabling,
 	.disable = sti_crtc_disabling,
-	.mode_fixup = sti_crtc_mode_fixup,
 	.mode_set = drm_helper_crtc_mode_set,
 	.mode_set = drm_helper_crtc_mode_set,
 	.mode_set_nofb = sti_crtc_mode_set_nofb,
 	.mode_set_nofb = sti_crtc_mode_set_nofb,
 	.mode_set_base = drm_helper_crtc_mode_set_base,
 	.mode_set_base = drm_helper_crtc_mode_set_base,

+ 47 - 2
drivers/irqchip/irq-gic-v3-its.c

@@ -41,6 +41,7 @@
 
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
+#define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
 
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
 
@@ -82,6 +83,7 @@ struct its_node {
 	u64			flags;
 	u64			flags;
 	u32			ite_size;
 	u32			ite_size;
 	u32			device_ids;
 	u32			device_ids;
+	int			numa_node;
 };
 };
 
 
 #define ITS_ITT_ALIGN		SZ_256
 #define ITS_ITT_ALIGN		SZ_256
@@ -613,11 +615,23 @@ static void its_unmask_irq(struct irq_data *d)
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 			    bool force)
 {
 {
-	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	unsigned int cpu;
+	const struct cpumask *cpu_mask = cpu_online_mask;
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_collection *target_col;
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 	u32 id = its_get_event_id(d);
 
 
+       /* lpi cannot be routed to a redistributor that is on a foreign node */
+	if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
+		if (its_dev->its->numa_node >= 0) {
+			cpu_mask = cpumask_of_node(its_dev->its->numa_node);
+			if (!cpumask_intersects(mask_val, cpu_mask))
+				return -EINVAL;
+		}
+	}
+
+	cpu = cpumask_any_and(mask_val, cpu_mask);
+
 	if (cpu >= nr_cpu_ids)
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 		return -EINVAL;
 
 
@@ -1101,6 +1115,16 @@ static void its_cpu_init_collection(void)
 	list_for_each_entry(its, &its_nodes, entry) {
 	list_for_each_entry(its, &its_nodes, entry) {
 		u64 target;
 		u64 target;
 
 
+		/* avoid cross node collections and its mapping */
+		if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) {
+			struct device_node *cpu_node;
+
+			cpu_node = of_get_cpu_node(cpu, NULL);
+			if (its->numa_node != NUMA_NO_NODE &&
+				its->numa_node != of_node_to_nid(cpu_node))
+				continue;
+		}
+
 		/*
 		/*
 		 * We now have to bind each collection to its target
 		 * We now have to bind each collection to its target
 		 * redistributor.
 		 * redistributor.
@@ -1351,9 +1375,14 @@ static void its_irq_domain_activate(struct irq_domain *domain,
 {
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
 	u32 event = its_get_event_id(d);
+	const struct cpumask *cpu_mask = cpu_online_mask;
+
+	/* get the cpu_mask of local node */
+	if (its_dev->its->numa_node >= 0)
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
 
 	/* Bind the LPI to the first possible CPU */
 	/* Bind the LPI to the first possible CPU */
-	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
 
 
 	/* Map the GIC IRQ and event to the device */
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
 	its_send_mapvi(its_dev, d->hwirq, event);
@@ -1443,6 +1472,13 @@ static void __maybe_unused its_enable_quirk_cavium_22375(void *data)
 	its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
 	its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375;
 }
 }
 
 
+static void __maybe_unused its_enable_quirk_cavium_23144(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_23144;
+}
+
 static const struct gic_quirk its_quirks[] = {
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 	{
 	{
@@ -1451,6 +1487,14 @@ static const struct gic_quirk its_quirks[] = {
 		.mask	= 0xffff0fff,
 		.mask	= 0xffff0fff,
 		.init	= its_enable_quirk_cavium_22375,
 		.init	= its_enable_quirk_cavium_22375,
 	},
 	},
+#endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23144
+	{
+		.desc	= "ITS: Cavium erratum 23144",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_quirk_cavium_23144,
+	},
 #endif
 #endif
 	{
 	{
 	}
 	}
@@ -1514,6 +1558,7 @@ static int __init its_probe(struct device_node *node,
 	its->base = its_base;
 	its->base = its_base;
 	its->phys_base = res.start;
 	its->phys_base = res.start;
 	its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
 	its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+	its->numa_node = of_node_to_nid(node);
 
 
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
 	if (!its->cmd_base) {
 	if (!its->cmd_base) {

+ 1 - 1
drivers/irqchip/irq-gic-v3.c

@@ -155,7 +155,7 @@ static void gic_enable_redist(bool enable)
 
 
 	while (count--) {
 	while (count--) {
 		val = readl_relaxed(rbase + GICR_WAKER);
 		val = readl_relaxed(rbase + GICR_WAKER);
-		if (enable ^ (val & GICR_WAKER_ChildrenAsleep))
+		if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
 			break;
 			break;
 		cpu_relax();
 		cpu_relax();
 		udelay(1);
 		udelay(1);

+ 1 - 1
drivers/irqchip/irq-pic32-evic.c

@@ -91,7 +91,7 @@ static int pic32_set_type_edge(struct irq_data *data,
 	/* set polarity for external interrupts only */
 	/* set polarity for external interrupts only */
 	for (i = 0; i < ARRAY_SIZE(priv->ext_irqs); i++) {
 	for (i = 0; i < ARRAY_SIZE(priv->ext_irqs); i++) {
 		if (priv->ext_irqs[i] == data->hwirq) {
 		if (priv->ext_irqs[i] == data->hwirq) {
-			ret = pic32_set_ext_polarity(i + 1, flow_type);
+			ret = pic32_set_ext_polarity(i, flow_type);
 			if (ret)
 			if (ret)
 				return ret;
 				return ret;
 		}
 		}

+ 2 - 2
drivers/mmc/core/mmc.c

@@ -1276,7 +1276,7 @@ static int mmc_select_hs200(struct mmc_card *card)
 	 * switch to HS200 mode if bus width is set successfully.
 	 * switch to HS200 mode if bus width is set successfully.
 	 */
 	 */
 	err = mmc_select_bus_width(card);
 	err = mmc_select_bus_width(card);
-	if (!err) {
+	if (err >= 0) {
 		val = EXT_CSD_TIMING_HS200 |
 		val = EXT_CSD_TIMING_HS200 |
 		      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
 		      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
 		err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 		err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -1583,7 +1583,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 	} else if (mmc_card_hs(card)) {
 	} else if (mmc_card_hs(card)) {
 		/* Select the desired bus width optionally */
 		/* Select the desired bus width optionally */
 		err = mmc_select_bus_width(card);
 		err = mmc_select_bus_width(card);
-		if (!err) {
+		if (err >= 0) {
 			err = mmc_select_hs_ddr(card);
 			err = mmc_select_hs_ddr(card);
 			if (err)
 			if (err)
 				goto free_card;
 				goto free_card;

+ 2 - 7
drivers/mmc/host/sunxi-mmc.c

@@ -970,8 +970,8 @@ static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = {
 	[SDXC_CLK_400K]		= { .output = 180, .sample = 180 },
 	[SDXC_CLK_400K]		= { .output = 180, .sample = 180 },
 	[SDXC_CLK_25M]		= { .output = 180, .sample =  75 },
 	[SDXC_CLK_25M]		= { .output = 180, .sample =  75 },
 	[SDXC_CLK_50M]		= { .output = 150, .sample = 120 },
 	[SDXC_CLK_50M]		= { .output = 150, .sample = 120 },
-	[SDXC_CLK_50M_DDR]	= { .output =  90, .sample = 120 },
-	[SDXC_CLK_50M_DDR_8BIT]	= { .output =  90, .sample = 120 },
+	[SDXC_CLK_50M_DDR]	= { .output =  54, .sample =  36 },
+	[SDXC_CLK_50M_DDR_8BIT]	= { .output =  72, .sample =  72 },
 };
 };
 
 
 static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
 static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
@@ -1129,11 +1129,6 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
 				  MMC_CAP_1_8V_DDR |
 				  MMC_CAP_1_8V_DDR |
 				  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 				  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
 
-	/* TODO MMC DDR is not working on A80 */
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "allwinner,sun9i-a80-mmc"))
-		mmc->caps &= ~MMC_CAP_1_8V_DDR;
-
 	ret = mmc_of_parse(mmc);
 	ret = mmc_of_parse(mmc);
 	if (ret)
 	if (ret)
 		goto error_free_dma;
 		goto error_free_dma;

+ 5 - 7
drivers/perf/arm_pmu.c

@@ -950,17 +950,14 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
 
 
 		/* For SPIs, we need to track the affinity per IRQ */
 		/* For SPIs, we need to track the affinity per IRQ */
 		if (using_spi) {
 		if (using_spi) {
-			if (i >= pdev->num_resources) {
-				of_node_put(dn);
+			if (i >= pdev->num_resources)
 				break;
 				break;
-			}
 
 
 			irqs[i] = cpu;
 			irqs[i] = cpu;
 		}
 		}
 
 
 		/* Keep track of the CPUs containing this PMU type */
 		/* Keep track of the CPUs containing this PMU type */
 		cpumask_set_cpu(cpu, &pmu->supported_cpus);
 		cpumask_set_cpu(cpu, &pmu->supported_cpus);
-		of_node_put(dn);
 		i++;
 		i++;
 	} while (1);
 	} while (1);
 
 
@@ -995,9 +992,6 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 
 
 	armpmu_init(pmu);
 	armpmu_init(pmu);
 
 
-	if (!__oprofile_cpu_pmu)
-		__oprofile_cpu_pmu = pmu;
-
 	pmu->plat_device = pdev;
 	pmu->plat_device = pdev;
 
 
 	if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) {
 	if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) {
@@ -1033,6 +1027,9 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 	if (ret)
 	if (ret)
 		goto out_destroy;
 		goto out_destroy;
 
 
+	if (!__oprofile_cpu_pmu)
+		__oprofile_cpu_pmu = pmu;
+
 	pr_info("enabled with %s PMU driver, %d counters available\n",
 	pr_info("enabled with %s PMU driver, %d counters available\n",
 			pmu->name, pmu->num_events);
 			pmu->name, pmu->num_events);
 
 
@@ -1043,6 +1040,7 @@ out_destroy:
 out_free:
 out_free:
 	pr_info("%s: failed to register PMU devices!\n",
 	pr_info("%s: failed to register PMU devices!\n",
 		of_node_full_name(node));
 		of_node_full_name(node));
+	kfree(pmu->irq_affinity);
 	kfree(pmu);
 	kfree(pmu);
 	return ret;
 	return ret;
 }
 }

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff