Przeglądaj źródła

Merge commit 'v2.6.34-rc5' into tracing/core

Merge reason: pick up latest -rc's.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Ingo Molnar 15 lat temu
rodzic
commit
ac0053fd51
100 zmienionych plików z 1873 dodań i 805 usunięć
  1. 13 0
      Documentation/DocBook/tracepoint.tmpl
  2. 22 17
      Documentation/RCU/NMI-RCU.txt
  3. 4 3
      Documentation/RCU/checklist.txt
  4. 26 2
      Documentation/RCU/lockdep.txt
  5. 6 0
      Documentation/RCU/whatisRCU.txt
  6. 2 2
      Documentation/block/biodoc.txt
  7. 17 6
      Documentation/input/multi-touch-protocol.txt
  8. 0 5
      Documentation/kernel-parameters.txt
  9. 46 30
      Documentation/networking/timestamping.txt
  10. 12 2
      MAINTAINERS
  11. 2 2
      Makefile
  12. 1 1
      arch/arm/boot/compressed/head.S
  13. 14 1
      arch/arm/include/asm/highmem.h
  14. 1 0
      arch/arm/include/asm/kmap_types.h
  15. 11 12
      arch/arm/include/asm/ucontext.h
  16. 11 1
      arch/arm/include/asm/user.h
  17. 89 4
      arch/arm/kernel/signal.c
  18. 2 2
      arch/arm/mach-at91/Makefile
  19. 12 4
      arch/arm/mach-at91/pm_slowclock.S
  20. 10 3
      arch/arm/mach-bcmring/dma.c
  21. 3 3
      arch/arm/mach-ep93xx/gpio.c
  22. 10 0
      arch/arm/mach-mx3/Kconfig
  23. 2 3
      arch/arm/mach-mx3/clock-imx31.c
  24. 18 1
      arch/arm/mach-mx3/devices.c
  25. 2 1
      arch/arm/mach-mx3/devices.h
  26. 166 0
      arch/arm/mach-mx3/mach-armadillo5x0.c
  27. 97 19
      arch/arm/mach-mx3/mach-mx31_3ds.c
  28. 0 1
      arch/arm/mach-mx3/mach-pcm037.c
  29. 1 1
      arch/arm/mach-mx3/mx31lite-db.c
  30. 1 1
      arch/arm/mach-mx5/clock-mx51.c
  31. 53 0
      arch/arm/mach-mx5/cpu.c
  32. 13 19
      arch/arm/mach-mx5/mm.c
  33. 1 8
      arch/arm/mm/copypage-v6.c
  34. 5 0
      arch/arm/mm/dma-mapping.c
  35. 15 10
      arch/arm/mm/flush.c
  36. 86 1
      arch/arm/mm/highmem.c
  37. 10 4
      arch/arm/mm/mmu.c
  38. 3 3
      arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
  39. 12 21
      arch/arm/plat-mxc/include/mach/mx51.h
  40. 4 0
      arch/arm/plat-mxc/include/mach/uncompress.h
  41. 10 21
      arch/arm/vfp/vfpmodule.c
  42. 6 2
      arch/m68k/include/asm/atomic_mm.h
  43. 1 3
      arch/m68k/include/asm/sigcontext.h
  44. 0 40
      arch/mips/alchemy/devboards/db1200/setup.c
  45. 2 1
      arch/mips/ar7/platform.c
  46. 147 84
      arch/mips/bcm63xx/boards/board_bcm963xx.c
  47. 5 0
      arch/mips/bcm63xx/cpu.c
  48. 50 16
      arch/mips/bcm63xx/dev-uart.c
  49. 2 2
      arch/mips/bcm63xx/gpio.c
  50. 1 81
      arch/mips/cavium-octeon/setup.c
  51. 0 8
      arch/mips/cavium-octeon/smp.c
  52. 340 155
      arch/mips/configs/bigsur_defconfig
  53. 4 2
      arch/mips/include/asm/abi.h
  54. 5 0
      arch/mips/include/asm/elf.h
  55. 5 1
      arch/mips/include/asm/fpu_emulator.h
  56. 15 0
      arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
  57. 6 0
      arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
  58. 4 0
      arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
  59. 2 0
      arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
  60. 1 1
      arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
  61. 5 1
      arch/mips/include/asm/mach-sibyte/war.h
  62. 4 1
      arch/mips/include/asm/mmu.h
  63. 1 1
      arch/mips/include/asm/mmu_context.h
  64. 4 2
      arch/mips/include/asm/page.h
  65. 9 2
      arch/mips/include/asm/processor.h
  66. 19 0
      arch/mips/include/asm/stackframe.h
  67. 2 0
      arch/mips/include/asm/uasm.h
  68. 29 0
      arch/mips/include/asm/vdso.h
  69. 1 1
      arch/mips/kernel/Makefile
  70. 4 0
      arch/mips/kernel/cpufreq/loongson2_clock.c
  71. 6 1
      arch/mips/kernel/process.c
  72. 0 5
      arch/mips/kernel/signal-common.h
  73. 19 67
      arch/mips/kernel/signal.c
  74. 14 41
      arch/mips/kernel/signal32.c
  75. 6 20
      arch/mips/kernel/signal_n32.c
  76. 1 1
      arch/mips/kernel/smtc.c
  77. 5 1
      arch/mips/kernel/syscall.c
  78. 1 1
      arch/mips/kernel/traps.c
  79. 112 0
      arch/mips/kernel/vdso.c
  80. 2 2
      arch/mips/lib/delay.c
  81. 1 2
      arch/mips/lib/libgcc.h
  82. 1 1
      arch/mips/mm/cache.c
  83. 16 6
      arch/mips/mm/tlbex.c
  84. 20 3
      arch/mips/mm/uasm.c
  85. 10 0
      arch/mips/pci/ops-loongson2.c
  86. 15 0
      arch/mips/sibyte/sb1250/setup.c
  87. 30 10
      arch/s390/defconfig
  88. 3 3
      arch/s390/include/asm/pgtable.h
  89. 2 1
      arch/s390/kernel/early.c
  90. 7 1
      arch/s390/kernel/entry.S
  91. 7 1
      arch/s390/kernel/entry64.S
  92. 2 1
      arch/s390/kernel/topology.c
  93. 3 8
      arch/s390/mm/vmem.c
  94. 3 0
      arch/sparc/Kconfig
  95. 1 4
      arch/sparc/Kconfig.debug
  96. 1 1
      arch/sparc/include/asm/cpudata_64.h
  97. 20 3
      arch/sparc/include/asm/irqflags_64.h
  98. 9 1
      arch/sparc/kernel/Makefile
  99. 59 1
      arch/sparc/kernel/ftrace.c
  100. 10 1
      arch/sparc/kernel/irq_64.c

+ 13 - 0
Documentation/DocBook/tracepoint.tmpl

@@ -16,6 +16,15 @@
      </address>
      </address>
     </affiliation>
     </affiliation>
    </author>
    </author>
+   <author>
+    <firstname>William</firstname>
+    <surname>Cohen</surname>
+    <affiliation>
+     <address>
+      <email>wcohen@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
   </authorgroup>
   </authorgroup>
 
 
   <legalnotice>
   <legalnotice>
@@ -91,4 +100,8 @@
 !Iinclude/trace/events/signal.h
 !Iinclude/trace/events/signal.h
   </chapter>
   </chapter>
 
 
+  <chapter id="block">
+   <title>Block IO</title>
+!Iinclude/trace/events/block.h
+  </chapter>
 </book>
 </book>

+ 22 - 17
Documentation/RCU/NMI-RCU.txt

@@ -34,7 +34,7 @@ NMI handler.
 		cpu = smp_processor_id();
 		cpu = smp_processor_id();
 		++nmi_count(cpu);
 		++nmi_count(cpu);
 
 
-		if (!rcu_dereference(nmi_callback)(regs, cpu))
+		if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
 			default_do_nmi(regs);
 			default_do_nmi(regs);
 
 
 		nmi_exit();
 		nmi_exit();
@@ -47,12 +47,13 @@ function pointer.  If this handler returns zero, do_nmi() invokes the
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 preemption is restored.
 preemption is restored.
 
 
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway.  However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway.  However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
 
 
-Quick Quiz:  Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz:  Why might the rcu_dereference_sched() be necessary on Alpha,
 	     given that the code referenced by the pointer is read-only?
 	     given that the code referenced by the pointer is read-only?
 
 
 
 
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
 
 
 Answer to Quick Quiz
 Answer to Quick Quiz
 
 
-	Why might the rcu_dereference() be necessary on Alpha, given
+	Why might the rcu_dereference_sched() be necessary on Alpha, given
 	that the code referenced by the pointer is read-only?
 	that the code referenced by the pointer is read-only?
 
 
 	Answer: The caller to set_nmi_callback() might well have
 	Answer: The caller to set_nmi_callback() might well have
-		initialized some data that is to be used by the
-		new NMI handler.  In this case, the rcu_dereference()
-		would be needed, because otherwise a CPU that received
-		an NMI just after the new handler was set might see
-		the pointer to the new NMI handler, but the old
-		pre-initialized version of the handler's data.
-
-		More important, the rcu_dereference() makes it clear
-		to someone reading the code that the pointer is being
-		protected by RCU.
+		initialized some data that is to be used by the new NMI
+		handler.  In this case, the rcu_dereference_sched() would
+		be needed, because otherwise a CPU that received an NMI
+		just after the new handler was set might see the pointer
+		to the new NMI handler, but the old pre-initialized
+		version of the handler's data.
+
+		This same sad story can happen on other CPUs when using
+		a compiler with aggressive pointer-value speculation
+		optimizations.
+
+		More important, the rcu_dereference_sched() makes it
+		clear to someone reading the code that the pointer is
+		being protected by RCU-sched.

+ 4 - 3
Documentation/RCU/checklist.txt

@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
 	The reason that it is permissible to use RCU list-traversal
 	The reason that it is permissible to use RCU list-traversal
 	primitives when the update-side lock is held is that doing so
 	primitives when the update-side lock is held is that doing so
 	can be quite helpful in reducing code bloat when common code is
 	can be quite helpful in reducing code bloat when common code is
-	shared between readers and updaters.
+	shared between readers and updaters.  Additional primitives
+	are provided for this case, as discussed in lockdep.txt.
 
 
 10.	Conversely, if you are in an RCU read-side critical section,
 10.	Conversely, if you are in an RCU read-side critical section,
 	and you don't hold the appropriate update-side lock, you -must-
 	and you don't hold the appropriate update-side lock, you -must-
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
 	requiring SRCU's read-side deadlock immunity or low read-side
 	requiring SRCU's read-side deadlock immunity or low read-side
 	realtime latency.
 	realtime latency.
 
 
-	Note that, rcu_assign_pointer() and rcu_dereference() relate to
-	SRCU just as they do to other forms of RCU.
+	Note that, rcu_assign_pointer() relates to SRCU just as they do
+	to other forms of RCU.
 
 
 15.	The whole point of call_rcu(), synchronize_rcu(), and friends
 15.	The whole point of call_rcu(), synchronize_rcu(), and friends
 	is to wait until all pre-existing readers have finished before
 	is to wait until all pre-existing readers have finished before

+ 26 - 2
Documentation/RCU/lockdep.txt

@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
 	srcu_dereference(p, sp):
 	srcu_dereference(p, sp):
 		Check for SRCU read-side critical section.
 		Check for SRCU read-side critical section.
 	rcu_dereference_check(p, c):
 	rcu_dereference_check(p, c):
-		Use explicit check expression "c".
+		Use explicit check expression "c".  This is useful in
+		code that is invoked by both readers and updaters.
 	rcu_dereference_raw(p)
 	rcu_dereference_raw(p)
 		Don't check.  (Use sparingly, if at all.)
 		Don't check.  (Use sparingly, if at all.)
+	rcu_dereference_protected(p, c):
+		Use explicit check expression "c", and omit all barriers
+		and compiler constraints.  This is useful when the data
+		structure cannot change, for example, in code that is
+		invoked only by updaters.
+	rcu_access_pointer(p):
+		Return the value of the pointer and omit all barriers,
+		but retain the compiler constraints that prevent duplicating
+		or coalescsing.  This is useful when when testing the
+		value of the pointer itself, for example, against NULL.
 
 
 The rcu_dereference_check() check expression can be any boolean
 The rcu_dereference_check() check expression can be any boolean
 expression, but would normally include one of the rcu_read_lock_held()
 expression, but would normally include one of the rcu_read_lock_held()
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
 RCU read-side critical sections, in case (2) the ->file_lock prevents
 RCU read-side critical sections, in case (2) the ->file_lock prevents
 any change from taking place, and finally, in case (3) the current task
 any change from taking place, and finally, in case (3) the current task
 is the only task accessing the file_struct, again preventing any change
 is the only task accessing the file_struct, again preventing any change
-from taking place.
+from taking place.  If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+	file = rcu_dereference_protected(fdt->fd[fd],
+					 lockdep_is_held(&files->file_lock) ||
+					 atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held.  Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference().  On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
 
 
 There are currently only "universal" versions of the rcu_assign_pointer()
 There are currently only "universal" versions of the rcu_assign_pointer()
 and RCU list-/tree-traversal primitives, which do not (yet) check for
 and RCU list-/tree-traversal primitives, which do not (yet) check for

+ 6 - 0
Documentation/RCU/whatisRCU.txt

@@ -840,6 +840,12 @@ SRCU:	Initialization/cleanup
 	init_srcu_struct
 	init_srcu_struct
 	cleanup_srcu_struct
 	cleanup_srcu_struct
 
 
+All:  lockdep-checked RCU-protected pointer access
+
+	rcu_dereference_check
+	rcu_dereference_protected
+	rcu_access_pointer
+
 See the comment headers in the source code (or the docbook generated
 See the comment headers in the source code (or the docbook generated
 from them) for more information.
 from them) for more information.
 
 

+ 2 - 2
Documentation/block/biodoc.txt

@@ -1162,8 +1162,8 @@ where a driver received a request ala this before:
 
 
 As mentioned, there is no virtual mapping of a bio. For DMA, this is
 As mentioned, there is no virtual mapping of a bio. For DMA, this is
 not a problem as the driver probably never will need a virtual mapping.
 not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (pci_map_page for a single segment or
-use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For
+Instead it needs a bus mapping (dma_map_page for a single segment or
+use dma_map_sg for scatter gather) to be able to ship it to the driver. For
 PIO drivers (or drivers that need to revert to PIO transfer once in a
 PIO drivers (or drivers that need to revert to PIO transfer once in a
 while (IDE for example)), where the CPU is doing the actual data
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
 transfer a virtual mapping is needed. If the driver supports highmem I/O,

+ 17 - 6
Documentation/input/multi-touch-protocol.txt

@@ -68,6 +68,22 @@ like:
    SYN_MT_REPORT
    SYN_MT_REPORT
    SYN_REPORT
    SYN_REPORT
 
 
+Here is the sequence after lifting one of the fingers:
+
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+   SYN_MT_REPORT
+   SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
 
 
 Event Semantics
 Event Semantics
 ---------------
 ---------------
@@ -217,11 +233,6 @@ where examples can be found.
 difference between the contact position and the approaching tool position
 difference between the contact position and the approaching tool position
 could be used to derive tilt.
 could be used to derive tilt.
 [2] The list can of course be extended.
 [2] The list can of course be extended.
-[3] The multi-touch X driver is currently in the prototyping stage. At the
-time of writing (April 2009), the MT protocol is not yet merged, and the
-prototype implements finger matching, basic mouse support and two-finger
-scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the Synaptics X driver, and in addition
-implement more advanced gestures.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
 [4] See the section on event computation.
 [4] See the section on event computation.
 [5] See the section on finger tracking.
 [5] See the section on finger tracking.

+ 0 - 5
Documentation/kernel-parameters.txt

@@ -320,11 +320,6 @@ and is between 256 and 4096 characters. It is defined in the file
 	amd_iommu=	[HW,X86-84]
 	amd_iommu=	[HW,X86-84]
 			Pass parameters to the AMD IOMMU driver in the system.
 			Pass parameters to the AMD IOMMU driver in the system.
 			Possible values are:
 			Possible values are:
-			isolate - enable device isolation (each device, as far
-			          as possible, will get its own protection
-			          domain) [default]
-			share - put every device behind one IOMMU into the
-				same protection domain
 			fullflush - enable flushing of IO/TLB entries when
 			fullflush - enable flushing of IO/TLB entries when
 				    they are unmapped. Otherwise they are
 				    they are unmapped. Otherwise they are
 				    flushed before they will be reused, which
 				    flushed before they will be reused, which

+ 46 - 30
Documentation/networking/timestamping.txt

@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
 SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
 SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
 SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
 SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
 following control message:
 following control message:
-    struct scm_timestamping {
-           struct timespec systime;
-           struct timespec hwtimetrans;
-           struct timespec hwtimeraw;
-    };
+
+struct scm_timestamping {
+	struct timespec systime;
+	struct timespec hwtimetrans;
+	struct timespec hwtimeraw;
+};
 
 
 recvmsg() can be used to get this control message for regular incoming
 recvmsg() can be used to get this control message for regular incoming
 packets. For send time stamps the outgoing packet is looped back to
 packets. For send time stamps the outgoing packet is looped back to
@@ -87,12 +88,13 @@ by the network device and will be empty without that support.
 SIOCSHWTSTAMP:
 SIOCSHWTSTAMP:
 
 
 Hardware time stamping must also be initialized for each device driver
 Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
 
 
 struct hwtstamp_config {
 struct hwtstamp_config {
-    int flags;           /* no flags defined right now, must be zero */
-    int tx_type;         /* HWTSTAMP_TX_* */
-    int rx_filter;       /* HWTSTAMP_FILTER_* */
+	int flags;	/* no flags defined right now, must be zero */
+	int tx_type;	/* HWTSTAMP_TX_* */
+	int rx_filter;	/* HWTSTAMP_FILTER_* */
 };
 };
 
 
 Desired behavior is passed into the kernel and to a specific device by
 Desired behavior is passed into the kernel and to a specific device by
@@ -139,42 +141,56 @@ enum {
 	/* time stamp any incoming packet */
 	/* time stamp any incoming packet */
 	HWTSTAMP_FILTER_ALL,
 	HWTSTAMP_FILTER_ALL,
 
 
-        /* return value: time stamp all packets requested plus some others */
-        HWTSTAMP_FILTER_SOME,
+	/* return value: time stamp all packets requested plus some others */
+	HWTSTAMP_FILTER_SOME,
 
 
 	/* PTP v1, UDP, any kind of event packet */
 	/* PTP v1, UDP, any kind of event packet */
 	HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
 	HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
 
 
-        ...
+	/* for the complete list of values, please check
+	 * the include file /include/linux/net_tstamp.h
+	 */
 };
 };
 
 
 
 
 DEVICE IMPLEMENTATION
 DEVICE IMPLEMENTATION
 
 
 A driver which supports hardware time stamping must support the
 A driver which supports hardware time stamping must support the
-SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
-in the skb with skb_hwtstamp_set().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+	/* hardware time stamp transformed into duration
+	 * since arbitrary point in time
+	 */
+	ktime_t	hwtstamp;
+	ktime_t	syststamp; /* hwtstamp transformed to system time base */
+};
 
 
 Time stamps for outgoing packets are to be generated as follows:
 Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
-  returns non-zero. If yes, then the driver is expected
-  to do hardware time stamping.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
+  If yes, then the driver is expected to do hardware time stamping.
 - If this is possible for the skb and requested, then declare
 - If this is possible for the skb and requested, then declare
-  that the driver is doing the time stamping by calling
-  skb_hwtstamp_tx_in_progress(). A driver not supporting
-  hardware time stamping doesn't do that. A driver must never
-  touch sk_buff::tstamp! It is used to store how time stamping
-  for an outgoing packets is to be done.
+  that the driver is doing the time stamping by setting the field
+  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+  to the associated skb for the next step and not free the skb. A driver
+  not supporting hardware time stamping doesn't do that. A driver must
+  never touch sk_buff::tstamp! It is used to store software generated
+  time stamps by the network subsystem.
 - As soon as the driver has sent the packet and/or obtained a
 - As soon as the driver has sent the packet and/or obtained a
   hardware time stamp for it, it passes the time stamp back by
   hardware time stamp for it, it passes the time stamp back by
   calling skb_hwtstamp_tx() with the original skb, the raw
   calling skb_hwtstamp_tx() with the original skb, the raw
-  hardware time stamp and a handle to the device (necessary
-  to convert the hardware time stamp to system time). If obtaining
-  the hardware time stamp somehow fails, then the driver should
-  not fall back to software time stamping. The rationale is that
-  this would occur at a later time in the processing pipeline
-  than other software time stamping and therefore could lead
-  to unexpected deltas between time stamps.
-- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+  hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+  adds the timestamps, therefore the original skb has to be freed now.
+  If obtaining the hardware time stamp somehow fails, then the driver
+  should not fall back to software time stamping. The rationale is that
+  this would occur at a later time in the processing pipeline than other
+  software time stamping and therefore could lead to unexpected deltas
+  between time stamps.
+- If the driver did not call set skb_tx(skb)->in_progress, then
   dev_hard_start_xmit() checks whether software time stamping
   dev_hard_start_xmit() checks whether software time stamping
   is wanted as fallback and potentially generates the time stamp.
   is wanted as fallback and potentially generates the time stamp.

+ 12 - 2
MAINTAINERS

@@ -485,8 +485,8 @@ S:	Maintained
 F:	drivers/input/mouse/bcm5974.c
 F:	drivers/input/mouse/bcm5974.c
 
 
 APPLE SMC DRIVER
 APPLE SMC DRIVER
-M:	Nicolas Boichat <nicolas@boichat.ch>
-L:	mactel-linux-devel@lists.sourceforge.net
+M:	Henrik Rydberg <rydberg@euromail.se>
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 S:	Maintained
 F:	drivers/hwmon/applesmc.c
 F:	drivers/hwmon/applesmc.c
 
 
@@ -971,6 +971,16 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.mcuos.com
 W:	http://www.mcuos.com
 S:	Maintained
 S:	Maintained
 
 
+ARM/U300 MACHINE SUPPORT
+M:	Linus Walleij <linus.walleij@stericsson.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Supported
+F:	arch/arm/mach-u300/
+F:	drivers/i2c/busses/i2c-stu300.c
+F:	drivers/rtc/rtc-coh901331.c
+F:	drivers/watchdog/coh901327_wdt.c
+F:	drivers/dma/coh901318*
+
 ARM/U8500 ARM ARCHITECTURE
 ARM/U8500 ARM ARCHITECTURE
 M:	Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 M:	Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)

+ 2 - 2
Makefile

@@ -1,8 +1,8 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 34
 SUBLEVEL = 34
-EXTRAVERSION = -rc3
-NAME = Man-Eating Seals of Antiquity
+EXTRAVERSION = -rc5
+NAME = Sheep on Meth
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
 # To see a list of typical targets execute "make help"

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

@@ -172,7 +172,7 @@ not_angel:
 		adr	r0, LC0
 		adr	r0, LC0
  ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
  ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
  THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip}	)
  THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, r11, ip}	)
- THUMB(		ldr	sp, [r0, #28]				)
+ THUMB(		ldr	sp, [r0, #32]				)
 		subs	r0, r0, r1		@ calculate the delta offset
 		subs	r0, r0, r1		@ calculate the delta offset
 
 
 						@ if delta is zero, we are
 						@ if delta is zero, we are

+ 14 - 1
arch/arm/include/asm/highmem.h

@@ -11,7 +11,11 @@
 
 
 #define kmap_prot		PAGE_KERNEL
 #define kmap_prot		PAGE_KERNEL
 
 
-#define flush_cache_kmaps()	flush_cache_all()
+#define flush_cache_kmaps() \
+	do { \
+		if (cache_is_vivt()) \
+			flush_cache_all(); \
+	} while (0)
 
 
 extern pte_t *pkmap_page_table;
 extern pte_t *pkmap_page_table;
 
 
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void kunmap_high(struct page *page);
 extern void kunmap_high(struct page *page);
 
 
+extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
 extern void *kmap(struct page *page);
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
 extern void kunmap(struct page *page);
 extern void *kmap_atomic(struct page *page, enum km_type type);
 extern void *kmap_atomic(struct page *page, enum km_type type);
 extern void kunmap_atomic(void *kvaddr, enum km_type type);
 extern void kunmap_atomic(void *kvaddr, enum km_type type);
 extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 extern struct page *kmap_atomic_to_page(const void *ptr);
 extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
 
 
 #endif
 #endif

+ 1 - 0
arch/arm/include/asm/kmap_types.h

@@ -18,6 +18,7 @@ enum km_type {
 	KM_IRQ1,
 	KM_IRQ1,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ0,
 	KM_SOFTIRQ1,
 	KM_SOFTIRQ1,
+	KM_L1_CACHE,
 	KM_L2_CACHE,
 	KM_L2_CACHE,
 	KM_TYPE_NR
 	KM_TYPE_NR
 };
 };

+ 11 - 12
arch/arm/include/asm/ucontext.h

@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
 #endif /* CONFIG_IWMMXT */
 #endif /* CONFIG_IWMMXT */
 
 
 #ifdef CONFIG_VFP
 #ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax.  This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment.  */
 #define VFP_MAGIC		0x56465001
 #define VFP_MAGIC		0x56465001
-#define VFP_STORAGE_SIZE	152
-#else
-#define VFP_MAGIC		0x56465002
-#define VFP_STORAGE_SIZE	144
-#endif
 
 
 struct vfp_sigframe
 struct vfp_sigframe
 {
 {
 	unsigned long		magic;
 	unsigned long		magic;
 	unsigned long		size;
 	unsigned long		size;
-	union vfp_state		storage;
-};
+	struct user_vfp		ufp;
+	struct user_vfp_exc	ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ *  8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ *  4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE	sizeof(struct vfp_sigframe)
+
 #endif /* CONFIG_VFP */
 #endif /* CONFIG_VFP */
 
 
 /*
 /*
@@ -91,7 +90,7 @@ struct aux_sigframe {
 #ifdef CONFIG_IWMMXT
 #ifdef CONFIG_IWMMXT
 	struct iwmmxt_sigframe	iwmmxt;
 	struct iwmmxt_sigframe	iwmmxt;
 #endif
 #endif
-#if 0 && defined CONFIG_VFP /* Not yet saved.  */
+#ifdef CONFIG_VFP
 	struct vfp_sigframe	vfp;
 	struct vfp_sigframe	vfp;
 #endif
 #endif
 	/* Something that isn't a valid magic number for any coprocessor.  */
 	/* Something that isn't a valid magic number for any coprocessor.  */

+ 11 - 1
arch/arm/include/asm/user.h

@@ -83,11 +83,21 @@ struct user{
 
 
 /*
 /*
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
  */
  */
 struct user_vfp {
 struct user_vfp {
 	unsigned long long fpregs[32];
 	unsigned long long fpregs[32];
 	unsigned long fpscr;
 	unsigned long fpscr;
 };
 };
 
 
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+	unsigned long	fpexc;
+	unsigned long	fpinst;
+	unsigned long	fpinst2;
+};
+
 #endif /* _ARM_USER_H */
 #endif /* _ARM_USER_H */

+ 89 - 4
arch/arm/kernel/signal.c

@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
 #include <asm/unistd.h>
+#include <asm/vfp.h>
 
 
 #include "ptrace.h"
 #include "ptrace.h"
 #include "signal.h"
 #include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
 
 
 #endif
 #endif
 
 
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+	struct thread_info *thread = current_thread_info();
+	struct vfp_hard_struct *h = &thread->vfpstate.hard;
+	const unsigned long magic = VFP_MAGIC;
+	const unsigned long size = VFP_STORAGE_SIZE;
+	int err = 0;
+
+	vfp_sync_hwstate(thread);
+	__put_user_error(magic, &frame->magic, err);
+	__put_user_error(size, &frame->size, err);
+
+	/*
+	 * Copy the floating point registers. There can be unused
+	 * registers see asm/hwcap.h for details.
+	 */
+	err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+			      sizeof(h->fpregs));
+	/*
+	 * Copy the status and control register.
+	 */
+	__put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+	/*
+	 * Copy the exception registers.
+	 */
+	__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+	__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+	__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+	return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+	struct thread_info *thread = current_thread_info();
+	struct vfp_hard_struct *h = &thread->vfpstate.hard;
+	unsigned long magic;
+	unsigned long size;
+	unsigned long fpexc;
+	int err = 0;
+
+	__get_user_error(magic, &frame->magic, err);
+	__get_user_error(size, &frame->size, err);
+
+	if (err)
+		return -EFAULT;
+	if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+		return -EINVAL;
+
+	/*
+	 * Copy the floating point registers. There can be unused
+	 * registers see asm/hwcap.h for details.
+	 */
+	err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+				sizeof(h->fpregs));
+	/*
+	 * Copy the status and control register.
+	 */
+	__get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+	/*
+	 * Sanitise and restore the exception registers.
+	 */
+	__get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+	/* Ensure the VFP is enabled. */
+	fpexc |= FPEXC_EN;
+	/* Ensure FPINST2 is invalid and the exception flag is cleared. */
+	fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+	h->fpexc = fpexc;
+
+	__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+	__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+	if (!err)
+		vfp_flush_hwstate(thread);
+
+	return err ? -EFAULT : 0;
+}
+
+#endif
+
 /*
 /*
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  */
  */
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
 		err |= restore_iwmmxt_context(&aux->iwmmxt);
 		err |= restore_iwmmxt_context(&aux->iwmmxt);
 #endif
 #endif
 #ifdef CONFIG_VFP
 #ifdef CONFIG_VFP
-//	if (err == 0)
-//		err |= vfp_restore_state(&sf->aux.vfp);
+	if (err == 0)
+		err |= restore_vfp_context(&aux->vfp);
 #endif
 #endif
 
 
 	return err;
 	return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
 		err |= preserve_iwmmxt_context(&aux->iwmmxt);
 		err |= preserve_iwmmxt_context(&aux->iwmmxt);
 #endif
 #endif
 #ifdef CONFIG_VFP
 #ifdef CONFIG_VFP
-//	if (err == 0)
-//		err |= vfp_save_state(&sf->aux.vfp);
+	if (err == 0)
+		err |= preserve_vfp_context(&aux->vfp);
 #endif
 #endif
 	__put_user_error(0, &aux->end_magic, err);
 	__put_user_error(0, &aux->end_magic, err);
 
 

+ 2 - 2
arch/arm/mach-at91/Makefile

@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_d
 obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o

+ 12 - 4
arch/arm/mach-at91/pm_slowclock.S

@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
 	orr	r3, r3, #(1 << 29)		/* bit 29 always set */
 	orr	r3, r3, #(1 << 29)		/* bit 29 always set */
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
 
-	wait_pllalock
-
 	/* Save PLLB setting and disable it */
 	/* Save PLLB setting and disable it */
 	ldr	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 	ldr	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 	str	r3, .saved_pllbr
 	str	r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
 	mov	r3, #AT91_PMC_PLLCOUNT
 	mov	r3, #AT91_PMC_PLLCOUNT
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
 
-	wait_pllblock
-
 	/* Turn off the main oscillator */
 	/* Turn off the main oscillator */
 	ldr	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
 	ldr	r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
 	bic	r3, r3, #AT91_PMC_MOSCEN
 	bic	r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
 	ldr	r3, .saved_pllbr
 	ldr	r3, .saved_pllbr
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 	str	r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
 
+	tst	r3, #(AT91_PMC_MUL &  0xff0000)
+	bne	1f
+	tst	r3, #(AT91_PMC_MUL & ~0xff0000)
+	beq	2f
+1:
 	wait_pllblock
 	wait_pllblock
+2:
 
 
 	/* Restore PLLA setting */
 	/* Restore PLLA setting */
 	ldr	r3, .saved_pllar
 	ldr	r3, .saved_pllar
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 	str	r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
 
+	tst	r3, #(AT91_PMC_MUL &  0xff0000)
+	bne	3f
+	tst	r3, #(AT91_PMC_MUL & ~0xff0000)
+	beq	4f
+3:
 	wait_pllalock
 	wait_pllalock
+4:
 
 
 #ifdef SLOWDOWN_MASTER_CLOCK
 #ifdef SLOWDOWN_MASTER_CLOCK
 	/*
 	/*

+ 10 - 3
arch/arm/mach-bcmring/dma.c

@@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
 int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 	      int dirtied	/* non-zero if any of the pages were modified */
 	      int dirtied	/* non-zero if any of the pages were modified */
     ) {
     ) {
+
+	int rc = 0;
 	int regionIdx;
 	int regionIdx;
 	int segmentIdx;
 	int segmentIdx;
 	DMA_Region_t *region;
 	DMA_Region_t *region;
 	DMA_Segment_t *segment;
 	DMA_Segment_t *segment;
 
 
+	down(&memMap->lock);
+
 	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
 	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
 		region = &memMap->region[regionIdx];
 		region = &memMap->region[regionIdx];
 
 
@@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 					printk(KERN_ERR
 					printk(KERN_ERR
 					       "%s: vmalloc'd pages are not yet supported\n",
 					       "%s: vmalloc'd pages are not yet supported\n",
 					       __func__);
 					       __func__);
-					return -EINVAL;
+					rc = -EINVAL;
+					goto out;
 				}
 				}
 
 
 			case DMA_MEM_TYPE_KMALLOC:
 			case DMA_MEM_TYPE_KMALLOC:
@@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 					printk(KERN_ERR
 					printk(KERN_ERR
 					       "%s: Unsupported memory type: %d\n",
 					       "%s: Unsupported memory type: %d\n",
 					       __func__, region->memType);
 					       __func__, region->memType);
-					return -EINVAL;
+					rc = -EINVAL;
+					goto out;
 				}
 				}
 			}
 			}
 
 
@@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
 	memMap->numRegionsUsed = 0;
 	memMap->numRegionsUsed = 0;
 	memMap->inUse = 0;
 	memMap->inUse = 0;
 
 
+out:
 	up(&memMap->lock);
 	up(&memMap->lock);
 
 
-	return 0;
+	return rc;
 }
 }
 
 
 EXPORT_SYMBOL(dma_unmap);
 EXPORT_SYMBOL(dma_unmap);

+ 3 - 3
arch/arm/mach-ep93xx/gpio.c

@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 
 
 /*************************************************************************
 /*************************************************************************
- * GPIO handling for EP93xx
+ * Interrupt handling for EP93xx on-chip GPIOs
  *************************************************************************/
  *************************************************************************/
 static unsigned char gpio_int_unmasked[3];
 static unsigned char gpio_int_unmasked[3];
 static unsigned char gpio_int_enabled[3];
 static unsigned char gpio_int_enabled[3];
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3]		= { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
 static const u8 int_en_register_offset[3]	= { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
 static const u8 int_debounce_register_offset[3]	= { 0xa8, 0xc4, 0x64 };
 
 
-void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(unsigned port)
 {
 {
 	BUG_ON(port > 2);
 	BUG_ON(port > 2);
 
 
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
 		EP93XX_GPIO_REG(int_en_register_offset[port]));
 		EP93XX_GPIO_REG(int_en_register_offset[port]));
 }
 }
 
 
-void ep93xx_gpio_int_mask(unsigned line)
+static inline void ep93xx_gpio_int_mask(unsigned line)
 {
 {
 	gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 	gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 }
 }

+ 10 - 0
arch/arm/mach-mx3/Kconfig

@@ -62,6 +62,15 @@ config MACH_MX31_3DS
 	  Include support for MX31PDK (3DS) platform. This includes specific
 	  Include support for MX31PDK (3DS) platform. This includes specific
 	  configurations for the board and its peripherals.
 	  configurations for the board and its peripherals.
 
 
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+	bool "Make the MXC NAND driver use the in flash Bad Block Table"
+	depends on MACH_MX31_3DS
+	depends on MTD_NAND_MXC
+	help
+	  Enable this if you want that the MXC NAND driver uses the in flash
+	  Bad Block Table to know what blocks are bad instead of scanning the
+	  entire flash looking for bad block markers.
+
 config MACH_MX31MOBOARD
 config MACH_MX31MOBOARD
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
 	select ARCH_MX31
 	select ARCH_MX31
@@ -95,6 +104,7 @@ config MACH_PCM043
 config MACH_ARMADILLO5X0
 config MACH_ARMADILLO5X0
 	bool "Support Atmark Armadillo-500 Development Base Board"
 	bool "Support Atmark Armadillo-500 Development Base Board"
 	select ARCH_MX31
 	select ARCH_MX31
+	select MXC_ULPI if USB_ULPI
 	help
 	help
 	  Include support for Atmark Armadillo-500 platform. This includes
 	  Include support for Atmark Armadillo-500 platform. This includes
 	  specific configurations for the board and its peripherals.
 	  specific configurations for the board and its peripherals.

+ 2 - 3
arch/arm/mach-mx3/clock-imx31.c

@@ -468,6 +468,7 @@ static struct clk ahb_clk = {
 	}
 	}
 
 
 DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 
 DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
@@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk,   0, MXC_CCM_CGR1,  0, NULL, NULL, &ahb_clk);
 DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &serial_pll_clk);
 DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ckil_clk);
 DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
@@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk)
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 
 #define _REGISTER_CLOCK(d, n, c) \
 #define _REGISTER_CLOCK(d, n, c) \
 	{ \
 	{ \
@@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "iim", iim_clk)
 	_REGISTER_CLOCK(NULL, "iim", iim_clk)
 	_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
 	_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
 	_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
 	_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
-	_REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
 };
 };
 
 
 int __init mx31_clocks_init(unsigned long fref)
 int __init mx31_clocks_init(unsigned long fref)

+ 18 - 1
arch/arm/mach-mx3/devices.c

@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
 	.resource = imx_ssi_resources1,
 	.resource = imx_ssi_resources1,
 };
 };
 
 
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+	{
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device imx_wdt_device0 = {
+	.name           = "imx-wdt",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(imx_wdt_resources),
+	.resource       = imx_wdt_resources,
+};
+
+static int __init mx3_devices_init(void)
 {
 {
 	if (cpu_is_mx31()) {
 	if (cpu_is_mx31()) {
 		mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
 		mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
 		mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
 		mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+		imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
+		imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
 		mxc_register_device(&mxc_rnga_device, NULL);
 		mxc_register_device(&mxc_rnga_device, NULL);
 	}
 	}
 	if (cpu_is_mx35()) {
 	if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
 		imx_ssi_resources0[1].end = MX35_INT_SSI1;
 		imx_ssi_resources0[1].end = MX35_INT_SSI1;
 		imx_ssi_resources1[1].start = MX35_INT_SSI2;
 		imx_ssi_resources1[1].start = MX35_INT_SSI2;
 		imx_ssi_resources1[1].end = MX35_INT_SSI2;
 		imx_ssi_resources1[1].end = MX35_INT_SSI2;
+		imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+		imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 2 - 1
arch/arm/mach-mx3/devices.h

@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
 extern struct platform_device imx_ssi_device1;
-
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_wdt_device0;

+ 166 - 0
arch/arm/mach-mx3/mach-armadillo5x0.c

@@ -36,6 +36,9 @@
 #include <linux/input.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio_keys.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -52,6 +55,8 @@
 #include <mach/ipu.h>
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/mx3fb.h>
 #include <mach/mxc_nand.h>
 #include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 
 #include "devices.h"
 #include "devices.h"
 #include "crm_regs.h"
 #include "crm_regs.h"
@@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = {
 	/* I2C2 */
 	/* I2C2 */
 	MX31_PIN_CSPI2_MOSI__SCL,
 	MX31_PIN_CSPI2_MOSI__SCL,
 	MX31_PIN_CSPI2_MISO__SDA,
 	MX31_PIN_CSPI2_MISO__SDA,
+	/* OTG */
+	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+	MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+	MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+	MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+	MX31_PIN_USBOTG_STP__USBOTG_STP,
+	/* USB host 2 */
+	IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+	IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
 };
 };
 
 
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+	int err;
+
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+	/* Chip already enabled by hardware */
+	/* OTG phy reset*/
+	err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+	if (err) {
+		pr_err("Failed to request the usb otg reset gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+	if (err) {
+		pr_err("Failed to reset the usb otg phy\n");
+		goto otg_free_reset;
+	}
+
+	gpio_set_value(OTG_RESET, 0/*LOW*/);
+	mdelay(5);
+	gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+	return 0;
+
+otg_free_reset:
+	gpio_free(OTG_RESET);
+	return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+	int err;
+
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+	/* Enable the chip */
+	err = gpio_request(USBH2_CS, "USB-H2-CS");
+	if (err) {
+		pr_err("Failed to request the usb host 2 CS gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+	if (err) {
+		pr_err("Failed to drive the usb host 2 CS gpio\n");
+		goto h2_free_cs;
+	}
+
+	/* H2 phy reset*/
+	err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+	if (err) {
+		pr_err("Failed to request the usb host 2 reset gpio\n");
+		goto h2_free_cs;
+	}
+
+	err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+	if (err) {
+		pr_err("Failed to reset the usb host 2 phy\n");
+		goto h2_free_reset;
+	}
+
+	gpio_set_value(USBH2_RESET, 0/*LOW*/);
+	mdelay(5);
+	gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+	return 0;
+
+h2_free_reset:
+	gpio_free(USBH2_RESET);
+h2_free_cs:
+	gpio_free(USBH2_CS);
+	return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+	.init	= usbotg_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+	.init	= usbh2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+	.flags	= MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
 /* RTC over I2C*/
 /* RTC over I2C*/
 #define ARMADILLO5X0_RTC_GPIO	IOMUX_TO_GPIO(MX31_PIN_SRXD4)
 #define ARMADILLO5X0_RTC_GPIO	IOMUX_TO_GPIO(MX31_PIN_SRXD4)
 
 
@@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void)
 	if (armadillo5x0_i2c_rtc.irq == 0)
 	if (armadillo5x0_i2c_rtc.irq == 0)
 		pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
 		pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
 	i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
 	i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+	/* USB */
+#if defined(CONFIG_USB_ULPI)
+	usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+			USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+	mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+	mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
 }
 }
 
 
 static void __init armadillo5x0_timer_init(void)
 static void __init armadillo5x0_timer_init(void)

+ 97 - 19
arch/arm/mach-mx3/mach-mx31_3ds.c

@@ -23,6 +23,9 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
 #include <linux/smsc911x.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
 
 
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -31,26 +34,96 @@
 #include <asm/memory.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <mach/common.h>
 #include <mach/common.h>
-#include <mach/board-mx31pdk.h>
+#include <mach/board-mx31_3ds.h>
 #include <mach/imx-uart.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 #include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
 #include "devices.h"
 #include "devices.h"
 
 
 /*!
 /*!
- * @file mx31pdk.c
+ * @file mx31_3ds.c
  *
  *
  * @brief This file contains the board-specific initialization routines.
  * @brief This file contains the board-specific initialization routines.
  *
  *
  * @ingroup System
  * @ingroup System
  */
  */
 
 
-static int mx31pdk_pins[] = {
+static int mx31_3ds_pins[] = {
 	/* UART1 */
 	/* UART1 */
 	MX31_PIN_CTS1__CTS1,
 	MX31_PIN_CTS1__CTS1,
 	MX31_PIN_RTS1__RTS1,
 	MX31_PIN_RTS1__RTS1,
 	MX31_PIN_TXD1__TXD1,
 	MX31_PIN_TXD1__TXD1,
 	MX31_PIN_RXD1__RXD1,
 	MX31_PIN_RXD1__RXD1,
 	IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
 	IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+	/* SPI 1 */
+	MX31_PIN_CSPI2_SCLK__SCLK,
+	MX31_PIN_CSPI2_MOSI__MOSI,
+	MX31_PIN_CSPI2_MISO__MISO,
+	MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI2_SS0__SS0,
+	MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+	/* MC13783 IRQ */
+	IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+	.constraints = {
+		.boot_on	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+	{
+		.id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+		.init_data = &pwgtx_init,
+	}, {
+		.id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+		.init_data = &pwgtx_init,
+	},
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+	.regulators = mx31_3ds_regulators,
+	.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+	.flags  = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+	.chipselect	= spi1_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+	{
+		.modalias	= "mc13783",
+		.max_speed_hz	= 1000000,
+		.bus_num	= 1,
+		.chip_select	= 1, /* SS2 */
+		.platform_data	= &mc13783_pdata,
+		.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+		.mode = SPI_CS_HIGH,
+	},
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+	.width		= 1,
+	.hw_ecc		= 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+	.flash_bbt	= 1,
+#endif
 };
 };
 
 
 static struct imxuart_platform_data uart_pdata = {
 static struct imxuart_platform_data uart_pdata = {
@@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = {
  * LEDs, switches, interrupts for Ethernet.
  * LEDs, switches, interrupts for Ethernet.
  */
  */
 
 
-static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
+static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
 {
 {
 	uint32_t imr_val;
 	uint32_t imr_val;
 	uint32_t int_valid;
 	uint32_t int_valid;
@@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = {
 	.unmask = expio_unmask_irq,
 	.unmask = expio_unmask_irq,
 };
 };
 
 
-static int __init mx31pdk_init_expio(void)
+static int __init mx31_3ds_init_expio(void)
 {
 {
 	int i;
 	int i;
 	int ret;
 	int ret;
@@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
+	pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
 		__raw_readw(CPLD_CODE_VER_REG));
 		__raw_readw(CPLD_CODE_VER_REG));
 
 
 	/*
 	/*
@@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void)
 		set_irq_flags(i, IRQF_VALID);
 		set_irq_flags(i, IRQF_VALID);
 	}
 	}
 	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
 	set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
-	set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
+	set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void)
 /*
 /*
  * This structure defines the MX31 memory map.
  * This structure defines the MX31 memory map.
  */
  */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
+static struct map_desc mx31_3ds_io_desc[] __initdata = {
 	{
 	{
 		.virtual = MX31_CS5_BASE_ADDR_VIRT,
 		.virtual = MX31_CS5_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
 		.pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
@@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = {
 /*
 /*
  * Set up static virtual mappings.
  * Set up static virtual mappings.
  */
  */
-static void __init mx31pdk_map_io(void)
+static void __init mx31_3ds_map_io(void)
 {
 {
 	mx31_map_io();
 	mx31_map_io();
-	iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+	iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
 }
 }
 
 
 /*!
 /*!
@@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void)
  */
  */
 static void __init mxc_board_init(void)
 static void __init mxc_board_init(void)
 {
 {
-	mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
-				      "mx31pdk");
+	mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+				      "mx31_3ds");
 
 
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+
+	mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+	spi_register_board_info(mx31_3ds_spi_devs,
+						ARRAY_SIZE(mx31_3ds_spi_devs));
 
 
-	if (!mx31pdk_init_expio())
+	if (!mx31_3ds_init_expio())
 		platform_device_register(&smsc911x_device);
 		platform_device_register(&smsc911x_device);
 }
 }
 
 
-static void __init mx31pdk_timer_init(void)
+static void __init mx31_3ds_timer_init(void)
 {
 {
 	mx31_clocks_init(26000000);
 	mx31_clocks_init(26000000);
 }
 }
 
 
-static struct sys_timer mx31pdk_timer = {
-	.init	= mx31pdk_timer_init,
+static struct sys_timer mx31_3ds_timer = {
+	.init	= mx31_3ds_timer_init,
 };
 };
 
 
 /*
 /*
  * The following uses standard kernel macros defined in arch.h in order to
  * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
+ * initialize __mach_desc_MX31_3DS data structure.
  */
  */
 MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
 MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
 	/* Maintainer: Freescale Semiconductor, Inc. */
 	/* Maintainer: Freescale Semiconductor, Inc. */
 	.phys_io	= MX31_AIPS1_BASE_ADDR,
 	.phys_io	= MX31_AIPS1_BASE_ADDR,
 	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
 	.io_pg_offst	= (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
 	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
 	.boot_params    = MX3x_PHYS_OFFSET + 0x100,
-	.map_io         = mx31pdk_map_io,
+	.map_io         = mx31_3ds_map_io,
 	.init_irq       = mx31_init_irq,
 	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.init_machine   = mxc_board_init,
-	.timer          = &mx31pdk_timer,
+	.timer          = &mx31_3ds_timer,
 MACHINE_END
 MACHINE_END

+ 0 - 1
arch/arm/mach-mx3/mach-pcm037.c

@@ -35,7 +35,6 @@
 #include <linux/can/platform/sja1000.h>
 #include <linux/can/platform/sja1000.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 #include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
 #include <linux/gfp.h>
 #include <linux/gfp.h>
 
 
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>

+ 1 - 1
arch/arm/mach-mx3/mx31lite-db.c

@@ -28,7 +28,6 @@
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
-#include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 
 
@@ -206,5 +205,6 @@ void __init mx31lite_db_init(void)
 	mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
 	mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
 	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
 	mxc_register_device(&mxc_spi_device0, &spi0_pdata);
 	platform_device_register(&litekit_led_device);
 	platform_device_register(&litekit_led_device);
+	mxc_register_device(&imx_wdt_device0, NULL);
 }
 }
 
 

+ 1 - 1
arch/arm/mach-mx5/clock-mx51.c

@@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
 
 
 /* GPT */
 /* GPT */
 DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
 DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
-	NULL,  NULL, &ipg_perclk, NULL);
+	NULL,  NULL, &ipg_clk, NULL);
 DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
 DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
 	NULL,  NULL, &ipg_clk, NULL);
 	NULL,  NULL, &ipg_clk, NULL);
 
 

+ 53 - 0
arch/arm/mach-mx5/cpu.c

@@ -14,9 +14,62 @@
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+	void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+	u32 rev;
+
+	if (!rom) {
+		cpu_silicon_rev = -EINVAL;
+		return;
+	}
+
+	rev = readl(rom + SI_REV);
+	switch (rev) {
+	case 0x1:
+		cpu_silicon_rev = MX51_CHIP_REV_1_0;
+		break;
+	case 0x2:
+		cpu_silicon_rev = MX51_CHIP_REV_1_1;
+		break;
+	case 0x10:
+		cpu_silicon_rev = MX51_CHIP_REV_2_0;
+		break;
+	case 0x20:
+		cpu_silicon_rev = MX51_CHIP_REV_3_0;
+		break;
+	default:
+		cpu_silicon_rev = 0;
+	}
+
+	iounmap(rom);
+}
+
+/*
+ * Returns:
+ *	the silicon revision of the cpu
+ *	-EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+	if (!cpu_is_mx51())
+		return -EINVAL;
+
+	if (cpu_silicon_rev == -1)
+		query_silicon_parameter();
+
+	return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
 static int __init post_cpu_init(void)
 static int __init post_cpu_init(void)
 {
 {
 	unsigned int reg;
 	unsigned int reg;

+ 13 - 19
arch/arm/mach-mx5/mm.c

@@ -34,11 +34,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
 		.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
 		.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
 		.length = MX51_DEBUG_SIZE,
 		.length = MX51_DEBUG_SIZE,
 		.type = MT_DEVICE
 		.type = MT_DEVICE
-	}, {
-		.virtual = MX51_TZIC_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
-		.length = MX51_TZIC_SIZE,
-		.type = MT_DEVICE
 	}, {
 	}, {
 		.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
 		.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
 		.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
@@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
 		.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
 		.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
 		.length = MX51_AIPS2_SIZE,
 		.length = MX51_AIPS2_SIZE,
 		.type = MT_DEVICE
 		.type = MT_DEVICE
-	}, {
-		.virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
-		.length = MX51_NFC_AXI_SIZE,
-		.type = MT_DEVICE
 	},
 	},
 };
 };
 
 
@@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
  */
  */
 void __init mx51_map_io(void)
 void __init mx51_map_io(void)
 {
 {
-	u32 tzic_addr;
-
-	if (mx51_revision() < MX51_CHIP_REV_2_0)
-		tzic_addr = 0x8FFFC000;
-	else
-		tzic_addr = 0xE0003000;
-	mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
-
 	mxc_set_cpu_type(MXC_CPU_MX51);
 	mxc_set_cpu_type(MXC_CPU_MX51);
 	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
 	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
 	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
 	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
@@ -85,5 +67,17 @@ void __init mx51_map_io(void)
 
 
 void __init mx51_init_irq(void)
 void __init mx51_init_irq(void)
 {
 {
-	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+	unsigned long tzic_addr;
+	void __iomem *tzic_virt;
+
+	if (mx51_revision() < MX51_CHIP_REV_2_0)
+		tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+	else
+		tzic_addr = MX51_TZIC_BASE_ADDR;
+
+	tzic_virt = ioremap(tzic_addr, SZ_16K);
+	if (!tzic_virt)
+		panic("unable to map TZIC interrupt controller\n");
+
+	tzic_init_irq(tzic_virt);
 }
 }

+ 1 - 8
arch/arm/mm/copypage-v6.c

@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
 	kfrom = kmap_atomic(from, KM_USER0);
 	kfrom = kmap_atomic(from, KM_USER0);
 	kto = kmap_atomic(to, KM_USER1);
 	kto = kmap_atomic(to, KM_USER1);
 	copy_page(kto, kfrom);
 	copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
-	/*
-	 * kmap_atomic() doesn't set the page virtual address, and
-	 * kunmap_atomic() takes care of cache flushing already.
-	 */
-	if (page_address(to) != NULL)
-#endif
-		__cpuc_flush_dcache_area(kto, PAGE_SIZE);
+	__cpuc_flush_dcache_area(kto, PAGE_SIZE);
 	kunmap_atomic(kto, KM_USER1);
 	kunmap_atomic(kto, KM_USER1);
 	kunmap_atomic(kfrom, KM_USER0);
 	kunmap_atomic(kfrom, KM_USER0);
 }
 }

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

@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
 				vaddr += offset;
 				vaddr += offset;
 				op(vaddr, len, dir);
 				op(vaddr, len, dir);
 				kunmap_high(page);
 				kunmap_high(page);
+			} else if (cache_is_vipt()) {
+				pte_t saved_pte;
+				vaddr = kmap_high_l1_vipt(page, &saved_pte);
+				op(vaddr + offset, len, dir);
+				kunmap_high_l1_vipt(page, saved_pte);
 			}
 			}
 		} else {
 		} else {
 			vaddr = page_address(page) + offset;
 			vaddr = page_address(page) + offset;

+ 15 - 10
arch/arm/mm/flush.c

@@ -13,6 +13,7 @@
 
 
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/cachetype.h>
+#include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
 {
-	void *addr = page_address(page);
-
 	/*
 	/*
 	 * Writeback any data associated with the kernel mapping of this
 	 * Writeback any data associated with the kernel mapping of this
 	 * page.  This ensures that data in the physical page is mutually
 	 * page.  This ensures that data in the physical page is mutually
 	 * coherent with the kernels mapping.
 	 * coherent with the kernels mapping.
 	 */
 	 */
-#ifdef CONFIG_HIGHMEM
-	/*
-	 * kmap_atomic() doesn't set the page virtual address, and
-	 * kunmap_atomic() takes care of cache flushing already.
-	 */
-	if (addr)
-#endif
-		__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+	if (!PageHighMem(page)) {
+		__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+	} else {
+		void *addr = kmap_high_get(page);
+		if (addr) {
+			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+			kunmap_high(page);
+		} else if (cache_is_vipt()) {
+			pte_t saved_pte;
+			addr = kmap_high_l1_vipt(page, &saved_pte);
+			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+			kunmap_high_l1_vipt(page, saved_pte);
+		}
+	}
 
 
 	/*
 	/*
 	 * If this is a page cache page, and we have an aliasing VIPT cache,
 	 * If this is a page cache page, and we have an aliasing VIPT cache,

+ 86 - 1
arch/arm/mm/highmem.c

@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
 	unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 	unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
 
 	if (kvaddr >= (void *)FIXADDR_START) {
 	if (kvaddr >= (void *)FIXADDR_START) {
-		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+		if (cache_is_vivt())
+			__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
 #ifdef CONFIG_DEBUG_HIGHMEM
 		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
 		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
 		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
 	pte = TOP_PTE(vaddr);
 	pte = TOP_PTE(vaddr);
 	return pte_page(*pte);
 	return pte_page(*pte);
 }
 }
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately.  So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed.  If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+	unsigned int idx, cpu = smp_processor_id();
+	int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+	unsigned long vaddr, flags;
+	pte_t pte, *ptep;
+
+	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	ptep = TOP_PTE(vaddr);
+	pte = mk_pte(page, kmap_prot);
+
+	if (!in_interrupt())
+		preempt_disable();
+
+	raw_local_irq_save(flags);
+	(*depth)++;
+	if (pte_val(*ptep) == pte_val(pte)) {
+		*saved_pte = pte;
+	} else {
+		*saved_pte = *ptep;
+		set_pte_ext(ptep, pte, 0);
+		local_flush_tlb_kernel_page(vaddr);
+	}
+	raw_local_irq_restore(flags);
+
+	return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+	unsigned int idx, cpu = smp_processor_id();
+	int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+	unsigned long vaddr, flags;
+	pte_t pte, *ptep;
+
+	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	ptep = TOP_PTE(vaddr);
+	pte = mk_pte(page, kmap_prot);
+
+	BUG_ON(pte_val(*ptep) != pte_val(pte));
+	BUG_ON(*depth <= 0);
+
+	raw_local_irq_save(flags);
+	(*depth)--;
+	if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+		set_pte_ext(ptep, saved_pte, 0);
+		local_flush_tlb_kernel_page(vaddr);
+	}
+	raw_local_irq_restore(flags);
+
+	if (!in_interrupt())
+		preempt_enable();
+}
+
+#endif  /* CONFIG_CPU_CACHE_VIPT */

+ 10 - 4
arch/arm/mm/mmu.c

@@ -420,6 +420,10 @@ static void __init build_mem_type_table(void)
 		user_pgprot |= L_PTE_SHARED;
 		user_pgprot |= L_PTE_SHARED;
 		kern_pgprot |= L_PTE_SHARED;
 		kern_pgprot |= L_PTE_SHARED;
 		vecs_pgprot |= L_PTE_SHARED;
 		vecs_pgprot |= L_PTE_SHARED;
+		mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+		mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+		mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+		mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
 		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
 #endif
@@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
 	pgd_t *pgd;
 	pgd_t *pgd;
 	int i;
 	int i;
 
 
-	if (current->mm && current->mm->pgd)
-		pgd = current->mm->pgd;
-	else
-		pgd = init_mm.pgd;
+	/*
+	 * We need to access to user-mode page tables here. For kernel threads
+	 * we don't have any user-mode mappings so we use the context that we
+	 * "borrowed".
+	 */
+	pgd = current->active_mm->pgd;
 
 
 	base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
 	base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
 	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
 	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())

+ 3 - 3
arch/arm/plat-mxc/include/mach/board-mx31pdk.h → arch/arm/plat-mxc/include/mach/board-mx31_3ds.h

@@ -8,8 +8,8 @@
  * published by the Free Software Foundation.
  * published by the Free Software Foundation.
  */
  */
 
 
-#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
+#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
 
 
 /* Definitions for components on the Debug board */
 /* Definitions for components on the Debug board */
 
 
@@ -56,4 +56,4 @@
 
 
 #define MXC_MAX_EXP_IO_LINES	16
 #define MXC_MAX_EXP_IO_LINES	16
 
 
-#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
+#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */

+ 12 - 21
arch/arm/plat-mxc/include/mach/mx51.h

@@ -14,7 +14,7 @@
  * FB100000	70000000	1M	SPBA 0
  * FB100000	70000000	1M	SPBA 0
  * FB000000	73F00000	1M	AIPS 1
  * FB000000	73F00000	1M	AIPS 1
  * FB200000	83F00000	1M	AIPS 2
  * FB200000	83F00000	1M	AIPS 2
- * FA100000	8FFFC000	16K	TZIC (interrupt controller)
+ *		8FFFC000	16K	TZIC (interrupt controller)
  *         	90000000	256M	CSD0 SDRAM/DDR
  *         	90000000	256M	CSD0 SDRAM/DDR
  *         	A0000000	256M	CSD1 SDRAM/DDR
  *         	A0000000	256M	CSD1 SDRAM/DDR
  *         	B0000000	128M	CS0 Flash
  *         	B0000000	128M	CS0 Flash
@@ -23,10 +23,16 @@
  *         	C8000000	64M	CS3 Flash
  *         	C8000000	64M	CS3 Flash
  *         	CC000000	32M	CS4 SRAM
  *         	CC000000	32M	CS4 SRAM
  *         	CE000000	32M	CS5 SRAM
  *         	CE000000	32M	CS5 SRAM
- * F9000000	CFFF0000	64K	NFC (NAND Flash AXI)
+ *		CFFF0000	64K	NFC (NAND Flash AXI)
  *
  *
  */
  */
 
 
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR		0x0
+#define MX51_IROM_SIZE			SZ_64K
+
 /*
 /*
  * IRAM
  * IRAM
  */
  */
@@ -40,7 +46,6 @@
  * NFC
  * NFC
  */
  */
 #define MX51_NFC_AXI_BASE_ADDR		0xCFFF0000	/* NAND flash AXI */
 #define MX51_NFC_AXI_BASE_ADDR		0xCFFF0000	/* NAND flash AXI */
-#define MX51_NFC_AXI_BASE_ADDR_VIRT	0xF9000000
 #define MX51_NFC_AXI_SIZE		SZ_64K
 #define MX51_NFC_AXI_SIZE		SZ_64K
 
 
 /*
 /*
@@ -49,9 +54,8 @@
 #define MX51_GPU_BASE_ADDR		0x20000000
 #define MX51_GPU_BASE_ADDR		0x20000000
 #define MX51_GPU2D_BASE_ADDR		0xD0000000
 #define MX51_GPU2D_BASE_ADDR		0xD0000000
 
 
-#define MX51_TZIC_BASE_ADDR		0x8FFFC000
-#define MX51_TZIC_BASE_ADDR_VIRT	0xFA100000
-#define MX51_TZIC_SIZE			SZ_16K
+#define MX51_TZIC_BASE_ADDR_TO1		0x8FFFC000
+#define MX51_TZIC_BASE_ADDR		0xE0000000
 
 
 #define MX51_DEBUG_BASE_ADDR		0x60000000
 #define MX51_DEBUG_BASE_ADDR		0x60000000
 #define MX51_DEBUG_BASE_ADDR_VIRT	0xFA200000
 #define MX51_DEBUG_BASE_ADDR_VIRT	0xFA200000
@@ -232,12 +236,10 @@
 #define MX51_IO_ADDRESS(x)					\
 #define MX51_IO_ADDRESS(x)					\
 	(void __iomem *)					\
 	(void __iomem *)					\
 	(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :	\
 	(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :	\
-	MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :	\
 	MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :	\
-	MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) :	\
-	MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
+	MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
 	0xDEADBEEF)
 	0xDEADBEEF)
 
 
 /*
 /*
@@ -246,9 +248,6 @@
 #define MX51_IRAM_IO_ADDRESS(x)  \
 #define MX51_IRAM_IO_ADDRESS(x)  \
 	(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
 	(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
 
 
-#define MX51_TZIC_IO_ADDRESS(x)  \
-	(((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
-
 #define MX51_DEBUG_IO_ADDRESS(x)  \
 #define MX51_DEBUG_IO_ADDRESS(x)  \
 	(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
 	(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
 
 
@@ -261,9 +260,6 @@
 #define MX51_AIPS2_IO_ADDRESS(x)  \
 #define MX51_AIPS2_IO_ADDRESS(x)  \
 	(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
 	(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
 
 
-#define MX51_NFC_AXI_IO_ADDRESS(x) \
-	(((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
-
 #define MX51_IS_MEM_DEVICE_NONSHARED(x)		0
 #define MX51_IS_MEM_DEVICE_NONSHARED(x)		0
 
 
 /*
 /*
@@ -443,12 +439,7 @@
 
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
 
-extern unsigned int system_rev;
-
-static inline unsigned int mx51_revision(void)
-{
-	return system_rev;
-}
+extern int mx51_revision(void);
 #endif
 #endif
 
 
 #endif	/*  __ASM_ARCH_MXC_MX51_H__ */
 #endif	/*  __ASM_ARCH_MXC_MX51_H__ */

+ 4 - 0
arch/arm/plat-mxc/include/mach/uncompress.h

@@ -66,6 +66,7 @@ static inline void flush(void)
 #define MX2X_UART1_BASE_ADDR	0x1000a000
 #define MX2X_UART1_BASE_ADDR	0x1000a000
 #define MX3X_UART1_BASE_ADDR	0x43F90000
 #define MX3X_UART1_BASE_ADDR	0x43F90000
 #define MX3X_UART2_BASE_ADDR	0x43F94000
 #define MX3X_UART2_BASE_ADDR	0x43F94000
+#define MX51_UART1_BASE_ADDR	0x73fbc000
 
 
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
 {
@@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 	case MACH_TYPE_MAGX_ZN5:
 	case MACH_TYPE_MAGX_ZN5:
 		uart_base = MX3X_UART2_BASE_ADDR;
 		uart_base = MX3X_UART2_BASE_ADDR;
 		break;
 		break;
+	case MACH_TYPE_MX51_BABBAGE:
+		uart_base = MX51_UART1_BASE_ADDR;
+		break;
 	default:
 	default:
 		break;
 		break;
 	}
 	}

+ 10 - 21
arch/arm/vfp/vfpmodule.c

@@ -428,26 +428,6 @@ static void vfp_pm_init(void)
 static inline void vfp_pm_init(void) { }
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
 #endif /* CONFIG_PM */
 
 
-/*
- * Synchronise the hardware VFP state of a thread other than current with the
- * saved one. This function is used by the ptrace mechanism.
- */
-#ifdef CONFIG_SMP
-void vfp_sync_hwstate(struct thread_info *thread)
-{
-}
-
-void vfp_flush_hwstate(struct thread_info *thread)
-{
-	/*
-	 * On SMP systems, the VFP state is automatically saved at every
-	 * context switch. We mark the thread VFP state as belonging to a
-	 * non-existent CPU so that the saved one will be reloaded when
-	 * needed.
-	 */
-	thread->vfpstate.hard.cpu = NR_CPUS;
-}
-#else
 void vfp_sync_hwstate(struct thread_info *thread)
 void vfp_sync_hwstate(struct thread_info *thread)
 {
 {
 	unsigned int cpu = get_cpu();
 	unsigned int cpu = get_cpu();
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
 		last_VFP_context[cpu] = NULL;
 		last_VFP_context[cpu] = NULL;
 	}
 	}
 
 
+#ifdef CONFIG_SMP
+	/*
+	 * For SMP we still have to take care of the case where the thread
+	 * migrates to another CPU and then back to the original CPU on which
+	 * the last VFP user is still the same thread. Mark the thread VFP
+	 * state as belonging to a non-existent CPU so that the saved one will
+	 * be reloaded in the above case.
+	 */
+	thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
 	put_cpu();
 	put_cpu();
 }
 }
-#endif
 
 
 #include <linux/smp.h>
 #include <linux/smp.h>
 
 

+ 6 - 2
arch/m68k/include/asm/atomic_mm.h

@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
 {
 	char c;
 	char c;
-	__asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+	__asm__ __volatile__("subl %2,%1; seq %0"
+			     : "=d" (c), "+m" (*v)
+			     : "id" (i));
 	return c != 0;
 	return c != 0;
 }
 }
 
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
 {
 	char c;
 	char c;
-	__asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+	__asm__ __volatile__("addl %2,%1; smi %0"
+			     : "=d" (c), "+m" (*v)
+			     : "id" (i));
 	return c != 0;
 	return c != 0;
 }
 }
 
 

+ 1 - 3
arch/m68k/include/asm/sigcontext.h

@@ -17,13 +17,11 @@ struct sigcontext {
 #ifndef __uClinux__
 #ifndef __uClinux__
 # ifdef __mcoldfire__
 # ifdef __mcoldfire__
 	unsigned long  sc_fpregs[2][2];	/* room for two fp registers */
 	unsigned long  sc_fpregs[2][2];	/* room for two fp registers */
-	unsigned long  sc_fpcntl[3];
-	unsigned char  sc_fpstate[16+6*8];
 # else
 # else
 	unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
 	unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+# endif
 	unsigned long  sc_fpcntl[3];
 	unsigned long  sc_fpcntl[3];
 	unsigned char  sc_fpstate[216];
 	unsigned char  sc_fpstate[216];
-# endif
 #endif
 #endif
 };
 };
 
 

+ 0 - 40
arch/mips/alchemy/devboards/db1200/setup.c

@@ -60,43 +60,6 @@ void __init board_setup(void)
 	wmb();
 	wmb();
 }
 }
 
 
-/* use the hexleds to count the number of times the cpu has entered
- * wait, the dots to indicate whether the CPU is currently idle or
- * active (dots off = sleeping, dots on = working) for cases where
- * the number doesn't change for a long(er) period of time.
- */
-static void db1200_wait(void)
-{
-	__asm__("	.set	push			\n"
-		"	.set	mips3			\n"
-		"	.set	noreorder		\n"
-		"	cache	0x14, 0(%0)		\n"
-		"	cache	0x14, 32(%0)		\n"
-		"	cache	0x14, 64(%0)		\n"
-		/* dots off: we're about to call wait */
-		"	lui	$26, 0xb980		\n"
-		"	ori	$27, $0, 3		\n"
-		"	sb	$27, 0x18($26)		\n"
-		"	sync				\n"
-		"	nop				\n"
-		"	wait				\n"
-		"	nop				\n"
-		"	nop				\n"
-		"	nop				\n"
-		"	nop				\n"
-		"	nop				\n"
-		/* dots on: there's work to do, increment cntr */
-		"	lui	$26, 0xb980		\n"
-		"	sb	$0, 0x18($26)		\n"
-		"	lui	$26, 0xb9c0		\n"
-		"	lb	$27, 0($26)		\n"
-		"	addiu	$27, $27, 1		\n"
-		"	sb	$27, 0($26)		\n"
-		"	sync				\n"
-		"	.set	pop			\n"
-		: : "r" (db1200_wait));
-}
-
 static int __init db1200_arch_init(void)
 static int __init db1200_arch_init(void)
 {
 {
 	/* GPIO7 is low-level triggered CPLD cascade */
 	/* GPIO7 is low-level triggered CPLD cascade */
@@ -110,9 +73,6 @@ static int __init db1200_arch_init(void)
 	irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
 	irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
 	irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
 	irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
 
 
-	if (cpu_wait)
-		cpu_wait = db1200_wait;
-
 	return 0;
 	return 0;
 }
 }
 arch_initcall(db1200_arch_init);
 arch_initcall(db1200_arch_init);

+ 2 - 1
arch/mips/ar7/platform.c

@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
 		.on	= vlynq_on,
 		.on	= vlynq_on,
 		.off	= vlynq_off,
 		.off	= vlynq_off,
 	},
 	},
-	.reset_bit	= 26,
+	.reset_bit	= 16,
 	.gpio_bit	= 19,
 	.gpio_bit	= 19,
 };
 };
 
 
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
 	}
 	}
 
 
 	if (ar7_has_high_cpmac()) {
 	if (ar7_has_high_cpmac()) {
+		res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
 		if (!res) {
 		if (!res) {
 			cpmac_get_mac(1, cpmac_high_data.dev_addr);
 			cpmac_get_mac(1, cpmac_high_data.dev_addr);
 
 

+ 147 - 84
arch/mips/bcm63xx/boards/board_bcm963xx.c

@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
 	.name				= "96338GW",
 	.name				= "96338GW",
 	.expected_cpu_id		= 0x6338,
 	.expected_cpu_id		= 0x6338,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 	.enet0 = {
 		.force_speed_100	= 1,
 		.force_speed_100	= 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
 	.name				= "96338W",
 	.name				= "96338W",
 	.expected_cpu_id		= 0x6338,
 	.expected_cpu_id		= 0x6338,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.enet0 = {
 	.enet0 = {
 		.force_speed_100	= 1,
 		.force_speed_100	= 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
 static struct board_info __initdata board_96345gw2 = {
 static struct board_info __initdata board_96345gw2 = {
 	.name				= "96345GW2",
 	.name				= "96345GW2",
 	.expected_cpu_id		= 0x6345,
 	.expected_cpu_id		= 0x6345,
+
+	.has_uart0			= 1,
 };
 };
 #endif
 #endif
 
 
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
 	.name				= "96348R",
 	.name				= "96348R",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
 
 
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
 	.name				= "96348GW-10",
 	.name				= "96348GW-10",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
 	.name				= "96348GW-11",
 	.name				= "96348GW-11",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
 	.name				= "96348GW",
 	.name				= "96348GW",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
 	.name				= "F@ST2404",
 	.name				= "F@ST2404",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
-	.has_enet0			= 1,
-	.has_enet1			= 1,
-	.has_pci			= 1,
+	.has_uart0			= 1,
+        .has_enet0			= 1,
+        .has_enet1			= 1,
+        .has_pci			= 1,
 
 
 	.enet0 = {
 	.enet0 = {
 		.has_phy		= 1,
 		.has_phy		= 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
 	.has_ehci0			= 1,
 	.has_ehci0			= 1,
 };
 };
 
 
+static struct board_info __initdata board_rta1025w_16 = {
+	.name				= "RTA1025W_16",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+};
+
+
 static struct board_info __initdata board_DV201AMR = {
 static struct board_info __initdata board_DV201AMR = {
 	.name				= "DV201AMR",
 	.name				= "DV201AMR",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
 	.has_ohci0			= 1,
 	.has_ohci0			= 1,
 
 
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
 	.name				= "96348GW-A",
 	.name				= "96348GW-A",
 	.expected_cpu_id		= 0x6348,
 	.expected_cpu_id		= 0x6348,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
 	.name				= "96358VW",
 	.name				= "96358VW",
 	.expected_cpu_id		= 0x6358,
 	.expected_cpu_id		= 0x6358,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
 	.name				= "96358VW2",
 	.name				= "96358VW2",
 	.expected_cpu_id		= 0x6358,
 	.expected_cpu_id		= 0x6358,
 
 
+	.has_uart0			= 1,
 	.has_enet0			= 1,
 	.has_enet0			= 1,
 	.has_enet1			= 1,
 	.has_enet1			= 1,
 	.has_pci			= 1,
 	.has_pci			= 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
 	.name                           = "AGPF-S0",
 	.name                           = "AGPF-S0",
 	.expected_cpu_id                = 0x6358,
 	.expected_cpu_id                = 0x6358,
 
 
+	.has_uart0			= 1,
 	.has_enet0                      = 1,
 	.has_enet0                      = 1,
 	.has_enet1                      = 1,
 	.has_enet1                      = 1,
 	.has_pci                        = 1,
 	.has_pci                        = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
 	.has_ohci0 = 1,
 	.has_ohci0 = 1,
 	.has_ehci0 = 1,
 	.has_ehci0 = 1,
 };
 };
+
+static struct board_info __initdata board_DWVS0 = {
+	.name				= "DWV-S0",
+	.expected_cpu_id		= 0x6358,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0			= 1,
+};
 #endif
 #endif
 
 
 /*
 /*
@@ -552,15 +607,87 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
 	&board_FAST2404,
 	&board_FAST2404,
 	&board_DV201AMR,
 	&board_DV201AMR,
 	&board_96348gw_a,
 	&board_96348gw_a,
+	&board_rta1025w_16,
 #endif
 #endif
 
 
 #ifdef CONFIG_BCM63XX_CPU_6358
 #ifdef CONFIG_BCM63XX_CPU_6358
 	&board_96358vw,
 	&board_96358vw,
 	&board_96358vw2,
 	&board_96358vw2,
 	&board_AGPFS0,
 	&board_AGPFS0,
+	&board_DWVS0,
 #endif
 #endif
 };
 };
 
 
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+	.revision		= 0x02,
+	.board_rev		= 0x17,
+	.country_code		= 0x0,
+	.ant_available_bg 	= 0x3,
+	.pa0b0			= 0x15ae,
+	.pa0b1			= 0xfa85,
+	.pa0b2			= 0xfe8d,
+	.pa1b0			= 0xffff,
+	.pa1b1			= 0xffff,
+	.pa1b2			= 0xffff,
+	.gpio0			= 0xff,
+	.gpio1			= 0xff,
+	.gpio2			= 0xff,
+	.gpio3			= 0xff,
+	.maxpwr_bg		= 0x004c,
+	.itssi_bg		= 0x00,
+	.boardflags_lo		= 0x2848,
+	.boardflags_hi		= 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+	return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+	u8 *p;
+	int count;
+
+	if (mac_addr_used >= nvram.mac_addr_count) {
+		printk(KERN_ERR PFX "not enough mac address\n");
+		return -ENODEV;
+	}
+
+	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+	p = mac + ETH_ALEN - 1;
+	count = mac_addr_used;
+
+	while (count--) {
+		do {
+			(*p)++;
+			if (*p != 0)
+				break;
+			p--;
+		} while (p != mac);
+	}
+
+	if (p == mac) {
+		printk(KERN_ERR PFX "unable to fetch mac address\n");
+		return -ENODEV;
+	}
+
+	mac_addr_used++;
+	return 0;
+}
+
 /*
 /*
  * early init callback, read nvram data from flash and checksum it
  * early init callback, read nvram data from flash and checksum it
  */
  */
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
 	}
 	}
 
 
 	bcm_gpio_writel(val, GPIO_MODE_REG);
 	bcm_gpio_writel(val, GPIO_MODE_REG);
+
+	/* Generate MAC address for WLAN and
+	 * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+			printk(KERN_ERR "failed to register fallback SPROM\n");
+	}
+#endif
 }
 }
 
 
 /*
 /*
@@ -676,49 +814,6 @@ void __init board_setup(void)
 		panic("unexpected CPU for bcm963xx board");
 		panic("unexpected CPU for bcm963xx board");
 }
 }
 
 
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
-	return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-	u8 *p;
-	int count;
-
-	if (mac_addr_used >= nvram.mac_addr_count) {
-		printk(KERN_ERR PFX "not enough mac address\n");
-		return -ENODEV;
-	}
-
-	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-	p = mac + ETH_ALEN - 1;
-	count = mac_addr_used;
-
-	while (count--) {
-		do {
-			(*p)++;
-			if (*p != 0)
-				break;
-			p--;
-		} while (p != mac);
-	}
-
-	if (p == mac) {
-		printk(KERN_ERR PFX "unable to fetch mac address\n");
-		return -ENODEV;
-	}
-
-	mac_addr_used++;
-	return 0;
-}
-
 static struct mtd_partition mtd_partitions[] = {
 static struct mtd_partition mtd_partitions[] = {
 	{
 	{
 		.name		= "cfe",
 		.name		= "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
 	},
 	},
 };
 };
 
 
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
-	.revision		= 0x02,
-	.board_rev		= 0x17,
-	.country_code		= 0x0,
-	.ant_available_bg 	= 0x3,
-	.pa0b0			= 0x15ae,
-	.pa0b1			= 0xfa85,
-	.pa0b2			= 0xfe8d,
-	.pa1b0			= 0xffff,
-	.pa1b1			= 0xffff,
-	.pa1b2			= 0xffff,
-	.gpio0			= 0xff,
-	.gpio1			= 0xff,
-	.gpio2			= 0xff,
-	.gpio3			= 0xff,
-	.maxpwr_bg		= 0x004c,
-	.itssi_bg		= 0x00,
-	.boardflags_lo		= 0x2848,
-	.boardflags_hi		= 0x0000,
-};
-#endif
-
 static struct gpio_led_platform_data bcm63xx_led_data;
 static struct gpio_led_platform_data bcm63xx_led_data;
 
 
 static struct platform_device bcm63xx_gpio_leds = {
 static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
 {
 {
 	u32 val;
 	u32 val;
 
 
+	if (board.has_uart0)
+		bcm63xx_uart_register(0);
+
+	if (board.has_uart1)
+		bcm63xx_uart_register(1);
+
 	if (board.has_pccard)
 	if (board.has_pccard)
 		bcm63xx_pcmcia_register();
 		bcm63xx_pcmcia_register();
 
 
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
 	if (board.has_dsp)
 	if (board.has_dsp)
 		bcm63xx_dsp_register(&board.dsp);
 		bcm63xx_dsp_register(&board.dsp);
 
 
-	/* Generate MAC address for WLAN and
-	 * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-			printk(KERN_ERR "failed to register fallback SPROM\n");
-	}
-#endif
-
 	/* read base address of boot chip select (0) */
 	/* read base address of boot chip select (0) */
 	if (BCMCPU_IS_6345())
 	if (BCMCPU_IS_6345())
 		val = 0x1fc00000;
 		val = 0x1fc00000;

+ 5 - 0
arch/mips/bcm63xx/cpu.c

@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
 	[RSET_TIMER]		= BCM_6338_TIMER_BASE,
 	[RSET_TIMER]		= BCM_6338_TIMER_BASE,
 	[RSET_WDT]		= BCM_6338_WDT_BASE,
 	[RSET_WDT]		= BCM_6338_WDT_BASE,
 	[RSET_UART0]		= BCM_6338_UART0_BASE,
 	[RSET_UART0]		= BCM_6338_UART0_BASE,
+	[RSET_UART1]		= BCM_6338_UART1_BASE,
 	[RSET_GPIO]		= BCM_6338_GPIO_BASE,
 	[RSET_GPIO]		= BCM_6338_GPIO_BASE,
 	[RSET_SPI]		= BCM_6338_SPI_BASE,
 	[RSET_SPI]		= BCM_6338_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6338_OHCI0_BASE,
 	[RSET_OHCI0]		= BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
 	[RSET_TIMER]		= BCM_6345_TIMER_BASE,
 	[RSET_TIMER]		= BCM_6345_TIMER_BASE,
 	[RSET_WDT]		= BCM_6345_WDT_BASE,
 	[RSET_WDT]		= BCM_6345_WDT_BASE,
 	[RSET_UART0]		= BCM_6345_UART0_BASE,
 	[RSET_UART0]		= BCM_6345_UART0_BASE,
+	[RSET_UART1]		= BCM_6345_UART1_BASE,
 	[RSET_GPIO]		= BCM_6345_GPIO_BASE,
 	[RSET_GPIO]		= BCM_6345_GPIO_BASE,
 	[RSET_SPI]		= BCM_6345_SPI_BASE,
 	[RSET_SPI]		= BCM_6345_SPI_BASE,
 	[RSET_UDC0]		= BCM_6345_UDC0_BASE,
 	[RSET_UDC0]		= BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
 	[RSET_TIMER]		= BCM_6348_TIMER_BASE,
 	[RSET_TIMER]		= BCM_6348_TIMER_BASE,
 	[RSET_WDT]		= BCM_6348_WDT_BASE,
 	[RSET_WDT]		= BCM_6348_WDT_BASE,
 	[RSET_UART0]		= BCM_6348_UART0_BASE,
 	[RSET_UART0]		= BCM_6348_UART0_BASE,
+	[RSET_UART1]		= BCM_6348_UART1_BASE,
 	[RSET_GPIO]		= BCM_6348_GPIO_BASE,
 	[RSET_GPIO]		= BCM_6348_GPIO_BASE,
 	[RSET_SPI]		= BCM_6348_SPI_BASE,
 	[RSET_SPI]		= BCM_6348_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6348_OHCI0_BASE,
 	[RSET_OHCI0]		= BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
 	[RSET_TIMER]		= BCM_6358_TIMER_BASE,
 	[RSET_TIMER]		= BCM_6358_TIMER_BASE,
 	[RSET_WDT]		= BCM_6358_WDT_BASE,
 	[RSET_WDT]		= BCM_6358_WDT_BASE,
 	[RSET_UART0]		= BCM_6358_UART0_BASE,
 	[RSET_UART0]		= BCM_6358_UART0_BASE,
+	[RSET_UART1]		= BCM_6358_UART1_BASE,
 	[RSET_GPIO]		= BCM_6358_GPIO_BASE,
 	[RSET_GPIO]		= BCM_6358_GPIO_BASE,
 	[RSET_SPI]		= BCM_6358_SPI_BASE,
 	[RSET_SPI]		= BCM_6358_SPI_BASE,
 	[RSET_OHCI0]		= BCM_6358_OHCI0_BASE,
 	[RSET_OHCI0]		= BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
 static const int bcm96358_irqs[] = {
 static const int bcm96358_irqs[] = {
 	[IRQ_TIMER]		= BCM_6358_TIMER_IRQ,
 	[IRQ_TIMER]		= BCM_6358_TIMER_IRQ,
 	[IRQ_UART0]		= BCM_6358_UART0_IRQ,
 	[IRQ_UART0]		= BCM_6358_UART0_IRQ,
+	[IRQ_UART1]		= BCM_6358_UART1_IRQ,
 	[IRQ_DSL]		= BCM_6358_DSL_IRQ,
 	[IRQ_DSL]		= BCM_6358_DSL_IRQ,
 	[IRQ_ENET0]		= BCM_6358_ENET0_IRQ,
 	[IRQ_ENET0]		= BCM_6358_ENET0_IRQ,
 	[IRQ_ENET1]		= BCM_6358_ENET1_IRQ,
 	[IRQ_ENET1]		= BCM_6358_ENET1_IRQ,

+ 50 - 16
arch/mips/bcm63xx/dev-uart.c

@@ -11,31 +11,65 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_cpu.h>
 
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
 	{
 	{
-		.start		= -1, /* filled at runtime */
-		.end		= -1, /* filled at runtime */
+		/* start & end filled at runtime */
 		.flags		= IORESOURCE_MEM,
 		.flags		= IORESOURCE_MEM,
 	},
 	},
 	{
 	{
-		.start		= -1, /* filled at runtime */
+		/* start filled at runtime */
 		.flags		= IORESOURCE_IRQ,
 		.flags		= IORESOURCE_IRQ,
 	},
 	},
 };
 };
 
 
-static struct platform_device bcm63xx_uart_device = {
-	.name		= "bcm63xx_uart",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(uart_resources),
-	.resource	= uart_resources,
+static struct resource uart1_resources[] = {
+	{
+		/* start & end filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		/* start filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 0,
+		.num_resources	= ARRAY_SIZE(uart0_resources),
+		.resource	= uart0_resources,
+	},
+
+	{
+		.name		= "bcm63xx_uart",
+		.id		= 1,
+		.num_resources	= ARRAY_SIZE(uart1_resources),
+		.resource	= uart1_resources,
+	}
 };
 };
 
 
-int __init bcm63xx_uart_register(void)
+int __init bcm63xx_uart_register(unsigned int id)
 {
 {
-	uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-	uart_resources[0].end = uart_resources[0].start;
-	uart_resources[0].end += RSET_UART_SIZE - 1;
-	uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-	return platform_device_register(&bcm63xx_uart_device);
+	if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+		return -ENODEV;
+
+	if (id == 1 && !BCMCPU_IS_6358())
+		return -ENODEV;
+
+	if (id == 0) {
+		uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+		uart0_resources[0].end = uart0_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+	}
+
+	if (id == 1) {
+		uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+		uart1_resources[0].end = uart1_resources[0].start +
+			RSET_UART_SIZE - 1;
+		uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+	}
+
+	return platform_device_register(&bcm63xx_uart_devices[id]);
 }
 }
-arch_initcall(bcm63xx_uart_register);

+ 2 - 2
arch/mips/bcm63xx/gpio.c

@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
 
 
 int __init bcm63xx_gpio_init(void)
 int __init bcm63xx_gpio_init(void)
 {
 {
+	gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+	gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
 	bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
 	bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
 	pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 	pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
 
 	return gpiochip_add(&bcm63xx_gpio_chip);
 	return gpiochip_add(&bcm63xx_gpio_chip);
 }
 }
-
-arch_initcall(bcm63xx_gpio_init);

+ 1 - 81
arch/mips/cavium-octeon/setup.c

@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
 extern void pci_console_init(const char *arg);
 extern void pci_console_init(const char *arg);
 #endif
 #endif
 
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
 	write_octeon_c0_dcacheerr(0);
 	write_octeon_c0_dcacheerr(0);
 }
 }
 
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-	/*
-	 * The config has selected to wire the reserve32 memory for all
-	 * userspace applications. We need to put a wired TLB entry in for each
-	 * 512MB of reserve32 memory. We only handle double 256MB pages here,
-	 * so reserve32 must be multiple of 512MB.
-	 */
-	uint32_t size = CONFIG_CAVIUM_RESERVE32;
-	uint32_t entrylo0 =
-		0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-	uint32_t entrylo1 = entrylo0 + (256 << 14);
-	uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-	while (size >= 512) {
-#if 0
-		pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-			smp_processor_id(), entryhi);
-#endif
-		add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-		entrylo0 += 512 << 14;
-		entrylo1 += 512 << 14;
-		entryhi += 512 << 20;
-		size -= 512;
-	}
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
 /**
  * Reboot Octeon
  * Reboot Octeon
  *
  *
@@ -294,18 +243,6 @@ static void octeon_halt(void)
 	octeon_kill_core(NULL);
 	octeon_kill_core(NULL);
 }
 }
 
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-	/* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
 /**
  * Handle all the error condition interrupts that might occur.
  * Handle all the error condition interrupts that might occur.
  *
  *
@@ -502,25 +439,13 @@ void __init prom_init(void)
 	 * memory when it is getting memory from the
 	 * memory when it is getting memory from the
 	 * bootloader. Later, after the memory allocations are
 	 * bootloader. Later, after the memory allocations are
 	 * complete, the reserve32 will be freed.
 	 * complete, the reserve32 will be freed.
-	 */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-	if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-		pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-		       "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-		       "is set\n");
-	else
-		addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-							0, 0, 512 << 20,
-							"CAVIUM_RESERVE32", 0);
-#else
-	/*
+	 *
 	 * Allocate memory for RESERVED32 aligned on 2MB boundary. This
 	 * Allocate memory for RESERVED32 aligned on 2MB boundary. This
 	 * is in case we later use hugetlb entries with it.
 	 * is in case we later use hugetlb entries with it.
 	 */
 	 */
 	addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
 	addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
 						0, 0, 2 << 20,
 						0, 0, 2 << 20,
 						"CAVIUM_RESERVE32", 0);
 						"CAVIUM_RESERVE32", 0);
-#endif
 	if (addr < 0)
 	if (addr < 0)
 		pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
 		pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
 	else
 	else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
 		panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
 		panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
 	}
 	}
 #endif
 #endif
-
-	/* This call is here so that it is performed after any TLB
-	   initializations. It needs to be after these in case the
-	   CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-	octeon_hal_setup_reserved32();
 }
 }

+ 0 - 8
arch/mips/cavium-octeon/smp.c

@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
 	uint32_t avail_coremask;
 	uint32_t avail_coremask;
 	struct cvmx_bootmem_named_block_desc *block_desc;
 	struct cvmx_bootmem_named_block_desc *block_desc;
 
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-	/* Disable the watchdog */
-	cvmx_ciu_wdogx_t ciu_wdog;
-	ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-	ciu_wdog.s.mode = 0;
-	cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
 	while (per_cpu(cpu_state, cpu) != CPU_DEAD)
 	while (per_cpu(cpu_state, cpu) != CPU_DEAD)
 		cpu_relax();
 		cpu_relax();
 
 

Plik diff jest za duży
+ 340 - 155
arch/mips/configs/bigsur_defconfig


+ 4 - 2
arch/mips/include/asm/abi.h

@@ -13,12 +13,14 @@
 #include <asm/siginfo.h>
 #include <asm/siginfo.h>
 
 
 struct mips_abi {
 struct mips_abi {
-	int (* const setup_frame)(struct k_sigaction * ka,
+	int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
 	                          struct pt_regs *regs, int signr,
 	                          struct pt_regs *regs, int signr,
 	                          sigset_t *set);
 	                          sigset_t *set);
-	int (* const setup_rt_frame)(struct k_sigaction * ka,
+	const unsigned long	signal_return_offset;
+	int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
 	                       struct pt_regs *regs, int signr,
 	                       struct pt_regs *regs, int signr,
 	                       sigset_t *set, siginfo_t *info);
 	                       sigset_t *set, siginfo_t *info);
+	const unsigned long	rt_signal_return_offset;
 	const unsigned long	restart;
 	const unsigned long	restart;
 };
 };
 
 

+ 5 - 0
arch/mips/include/asm/elf.h

@@ -310,6 +310,7 @@ do {									\
 
 
 #endif /* CONFIG_64BIT */
 #endif /* CONFIG_64BIT */
 
 
+struct pt_regs;
 struct task_struct;
 struct task_struct;
 
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -367,4 +368,8 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 #endif
 
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int uses_interp);
 #endif /* _ASM_ELF_H */
 #endif /* _ASM_ELF_H */

+ 5 - 1
arch/mips/include/asm/fpu_emulator.h

@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 
 
 #define MIPS_FPU_EMU_INC_STATS(M)					\
 #define MIPS_FPU_EMU_INC_STATS(M)					\
-	cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do {									\
+	preempt_disable();						\
+	__local_inc(&__get_cpu_var(fpuemustats).M);			\
+	preempt_enable();						\
+} while (0)
 
 
 #else
 #else
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)

+ 15 - 0
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h

@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
 	RSET_TIMER,
 	RSET_TIMER,
 	RSET_WDT,
 	RSET_WDT,
 	RSET_UART0,
 	RSET_UART0,
+	RSET_UART1,
 	RSET_GPIO,
 	RSET_GPIO,
 	RSET_SPI,
 	RSET_SPI,
 	RSET_UDC0,
 	RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_TIMER_BASE		(0xfffe0200)
 #define BCM_6338_TIMER_BASE		(0xfffe0200)
 #define BCM_6338_WDT_BASE		(0xfffe021c)
 #define BCM_6338_WDT_BASE		(0xfffe021c)
 #define BCM_6338_UART0_BASE		(0xfffe0300)
 #define BCM_6338_UART0_BASE		(0xfffe0300)
+#define BCM_6338_UART1_BASE		(0xdeadbeef)
 #define BCM_6338_GPIO_BASE		(0xfffe0400)
 #define BCM_6338_GPIO_BASE		(0xfffe0400)
 #define BCM_6338_SPI_BASE		(0xfffe0c00)
 #define BCM_6338_SPI_BASE		(0xfffe0c00)
 #define BCM_6338_UDC0_BASE		(0xdeadbeef)
 #define BCM_6338_UDC0_BASE		(0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_TIMER_BASE		(0xfffe0200)
 #define BCM_6345_TIMER_BASE		(0xfffe0200)
 #define BCM_6345_WDT_BASE		(0xfffe021c)
 #define BCM_6345_WDT_BASE		(0xfffe021c)
 #define BCM_6345_UART0_BASE		(0xfffe0300)
 #define BCM_6345_UART0_BASE		(0xfffe0300)
+#define BCM_6345_UART1_BASE		(0xdeadbeef)
 #define BCM_6345_GPIO_BASE		(0xfffe0400)
 #define BCM_6345_GPIO_BASE		(0xfffe0400)
 #define BCM_6345_SPI_BASE		(0xdeadbeef)
 #define BCM_6345_SPI_BASE		(0xdeadbeef)
 #define BCM_6345_UDC0_BASE		(0xdeadbeef)
 #define BCM_6345_UDC0_BASE		(0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_TIMER_BASE		(0xfffe0200)
 #define BCM_6348_TIMER_BASE		(0xfffe0200)
 #define BCM_6348_WDT_BASE		(0xfffe021c)
 #define BCM_6348_WDT_BASE		(0xfffe021c)
 #define BCM_6348_UART0_BASE		(0xfffe0300)
 #define BCM_6348_UART0_BASE		(0xfffe0300)
+#define BCM_6348_UART1_BASE		(0xdeadbeef)
 #define BCM_6348_GPIO_BASE		(0xfffe0400)
 #define BCM_6348_GPIO_BASE		(0xfffe0400)
 #define BCM_6348_SPI_BASE		(0xfffe0c00)
 #define BCM_6348_SPI_BASE		(0xfffe0c00)
 #define BCM_6348_UDC0_BASE		(0xfffe1000)
 #define BCM_6348_UDC0_BASE		(0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_TIMER_BASE		(0xfffe0040)
 #define BCM_6358_TIMER_BASE		(0xfffe0040)
 #define BCM_6358_WDT_BASE		(0xfffe005c)
 #define BCM_6358_WDT_BASE		(0xfffe005c)
 #define BCM_6358_UART0_BASE		(0xfffe0100)
 #define BCM_6358_UART0_BASE		(0xfffe0100)
+#define BCM_6358_UART1_BASE		(0xfffe0120)
 #define BCM_6358_GPIO_BASE		(0xfffe0080)
 #define BCM_6358_GPIO_BASE		(0xfffe0080)
 #define BCM_6358_SPI_BASE		(0xdeadbeef)
 #define BCM_6358_SPI_BASE		(0xdeadbeef)
 #define BCM_6358_UDC0_BASE		(0xfffe0800)
 #define BCM_6358_UDC0_BASE		(0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 		return BCM_6338_WDT_BASE;
 		return BCM_6338_WDT_BASE;
 	case RSET_UART0:
 	case RSET_UART0:
 		return BCM_6338_UART0_BASE;
 		return BCM_6338_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6338_UART1_BASE;
 	case RSET_GPIO:
 	case RSET_GPIO:
 		return BCM_6338_GPIO_BASE;
 		return BCM_6338_GPIO_BASE;
 	case RSET_SPI:
 	case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 		return BCM_6345_WDT_BASE;
 		return BCM_6345_WDT_BASE;
 	case RSET_UART0:
 	case RSET_UART0:
 		return BCM_6345_UART0_BASE;
 		return BCM_6345_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6345_UART1_BASE;
 	case RSET_GPIO:
 	case RSET_GPIO:
 		return BCM_6345_GPIO_BASE;
 		return BCM_6345_GPIO_BASE;
 	case RSET_SPI:
 	case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 		return BCM_6348_WDT_BASE;
 		return BCM_6348_WDT_BASE;
 	case RSET_UART0:
 	case RSET_UART0:
 		return BCM_6348_UART0_BASE;
 		return BCM_6348_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6348_UART1_BASE;
 	case RSET_GPIO:
 	case RSET_GPIO:
 		return BCM_6348_GPIO_BASE;
 		return BCM_6348_GPIO_BASE;
 	case RSET_SPI:
 	case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 		return BCM_6358_WDT_BASE;
 		return BCM_6358_WDT_BASE;
 	case RSET_UART0:
 	case RSET_UART0:
 		return BCM_6358_UART0_BASE;
 		return BCM_6358_UART0_BASE;
+	case RSET_UART1:
+		return BCM_6358_UART1_BASE;
 	case RSET_GPIO:
 	case RSET_GPIO:
 		return BCM_6358_GPIO_BASE;
 		return BCM_6358_GPIO_BASE;
 	case RSET_SPI:
 	case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 enum bcm63xx_irq {
 enum bcm63xx_irq {
 	IRQ_TIMER = 0,
 	IRQ_TIMER = 0,
 	IRQ_UART0,
 	IRQ_UART0,
+	IRQ_UART1,
 	IRQ_DSL,
 	IRQ_DSL,
 	IRQ_ENET0,
 	IRQ_ENET0,
 	IRQ_ENET1,
 	IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
  */
  */
 #define BCM_6358_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
 #define BCM_6358_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ		(IRQ_INTERNAL_BASE + 3)
 #define BCM_6358_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_ENET1_IRQ		(IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET1_IRQ		(IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
 #define BCM_6358_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)

+ 6 - 0
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h

@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */

+ 4 - 0
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h

@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
 	switch (bcm63xx_get_cpu_id()) {
 	switch (bcm63xx_get_cpu_id()) {
 	case BCM6358_CPU_ID:
 	case BCM6358_CPU_ID:
 		return 40;
 		return 40;
+	case BCM6338_CPU_ID:
+		return 8;
+	case BCM6345_CPU_ID:
+		return 16;
 	case BCM6348_CPU_ID:
 	case BCM6348_CPU_ID:
 	default:
 	default:
 		return 37;
 		return 37;

+ 2 - 0
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h

@@ -45,6 +45,8 @@ struct board_info {
 	unsigned int	has_ohci0:1;
 	unsigned int	has_ohci0:1;
 	unsigned int	has_ehci0:1;
 	unsigned int	has_ehci0:1;
 	unsigned int	has_dsp:1;
 	unsigned int	has_dsp:1;
+	unsigned int	has_uart0:1;
+	unsigned int	has_uart1:1;
 
 
 	/* ethernet config */
 	/* ethernet config */
 	struct bcm63xx_enet_platform_data enet0;
 	struct bcm63xx_enet_platform_data enet0;

+ 1 - 1
arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h

@@ -24,7 +24,7 @@
 #define cpu_has_smartmips		0
 #define cpu_has_smartmips		0
 #define cpu_has_vtag_icache		0
 #define cpu_has_vtag_icache		0
 
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases		0
 #define cpu_has_dc_aliases		0
 #endif
 #endif
 
 

+ 5 - 1
arch/mips/include/asm/mach-sibyte/war.h

@@ -16,7 +16,11 @@
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
 
 
-#define BCM1250_M3_WAR	1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR	sb1250_m3_workaround_needed()
 #define SIBYTE_1956_WAR	1
 #define SIBYTE_1956_WAR	1
 
 
 #else
 #else

+ 4 - 1
arch/mips/include/asm/mmu.h

@@ -1,6 +1,9 @@
 #ifndef __ASM_MMU_H
 #ifndef __ASM_MMU_H
 #define __ASM_MMU_H
 #define __ASM_MMU_H
 
 
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+	unsigned long asid[NR_CPUS];
+	void *vdso;
+} mm_context_t;
 
 
 #endif /* __ASM_MMU_H */
 #endif /* __ASM_MMU_H */

+ 1 - 1
arch/mips/include/asm/mmu_context.h

@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
 
 
 #endif
 #endif
 
 
-#define cpu_context(cpu, mm)	((mm)->context[cpu])
+#define cpu_context(cpu, mm)	((mm)->context.asid[cpu])
 #define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
 #define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 
 

+ 4 - 2
arch/mips/include/asm/page.h

@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
 
-#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE + 	\
+								PHYS_OFFSET)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET -	\
+								PHYS_OFFSET)
 
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
 #include <asm-generic/getorder.h>

+ 9 - 2
arch/mips/include/asm/processor.h

@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
 
 
 extern unsigned int vced_count, vcei_count;
 extern unsigned int vced_count, vcei_count;
 
 
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
 #ifdef CONFIG_32BIT
 #ifdef CONFIG_32BIT
 /*
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  * so don't change it unless you know what you are doing.
  */
  */
 #define TASK_SIZE	0x7fff8000UL
 #define TASK_SIZE	0x7fff8000UL
-#define STACK_TOP	TASK_SIZE
+#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 
 /*
 /*
  * This decides where the kernel will search for a free chunk of vm
  * This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
 #define TASK_SIZE32	0x7fff8000UL
 #define TASK_SIZE32	0x7fff8000UL
 #define TASK_SIZE	0x10000000000UL
 #define TASK_SIZE	0x10000000000UL
 #define STACK_TOP	\
 #define STACK_TOP	\
-      (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+	(((test_thread_flag(TIF_32BIT_ADDR) ?				\
+	   TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 
 /*
 /*
  * This decides where the kernel will search for a free chunk of vm
  * This decides where the kernel will search for a free chunk of vm

+ 19 - 0
arch/mips/include/asm/stackframe.h

@@ -121,6 +121,25 @@
 		.endm
 		.endm
 #else
 #else
 		.macro	get_saved_sp	/* Uniprocessor variation */
 		.macro	get_saved_sp	/* Uniprocessor variation */
+#ifdef CONFIG_CPU_LOONGSON2F
+		/*
+		 * Clear BTB (branch target buffer), forbid RAS (return address
+		 * stack) to workaround the Out-of-order Issue in Loongson2F
+		 * via its diagnostic register.
+		 */
+		move	k0, ra
+		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		jal	1f
+		 nop
+1:		move	ra, k0
+		li	k0, 3
+		mtc0	k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 		lui	k1, %hi(kernelsp)
 		lui	k1, %hi(kernelsp)
 #else
 #else

+ 2 - 0
arch/mips/include/asm/uasm.h

@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
 Ip_u1u2u3(_mfc0);
 Ip_u1u2u3(_mfc0);
 Ip_u1u2u3(_mtc0);
 Ip_u1u2u3(_mtc0);
 Ip_u2u1u3(_ori);
 Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
 Ip_u2s3u1(_pref);
 Ip_u2s3u1(_pref);
 Ip_0(_rfe);
 Ip_0(_rfe);
 Ip_u2s3u1(_sc);
 Ip_u2s3u1(_sc);
@@ -102,6 +103,7 @@ Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
 Ip_u2u1u3(_xori);
 Ip_u2u1msbu3(_dins);
 Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
 
 
 /* Handle labels. */
 /* Handle labels. */
 struct uasm_label {
 struct uasm_label {

+ 29 - 0
arch/mips/include/asm/vdso.h

@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+	u32 signal_trampoline[2];
+	u32 rt_signal_trampoline[2];
+};
+#else  /* !CONFIG_32BIT */
+struct mips_vdso {
+	u32 o32_signal_trampoline[2];
+	u32 o32_rt_signal_trampoline[2];
+	u32 rt_signal_trampoline[2];
+	u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */

+ 1 - 1
arch/mips/kernel/Makefile

@@ -6,7 +6,7 @@ extra-y		:= head.o init_task.o vmlinux.lds
 
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 		   ptrace.o reset.o setup.o signal.o syscall.o \
 		   ptrace.o reset.o setup.o signal.o syscall.o \
-		   time.o topology.o traps.o unaligned.o watch.o
+		   time.o topology.o traps.o unaligned.o watch.o vdso.o
 
 
 ifdef CONFIG_FUNCTION_TRACER
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg

+ 4 - 0
arch/mips/kernel/cpufreq/loongson2_clock.c

@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
 	spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 	spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 }
 }
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");

+ 6 - 1
arch/mips/kernel/process.c

@@ -63,8 +63,13 @@ void __noreturn cpu_idle(void)
 
 
 			smtc_idle_loop_hook();
 			smtc_idle_loop_hook();
 #endif
 #endif
-			if (cpu_wait)
+
+			if (cpu_wait) {
+				/* Don't trace irqs off for idle */
+				stop_critical_timings();
 				(*cpu_wait)();
 				(*cpu_wait)();
+				start_critical_timings();
+			}
 		}
 		}
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_HOTPLUG_CPU
 		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
 		if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&

+ 0 - 5
arch/mips/kernel/signal-common.h

@@ -26,11 +26,6 @@
  */
  */
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 				 size_t frame_size);
 				 size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
 /* Check and clear pending FPU exceptions in saved CSR */
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 
 

+ 19 - 67
arch/mips/kernel/signal.c

@@ -32,6 +32,7 @@
 #include <asm/ucontext.h>
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 
 #include "signal-common.h"
 #include "signal-common.h"
 
 
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe {
 struct sigframe {
 	u32 sf_ass[4];		/* argument save space for o32 */
 	u32 sf_ass[4];		/* argument save space for o32 */
-	u32 sf_code[2];		/* signal trampoline */
+	u32 sf_pad[2];		/* Was: signal trampoline */
 	struct sigcontext sf_sc;
 	struct sigcontext sf_sc;
 	sigset_t sf_mask;
 	sigset_t sf_mask;
 };
 };
 
 
 struct rt_sigframe {
 struct rt_sigframe {
 	u32 rs_ass[4];		/* argument save space for o32 */
 	u32 rs_ass[4];		/* argument save space for o32 */
-	u32 rs_code[2];		/* signal trampoline */
+	u32 rs_pad[2];		/* Was: signal trampoline */
 	struct siginfo rs_info;
 	struct siginfo rs_info;
 	struct ucontext rs_uc;
 	struct ucontext rs_uc;
 };
 };
 
 
-#else
-
-struct sigframe {
-	u32 sf_ass[4];			/* argument save space for o32 */
-	u32 sf_pad[2];
-	struct sigcontext sf_sc;	/* hw context */
-	sigset_t sf_mask;
-	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
-};
-
-struct rt_sigframe {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
-	struct siginfo rs_info;
-	struct ucontext rs_uc;
-	u32 rs_code[8] ____cacheline_aligned;	/* signal trampoline */
-};
-
-#endif
-
 /*
 /*
  * Helper routines
  * Helper routines
  */
  */
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 	return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 	return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
 }
 
 
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
-	int err;
-
-	/*
-	 * Set up the return code ...
-	 *
-	 *         li      v0, __NR__foo_sigreturn
-	 *         syscall
-	 */
-
-	err = __put_user(0x24020000 + syscall, tramp + 0);
-	err |= __put_user(0x0000000c         , tramp + 1);
-	if (ICACHE_REFILLS_WORKAROUND_WAR) {
-		err |= __put_user(0, tramp + 2);
-		err |= __put_user(0, tramp + 3);
-		err |= __put_user(0, tramp + 4);
-		err |= __put_user(0, tramp + 5);
-		err |= __put_user(0, tramp + 6);
-		err |= __put_user(0, tramp + 7);
-	}
-	flush_cache_sigtramp((unsigned long) tramp);
-
-	return err;
-}
-
 /*
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  * Atomically swap in the new signal mask, and wait for a signal.
  */
  */
@@ -484,8 +432,8 @@ badframe:
 }
 }
 
 
 #ifdef CONFIG_TRAD_SIGNALS
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+		       struct pt_regs *regs, int signr, sigset_t *set)
 {
 {
 	struct sigframe __user *frame;
 	struct sigframe __user *frame;
 	int err = 0;
 	int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
-	err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
 	err |= setup_sigcontext(regs, &frame->sf_sc);
 	err |= setup_sigcontext(regs, &frame->sf_sc);
 	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
 	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
 	if (err)
 	if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	regs->regs[ 5] = 0;
 	regs->regs[ 5] = 0;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[29] = (unsigned long) frame;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
 }
 }
 #endif
 #endif
 
 
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+			  struct pt_regs *regs,	int signr, sigset_t *set,
+			  siginfo_t *info)
 {
 {
 	struct rt_sigframe __user *frame;
 	struct rt_sigframe __user *frame;
 	int err = 0;
 	int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
-	err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
 	/* Create siginfo.  */
 	/* Create siginfo.  */
 	err |= copy_siginfo_to_user(&frame->rs_info, info);
 	err |= copy_siginfo_to_user(&frame->rs_info, info);
 
 
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
 struct mips_abi mips_abi = {
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
 #ifdef CONFIG_TRAD_SIGNALS
 	.setup_frame	= setup_frame,
 	.setup_frame	= setup_frame,
+	.signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
 #endif
 	.setup_rt_frame	= setup_rt_frame,
 	.setup_rt_frame	= setup_rt_frame,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, rt_signal_trampoline),
 	.restart	= __NR_restart_syscall
 	.restart	= __NR_restart_syscall
 };
 };
 
 
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
 {
 	int ret;
 	int ret;
+	struct mips_abi *abi = current->thread.abi;
+	void *vdso = current->mm->context.vdso;
 
 
 	switch(regs->regs[0]) {
 	switch(regs->regs[0]) {
 	case ERESTART_RESTARTBLOCK:
 	case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	regs->regs[0] = 0;		/* Don't deal with this again.  */
 	regs->regs[0] = 0;		/* Don't deal with this again.  */
 
 
 	if (sig_uses_siginfo(ka))
 	if (sig_uses_siginfo(ka))
-		ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+		ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+					  ka, regs, sig, oldset, info);
 	else
 	else
-		ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+		ret = abi->setup_frame(vdso + abi->signal_return_offset,
+				       ka, regs, sig, oldset);
 
 
 	spin_lock_irq(&current->sighand->siglock);
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);

+ 14 - 41
arch/mips/kernel/signal32.c

@@ -32,6 +32,7 @@
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/fpu.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 
 #include "signal-common.h"
 #include "signal-common.h"
 
 
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
 /*
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
  */
-#define __NR_O32_sigreturn		4119
-#define __NR_O32_rt_sigreturn		4193
 #define __NR_O32_restart_syscall        4253
 #define __NR_O32_restart_syscall        4253
 
 
 /* 32-bit compatibility types */
 /* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 };
 
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe32 {
 struct sigframe32 {
 	u32 sf_ass[4];		/* argument save space for o32 */
 	u32 sf_ass[4];		/* argument save space for o32 */
-	u32 sf_code[2];		/* signal trampoline */
+	u32 sf_pad[2];		/* Was: signal trampoline */
 	struct sigcontext32 sf_sc;
 	struct sigcontext32 sf_sc;
 	compat_sigset_t sf_mask;
 	compat_sigset_t sf_mask;
 };
 };
 
 
 struct rt_sigframe32 {
 struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
+	u32 rs_pad[2];			/* Was: signal trampoline */
 	compat_siginfo_t rs_info;
 	compat_siginfo_t rs_info;
 	struct ucontext32 rs_uc;
 	struct ucontext32 rs_uc;
 };
 };
 
 
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
-	u32 sf_ass[4];			/* argument save space for o32 */
-	u32 sf_pad[2];
-	struct sigcontext32 sf_sc;	/* hw context */
-	compat_sigset_t sf_mask;
-	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
-};
-
-struct rt_sigframe32 {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
-	compat_siginfo_t rs_info;
-	struct ucontext32 rs_uc;
-	u32 rs_code[8] __attribute__((aligned(32)));	/* signal trampoline */
-};
-
-#endif	/* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 /*
 /*
  * sigcontext handlers
  * sigcontext handlers
  */
  */
@@ -598,8 +570,8 @@ badframe:
 	force_sig(SIGSEGV, current);
 	force_sig(SIGSEGV, current);
 }
 }
 
 
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+			  struct pt_regs *regs, int signr, sigset_t *set)
 {
 {
 	struct sigframe32 __user *frame;
 	struct sigframe32 __user *frame;
 	int err = 0;
 	int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
-	err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
 	err |= setup_sigcontext32(regs, &frame->sf_sc);
 	err |= setup_sigcontext32(regs, &frame->sf_sc);
 	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
 
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	regs->regs[ 5] = 0;
 	regs->regs[ 5] = 0;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 	regs->regs[29] = (unsigned long) frame;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->sf_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
 	return -EFAULT;
 	return -EFAULT;
 }
 }
 
 
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-	int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+			     struct pt_regs *regs, int signr, sigset_t *set,
+			     siginfo_t *info)
 {
 {
 	struct rt_sigframe32 __user *frame;
 	struct rt_sigframe32 __user *frame;
 	int err = 0;
 	int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
-	err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
 	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
  */
  */
 struct mips_abi mips_abi_32 = {
 struct mips_abi mips_abi_32 = {
 	.setup_frame	= setup_frame_32,
 	.setup_frame	= setup_frame_32,
+	.signal_return_offset =
+		offsetof(struct mips_vdso, o32_signal_trampoline),
 	.setup_rt_frame	= setup_rt_frame_32,
 	.setup_rt_frame	= setup_rt_frame_32,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
 	.restart	= __NR_O32_restart_syscall
 	.restart	= __NR_O32_restart_syscall
 };
 };
 
 

+ 6 - 20
arch/mips/kernel/signal_n32.c

@@ -39,13 +39,13 @@
 #include <asm/fpu.h>
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 
 #include "signal-common.h"
 #include "signal-common.h"
 
 
 /*
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
  */
-#define __NR_N32_rt_sigreturn		6211
 #define __NR_N32_restart_syscall	6214
 #define __NR_N32_restart_syscall	6214
 
 
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 };
 
 
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
-	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_code[2];			/* signal trampoline */
-	struct compat_siginfo rs_info;
-	struct ucontextn32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
 struct rt_sigframe_n32 {
 struct rt_sigframe_n32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_ass[4];			/* argument save space for o32 */
-	u32 rs_pad[2];
+	u32 rs_pad[2];			/* Was: signal trampoline */
 	struct compat_siginfo rs_info;
 	struct compat_siginfo rs_info;
 	struct ucontextn32 rs_uc;
 	struct ucontextn32 rs_uc;
-	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
 };
 };
 
 
-#endif	/* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
 	force_sig(SIGSEGV, current);
 	force_sig(SIGSEGV, current);
 }
 }
 
 
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
 {
 	struct rt_sigframe_n32 __user *frame;
 	struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 		goto give_sigsegv;
 		goto give_sigsegv;
 
 
-	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
 	/* Create siginfo.  */
 	/* Create siginfo.  */
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 	regs->regs[29] = (unsigned long) frame;
 	regs->regs[29] = (unsigned long) frame;
-	regs->regs[31] = (unsigned long) frame->rs_code;
+	regs->regs[31] = (unsigned long) sig_return;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
 
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
 
 
 struct mips_abi mips_abi_n32 = {
 struct mips_abi mips_abi_n32 = {
 	.setup_rt_frame	= setup_rt_frame_n32,
 	.setup_rt_frame	= setup_rt_frame_n32,
+	.rt_signal_return_offset =
+		offsetof(struct mips_vdso, n32_rt_signal_trampoline),
 	.restart	= __NR_N32_restart_syscall
 	.restart	= __NR_N32_restart_syscall
 };
 };

+ 1 - 1
arch/mips/kernel/smtc.c

@@ -182,7 +182,7 @@ static int vpemask[2][8] = {
 	{0, 0, 0, 0, 0, 0, 0, 1}
 	{0, 0, 0, 0, 0, 0, 0, 1}
 };
 };
 int tcnoprog[NR_CPUS];
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 static int clock_hang_reported[NR_CPUS];
 
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */

+ 5 - 1
arch/mips/kernel/syscall.c

@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	int do_color_align;
 	int do_color_align;
 	unsigned long task_size;
 	unsigned long task_size;
 
 
-	task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+	task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+	task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
 
 
 	if (len > task_size)
 	if (len > task_size)
 		return -ENOMEM;
 		return -ENOMEM;

+ 1 - 1
arch/mips/kernel/traps.c

@@ -1599,7 +1599,7 @@ void __init trap_init(void)
 		ebase = (unsigned long)
 		ebase = (unsigned long)
 			__alloc_bootmem(size, 1 << fls(size), 0);
 			__alloc_bootmem(size, 1 << fls(size), 0);
 	} else {
 	} else {
-		ebase = CAC_BASE;
+		ebase = CKSEG0;
 		if (cpu_has_mips_r2)
 		if (cpu_has_mips_r2)
 			ebase += (read_c0_ebase() & 0x3ffff000);
 			ebase += (read_c0_ebase() & 0x3ffff000);
 	}
 	}

+ 112 - 0
arch/mips/kernel/vdso.c

@@ -0,0 +1,112 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn		4119
+#define __NR_O32_rt_sigreturn		4193
+#define __NR_N32_rt_sigreturn		6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+	uasm_i_addiu(&tramp, 2, 0, sigreturn);	/* li v0, sigreturn */
+	uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+	struct mips_vdso *vdso;
+
+	vdso_page = alloc_page(GFP_KERNEL);
+	if (!vdso_page)
+		panic("Cannot allocate vdso");
+
+	vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+	if (!vdso)
+		panic("Cannot map vdso");
+	clear_page(vdso);
+
+	install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+	install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+	install_trampoline(vdso->n32_rt_signal_trampoline,
+			   __NR_N32_rt_sigreturn);
+	install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+	install_trampoline(vdso->o32_rt_signal_trampoline,
+			   __NR_O32_rt_sigreturn);
+#endif
+
+	vunmap(vdso);
+
+	pr_notice("init_vdso successfull\n");
+
+	return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+	return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+	int ret;
+	unsigned long addr;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+
+	addr = vdso_addr(mm->start_stack);
+
+	addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto up_fail;
+	}
+
+	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+				      VM_READ|VM_EXEC|
+				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+				      VM_ALWAYSDUMP,
+				      &vdso_page);
+
+	if (ret)
+		goto up_fail;
+
+	mm->context.vdso = (void *)addr;
+
+up_fail:
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+		return "[vdso]";
+	return NULL;
+}

+ 2 - 2
arch/mips/lib/delay.c

@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
 
 
 void __udelay(unsigned long us)
 void __udelay(unsigned long us)
 {
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 
 	__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 	__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
 }
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
 
 
 void __ndelay(unsigned long ns)
 void __ndelay(unsigned long ns)
 {
 {
-	unsigned int lpj = current_cpu_data.udelay_val;
+	unsigned int lpj = raw_current_cpu_data.udelay_val;
 
 
 	__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 	__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
 }

+ 1 - 2
arch/mips/lib/libgcc.h

@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #error I feel sick.
 #endif
 #endif
 
 
-typedef union
-{
+typedef union {
 	struct DWstruct s;
 	struct DWstruct s;
 	long long ll;
 	long long ll;
 } DWunion;
 } DWunion;

+ 1 - 1
arch/mips/mm/cache.c

@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
 }
 }
 
 
 unsigned long _page_cachable_default;
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 
 static inline void setup_protection_map(void)
 static inline void setup_protection_map(void)
 {
 {

+ 16 - 6
arch/mips/mm/tlbex.c

@@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 	 * create the plain linear handler
 	 * create the plain linear handler
 	 */
 	 */
 	if (bcm1250_m3_war()) {
 	if (bcm1250_m3_war()) {
-		UASM_i_MFC0(&p, K0, C0_BADVADDR);
-		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+		unsigned int segbits = 44;
+
+		uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+		uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
 		uasm_i_xor(&p, K0, K0, K1);
 		uasm_i_xor(&p, K0, K0, K1);
-		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+		uasm_i_dsrl(&p, K0, K0, 12 + 1);
+		uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+		uasm_i_or(&p, K0, K0, K1);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		/* No need for uasm_i_nop */
 		/* No need for uasm_i_nop */
 	}
 	}
@@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
 	memset(relocs, 0, sizeof(relocs));
 	memset(relocs, 0, sizeof(relocs));
 
 
 	if (bcm1250_m3_war()) {
 	if (bcm1250_m3_war()) {
-		UASM_i_MFC0(&p, K0, C0_BADVADDR);
-		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+		unsigned int segbits = 44;
+
+		uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+		uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
 		uasm_i_xor(&p, K0, K0, K1);
 		uasm_i_xor(&p, K0, K0, K1);
-		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+		uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+		uasm_i_dsrl(&p, K0, K0, 12 + 1);
+		uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+		uasm_i_or(&p, K0, K0, K1);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		uasm_il_bnez(&p, &r, K0, label_leave);
 		/* No need for uasm_i_nop */
 		/* No need for uasm_i_nop */
 	}
 	}

+ 20 - 3
arch/mips/mm/uasm.c

@@ -31,7 +31,8 @@ enum fields {
 	BIMM = 0x040,
 	BIMM = 0x040,
 	JIMM = 0x080,
 	JIMM = 0x080,
 	FUNC = 0x100,
 	FUNC = 0x100,
-	SET = 0x200
+	SET = 0x200,
+	SCIMM = 0x400
 };
 };
 
 
 #define OP_MASK		0x3f
 #define OP_MASK		0x3f
@@ -52,6 +53,8 @@ enum fields {
 #define FUNC_SH		0
 #define FUNC_SH		0
 #define SET_MASK	0x7
 #define SET_MASK	0x7
 #define SET_SH		0
 #define SET_SH		0
+#define SCIMM_MASK	0xfffff
+#define SCIMM_SH	6
 
 
 enum opcode {
 enum opcode {
 	insn_invalid,
 	insn_invalid,
@@ -61,10 +64,10 @@ enum opcode {
 	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
 	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
 	insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
 	insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
 	insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
 	insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-	insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+	insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
 	insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
 	insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
 	insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
 	insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
-	insn_dins
+	insn_dins, insn_syscall
 };
 };
 
 
 struct insn {
 struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
 	{ insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
 	{ insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
 	{ insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
 	{ insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
+	{ insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
 	{ insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
 	{ insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
 	{ insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
 	{ insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
 	{ insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
 	{ insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
 	{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
 	{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+	{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
 	{ insn_invalid, 0, 0 }
 	{ insn_invalid, 0, 0 }
 };
 };
 
 
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
 	return (arg >> 2) & JIMM_MASK;
 	return (arg >> 2) & JIMM_MASK;
 }
 }
 
 
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+	if (arg & ~SCIMM_MASK)
+		printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+	return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
 static inline __cpuinit u32 build_func(u32 arg)
 static inline __cpuinit u32 build_func(u32 arg)
 {
 {
 	if (arg & ~FUNC_MASK)
 	if (arg & ~FUNC_MASK)
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
 		op |= build_func(va_arg(ap, u32));
 		op |= build_func(va_arg(ap, u32));
 	if (ip->fields & SET)
 	if (ip->fields & SET)
 		op |= build_set(va_arg(ap, u32));
 		op |= build_set(va_arg(ap, u32));
+	if (ip->fields & SCIMM)
+		op |= build_scimm(va_arg(ap, u32));
 	va_end(ap);
 	va_end(ap);
 
 
 	**buf = op;
 	**buf = op;
@@ -373,6 +388,7 @@ I_u2s3u1(_lw)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
 I_u2u1u3(_ori)
+I_u3u1u2(_or)
 I_u2s3u1(_pref)
 I_u2s3u1(_pref)
 I_0(_rfe)
 I_0(_rfe)
 I_u2s3u1(_sc)
 I_u2s3u1(_sc)
@@ -391,6 +407,7 @@ I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
 I_u2u1msbu3(_dins);
+I_u1(_syscall);
 
 
 /* Handle labels. */
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)

+ 10 - 0
arch/mips/pci/ops-loongson2.c

@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
 };
 };
 
 
 #ifdef CONFIG_CS5536
 #ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 {
 {
 	struct pci_bus bus = {
 	struct pci_bus bus = {
 		.number = PCI_BUS_CS5536
 		.number = PCI_BUS_CS5536
 	};
 	};
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&msr_lock, flags);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
 	loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+	raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 }
 EXPORT_SYMBOL(_rdmsr);
 EXPORT_SYMBOL(_rdmsr);
 
 
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
 		.number = PCI_BUS_CS5536
 		.number = PCI_BUS_CS5536
 	};
 	};
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
 	u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&msr_lock, flags);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
 	loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+	raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 }
 EXPORT_SYMBOL(_wrmsr);
 EXPORT_SYMBOL(_wrmsr);
 #endif
 #endif

+ 15 - 0
arch/mips/sibyte/sb1250/setup.c

@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
 	return ret;
 	return ret;
 }
 }
 
 
+int sb1250_m3_workaround_needed(void)
+{
+	switch (soc_type) {
+	case K_SYS_SOC_TYPE_BCM1250:
+	case K_SYS_SOC_TYPE_BCM1250_ALT:
+	case K_SYS_SOC_TYPE_BCM1250_ALT2:
+	case K_SYS_SOC_TYPE_BCM1125:
+	case K_SYS_SOC_TYPE_BCM1125H:
+		return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+	default:
+		return 0;
+	}
+}
+
 static int __init setup_bcm112x(void)
 static int __init setup_bcm112x(void)
 {
 {
 	int ret = 0;
 	int ret = 0;

+ 30 - 10
arch/s390/defconfig

@@ -1,7 +1,7 @@
 #
 #
 # Automatically generated make config: don't edit
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 09:03:07 2010
+# Linux kernel version: 2.6.34-rc3
+# Fri Apr  9 09:57:10 2010
 #
 #
 CONFIG_SCHED_MC=y
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
 CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_NO_IOMEM=y
 CONFIG_NO_IOMEM=y
 CONFIG_NO_DMA=y
 CONFIG_NO_DMA=y
 CONFIG_GENERIC_LOCKBREAK=y
 CONFIG_GENERIC_LOCKBREAK=y
@@ -62,15 +63,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_NS=y
@@ -79,6 +76,7 @@ CONFIG_CGROUP_NS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_RELAY is not set
@@ -93,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
 CONFIG_ANON_INODES=y
@@ -126,6 +125,7 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 # CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -134,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
 CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
 
 
 #
 #
@@ -246,6 +247,7 @@ CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_BOOK is not set
 CONFIG_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_AUDIT_ARCH=y
@@ -345,13 +347,13 @@ CONFIG_PM_SLEEP=y
 CONFIG_HIBERNATION=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 CONFIG_PM_STD_PARTITION=""
 # CONFIG_PM_RUNTIME is not set
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_NET=y
 CONFIG_NET=y
 
 
 #
 #
 # Networking options
 # Networking options
 #
 #
 CONFIG_PACKET=y
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_USER is not set
@@ -529,6 +531,7 @@ CONFIG_NET_SCH_FIFO=y
 #
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 CONFIG_CAN=m
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
 CONFIG_CAN_BCM=m
@@ -605,6 +608,7 @@ CONFIG_MISC_DEVICES=y
 #
 #
 # SCSI device support
 # SCSI device support
 #
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_DMA is not set
@@ -863,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_VXFS_FS is not set
@@ -891,6 +896,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_CODA_FS is not set
@@ -952,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_INFO is not set
@@ -973,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 # CONFIG_LATENCYTOP is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_FUNCTION_TRACER is not set
@@ -995,10 +1007,15 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_KPROBE_EVENT=y
+# CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 CONFIG_SAMPLES=y
 CONFIG_SAMPLES=y
+# CONFIG_SAMPLE_TRACEPOINTS is not set
+# CONFIG_SAMPLE_TRACE_EVENTS is not set
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
 # CONFIG_SAMPLE_KPROBES is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 
 #
 #
 # Security options
 # Security options
@@ -1032,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_AUTHENC=m
@@ -1119,7 +1137,7 @@ CONFIG_CRYPTO_SHA512_S390=m
 # CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_AES_S390 is not set
 # CONFIG_CRYPTO_AES_S390 is not set
 CONFIG_S390_PRNG=m
 CONFIG_S390_PRNG=m
-# CONFIG_BINARY_PRINTF is not set
+CONFIG_BINARY_PRINTF=y
 
 
 #
 #
 # Library routines
 # Library routines
@@ -1136,14 +1154,16 @@ CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_NLATTR=y
 CONFIG_NLATTR=y
 CONFIG_HAVE_KVM=y
 CONFIG_HAVE_KVM=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
 CONFIG_KVM=m
+# CONFIG_VHOST_NET is not set
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_RING=y
 CONFIG_VIRTIO_RING=y
 CONFIG_VIRTIO_BALLOON=m
 CONFIG_VIRTIO_BALLOON=m

+ 3 - 3
arch/s390/include/asm/pgtable.h

@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
 #ifndef __ASSEMBLY__
 #ifndef __ASSEMBLY__
 /*
 /*
  * The vmalloc area will always be on the topmost area of the kernel
  * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
  * which should be enough for any sane case.
  * which should be enough for any sane case.
  * By putting vmalloc at the top, we maximise the gap between physical
  * By putting vmalloc at the top, we maximise the gap between physical
  * memory and vmalloc to catch misplaced memory accesses. As a side
  * memory and vmalloc to catch misplaced memory accesses. As a side
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
 #define VMALLOC_END	0x7e000000UL
 #define VMALLOC_END	0x7e000000UL
 #define VMEM_MAP_END	0x80000000UL
 #define VMEM_MAP_END	0x80000000UL
 #else /* __s390x__ */
 #else /* __s390x__ */
-#define VMALLOC_SIZE	(1UL << 30)
-#define VMALLOC_END	0x3e040000000UL
+#define VMALLOC_SIZE	(128UL << 30)
+#define VMALLOC_END	0x3e000000000UL
 #define VMEM_MAP_END	0x40000000000UL
 #define VMEM_MAP_END	0x40000000000UL
 #endif /* __s390x__ */
 #endif /* __s390x__ */
 
 

+ 2 - 1
arch/s390/kernel/early.c

@@ -82,7 +82,8 @@ asm(
 	"	lm	6,15,24(15)\n"
 	"	lm	6,15,24(15)\n"
 #endif
 #endif
 	"	br	14\n"
 	"	br	14\n"
-	"	.size	savesys_ipl_nss, .-savesys_ipl_nss\n");
+	"	.size	savesys_ipl_nss, .-savesys_ipl_nss\n"
+	"	.previous\n");
 
 
 static __initdata char upper_command_line[COMMAND_LINE_SIZE];
 static __initdata char upper_command_line[COMMAND_LINE_SIZE];
 
 

+ 7 - 1
arch/s390/kernel/entry.S

@@ -964,7 +964,7 @@ cleanup_critical:
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop)
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop)
 	bl	BASED(0f)
 	bl	BASED(0f)
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop+4)
 	clc	4(4,%r12),BASED(cleanup_table_io_work_loop+4)
-	bl	BASED(cleanup_io_return)
+	bl	BASED(cleanup_io_work_loop)
 0:
 0:
 	br	%r14
 	br	%r14
 
 
@@ -1038,6 +1038,12 @@ cleanup_sysc_leave_insn:
 	.long	sysc_done - 8 + 0x80000000
 	.long	sysc_done - 8 + 0x80000000
 
 
 cleanup_io_return:
 cleanup_io_return:
+	mvc	__LC_RETURN_PSW(4),0(%r12)
+	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+	la	%r12,__LC_RETURN_PSW
+	br	%r14
+
+cleanup_io_work_loop:
 	mvc	__LC_RETURN_PSW(4),0(%r12)
 	mvc	__LC_RETURN_PSW(4),0(%r12)
 	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
 	mvc	__LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
 	la	%r12,__LC_RETURN_PSW
 	la	%r12,__LC_RETURN_PSW

+ 7 - 1
arch/s390/kernel/entry64.S

@@ -946,7 +946,7 @@ cleanup_critical:
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop)
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop)
 	jl	0f
 	jl	0f
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop+8)
 	clc	8(8,%r12),BASED(cleanup_table_io_work_loop+8)
-	jl	cleanup_io_return
+	jl	cleanup_io_work_loop
 0:
 0:
 	br	%r14
 	br	%r14
 
 
@@ -1020,6 +1020,12 @@ cleanup_sysc_leave_insn:
 	.quad	sysc_done - 16
 	.quad	sysc_done - 16
 
 
 cleanup_io_return:
 cleanup_io_return:
+	mvc	__LC_RETURN_PSW(8),0(%r12)
+	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+	la	%r12,__LC_RETURN_PSW
+	br	%r14
+
+cleanup_io_work_loop:
 	mvc	__LC_RETURN_PSW(8),0(%r12)
 	mvc	__LC_RETURN_PSW(8),0(%r12)
 	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
 	mvc	__LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
 	la	%r12,__LC_RETURN_PSW
 	la	%r12,__LC_RETURN_PSW

+ 2 - 1
arch/s390/kernel/topology.c

@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *info)
 		default:
 		default:
 			clear_cores();
 			clear_cores();
 			machine_has_topology = 0;
 			machine_has_topology = 0;
-			return;
+			goto out;
 		}
 		}
 		tle = next_tle(tle);
 		tle = next_tle(tle);
 	}
 	}
+out:
 	spin_unlock_irq(&topology_lock);
 	spin_unlock_irq(&topology_lock);
 }
 }
 
 

+ 3 - 8
arch/s390/mm/vmem.c

@@ -71,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void)
 		pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
 		pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
 	if (!pte)
 	if (!pte)
 		return NULL;
 		return NULL;
-	if (MACHINE_HAS_HPAGE)
-		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
-			    PTRS_PER_PTE * sizeof(pte_t));
-	else
-		clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-			    PTRS_PER_PTE * sizeof(pte_t));
+	clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+		    PTRS_PER_PTE * sizeof(pte_t));
 	return pte;
 	return pte;
 }
 }
 
 
@@ -117,8 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
 		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
 		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
 		    (address + HPAGE_SIZE <= start + size) &&
 		    (address + HPAGE_SIZE <= start + size) &&
 		    (address >= HPAGE_SIZE)) {
 		    (address >= HPAGE_SIZE)) {
-			pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
-					_SEGMENT_ENTRY_CO;
+			pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
 			pmd_val(*pm_dir) = pte_val(pte);
 			pmd_val(*pm_dir) = pte_val(pte);
 			address += HPAGE_SIZE - PAGE_SIZE;
 			address += HPAGE_SIZE - PAGE_SIZE;
 			continue;
 			continue;

+ 3 - 0
arch/sparc/Kconfig

@@ -37,6 +37,9 @@ config SPARC64
 	def_bool 64BIT
 	def_bool 64BIT
 	select ARCH_SUPPORTS_MSI
 	select ARCH_SUPPORTS_MSI
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_GRAPH_TRACER
+	select HAVE_FUNCTION_GRAPH_FP_TEST
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_KRETPROBES
 	select HAVE_KRETPROBES
 	select HAVE_KPROBES
 	select HAVE_KPROBES
 	select HAVE_LMB
 	select HAVE_LMB

+ 1 - 4
arch/sparc/Kconfig.debug

@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
 	bool "D-cache flush debugging"
 	bool "D-cache flush debugging"
 	depends on SPARC64 && DEBUG_KERNEL
 	depends on SPARC64 && DEBUG_KERNEL
 
 
-config STACK_DEBUG
-	bool "Stack Overflow Detection Support"
-
 config MCOUNT
 config MCOUNT
 	bool
 	bool
 	depends on SPARC64
 	depends on SPARC64
-	depends on STACK_DEBUG || FUNCTION_TRACER
+	depends on FUNCTION_TRACER
 	default y
 	default y
 
 
 config FRAME_POINTER
 config FRAME_POINTER

+ 1 - 1
arch/sparc/include/asm/cpudata_64.h

@@ -17,7 +17,7 @@ typedef struct {
 	unsigned int	__nmi_count;
 	unsigned int	__nmi_count;
 	unsigned long	clock_tick;	/* %tick's per second */
 	unsigned long	clock_tick;	/* %tick's per second */
 	unsigned long	__pad;
 	unsigned long	__pad;
-	unsigned int	__pad1;
+	unsigned int	irq0_irqs;
 	unsigned int	__pad2;
 	unsigned int	__pad2;
 
 
 	/* Dcache line 2, rarely used */
 	/* Dcache line 2, rarely used */

+ 20 - 3
arch/sparc/include/asm/irqflags_64.h

@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
  */
  */
 static inline unsigned long __raw_local_irq_save(void)
 static inline unsigned long __raw_local_irq_save(void)
 {
 {
-	unsigned long flags = __raw_local_save_flags();
-
-	raw_local_irq_disable();
+	unsigned long flags, tmp;
+
+	/* Disable interrupts to PIL_NORMAL_MAX unless we already
+	 * are using PIL_NMI, in which case PIL_NMI is retained.
+	 *
+	 * The only values we ever program into the %pil are 0,
+	 * PIL_NORMAL_MAX and PIL_NMI.
+	 *
+	 * Since PIL_NMI is the largest %pil value and all bits are
+	 * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+	 * actually is.
+	 */
+	__asm__ __volatile__(
+		"rdpr	%%pil, %0\n\t"
+		"or	%0, %2, %1\n\t"
+		"wrpr	%1, 0x0, %%pil"
+		: "=r" (flags), "=r" (tmp)
+		: "i" (PIL_NORMAL_MAX)
+		: "memory"
+	);
 
 
 	return flags;
 	return flags;
 }
 }

+ 9 - 1
arch/sparc/kernel/Makefile

@@ -13,6 +13,14 @@ extra-y     += init_task.o
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 extra-y              += vmlinux.lds
 extra-y              += vmlinux.lds
 
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS).o
 
 
 
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 
 
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o

+ 59 - 1
arch/sparc/kernel/ftrace.c

@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
 
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
 {
-	static u32 call;
+	u32 call;
 	s32 off;
 	s32 off;
 
 
 	off = ((s32)addr - (s32)ip);
 	off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
 	return 0;
 	return 0;
 }
 }
 #endif
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	u32 old, new;
+
+	old = *(u32 *) &ftrace_graph_call;
+	new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+	return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned long ip = (unsigned long)(&ftrace_graph_call);
+	u32 old, new;
+
+	old = *(u32 *) &ftrace_graph_call;
+	new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+	return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+				    unsigned long self_addr,
+				    unsigned long frame_pointer)
+{
+	unsigned long return_hooker = (unsigned long) &return_to_handler;
+	struct ftrace_graph_ent trace;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return parent + 8UL;
+
+	if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+				     frame_pointer) == -EBUSY)
+		return parent + 8UL;
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		return parent + 8UL;
+	}
+
+	return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

+ 10 - 1
arch/sparc/kernel/irq_64.c

@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
 
 
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
@@ -647,6 +648,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 	bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
 	bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
 	if (unlikely(!bucket))
 	if (unlikely(!bucket))
 		return 0;
 		return 0;
+
+	/* The only reference we store to the IRQ bucket is
+	 * by physical address which kmemleak can't see, tell
+	 * it that this object explicitly is not a leak and
+	 * should be scanned.
+	 */
+	kmemleak_not_leak(bucket);
+
 	__flush_dcache_range((unsigned long) bucket,
 	__flush_dcache_range((unsigned long) bucket,
 			     ((unsigned long) bucket +
 			     ((unsigned long) bucket +
 			      sizeof(struct ino_bucket)));
 			      sizeof(struct ino_bucket)));
@@ -721,7 +730,7 @@ static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
 	__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
 	__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
 }
 }
 
 
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
 {
 {
 	unsigned long pstate, bucket_pa;
 	unsigned long pstate, bucket_pa;
 	struct pt_regs *old_regs;
 	struct pt_regs *old_regs;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików