Browse Source

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for MIPS for 4.5 plus some 4.4 fixes.

  The executive summary:

   - ATH79 platform improvments, use DT bindings for the ATH79 USB PHY.
   - Avoid useless rebuilds for zboot.
   - jz4780: Add NEMC, BCH and NAND device tree nodes
   - Initial support for the MicroChip's DT platform.  As all the device
     drivers are missing this is still of limited use.
   - Some Loongson3 cleanups.
   - The unavoidable whitespace polishing.
   - Reduce clock skew when synchronizing the CPU cycle counters on CPU
     startup.
   - Add MIPS R6 fixes.
   - Lots of cleanups across arch/mips as fallout from KVM.
   - Lots of minor fixes and changes for IEEE 754-2008 support to the
     FPU emulator / fp-assist software.
   - Minor Ralink, BCM47xx and bcm963xx platform support improvments.
   - Support SMP on BCM63168"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (84 commits)
  MIPS: zboot: Add support for serial debug using the PROM
  MIPS: zboot: Avoid useless rebuilds
  MIPS: BMIPS: Enable ARCH_WANT_OPTIONAL_GPIOLIB
  MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function
  MIPS: bcm963xx: Update bcm_tag field image_sequence
  MIPS: bcm963xx: Move extended flash address to bcm_tag header file
  MIPS: bcm963xx: Move Broadcom BCM963xx image tag data structure
  MIPS: bcm63xx: nvram: Use nvram structure definition from header file
  MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
  MAINTAINERS: Add KVM for MIPS entry
  MIPS: KVM: Add missing newline to kvm_err()
  MIPS: Move KVM specific opcodes into asm/inst.h
  MIPS: KVM: Use cacheops.h definitions
  MIPS: Break down cacheops.h definitions
  MIPS: Use EXCCODE_ constants with set_except_vector()
  MIPS: Update trap codes
  MIPS: Move Cause.ExcCode trap codes to mipsregs.h
  MIPS: KVM: Make kvm_mips_{init,exit}() static
  MIPS: KVM: Refactor added offsetof()s
  MIPS: KVM: Convert EXPORT_SYMBOL to _GPL
  ...
Linus Torvalds 9 years ago
parent
commit
e2464688b5
100 changed files with 2823 additions and 625 deletions
  1. 67 0
      Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt
  2. 31 0
      Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt
  3. 26 0
      Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt
  4. 61 0
      Documentation/devicetree/bindings/net/ralink,rt2880-net.txt
  5. 32 0
      Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt
  6. 18 0
      Documentation/devicetree/bindings/phy/phy-ath79-usb.txt
  7. 35 0
      Documentation/kernel-parameters.txt
  8. 22 0
      MAINTAINERS
  9. 1 0
      arch/mips/Kbuild.platforms
  10. 16 1
      arch/mips/Kconfig
  11. 0 10
      arch/mips/Makefile
  12. 3 3
      arch/mips/alchemy/common/gpiolib.c
  13. 1 1
      arch/mips/ar7/gpio.c
  14. 0 1
      arch/mips/ath79/common.h
  15. 28 33
      arch/mips/ath79/irq.c
  16. 1 10
      arch/mips/ath79/setup.c
  17. 9 3
      arch/mips/bcm47xx/sprom.c
  18. 3 43
      arch/mips/bcm63xx/nvram.c
  19. 1 0
      arch/mips/bmips/setup.c
  20. 9 6
      arch/mips/boot/compressed/Makefile
  21. 7 0
      arch/mips/boot/compressed/uart-prom.c
  22. 1 0
      arch/mips/boot/dts/Makefile
  23. 9 0
      arch/mips/boot/dts/brcm/bcm6328.dtsi
  24. 22 0
      arch/mips/boot/dts/brcm/bcm6368.dtsi
  25. 64 0
      arch/mips/boot/dts/ingenic/ci20.dts
  26. 26 0
      arch/mips/boot/dts/ingenic/jz4780.dtsi
  27. 12 0
      arch/mips/boot/dts/pic32/Makefile
  28. 236 0
      arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi
  29. 281 0
      arch/mips/boot/dts/pic32/pic32mzda.dtsi
  30. 151 0
      arch/mips/boot/dts/pic32/pic32mzda_sk.dts
  31. 26 0
      arch/mips/boot/dts/qca/ar9132.dtsi
  32. 8 0
      arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
  33. 89 0
      arch/mips/configs/pic32mzda_defconfig
  34. 64 42
      arch/mips/include/asm/cacheops.h
  35. 7 0
      arch/mips/include/asm/cpu-features.h
  36. 2 0
      arch/mips/include/asm/cpu.h
  37. 11 4
      arch/mips/include/asm/elf.h
  38. 1 1
      arch/mips/include/asm/fpu_emulator.h
  39. 1 0
      arch/mips/include/asm/io.h
  40. 0 30
      arch/mips/include/asm/irqflags.h
  41. 1 38
      arch/mips/include/asm/kvm_host.h
  42. 1 0
      arch/mips/include/asm/mach-ath79/ath79.h
  43. 0 2
      arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
  44. 32 0
      arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h
  45. 22 0
      arch/mips/include/asm/mach-pic32/irq.h
  46. 44 0
      arch/mips/include/asm/mach-pic32/pic32.h
  47. 24 0
      arch/mips/include/asm/mach-pic32/spaces.h
  48. 9 0
      arch/mips/include/asm/mach-ralink/irq.h
  49. 38 0
      arch/mips/include/asm/mach-ralink/mt7621.h
  50. 65 0
      arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h
  51. 4 0
      arch/mips/include/asm/mips-cm.h
  52. 1 1
      arch/mips/include/asm/mips-r2-to-r6-emul.h
  53. 34 0
      arch/mips/include/asm/mipsregs.h
  54. 1 1
      arch/mips/include/asm/page.h
  55. 2 2
      arch/mips/include/asm/pgtable.h
  56. 12 3
      arch/mips/include/uapi/asm/inst.h
  57. 4 4
      arch/mips/kernel/cpu-bugs64.c
  58. 161 0
      arch/mips/kernel/cpu-probe.c
  59. 87 15
      arch/mips/kernel/elf.c
  60. 1 1
      arch/mips/kernel/gpio_txx9.c
  61. 0 3
      arch/mips/kernel/ptrace.c
  62. 1 1
      arch/mips/kernel/setup.c
  63. 3 0
      arch/mips/kernel/smp-cps.c
  64. 8 24
      arch/mips/kernel/sync-r4k.c
  65. 26 26
      arch/mips/kernel/traps.c
  66. 1 1
      arch/mips/kvm/callback.c
  67. 3 7
      arch/mips/kvm/dyntrans.c
  68. 50 66
      arch/mips/kvm/emulate.c
  69. 4 4
      arch/mips/kvm/interrupt.c
  70. 6 6
      arch/mips/kvm/locore.S
  71. 19 19
      arch/mips/kvm/mips.c
  72. 0 22
      arch/mips/kvm/opcode.h
  73. 20 57
      arch/mips/kvm/tlb.c
  74. 0 1
      arch/mips/kvm/trap_emul.c
  75. 1 29
      arch/mips/lib/mips-atomic.c
  76. 21 0
      arch/mips/loongson64/Platform
  77. 7 3
      arch/mips/loongson64/loongson-3/hpet.c
  78. 13 7
      arch/mips/loongson64/loongson-3/smp.c
  79. 4 0
      arch/mips/math-emu/cp1emu.c
  80. 25 13
      arch/mips/math-emu/dp_simple.c
  81. 6 3
      arch/mips/math-emu/dp_tint.c
  82. 6 3
      arch/mips/math-emu/dp_tlong.c
  83. 52 25
      arch/mips/math-emu/dsemul.c
  84. 4 2
      arch/mips/math-emu/ieee754.c
  85. 29 13
      arch/mips/math-emu/ieee754.h
  86. 10 2
      arch/mips/math-emu/ieee754dp.c
  87. 6 6
      arch/mips/math-emu/ieee754int.h
  88. 10 2
      arch/mips/math-emu/ieee754sp.c
  89. 8 5
      arch/mips/math-emu/sp_fdp.c
  90. 25 13
      arch/mips/math-emu/sp_simple.c
  91. 6 3
      arch/mips/math-emu/sp_tint.c
  92. 6 3
      arch/mips/math-emu/sp_tlong.c
  93. 1 1
      arch/mips/mm/tlbex.c
  94. 1 0
      arch/mips/pci/Makefile
  95. 426 0
      arch/mips/pci/pci-mt7620.c
  96. 51 0
      arch/mips/pic32/Kconfig
  97. 6 0
      arch/mips/pic32/Makefile
  98. 7 0
      arch/mips/pic32/Platform
  99. 5 0
      arch/mips/pic32/common/Makefile
  100. 21 0
      arch/mips/pic32/common/irq.c

+ 67 - 0
Documentation/devicetree/bindings/interrupt-controller/microchip,pic32-evic.txt

@@ -0,0 +1,67 @@
+Microchip PIC32 Interrupt Controller
+====================================
+
+The Microchip PIC32 contains an Enhanced Vectored Interrupt Controller (EVIC).
+It handles all internal and external interrupts. This controller exists outside
+of the CPU and is the arbitrator of all interrupts (including interrupts from
+the CPU itself) before they are presented to the CPU.
+
+External interrupts have a software configurable edge polarity. Non external
+interrupts have a type and polarity that is determined by the source of the
+interrupt.
+
+Required properties
+-------------------
+
+- compatible: Should be "microchip,pic32mzda-evic"
+- reg: Specifies physical base address and size of register range.
+- interrupt-controller: Identifies the node as an interrupt controller.
+- #interrupt cells: Specifies the number of cells used to encode an interrupt
+  source connected to this controller. The value shall be 2 and interrupt
+  descriptor shall have the following format:
+
+	<hw_irq irq_type>
+
+  hw_irq - represents the hardware interrupt number as in the data sheet.
+  irq_type - is used to describe the type and polarity of an interrupt. For
+  internal interrupts use IRQ_TYPE_EDGE_RISING for non persistent interrupts and
+  IRQ_TYPE_LEVEL_HIGH for persistent interrupts. For external interrupts use
+  IRQ_TYPE_EDGE_RISING or IRQ_TYPE_EDGE_FALLING to select the desired polarity.
+
+Optional properties
+-------------------
+- microchip,external-irqs: u32 array of external interrupts with software
+  polarity configuration. This array corresponds to the bits in the INTCON
+  SFR.
+
+Example
+-------
+
+evic: interrupt-controller@1f810000 {
+	compatible = "microchip,pic32mzda-evic";
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	reg = <0x1f810000 0x1000>;
+	microchip,external-irqs = <3 8 13 18 23>;
+};
+
+Each device/peripheral must request its interrupt line with the associated type
+and polarity.
+
+Internal interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+	...
+	interrupts = <113 IRQ_TYPE_LEVEL_HIGH>;
+	...
+};
+
+External interrupt DTS snippet
+------------------------------
+
+device@1f800000 {
+	...
+	interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+	...
+};

+ 31 - 0
Documentation/devicetree/bindings/mips/pic32/microchip,pic32mzda.txt

@@ -0,0 +1,31 @@
+* Microchip PIC32MZDA Platforms
+
+PIC32MZDA Starter Kit
+Required root node properties:
+    - compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda"
+
+CPU nodes:
+----------
+A "cpus" node is required.  Required properties:
+ - #address-cells: Must be 1.
+ - #size-cells: Must be 0.
+A CPU sub-node is also required.  Required properties:
+ - device_type: Must be "cpu".
+ - compatible: Must be "mti,mips14KEc".
+Example:
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "mti,mips14KEc";
+		};
+	};
+
+Boot protocol
+--------------
+In accordance with Unified Hosting Interface Reference Manual (MD01069), the
+bootloader must pass the following arguments to the kernel:
+ - $a0: -2.
+ - $a1: KSEG0 address of the flattened device-tree blob.

+ 26 - 0
Documentation/devicetree/bindings/net/mediatek,mt7620-gsw.txt

@@ -0,0 +1,26 @@
+Mediatek Gigabit Switch
+=======================
+
+The mediatek gigabit switch can be found on Mediatek SoCs (mt7620, mt7621).
+
+Required properties:
+- compatible: Should be "mediatek,mt7620-gsw" or "mediatek,mt7621-gsw"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the gigabit switches interrupt
+- resets: Should contain the gigabit switches resets
+- reset-names: Should contain the reset names "gsw"
+
+Example:
+
+gsw@10110000 {
+	compatible = "ralink,mt7620-gsw";
+	reg = <0x10110000 8000>;
+
+	resets = <&rstctrl 23>;
+	reset-names = "gsw";
+
+	interrupt-parent = <&intc>;
+	interrupts = <17>;
+};

+ 61 - 0
Documentation/devicetree/bindings/net/ralink,rt2880-net.txt

@@ -0,0 +1,61 @@
+Ralink Frame Engine Ethernet controller
+=======================================
+
+The Ralink frame engine ethernet controller can be found on Ralink and
+Mediatek SoCs (RT288x, RT3x5x, RT366x, RT388x, rt5350, mt7620, mt7621, mt76x8).
+
+Depending on the SoC, there is a number of ports connected to the CPU port
+directly and/or via a (gigabit-)switch.
+
+* Ethernet controller node
+
+Required properties:
+- compatible: Should be one of "ralink,rt2880-eth", "ralink,rt3050-eth",
+  "ralink,rt3050-eth", "ralink,rt3883-eth", "ralink,rt5350-eth",
+  "mediatek,mt7620-eth", "mediatek,mt7621-eth"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the frame engines interrupt
+- resets: Should contain the frame engines resets
+- reset-names: Should contain the reset names "fe". If a switch is present
+  "esw" is also required.
+
+
+* Ethernet port node
+
+Required properties:
+- compatible: Should be "ralink,eth-port"
+- reg: The number of the physical port
+- phy-handle: reference to the node describing the phy
+
+Example:
+
+mdio-bus {
+	...
+	phy0: ethernet-phy@0 {
+		phy-mode = "mii";
+		reg = <0>;
+	};
+};
+
+ethernet@400000 {
+	compatible = "ralink,rt2880-eth";
+	reg = <0x00400000 10000>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	resets = <&rstctrl 18>;
+	reset-names = "fe";
+
+	interrupt-parent = <&cpuintc>;
+	interrupts = <5>;
+
+	port@0 {
+		compatible = "ralink,eth-port";
+		reg = <0>;
+		phy-handle = <&phy0>;
+	};
+
+};

+ 32 - 0
Documentation/devicetree/bindings/net/ralink,rt3050-esw.txt

@@ -0,0 +1,32 @@
+Ralink Fast Ethernet Embedded Switch
+====================================
+
+The ralink fast ethernet embedded switch can be found on Ralink and Mediatek
+SoCs (RT3x5x, RT5350, MT76x8).
+
+Required properties:
+- compatible: Should be "ralink,rt3050-esw"
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the embedded switches interrupt
+- resets: Should contain the embedded switches resets
+- reset-names: Should contain the reset names "esw"
+
+Optional properties:
+- ralink,portmap: can be used to choose if the default switch setup is
+  llllw or wllll
+- ralink,led_polarity: override the active high/low settings of the leds
+
+Example:
+
+esw@10110000 {
+	compatible = "ralink,rt3050-esw";
+	reg = <0x10110000 8000>;
+
+	resets = <&rstctrl 23>;
+	reset-names = "esw";
+
+	interrupt-parent = <&intc>;
+	interrupts = <17>;
+};

+ 18 - 0
Documentation/devicetree/bindings/phy/phy-ath79-usb.txt

@@ -0,0 +1,18 @@
+* Atheros AR71XX/9XXX USB PHY
+
+Required properties:
+- compatible: "qca,ar7100-usb-phy"
+- #phys-cells: should be 0
+- reset-names: "usb-phy"[, "usb-suspend-override"]
+- resets: references to the reset controllers
+
+Example:
+
+	usb-phy {
+		compatible = "qca,ar7100-usb-phy";
+
+		reset-names = "usb-phy", "usb-suspend-override";
+		resets = <&rst 4>, <&rst 3>;
+
+		#phy-cells = <0>;
+	};

+ 35 - 0
Documentation/kernel-parameters.txt

@@ -1454,6 +1454,41 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			In such case C2/C3 won't be used again.
 			In such case C2/C3 won't be used again.
 			idle=nomwait: Disable mwait for CPU C-states
 			idle=nomwait: Disable mwait for CPU C-states
 
 
+	ieee754=	[MIPS] Select IEEE Std 754 conformance mode
+			Format: { strict | legacy | 2008 | relaxed }
+			Default: strict
+
+			Choose which programs will be accepted for execution
+			based on the IEEE 754 NaN encoding(s) supported by
+			the FPU and the NaN encoding requested with the value
+			of an ELF file header flag individually set by each
+			binary.  Hardware implementations are permitted to
+			support either or both of the legacy and the 2008 NaN
+			encoding mode.
+
+			Available settings are as follows:
+			strict	accept binaries that request a NaN encoding
+				supported by the FPU
+			legacy	only accept legacy-NaN binaries, if supported
+				by the FPU
+			2008	only accept 2008-NaN binaries, if supported
+				by the FPU
+			relaxed	accept any binaries regardless of whether
+				supported by the FPU
+
+			The FPU emulator is always able to support both NaN
+			encodings, so if no FPU hardware is present or it has
+			been disabled with 'nofpu', then the settings of
+			'legacy' and '2008' strap the emulator accordingly,
+			'relaxed' straps the emulator for both legacy-NaN and
+			2008-NaN, whereas 'strict' enables legacy-NaN only on
+			legacy processors and both NaN encodings on MIPS32 or
+			MIPS64 CPUs.
+
+			The setting for ABS.fmt/NEG.fmt instruction execution
+			mode generally follows that for the NaN encoding,
+			except where unsupported by hardware.
+
 	ignore_loglevel	[KNL]
 	ignore_loglevel	[KNL]
 			Ignore loglevel setting - this will print /all/
 			Ignore loglevel setting - this will print /all/
 			kernel messages to the console. Useful for debugging.
 			kernel messages to the console. Useful for debugging.

+ 22 - 0
MAINTAINERS

@@ -2420,6 +2420,8 @@ F:	arch/mips/kernel/*bmips*
 F:	arch/mips/boot/dts/brcm/bcm*.dts*
 F:	arch/mips/boot/dts/brcm/bcm*.dts*
 F:	drivers/irqchip/irq-bcm7*
 F:	drivers/irqchip/irq-bcm7*
 F:	drivers/irqchip/irq-brcmstb*
 F:	drivers/irqchip/irq-brcmstb*
+F:	include/linux/bcm963xx_nvram.h
+F:	include/linux/bcm963xx_tag.h
 
 
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 M:	Prashant Sreedharan <prashant@broadcom.com>
 M:	Prashant Sreedharan <prashant@broadcom.com>
@@ -6216,6 +6218,14 @@ F:	arch/arm64/include/uapi/asm/kvm*
 F:	arch/arm64/include/asm/kvm*
 F:	arch/arm64/include/asm/kvm*
 F:	arch/arm64/kvm/
 F:	arch/arm64/kvm/
 
 
+KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
+M:	James Hogan <james.hogan@imgtec.com>
+L:	linux-mips@linux-mips.org
+S:	Supported
+F:	arch/mips/include/uapi/asm/kvm*
+F:	arch/mips/include/asm/kvm*
+F:	arch/mips/kvm/
+
 KEXEC
 KEXEC
 M:	Eric Biederman <ebiederm@xmission.com>
 M:	Eric Biederman <ebiederm@xmission.com>
 W:	http://kernel.org/pub/linux/utils/kernel/kexec/
 W:	http://kernel.org/pub/linux/utils/kernel/kexec/
@@ -6313,6 +6323,12 @@ S:	Maintained
 F:	net/l3mdev
 F:	net/l3mdev
 F:	include/net/l3mdev.h
 F:	include/net/l3mdev.h
 
 
+LANTIQ MIPS ARCHITECTURE
+M:	John Crispin <blogic@openwrt.org>
+L:	linux-mips@linux-mips.org
+S:	Maintained
+F:	arch/mips/lantiq
+
 LAPB module
 LAPB module
 L:	linux-x25@vger.kernel.org
 L:	linux-x25@vger.kernel.org
 S:	Orphan
 S:	Orphan
@@ -8997,6 +9013,12 @@ L:	linux-fbdev@vger.kernel.org
 S:	Maintained
 S:	Maintained
 F:	drivers/video/fbdev/aty/aty128fb.c
 F:	drivers/video/fbdev/aty/aty128fb.c
 
 
+RALINK MIPS ARCHITECTURE
+M:	John Crispin <blogic@openwrt.org>
+L:	linux-mips@linux-mips.org
+S:	Maintained
+F:	arch/mips/ralink
+
 RALINK RT2X00 WIRELESS LAN DRIVER
 RALINK RT2X00 WIRELESS LAN DRIVER
 P:	rt2x00 project
 P:	rt2x00 project
 M:	Stanislaw Gruszka <sgruszka@redhat.com>
 M:	Stanislaw Gruszka <sgruszka@redhat.com>

+ 1 - 0
arch/mips/Kbuild.platforms

@@ -21,6 +21,7 @@ platforms += mti-malta
 platforms += mti-sead3
 platforms += mti-sead3
 platforms += netlogic
 platforms += netlogic
 platforms += paravirt
 platforms += paravirt
+platforms += pic32
 platforms += pistachio
 platforms += pistachio
 platforms += pmcs-msp71xx
 platforms += pmcs-msp71xx
 platforms += pnx833x
 platforms += pnx833x

+ 16 - 1
arch/mips/Kconfig

@@ -169,6 +169,7 @@ config BMIPS_GENERIC
 	select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
 	select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
 	select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
 	select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
 	select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
 	select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	help
 	  Build a generic DT-based kernel image that boots on select
 	  Build a generic DT-based kernel image that boots on select
 	  BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
 	  BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
@@ -480,6 +481,14 @@ config MIPS_MALTA
 	  This enables support for the MIPS Technologies Malta evaluation
 	  This enables support for the MIPS Technologies Malta evaluation
 	  board.
 	  board.
 
 
+config MACH_PIC32
+	bool "Microchip PIC32 Family"
+	help
+	  This enables support for the Microchip PIC32 family of platforms.
+
+	  Microchip PIC32 is a family of general-purpose 32 bit MIPS core
+	  microcontrollers.
+
 config MIPS_SEAD3
 config MIPS_SEAD3
 	bool "MIPS SEAD3 board"
 	bool "MIPS SEAD3 board"
 	select BOOT_ELF32
 	select BOOT_ELF32
@@ -979,6 +988,7 @@ source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
 source "arch/mips/jz4740/Kconfig"
 source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/lasat/Kconfig"
+source "arch/mips/pic32/Kconfig"
 source "arch/mips/pistachio/Kconfig"
 source "arch/mips/pistachio/Kconfig"
 source "arch/mips/pmcs-msp71xx/Kconfig"
 source "arch/mips/pmcs-msp71xx/Kconfig"
 source "arch/mips/ralink/Kconfig"
 source "arch/mips/ralink/Kconfig"
@@ -1755,6 +1765,10 @@ config SYS_SUPPORTS_ZBOOT_UART16550
 	bool
 	bool
 	select SYS_SUPPORTS_ZBOOT
 	select SYS_SUPPORTS_ZBOOT
 
 
+config SYS_SUPPORTS_ZBOOT_UART_PROM
+	bool
+	select SYS_SUPPORTS_ZBOOT
+
 config CPU_LOONGSON2
 config CPU_LOONGSON2
 	bool
 	bool
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_32BIT_KERNEL
@@ -2017,7 +2031,8 @@ config KVM_GUEST
 	bool "KVM Guest Kernel"
 	bool "KVM Guest Kernel"
 	depends on BROKEN_ON_SMP
 	depends on BROKEN_ON_SMP
 	help
 	help
-	  Select this option if building a guest kernel for KVM (Trap & Emulate) mode
+	  Select this option if building a guest kernel for KVM (Trap & Emulate)
+	  mode.
 
 
 config KVM_GUEST_TIMER_FREQ
 config KVM_GUEST_TIMER_FREQ
 	int "Count/Compare Timer Frequency (MHz)"
 	int "Count/Compare Timer Frequency (MHz)"

+ 0 - 10
arch/mips/Makefile

@@ -166,16 +166,6 @@ cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
 endif
 endif
 cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
 cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
 cflags-$(CONFIG_CPU_BMIPS)	+= -march=mips32 -Wa,-mips32 -Wa,--trap
 cflags-$(CONFIG_CPU_BMIPS)	+= -march=mips32 -Wa,-mips32 -Wa,--trap
-#
-# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
-# as MIPS64 R1; older versions as just R1.  This leaves the possibility open
-# that GCC might generate R2 code for -march=loongson3a which then is rejected
-# by GAS.  The cc-option can't probe for this behaviour so -march=loongson3a
-# can't easily be used safely within the kbuild framework.
-#
-cflags-$(CONFIG_CPU_LOONGSON3)  +=					\
-	$(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
-	-Wa,-mips64r2 -Wa,--trap
 
 
 cflags-$(CONFIG_CPU_R4000_WORKAROUNDS)	+= $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4000_WORKAROUNDS)	+= $(call cc-option,-mfix-r4000,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS)	+= $(call cc-option,-mfix-r4400,)
 cflags-$(CONFIG_CPU_R4400_WORKAROUNDS)	+= $(call cc-option,-mfix-r4400,)

+ 3 - 3
arch/mips/alchemy/common/gpiolib.c

@@ -40,7 +40,7 @@
 
 
 static int gpio2_get(struct gpio_chip *chip, unsigned offset)
 static int gpio2_get(struct gpio_chip *chip, unsigned offset)
 {
 {
-	return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
+	return !!alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
 }
 }
 
 
 static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
 static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -68,7 +68,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
 
 
 static int gpio1_get(struct gpio_chip *chip, unsigned offset)
 static int gpio1_get(struct gpio_chip *chip, unsigned offset)
 {
 {
-	return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
+	return !!alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
 }
 }
 
 
 static void gpio1_set(struct gpio_chip *chip,
 static void gpio1_set(struct gpio_chip *chip,
@@ -119,7 +119,7 @@ struct gpio_chip alchemy_gpio_chip[] = {
 
 
 static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
 static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
 {
 {
-	return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
+	return !!au1300_gpio_get_value(off + AU1300_GPIO_BASE);
 }
 }
 
 
 static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
 static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)

+ 1 - 1
arch/mips/ar7/gpio.c

@@ -37,7 +37,7 @@ static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 				container_of(chip, struct ar7_gpio_chip, chip);
 				container_of(chip, struct ar7_gpio_chip, chip);
 	void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
 	void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
 
 
-	return readl(gpio_in) & (1 << gpio);
+	return !!(readl(gpio_in) & (1 << gpio));
 }
 }
 
 
 static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)

+ 0 - 1
arch/mips/ath79/common.h

@@ -23,7 +23,6 @@ void ath79_clocks_init(void);
 unsigned long ath79_get_sys_clk_rate(const char *id);
 unsigned long ath79_get_sys_clk_rate(const char *id);
 
 
 void ath79_ddr_ctrl_init(void);
 void ath79_ddr_ctrl_init(void);
-void ath79_ddr_wb_flush(unsigned int reg);
 
 
 void ath79_gpio_init(void);
 void ath79_gpio_init(void);
 
 

+ 28 - 33
arch/mips/ath79/irq.c

@@ -26,9 +26,13 @@
 #include "common.h"
 #include "common.h"
 #include "machtypes.h"
 #include "machtypes.h"
 
 
+static void __init ath79_misc_intc_domain_init(
+	struct device_node *node, int irq);
+
 static void ath79_misc_irq_handler(struct irq_desc *desc)
 static void ath79_misc_irq_handler(struct irq_desc *desc)
 {
 {
-	void __iomem *base = ath79_reset_base;
+	struct irq_domain *domain = irq_desc_get_handler_data(desc);
+	void __iomem *base = domain->host_data;
 	u32 pending;
 	u32 pending;
 
 
 	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
 	pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
@@ -42,15 +46,15 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
 	while (pending) {
 	while (pending) {
 		int bit = __ffs(pending);
 		int bit = __ffs(pending);
 
 
-		generic_handle_irq(ATH79_MISC_IRQ(bit));
+		generic_handle_irq(irq_linear_revmap(domain, bit));
 		pending &= ~BIT(bit);
 		pending &= ~BIT(bit);
 	}
 	}
 }
 }
 
 
 static void ar71xx_misc_irq_unmask(struct irq_data *d)
 static void ar71xx_misc_irq_unmask(struct irq_data *d)
 {
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
 	u32 t;
 	u32 t;
 
 
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
@@ -62,8 +66,8 @@ static void ar71xx_misc_irq_unmask(struct irq_data *d)
 
 
 static void ar71xx_misc_irq_mask(struct irq_data *d)
 static void ar71xx_misc_irq_mask(struct irq_data *d)
 {
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
 	u32 t;
 	u32 t;
 
 
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
@@ -75,8 +79,8 @@ static void ar71xx_misc_irq_mask(struct irq_data *d)
 
 
 static void ar724x_misc_irq_ack(struct irq_data *d)
 static void ar724x_misc_irq_ack(struct irq_data *d)
 {
 {
-	unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
-	void __iomem *base = ath79_reset_base;
+	void __iomem *base = irq_data_get_irq_chip_data(d);
+	unsigned int irq = d->hwirq;
 	u32 t;
 	u32 t;
 
 
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
 	t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
@@ -94,12 +98,6 @@ static struct irq_chip ath79_misc_irq_chip = {
 
 
 static void __init ath79_misc_irq_init(void)
 static void __init ath79_misc_irq_init(void)
 {
 {
-	void __iomem *base = ath79_reset_base;
-	int i;
-
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
-	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
 	if (soc_is_ar71xx() || soc_is_ar913x())
 	if (soc_is_ar71xx() || soc_is_ar913x())
 		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
 		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
 	else if (soc_is_ar724x() ||
 	else if (soc_is_ar724x() ||
@@ -110,13 +108,7 @@ static void __init ath79_misc_irq_init(void)
 	else
 	else
 		BUG();
 		BUG();
 
 
-	for (i = ATH79_MISC_IRQ_BASE;
-	     i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
-		irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
-					 handle_level_irq);
-	}
-
-	irq_set_chained_handler(ATH79_CPU_IRQ(6), ath79_misc_irq_handler);
+	ath79_misc_intc_domain_init(NULL, ATH79_CPU_IRQ(6));
 }
 }
 
 
 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
 static void ar934x_ip2_irq_dispatch(struct irq_desc *desc)
@@ -256,10 +248,10 @@ asmlinkage void plat_irq_dispatch(void)
 	}
 	}
 }
 }
 
 
-#ifdef CONFIG_IRQCHIP
 static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
 {
 	irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
 	irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
+	irq_set_chip_data(irq, d->host_data);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -268,19 +260,14 @@ static const struct irq_domain_ops misc_irq_domain_ops = {
 	.map = misc_map,
 	.map = misc_map,
 };
 };
 
 
-static int __init ath79_misc_intc_of_init(
-	struct device_node *node, struct device_node *parent)
+static void __init ath79_misc_intc_domain_init(
+	struct device_node *node, int irq)
 {
 {
 	void __iomem *base = ath79_reset_base;
 	void __iomem *base = ath79_reset_base;
 	struct irq_domain *domain;
 	struct irq_domain *domain;
-	int irq;
-
-	irq = irq_of_parse_and_map(node, 0);
-	if (!irq)
-		panic("Failed to get MISC IRQ");
 
 
 	domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
 	domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
-			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
+			ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, base);
 	if (!domain)
 	if (!domain)
 		panic("Failed to add MISC irqdomain");
 		panic("Failed to add MISC irqdomain");
 
 
@@ -288,9 +275,19 @@ static int __init ath79_misc_intc_of_init(
 	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
 	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
 	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
 	__raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
 
 
+	irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
+}
 
 
-	irq_set_chained_handler(irq, ath79_misc_irq_handler);
+static int __init ath79_misc_intc_of_init(
+	struct device_node *node, struct device_node *parent)
+{
+	int irq;
 
 
+	irq = irq_of_parse_and_map(node, 0);
+	if (!irq)
+		panic("Failed to get MISC IRQ");
+
+	ath79_misc_intc_domain_init(node, irq);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -349,8 +346,6 @@ static int __init ar79_cpu_intc_of_init(
 IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
 IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
 		ar79_cpu_intc_of_init);
 		ar79_cpu_intc_of_init);
 
 
-#endif
-
 void __init arch_init_irq(void)
 void __init arch_init_irq(void)
 {
 {
 	if (mips_machtype == ATH79_MACH_GENERIC_OF) {
 	if (mips_machtype == ATH79_MACH_GENERIC_OF) {

+ 1 - 10
arch/mips/ath79/setup.c

@@ -36,10 +36,6 @@
 
 
 #define ATH79_SYS_TYPE_LEN	64
 #define ATH79_SYS_TYPE_LEN	64
 
 
-#define AR71XX_BASE_FREQ	40000000
-#define AR724X_BASE_FREQ	5000000
-#define AR913X_BASE_FREQ	5000000
-
 static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
 static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
 
 
 static void ath79_restart(char *command)
 static void ath79_restart(char *command)
@@ -272,15 +268,10 @@ void __init device_tree_init(void)
 	unflatten_and_copy_device_tree();
 	unflatten_and_copy_device_tree();
 }
 }
 
 
-static void __init ath79_generic_init(void)
-{
-	/* Nothing to do */
-}
-
 MIPS_MACHINE(ATH79_MACH_GENERIC,
 MIPS_MACHINE(ATH79_MACH_GENERIC,
 	     "Generic",
 	     "Generic",
 	     "Generic AR71XX/AR724X/AR913X based board",
 	     "Generic AR71XX/AR724X/AR913X based board",
-	     ath79_generic_init);
+	     NULL);
 
 
 MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
 MIPS_MACHINE(ATH79_MACH_GENERIC_OF,
 	     "DTB",
 	     "DTB",

+ 9 - 3
arch/mips/bcm47xx/sprom.c

@@ -666,9 +666,15 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
 	switch (bus->hosttype) {
 	switch (bus->hosttype) {
 	case BCMA_HOSTTYPE_PCI:
 	case BCMA_HOSTTYPE_PCI:
 		memset(out, 0, sizeof(struct ssb_sprom));
 		memset(out, 0, sizeof(struct ssb_sprom));
-		snprintf(buf, sizeof(buf), "pci/%u/%u/",
-			 bus->host_pci->bus->number + 1,
-			 PCI_SLOT(bus->host_pci->devfn));
+		/* On BCM47XX all PCI buses share the same domain */
+		if (config_enabled(CONFIG_BCM47XX))
+			snprintf(buf, sizeof(buf), "pci/%u/%u/",
+				 bus->host_pci->bus->number + 1,
+				 PCI_SLOT(bus->host_pci->devfn));
+		else
+			snprintf(buf, sizeof(buf), "pci/%u/%u/",
+				 pci_domain_nr(bus->host_pci->bus) + 1,
+				 bus->host_pci->bus->number);
 		bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
 		bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
 		prefix = buf;
 		prefix = buf;
 		break;
 		break;

+ 3 - 43
arch/mips/bcm63xx/nvram.c

@@ -10,6 +10,7 @@
 
 
 #define pr_fmt(fmt) "bcm63xx_nvram: " fmt
 #define pr_fmt(fmt) "bcm63xx_nvram: " fmt
 
 
+#include <linux/bcm963xx_nvram.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 #include <linux/crc32.h>
 #include <linux/export.h>
 #include <linux/export.h>
@@ -18,51 +19,19 @@
 
 
 #include <bcm63xx_nvram.h>
 #include <bcm63xx_nvram.h>
 
 
-/*
- * nvram structure
- */
-struct bcm963xx_nvram {
-	u32	version;
-	u8	reserved1[256];
-	u8	name[16];
-	u32	main_tp_number;
-	u32	psi_size;
-	u32	mac_addr_count;
-	u8	mac_addr_base[ETH_ALEN];
-	u8	reserved2[2];
-	u32	checksum_old;
-	u8	reserved3[720];
-	u32	checksum_high;
-};
-
-#define BCM63XX_DEFAULT_PSI_SIZE	64
-
 static struct bcm963xx_nvram nvram;
 static struct bcm963xx_nvram nvram;
 static int mac_addr_used;
 static int mac_addr_used;
 
 
 void __init bcm63xx_nvram_init(void *addr)
 void __init bcm63xx_nvram_init(void *addr)
 {
 {
-	unsigned int check_len;
 	u32 crc, expected_crc;
 	u32 crc, expected_crc;
 	u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
 	u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
 
 
 	/* extract nvram data */
 	/* extract nvram data */
-	memcpy(&nvram, addr, sizeof(nvram));
+	memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE);
 
 
 	/* check checksum before using data */
 	/* check checksum before using data */
-	if (nvram.version <= 4) {
-		check_len = offsetof(struct bcm963xx_nvram, reserved3);
-		expected_crc = nvram.checksum_old;
-		nvram.checksum_old = 0;
-	} else {
-		check_len = sizeof(nvram);
-		expected_crc = nvram.checksum_high;
-		nvram.checksum_high = 0;
-	}
-
-	crc = crc32_le(~0, (u8 *)&nvram, check_len);
-
-	if (crc != expected_crc)
+	if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc))
 		pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
 		pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
 			expected_crc, crc);
 			expected_crc, crc);
 
 
@@ -116,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac)
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
 EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
-
-int bcm63xx_nvram_get_psi_size(void)
-{
-	if (nvram.psi_size > 0)
-		return nvram.psi_size;
-
-	return BCM63XX_DEFAULT_PSI_SIZE;
-}
-EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size);

+ 1 - 0
arch/mips/bmips/setup.c

@@ -105,6 +105,7 @@ static const struct bmips_quirk bmips_quirk_list[] = {
 	{ "brcm,bcm33843-viper",	&bcm3384_viper_quirks		},
 	{ "brcm,bcm33843-viper",	&bcm3384_viper_quirks		},
 	{ "brcm,bcm6328",		&bcm6328_quirks			},
 	{ "brcm,bcm6328",		&bcm6328_quirks			},
 	{ "brcm,bcm6368",		&bcm6368_quirks			},
 	{ "brcm,bcm6368",		&bcm6368_quirks			},
+	{ "brcm,bcm63168",		&bcm6368_quirks			},
 	{ },
 	{ },
 };
 };
 
 

+ 9 - 6
arch/mips/boot/compressed/Makefile

@@ -29,20 +29,23 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
 	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
 	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
 	-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
 	-DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
 
 
-targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
-
 # decompressor objects (linked with vmlinuz)
 # decompressor objects (linked with vmlinuz)
 vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
 vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
 
 
 ifdef CONFIG_DEBUG_ZBOOT
 ifdef CONFIG_DEBUG_ZBOOT
 vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT)		   += $(obj)/dbg.o
 vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT)		   += $(obj)/dbg.o
 vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
 vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o
 vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)		   += $(obj)/uart-alchemy.o
 vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)		   += $(obj)/uart-alchemy.o
 endif
 endif
 
 
-ifdef CONFIG_KERNEL_XZ
-vmlinuzobjs-y += $(obj)/../../lib/ashldi3.o
-endif
+vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
+
+$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib
+$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c
+	$(call cmd,shipped)
+
+targets := $(notdir $(vmlinuzobjs-y))
 
 
 targets += vmlinux.bin
 targets += vmlinux.bin
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
 OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
@@ -60,7 +63,7 @@ targets += vmlinux.bin.z
 $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
 $(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,$(tool_y))
 	$(call if_changed,$(tool_y))
 
 
-targets += piggy.o
+targets += piggy.o dummy.o
 OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
 OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
 			--set-section-flags=.image=contents,alloc,load,readonly,data
 			--set-section-flags=.image=contents,alloc,load,readonly,data
 $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
 $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE

+ 7 - 0
arch/mips/boot/compressed/uart-prom.c

@@ -0,0 +1,7 @@
+
+extern void prom_putchar(unsigned char ch);
+
+void putc(char c)
+{
+	prom_putchar(c);
+}

+ 1 - 0
arch/mips/boot/dts/Makefile

@@ -4,6 +4,7 @@ dts-dirs	+= ingenic
 dts-dirs	+= lantiq
 dts-dirs	+= lantiq
 dts-dirs	+= mti
 dts-dirs	+= mti
 dts-dirs	+= netlogic
 dts-dirs	+= netlogic
+dts-dirs	+= pic32
 dts-dirs	+= qca
 dts-dirs	+= qca
 dts-dirs	+= ralink
 dts-dirs	+= ralink
 dts-dirs	+= xilfpga
 dts-dirs	+= xilfpga

+ 9 - 0
arch/mips/boot/dts/brcm/bcm6328.dtsi

@@ -31,6 +31,7 @@
 	};
 	};
 
 
 	aliases {
 	aliases {
+		leds0 = &leds0;
 		uart0 = &uart0;
 		uart0 = &uart0;
 	};
 	};
 
 
@@ -81,5 +82,13 @@
 			offset = <0x28>;
 			offset = <0x28>;
 			mask = <0x1>;
 			mask = <0x1>;
 		};
 		};
+
+		leds0: led-controller@10000800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,bcm6328-leds";
+			reg = <0x10000800 0x24>;
+			status = "disabled";
+		};
 	};
 	};
 };
 };

+ 22 - 0
arch/mips/boot/dts/brcm/bcm6368.dtsi

@@ -32,6 +32,7 @@
 	};
 	};
 
 
 	aliases {
 	aliases {
+		leds0 = &leds0;
 		uart0 = &uart0;
 		uart0 = &uart0;
 	};
 	};
 
 
@@ -50,6 +51,19 @@
 		compatible = "simple-bus";
 		compatible = "simple-bus";
 		ranges;
 		ranges;
 
 
+		periph_cntl: syscon@10000000 {
+			compatible = "syscon";
+			reg = <0x10000000 0x14>;
+			little-endian;
+		};
+
+		reboot: syscon-reboot@10000008 {
+			compatible = "syscon-reboot";
+			regmap = <&periph_cntl>;
+			offset = <0x8>;
+			mask = <0x1>;
+		};
+
 		periph_intc: periph_intc@10000020 {
 		periph_intc: periph_intc@10000020 {
 			compatible = "brcm,bcm3380-l2-intc";
 			compatible = "brcm,bcm3380-l2-intc";
 			reg = <0x10000024 0x4 0x1000002c 0x4>,
 			reg = <0x10000024 0x4 0x1000002c 0x4>,
@@ -62,6 +76,14 @@
 			interrupts = <2>;
 			interrupts = <2>;
 		};
 		};
 
 
+		leds0: led-controller@100000d0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "brcm,bcm6358-leds";
+			reg = <0x100000d0 0x8>;
+			status = "disabled";
+		};
+
 		uart0: serial@10000100 {
 		uart0: serial@10000100 {
 			compatible = "brcm,bcm6345-uart";
 			compatible = "brcm,bcm6345-uart";
 			reg = <0x10000100 0x18>;
 			reg = <0x10000100 0x18>;

+ 64 - 0
arch/mips/boot/dts/ingenic/ci20.dts

@@ -42,3 +42,67 @@
 &uart4 {
 &uart4 {
 	status = "okay";
 	status = "okay";
 };
 };
+
+&nemc {
+	status = "okay";
+
+	nandc: nand-controller@1 {
+		compatible = "ingenic,jz4780-nand";
+		reg = <1 0 0x1000000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ingenic,bch-controller = <&bch>;
+
+		ingenic,nemc-tAS = <10>;
+		ingenic,nemc-tAH = <5>;
+		ingenic,nemc-tBP = <10>;
+		ingenic,nemc-tAW = <15>;
+		ingenic,nemc-tSTRV = <100>;
+
+		nand@1 {
+			reg = <1>;
+
+			nand-ecc-step-size = <1024>;
+			nand-ecc-strength = <24>;
+			nand-ecc-mode = "hw";
+			nand-on-flash-bbt;
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <2>;
+				#size-cells = <2>;
+
+				partition@0 {
+					label = "u-boot-spl";
+					reg = <0x0 0x0 0x0 0x800000>;
+				};
+
+				partition@0x800000 {
+					label = "u-boot";
+					reg = <0x0 0x800000 0x0 0x200000>;
+				};
+
+				partition@0xa00000 {
+					label = "u-boot-env";
+					reg = <0x0 0xa00000 0x0 0x200000>;
+				};
+
+				partition@0xc00000 {
+					label = "boot";
+					reg = <0x0 0xc00000 0x0 0x4000000>;
+				};
+
+				partition@0x8c00000 {
+					label = "system";
+					reg = <0x0 0x4c00000 0x1 0xfb400000>;
+				};
+			};
+		};
+	};
+};
+
+&bch {
+	status = "okay";
+};

+ 26 - 0
arch/mips/boot/dts/ingenic/jz4780.dtsi

@@ -108,4 +108,30 @@
 
 
 		status = "disabled";
 		status = "disabled";
 	};
 	};
+
+	nemc: nemc@13410000 {
+		compatible = "ingenic,jz4780-nemc";
+		reg = <0x13410000 0x10000>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <1 0 0x1b000000 0x1000000
+			  2 0 0x1a000000 0x1000000
+			  3 0 0x19000000 0x1000000
+			  4 0 0x18000000 0x1000000
+			  5 0 0x17000000 0x1000000
+			  6 0 0x16000000 0x1000000>;
+
+		clocks = <&cgu JZ4780_CLK_NEMC>;
+
+		status = "disabled";
+	};
+
+	bch: bch@134d0000 {
+		compatible = "ingenic,jz4780-bch";
+		reg = <0x134d0000 0x10000>;
+
+		clocks = <&cgu JZ4780_CLK_BCH>;
+
+		status = "disabled";
+	};
 };
 };

+ 12 - 0
arch/mips/boot/dts/pic32/Makefile

@@ -0,0 +1,12 @@
+dtb-$(CONFIG_DTB_PIC32_MZDA_SK)		+= pic32mzda_sk.dtb
+
+dtb-$(CONFIG_DTB_PIC32_NONE)		+= \
+					pic32mzda_sk.dtb
+
+obj-y				+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-				+= dummy.o
+
+always				:= $(dtb-y)
+clean-files			:= *.dtb *.dtb.S

+ 236 - 0
arch/mips/boot/dts/pic32/pic32mzda-clk.dtsi

@@ -0,0 +1,236 @@
+/*
+ * Device Tree Source for PIC32MZDA clock data
+ *
+ * Purna Chandra Mandal <purna.mandal@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/* all fixed rate clocks */
+
+/ {
+	POSC:posc_clk { /* On-chip primary oscillator */
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+	};
+
+	FRC:frc_clk { /* internal FRC oscillator */
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <8000000>;
+	};
+
+	BFRC:bfrc_clk { /* internal backup FRC oscillator */
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <8000000>;
+	};
+
+	LPRC:lprc_clk { /* internal low-power FRC oscillator */
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <32000>;
+	};
+
+	/* UPLL provides clock to USBCORE */
+	UPLL:usb_phy_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "usbphy_clk";
+	};
+
+	TxCKI:txcki_clk { /* external clock input on TxCLKI pin */
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <4000000>;
+		status = "disabled";
+	};
+
+	/* external clock input on REFCLKIx pin */
+	REFIx:refix_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		status = "disabled";
+	};
+
+	/* PIC32 specific clks */
+	pic32_clktree {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x1f801200 0x200>;
+		compatible = "microchip,pic32mzda-clk";
+		ranges = <0 0x1f801200 0x200>;
+
+		/* secondary oscillator; external input on SOSCI pin */
+		SOSC:sosc_clk@0 {
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-sosc";
+			clock-frequency = <32768>;
+			reg = <0x000 0x10>,   /* enable reg */
+			      <0x1d0 0x10>; /* status reg */
+			microchip,bit-mask = <0x02>; /* enable mask */
+			microchip,status-bit-mask = <0x10>; /* status-mask*/
+		};
+
+		FRCDIV:frcdiv_clk {
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-frcdivclk";
+			clocks = <&FRC>;
+			clock-output-names = "frcdiv_clk";
+		};
+
+		/* System PLL clock */
+		SYSPLL:spll_clk@020 {
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-syspll";
+			reg = <0x020 0x10>, /* SPLL register */
+			      <0x1d0 0x10>; /* CLKSTAT register */
+			clocks = <&POSC>, <&FRC>;
+			clock-output-names = "sys_pll";
+			microchip,status-bit-mask = <0x80>; /* SPLLRDY */
+		};
+
+		/* system clock; mux with postdiv & slew */
+		SYSCLK:sys_clk@1c0 {
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-sysclk-v2";
+			reg = <0x1c0 0x04>; /* SLEWCON */
+			clocks = <&FRCDIV>, <&SYSPLL>, <&POSC>, <&SOSC>,
+				 <&LPRC>, <&FRCDIV>;
+			microchip,clock-indices = <0>, <1>, <2>, <4>,
+						  <5>, <7>;
+			clock-output-names = "sys_clk";
+		};
+
+		/* Peripheral bus1 clock */
+		PBCLK1:pb1_clk@140 {
+			reg = <0x140 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			clock-output-names = "pb1_clk";
+			/* used by system modules, not gateable */
+			microchip,ignore-unused;
+		};
+
+		/* Peripheral bus2 clock */
+		PBCLK2:pb2_clk@150 {
+			reg = <0x150 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			clock-output-names = "pb2_clk";
+			/* avoid gating even if unused */
+			microchip,ignore-unused;
+		};
+
+		/* Peripheral bus3 clock */
+		PBCLK3:pb3_clk@160 {
+			reg = <0x160 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			clock-output-names = "pb3_clk";
+		};
+
+		/* Peripheral bus4 clock(I/O ports, GPIO) */
+		PBCLK4:pb4_clk@170 {
+			reg = <0x170 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			clock-output-names = "pb4_clk";
+		};
+
+		/* Peripheral bus clock */
+		PBCLK5:pb5_clk@180 {
+			reg = <0x180 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			clock-output-names = "pb5_clk";
+		};
+
+		/* Peripheral Bus6 clock; */
+		PBCLK6:pb6_clk@190 {
+			reg = <0x190 0x10>;
+			compatible = "microchip,pic32mzda-pbclk";
+			clocks = <&SYSCLK>;
+			#clock-cells = <0>;
+		};
+
+		/* Peripheral bus7 clock */
+		PBCLK7:pb7_clk@1a0 {
+			reg = <0x1a0 0x10>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-pbclk";
+			/* CPU is driven by this clock; so named */
+			clock-output-names = "cpu_clk";
+			clocks = <&SYSCLK>;
+		};
+
+		/* Reference Oscillator clock for SPI/I2S */
+		REFCLKO1:refo1_clk@80 {
+			reg = <0x080 0x20>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-refoclk";
+			clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+				 <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+			microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+						  <5>, <7>, <8>, <9>;
+			clock-output-names = "refo1_clk";
+		};
+
+		/* Reference Oscillator clock for SQI */
+		REFCLKO2:refo2_clk@a0 {
+			reg = <0x0a0 0x20>;
+			#clock-cells = <0>;
+			compatible = "microchip,pic32mzda-refoclk";
+			clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+				 <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+			microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+						  <5>, <7>, <8>, <9>;
+			clock-output-names = "refo2_clk";
+		};
+
+		/* Reference Oscillator clock, ADC */
+		REFCLKO3:refo3_clk@c0 {
+			reg = <0x0c0 0x20>;
+			compatible = "microchip,pic32mzda-refoclk";
+			clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+				 <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+			microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+						  <5>, <7>, <8>, <9>;
+			#clock-cells = <0>;
+			clock-output-names = "refo3_clk";
+		};
+
+		/* Reference Oscillator clock */
+		REFCLKO4:refo4_clk@e0 {
+			reg = <0x0e0 0x20>;
+			compatible = "microchip,pic32mzda-refoclk";
+			clocks = <&SYSCLK>, <&PBCLK1>, <&POSC>, <&FRC>, <&LPRC>,
+				 <&SOSC>, <&SYSPLL>, <&REFIx>, <&BFRC>;
+			microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+						  <5>, <7>, <8>, <9>;
+			#clock-cells = <0>;
+			clock-output-names = "refo4_clk";
+		};
+
+		/* Reference Oscillator clock, LCD */
+		REFCLKO5:refo5_clk@100 {
+			reg = <0x100 0x20>;
+			compatible = "microchip,pic32mzda-refoclk";
+			clocks = <&SYSCLK>,<&PBCLK1>,<&POSC>,<&FRC>,<&LPRC>,
+				 <&SOSC>,<&SYSPLL>,<&REFIx>,<&BFRC>;
+			microchip,clock-indices = <0>, <1>, <2>, <3>, <4>,
+						  <5>, <7>, <8>, <9>;
+			#clock-cells = <0>;
+			clock-output-names = "refo5_clk";
+		};
+	};
+};

+ 281 - 0
arch/mips/boot/dts/pic32/pic32mzda.dtsi

@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda-clk.dtsi"
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&evic>;
+
+	aliases {
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+		gpio3 = &gpio3;
+		gpio4 = &gpio4;
+		gpio5 = &gpio5;
+		gpio6 = &gpio6;
+		gpio7 = &gpio7;
+		gpio8 = &gpio8;
+		gpio9 = &gpio9;
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart5;
+		serial5 = &uart6;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mti,mips14KEc";
+			device_type = "cpu";
+		};
+	};
+
+	soc {
+		compatible = "microchip,pic32mzda-infra";
+		interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+	};
+
+	evic: interrupt-controller@1f810000 {
+		compatible = "microchip,pic32mzda-evic";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0x1f810000 0x1000>;
+		microchip,external-irqs = <3 8 13 18 23>;
+	};
+
+	pic32_pinctrl: pinctrl@1f801400{
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "microchip,pic32mzda-pinctrl";
+		reg = <0x1f801400 0x400>;
+		clocks = <&PBCLK1>;
+	};
+
+	/* PORTA */
+	gpio0: gpio0@1f860000 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860000 0x100>;
+		interrupts = <118 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <0>;
+		gpio-ranges = <&pic32_pinctrl 0 0 16>;
+	};
+
+	/* PORTB */
+	gpio1: gpio1@1f860100 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860100 0x100>;
+		interrupts = <119 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <1>;
+		gpio-ranges = <&pic32_pinctrl 0 16 16>;
+	};
+
+	/* PORTC */
+	gpio2: gpio2@1f860200 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860200 0x100>;
+		interrupts = <120 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <2>;
+		gpio-ranges = <&pic32_pinctrl 0 32 16>;
+	};
+
+	/* PORTD */
+	gpio3: gpio3@1f860300 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860300 0x100>;
+		interrupts = <121 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <3>;
+		gpio-ranges = <&pic32_pinctrl 0 48 16>;
+	};
+
+	/* PORTE */
+	gpio4: gpio4@1f860400 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860400 0x100>;
+		interrupts = <122 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <4>;
+		gpio-ranges = <&pic32_pinctrl 0 64 16>;
+	};
+
+	/* PORTF */
+	gpio5: gpio5@1f860500 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860500 0x100>;
+		interrupts = <123 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <5>;
+		gpio-ranges = <&pic32_pinctrl 0 80 16>;
+	};
+
+	/* PORTG */
+	gpio6: gpio6@1f860600 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860600 0x100>;
+		interrupts = <124 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <6>;
+		gpio-ranges = <&pic32_pinctrl 0 96 16>;
+	};
+
+	/* PORTH */
+	gpio7: gpio7@1f860700 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860700 0x100>;
+		interrupts = <125 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <7>;
+		gpio-ranges = <&pic32_pinctrl 0 112 16>;
+	};
+
+	/* PORTI does not exist */
+
+	/* PORTJ */
+	gpio8: gpio8@1f860800 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860800 0x100>;
+		interrupts = <126 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <8>;
+		gpio-ranges = <&pic32_pinctrl 0 128 16>;
+	};
+
+	/* PORTK */
+	gpio9: gpio9@1f860900 {
+		compatible = "microchip,pic32mzda-gpio";
+		reg = <0x1f860900 0x100>;
+		interrupts = <127 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		clocks = <&PBCLK4>;
+		microchip,gpio-bank = <9>;
+		gpio-ranges = <&pic32_pinctrl 0 144 16>;
+	};
+
+	sdhci: sdhci@1f8ec000 {
+		compatible = "microchip,pic32mzda-sdhci";
+		reg = <0x1f8ec000 0x100>;
+		interrupts = <191 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&REFCLKO4>, <&PBCLK5>;
+		clock-names = "base_clk", "sys_clk";
+		bus-width = <4>;
+		cap-sd-highspeed;
+		status = "disabled";
+	};
+
+	uart1: serial@1f822000 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822000 0x50>;
+		interrupts = <112 IRQ_TYPE_LEVEL_HIGH>,
+			<113 IRQ_TYPE_LEVEL_HIGH>,
+			<114 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+
+	uart2: serial@1f822200 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822200 0x50>;
+		interrupts = <145 IRQ_TYPE_LEVEL_HIGH>,
+			<146 IRQ_TYPE_LEVEL_HIGH>,
+			<147 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+
+	uart3: serial@1f822400 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822400 0x50>;
+		interrupts = <157 IRQ_TYPE_LEVEL_HIGH>,
+			<158 IRQ_TYPE_LEVEL_HIGH>,
+			<159 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+
+	uart4: serial@1f822600 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822600 0x50>;
+		interrupts = <170 IRQ_TYPE_LEVEL_HIGH>,
+			<171 IRQ_TYPE_LEVEL_HIGH>,
+			<172 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+
+	uart5: serial@1f822800 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822800 0x50>;
+		interrupts = <179 IRQ_TYPE_LEVEL_HIGH>,
+			<180 IRQ_TYPE_LEVEL_HIGH>,
+			<181 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+
+	uart6: serial@1f822A00 {
+		compatible = "microchip,pic32mzda-uart";
+		reg = <0x1f822A00 0x50>;
+		interrupts = <188 IRQ_TYPE_LEVEL_HIGH>,
+			<189 IRQ_TYPE_LEVEL_HIGH>,
+			<190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&PBCLK2>;
+		status = "disabled";
+	};
+};

+ 151 - 0
arch/mips/boot/dts/pic32/pic32mzda_sk.dts

@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "pic32mzda.dtsi"
+
+/ {
+	compatible = "microchip,pic32mzda-sk", "microchip,pic32mzda";
+	model = "Microchip PIC32MZDA Starter Kit";
+
+	memory {
+		device_type = "memory";
+		reg = <0x08000000 0x08000000>;
+	};
+
+	chosen {
+		bootargs = "earlyprintk=ttyPIC1,115200n8r console=ttyPIC1,115200n8";
+	};
+
+	leds0 {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_leds_s0>;
+
+		led@1 {
+			label = "pic32mzda_sk:red:led1";
+			gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led@2 {
+			label = "pic32mzda_sk:yellow:led2";
+			gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+		};
+
+		led@3 {
+			label = "pic32mzda_sk:green:led3";
+			gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	keys0 {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&user_buttons_s0>;
+		pinctrl-names = "default";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button@sw1 {
+			label = "ESC";
+			linux,code = <1>;
+			gpios = <&gpio1 12 0>;
+		};
+
+		button@sw2 {
+			label = "Home";
+			linux,code = <102>;
+			gpios = <&gpio1 13 0>;
+		};
+
+		button@sw3 {
+			label = "Menu";
+			linux,code = <139>;
+			gpios = <&gpio1 14 0>;
+		};
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	status = "okay";
+};
+
+&sdhci {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdhc1>;
+	status = "okay";
+	assigned-clocks = <&REFCLKO2>,<&REFCLKO4>,<&REFCLKO5>;
+	assigned-clock-rates = <50000000>,<25000000>,<40000000>;
+};
+
+&pic32_pinctrl {
+
+	pinctrl_sdhc1: sdhc1_pins0 {
+		pins = "A6", "D4", "G13", "G12", "G14", "A7", "A0";
+		microchip,digital;
+	};
+
+	user_leds_s0: user_leds_s0 {
+		pins = "H0", "H1", "H2";
+		output-low;
+		microchip,digital;
+	};
+
+	user_buttons_s0: user_buttons_s0 {
+		pins = "B12", "B13", "B14";
+		microchip,digital;
+		input-enable;
+		bias-pull-up;
+	};
+
+	pinctrl_uart2: pinctrl_uart2 {
+		uart2-tx {
+			pins = "G9";
+			function = "U2TX";
+			microchip,digital;
+			output-high;
+		};
+		uart2-rx {
+			pins = "B0";
+			function = "U2RX";
+			microchip,digital;
+			input-enable;
+		};
+	};
+
+	pinctrl_uart4: uart4-0 {
+		uart4-tx {
+			pins = "C3";
+			function = "U4TX";
+			microchip,digital;
+			output-high;
+		};
+		uart4-rx {
+			pins = "E8";
+			function = "U4RX";
+			microchip,digital;
+			input-enable;
+		};
+	};
+};

+ 26 - 0
arch/mips/boot/dts/qca/ar9132.dtsi

@@ -125,6 +125,21 @@
 			};
 			};
 		};
 		};
 
 
+		usb@1b000100 {
+			compatible = "qca,ar7100-ehci", "generic-ehci";
+			reg = <0x1b000100 0x100>;
+
+			interrupts = <3>;
+			resets = <&rst 5>;
+
+			has-transaction-translator;
+
+			phy-names = "usb";
+			phys = <&usb_phy>;
+
+			status = "disabled";
+		};
+
 		spi@1f000000 {
 		spi@1f000000 {
 			compatible = "qca,ar9132-spi", "qca,ar7100-spi";
 			compatible = "qca,ar9132-spi", "qca,ar7100-spi";
 			reg = <0x1f000000 0x10>;
 			reg = <0x1f000000 0x10>;
@@ -138,4 +153,15 @@
 			#size-cells = <0>;
 			#size-cells = <0>;
 		};
 		};
 	};
 	};
+
+	usb_phy: usb-phy {
+		compatible = "qca,ar7100-usb-phy";
+
+		reset-names = "usb-phy", "usb-suspend-override";
+		resets = <&rst 4>, <&rst 3>;
+
+		#phy-cells = <0>;
+
+		status = "disabled";
+	};
 };
 };

+ 8 - 0
arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts

@@ -35,6 +35,10 @@
 			};
 			};
 		};
 		};
 
 
+		usb@1b000100 {
+			status = "okay";
+		};
+
 		spi@1f000000 {
 		spi@1f000000 {
 			status = "okay";
 			status = "okay";
 			num-cs = <1>;
 			num-cs = <1>;
@@ -65,6 +69,10 @@
 		};
 		};
 	};
 	};
 
 
+	usb-phy {
+		status = "okay";
+	};
+
 	gpio-keys {
 	gpio-keys {
 		compatible = "gpio-keys-polled";
 		compatible = "gpio-keys-polled";
 		#address-cells = <1>;
 		#address-cells = <1>;

+ 89 - 0
arch/mips/configs/pic32mzda_defconfig

@@ -0,0 +1,89 @@
+CONFIG_MACH_PIC32=y
+CONFIG_DTB_PIC32_MZDA_SK=y
+CONFIG_HZ_100=y
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_SGI_PARTITION=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_SUSPEND is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_INPUT_LEDS=m
+CONFIG_INPUT_POLLDEV=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_GPIO_POLLED=m
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PIC32=y
+CONFIG_SERIAL_PIC32_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_RAW_DRIVER=m
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_HIDRAW=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MICROCHIP_PIC32=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_MIPS_PLATFORM_DEVICES is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_FSCACHE=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y

+ 64 - 42
arch/mips/include/asm/cacheops.h

@@ -11,55 +11,77 @@
 #ifndef __ASM_CACHEOPS_H
 #ifndef __ASM_CACHEOPS_H
 #define __ASM_CACHEOPS_H
 #define __ASM_CACHEOPS_H
 
 
+/*
+ * Most cache ops are split into a 2 bit field identifying the cache, and a 3
+ * bit field identifying the cache operation.
+ */
+#define CacheOp_Cache			0x03
+#define CacheOp_Op			0x1c
+
+#define Cache_I				0x00
+#define Cache_D				0x01
+#define Cache_T				0x02
+#define Cache_S				0x03
+
+#define Index_Writeback_Inv		0x00
+#define Index_Load_Tag			0x04
+#define Index_Store_Tag			0x08
+#define Hit_Invalidate			0x10
+#define Hit_Writeback_Inv		0x14	/* not with Cache_I though */
+#define Hit_Writeback			0x18
+
 /*
 /*
  * Cache Operations available on all MIPS processors with R4000-style caches
  * Cache Operations available on all MIPS processors with R4000-style caches
  */
  */
-#define Index_Invalidate_I		0x00
-#define Index_Writeback_Inv_D		0x01
-#define Index_Load_Tag_I		0x04
-#define Index_Load_Tag_D		0x05
-#define Index_Store_Tag_I		0x08
-#define Index_Store_Tag_D		0x09
-#define Hit_Invalidate_I		0x10
-#define Hit_Invalidate_D		0x11
-#define Hit_Writeback_Inv_D		0x15
+#define Index_Invalidate_I		(Cache_I | Index_Writeback_Inv)
+#define Index_Writeback_Inv_D		(Cache_D | Index_Writeback_Inv)
+#define Index_Load_Tag_I		(Cache_I | Index_Load_Tag)
+#define Index_Load_Tag_D		(Cache_D | Index_Load_Tag)
+#define Index_Store_Tag_I		(Cache_I | Index_Store_Tag)
+#define Index_Store_Tag_D		(Cache_D | Index_Store_Tag)
+#define Hit_Invalidate_I		(Cache_I | Hit_Invalidate)
+#define Hit_Invalidate_D		(Cache_D | Hit_Invalidate)
+#define Hit_Writeback_Inv_D		(Cache_D | Hit_Writeback_Inv)
 
 
 /*
 /*
  * R4000-specific cacheops
  * R4000-specific cacheops
  */
  */
-#define Create_Dirty_Excl_D		0x0d
-#define Fill				0x14
-#define Hit_Writeback_I			0x18
-#define Hit_Writeback_D			0x19
+#define Create_Dirty_Excl_D		(Cache_D | 0x0c)
+#define Fill				(Cache_I | 0x14)
+#define Hit_Writeback_I			(Cache_I | Hit_Writeback)
+#define Hit_Writeback_D			(Cache_D | Hit_Writeback)
 
 
 /*
 /*
  * R4000SC and R4400SC-specific cacheops
  * R4000SC and R4400SC-specific cacheops
  */
  */
-#define Index_Invalidate_SI		0x02
-#define Index_Writeback_Inv_SD		0x03
-#define Index_Load_Tag_SI		0x06
-#define Index_Load_Tag_SD		0x07
-#define Index_Store_Tag_SI		0x0A
-#define Index_Store_Tag_SD		0x0B
-#define Create_Dirty_Excl_SD		0x0f
-#define Hit_Invalidate_SI		0x12
-#define Hit_Invalidate_SD		0x13
-#define Hit_Writeback_Inv_SD		0x17
-#define Hit_Writeback_SD		0x1b
-#define Hit_Set_Virtual_SI		0x1e
-#define Hit_Set_Virtual_SD		0x1f
+#define Cache_SI			0x02
+#define Cache_SD			0x03
+
+#define Index_Invalidate_SI		(Cache_SI | Index_Writeback_Inv)
+#define Index_Writeback_Inv_SD		(Cache_SD | Index_Writeback_Inv)
+#define Index_Load_Tag_SI		(Cache_SI | Index_Load_Tag)
+#define Index_Load_Tag_SD		(Cache_SD | Index_Load_Tag)
+#define Index_Store_Tag_SI		(Cache_SI | Index_Store_Tag)
+#define Index_Store_Tag_SD		(Cache_SD | Index_Store_Tag)
+#define Create_Dirty_Excl_SD		(Cache_SD | 0x0c)
+#define Hit_Invalidate_SI		(Cache_SI | Hit_Invalidate)
+#define Hit_Invalidate_SD		(Cache_SD | Hit_Invalidate)
+#define Hit_Writeback_Inv_SD		(Cache_SD | Hit_Writeback_Inv)
+#define Hit_Writeback_SD		(Cache_SD | Hit_Writeback)
+#define Hit_Set_Virtual_SI		(Cache_SI | 0x1c)
+#define Hit_Set_Virtual_SD		(Cache_SD | 0x1c)
 
 
 /*
 /*
  * R5000-specific cacheops
  * R5000-specific cacheops
  */
  */
-#define R5K_Page_Invalidate_S		0x17
+#define R5K_Page_Invalidate_S		(Cache_S | 0x14)
 
 
 /*
 /*
  * RM7000-specific cacheops
  * RM7000-specific cacheops
  */
  */
-#define Page_Invalidate_T		0x16
-#define Index_Store_Tag_T		0x0a
-#define Index_Load_Tag_T		0x06
+#define Page_Invalidate_T		(Cache_T | 0x14)
+#define Index_Store_Tag_T		(Cache_T | Index_Store_Tag)
+#define Index_Load_Tag_T		(Cache_T | Index_Load_Tag)
 
 
 /*
 /*
  * R10000-specific cacheops
  * R10000-specific cacheops
@@ -67,22 +89,22 @@
  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
  * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
  * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
  */
  */
-#define Index_Writeback_Inv_S		0x03
-#define Index_Load_Tag_S		0x07
-#define Index_Store_Tag_S		0x0B
-#define Hit_Invalidate_S		0x13
+#define Index_Writeback_Inv_S		(Cache_S | Index_Writeback_Inv)
+#define Index_Load_Tag_S		(Cache_S | Index_Load_Tag)
+#define Index_Store_Tag_S		(Cache_S | Index_Store_Tag)
+#define Hit_Invalidate_S		(Cache_S | Hit_Invalidate)
 #define Cache_Barrier			0x14
 #define Cache_Barrier			0x14
-#define Hit_Writeback_Inv_S		0x17
-#define Index_Load_Data_I		0x18
-#define Index_Load_Data_D		0x19
-#define Index_Load_Data_S		0x1b
-#define Index_Store_Data_I		0x1c
-#define Index_Store_Data_D		0x1d
-#define Index_Store_Data_S		0x1f
+#define Hit_Writeback_Inv_S		(Cache_S | Hit_Writeback_Inv)
+#define Index_Load_Data_I		(Cache_I | 0x18)
+#define Index_Load_Data_D		(Cache_D | 0x18)
+#define Index_Load_Data_S		(Cache_S | 0x18)
+#define Index_Store_Data_I		(Cache_I | 0x1c)
+#define Index_Store_Data_D		(Cache_D | 0x1c)
+#define Index_Store_Data_S		(Cache_S | 0x1c)
 
 
 /*
 /*
  * Loongson2-specific cacheops
  * Loongson2-specific cacheops
  */
  */
-#define Hit_Invalidate_I_Loongson2	0x00
+#define Hit_Invalidate_I_Loongson2	(Cache_I | 0x00)
 
 
 #endif	/* __ASM_CACHEOPS_H */
 #endif	/* __ASM_CACHEOPS_H */

+ 7 - 0
arch/mips/include/asm/cpu-features.h

@@ -414,4 +414,11 @@
 # define cpu_has_small_pages	(cpu_data[0].options & MIPS_CPU_SP)
 # define cpu_has_small_pages	(cpu_data[0].options & MIPS_CPU_SP)
 #endif
 #endif
 
 
+#ifndef cpu_has_nan_legacy
+#define cpu_has_nan_legacy	(cpu_data[0].options & MIPS_CPU_NAN_LEGACY)
+#endif
+#ifndef cpu_has_nan_2008
+#define cpu_has_nan_2008	(cpu_data[0].options & MIPS_CPU_NAN_2008)
+#endif
+
 #endif /* __ASM_CPU_FEATURES_H */
 #endif /* __ASM_CPU_FEATURES_H */

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

@@ -386,6 +386,8 @@ enum cpu_type_enum {
 #define MIPS_CPU_BP_GHIST	0x8000000000ull /* R12K+ Branch Prediction Global History */
 #define MIPS_CPU_BP_GHIST	0x8000000000ull /* R12K+ Branch Prediction Global History */
 #define MIPS_CPU_SP		0x10000000000ull /* Small (1KB) page support */
 #define MIPS_CPU_SP		0x10000000000ull /* Small (1KB) page support */
 #define MIPS_CPU_FTLB		0x20000000000ull /* CPU has Fixed-page-size TLB */
 #define MIPS_CPU_FTLB		0x20000000000ull /* CPU has Fixed-page-size TLB */
+#define MIPS_CPU_NAN_LEGACY	0x40000000000ull /* Legacy NaN implemented */
+#define MIPS_CPU_NAN_2008	0x80000000000ull /* 2008 NaN implemented */
 
 
 /*
 /*
  * CPU ASE encodings
  * CPU ASE encodings

+ 11 - 4
arch/mips/include/asm/elf.h

@@ -12,7 +12,6 @@
 #include <linux/fs.h>
 #include <linux/fs.h>
 #include <uapi/linux/elf.h>
 #include <uapi/linux/elf.h>
 
 
-#include <asm/cpu-info.h>
 #include <asm/current.h>
 #include <asm/current.h>
 
 
 /* ELF header e_flags defines. */
 /* ELF header e_flags defines. */
@@ -44,6 +43,7 @@
 #define EF_MIPS_OPTIONS_FIRST	0x00000080
 #define EF_MIPS_OPTIONS_FIRST	0x00000080
 #define EF_MIPS_32BITMODE	0x00000100
 #define EF_MIPS_32BITMODE	0x00000100
 #define EF_MIPS_FP64		0x00000200
 #define EF_MIPS_FP64		0x00000200
+#define EF_MIPS_NAN2008		0x00000400
 #define EF_MIPS_ABI		0x0000f000
 #define EF_MIPS_ABI		0x0000f000
 #define EF_MIPS_ARCH		0xf0000000
 #define EF_MIPS_ARCH		0xf0000000
 
 
@@ -305,7 +305,7 @@ do {									\
 									\
 									\
 	current->thread.abi = &mips_abi;				\
 	current->thread.abi = &mips_abi;				\
 									\
 									\
-	current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;		\
+	mips_set_personality_nan(state);				\
 } while (0)
 } while (0)
 
 
 #endif /* CONFIG_32BIT */
 #endif /* CONFIG_32BIT */
@@ -367,7 +367,7 @@ do {									\
 	else								\
 	else								\
 		current->thread.abi = &mips_abi;			\
 		current->thread.abi = &mips_abi;			\
 									\
 									\
-	current->thread.fpu.fcr31 = boot_cpu_data.fpu_csr31;		\
+	mips_set_personality_nan(state);				\
 									\
 									\
 	p = personality(current->personality);				\
 	p = personality(current->personality);				\
 	if (p != PER_LINUX32 && p != PER_LINUX)				\
 	if (p != PER_LINUX32 && p != PER_LINUX)				\
@@ -432,6 +432,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int uses_interp);
 				       int uses_interp);
 
 
 struct arch_elf_state {
 struct arch_elf_state {
+	int nan_2008;
 	int fp_abi;
 	int fp_abi;
 	int interp_fp_abi;
 	int interp_fp_abi;
 	int overall_fp_mode;
 	int overall_fp_mode;
@@ -440,17 +441,23 @@ struct arch_elf_state {
 #define MIPS_ABI_FP_UNKNOWN	(-1)	/* Unknown FP ABI (kernel internal) */
 #define MIPS_ABI_FP_UNKNOWN	(-1)	/* Unknown FP ABI (kernel internal) */
 
 
 #define INIT_ARCH_ELF_STATE {			\
 #define INIT_ARCH_ELF_STATE {			\
+	.nan_2008 = -1,				\
 	.fp_abi = MIPS_ABI_FP_UNKNOWN,		\
 	.fp_abi = MIPS_ABI_FP_UNKNOWN,		\
 	.interp_fp_abi = MIPS_ABI_FP_UNKNOWN,	\
 	.interp_fp_abi = MIPS_ABI_FP_UNKNOWN,	\
 	.overall_fp_mode = -1,			\
 	.overall_fp_mode = -1,			\
 }
 }
 
 
+/* Whether to accept legacy-NaN and 2008-NaN user binaries.  */
+extern bool mips_use_nan_legacy;
+extern bool mips_use_nan_2008;
+
 extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
 extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
 			    bool is_interp, struct arch_elf_state *state);
 			    bool is_interp, struct arch_elf_state *state);
 
 
-extern int arch_check_elf(void *ehdr, bool has_interpreter,
+extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
 			  struct arch_elf_state *state);
 			  struct arch_elf_state *state);
 
 
+extern void mips_set_personality_nan(struct arch_elf_state *state);
 extern void mips_set_personality_fp(struct arch_elf_state *state);
 extern void mips_set_personality_fp(struct arch_elf_state *state);
 
 
 #endif /* _ASM_ELF_H */
 #endif /* _ASM_ELF_H */

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

@@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 /*
 /*
  * Break instruction with special math emu break code set
  * Break instruction with special math emu break code set
  */
  */
-#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
+#define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
 
 
 #define SIGNALLING_NAN 0x7ff800007ff80000LL
 #define SIGNALLING_NAN 0x7ff800007ff80000LL
 
 

+ 1 - 0
arch/mips/include/asm/io.h

@@ -275,6 +275,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  */
  */
 #define ioremap_cachable(offset, size)					\
 #define ioremap_cachable(offset, size)					\
 	__ioremap_mode((offset), (size), _page_cachable_default)
 	__ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cache ioremap_cachable
 
 
 /*
 /*
  * These two are MIPS specific ioremap variant.	 ioremap_cacheable_cow
  * These two are MIPS specific ioremap variant.	 ioremap_cacheable_cow

+ 0 - 30
arch/mips/include/asm/irqflags.h

@@ -84,41 +84,11 @@ static inline void arch_local_irq_restore(unsigned long flags)
 	: "memory");
 	: "memory");
 }
 }
 
 
-static inline void __arch_local_irq_restore(unsigned long flags)
-{
-	__asm__ __volatile__(
-	"	.set	push						\n"
-	"	.set	noreorder					\n"
-	"	.set	noat						\n"
-#if defined(CONFIG_IRQ_MIPS_CPU)
-	/*
-	 * Slow, but doesn't suffer from a relatively unlikely race
-	 * condition we're having since days 1.
-	 */
-	"	beqz	%[flags], 1f					\n"
-	"	di							\n"
-	"	ei							\n"
-	"1:								\n"
-#else
-	/*
-	 * Fast, dangerous.  Life is fun, life is good.
-	 */
-	"	mfc0	$1, $12						\n"
-	"	ins	$1, %[flags], 0, 1				\n"
-	"	mtc0	$1, $12						\n"
-#endif
-	"	" __stringify(__irq_disable_hazard) "			\n"
-	"	.set	pop						\n"
-	: [flags] "=r" (flags)
-	: "0" (flags)
-	: "memory");
-}
 #else
 #else
 /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
 /* Functions that require preempt_{dis,en}able() are in mips-atomic.c */
 void arch_local_irq_disable(void);
 void arch_local_irq_disable(void);
 unsigned long arch_local_irq_save(void);
 unsigned long arch_local_irq_save(void);
 void arch_local_irq_restore(unsigned long flags);
 void arch_local_irq_restore(unsigned long flags);
-void __arch_local_irq_restore(unsigned long flags);
 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
 
 
 static inline void arch_local_irq_enable(void)
 static inline void arch_local_irq_enable(void)

+ 1 - 38
arch/mips/include/asm/kvm_host.h

@@ -58,7 +58,7 @@
 #define KVM_MAX_VCPUS		1
 #define KVM_MAX_VCPUS		1
 #define KVM_USER_MEM_SLOTS	8
 #define KVM_USER_MEM_SLOTS	8
 /* memory slots that does not exposed to userspace */
 /* memory slots that does not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS 	0
+#define KVM_PRIVATE_MEM_SLOTS	0
 
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_HALT_POLL_NS_DEFAULT 500000
 #define KVM_HALT_POLL_NS_DEFAULT 500000
@@ -92,14 +92,6 @@
 #define KVM_INVALID_INST		0xdeadbeef
 #define KVM_INVALID_INST		0xdeadbeef
 #define KVM_INVALID_ADDR		0xdeadbeef
 #define KVM_INVALID_ADDR		0xdeadbeef
 
 
-#define KVM_MALTA_GUEST_RTC_ADDR	0xb8000070UL
-
-#define GUEST_TICKS_PER_JIFFY		(40000000/HZ)
-#define MS_TO_NS(x)			(x * 1E6L)
-
-#define CAUSEB_DC			27
-#define CAUSEF_DC			(_ULCAST_(1) << 27)
-
 extern atomic_t kvm_mips_instance;
 extern atomic_t kvm_mips_instance;
 extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
 extern kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
 extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
 extern void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
@@ -289,34 +281,6 @@ enum mips_mmu_types {
 	MMU_TYPE_R8000
 	MMU_TYPE_R8000
 };
 };
 
 
-/*
- * Trap codes
- */
-#define T_INT			0	/* Interrupt pending */
-#define T_TLB_MOD		1	/* TLB modified fault */
-#define T_TLB_LD_MISS		2	/* TLB miss on load or ifetch */
-#define T_TLB_ST_MISS		3	/* TLB miss on a store */
-#define T_ADDR_ERR_LD		4	/* Address error on a load or ifetch */
-#define T_ADDR_ERR_ST		5	/* Address error on a store */
-#define T_BUS_ERR_IFETCH	6	/* Bus error on an ifetch */
-#define T_BUS_ERR_LD_ST		7	/* Bus error on a load or store */
-#define T_SYSCALL		8	/* System call */
-#define T_BREAK			9	/* Breakpoint */
-#define T_RES_INST		10	/* Reserved instruction exception */
-#define T_COP_UNUSABLE		11	/* Coprocessor unusable */
-#define T_OVFLOW		12	/* Arithmetic overflow */
-
-/*
- * Trap definitions added for r4000 port.
- */
-#define T_TRAP			13	/* Trap instruction */
-#define T_VCEI			14	/* Virtual coherency exception */
-#define T_MSAFPE		14	/* MSA floating point exception */
-#define T_FPE			15	/* Floating point exception */
-#define T_MSADIS		21	/* MSA disabled exception */
-#define T_WATCH			23	/* Watch address reference */
-#define T_VCED			31	/* Virtual coherency data */
-
 /* Resume Flags */
 /* Resume Flags */
 #define RESUME_FLAG_DR		(1<<0)	/* Reload guest nonvolatile state? */
 #define RESUME_FLAG_DR		(1<<0)	/* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST	(1<<1)	/* Resume host? */
 #define RESUME_FLAG_HOST	(1<<1)	/* Resume host? */
@@ -686,7 +650,6 @@ extern void kvm_mips_dump_host_tlbs(void);
 extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
 extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
 extern void kvm_mips_flush_host_tlb(int skip_kseg0);
 extern void kvm_mips_flush_host_tlb(int skip_kseg0);
 extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
 extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
-extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
 
 
 extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
 extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
 				     unsigned long entryhi);
 				     unsigned long entryhi);

+ 1 - 0
arch/mips/include/asm/mach-ath79/ath79.h

@@ -115,6 +115,7 @@ static inline int soc_is_qca955x(void)
 	return soc_is_qca9556() || soc_is_qca9558();
 	return soc_is_qca9556() || soc_is_qca9558();
 }
 }
 
 
+void ath79_ddr_wb_flush(unsigned int reg);
 void ath79_ddr_set_pci_windows(void);
 void ath79_ddr_set_pci_windows(void);
 
 
 extern void __iomem *ath79_pll_base;
 extern void __iomem *ath79_pll_base;

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

@@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void);
  */
  */
 int bcm63xx_nvram_get_mac_address(u8 *mac);
 int bcm63xx_nvram_get_mac_address(u8 *mac);
 
 
-int bcm63xx_nvram_get_psi_size(void);
-
 #endif /* BCM63XX_NVRAM_H */
 #endif /* BCM63XX_NVRAM_H */

+ 32 - 0
arch/mips/include/asm/mach-pic32/cpu-feature-overrides.h

@@ -0,0 +1,32 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * 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.
+ */
+#ifndef __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * CPU feature overrides for PIC32 boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_vint		1
+#define cpu_has_veic		0
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_4k_cache	1
+#define cpu_has_fpu		0
+#define cpu_has_counter		1
+#define cpu_has_llsc		1
+#define cpu_has_nofpuex		0
+#define cpu_icache_snoops_remote_store 1
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#error This platform does not support 64bit.
+#endif
+
+#endif /* __ASM_MACH_PIC32_CPU_FEATURE_OVERRIDES_H */

+ 22 - 0
arch/mips/include/asm/mach-pic32/irq.h

@@ -0,0 +1,22 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef __ASM_MACH_PIC32_IRQ_H
+#define __ASM_MACH_PIC32_IRQ_H
+
+#define NR_IRQS	256
+#define MIPS_CPU_IRQ_BASE 0
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_PIC32_IRQ_H */

+ 44 - 0
arch/mips/include/asm/mach-pic32/pic32.h

@@ -0,0 +1,44 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef _ASM_MACH_PIC32_H
+#define _ASM_MACH_PIC32_H
+
+#include <linux/io.h>
+
+/*
+ * PIC32 register offsets for SET/CLR/INV where supported.
+ */
+#define PIC32_CLR(_reg)		((_reg) + 0x04)
+#define PIC32_SET(_reg)		((_reg) + 0x08)
+#define PIC32_INV(_reg)		((_reg) + 0x0C)
+
+/*
+ * PIC32 Base Register Offsets
+ */
+#define PIC32_BASE_CONFIG	0x1f800000
+#define PIC32_BASE_OSC		0x1f801200
+#define PIC32_BASE_RESET	0x1f801240
+#define PIC32_BASE_PPS		0x1f801400
+#define PIC32_BASE_UART		0x1f822000
+#define PIC32_BASE_PORT		0x1f860000
+#define PIC32_BASE_DEVCFG2	0x1fc4ff44
+
+/*
+ * Register unlock sequence required for some register access.
+ */
+void pic32_syskey_unlock_debug(const char *fn, const ulong ln);
+#define pic32_syskey_unlock()	\
+	pic32_syskey_unlock_debug(__func__, __LINE__)
+
+#endif /* _ASM_MACH_PIC32_H */

+ 24 - 0
arch/mips/include/asm/mach-pic32/spaces.h

@@ -0,0 +1,24 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+#ifndef _ASM_MACH_PIC32_SPACES_H
+#define _ASM_MACH_PIC32_SPACES_H
+
+#ifdef CONFIG_PIC32MZDA
+#define PHYS_OFFSET	_AC(0x08000000, UL)
+#define UNCAC_BASE	_AC(0xa8000000, UL)
+#endif
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_MACH_PIC32_SPACES_H */

+ 9 - 0
arch/mips/include/asm/mach-ralink/irq.h

@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_RALINK_IRQ_H
+#define __ASM_MACH_RALINK_IRQ_H
+
+#define GIC_NUM_INTRS	64
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif

+ 38 - 0
arch/mips/include/asm/mach-ralink/mt7621.h

@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _MT7621_REGS_H_
+#define _MT7621_REGS_H_
+
+#define MT7621_PALMBUS_BASE		0x1C000000
+#define MT7621_PALMBUS_SIZE		0x03FFFFFF
+
+#define MT7621_SYSC_BASE		0x1E000000
+
+#define SYSC_REG_CHIP_NAME0		0x00
+#define SYSC_REG_CHIP_NAME1		0x04
+#define SYSC_REG_CHIP_REV		0x0c
+#define SYSC_REG_SYSTEM_CONFIG0		0x10
+#define SYSC_REG_SYSTEM_CONFIG1		0x14
+
+#define CHIP_REV_PKG_MASK		0x1
+#define CHIP_REV_PKG_SHIFT		16
+#define CHIP_REV_VER_MASK		0xf
+#define CHIP_REV_VER_SHIFT		8
+#define CHIP_REV_ECO_MASK		0xf
+
+#define MT7621_DRAM_BASE                0x0
+#define MT7621_DDR2_SIZE_MIN		32
+#define MT7621_DDR2_SIZE_MAX		256
+
+#define MT7621_CHIP_NAME0		0x3637544D
+#define MT7621_CHIP_NAME1		0x20203132
+
+#define MIPS_GIC_IRQ_BASE           (MIPS_CPU_IRQ_BASE + 8)
+
+#endif

+ 65 - 0
arch/mips/include/asm/mach-ralink/mt7621/cpu-feature-overrides.h

@@ -0,0 +1,65 @@
+/*
+ * Ralink MT7621 specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ *	Copyright (C) 2003, 2004 Ralf Baechle
+ *	Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef _MT7621_CPU_FEATURE_OVERRIDES_H
+#define _MT7621_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb		1
+#define cpu_has_4kex		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_tx39_cache	0
+#define cpu_has_sb1_cache	0
+#define cpu_has_fpu		0
+#define cpu_has_32fpr		0
+#define cpu_has_counter		1
+#define cpu_has_watch		1
+#define cpu_has_divec		1
+
+#define cpu_has_prefetch	1
+#define cpu_has_ejtag		1
+#define cpu_has_llsc		1
+
+#define cpu_has_mips16		1
+#define cpu_has_mdmx		0
+#define cpu_has_mips3d		0
+#define cpu_has_smartmips	0
+
+#define cpu_has_mips32r1	1
+#define cpu_has_mips32r2	1
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
+#define cpu_has_dsp		1
+#define cpu_has_dsp2		0
+#define cpu_has_mipsmt		1
+
+#define cpu_has_64bits		0
+#define cpu_has_64bit_zero_reg	0
+#define cpu_has_64bit_gp_regs	0
+#define cpu_has_64bit_addresses	0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+
+#define cpu_has_dc_aliases	0
+#define cpu_has_vtag_icache	0
+
+#define cpu_has_rixi		0
+#define cpu_has_tlbinv		0
+#define cpu_has_userlocal	1
+
+#endif /* _MT7621_CPU_FEATURE_OVERRIDES_H */

+ 4 - 0
arch/mips/include/asm/mips-cm.h

@@ -243,6 +243,10 @@ BUILD_CM_Cx_R_(tcid_8_priority,	0x80)
 #define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
 #define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
 #define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
 #define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
 
 
+/* GCR_RESET_EXT_BASE register fields */
+#define CM_GCR_RESET_EXT_BASE_EVARESET		BIT(31)
+#define CM_GCR_RESET_EXT_BASE_UEB		BIT(30)
+
 /* GCR_ACCESS register fields */
 /* GCR_ACCESS register fields */
 #define CM_GCR_ACCESS_ACCESSEN_SHF		0
 #define CM_GCR_ACCESS_ACCESSEN_SHF		0
 #define CM_GCR_ACCESS_ACCESSEN_MSK		(_ULCAST_(0xff) << 0)
 #define CM_GCR_ACCESS_ACCESSEN_MSK		(_ULCAST_(0xff) << 0)

+ 1 - 1
arch/mips/include/asm/mips-r2-to-r6-emul.h

@@ -52,7 +52,7 @@ do {									\
 	__this_cpu_inc(mipsr2emustats.M);				\
 	__this_cpu_inc(mipsr2emustats.M);				\
 	err = __get_user(nir, (u32 __user *)regs->cp0_epc);		\
 	err = __get_user(nir, (u32 __user *)regs->cp0_epc);		\
 	if (!err) {							\
 	if (!err) {							\
-		if (nir == BREAK_MATH)					\
+		if (nir == BREAK_MATH(0))				\
 			__this_cpu_inc(mipsr2bdemustats.M);		\
 			__this_cpu_inc(mipsr2bdemustats.M);		\
 	}								\
 	}								\
 	preempt_enable();						\
 	preempt_enable();						\

+ 34 - 0
arch/mips/include/asm/mipsregs.h

@@ -394,6 +394,8 @@
 #define CAUSEF_IV		(_ULCAST_(1)   << 23)
 #define CAUSEF_IV		(_ULCAST_(1)   << 23)
 #define CAUSEB_PCI		26
 #define CAUSEB_PCI		26
 #define CAUSEF_PCI		(_ULCAST_(1)   << 26)
 #define CAUSEF_PCI		(_ULCAST_(1)   << 26)
+#define CAUSEB_DC		27
+#define CAUSEF_DC		(_ULCAST_(1)   << 27)
 #define CAUSEB_CE		28
 #define CAUSEB_CE		28
 #define CAUSEF_CE		(_ULCAST_(3)   << 28)
 #define CAUSEF_CE		(_ULCAST_(3)   << 28)
 #define CAUSEB_TI		30
 #define CAUSEB_TI		30
@@ -401,6 +403,38 @@
 #define CAUSEB_BD		31
 #define CAUSEB_BD		31
 #define CAUSEF_BD		(_ULCAST_(1)   << 31)
 #define CAUSEF_BD		(_ULCAST_(1)   << 31)
 
 
+/*
+ * Cause.ExcCode trap codes.
+ */
+#define EXCCODE_INT		0	/* Interrupt pending */
+#define EXCCODE_MOD		1	/* TLB modified fault */
+#define EXCCODE_TLBL		2	/* TLB miss on load or ifetch */
+#define EXCCODE_TLBS		3	/* TLB miss on a store */
+#define EXCCODE_ADEL		4	/* Address error on a load or ifetch */
+#define EXCCODE_ADES		5	/* Address error on a store */
+#define EXCCODE_IBE		6	/* Bus error on an ifetch */
+#define EXCCODE_DBE		7	/* Bus error on a load or store */
+#define EXCCODE_SYS		8	/* System call */
+#define EXCCODE_BP		9	/* Breakpoint */
+#define EXCCODE_RI		10	/* Reserved instruction exception */
+#define EXCCODE_CPU		11	/* Coprocessor unusable */
+#define EXCCODE_OV		12	/* Arithmetic overflow */
+#define EXCCODE_TR		13	/* Trap instruction */
+#define EXCCODE_MSAFPE		14	/* MSA floating point exception */
+#define EXCCODE_FPE		15	/* Floating point exception */
+#define EXCCODE_TLBRI		19	/* TLB Read-Inhibit exception */
+#define EXCCODE_TLBXI		20	/* TLB Execution-Inhibit exception */
+#define EXCCODE_MSADIS		21	/* MSA disabled exception */
+#define EXCCODE_MDMX		22	/* MDMX unusable exception */
+#define EXCCODE_WATCH		23	/* Watch address reference */
+#define EXCCODE_MCHECK		24	/* Machine check */
+#define EXCCODE_THREAD		25	/* Thread exceptions (MT) */
+#define EXCCODE_DSPDIS		26	/* DSP disabled exception */
+#define EXCCODE_GE		27	/* Virtualized guest exception (VZ) */
+
+/* Implementation specific trap codes used by MIPS cores */
+#define MIPS_EXCCODE_TLBPAR	16	/* TLB parity error exception */
+
 /*
 /*
  * Bits in the coprocessor 0 config register.
  * Bits in the coprocessor 0 config register.
  */
  */

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

@@ -33,7 +33,7 @@
 #define PAGE_SHIFT	16
 #define PAGE_SHIFT	16
 #endif
 #endif
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK	(~(PAGE_SIZE - 1))
+#define PAGE_MASK	(~((1 << PAGE_SHIFT) - 1))
 
 
 /*
 /*
  * This is used for calculating the real page sizes
  * This is used for calculating the real page sizes

+ 2 - 2
arch/mips/include/asm/pgtable.h

@@ -353,7 +353,7 @@ static inline pte_t pte_mkdirty(pte_t pte)
 static inline pte_t pte_mkyoung(pte_t pte)
 static inline pte_t pte_mkyoung(pte_t pte)
 {
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
 	pte_val(pte) |= _PAGE_ACCESSED;
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (!(pte_val(pte) & _PAGE_NO_READ))
 	if (!(pte_val(pte) & _PAGE_NO_READ))
 		pte_val(pte) |= _PAGE_SILENT_READ;
 		pte_val(pte) |= _PAGE_SILENT_READ;
 	else
 	else
@@ -542,7 +542,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
 {
 {
 	pmd_val(pmd) |= _PAGE_ACCESSED;
 	pmd_val(pmd) |= _PAGE_ACCESSED;
 
 
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (!(pmd_val(pmd) & _PAGE_NO_READ))
 	if (!(pmd_val(pmd) & _PAGE_NO_READ))
 		pmd_val(pmd) |= _PAGE_SILENT_READ;
 		pmd_val(pmd) |= _PAGE_SILENT_READ;
 	else
 	else

+ 12 - 3
arch/mips/include/uapi/asm/inst.h

@@ -116,7 +116,8 @@ enum cop_op {
 	dmtc_op	      = 0x05, ctc_op	    = 0x06,
 	dmtc_op	      = 0x05, ctc_op	    = 0x06,
 	mthc0_op      = 0x06, mthc_op	    = 0x07,
 	mthc0_op      = 0x06, mthc_op	    = 0x07,
 	bc_op	      = 0x08, bc1eqz_op     = 0x09,
 	bc_op	      = 0x08, bc1eqz_op     = 0x09,
-	bc1nez_op     = 0x0d, cop_op	    = 0x10,
+	mfmc0_op      = 0x0b, bc1nez_op     = 0x0d,
+	wrpgpr_op     = 0x0e, cop_op	    = 0x10,
 	copm_op	      = 0x18
 	copm_op	      = 0x18
 };
 };
 
 
@@ -529,7 +530,7 @@ enum MIPS6e_i8_func {
 };
 };
 
 
 /*
 /*
- * (microMIPS & MIPS16e) NOP instruction.
+ * (microMIPS) NOP instruction.
  */
  */
 #define MM_NOP16	0x0c00
 #define MM_NOP16	0x0c00
 
 
@@ -679,7 +680,7 @@ struct fp0_format {		/* FPU multiply and add format (MIPS32) */
 	;))))))
 	;))))))
 };
 };
 
 
-struct mm_fp0_format {		/* FPU multipy and add format (microMIPS) */
+struct mm_fp0_format {		/* FPU multiply and add format (microMIPS) */
 	__BITFIELD_FIELD(unsigned int opcode : 6,
 	__BITFIELD_FIELD(unsigned int opcode : 6,
 	__BITFIELD_FIELD(unsigned int ft : 5,
 	__BITFIELD_FIELD(unsigned int ft : 5,
 	__BITFIELD_FIELD(unsigned int fs : 5,
 	__BITFIELD_FIELD(unsigned int fs : 5,
@@ -799,6 +800,13 @@ struct mm_x_format {		/* Scaled indexed load format (microMIPS) */
 	;)))))
 	;)))))
 };
 };
 
 
+struct mm_a_format {		/* ADDIUPC format (microMIPS) */
+	__BITFIELD_FIELD(unsigned int opcode : 6,
+	__BITFIELD_FIELD(unsigned int rs : 3,
+	__BITFIELD_FIELD(signed int simmediate : 23,
+	;)))
+};
+
 /*
 /*
  * microMIPS instruction formats (16-bit length)
  * microMIPS instruction formats (16-bit length)
  */
  */
@@ -940,6 +948,7 @@ union mips_instruction {
 	struct mm_i_format mm_i_format;
 	struct mm_i_format mm_i_format;
 	struct mm_m_format mm_m_format;
 	struct mm_m_format mm_m_format;
 	struct mm_x_format mm_x_format;
 	struct mm_x_format mm_x_format;
+	struct mm_a_format mm_a_format;
 	struct mm_b0_format mm_b0_format;
 	struct mm_b0_format mm_b0_format;
 	struct mm_b1_format mm_b1_format;
 	struct mm_b1_format mm_b1_format;
 	struct mm16_m_format mm16_m_format ;
 	struct mm16_m_format mm16_m_format ;

+ 4 - 4
arch/mips/kernel/cpu-bugs64.c

@@ -190,7 +190,7 @@ static inline void check_daddi(void)
 	printk("Checking for the daddi bug... ");
 	printk("Checking for the daddi bug... ");
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	handler = set_except_vector(12, handle_daddi_ov);
+	handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
 	/*
 	/*
 	 * The following code fails to trigger an overflow exception
 	 * The following code fails to trigger an overflow exception
 	 * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
 	 * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
@@ -214,7 +214,7 @@ static inline void check_daddi(void)
 		".set	pop"
 		".set	pop"
 		: "=r" (v), "=&r" (tmp)
 		: "=r" (v), "=&r" (tmp)
 		: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
 		: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
-	set_except_vector(12, handler);
+	set_except_vector(EXCCODE_OV, handler);
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 
 
 	if (daddi_ov) {
 	if (daddi_ov) {
@@ -225,14 +225,14 @@ static inline void check_daddi(void)
 	printk("yes, workaround... ");
 	printk("yes, workaround... ");
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	handler = set_except_vector(12, handle_daddi_ov);
+	handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
 	asm volatile(
 	asm volatile(
 		"addiu	%1, $0, %2\n\t"
 		"addiu	%1, $0, %2\n\t"
 		"dsrl	%1, %1, 1\n\t"
 		"dsrl	%1, %1, 1\n\t"
 		"daddi	%0, %1, %3"
 		"daddi	%0, %1, %3"
 		: "=r" (v), "=&r" (tmp)
 		: "=r" (v), "=&r" (tmp)
 		: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
 		: "I" (0xffffffffffffdb9aUL), "I" (0x1234));
-	set_except_vector(12, handler);
+	set_except_vector(EXCCODE_OV, handler);
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 
 
 	if (daddi_ov) {
 	if (daddi_ov) {

+ 161 - 0
arch/mips/kernel/cpu-probe.c

@@ -98,6 +98,161 @@ static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
 	c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
 	c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
 }
 }
 
 
+/*
+ * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
+ * supported by FPU hardware.
+ */
+static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
+{
+	if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+			    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+		unsigned long sr, fir, fcsr, fcsr0, fcsr1;
+
+		sr = read_c0_status();
+		__enable_fpu(FPU_AS_IS);
+
+		fir = read_32bit_cp1_register(CP1_REVISION);
+		if (fir & MIPS_FPIR_HAS2008) {
+			fcsr = read_32bit_cp1_register(CP1_STATUS);
+
+			fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+			write_32bit_cp1_register(CP1_STATUS, fcsr0);
+			fcsr0 = read_32bit_cp1_register(CP1_STATUS);
+
+			fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+			write_32bit_cp1_register(CP1_STATUS, fcsr1);
+			fcsr1 = read_32bit_cp1_register(CP1_STATUS);
+
+			write_32bit_cp1_register(CP1_STATUS, fcsr);
+
+			if (!(fcsr0 & FPU_CSR_NAN2008))
+				c->options |= MIPS_CPU_NAN_LEGACY;
+			if (fcsr1 & FPU_CSR_NAN2008)
+				c->options |= MIPS_CPU_NAN_2008;
+
+			if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
+				c->fpu_msk31 &= ~FPU_CSR_ABS2008;
+			else
+				c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;
+
+			if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
+				c->fpu_msk31 &= ~FPU_CSR_NAN2008;
+			else
+				c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
+		} else {
+			c->options |= MIPS_CPU_NAN_LEGACY;
+		}
+
+		write_c0_status(sr);
+	} else {
+		c->options |= MIPS_CPU_NAN_LEGACY;
+	}
+}
+
+/*
+ * IEEE 754 conformance mode to use.  Affects the NaN encoding and the
+ * ABS.fmt/NEG.fmt execution mode.
+ */
+static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
+
+/*
+ * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
+ * to support by the FPU emulator according to the IEEE 754 conformance
+ * mode selected.  Note that "relaxed" straps the emulator so that it
+ * allows 2008-NaN binaries even for legacy processors.
+ */
+static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
+{
+	c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
+	c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+	c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
+
+	switch (ieee754) {
+	case STRICT:
+		if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+				    MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+				    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+			c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+		} else {
+			c->options |= MIPS_CPU_NAN_LEGACY;
+			c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+		}
+		break;
+	case LEGACY:
+		c->options |= MIPS_CPU_NAN_LEGACY;
+		c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+		break;
+	case STD2008:
+		c->options |= MIPS_CPU_NAN_2008;
+		c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+		c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+		break;
+	case RELAXED:
+		c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
+		break;
+	}
+}
+
+/*
+ * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * according to the "ieee754=" parameter.
+ */
+static void cpu_set_nan_2008(struct cpuinfo_mips *c)
+{
+	switch (ieee754) {
+	case STRICT:
+		mips_use_nan_legacy = !!cpu_has_nan_legacy;
+		mips_use_nan_2008 = !!cpu_has_nan_2008;
+		break;
+	case LEGACY:
+		mips_use_nan_legacy = !!cpu_has_nan_legacy;
+		mips_use_nan_2008 = !cpu_has_nan_legacy;
+		break;
+	case STD2008:
+		mips_use_nan_legacy = !cpu_has_nan_2008;
+		mips_use_nan_2008 = !!cpu_has_nan_2008;
+		break;
+	case RELAXED:
+		mips_use_nan_legacy = true;
+		mips_use_nan_2008 = true;
+		break;
+	}
+}
+
+/*
+ * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
+ * settings:
+ *
+ * strict:  accept binaries that request a NaN encoding supported by the FPU
+ * legacy:  only accept legacy-NaN binaries
+ * 2008:    only accept 2008-NaN binaries
+ * relaxed: accept any binaries regardless of whether supported by the FPU
+ */
+static int __init ieee754_setup(char *s)
+{
+	if (!s)
+		return -1;
+	else if (!strcmp(s, "strict"))
+		ieee754 = STRICT;
+	else if (!strcmp(s, "legacy"))
+		ieee754 = LEGACY;
+	else if (!strcmp(s, "2008"))
+		ieee754 = STD2008;
+	else if (!strcmp(s, "relaxed"))
+		ieee754 = RELAXED;
+	else
+		return -1;
+
+	if (!(boot_cpu_data.options & MIPS_CPU_FPU))
+		cpu_set_nofpu_2008(&boot_cpu_data);
+	cpu_set_nan_2008(&boot_cpu_data);
+
+	return 0;
+}
+
+early_param("ieee754", ieee754_setup);
+
 /*
 /*
  * Set the FIR feature flags for the FPU emulator.
  * Set the FIR feature flags for the FPU emulator.
  */
  */
@@ -113,6 +268,8 @@ static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
 	if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
 	if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
 			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
 			    MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
 		value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
 		value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+	if (c->options & MIPS_CPU_NAN_2008)
+		value |= MIPS_FPIR_HAS2008;
 	c->fpu_id = value;
 	c->fpu_id = value;
 }
 }
 
 
@@ -137,6 +294,8 @@ static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
 	}
 	}
 
 
 	cpu_set_fpu_fcsr_mask(c);
 	cpu_set_fpu_fcsr_mask(c);
+	cpu_set_fpu_2008(c);
+	cpu_set_nan_2008(c);
 }
 }
 
 
 /*
 /*
@@ -147,6 +306,8 @@ static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
 	c->options &= ~MIPS_CPU_FPU;
 	c->options &= ~MIPS_CPU_FPU;
 	c->fpu_msk31 = mips_nofpu_msk31;
 	c->fpu_msk31 = mips_nofpu_msk31;
 
 
+	cpu_set_nofpu_2008(c);
+	cpu_set_nan_2008(c);
 	cpu_set_nofpu_id(c);
 	cpu_set_nofpu_id(c);
 }
 }
 
 

+ 87 - 15
arch/mips/kernel/elf.c

@@ -11,6 +11,12 @@
 #include <linux/elf.h>
 #include <linux/elf.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 
 
+#include <asm/cpu-info.h>
+
+/* Whether to accept legacy-NaN and 2008-NaN user binaries.  */
+bool mips_use_nan_legacy;
+bool mips_use_nan_2008;
+
 /* FPU modes */
 /* FPU modes */
 enum {
 enum {
 	FP_FRE,
 	FP_FRE,
@@ -68,15 +74,23 @@ static struct mode_req none_req = { true, true, false, true, true };
 int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 		     bool is_interp, struct arch_elf_state *state)
 		     bool is_interp, struct arch_elf_state *state)
 {
 {
-	struct elf32_hdr *ehdr32 = _ehdr;
+	union {
+		struct elf32_hdr e32;
+		struct elf64_hdr e64;
+	} *ehdr = _ehdr;
 	struct elf32_phdr *phdr32 = _phdr;
 	struct elf32_phdr *phdr32 = _phdr;
 	struct elf64_phdr *phdr64 = _phdr;
 	struct elf64_phdr *phdr64 = _phdr;
 	struct mips_elf_abiflags_v0 abiflags;
 	struct mips_elf_abiflags_v0 abiflags;
+	bool elf32;
+	u32 flags;
 	int ret;
 	int ret;
 
 
+	elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+	flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
 	/* Lets see if this is an O32 ELF */
 	/* Lets see if this is an O32 ELF */
-	if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
-		if (ehdr32->e_flags & EF_MIPS_FP64) {
+	if (elf32) {
+		if (flags & EF_MIPS_FP64) {
 			/*
 			/*
 			 * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
 			 * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
 			 * later if needed
 			 * later if needed
@@ -120,13 +134,50 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 	return 0;
 	return 0;
 }
 }
 
 
-int arch_check_elf(void *_ehdr, bool has_interpreter,
+int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
 		   struct arch_elf_state *state)
 		   struct arch_elf_state *state)
 {
 {
-	struct elf32_hdr *ehdr = _ehdr;
+	union {
+		struct elf32_hdr e32;
+		struct elf64_hdr e64;
+	} *ehdr = _ehdr;
+	union {
+		struct elf32_hdr e32;
+		struct elf64_hdr e64;
+	} *iehdr = _interp_ehdr;
 	struct mode_req prog_req, interp_req;
 	struct mode_req prog_req, interp_req;
 	int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
 	int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
-	bool is_mips64;
+	bool elf32;
+	u32 flags;
+
+	elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+	flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
+
+	/*
+	 * Determine the NaN personality, reject the binary if not allowed.
+	 * Also ensure that any interpreter matches the executable.
+	 */
+	if (flags & EF_MIPS_NAN2008) {
+		if (mips_use_nan_2008)
+			state->nan_2008 = 1;
+		else
+			return -ENOEXEC;
+	} else {
+		if (mips_use_nan_legacy)
+			state->nan_2008 = 0;
+		else
+			return -ENOEXEC;
+	}
+	if (has_interpreter) {
+		bool ielf32;
+		u32 iflags;
+
+		ielf32 = iehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
+		iflags = ielf32 ? iehdr->e32.e_flags : iehdr->e64.e_flags;
+
+		if ((flags ^ iflags) & EF_MIPS_NAN2008)
+			return -ELIBBAD;
+	}
 
 
 	if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
 	if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
 		return 0;
 		return 0;
@@ -142,21 +193,18 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
 		abi0 = abi1 = fp_abi;
 		abi0 = abi1 = fp_abi;
 	}
 	}
 
 
-	is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
-		    (ehdr->e_flags & EF_MIPS_ABI2);
+	if (elf32 && !(flags & EF_MIPS_ABI2)) {
+		/* Default to a mode capable of running code expecting FR=0 */
+		state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
 
 
-	if (is_mips64) {
+		/* Allow all ABIs we know about */
+		max_abi = MIPS_ABI_FP_64A;
+	} else {
 		/* MIPS64 code always uses FR=1, thus the default is easy */
 		/* MIPS64 code always uses FR=1, thus the default is easy */
 		state->overall_fp_mode = FP_FR1;
 		state->overall_fp_mode = FP_FR1;
 
 
 		/* Disallow access to the various FPXX & FP64 ABIs */
 		/* Disallow access to the various FPXX & FP64 ABIs */
 		max_abi = MIPS_ABI_FP_SOFT;
 		max_abi = MIPS_ABI_FP_SOFT;
-	} else {
-		/* Default to a mode capable of running code expecting FR=0 */
-		state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
-
-		/* Allow all ABIs we know about */
-		max_abi = MIPS_ABI_FP_64A;
 	}
 	}
 
 
 	if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
 	if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
@@ -254,3 +302,27 @@ void mips_set_personality_fp(struct arch_elf_state *state)
 		BUG();
 		BUG();
 	}
 	}
 }
 }
+
+/*
+ * Select the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
+ * in FCSR according to the ELF NaN personality.
+ */
+void mips_set_personality_nan(struct arch_elf_state *state)
+{
+	struct cpuinfo_mips *c = &boot_cpu_data;
+	struct task_struct *t = current;
+
+	t->thread.fpu.fcr31 = c->fpu_csr31;
+	switch (state->nan_2008) {
+	case 0:
+		break;
+	case 1:
+		if (!(c->fpu_msk31 & FPU_CSR_NAN2008))
+			t->thread.fpu.fcr31 |= FPU_CSR_NAN2008;
+		if (!(c->fpu_msk31 & FPU_CSR_ABS2008))
+			t->thread.fpu.fcr31 |= FPU_CSR_ABS2008;
+		break;
+	default:
+		BUG();
+	}
+}

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

@@ -21,7 +21,7 @@ static struct txx9_pio_reg __iomem *txx9_pioptr;
 
 
 static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
 static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 {
-	return __raw_readl(&txx9_pioptr->din) & (1 << offset);
+	return !!(__raw_readl(&txx9_pioptr->din) & (1 << offset));
 }
 }
 
 
 static void txx9_gpio_set_raw(unsigned int offset, int value)
 static void txx9_gpio_set_raw(unsigned int offset, int value)

+ 0 - 3
arch/mips/kernel/ptrace.c

@@ -548,9 +548,6 @@ static const struct pt_regs_offset regoffset_table[] = {
 	REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
 	REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
 	REG_OFFSET_NAME(c0_cause, cp0_cause),
 	REG_OFFSET_NAME(c0_cause, cp0_cause),
 	REG_OFFSET_NAME(c0_epc, cp0_epc),
 	REG_OFFSET_NAME(c0_epc, cp0_epc),
-#ifdef CONFIG_MIPS_MT_SMTC
-	REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
-#endif
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 	REG_OFFSET_NAME(mpl0, mpl[0]),
 	REG_OFFSET_NAME(mpl0, mpl[0]),
 	REG_OFFSET_NAME(mpl1, mpl[1]),
 	REG_OFFSET_NAME(mpl1, mpl[1]),

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

@@ -623,7 +623,7 @@ static void __init request_crashkernel(struct resource *res)
 
 
 #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
 #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
-#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
+#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
 
 
 static void __init arch_mem_init(char **cmdline_p)
 static void __init arch_mem_init(char **cmdline_p)
 {
 {

+ 3 - 0
arch/mips/kernel/smp-cps.c

@@ -202,6 +202,9 @@ static void boot_core(unsigned core)
 	/* Ensure its coherency is disabled */
 	/* Ensure its coherency is disabled */
 	write_gcr_co_coherence(0);
 	write_gcr_co_coherence(0);
 
 
+	/* Start it with the legacy memory map and exception base */
+	write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
+
 	/* Ensure the core can access the GCRs */
 	/* Ensure the core can access the GCRs */
 	access = read_gcr_access();
 	access = read_gcr_access();
 	access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
 	access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);

+ 8 - 24
arch/mips/kernel/sync-r4k.c

@@ -17,34 +17,22 @@
 #include <asm/barrier.h>
 #include <asm/barrier.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsregs.h>
 
 
-static atomic_t count_start_flag = ATOMIC_INIT(0);
+static unsigned int initcount = 0;
 static atomic_t count_count_start = ATOMIC_INIT(0);
 static atomic_t count_count_start = ATOMIC_INIT(0);
 static atomic_t count_count_stop = ATOMIC_INIT(0);
 static atomic_t count_count_stop = ATOMIC_INIT(0);
-static atomic_t count_reference = ATOMIC_INIT(0);
 
 
 #define COUNTON 100
 #define COUNTON 100
-#define NR_LOOPS 5
+#define NR_LOOPS 3
 
 
 void synchronise_count_master(int cpu)
 void synchronise_count_master(int cpu)
 {
 {
 	int i;
 	int i;
 	unsigned long flags;
 	unsigned long flags;
-	unsigned int initcount;
 
 
 	printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
 	printk(KERN_INFO "Synchronize counters for CPU %u: ", cpu);
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
-	/*
-	 * Notify the slaves that it's time to start
-	 */
-	atomic_set(&count_reference, read_c0_count());
-	atomic_set(&count_start_flag, cpu);
-	smp_wmb();
-
-	/* Count will be initialised to current timer for all CPU's */
-	initcount = read_c0_count();
-
 	/*
 	/*
 	 * We loop a few times to get a primed instruction cache,
 	 * We loop a few times to get a primed instruction cache,
 	 * then the last pass is more or less synchronised and
 	 * then the last pass is more or less synchronised and
@@ -63,9 +51,13 @@ void synchronise_count_master(int cpu)
 		atomic_set(&count_count_stop, 0);
 		atomic_set(&count_count_stop, 0);
 		smp_wmb();
 		smp_wmb();
 
 
-		/* this lets the slaves write their count register */
+		/* Let the slave writes its count register */
 		atomic_inc(&count_count_start);
 		atomic_inc(&count_count_start);
 
 
+		/* Count will be initialised to current timer */
+		if (i == 1)
+			initcount = read_c0_count();
+
 		/*
 		/*
 		 * Everyone initialises count in the last loop:
 		 * Everyone initialises count in the last loop:
 		 */
 		 */
@@ -73,7 +65,7 @@ void synchronise_count_master(int cpu)
 			write_c0_count(initcount);
 			write_c0_count(initcount);
 
 
 		/*
 		/*
-		 * Wait for all slaves to leave the synchronization point:
+		 * Wait for slave to leave the synchronization point:
 		 */
 		 */
 		while (atomic_read(&count_count_stop) != 1)
 		while (atomic_read(&count_count_stop) != 1)
 			mb();
 			mb();
@@ -83,7 +75,6 @@ void synchronise_count_master(int cpu)
 	}
 	}
 	/* Arrange for an interrupt in a short while */
 	/* Arrange for an interrupt in a short while */
 	write_c0_compare(read_c0_count() + COUNTON);
 	write_c0_compare(read_c0_count() + COUNTON);
-	atomic_set(&count_start_flag, 0);
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 
 
@@ -98,19 +89,12 @@ void synchronise_count_master(int cpu)
 void synchronise_count_slave(int cpu)
 void synchronise_count_slave(int cpu)
 {
 {
 	int i;
 	int i;
-	unsigned int initcount;
 
 
 	/*
 	/*
 	 * Not every cpu is online at the time this gets called,
 	 * Not every cpu is online at the time this gets called,
 	 * so we first wait for the master to say everyone is ready
 	 * so we first wait for the master to say everyone is ready
 	 */
 	 */
 
 
-	while (atomic_read(&count_start_flag) != cpu)
-		mb();
-
-	/* Count will be initialised to next expire for all CPU's */
-	initcount = atomic_read(&count_reference);
-
 	for (i = 0; i < NR_LOOPS; i++) {
 	for (i = 0; i < NR_LOOPS; i++) {
 		atomic_inc(&count_count_start);
 		atomic_inc(&count_count_start);
 		while (atomic_read(&count_count_start) != 2)
 		while (atomic_read(&count_count_start) != 2)

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

@@ -2250,7 +2250,7 @@ void __init trap_init(void)
 	 * Only some CPUs have the watch exceptions.
 	 * Only some CPUs have the watch exceptions.
 	 */
 	 */
 	if (cpu_has_watch)
 	if (cpu_has_watch)
-		set_except_vector(23, handle_watch);
+		set_except_vector(EXCCODE_WATCH, handle_watch);
 
 
 	/*
 	/*
 	 * Initialise interrupt handlers
 	 * Initialise interrupt handlers
@@ -2277,27 +2277,27 @@ void __init trap_init(void)
 	if (board_be_init)
 	if (board_be_init)
 		board_be_init();
 		board_be_init();
 
 
-	set_except_vector(0, using_rollback_handler() ? rollback_handle_int
-						      : handle_int);
-	set_except_vector(1, handle_tlbm);
-	set_except_vector(2, handle_tlbl);
-	set_except_vector(3, handle_tlbs);
+	set_except_vector(EXCCODE_INT, using_rollback_handler() ?
+					rollback_handle_int : handle_int);
+	set_except_vector(EXCCODE_MOD, handle_tlbm);
+	set_except_vector(EXCCODE_TLBL, handle_tlbl);
+	set_except_vector(EXCCODE_TLBS, handle_tlbs);
 
 
-	set_except_vector(4, handle_adel);
-	set_except_vector(5, handle_ades);
+	set_except_vector(EXCCODE_ADEL, handle_adel);
+	set_except_vector(EXCCODE_ADES, handle_ades);
 
 
-	set_except_vector(6, handle_ibe);
-	set_except_vector(7, handle_dbe);
+	set_except_vector(EXCCODE_IBE, handle_ibe);
+	set_except_vector(EXCCODE_DBE, handle_dbe);
 
 
-	set_except_vector(8, handle_sys);
-	set_except_vector(9, handle_bp);
-	set_except_vector(10, rdhwr_noopt ? handle_ri :
+	set_except_vector(EXCCODE_SYS, handle_sys);
+	set_except_vector(EXCCODE_BP, handle_bp);
+	set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
 			  (cpu_has_vtag_icache ?
 			  (cpu_has_vtag_icache ?
 			   handle_ri_rdhwr_vivt : handle_ri_rdhwr));
 			   handle_ri_rdhwr_vivt : handle_ri_rdhwr));
-	set_except_vector(11, handle_cpu);
-	set_except_vector(12, handle_ov);
-	set_except_vector(13, handle_tr);
-	set_except_vector(14, handle_msa_fpe);
+	set_except_vector(EXCCODE_CPU, handle_cpu);
+	set_except_vector(EXCCODE_OV, handle_ov);
+	set_except_vector(EXCCODE_TR, handle_tr);
+	set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
 
 
 	if (current_cpu_type() == CPU_R6000 ||
 	if (current_cpu_type() == CPU_R6000 ||
 	    current_cpu_type() == CPU_R6000A) {
 	    current_cpu_type() == CPU_R6000A) {
@@ -2318,25 +2318,25 @@ void __init trap_init(void)
 		board_nmi_handler_setup();
 		board_nmi_handler_setup();
 
 
 	if (cpu_has_fpu && !cpu_has_nofpuex)
 	if (cpu_has_fpu && !cpu_has_nofpuex)
-		set_except_vector(15, handle_fpe);
+		set_except_vector(EXCCODE_FPE, handle_fpe);
 
 
-	set_except_vector(16, handle_ftlb);
+	set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
 
 
 	if (cpu_has_rixiex) {
 	if (cpu_has_rixiex) {
-		set_except_vector(19, tlb_do_page_fault_0);
-		set_except_vector(20, tlb_do_page_fault_0);
+		set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0);
+		set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0);
 	}
 	}
 
 
-	set_except_vector(21, handle_msa);
-	set_except_vector(22, handle_mdmx);
+	set_except_vector(EXCCODE_MSADIS, handle_msa);
+	set_except_vector(EXCCODE_MDMX, handle_mdmx);
 
 
 	if (cpu_has_mcheck)
 	if (cpu_has_mcheck)
-		set_except_vector(24, handle_mcheck);
+		set_except_vector(EXCCODE_MCHECK, handle_mcheck);
 
 
 	if (cpu_has_mipsmt)
 	if (cpu_has_mipsmt)
-		set_except_vector(25, handle_mt);
+		set_except_vector(EXCCODE_THREAD, handle_mt);
 
 
-	set_except_vector(26, handle_dsp);
+	set_except_vector(EXCCODE_DSPDIS, handle_dsp);
 
 
 	if (board_cache_error_setup)
 	if (board_cache_error_setup)
 		board_cache_error_setup();
 		board_cache_error_setup();

+ 1 - 1
arch/mips/kvm/callback.c

@@ -11,4 +11,4 @@
 #include <linux/kvm_host.h>
 #include <linux/kvm_host.h>
 
 
 struct kvm_mips_callbacks *kvm_mips_callbacks;
 struct kvm_mips_callbacks *kvm_mips_callbacks;
-EXPORT_SYMBOL(kvm_mips_callbacks);
+EXPORT_SYMBOL_GPL(kvm_mips_callbacks);

+ 3 - 7
arch/mips/kvm/dyntrans.c

@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
 	} else {
 	} else {
 		mfc0_inst = LW_TEMPLATE;
 		mfc0_inst = LW_TEMPLATE;
 		mfc0_inst |= ((rt & 0x1f) << 16);
 		mfc0_inst |= ((rt & 0x1f) << 16);
-		mfc0_inst |=
-		    offsetof(struct mips_coproc,
-			     reg[rd][sel]) + offsetof(struct kvm_mips_commpage,
-						      cop0);
+		mfc0_inst |= offsetof(struct kvm_mips_commpage,
+				      cop0.reg[rd][sel]);
 	}
 	}
 
 
 	if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
 	if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
 	sel = inst & 0x7;
 	sel = inst & 0x7;
 
 
 	mtc0_inst |= ((rt & 0x1f) << 16);
 	mtc0_inst |= ((rt & 0x1f) << 16);
-	mtc0_inst |=
-	    offsetof(struct mips_coproc,
-		     reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0);
+	mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]);
 
 
 	if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
 	if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
 		kseg0_opc =
 		kseg0_opc =

+ 50 - 66
arch/mips/kvm/emulate.c

@@ -20,6 +20,7 @@
 #include <linux/random.h>
 #include <linux/random.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
+#include <asm/cacheops.h>
 #include <asm/cpu-info.h>
 #include <asm/cpu-info.h>
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
@@ -29,7 +30,6 @@
 #include <asm/r4kcache.h>
 #include <asm/r4kcache.h>
 #define CONFIG_MIPS_MT
 #define CONFIG_MIPS_MT
 
 
-#include "opcode.h"
 #include "interrupt.h"
 #include "interrupt.h"
 #include "commpage.h"
 #include "commpage.h"
 
 
@@ -1239,21 +1239,20 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
 			er = EMULATE_FAIL;
 			er = EMULATE_FAIL;
 			break;
 			break;
 
 
-		case mfmcz_op:
+		case mfmc0_op:
 #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
 #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
 			cop0->stat[MIPS_CP0_STATUS][0]++;
 			cop0->stat[MIPS_CP0_STATUS][0]++;
 #endif
 #endif
-			if (rt != 0) {
+			if (rt != 0)
 				vcpu->arch.gprs[rt] =
 				vcpu->arch.gprs[rt] =
 				    kvm_read_c0_guest_status(cop0);
 				    kvm_read_c0_guest_status(cop0);
-			}
 			/* EI */
 			/* EI */
 			if (inst & 0x20) {
 			if (inst & 0x20) {
-				kvm_debug("[%#lx] mfmcz_op: EI\n",
+				kvm_debug("[%#lx] mfmc0_op: EI\n",
 					  vcpu->arch.pc);
 					  vcpu->arch.pc);
 				kvm_set_c0_guest_status(cop0, ST0_IE);
 				kvm_set_c0_guest_status(cop0, ST0_IE);
 			} else {
 			} else {
-				kvm_debug("[%#lx] mfmcz_op: DI\n",
+				kvm_debug("[%#lx] mfmc0_op: DI\n",
 					  vcpu->arch.pc);
 					  vcpu->arch.pc);
 				kvm_clear_c0_guest_status(cop0, ST0_IE);
 				kvm_clear_c0_guest_status(cop0, ST0_IE);
 			}
 			}
@@ -1545,19 +1544,6 @@ int kvm_mips_sync_icache(unsigned long va, struct kvm_vcpu *vcpu)
 	return 0;
 	return 0;
 }
 }
 
 
-#define MIPS_CACHE_OP_INDEX_INV         0x0
-#define MIPS_CACHE_OP_INDEX_LD_TAG      0x1
-#define MIPS_CACHE_OP_INDEX_ST_TAG      0x2
-#define MIPS_CACHE_OP_IMP               0x3
-#define MIPS_CACHE_OP_HIT_INV           0x4
-#define MIPS_CACHE_OP_FILL_WB_INV       0x5
-#define MIPS_CACHE_OP_HIT_HB            0x6
-#define MIPS_CACHE_OP_FETCH_LOCK        0x7
-
-#define MIPS_CACHE_ICACHE               0x0
-#define MIPS_CACHE_DCACHE               0x1
-#define MIPS_CACHE_SEC                  0x3
-
 enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 					     uint32_t cause,
 					     uint32_t cause,
 					     struct kvm_run *run,
 					     struct kvm_run *run,
@@ -1582,8 +1568,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 	base = (inst >> 21) & 0x1f;
 	base = (inst >> 21) & 0x1f;
 	op_inst = (inst >> 16) & 0x1f;
 	op_inst = (inst >> 16) & 0x1f;
 	offset = (int16_t)inst;
 	offset = (int16_t)inst;
-	cache = (inst >> 16) & 0x3;
-	op = (inst >> 18) & 0x7;
+	cache = op_inst & CacheOp_Cache;
+	op = op_inst & CacheOp_Op;
 
 
 	va = arch->gprs[base] + offset;
 	va = arch->gprs[base] + offset;
 
 
@@ -1595,14 +1581,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 	 * invalidate the caches entirely by stepping through all the
 	 * invalidate the caches entirely by stepping through all the
 	 * ways/indexes
 	 * ways/indexes
 	 */
 	 */
-	if (op == MIPS_CACHE_OP_INDEX_INV) {
+	if (op == Index_Writeback_Inv) {
 		kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
 		kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
 			  vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
 			  vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
 			  arch->gprs[base], offset);
 			  arch->gprs[base], offset);
 
 
-		if (cache == MIPS_CACHE_DCACHE)
+		if (cache == Cache_D)
 			r4k_blast_dcache();
 			r4k_blast_dcache();
-		else if (cache == MIPS_CACHE_ICACHE)
+		else if (cache == Cache_I)
 			r4k_blast_icache();
 			r4k_blast_icache();
 		else {
 		else {
 			kvm_err("%s: unsupported CACHE INDEX operation\n",
 			kvm_err("%s: unsupported CACHE INDEX operation\n",
@@ -1675,9 +1661,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 
 
 skip_fault:
 skip_fault:
 	/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
 	/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
-	if (cache == MIPS_CACHE_DCACHE
-	    && (op == MIPS_CACHE_OP_FILL_WB_INV
-		|| op == MIPS_CACHE_OP_HIT_INV)) {
+	if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
 		flush_dcache_line(va);
 		flush_dcache_line(va);
 
 
 #ifdef CONFIG_KVM_MIPS_DYN_TRANS
 #ifdef CONFIG_KVM_MIPS_DYN_TRANS
@@ -1687,7 +1671,7 @@ skip_fault:
 		 */
 		 */
 		kvm_mips_trans_cache_va(inst, opc, vcpu);
 		kvm_mips_trans_cache_va(inst, opc, vcpu);
 #endif
 #endif
-	} else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) {
+	} else if (op_inst == Hit_Invalidate_I) {
 		flush_dcache_line(va);
 		flush_dcache_line(va);
 		flush_icache_line(va);
 		flush_icache_line(va);
 
 
@@ -1781,7 +1765,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned long cause,
 		kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_SYSCALL << CAUSEB_EXCCODE));
+					  (EXCCODE_SYS << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -1828,7 +1812,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_ld(unsigned long cause,
 	}
 	}
 
 
 	kvm_change_c0_guest_cause(cop0, (0xff),
 	kvm_change_c0_guest_cause(cop0, (0xff),
-				  (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+				  (EXCCODE_TLBL << CAUSEB_EXCCODE));
 
 
 	/* setup badvaddr, context and entryhi registers for the guest */
 	/* setup badvaddr, context and entryhi registers for the guest */
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1874,7 +1858,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_ld(unsigned long cause,
 	}
 	}
 
 
 	kvm_change_c0_guest_cause(cop0, (0xff),
 	kvm_change_c0_guest_cause(cop0, (0xff),
-				  (T_TLB_LD_MISS << CAUSEB_EXCCODE));
+				  (EXCCODE_TLBL << CAUSEB_EXCCODE));
 
 
 	/* setup badvaddr, context and entryhi registers for the guest */
 	/* setup badvaddr, context and entryhi registers for the guest */
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1918,7 +1902,7 @@ enum emulation_result kvm_mips_emulate_tlbmiss_st(unsigned long cause,
 	}
 	}
 
 
 	kvm_change_c0_guest_cause(cop0, (0xff),
 	kvm_change_c0_guest_cause(cop0, (0xff),
-				  (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+				  (EXCCODE_TLBS << CAUSEB_EXCCODE));
 
 
 	/* setup badvaddr, context and entryhi registers for the guest */
 	/* setup badvaddr, context and entryhi registers for the guest */
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -1962,7 +1946,7 @@ enum emulation_result kvm_mips_emulate_tlbinv_st(unsigned long cause,
 	}
 	}
 
 
 	kvm_change_c0_guest_cause(cop0, (0xff),
 	kvm_change_c0_guest_cause(cop0, (0xff),
-				  (T_TLB_ST_MISS << CAUSEB_EXCCODE));
+				  (EXCCODE_TLBS << CAUSEB_EXCCODE));
 
 
 	/* setup badvaddr, context and entryhi registers for the guest */
 	/* setup badvaddr, context and entryhi registers for the guest */
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2033,7 +2017,8 @@ enum emulation_result kvm_mips_emulate_tlbmod(unsigned long cause,
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 	}
 	}
 
 
-	kvm_change_c0_guest_cause(cop0, (0xff), (T_TLB_MOD << CAUSEB_EXCCODE));
+	kvm_change_c0_guest_cause(cop0, (0xff),
+				  (EXCCODE_MOD << CAUSEB_EXCCODE));
 
 
 	/* setup badvaddr, context and entryhi registers for the guest */
 	/* setup badvaddr, context and entryhi registers for the guest */
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
 	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
@@ -2068,7 +2053,7 @@ enum emulation_result kvm_mips_emulate_fpu_exc(unsigned long cause,
 	arch->pc = KVM_GUEST_KSEG0 + 0x180;
 	arch->pc = KVM_GUEST_KSEG0 + 0x180;
 
 
 	kvm_change_c0_guest_cause(cop0, (0xff),
 	kvm_change_c0_guest_cause(cop0, (0xff),
-				  (T_COP_UNUSABLE << CAUSEB_EXCCODE));
+				  (EXCCODE_CPU << CAUSEB_EXCCODE));
 	kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));
 	kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));
 
 
 	return EMULATE_DONE;
 	return EMULATE_DONE;
@@ -2096,7 +2081,7 @@ enum emulation_result kvm_mips_emulate_ri_exc(unsigned long cause,
 		kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_RES_INST << CAUSEB_EXCCODE));
+					  (EXCCODE_RI << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2131,7 +2116,7 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause,
 		kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_BREAK << CAUSEB_EXCCODE));
+					  (EXCCODE_BP << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2166,7 +2151,7 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
 		kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_TRAP << CAUSEB_EXCCODE));
+					  (EXCCODE_TR << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2201,7 +2186,7 @@ enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
 		kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_MSAFPE << CAUSEB_EXCCODE));
+					  (EXCCODE_MSAFPE << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2236,7 +2221,7 @@ enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
 		kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_FPE << CAUSEB_EXCCODE));
+					  (EXCCODE_FPE << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2271,7 +2256,7 @@ enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause,
 		kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);
 		kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);
 
 
 		kvm_change_c0_guest_cause(cop0, (0xff),
 		kvm_change_c0_guest_cause(cop0, (0xff),
-					  (T_MSADIS << CAUSEB_EXCCODE));
+					  (EXCCODE_MSADIS << CAUSEB_EXCCODE));
 
 
 		/* Set PC to the exception entry point */
 		/* Set PC to the exception entry point */
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
 		arch->pc = KVM_GUEST_KSEG0 + 0x180;
@@ -2480,25 +2465,25 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
 
 
 	if (usermode) {
 	if (usermode) {
 		switch (exccode) {
 		switch (exccode) {
-		case T_INT:
-		case T_SYSCALL:
-		case T_BREAK:
-		case T_RES_INST:
-		case T_TRAP:
-		case T_MSAFPE:
-		case T_FPE:
-		case T_MSADIS:
+		case EXCCODE_INT:
+		case EXCCODE_SYS:
+		case EXCCODE_BP:
+		case EXCCODE_RI:
+		case EXCCODE_TR:
+		case EXCCODE_MSAFPE:
+		case EXCCODE_FPE:
+		case EXCCODE_MSADIS:
 			break;
 			break;
 
 
-		case T_COP_UNUSABLE:
+		case EXCCODE_CPU:
 			if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
 			if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
 				er = EMULATE_PRIV_FAIL;
 				er = EMULATE_PRIV_FAIL;
 			break;
 			break;
 
 
-		case T_TLB_MOD:
+		case EXCCODE_MOD:
 			break;
 			break;
 
 
-		case T_TLB_LD_MISS:
+		case EXCCODE_TLBL:
 			/*
 			/*
 			 * We we are accessing Guest kernel space, then send an
 			 * We we are accessing Guest kernel space, then send an
 			 * address error exception to the guest
 			 * address error exception to the guest
@@ -2507,12 +2492,12 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
 				kvm_debug("%s: LD MISS @ %#lx\n", __func__,
 				kvm_debug("%s: LD MISS @ %#lx\n", __func__,
 					  badvaddr);
 					  badvaddr);
 				cause &= ~0xff;
 				cause &= ~0xff;
-				cause |= (T_ADDR_ERR_LD << CAUSEB_EXCCODE);
+				cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE);
 				er = EMULATE_PRIV_FAIL;
 				er = EMULATE_PRIV_FAIL;
 			}
 			}
 			break;
 			break;
 
 
-		case T_TLB_ST_MISS:
+		case EXCCODE_TLBS:
 			/*
 			/*
 			 * We we are accessing Guest kernel space, then send an
 			 * We we are accessing Guest kernel space, then send an
 			 * address error exception to the guest
 			 * address error exception to the guest
@@ -2521,26 +2506,26 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause,
 				kvm_debug("%s: ST MISS @ %#lx\n", __func__,
 				kvm_debug("%s: ST MISS @ %#lx\n", __func__,
 					  badvaddr);
 					  badvaddr);
 				cause &= ~0xff;
 				cause &= ~0xff;
-				cause |= (T_ADDR_ERR_ST << CAUSEB_EXCCODE);
+				cause |= (EXCCODE_ADES << CAUSEB_EXCCODE);
 				er = EMULATE_PRIV_FAIL;
 				er = EMULATE_PRIV_FAIL;
 			}
 			}
 			break;
 			break;
 
 
-		case T_ADDR_ERR_ST:
+		case EXCCODE_ADES:
 			kvm_debug("%s: address error ST @ %#lx\n", __func__,
 			kvm_debug("%s: address error ST @ %#lx\n", __func__,
 				  badvaddr);
 				  badvaddr);
 			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
 			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
 				cause &= ~0xff;
 				cause &= ~0xff;
-				cause |= (T_TLB_ST_MISS << CAUSEB_EXCCODE);
+				cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE);
 			}
 			}
 			er = EMULATE_PRIV_FAIL;
 			er = EMULATE_PRIV_FAIL;
 			break;
 			break;
-		case T_ADDR_ERR_LD:
+		case EXCCODE_ADEL:
 			kvm_debug("%s: address error LD @ %#lx\n", __func__,
 			kvm_debug("%s: address error LD @ %#lx\n", __func__,
 				  badvaddr);
 				  badvaddr);
 			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
 			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
 				cause &= ~0xff;
 				cause &= ~0xff;
-				cause |= (T_TLB_LD_MISS << CAUSEB_EXCCODE);
+				cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE);
 			}
 			}
 			er = EMULATE_PRIV_FAIL;
 			er = EMULATE_PRIV_FAIL;
 			break;
 			break;
@@ -2583,13 +2568,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
 	 * an entry into the guest TLB.
 	 * an entry into the guest TLB.
 	 */
 	 */
 	index = kvm_mips_guest_tlb_lookup(vcpu,
 	index = kvm_mips_guest_tlb_lookup(vcpu,
-					  (va & VPN2_MASK) |
-					  (kvm_read_c0_guest_entryhi
-					   (vcpu->arch.cop0) & ASID_MASK));
+		      (va & VPN2_MASK) |
+		      (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK));
 	if (index < 0) {
 	if (index < 0) {
-		if (exccode == T_TLB_LD_MISS) {
+		if (exccode == EXCCODE_TLBL) {
 			er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
 			er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
-		} else if (exccode == T_TLB_ST_MISS) {
+		} else if (exccode == EXCCODE_TLBS) {
 			er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
 			er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
 		} else {
 		} else {
 			kvm_err("%s: invalid exc code: %d\n", __func__,
 			kvm_err("%s: invalid exc code: %d\n", __func__,
@@ -2604,10 +2588,10 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned long cause,
 		 * exception to the guest
 		 * exception to the guest
 		 */
 		 */
 		if (!TLB_IS_VALID(*tlb, va)) {
 		if (!TLB_IS_VALID(*tlb, va)) {
-			if (exccode == T_TLB_LD_MISS) {
+			if (exccode == EXCCODE_TLBL) {
 				er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
 				er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
 								vcpu);
 								vcpu);
-			} else if (exccode == T_TLB_ST_MISS) {
+			} else if (exccode == EXCCODE_TLBS) {
 				er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
 				er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
 								vcpu);
 								vcpu);
 			} else {
 			} else {

+ 4 - 4
arch/mips/kvm/interrupt.c

@@ -128,7 +128,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ5)) {
 			allowed = 1;
 			allowed = 1;
-			exccode = T_INT;
+			exccode = EXCCODE_INT;
 		}
 		}
 		break;
 		break;
 
 
@@ -137,7 +137,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ0)) {
 			allowed = 1;
 			allowed = 1;
-			exccode = T_INT;
+			exccode = EXCCODE_INT;
 		}
 		}
 		break;
 		break;
 
 
@@ -146,7 +146,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ1)) {
 			allowed = 1;
 			allowed = 1;
-			exccode = T_INT;
+			exccode = EXCCODE_INT;
 		}
 		}
 		break;
 		break;
 
 
@@ -155,7 +155,7 @@ int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (!(kvm_read_c0_guest_status(cop0) & (ST0_EXL | ST0_ERL)))
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
 		    && (kvm_read_c0_guest_status(cop0) & IE_IRQ2)) {
 			allowed = 1;
 			allowed = 1;
-			exccode = T_INT;
+			exccode = EXCCODE_INT;
 		}
 		}
 		break;
 		break;
 
 

+ 6 - 6
arch/mips/kvm/locore.S

@@ -335,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
 
 
 	/* Now restore the host state just enough to run the handlers */
 	/* Now restore the host state just enough to run the handlers */
 
 
-	/* Swtich EBASE to the one used by Linux */
+	/* Switch EBASE to the one used by Linux */
 	/* load up the host EBASE */
 	/* load up the host EBASE */
 	mfc0	v0, CP0_STATUS
 	mfc0	v0, CP0_STATUS
 
 
@@ -490,11 +490,11 @@ __kvm_mips_return_to_guest:
 	REG_ADDU t3, t1, t2
 	REG_ADDU t3, t1, t2
 	LONG_L	k0, (t3)
 	LONG_L	k0, (t3)
 	andi	k0, k0, 0xff
 	andi	k0, k0, 0xff
-	mtc0	k0,CP0_ENTRYHI
+	mtc0	k0, CP0_ENTRYHI
 	ehb
 	ehb
 
 
 	/* Disable RDHWR access */
 	/* Disable RDHWR access */
-	mtc0    zero,  CP0_HWRENA
+	mtc0	zero, CP0_HWRENA
 
 
 	/* load the guest context from VCPU and return */
 	/* load the guest context from VCPU and return */
 	LONG_L	$0, VCPU_R0(k1)
 	LONG_L	$0, VCPU_R0(k1)
@@ -606,11 +606,11 @@ __kvm_mips_return_to_host:
 
 
 	/* Restore RDHWR access */
 	/* Restore RDHWR access */
 	PTR_LI	k0, 0x2000000F
 	PTR_LI	k0, 0x2000000F
-	mtc0	k0,  CP0_HWRENA
+	mtc0	k0, CP0_HWRENA
 
 
 	/* Restore RA, which is the address we will return to */
 	/* Restore RA, which is the address we will return to */
-	LONG_L  ra, PT_R31(k1)
-	j       ra
+	LONG_L	ra, PT_R31(k1)
+	j	ra
 	 nop
 	 nop
 
 
 VECTOR_END(MIPSX(GuestExceptionEnd))
 VECTOR_END(MIPSX(GuestExceptionEnd))

+ 19 - 19
arch/mips/kvm/mips.c

@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
 			    kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
 			    kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
 
 
 			if (!kvm->arch.guest_pmap) {
 			if (!kvm->arch.guest_pmap) {
-				kvm_err("Failed to allocate guest PMAP");
+				kvm_err("Failed to allocate guest PMAP\n");
 				return;
 				return;
 			}
 			}
 
 
@@ -1264,8 +1264,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 	}
 	}
 
 
 	switch (exccode) {
 	switch (exccode) {
-	case T_INT:
-		kvm_debug("[%d]T_INT @ %p\n", vcpu->vcpu_id, opc);
+	case EXCCODE_INT:
+		kvm_debug("[%d]EXCCODE_INT @ %p\n", vcpu->vcpu_id, opc);
 
 
 		++vcpu->stat.int_exits;
 		++vcpu->stat.int_exits;
 		trace_kvm_exit(vcpu, INT_EXITS);
 		trace_kvm_exit(vcpu, INT_EXITS);
@@ -1276,8 +1276,8 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		ret = RESUME_GUEST;
 		ret = RESUME_GUEST;
 		break;
 		break;
 
 
-	case T_COP_UNUSABLE:
-		kvm_debug("T_COP_UNUSABLE: @ PC: %p\n", opc);
+	case EXCCODE_CPU:
+		kvm_debug("EXCCODE_CPU: @ PC: %p\n", opc);
 
 
 		++vcpu->stat.cop_unusable_exits;
 		++vcpu->stat.cop_unusable_exits;
 		trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS);
 		trace_kvm_exit(vcpu, COP_UNUSABLE_EXITS);
@@ -1287,13 +1287,13 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 			ret = RESUME_HOST;
 			ret = RESUME_HOST;
 		break;
 		break;
 
 
-	case T_TLB_MOD:
+	case EXCCODE_MOD:
 		++vcpu->stat.tlbmod_exits;
 		++vcpu->stat.tlbmod_exits;
 		trace_kvm_exit(vcpu, TLBMOD_EXITS);
 		trace_kvm_exit(vcpu, TLBMOD_EXITS);
 		ret = kvm_mips_callbacks->handle_tlb_mod(vcpu);
 		ret = kvm_mips_callbacks->handle_tlb_mod(vcpu);
 		break;
 		break;
 
 
-	case T_TLB_ST_MISS:
+	case EXCCODE_TLBS:
 		kvm_debug("TLB ST fault:  cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n",
 		kvm_debug("TLB ST fault:  cause %#x, status %#lx, PC: %p, BadVaddr: %#lx\n",
 			  cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc,
 			  cause, kvm_read_c0_guest_status(vcpu->arch.cop0), opc,
 			  badvaddr);
 			  badvaddr);
@@ -1303,7 +1303,7 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu);
 		ret = kvm_mips_callbacks->handle_tlb_st_miss(vcpu);
 		break;
 		break;
 
 
-	case T_TLB_LD_MISS:
+	case EXCCODE_TLBL:
 		kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n",
 		kvm_debug("TLB LD fault: cause %#x, PC: %p, BadVaddr: %#lx\n",
 			  cause, opc, badvaddr);
 			  cause, opc, badvaddr);
 
 
@@ -1312,55 +1312,55 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu);
 		ret = kvm_mips_callbacks->handle_tlb_ld_miss(vcpu);
 		break;
 		break;
 
 
-	case T_ADDR_ERR_ST:
+	case EXCCODE_ADES:
 		++vcpu->stat.addrerr_st_exits;
 		++vcpu->stat.addrerr_st_exits;
 		trace_kvm_exit(vcpu, ADDRERR_ST_EXITS);
 		trace_kvm_exit(vcpu, ADDRERR_ST_EXITS);
 		ret = kvm_mips_callbacks->handle_addr_err_st(vcpu);
 		ret = kvm_mips_callbacks->handle_addr_err_st(vcpu);
 		break;
 		break;
 
 
-	case T_ADDR_ERR_LD:
+	case EXCCODE_ADEL:
 		++vcpu->stat.addrerr_ld_exits;
 		++vcpu->stat.addrerr_ld_exits;
 		trace_kvm_exit(vcpu, ADDRERR_LD_EXITS);
 		trace_kvm_exit(vcpu, ADDRERR_LD_EXITS);
 		ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu);
 		ret = kvm_mips_callbacks->handle_addr_err_ld(vcpu);
 		break;
 		break;
 
 
-	case T_SYSCALL:
+	case EXCCODE_SYS:
 		++vcpu->stat.syscall_exits;
 		++vcpu->stat.syscall_exits;
 		trace_kvm_exit(vcpu, SYSCALL_EXITS);
 		trace_kvm_exit(vcpu, SYSCALL_EXITS);
 		ret = kvm_mips_callbacks->handle_syscall(vcpu);
 		ret = kvm_mips_callbacks->handle_syscall(vcpu);
 		break;
 		break;
 
 
-	case T_RES_INST:
+	case EXCCODE_RI:
 		++vcpu->stat.resvd_inst_exits;
 		++vcpu->stat.resvd_inst_exits;
 		trace_kvm_exit(vcpu, RESVD_INST_EXITS);
 		trace_kvm_exit(vcpu, RESVD_INST_EXITS);
 		ret = kvm_mips_callbacks->handle_res_inst(vcpu);
 		ret = kvm_mips_callbacks->handle_res_inst(vcpu);
 		break;
 		break;
 
 
-	case T_BREAK:
+	case EXCCODE_BP:
 		++vcpu->stat.break_inst_exits;
 		++vcpu->stat.break_inst_exits;
 		trace_kvm_exit(vcpu, BREAK_INST_EXITS);
 		trace_kvm_exit(vcpu, BREAK_INST_EXITS);
 		ret = kvm_mips_callbacks->handle_break(vcpu);
 		ret = kvm_mips_callbacks->handle_break(vcpu);
 		break;
 		break;
 
 
-	case T_TRAP:
+	case EXCCODE_TR:
 		++vcpu->stat.trap_inst_exits;
 		++vcpu->stat.trap_inst_exits;
 		trace_kvm_exit(vcpu, TRAP_INST_EXITS);
 		trace_kvm_exit(vcpu, TRAP_INST_EXITS);
 		ret = kvm_mips_callbacks->handle_trap(vcpu);
 		ret = kvm_mips_callbacks->handle_trap(vcpu);
 		break;
 		break;
 
 
-	case T_MSAFPE:
+	case EXCCODE_MSAFPE:
 		++vcpu->stat.msa_fpe_exits;
 		++vcpu->stat.msa_fpe_exits;
 		trace_kvm_exit(vcpu, MSA_FPE_EXITS);
 		trace_kvm_exit(vcpu, MSA_FPE_EXITS);
 		ret = kvm_mips_callbacks->handle_msa_fpe(vcpu);
 		ret = kvm_mips_callbacks->handle_msa_fpe(vcpu);
 		break;
 		break;
 
 
-	case T_FPE:
+	case EXCCODE_FPE:
 		++vcpu->stat.fpe_exits;
 		++vcpu->stat.fpe_exits;
 		trace_kvm_exit(vcpu, FPE_EXITS);
 		trace_kvm_exit(vcpu, FPE_EXITS);
 		ret = kvm_mips_callbacks->handle_fpe(vcpu);
 		ret = kvm_mips_callbacks->handle_fpe(vcpu);
 		break;
 		break;
 
 
-	case T_MSADIS:
+	case EXCCODE_MSADIS:
 		++vcpu->stat.msa_disabled_exits;
 		++vcpu->stat.msa_disabled_exits;
 		trace_kvm_exit(vcpu, MSA_DISABLED_EXITS);
 		trace_kvm_exit(vcpu, MSA_DISABLED_EXITS);
 		ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
 		ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
@@ -1620,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = {
 	.notifier_call = kvm_mips_csr_die_notify,
 	.notifier_call = kvm_mips_csr_die_notify,
 };
 };
 
 
-int __init kvm_mips_init(void)
+static int __init kvm_mips_init(void)
 {
 {
 	int ret;
 	int ret;
 
 
@@ -1646,7 +1646,7 @@ int __init kvm_mips_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-void __exit kvm_mips_exit(void)
+static void __exit kvm_mips_exit(void)
 {
 {
 	kvm_exit();
 	kvm_exit();
 
 

+ 0 - 22
arch/mips/kvm/opcode.h

@@ -1,22 +0,0 @@
-/*
- * 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) 2012  MIPS Technologies, Inc.  All rights reserved.
- * Authors: Sanjay Lal <sanjayl@kymasys.com>
- */
-
-/* Define opcode values not defined in <asm/isnt.h> */
-
-#ifndef __KVM_MIPS_OPCODE_H__
-#define __KVM_MIPS_OPCODE_H__
-
-/* COP0 Ops */
-#define mfmcz_op	0x0b	/* 01011 */
-#define wrpgpr_op	0x0e	/* 01110 */
-
-/* COP0 opcodes (only if COP0 and CO=1): */
-#define wait_op		0x20	/* 100000 */
-
-#endif /* __KVM_MIPS_OPCODE_H__ */

+ 20 - 57
arch/mips/kvm/tlb.c

@@ -35,17 +35,17 @@
 #define PRIx64 "llx"
 #define PRIx64 "llx"
 
 
 atomic_t kvm_mips_instance;
 atomic_t kvm_mips_instance;
-EXPORT_SYMBOL(kvm_mips_instance);
+EXPORT_SYMBOL_GPL(kvm_mips_instance);
 
 
 /* These function pointers are initialized once the KVM module is loaded */
 /* These function pointers are initialized once the KVM module is loaded */
 kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
 kvm_pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
-EXPORT_SYMBOL(kvm_mips_gfn_to_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn);
 
 
 void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
 void (*kvm_mips_release_pfn_clean)(kvm_pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_release_pfn_clean);
+EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean);
 
 
 bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
 bool (*kvm_mips_is_error_pfn)(kvm_pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_is_error_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn);
 
 
 uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
 uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
 {
 {
@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void)
 	mtc0_tlbw_hazard();
 	mtc0_tlbw_hazard();
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
-EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs);
 
 
 void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 {
 {
@@ -139,7 +139,7 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 			 (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
 			 (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
 	}
 	}
 }
 }
-EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
 
 
 static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
 {
@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu,
 
 
 	return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 	return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 }
 }
-EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
+EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa);
 
 
 /* XXXKYMA: Must be called with interrupts disabled */
 /* XXXKYMA: Must be called with interrupts disabled */
 /* set flush_dcache_mask == 0 if no dcache flush required */
 /* set flush_dcache_mask == 0 if no dcache flush required */
@@ -308,7 +308,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
 	return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
 	return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
 				       flush_dcache_mask);
 				       flush_dcache_mask);
 }
 }
-EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault);
 
 
 int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
 int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
 	struct kvm_vcpu *vcpu)
 	struct kvm_vcpu *vcpu)
@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
 
 
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault);
 
 
 int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
 int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
 					 struct kvm_mips_tlb *tlb,
 					 struct kvm_mips_tlb *tlb,
@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
 	return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
 	return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
 				       tlb->tlb_mask);
 				       tlb->tlb_mask);
 }
 }
-EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault);
 
 
 int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 {
 {
@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 
 
 	return index;
 	return index;
 }
 }
-EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup);
 
 
 int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 {
 {
@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 
 
 	return idx;
 	return idx;
 }
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup);
 
 
 int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 {
 {
@@ -505,44 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 
 
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
-
-/* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */
-int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index)
-{
-	unsigned long flags, old_entryhi;
-
-	if (index >= current_cpu_data.tlbsize)
-		BUG();
-
-	local_irq_save(flags);
-
-	old_entryhi = read_c0_entryhi();
-
-	write_c0_entryhi(UNIQUE_ENTRYHI(index));
-	mtc0_tlbw_hazard();
-
-	write_c0_index(index);
-	mtc0_tlbw_hazard();
-
-	write_c0_entrylo0(0);
-	mtc0_tlbw_hazard();
-
-	write_c0_entrylo1(0);
-	mtc0_tlbw_hazard();
-
-	tlb_write_indexed();
-	mtc0_tlbw_hazard();
-	tlbw_use_hazard();
-
-	write_c0_entryhi(old_entryhi);
-	mtc0_tlbw_hazard();
-	tlbw_use_hazard();
-
-	local_irq_restore(flags);
-
-	return 0;
-}
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv);
 
 
 void kvm_mips_flush_host_tlb(int skip_kseg0)
 void kvm_mips_flush_host_tlb(int skip_kseg0)
 {
 {
@@ -594,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
-EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
+EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb);
 
 
 void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
 void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
 			     struct kvm_vcpu *vcpu)
 			     struct kvm_vcpu *vcpu)
@@ -642,7 +605,7 @@ void kvm_local_flush_tlb_all(void)
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
-EXPORT_SYMBOL(kvm_local_flush_tlb_all);
+EXPORT_SYMBOL_GPL(kvm_local_flush_tlb_all);
 
 
 /**
 /**
  * kvm_mips_migrate_count() - Migrate timer.
  * kvm_mips_migrate_count() - Migrate timer.
@@ -673,8 +636,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
-	if (((vcpu->arch.
-	      guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) {
+	if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) &
+							ASID_VERSION_MASK) {
 		kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
 		kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
 		vcpu->arch.guest_kernel_asid[cpu] =
 		vcpu->arch.guest_kernel_asid[cpu] =
 		    vcpu->arch.guest_kernel_mm.context.asid[cpu];
 		    vcpu->arch.guest_kernel_mm.context.asid[cpu];
@@ -739,7 +702,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 
 
 }
 }
-EXPORT_SYMBOL(kvm_arch_vcpu_load);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_load);
 
 
 /* ASID can change if another task is scheduled during preemption */
 /* ASID can change if another task is scheduled during preemption */
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -768,7 +731,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
-EXPORT_SYMBOL(kvm_arch_vcpu_put);
+EXPORT_SYMBOL_GPL(kvm_arch_vcpu_put);
 
 
 uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 {
 {
@@ -813,4 +776,4 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 
 
 	return inst;
 	return inst;
 }
 }
-EXPORT_SYMBOL(kvm_get_inst);
+EXPORT_SYMBOL_GPL(kvm_get_inst);

+ 0 - 1
arch/mips/kvm/trap_emul.c

@@ -16,7 +16,6 @@
 
 
 #include <linux/kvm_host.h>
 #include <linux/kvm_host.h>
 
 
-#include "opcode.h"
 #include "interrupt.h"
 #include "interrupt.h"
 
 
 static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
 static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)

+ 1 - 29
arch/mips/lib/mips-atomic.c

@@ -57,7 +57,6 @@ notrace void arch_local_irq_disable(void)
 }
 }
 EXPORT_SYMBOL(arch_local_irq_disable);
 EXPORT_SYMBOL(arch_local_irq_disable);
 
 
-
 notrace unsigned long arch_local_irq_save(void)
 notrace unsigned long arch_local_irq_save(void)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
@@ -111,31 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags)
 }
 }
 EXPORT_SYMBOL(arch_local_irq_restore);
 EXPORT_SYMBOL(arch_local_irq_restore);
 
 
-
-notrace void __arch_local_irq_restore(unsigned long flags)
-{
-	unsigned long __tmp1;
-
-	preempt_disable();
-
-	__asm__ __volatile__(
-	"	.set	push						\n"
-	"	.set	noreorder					\n"
-	"	.set	noat						\n"
-	"	mfc0	$1, $12						\n"
-	"	andi	%[flags], 1					\n"
-	"	ori	$1, 0x1f					\n"
-	"	xori	$1, 0x1f					\n"
-	"	or	%[flags], $1					\n"
-	"	mtc0	%[flags], $12					\n"
-	"	" __stringify(__irq_disable_hazard) "			\n"
-	"	.set	pop						\n"
-	: [flags] "=r" (__tmp1)
-	: "0" (flags)
-	: "memory");
-
-	preempt_enable();
-}
-EXPORT_SYMBOL(__arch_local_irq_restore);
-
-#endif /* !CONFIG_CPU_MIPSR2 */
+#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */

+ 21 - 0
arch/mips/loongson64/Platform

@@ -22,6 +22,27 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
   endif
   endif
 endif
 endif
 
 
+cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
+#
+# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
+# as MIPS64 R2; older versions as just R1.  This leaves the possibility open
+# that GCC might generate R2 code for -march=loongson3a which then is rejected
+# by GAS.  The cc-option can't probe for this behaviour so -march=loongson3a
+# can't easily be used safely within the kbuild framework.
+#
+ifeq ($(call cc-ifversion, -ge, 0409, y), y)
+  ifeq ($(call ld-ifversion, -ge, 22500000, y), y)
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+  else
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+  endif
+else
+    cflags-$(CONFIG_CPU_LOONGSON3)  += \
+      $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+endif
+
 #
 #
 # Loongson Machines' Support
 # Loongson Machines' Support
 #
 #

+ 7 - 3
arch/mips/loongson64/loongson-3/hpet.c

@@ -13,6 +13,9 @@
 #define SMBUS_PCI_REG64		0x64
 #define SMBUS_PCI_REG64		0x64
 #define SMBUS_PCI_REGB4		0xb4
 #define SMBUS_PCI_REGB4		0xb4
 
 
+#define HPET_MIN_CYCLES		64
+#define HPET_MIN_PROG_DELTA	(HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
+
 static DEFINE_SPINLOCK(hpet_lock);
 static DEFINE_SPINLOCK(hpet_lock);
 DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
 DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
 
 
@@ -161,8 +164,9 @@ static int hpet_next_event(unsigned long delta,
 	cnt += delta;
 	cnt += delta;
 	hpet_write(HPET_T0_CMP, cnt);
 	hpet_write(HPET_T0_CMP, cnt);
 
 
-	res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
-	return res;
+	res = (int)(cnt - hpet_read(HPET_COUNTER));
+
+	return res < HPET_MIN_CYCLES ? -ETIME : 0;
 }
 }
 
 
 static irqreturn_t hpet_irq_handler(int irq, void *data)
 static irqreturn_t hpet_irq_handler(int irq, void *data)
@@ -237,7 +241,7 @@ void __init setup_hpet_timer(void)
 	cd->cpumask = cpumask_of(cpu);
 	cd->cpumask = cpumask_of(cpu);
 	clockevent_set_clock(cd, HPET_FREQ);
 	clockevent_set_clock(cd, HPET_FREQ);
 	cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
 	cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
-	cd->min_delta_ns = 5000;
+	cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
 
 
 	clockevents_register_device(cd);
 	clockevents_register_device(cd);
 	setup_irq(HPET_T0_IRQ, &hpet_irq);
 	setup_irq(HPET_T0_IRQ, &hpet_irq);

+ 13 - 7
arch/mips/loongson64/loongson-3/smp.c

@@ -30,13 +30,13 @@
 #include "smp.h"
 #include "smp.h"
 
 
 DEFINE_PER_CPU(int, cpu_state);
 DEFINE_PER_CPU(int, cpu_state);
-DEFINE_PER_CPU(uint32_t, core0_c0count);
 
 
 static void *ipi_set0_regs[16];
 static void *ipi_set0_regs[16];
 static void *ipi_clear0_regs[16];
 static void *ipi_clear0_regs[16];
 static void *ipi_status0_regs[16];
 static void *ipi_status0_regs[16];
 static void *ipi_en0_regs[16];
 static void *ipi_en0_regs[16];
 static void *ipi_mailbox_buf[16];
 static void *ipi_mailbox_buf[16];
+static uint32_t core0_c0count[NR_CPUS];
 
 
 /* read a 32bit value from ipi register */
 /* read a 32bit value from ipi register */
 #define loongson3_ipi_read32(addr) readl(addr)
 #define loongson3_ipi_read32(addr) readl(addr)
@@ -275,12 +275,14 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
 	if (action & SMP_ASK_C0COUNT) {
 	if (action & SMP_ASK_C0COUNT) {
 		BUG_ON(cpu != 0);
 		BUG_ON(cpu != 0);
 		c0count = read_c0_count();
 		c0count = read_c0_count();
-		for (i = 1; i < num_possible_cpus(); i++)
-			per_cpu(core0_c0count, i) = c0count;
+		c0count = c0count ? c0count : 1;
+		for (i = 1; i < nr_cpu_ids; i++)
+			core0_c0count[i] = c0count;
+		__wbflush(); /* Let others see the result ASAP */
 	}
 	}
 }
 }
 
 
-#define MAX_LOOPS 1111
+#define MAX_LOOPS 800
 /*
 /*
  * SMP init and finish on secondary CPUs
  * SMP init and finish on secondary CPUs
  */
  */
@@ -305,16 +307,20 @@ static void loongson3_init_secondary(void)
 		cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 		cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 
 
 	i = 0;
 	i = 0;
-	__this_cpu_write(core0_c0count, 0);
+	core0_c0count[cpu] = 0;
 	loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
 	loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
-	while (!__this_cpu_read(core0_c0count)) {
+	while (!core0_c0count[cpu]) {
 		i++;
 		i++;
 		cpu_relax();
 		cpu_relax();
 	}
 	}
 
 
 	if (i > MAX_LOOPS)
 	if (i > MAX_LOOPS)
 		i = MAX_LOOPS;
 		i = MAX_LOOPS;
-	initcount = __this_cpu_read(core0_c0count) + i;
+	if (cpu_data[cpu].package)
+		initcount = core0_c0count[cpu] + i;
+	else /* Local access is faster for loops */
+		initcount = core0_c0count[cpu] + i/2;
+
 	write_c0_count(initcount);
 	write_c0_count(initcount);
 }
 }
 
 

+ 4 - 0
arch/mips/math-emu/cp1emu.c

@@ -1266,6 +1266,8 @@ branch_common:
 						 */
 						 */
 						sig = mips_dsemul(xcp, ir,
 						sig = mips_dsemul(xcp, ir,
 								  contpc);
 								  contpc);
+						if (sig < 0)
+							break;
 						if (sig)
 						if (sig)
 							xcp->cp0_epc = bcpc;
 							xcp->cp0_epc = bcpc;
 						/*
 						/*
@@ -1319,6 +1321,8 @@ branch_common:
 				 * instruction in the dslot
 				 * instruction in the dslot
 				 */
 				 */
 				sig = mips_dsemul(xcp, ir, contpc);
 				sig = mips_dsemul(xcp, ir, contpc);
+				if (sig < 0)
+					break;
 				if (sig)
 				if (sig)
 					xcp->cp0_epc = bcpc;
 					xcp->cp0_epc = bcpc;
 				/* SIGILL forces out of the emulation loop.  */
 				/* SIGILL forces out of the emulation loop.  */

+ 25 - 13
arch/mips/math-emu/dp_simple.c

@@ -23,27 +23,39 @@
 
 
 union ieee754dp ieee754dp_neg(union ieee754dp x)
 union ieee754dp ieee754dp_neg(union ieee754dp x)
 {
 {
-	unsigned int oldrm;
 	union ieee754dp y;
 	union ieee754dp y;
 
 
-	oldrm = ieee754_csr.rm;
-	ieee754_csr.rm = FPU_CSR_RD;
-	y = ieee754dp_sub(ieee754dp_zero(0), x);
-	ieee754_csr.rm = oldrm;
+	if (ieee754_csr.abs2008) {
+		y = x;
+		DPSIGN(y) = !DPSIGN(x);
+	} else {
+		unsigned int oldrm;
+
+		oldrm = ieee754_csr.rm;
+		ieee754_csr.rm = FPU_CSR_RD;
+		y = ieee754dp_sub(ieee754dp_zero(0), x);
+		ieee754_csr.rm = oldrm;
+	}
 	return y;
 	return y;
 }
 }
 
 
 union ieee754dp ieee754dp_abs(union ieee754dp x)
 union ieee754dp ieee754dp_abs(union ieee754dp x)
 {
 {
-	unsigned int oldrm;
 	union ieee754dp y;
 	union ieee754dp y;
 
 
-	oldrm = ieee754_csr.rm;
-	ieee754_csr.rm = FPU_CSR_RD;
-	if (DPSIGN(x))
-		y = ieee754dp_sub(ieee754dp_zero(0), x);
-	else
-		y = ieee754dp_add(ieee754dp_zero(0), x);
-	ieee754_csr.rm = oldrm;
+	if (ieee754_csr.abs2008) {
+		y = x;
+		DPSIGN(y) = 0;
+	} else {
+		unsigned int oldrm;
+
+		oldrm = ieee754_csr.rm;
+		ieee754_csr.rm = FPU_CSR_RD;
+		if (DPSIGN(x))
+			y = ieee754dp_sub(ieee754dp_zero(0), x);
+		else
+			y = ieee754dp_add(ieee754dp_zero(0), x);
+		ieee754_csr.rm = oldrm;
+	}
 	return y;
 	return y;
 }
 }

+ 6 - 3
arch/mips/math-emu/dp_tint.c

@@ -38,10 +38,13 @@ int ieee754dp_tint(union ieee754dp x)
 	switch (xc) {
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754si_indef();
 		return ieee754si_indef();
 
 
+	case IEEE754_CLASS_INF:
+		ieee754_setcx(IEEE754_INVALID_OPERATION);
+		return ieee754si_overflow(xs);
+
 	case IEEE754_CLASS_ZERO:
 	case IEEE754_CLASS_ZERO:
 		return 0;
 		return 0;
 
 
@@ -53,7 +56,7 @@ int ieee754dp_tint(union ieee754dp x)
 		/* Set invalid. We will only use overflow for floating
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		   point overflow */
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754si_indef();
+		return ieee754si_overflow(xs);
 	}
 	}
 	/* oh gawd */
 	/* oh gawd */
 	if (xe > DP_FBITS) {
 	if (xe > DP_FBITS) {
@@ -93,7 +96,7 @@ int ieee754dp_tint(union ieee754dp x)
 		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
 		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
 			/* This can happen after rounding */
 			/* This can happen after rounding */
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
-			return ieee754si_indef();
+			return ieee754si_overflow(xs);
 		}
 		}
 		if (round || sticky)
 		if (round || sticky)
 			ieee754_setcx(IEEE754_INEXACT);
 			ieee754_setcx(IEEE754_INEXACT);

+ 6 - 3
arch/mips/math-emu/dp_tlong.c

@@ -38,10 +38,13 @@ s64 ieee754dp_tlong(union ieee754dp x)
 	switch (xc) {
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754di_indef();
 		return ieee754di_indef();
 
 
+	case IEEE754_CLASS_INF:
+		ieee754_setcx(IEEE754_INVALID_OPERATION);
+		return ieee754di_overflow(xs);
+
 	case IEEE754_CLASS_ZERO:
 	case IEEE754_CLASS_ZERO:
 		return 0;
 		return 0;
 
 
@@ -56,7 +59,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
 		/* Set invalid. We will only use overflow for floating
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		   point overflow */
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754di_indef();
+		return ieee754di_overflow(xs);
 	}
 	}
 	/* oh gawd */
 	/* oh gawd */
 	if (xe > DP_FBITS) {
 	if (xe > DP_FBITS) {
@@ -97,7 +100,7 @@ s64 ieee754dp_tlong(union ieee754dp x)
 		if ((xm >> 63) != 0) {
 		if ((xm >> 63) != 0) {
 			/* This can happen after rounding */
 			/* This can happen after rounding */
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
-			return ieee754di_indef();
+			return ieee754di_overflow(xs);
 		}
 		}
 		if (round || sticky)
 		if (round || sticky)
 			ieee754_setcx(IEEE754_INEXACT);
 			ieee754_setcx(IEEE754_INEXACT);

+ 52 - 25
arch/mips/math-emu/dsemul.c

@@ -31,17 +31,41 @@ struct emuframe {
 	unsigned long		epc;
 	unsigned long		epc;
 };
 };
 
 
+/*
+ * Set up an emulation frame for instruction IR, from a delay slot of
+ * a branch jumping to CPC.  Return 0 if successful, -1 if no emulation
+ * required, otherwise a signal number causing a frame setup failure.
+ */
 int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 {
 {
+	int isa16 = get_isa16_mode(regs->cp0_epc);
+	mips_instruction break_math;
 	struct emuframe __user *fr;
 	struct emuframe __user *fr;
 	int err;
 	int err;
 
 
-	if ((get_isa16_mode(regs->cp0_epc) && ((ir >> 16) == MM_NOP16)) ||
-		(ir == 0)) {
-		/* NOP is easy */
-		regs->cp0_epc = cpc;
-		clear_delay_slot(regs);
-		return 0;
+	/* NOP is easy */
+	if (ir == 0)
+		return -1;
+
+	/* microMIPS instructions */
+	if (isa16) {
+		union mips_instruction insn = { .word = ir };
+
+		/* NOP16 aka MOVE16 $0, $0 */
+		if ((ir >> 16) == MM_NOP16)
+			return -1;
+
+		/* ADDIUPC */
+		if (insn.mm_a_format.opcode == mm_addiupc_op) {
+			unsigned int rs;
+			s32 v;
+
+			rs = (((insn.mm_a_format.rs + 0x1e) & 0xf) + 2);
+			v = regs->cp0_epc & ~3;
+			v += insn.mm_a_format.simmediate << 2;
+			regs->regs[rs] = (long)v;
+			return -1;
+		}
 	}
 	}
 
 
 	pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
 	pr_debug("dsemul %lx %lx\n", regs->cp0_epc, cpc);
@@ -55,14 +79,10 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 	 * Algorithmics used a system call instruction, and
 	 * Algorithmics used a system call instruction, and
 	 * borrowed that vector.  MIPS/Linux version is a bit
 	 * borrowed that vector.  MIPS/Linux version is a bit
 	 * more heavyweight in the interests of portability and
 	 * more heavyweight in the interests of portability and
-	 * multiprocessor support.  For Linux we generate a
-	 * an unaligned access and force an address error exception.
-	 *
-	 * For embedded systems (stand-alone) we prefer to use a
-	 * non-existing CP1 instruction. This prevents us from emulating
-	 * branches, but gives us a cleaner interface to the exception
-	 * handler (single entry point).
+	 * multiprocessor support.  For Linux we use a BREAK 514
+	 * instruction causing a breakpoint exception.
 	 */
 	 */
+	break_math = BREAK_MATH(isa16);
 
 
 	/* Ensure that the two instructions are in the same cache line */
 	/* Ensure that the two instructions are in the same cache line */
 	fr = (struct emuframe __user *)
 	fr = (struct emuframe __user *)
@@ -72,14 +92,18 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 	if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
 	if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
 		return SIGBUS;
 		return SIGBUS;
 
 
-	if (get_isa16_mode(regs->cp0_epc)) {
-		err = __put_user(ir >> 16, (u16 __user *)(&fr->emul));
-		err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2));
-		err |= __put_user(BREAK_MATH >> 16, (u16 __user *)(&fr->badinst));
-		err |= __put_user(BREAK_MATH & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2));
+	if (isa16) {
+		err = __put_user(ir >> 16,
+				 (u16 __user *)(&fr->emul));
+		err |= __put_user(ir & 0xffff,
+				  (u16 __user *)((long)(&fr->emul) + 2));
+		err |= __put_user(break_math >> 16,
+				  (u16 __user *)(&fr->badinst));
+		err |= __put_user(break_math & 0xffff,
+				  (u16 __user *)((long)(&fr->badinst) + 2));
 	} else {
 	} else {
 		err = __put_user(ir, &fr->emul);
 		err = __put_user(ir, &fr->emul);
-		err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst);
+		err |= __put_user(break_math, &fr->badinst);
 	}
 	}
 
 
 	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
 	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
@@ -90,8 +114,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 		return SIGBUS;
 		return SIGBUS;
 	}
 	}
 
 
-	regs->cp0_epc = ((unsigned long) &fr->emul) |
-		get_isa16_mode(regs->cp0_epc);
+	regs->cp0_epc = (unsigned long)&fr->emul | isa16;
 
 
 	flush_cache_sigtramp((unsigned long)&fr->emul);
 	flush_cache_sigtramp((unsigned long)&fr->emul);
 
 
@@ -100,6 +123,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
 
 
 int do_dsemulret(struct pt_regs *xcp)
 int do_dsemulret(struct pt_regs *xcp)
 {
 {
+	int isa16 = get_isa16_mode(xcp->cp0_epc);
 	struct emuframe __user *fr;
 	struct emuframe __user *fr;
 	unsigned long epc;
 	unsigned long epc;
 	u32 insn, cookie;
 	u32 insn, cookie;
@@ -122,16 +146,19 @@ int do_dsemulret(struct pt_regs *xcp)
 	 *  - Is the instruction pointed to by the EPC an BREAK_MATH?
 	 *  - Is the instruction pointed to by the EPC an BREAK_MATH?
 	 *  - Is the following memory word the BD_COOKIE?
 	 *  - Is the following memory word the BD_COOKIE?
 	 */
 	 */
-	if (get_isa16_mode(xcp->cp0_epc)) {
-		err = __get_user(instr[0], (u16 __user *)(&fr->badinst));
-		err |= __get_user(instr[1], (u16 __user *)((long)(&fr->badinst) + 2));
+	if (isa16) {
+		err = __get_user(instr[0],
+				 (u16 __user *)(&fr->badinst));
+		err |= __get_user(instr[1],
+				  (u16 __user *)((long)(&fr->badinst) + 2));
 		insn = (instr[0] << 16) | instr[1];
 		insn = (instr[0] << 16) | instr[1];
 	} else {
 	} else {
 		err = __get_user(insn, &fr->badinst);
 		err = __get_user(insn, &fr->badinst);
 	}
 	}
 	err |= __get_user(cookie, &fr->cookie);
 	err |= __get_user(cookie, &fr->cookie);
 
 
-	if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
+	if (unlikely(err ||
+		     insn != BREAK_MATH(isa16) || cookie != BD_COOKIE)) {
 		MIPS_FPU_EMU_INC_STATS(errors);
 		MIPS_FPU_EMU_INC_STATS(errors);
 		return 0;
 		return 0;
 	}
 	}

+ 4 - 2
arch/mips/math-emu/ieee754.c

@@ -59,7 +59,8 @@ const union ieee754dp __ieee754dp_spcvals[] = {
 	DPCNST(1, 3,           0x4000000000000ULL),	/* - 10.0   */
 	DPCNST(1, 3,           0x4000000000000ULL),	/* - 10.0   */
 	DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL),	/* + infinity */
 	DPCNST(0, DP_EMAX + 1, 0x0000000000000ULL),	/* + infinity */
 	DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL),	/* - infinity */
 	DPCNST(1, DP_EMAX + 1, 0x0000000000000ULL),	/* - infinity */
-	DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL),	/* + indef quiet Nan */
+	DPCNST(0, DP_EMAX + 1, 0x7FFFFFFFFFFFFULL),	/* + ind legacy qNaN */
+	DPCNST(0, DP_EMAX + 1, 0x8000000000000ULL),	/* + indef 2008 qNaN */
 	DPCNST(0, DP_EMAX,     0xFFFFFFFFFFFFFULL),	/* + max */
 	DPCNST(0, DP_EMAX,     0xFFFFFFFFFFFFFULL),	/* + max */
 	DPCNST(1, DP_EMAX,     0xFFFFFFFFFFFFFULL),	/* - max */
 	DPCNST(1, DP_EMAX,     0xFFFFFFFFFFFFFULL),	/* - max */
 	DPCNST(0, DP_EMIN,     0x0000000000000ULL),	/* + min normal */
 	DPCNST(0, DP_EMIN,     0x0000000000000ULL),	/* + min normal */
@@ -82,7 +83,8 @@ const union ieee754sp __ieee754sp_spcvals[] = {
 	SPCNST(1, 3,	       0x200000),	/* - 10.0   */
 	SPCNST(1, 3,	       0x200000),	/* - 10.0   */
 	SPCNST(0, SP_EMAX + 1, 0x000000),	/* + infinity */
 	SPCNST(0, SP_EMAX + 1, 0x000000),	/* + infinity */
 	SPCNST(1, SP_EMAX + 1, 0x000000),	/* - infinity */
 	SPCNST(1, SP_EMAX + 1, 0x000000),	/* - infinity */
-	SPCNST(0, SP_EMAX + 1, 0x3FFFFF),	/* + indef quiet Nan  */
+	SPCNST(0, SP_EMAX + 1, 0x3FFFFF),	/* + indef legacy quiet NaN */
+	SPCNST(0, SP_EMAX + 1, 0x400000),	/* + indef 2008 quiet NaN */
 	SPCNST(0, SP_EMAX,     0x7FFFFF),	/* + max normal */
 	SPCNST(0, SP_EMAX,     0x7FFFFF),	/* + max normal */
 	SPCNST(1, SP_EMAX,     0x7FFFFF),	/* - max normal */
 	SPCNST(1, SP_EMAX,     0x7FFFFF),	/* - max normal */
 	SPCNST(0, SP_EMIN,     0x000000),	/* + min normal */
 	SPCNST(0, SP_EMIN,     0x000000),	/* + min normal */

+ 29 - 13
arch/mips/math-emu/ieee754.h

@@ -221,15 +221,16 @@ union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
 #define IEEE754_SPCVAL_NTEN		5	/* -10.0 */
 #define IEEE754_SPCVAL_NTEN		5	/* -10.0 */
 #define IEEE754_SPCVAL_PINFINITY	6	/* +inf */
 #define IEEE754_SPCVAL_PINFINITY	6	/* +inf */
 #define IEEE754_SPCVAL_NINFINITY	7	/* -inf */
 #define IEEE754_SPCVAL_NINFINITY	7	/* -inf */
-#define IEEE754_SPCVAL_INDEF		8	/* quiet NaN */
-#define IEEE754_SPCVAL_PMAX		9	/* +max norm */
-#define IEEE754_SPCVAL_NMAX		10	/* -max norm */
-#define IEEE754_SPCVAL_PMIN		11	/* +min norm */
-#define IEEE754_SPCVAL_NMIN		12	/* -min norm */
-#define IEEE754_SPCVAL_PMIND		13	/* +min denorm */
-#define IEEE754_SPCVAL_NMIND		14	/* -min denorm */
-#define IEEE754_SPCVAL_P1E31		15	/* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63		16	/* + 1.0e63 */
+#define IEEE754_SPCVAL_INDEF_LEG	8	/* legacy quiet NaN */
+#define IEEE754_SPCVAL_INDEF_2008	9	/* IEEE 754-2008 quiet NaN */
+#define IEEE754_SPCVAL_PMAX		10	/* +max norm */
+#define IEEE754_SPCVAL_NMAX		11	/* -max norm */
+#define IEEE754_SPCVAL_PMIN		12	/* +min norm */
+#define IEEE754_SPCVAL_NMIN		13	/* -min norm */
+#define IEEE754_SPCVAL_PMIND		14	/* +min denorm */
+#define IEEE754_SPCVAL_NMIND		15	/* -min denorm */
+#define IEEE754_SPCVAL_P1E31		16	/* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63		17	/* + 1.0e63 */
 
 
 extern const union ieee754dp __ieee754dp_spcvals[];
 extern const union ieee754dp __ieee754dp_spcvals[];
 extern const union ieee754sp __ieee754sp_spcvals[];
 extern const union ieee754sp __ieee754sp_spcvals[];
@@ -243,7 +244,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
 #define ieee754dp_zero(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754dp_zero(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754dp_one(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754dp_one(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754dp_ten(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
 #define ieee754dp_ten(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef()	(ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_indef()	(ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+						   ieee754_csr.nan2008])
 #define ieee754dp_max(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754dp_max(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754dp_min(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754dp_min(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754dp_mind(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
 #define ieee754dp_mind(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -254,7 +256,8 @@ extern const union ieee754sp __ieee754sp_spcvals[];
 #define ieee754sp_zero(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754sp_zero(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 #define ieee754sp_one(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754sp_one(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 #define ieee754sp_ten(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
 #define ieee754sp_ten(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef()	(ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_indef()	(ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
+						   ieee754_csr.nan2008])
 #define ieee754sp_max(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754sp_max(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 #define ieee754sp_min(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754sp_min(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 #define ieee754sp_mind(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
 #define ieee754sp_mind(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
@@ -266,12 +269,25 @@ extern const union ieee754sp __ieee754sp_spcvals[];
  */
  */
 static inline int ieee754si_indef(void)
 static inline int ieee754si_indef(void)
 {
 {
-	return INT_MAX;
+	return ieee754_csr.nan2008 ? 0 : INT_MAX;
 }
 }
 
 
 static inline s64 ieee754di_indef(void)
 static inline s64 ieee754di_indef(void)
 {
 {
-	return S64_MAX;
+	return ieee754_csr.nan2008 ? 0 : S64_MAX;
+}
+
+/*
+ * Overflow integer value
+ */
+static inline int ieee754si_overflow(int xs)
+{
+	return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX;
+}
+
+static inline s64 ieee754di_overflow(int xs)
+{
+	return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX;
 }
 }
 
 
 /* result types for xctx.rt */
 /* result types for xctx.rt */

+ 10 - 2
arch/mips/math-emu/ieee754dp.c

@@ -37,8 +37,11 @@ static inline int ieee754dp_isnan(union ieee754dp x)
 
 
 static inline int ieee754dp_issnan(union ieee754dp x)
 static inline int ieee754dp_issnan(union ieee754dp x)
 {
 {
+	int qbit;
+
 	assert(ieee754dp_isnan(x));
 	assert(ieee754dp_isnan(x));
-	return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+	qbit = (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
+	return ieee754_csr.nan2008 ^ qbit;
 }
 }
 
 
 
 
@@ -51,7 +54,12 @@ union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
 	assert(ieee754dp_issnan(r));
 	assert(ieee754dp_issnan(r));
 
 
 	ieee754_setcx(IEEE754_INVALID_OPERATION);
 	ieee754_setcx(IEEE754_INVALID_OPERATION);
-	return ieee754dp_indef();
+	if (ieee754_csr.nan2008)
+		DPMANT(r) |= DP_MBIT(DP_FBITS - 1);
+	else
+		r = ieee754dp_indef();
+
+	return r;
 }
 }
 
 
 static u64 ieee754dp_get_rounding(int sn, u64 xm)
 static u64 ieee754dp_get_rounding(int sn, u64 xm)

+ 6 - 6
arch/mips/math-emu/ieee754int.h

@@ -63,10 +63,10 @@ static inline int ieee754_class_nan(int xc)
 	if (ve == SP_EMAX+1+SP_EBIAS) {					\
 	if (ve == SP_EMAX+1+SP_EBIAS) {					\
 		if (vm == 0)						\
 		if (vm == 0)						\
 			vc = IEEE754_CLASS_INF;				\
 			vc = IEEE754_CLASS_INF;				\
-		else if (vm & SP_MBIT(SP_FBITS-1))			\
-			vc = IEEE754_CLASS_SNAN;			\
-		else							\
+		else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
 			vc = IEEE754_CLASS_QNAN;			\
 			vc = IEEE754_CLASS_QNAN;			\
+		else							\
+			vc = IEEE754_CLASS_SNAN;			\
 	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
 	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
 		if (vm) {						\
 		if (vm) {						\
 			ve = SP_EMIN;					\
 			ve = SP_EMIN;					\
@@ -97,10 +97,10 @@ static inline int ieee754_class_nan(int xc)
 	if (ve == DP_EMAX+1+DP_EBIAS) {					\
 	if (ve == DP_EMAX+1+DP_EBIAS) {					\
 		if (vm == 0)						\
 		if (vm == 0)						\
 			vc = IEEE754_CLASS_INF;				\
 			vc = IEEE754_CLASS_INF;				\
-		else if (vm & DP_MBIT(DP_FBITS-1))			\
-			vc = IEEE754_CLASS_SNAN;			\
-		else							\
+		else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
 			vc = IEEE754_CLASS_QNAN;			\
 			vc = IEEE754_CLASS_QNAN;			\
+		else							\
+			vc = IEEE754_CLASS_SNAN;			\
 	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
 	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
 		if (vm) {						\
 		if (vm) {						\
 			ve = DP_EMIN;					\
 			ve = DP_EMIN;					\

+ 10 - 2
arch/mips/math-emu/ieee754sp.c

@@ -37,8 +37,11 @@ static inline int ieee754sp_isnan(union ieee754sp x)
 
 
 static inline int ieee754sp_issnan(union ieee754sp x)
 static inline int ieee754sp_issnan(union ieee754sp x)
 {
 {
+	int qbit;
+
 	assert(ieee754sp_isnan(x));
 	assert(ieee754sp_isnan(x));
-	return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
+	qbit = (SPMANT(x) & SP_MBIT(SP_FBITS - 1)) == SP_MBIT(SP_FBITS - 1);
+	return ieee754_csr.nan2008 ^ qbit;
 }
 }
 
 
 
 
@@ -51,7 +54,12 @@ union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
 	assert(ieee754sp_issnan(r));
 	assert(ieee754sp_issnan(r));
 
 
 	ieee754_setcx(IEEE754_INVALID_OPERATION);
 	ieee754_setcx(IEEE754_INVALID_OPERATION);
-	return ieee754sp_indef();
+	if (ieee754_csr.nan2008)
+		SPMANT(r) |= SP_MBIT(SP_FBITS - 1);
+	else
+		r = ieee754sp_indef();
+
+	return r;
 }
 }
 
 
 static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
 static unsigned ieee754sp_get_rounding(int sn, unsigned xm)

+ 8 - 5
arch/mips/math-emu/sp_fdp.c

@@ -44,13 +44,16 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
 
 
 	switch (xc) {
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
-
+		x = ieee754dp_nanxcpt(x);
+		EXPLODEXDP;
+		/* Fall through.  */
 	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_QNAN:
 		y = ieee754sp_nan_fdp(xs, xm);
 		y = ieee754sp_nan_fdp(xs, xm);
-		EXPLODEYSP;
-		if (!ieee754_class_nan(yc))
-			y = ieee754sp_indef();
+		if (!ieee754_csr.nan2008) {
+			EXPLODEYSP;
+			if (!ieee754_class_nan(yc))
+				y = ieee754sp_indef();
+		}
 		return y;
 		return y;
 
 
 	case IEEE754_CLASS_INF:
 	case IEEE754_CLASS_INF:

+ 25 - 13
arch/mips/math-emu/sp_simple.c

@@ -23,27 +23,39 @@
 
 
 union ieee754sp ieee754sp_neg(union ieee754sp x)
 union ieee754sp ieee754sp_neg(union ieee754sp x)
 {
 {
-	unsigned int oldrm;
 	union ieee754sp y;
 	union ieee754sp y;
 
 
-	oldrm = ieee754_csr.rm;
-	ieee754_csr.rm = FPU_CSR_RD;
-	y = ieee754sp_sub(ieee754sp_zero(0), x);
-	ieee754_csr.rm = oldrm;
+	if (ieee754_csr.abs2008) {
+		y = x;
+		SPSIGN(y) = !SPSIGN(x);
+	} else {
+		unsigned int oldrm;
+
+		oldrm = ieee754_csr.rm;
+		ieee754_csr.rm = FPU_CSR_RD;
+		y = ieee754sp_sub(ieee754sp_zero(0), x);
+		ieee754_csr.rm = oldrm;
+	}
 	return y;
 	return y;
 }
 }
 
 
 union ieee754sp ieee754sp_abs(union ieee754sp x)
 union ieee754sp ieee754sp_abs(union ieee754sp x)
 {
 {
-	unsigned int oldrm;
 	union ieee754sp y;
 	union ieee754sp y;
 
 
-	oldrm = ieee754_csr.rm;
-	ieee754_csr.rm = FPU_CSR_RD;
-	if (SPSIGN(x))
-		y = ieee754sp_sub(ieee754sp_zero(0), x);
-	else
-		y = ieee754sp_add(ieee754sp_zero(0), x);
-	ieee754_csr.rm = oldrm;
+	if (ieee754_csr.abs2008) {
+		y = x;
+		SPSIGN(y) = 0;
+	} else {
+		unsigned int oldrm;
+
+		oldrm = ieee754_csr.rm;
+		ieee754_csr.rm = FPU_CSR_RD;
+		if (SPSIGN(x))
+			y = ieee754sp_sub(ieee754sp_zero(0), x);
+		else
+			y = ieee754sp_add(ieee754sp_zero(0), x);
+		ieee754_csr.rm = oldrm;
+	}
 	return y;
 	return y;
 }
 }

+ 6 - 3
arch/mips/math-emu/sp_tint.c

@@ -38,10 +38,13 @@ int ieee754sp_tint(union ieee754sp x)
 	switch (xc) {
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754si_indef();
 		return ieee754si_indef();
 
 
+	case IEEE754_CLASS_INF:
+		ieee754_setcx(IEEE754_INVALID_OPERATION);
+		return ieee754si_overflow(xs);
+
 	case IEEE754_CLASS_ZERO:
 	case IEEE754_CLASS_ZERO:
 		return 0;
 		return 0;
 
 
@@ -56,7 +59,7 @@ int ieee754sp_tint(union ieee754sp x)
 		/* Set invalid. We will only use overflow for floating
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		   point overflow */
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754si_indef();
+		return ieee754si_overflow(xs);
 	}
 	}
 	/* oh gawd */
 	/* oh gawd */
 	if (xe > SP_FBITS) {
 	if (xe > SP_FBITS) {
@@ -97,7 +100,7 @@ int ieee754sp_tint(union ieee754sp x)
 		if ((xm >> 31) != 0) {
 		if ((xm >> 31) != 0) {
 			/* This can happen after rounding */
 			/* This can happen after rounding */
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
-			return ieee754si_indef();
+			return ieee754si_overflow(xs);
 		}
 		}
 		if (round || sticky)
 		if (round || sticky)
 			ieee754_setcx(IEEE754_INEXACT);
 			ieee754_setcx(IEEE754_INEXACT);

+ 6 - 3
arch/mips/math-emu/sp_tlong.c

@@ -39,10 +39,13 @@ s64 ieee754sp_tlong(union ieee754sp x)
 	switch (xc) {
 	switch (xc) {
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_SNAN:
 	case IEEE754_CLASS_QNAN:
 	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		return ieee754di_indef();
 		return ieee754di_indef();
 
 
+	case IEEE754_CLASS_INF:
+		ieee754_setcx(IEEE754_INVALID_OPERATION);
+		return ieee754di_overflow(xs);
+
 	case IEEE754_CLASS_ZERO:
 	case IEEE754_CLASS_ZERO:
 		return 0;
 		return 0;
 
 
@@ -57,7 +60,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
 		/* Set invalid. We will only use overflow for floating
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		   point overflow */
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
 		ieee754_setcx(IEEE754_INVALID_OPERATION);
-		return ieee754di_indef();
+		return ieee754di_overflow(xs);
 	}
 	}
 	/* oh gawd */
 	/* oh gawd */
 	if (xe > SP_FBITS) {
 	if (xe > SP_FBITS) {
@@ -94,7 +97,7 @@ s64 ieee754sp_tlong(union ieee754sp x)
 		if ((xm >> 63) != 0) {
 		if ((xm >> 63) != 0) {
 			/* This can happen after rounding */
 			/* This can happen after rounding */
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
 			ieee754_setcx(IEEE754_INVALID_OPERATION);
-			return ieee754di_indef();
+			return ieee754di_overflow(xs);
 		}
 		}
 		if (round || sticky)
 		if (round || sticky)
 			ieee754_setcx(IEEE754_INEXACT);
 			ieee754_setcx(IEEE754_INEXACT);

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

@@ -241,7 +241,7 @@ static void output_pgtable_bits_defines(void)
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 	pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
 	pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
 #endif
 #endif
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
 	if (cpu_has_rixi) {
 	if (cpu_has_rixi) {
 #ifdef _PAGE_NO_EXEC_SHIFT
 #ifdef _PAGE_NO_EXEC_SHIFT
 		pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
 		pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);

+ 1 - 0
arch/mips/pci/Makefile

@@ -43,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80)	+= pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM)		+= fixup-sni.o ops-sni.o
 obj-$(CONFIG_SNI_RM)		+= fixup-sni.o ops-sni.o
 obj-$(CONFIG_LANTIQ)		+= fixup-lantiq.o
 obj-$(CONFIG_LANTIQ)		+= fixup-lantiq.o
 obj-$(CONFIG_PCI_LANTIQ)	+= pci-lantiq.o ops-lantiq.o
 obj-$(CONFIG_PCI_LANTIQ)	+= pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_SOC_MT7620)	+= pci-mt7620.o
 obj-$(CONFIG_SOC_RT288X)	+= pci-rt2880.o
 obj-$(CONFIG_SOC_RT288X)	+= pci-rt2880.o
 obj-$(CONFIG_SOC_RT3883)	+= pci-rt3883.o
 obj-$(CONFIG_SOC_RT3883)	+= pci-rt3883.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o

+ 426 - 0
arch/mips/pci/pci-mt7620.c

@@ -0,0 +1,426 @@
+/*
+ *  Ralink MT7620A SoC PCI support
+ *
+ *  Copyright (C) 2007-2013 Bruce Chang (Mediatek)
+ *  Copyright (C) 2013-2016 John Crispin <blogic@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/reset.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7620.h>
+
+#define RALINK_PCI_IO_MAP_BASE		0x10160000
+#define RALINK_PCI_MEMORY_BASE		0x0
+
+#define RALINK_INT_PCIE0		4
+
+#define RALINK_CLKCFG1			0x30
+#define RALINK_GPIOMODE			0x60
+
+#define PPLL_CFG1			0x9c
+#define PDRV_SW_SET			BIT(23)
+
+#define PPLL_DRV			0xa0
+#define PDRV_SW_SET			(1<<31)
+#define LC_CKDRVPD			(1<<19)
+#define LC_CKDRVOHZ			(1<<18)
+#define LC_CKDRVHZ			(1<<17)
+#define LC_CKTEST			(1<<16)
+
+/* PCI Bridge registers */
+#define RALINK_PCI_PCICFG_ADDR		0x00
+#define PCIRST				BIT(1)
+
+#define RALINK_PCI_PCIENA		0x0C
+#define PCIINT2				BIT(20)
+
+#define RALINK_PCI_CONFIG_ADDR		0x20
+#define RALINK_PCI_CONFIG_DATA_VIRT_REG	0x24
+#define RALINK_PCI_MEMBASE		0x28
+#define RALINK_PCI_IOBASE		0x2C
+
+/* PCI RC registers */
+#define RALINK_PCI0_BAR0SETUP_ADDR	0x10
+#define RALINK_PCI0_IMBASEBAR0_ADDR	0x18
+#define RALINK_PCI0_ID			0x30
+#define RALINK_PCI0_CLASS		0x34
+#define RALINK_PCI0_SUBID		0x38
+#define RALINK_PCI0_STATUS		0x50
+#define PCIE_LINK_UP_ST			BIT(0)
+
+#define PCIEPHY0_CFG			0x90
+
+#define RALINK_PCIEPHY_P0_CTL_OFFSET	0x7498
+#define RALINK_PCIE0_CLK_EN		(1 << 26)
+
+#define BUSY				0x80000000
+#define WAITRETRY_MAX			10
+#define WRITE_MODE			(1UL << 23)
+#define DATA_SHIFT			0
+#define ADDR_SHIFT			8
+
+
+static void __iomem *bridge_base;
+static void __iomem *pcie_base;
+
+static struct reset_control *rstpcie0;
+
+static inline void bridge_w32(u32 val, unsigned reg)
+{
+	iowrite32(val, bridge_base + reg);
+}
+
+static inline u32 bridge_r32(unsigned reg)
+{
+	return ioread32(bridge_base + reg);
+}
+
+static inline void pcie_w32(u32 val, unsigned reg)
+{
+	iowrite32(val, pcie_base + reg);
+}
+
+static inline u32 pcie_r32(unsigned reg)
+{
+	return ioread32(pcie_base + reg);
+}
+
+static inline void pcie_m32(u32 clr, u32 set, unsigned reg)
+{
+	u32 val = pcie_r32(reg);
+
+	val &= ~clr;
+	val |= set;
+	pcie_w32(val, reg);
+}
+
+static int wait_pciephy_busy(void)
+{
+	unsigned long reg_value = 0x0, retry = 0;
+
+	while (1) {
+		reg_value = pcie_r32(PCIEPHY0_CFG);
+
+		if (reg_value & BUSY)
+			mdelay(100);
+		else
+			break;
+		if (retry++ > WAITRETRY_MAX) {
+			printk(KERN_WARN "PCIE-PHY retry failed.\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void pcie_phy(unsigned long addr, unsigned long val)
+{
+	wait_pciephy_busy();
+	pcie_w32(WRITE_MODE | (val << DATA_SHIFT) | (addr << ADDR_SHIFT),
+		 PCIEPHY0_CFG);
+	mdelay(1);
+	wait_pciephy_busy();
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+			   int size, u32 *val)
+{
+	unsigned int slot = PCI_SLOT(devfn);
+	u8 func = PCI_FUNC(devfn);
+	u32 address;
+	u32 data;
+	u32 num = 0;
+
+	if (bus)
+		num = bus->number;
+
+	address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+		  (func << 8) | (where & 0xfc) | 0x80000000;
+	bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+	data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+		break;
+	case 4:
+		*val = data;
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+			    int size, u32 val)
+{
+	unsigned int slot = PCI_SLOT(devfn);
+	u8 func = PCI_FUNC(devfn);
+	u32 address;
+	u32 data;
+	u32 num = 0;
+
+	if (bus)
+		num = bus->number;
+
+	address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) |
+		  (func << 8) | (where & 0xfc) | 0x80000000;
+	bridge_w32(address, RALINK_PCI_CONFIG_ADDR);
+	data = bridge_r32(RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+	switch (size) {
+	case 1:
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+		break;
+	case 2:
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+		break;
+	case 4:
+		data = val;
+		break;
+	}
+
+	bridge_w32(data, RALINK_PCI_CONFIG_DATA_VIRT_REG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mt7620_pci_ops = {
+	.read	= pci_config_read,
+	.write	= pci_config_write,
+};
+
+static struct resource mt7620_res_pci_mem1;
+static struct resource mt7620_res_pci_io1;
+struct pci_controller mt7620_controller = {
+	.pci_ops	= &mt7620_pci_ops,
+	.mem_resource	= &mt7620_res_pci_mem1,
+	.mem_offset	= 0x00000000UL,
+	.io_resource	= &mt7620_res_pci_io1,
+	.io_offset	= 0x00000000UL,
+	.io_map_base	= 0xa0000000,
+};
+
+static int mt7620_pci_hw_init(struct platform_device *pdev)
+{
+	/* bypass PCIe DLL */
+	pcie_phy(0x0, 0x80);
+	pcie_phy(0x1, 0x04);
+
+	/* Elastic buffer control */
+	pcie_phy(0x68, 0xB4);
+
+	/* put core into reset */
+	pcie_m32(0, PCIRST, RALINK_PCI_PCICFG_ADDR);
+	reset_control_assert(rstpcie0);
+
+	/* disable power and all clocks */
+	rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+	rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+
+	/* bring core out of reset */
+	reset_control_deassert(rstpcie0);
+	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+	mdelay(100);
+
+	if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) {
+		dev_err(&pdev->dev, "MT7620 PPLL unlock\n");
+		reset_control_assert(rstpcie0);
+		rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+		return -1;
+	}
+
+	/* power up the bus */
+	rt_sysc_m32(LC_CKDRVHZ | LC_CKDRVOHZ, LC_CKDRVPD | PDRV_SW_SET,
+		    PPLL_DRV);
+
+	return 0;
+}
+
+static int mt7628_pci_hw_init(struct platform_device *pdev)
+{
+	u32 val = 0;
+
+	/* bring the core out of reset */
+	rt_sysc_m32(BIT(16), 0, RALINK_GPIOMODE);
+	reset_control_deassert(rstpcie0);
+
+	/* enable the pci clk */
+	rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1);
+	mdelay(100);
+
+	/* voodoo from the SDK driver */
+	pcie_m32(~0xff, 0x5, RALINK_PCIEPHY_P0_CTL_OFFSET);
+
+	pci_config_read(NULL, 0, 0x70c, 4, &val);
+	val &= ~(0xff) << 8;
+	val |= 0x50 << 8;
+	pci_config_write(NULL, 0, 0x70c, 4, val);
+
+	pci_config_read(NULL, 0, 0x70c, 4, &val);
+	dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val);
+
+	return 0;
+}
+
+static int mt7620_pci_probe(struct platform_device *pdev)
+{
+	struct resource *bridge_res = platform_get_resource(pdev,
+							    IORESOURCE_MEM, 0);
+	struct resource *pcie_res = platform_get_resource(pdev,
+							  IORESOURCE_MEM, 1);
+	u32 val = 0;
+
+	rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0");
+	if (IS_ERR(rstpcie0))
+		return PTR_ERR(rstpcie0);
+
+	bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res);
+	if (!bridge_base)
+		return -ENOMEM;
+
+	pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
+	if (!pcie_base)
+		return -ENOMEM;
+
+	iomem_resource.start = 0;
+	iomem_resource.end = ~0;
+	ioport_resource.start = 0;
+	ioport_resource.end = ~0;
+
+	/* bring up the pci core */
+	switch (ralink_soc) {
+	case MT762X_SOC_MT7620A:
+		if (mt7620_pci_hw_init(pdev))
+			return -1;
+		break;
+
+	case MT762X_SOC_MT7628AN:
+		if (mt7628_pci_hw_init(pdev))
+			return -1;
+		break;
+
+	default:
+		dev_err(&pdev->dev, "pcie is not supported on this hardware\n");
+		return -1;
+	}
+	mdelay(50);
+
+	/* enable write access */
+	pcie_m32(PCIRST, 0, RALINK_PCI_PCICFG_ADDR);
+	mdelay(100);
+
+	/* check if there is a card present */
+	if ((pcie_r32(RALINK_PCI0_STATUS) & PCIE_LINK_UP_ST) == 0) {
+		reset_control_assert(rstpcie0);
+		rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1);
+		if (ralink_soc == MT762X_SOC_MT7620A)
+			rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV);
+		dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n");
+		return -1;
+	}
+
+	/* setup ranges */
+	bridge_w32(0xffffffff, RALINK_PCI_MEMBASE);
+	bridge_w32(RALINK_PCI_IO_MAP_BASE, RALINK_PCI_IOBASE);
+
+	pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+	pcie_w32(RALINK_PCI_MEMORY_BASE, RALINK_PCI0_IMBASEBAR0_ADDR);
+	pcie_w32(0x06040001, RALINK_PCI0_CLASS);
+
+	/* enable interrupts */
+	pcie_m32(0, PCIINT2, RALINK_PCI_PCIENA);
+
+	/* voodoo from the SDK driver */
+	pci_config_read(NULL, 0, 4, 4, &val);
+	pci_config_write(NULL, 0, 4, 4, val | 0x7);
+
+	pci_load_of_ranges(&mt7620_controller, pdev->dev.of_node);
+	register_pci_controller(&mt7620_controller);
+
+	return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	u16 cmd;
+	u32 val;
+	int irq = 0;
+
+	if ((dev->bus->number == 0) && (slot == 0)) {
+		pcie_w32(0x7FFF0001, RALINK_PCI0_BAR0SETUP_ADDR);
+		pci_config_write(dev->bus, 0, PCI_BASE_ADDRESS_0, 4,
+				 RALINK_PCI_MEMORY_BASE);
+		pci_config_read(dev->bus, 0, PCI_BASE_ADDRESS_0, 4, &val);
+	} else if ((dev->bus->number == 1) && (slot == 0x0)) {
+		irq = RALINK_INT_PCIE0;
+	} else {
+		dev_err(&dev->dev, "no irq found - bus=0x%x, slot = 0x%x\n",
+			dev->bus->number, slot);
+		return 0;
+	}
+	dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n",
+		dev->bus->number, slot, irq);
+
+	/* configure the cache line size to 0x14 */
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
+
+	/* configure latency timer to 0xff */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xff);
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
+	/* setup the slot */
+	cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+	return irq;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+static const struct of_device_id mt7620_pci_ids[] = {
+	{ .compatible = "mediatek,mt7620-pci" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mt7620_pci_ids);
+
+static struct platform_driver mt7620_pci_driver = {
+	.probe = mt7620_pci_probe,
+	.driver = {
+		.name = "mt7620-pci",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(mt7620_pci_ids),
+	},
+};
+
+static int __init mt7620_pci_init(void)
+{
+	return platform_driver_register(&mt7620_pci_driver);
+}
+
+arch_initcall(mt7620_pci_init);

+ 51 - 0
arch/mips/pic32/Kconfig

@@ -0,0 +1,51 @@
+if MACH_PIC32
+
+choice
+	prompt "Machine Type"
+
+config PIC32MZDA
+	bool "Microchip PIC32MZDA Platform"
+	select BOOT_ELF32
+	select BOOT_RAW
+	select CEVT_R4K
+	select CSRC_R4K
+	select DMA_NONCOHERENT
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_HAS_EARLY_PRINTK
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select ARCH_REQUIRE_GPIOLIB
+	select HAVE_MACH_CLKDEV
+	select COMMON_CLK
+	select CLKDEV_LOOKUP
+	select LIBFDT
+	select USE_OF
+	select PINCTRL
+	select PIC32_EVIC
+	help
+	  Support for the Microchip PIC32MZDA microcontroller.
+
+	  This is a 32-bit microcontroller with support for external or
+	  internally packaged DDR2 memory up to 128MB.
+
+	  For more information, see <http://www.microchip.com/>.
+
+endchoice
+
+choice
+	prompt "Devicetree selection"
+	default DTB_PIC32_NONE
+	help
+	  Select the devicetree.
+
+config DTB_PIC32_NONE
+       bool "None"
+
+config DTB_PIC32_MZDA_SK
+       bool "PIC32MZDA Starter Kit"
+       depends on PIC32MZDA
+       select BUILTIN_DTB
+
+endchoice
+
+endif # MACH_PIC32

+ 6 - 0
arch/mips/pic32/Makefile

@@ -0,0 +1,6 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc.  All rights reserved.
+#
+obj-$(CONFIG_MACH_PIC32) += common/
+obj-$(CONFIG_PIC32MZDA) += pic32mzda/

+ 7 - 0
arch/mips/pic32/Platform

@@ -0,0 +1,7 @@
+#
+# PIC32MZDA
+#
+platform-$(CONFIG_PIC32MZDA)	+= pic32/
+cflags-$(CONFIG_PIC32MZDA)	+= -I$(srctree)/arch/mips/include/asm/mach-pic32
+load-$(CONFIG_PIC32MZDA)	+= 0xffffffff88000000
+all-$(CONFIG_PIC32MZDA)		:= $(COMPRESSION_FNAME).bin

+ 5 - 0
arch/mips/pic32/common/Makefile

@@ -0,0 +1,5 @@
+#
+# Joshua Henderson, <joshua.henderson@microchip.com>
+# Copyright (C) 2015 Microchip Technology, Inc.  All rights reserved.
+#
+obj-y = reset.o irq.o

+ 21 - 0
arch/mips/pic32/common/irq.c

@@ -0,0 +1,21 @@
+/*
+ * Joshua Henderson <joshua.henderson@microchip.com>
+ * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ */
+#include <linux/init.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+
+void __init arch_init_irq(void)
+{
+	irqchip_init();
+}

Some files were not shown because too many files changed in this diff